clean up ssc driver
[openwrt.git] / target / linux / etrax / patches / cris / 002-arch-cris.patch
1 diff -urN linux-2.6.19.2.old/arch/cris/Kconfig linux-2.6.19.2.dev/arch/cris/Kconfig
2 --- linux-2.6.19.2.old/arch/cris/Kconfig 2007-01-10 20:10:37.000000000 +0100
3 +++ linux-2.6.19.2.dev/arch/cris/Kconfig 2007-01-17 18:17:18.000000000 +0100
4 @@ -16,6 +16,10 @@
5 config RWSEM_XCHGADD_ALGORITHM
6 bool
7
8 +config GENERIC_IOMAP
9 + bool
10 + default y
11 +
12 config GENERIC_FIND_NEXT_BIT
13 bool
14 default y
15 @@ -42,6 +46,29 @@
16
17 source "fs/Kconfig.binfmt"
18
19 +config GENERIC_HARDIRQS
20 + bool
21 + default y
22 +
23 +config SMP
24 + bool "SMP"
25 + help
26 + SMP support. Always Say N.
27 +
28 +config NR_CPUS
29 + int
30 + depends on SMP
31 + default 2
32 +
33 +config SCHED_MC
34 + bool "Multi-core scheduler support"
35 + depends on SMP
36 + default y
37 + help
38 + Multi-core scheduler support improves the CPU scheduler's decision
39 + making when dealing with multi-core CPU chips at a cost of slightly
40 + increased overhead in some places. If unsure say N here.
41 +
42 config ETRAX_CMDLINE
43 string "Kernel command line"
44 default "root=/dev/mtdblock3"
45 @@ -70,17 +97,11 @@
46 timers).
47 This is needed if CONFIG_ETRAX_SERIAL_FAST_TIMER is enabled.
48
49 -config PREEMPT
50 - bool "Preemptible Kernel"
51 - help
52 - This option reduces the latency of the kernel when reacting to
53 - real-time or interactive events by allowing a low priority process to
54 - be preempted even if it is in kernel mode executing a system call.
55 - This allows applications to run more reliably even when the system is
56 - under load.
57 +config OOM_REBOOT
58 + bool "Enable reboot at out of memory"
59
60 - Say Y here if you are building a kernel for a desktop, embedded
61 - or real-time system. Say N if you are unsure.
62 +source "kernel/Kconfig.preempt"
63 +source "kernel/Kconfig.sched"
64
65 source mm/Kconfig
66
67 @@ -107,6 +128,16 @@
68 help
69 Support the xsim ETRAX Simulator.
70
71 +config ETRAXFS
72 + bool "ETRAX-FS-V32"
73 + help
74 + Support CRIS V32.
75 +
76 +config ETRAXFS_SIM
77 + bool "ETRAX-FS-V32-Simulator"
78 + help
79 + Support CRIS V32 VCS simualtor.
80 +
81 endchoice
82
83 config ETRAX_ARCH_V10
84 @@ -114,6 +145,11 @@
85 default y if ETRAX100LX || ETRAX100LX_V2
86 default n if !(ETRAX100LX || ETRAX100LX_V2)
87
88 +config ETRAX_ARCH_V32
89 + bool
90 + default y if ETRAXFS || ETRAXFS_SIM
91 + default n if !(ETRAXFS || ETRAXFS_SIM)
92 +
93 config ETRAX_DRAM_SIZE
94 int "DRAM size (dec, in MB)"
95 default "8"
96 @@ -121,12 +157,23 @@
97 Size of DRAM (decimal in MB) typically 2, 8 or 16.
98
99 config ETRAX_FLASH_BUSWIDTH
100 - int "Buswidth of flash in bytes"
101 + int "Buswidth of NOR flash in bytes"
102 default "2"
103 help
104 - Width in bytes of the Flash bus (1, 2 or 4). Is usually 2.
105 + Width in bytes of the NOR Flash bus (1, 2 or 4). Is usually 2.
106
107 -source arch/cris/arch-v10/Kconfig
108 +config ETRAX_NANDFLASH_BUSWIDTH
109 + int "Buswidth of NAND flash in bytes"
110 + default "1"
111 + help
112 + Width in bytes of the NAND flash (1 or 2).
113 +
114 +config ETRAX_FLASH1_SIZE
115 + int "FLASH1 size (dec, in MB. 0 = Unknown)"
116 + default "0"
117 +
118 +# arch/cris/arch is a symlink to correct arch (arch-v10 or arch-v32)
119 +source arch/cris/arch/Kconfig
120
121 endmenu
122
123 @@ -134,7 +181,8 @@
124
125 # bring in ETRAX built-in drivers
126 menu "Drivers for built-in interfaces"
127 -source arch/cris/arch-v10/drivers/Kconfig
128 +# arch/cris/arch is a symlink to correct arch (arch-v10 or arch-v32)
129 +source arch/cris/arch/drivers/Kconfig
130
131 endmenu
132
133 @@ -181,6 +229,10 @@
134
135 source "sound/Kconfig"
136
137 +source "drivers/pcmcia/Kconfig"
138 +
139 +source "drivers/pci/Kconfig"
140 +
141 source "drivers/usb/Kconfig"
142
143 source "arch/cris/Kconfig.debug"
144 diff -urN linux-2.6.19.2.old/arch/cris/Kconfig.debug linux-2.6.19.2.dev/arch/cris/Kconfig.debug
145 --- linux-2.6.19.2.old/arch/cris/Kconfig.debug 2007-01-10 20:10:37.000000000 +0100
146 +++ linux-2.6.19.2.dev/arch/cris/Kconfig.debug 2005-10-31 09:48:02.000000000 +0100
147 @@ -1,14 +1,15 @@
148 menu "Kernel hacking"
149
150 +source "lib/Kconfig.debug"
151 +
152 #bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC
153 +
154 config PROFILING
155 bool "Kernel profiling support"
156
157 config SYSTEM_PROFILER
158 bool "System profiling support"
159
160 -source "lib/Kconfig.debug"
161 -
162 config ETRAX_KGDB
163 bool "Use kernel GDB debugger"
164 depends on DEBUG_KERNEL
165 diff -urN linux-2.6.19.2.old/arch/cris/Makefile linux-2.6.19.2.dev/arch/cris/Makefile
166 --- linux-2.6.19.2.old/arch/cris/Makefile 2007-01-10 20:10:37.000000000 +0100
167 +++ linux-2.6.19.2.dev/arch/cris/Makefile 2006-11-29 17:05:40.000000000 +0100
168 @@ -1,4 +1,4 @@
169 -# $Id: Makefile,v 1.28 2005/03/17 10:44:37 larsv Exp $
170 +# $Id: Makefile,v 1.41 2006/11/29 16:05:40 ricardw Exp $
171 # cris/Makefile
172 #
173 # This file is included by the global makefile so that you can add your own
174 @@ -10,14 +10,11 @@
175 # License. See the file "COPYING" in the main directory of this archive
176 # for more details.
177
178 -# A bug in ld prevents us from having a (constant-value) symbol in a
179 -# "ORIGIN =" or "LENGTH =" expression.
180 -
181 arch-y := v10
182 arch-$(CONFIG_ETRAX_ARCH_V10) := v10
183 arch-$(CONFIG_ETRAX_ARCH_V32) := v32
184
185 -# No config avaiable for make clean etc
186 +# No config available for make clean etc
187 ifneq ($(arch-y),)
188 SARCH := arch-$(arch-y)
189 else
190 @@ -52,79 +49,58 @@
191 # cris object files path
192 OBJ_ARCH = $(objtree)/arch/$(ARCH)
193
194 -target_boot_arch_dir = $(OBJ_ARCH)/$(SARCH)/boot
195 -target_boot_dir = $(OBJ_ARCH)/boot
196 -src_boot_dir = $(SRC_ARCH)/boot
197 -target_compressed_dir = $(OBJ_ARCH)/boot/compressed
198 -src_compressed_dir = $(SRC_ARCH)/boot/compressed
199 -target_rescue_dir = $(OBJ_ARCH)/boot/rescue
200 -src_rescue_dir = $(SRC_ARCH)/boot/rescue
201 -
202 -export target_boot_arch_dir target_boot_dir src_boot_dir target_compressed_dir src_compressed_dir target_rescue_dir src_rescue_dir
203 -
204 -vmlinux.bin: vmlinux
205 - $(OBJCOPY) $(OBJCOPYFLAGS) vmlinux vmlinux.bin
206 -
207 -timage: vmlinux.bin
208 - cat vmlinux.bin cramfs.img >timage
209 -
210 -simimage: timage
211 - cp vmlinux.bin simvmlinux.bin
212 -
213 -# the following will remake timage without compiling the kernel
214 -# it does of course require that all object files exist...
215 -
216 -cramfs:
217 -## cramfs - Creates a cramfs image
218 - mkcramfs -b 8192 -m romfs_meta.txt root cramfs.img
219 - cat vmlinux.bin cramfs.img >timage
220 -
221 -clinux: vmlinux.bin decompress.bin rescue.bin
222 -
223 -decompress.bin: $(target_boot_dir)
224 - @$(MAKE) -f $(src_compressed_dir)/Makefile $(target_compressed_dir)/decompress.bin
225 -
226 -$(target_rescue_dir)/rescue.bin: $(target_boot_dir)
227 - @$(MAKE) -f $(src_rescue_dir)/Makefile $(target_rescue_dir)/rescue.bin
228 +boot := arch/$(ARCH)/boot
229 +MACHINE := arch/$(ARCH)/$(SARCH)
230
231 -zImage: $(target_boot_dir) vmlinux.bin $(target_rescue_dir)/rescue.bin
232 -## zImage - Compressed kernel (gzip)
233 - @$(MAKE) -f $(src_boot_dir)/Makefile zImage
234 +all: zImage
235
236 -$(target_boot_dir): $(target_boot_arch_dir)
237 - ln -sfn $< $@
238 -
239 -$(target_boot_arch_dir):
240 - mkdir -p $@
241 -
242 -compressed: zImage
243 -
244 -archmrproper:
245 -archclean:
246 - @if [ -d arch/$(ARCH)/boot ]; then \
247 - $(MAKE) $(clean)=arch/$(ARCH)/boot ; \
248 - fi
249 - rm -f timage vmlinux.bin decompress.bin rescue.bin cramfs.img
250 - rm -rf $(LD_SCRIPT).tmp
251 +zImage Image: vmlinux
252 + $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@
253
254 archprepare: $(SRC_ARCH)/.links $(srctree)/include/asm-$(ARCH)/.arch
255
256 # Create some links to make all tools happy
257 $(SRC_ARCH)/.links:
258 @rm -rf $(SRC_ARCH)/drivers
259 - @ln -sfn $(SRC_ARCH)/$(SARCH)/drivers $(SRC_ARCH)/drivers
260 + @ln -sfn $(SARCH)/drivers $(SRC_ARCH)/drivers
261 @rm -rf $(SRC_ARCH)/boot
262 - @ln -sfn $(SRC_ARCH)/$(SARCH)/boot $(SRC_ARCH)/boot
263 + @ln -sfn $(SARCH)/boot $(SRC_ARCH)/boot
264 @rm -rf $(SRC_ARCH)/lib
265 - @ln -sfn $(SRC_ARCH)/$(SARCH)/lib $(SRC_ARCH)/lib
266 - @ln -sfn $(SRC_ARCH)/$(SARCH) $(SRC_ARCH)/arch
267 - @ln -sfn $(SRC_ARCH)/$(SARCH)/vmlinux.lds.S $(SRC_ARCH)/kernel/vmlinux.lds.S
268 - @ln -sfn $(SRC_ARCH)/$(SARCH)/kernel/asm-offsets.c $(SRC_ARCH)/kernel/asm-offsets.c
269 + @ln -sfn $(SARCH)/lib $(SRC_ARCH)/lib
270 + @rm -rf $(SRC_ARCH)/arch
271 + @ln -sfn $(SARCH) $(SRC_ARCH)/arch
272 + @rm -rf $(SRC_ARCH)/kernel/vmlinux.lds.S
273 + @ln -sfn ../$(SARCH)/vmlinux.lds.S $(SRC_ARCH)/kernel/vmlinux.lds.S
274 + @rm -rf $(SRC_ARCH)/kernel/asm-offsets.c
275 + @ln -sfn ../$(SARCH)/kernel/asm-offsets.c $(SRC_ARCH)/kernel/asm-offsets.c
276 @touch $@
277
278 # Create link to sub arch includes
279 $(srctree)/include/asm-$(ARCH)/.arch: $(wildcard include/config/arch/*.h)
280 - @echo ' Making $(srctree)/include/asm-$(ARCH)/arch -> $(srctree)/include/asm-$(ARCH)/$(SARCH) symlink'
281 + @echo ' SYMLINK include/asm-$(ARCH)/arch -> include/asm-$(ARCH)/$(SARCH)'
282 @rm -f include/asm-$(ARCH)/arch
283 - @ln -sf $(srctree)/include/asm-$(ARCH)/$(SARCH) $(srctree)/include/asm-$(ARCH)/arch
284 + @ln -sf $(SARCH) $(srctree)/include/asm-$(ARCH)/arch
285 @touch $@
286 +
287 +archclean:
288 + $(Q)if [ -e arch/$(ARCH)/boot ]; then \
289 + $(MAKE) $(clean)=arch/$(ARCH)/boot; \
290 + fi
291 +
292 +CLEAN_FILES += \
293 + $(MACHINE)/boot/zImage \
294 + $(SRC_ARCH)/.links \
295 + $(srctree)/include/asm-$(ARCH)/.arch
296 +
297 +MRPROPER_FILES += \
298 + $(SRC_ARCH)/drivers \
299 + $(SRC_ARCH)/boot \
300 + $(SRC_ARCH)/lib \
301 + $(SRC_ARCH)/arch \
302 + $(SRC_ARCH)/kernel/vmlinux.lds.S \
303 + $(SRC_ARCH)/kernel/asm-offsets.c
304 +
305 +define archhelp
306 + echo '* zImage - Compressed kernel image (arch/$(ARCH)/boot/zImage)'
307 + echo '* Image - Uncompressed kernel image (arch/$(ARCH)/boot/Image)'
308 +endef
309 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/README.mm linux-2.6.19.2.dev/arch/cris/arch-v10/README.mm
310 --- linux-2.6.19.2.old/arch/cris/arch-v10/README.mm 2007-01-10 20:10:37.000000000 +0100
311 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/README.mm 2005-08-23 11:44:32.000000000 +0200
312 @@ -3,6 +3,9 @@
313 HISTORY:
314
315 $Log: README.mm,v $
316 +Revision 1.2 2005/08/23 09:44:32 starvik
317 +extern inline -> static inline. Patch provided by Adrian Bunk <bunk@stusta.de>
318 +
319 Revision 1.1 2001/12/17 13:59:27 bjornw
320 Initial revision
321
322 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/boot/Makefile linux-2.6.19.2.dev/arch/cris/arch-v10/boot/Makefile
323 --- linux-2.6.19.2.old/arch/cris/arch-v10/boot/Makefile 2007-01-10 20:10:37.000000000 +0100
324 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/boot/Makefile 2006-11-29 17:05:40.000000000 +0100
325 @@ -1,13 +1,21 @@
326 #
327 -# arch/cris/boot/Makefile
328 +# arch/cris/arch-v10/boot/Makefile
329 #
330 -target = $(target_boot_dir)
331 -src = $(src_boot_dir)
332
333 -zImage: compressed/vmlinuz
334 +OBJCOPY = objcopy-cris
335 +OBJCOPYFLAGS = -O binary --remove-section=.bss
336
337 -compressed/vmlinuz:
338 - @$(MAKE) -f $(src)/compressed/Makefile $(target_compressed_dir)/vmlinuz
339 +subdir- := compressed rescue
340 +targets := Image
341
342 -clean:
343 - @$(MAKE) -f $(src)/compressed/Makefile clean
344 +$(obj)/Image: vmlinux FORCE
345 + $(call if_changed,objcopy)
346 + @echo ' Kernel: $@ is ready'
347 +
348 +$(obj)/compressed/vmlinux: $(obj)/Image FORCE
349 + $(Q)$(MAKE) $(build)=$(obj)/compressed $@
350 + $(Q)$(MAKE) $(build)=$(obj)/rescue $(obj)/rescue/rescue.bin
351 +
352 +$(obj)/zImage: $(obj)/compressed/vmlinux
353 + @cp $< $@
354 + @echo ' Kernel: $@ is ready'
355 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/boot/compressed/Makefile linux-2.6.19.2.dev/arch/cris/arch-v10/boot/compressed/Makefile
356 --- linux-2.6.19.2.old/arch/cris/arch-v10/boot/compressed/Makefile 2007-01-10 20:10:37.000000000 +0100
357 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/boot/compressed/Makefile 2006-10-11 17:47:04.000000000 +0200
358 @@ -1,45 +1,34 @@
359 #
360 -# create a compressed vmlinuz image from the binary vmlinux.bin file
361 +# arch/cris/arch-v10/boot/compressed/Makefile
362 #
363 -target = $(target_compressed_dir)
364 -src = $(src_compressed_dir)
365
366 CC = gcc-cris -melf $(LINUXINCLUDE)
367 CFLAGS = -O2
368 LD = ld-cris
369 +LDFLAGS = -T $(obj)/decompress.ld
370 +OBJECTS = $(obj)/head.o $(obj)/misc.o
371 OBJCOPY = objcopy-cris
372 OBJCOPYFLAGS = -O binary --remove-section=.bss
373 -OBJECTS = $(target)/head.o $(target)/misc.o
374
375 -# files to compress
376 -SYSTEM = $(objtree)/vmlinux.bin
377 +quiet_cmd_image = BUILD $@
378 +cmd_image = cat $(obj)/decompress.bin $(obj)/piggy.gz > $@
379
380 -all: $(target_compressed_dir)/vmlinuz
381 +targets := vmlinux piggy.gz decompress.o decompress.bin
382
383 -$(target)/decompress.bin: $(OBJECTS)
384 - $(LD) -T $(src)/decompress.ld -o $(target)/decompress.o $(OBJECTS)
385 - $(OBJCOPY) $(OBJCOPYFLAGS) $(target)/decompress.o $(target)/decompress.bin
386 +$(obj)/decompress.o: $(OBJECTS) FORCE
387 + $(call if_changed,ld)
388
389 -# Create vmlinuz image in top-level build directory
390 -$(target_compressed_dir)/vmlinuz: $(target) piggy.img $(target)/decompress.bin
391 - @echo " COMPR vmlinux.bin --> vmlinuz"
392 - @cat $(target)/decompress.bin piggy.img > $(target_compressed_dir)/vmlinuz
393 - @rm -f piggy.img
394 +$(obj)/decompress.bin: $(obj)/decompress.o FORCE
395 + $(call if_changed,objcopy)
396
397 -$(target)/head.o: $(src)/head.S
398 - $(CC) -D__ASSEMBLY__ -traditional -c $< -o $@
399 +$(obj)/head.o: $(obj)/head.S .config
400 + @$(CC) -D__ASSEMBLY__ -traditional -c $< -o $@
401
402 -$(target)/misc.o: $(src)/misc.c
403 - $(CC) -D__KERNEL__ -c $< -o $@
404 +$(obj)/misc.o: $(obj)/misc.c .config
405 + @$(CC) -D__KERNEL__ -c $< -o $@
406
407 -# gzip the kernel image
408 -
409 -piggy.img: $(SYSTEM)
410 - @cat $(SYSTEM) | gzip -f -9 > piggy.img
411 -
412 -$(target):
413 - mkdir -p $(target)
414 -
415 -clean:
416 - rm -f piggy.img $(objtree)/vmlinuz
417 +$(obj)/vmlinux: $(obj)/piggy.gz $(obj)/decompress.bin FORCE
418 + $(call if_changed,image)
419
420 +$(obj)/piggy.gz: $(obj)/../Image FORCE
421 + $(call if_changed,gzip)
422 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/boot/compressed/misc.c linux-2.6.19.2.dev/arch/cris/arch-v10/boot/compressed/misc.c
423 --- linux-2.6.19.2.old/arch/cris/arch-v10/boot/compressed/misc.c 2007-01-10 20:10:37.000000000 +0100
424 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/boot/compressed/misc.c 2006-10-13 14:43:10.000000000 +0200
425 @@ -1,7 +1,7 @@
426 /*
427 * misc.c
428 *
429 - * $Id: misc.c,v 1.6 2003/10/27 08:04:31 starvik Exp $
430 + * $Id: misc.c,v 1.7 2006/10/13 12:43:10 starvik Exp $
431 *
432 * This is a collection of several routines from gzip-1.0.3
433 * adapted for Linux.
434 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/boot/rescue/Makefile linux-2.6.19.2.dev/arch/cris/arch-v10/boot/rescue/Makefile
435 --- linux-2.6.19.2.old/arch/cris/arch-v10/boot/rescue/Makefile 2007-01-10 20:10:37.000000000 +0100
436 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/boot/rescue/Makefile 2006-11-30 11:42:39.000000000 +0100
437 @@ -1,56 +1,38 @@
438 #
439 -# Makefile for rescue code
440 +# Makefile for rescue (bootstrap) code
441 #
442 -target = $(target_rescue_dir)
443 -src = $(src_rescue_dir)
444
445 CC = gcc-cris -mlinux $(LINUXINCLUDE)
446 CFLAGS = -O2
447 -LD = gcc-cris -mlinux -nostdlib
448 +AFLAGS = -traditional
449 +LD = gcc-cris -mlinux -nostdlib
450 +LDFLAGS = -T $(obj)/rescue.ld
451 OBJCOPY = objcopy-cris
452 OBJCOPYFLAGS = -O binary --remove-section=.bss
453 +obj-y = head.o
454 +OBJECT = $(obj)/$(obj-y)
455
456 -all: $(target)/rescue.bin $(target)/testrescue.bin $(target)/kimagerescue.bin
457 +targets := rescue.o rescue.bin
458
459 -$(target)/rescue.bin: $(target) $(target)/head.o
460 - $(LD) -T $(src)/rescue.ld -o $(target)/rescue.o $(target)/head.o
461 - $(OBJCOPY) $(OBJCOPYFLAGS) $(target)/rescue.o $(target)/rescue.bin
462 -# Place a copy in top-level build directory
463 - cp -p $(target)/rescue.bin $(objtree)
464 +$(obj)/rescue.o: $(OBJECT) FORCE
465 + $(call if_changed,ld)
466
467 -$(target)/testrescue.bin: $(target) $(target)/testrescue.o
468 - $(OBJCOPY) $(OBJCOPYFLAGS) $(target)/testrescue.o tr.bin
469 +$(obj)/rescue.bin: $(obj)/rescue.o FORCE
470 + $(call if_changed,objcopy)
471 + cp -p $(obj)/rescue.bin $(objtree)
472 +
473 +$(obj)/testrescue.bin: $(obj)/testrescue.o
474 + $(OBJCOPY) $(OBJCOPYFLAGS) $(obj)/testrescue.o tr.bin
475 # Pad it to 784 bytes
476 dd if=/dev/zero of=tmp2423 bs=1 count=784
477 cat tr.bin tmp2423 >testrescue_tmp.bin
478 - dd if=testrescue_tmp.bin of=$(target)/testrescue.bin bs=1 count=784
479 + dd if=testrescue_tmp.bin of=$(obj)/testrescue.bin bs=1 count=784
480 rm tr.bin tmp2423 testrescue_tmp.bin
481
482 -$(target)/kimagerescue.bin: $(target) $(target)/kimagerescue.o
483 - $(OBJCOPY) $(OBJCOPYFLAGS) $(target)/kimagerescue.o ktr.bin
484 +$(obj)/kimagerescue.bin: $(obj)/kimagerescue.o
485 + $(OBJCOPY) $(OBJCOPYFLAGS) $(obj)/kimagerescue.o ktr.bin
486 # Pad it to 784 bytes, that's what the rescue loader expects
487 dd if=/dev/zero of=tmp2423 bs=1 count=784
488 cat ktr.bin tmp2423 >kimagerescue_tmp.bin
489 - dd if=kimagerescue_tmp.bin of=$(target)/kimagerescue.bin bs=1 count=784
490 + dd if=kimagerescue_tmp.bin of=$(obj)/kimagerescue.bin bs=1 count=784
491 rm ktr.bin tmp2423 kimagerescue_tmp.bin
492 -
493 -$(target):
494 - mkdir -p $(target)
495 -
496 -$(target)/head.o: $(src)/head.S
497 - $(CC) -D__ASSEMBLY__ -traditional -c $< -o $*.o
498 -
499 -$(target)/testrescue.o: $(src)/testrescue.S
500 - $(CC) -D__ASSEMBLY__ -traditional -c $< -o $*.o
501 -
502 -$(target)/kimagerescue.o: $(src)/kimagerescue.S
503 - $(CC) -D__ASSEMBLY__ -traditional -c $< -o $*.o
504 -
505 -clean:
506 - rm -f $(target)/*.o $(target)/*.bin
507 -
508 -fastdep:
509 -
510 -modules:
511 -
512 -modules-install:
513 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/boot/rescue/head.S linux-2.6.19.2.dev/arch/cris/arch-v10/boot/rescue/head.S
514 --- linux-2.6.19.2.old/arch/cris/arch-v10/boot/rescue/head.S 2007-01-10 20:10:37.000000000 +0100
515 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/boot/rescue/head.S 2006-10-13 14:43:10.000000000 +0200
516 @@ -1,4 +1,4 @@
517 -/* $Id: head.S,v 1.7 2005/03/07 12:11:06 starvik Exp $
518 +/* $Id: head.S,v 1.9 2006/10/13 12:43:10 starvik Exp $
519 *
520 * Rescue code, made to reside at the beginning of the
521 * flash-memory. when it starts, it checks a partition
522 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/boot/rescue/kimagerescue.S linux-2.6.19.2.dev/arch/cris/arch-v10/boot/rescue/kimagerescue.S
523 --- linux-2.6.19.2.old/arch/cris/arch-v10/boot/rescue/kimagerescue.S 2007-01-10 20:10:37.000000000 +0100
524 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/boot/rescue/kimagerescue.S 2006-11-29 17:05:41.000000000 +0100
525 @@ -1,4 +1,4 @@
526 -/* $Id: kimagerescue.S,v 1.1 2001/12/17 13:59:27 bjornw Exp $
527 +/* $Id: kimagerescue.S,v 1.3 2006/11/29 16:05:41 ricardw Exp $
528 *
529 * Rescue code to be prepended on a kimage and copied to the
530 * rescue serial port.
531 @@ -7,7 +7,7 @@
532 */
533
534 #define ASSEMBLER_MACROS_ONLY
535 -#include <asm/sv_addr_ag.h>
536 +#include <asm/arch/sv_addr_ag.h>
537
538 #define CODE_START 0x40004000
539 #define CODE_LENGTH 784
540 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/boot/rescue/testrescue.S linux-2.6.19.2.dev/arch/cris/arch-v10/boot/rescue/testrescue.S
541 --- linux-2.6.19.2.old/arch/cris/arch-v10/boot/rescue/testrescue.S 2007-01-10 20:10:37.000000000 +0100
542 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/boot/rescue/testrescue.S 2006-11-29 17:05:41.000000000 +0100
543 @@ -1,4 +1,4 @@
544 -/* $Id: testrescue.S,v 1.1 2001/12/17 13:59:27 bjornw Exp $
545 +/* $Id: testrescue.S,v 1.2 2006/11/29 16:05:41 ricardw Exp $
546 *
547 * Simple testcode to download by the rescue block.
548 * Just lits some LEDs to show it was downloaded correctly.
549 @@ -7,7 +7,7 @@
550 */
551
552 #define ASSEMBLER_MACROS_ONLY
553 -#include <asm/sv_addr_ag.h>
554 +#include <asm/arch/sv_addr_ag.h>
555
556 .text
557
558 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/defconfig linux-2.6.19.2.dev/arch/cris/arch-v10/defconfig
559 --- linux-2.6.19.2.old/arch/cris/arch-v10/defconfig 2007-01-10 20:10:37.000000000 +0100
560 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/defconfig 2006-01-03 15:48:23.000000000 +0100
561 @@ -106,7 +106,6 @@
562 CONFIG_ETRAX_I2C_USES_PB_NOT_PB_I2C=y
563 # CONFIG_ETRAX_I2C_EEPROM is not set
564 CONFIG_ETRAX_GPIO=y
565 -CONFIG_ETRAX_PA_BUTTON_BITMASK=02
566 CONFIG_ETRAX_PA_CHANGEABLE_DIR=00
567 CONFIG_ETRAX_PA_CHANGEABLE_BITS=FF
568 CONFIG_ETRAX_PB_CHANGEABLE_DIR=00
569 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/drivers/Kconfig linux-2.6.19.2.dev/arch/cris/arch-v10/drivers/Kconfig
570 --- linux-2.6.19.2.old/arch/cris/arch-v10/drivers/Kconfig 2007-01-10 20:10:37.000000000 +0100
571 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/drivers/Kconfig 2007-01-09 10:29:18.000000000 +0100
572 @@ -6,6 +6,12 @@
573 This option enables the ETRAX 100LX built-in 10/100Mbit Ethernet
574 controller.
575
576 +config ETRAX_NO_PHY
577 + bool "PHY not present"
578 + depends on ETRAX_ETHERNET
579 + help
580 + Enable if PHY is not present.
581 +
582 choice
583 prompt "Network LED behavior"
584 depends on ETRAX_ETHERNET
585 @@ -90,7 +96,7 @@
586
587 config ETRAX_SERIAL_PORT0_DMA6_OUT
588 bool "DMA 6"
589 -
590 + depends on !ETRAX_DEBUG_PORT0
591 endchoice
592
593 choice
594 @@ -103,7 +109,7 @@
595
596 config ETRAX_SERIAL_PORT0_DMA7_IN
597 bool "DMA 7"
598 -
599 + depends on !ETRAX_DEBUG_PORT0
600 endchoice
601
602 choice
603 @@ -204,7 +210,7 @@
604
605 config ETRAX_SERIAL_PORT1_DMA8_OUT
606 bool "DMA 8"
607 -
608 + depends on !ETRAX_DEBUG_PORT1
609 endchoice
610
611 choice
612 @@ -217,7 +223,7 @@
613
614 config ETRAX_SERIAL_PORT1_DMA9_IN
615 bool "DMA 9"
616 -
617 + depends on !ETRAX_DEBUG_PORT1
618 endchoice
619
620 choice
621 @@ -321,7 +327,7 @@
622
623 config ETRAX_SERIAL_PORT2_DMA2_OUT
624 bool "DMA 2"
625 -
626 + depends on !ETRAX_DEBUG_PORT2
627 endchoice
628
629 choice
630 @@ -334,7 +340,7 @@
631
632 config ETRAX_SERIAL_PORT2_DMA3_IN
633 bool "DMA 3"
634 -
635 + depends on !ETRAX_DEBUG_PORT2
636 endchoice
637
638 choice
639 @@ -435,7 +441,7 @@
640
641 config ETRAX_SERIAL_PORT3_DMA4_OUT
642 bool "DMA 4"
643 -
644 + depends on !ETRAX_DEBUG_PORT3
645 endchoice
646
647 choice
648 @@ -448,7 +454,7 @@
649
650 config ETRAX_SERIAL_PORT3_DMA5_IN
651 bool "DMA 5"
652 -
653 + depends on !ETRAX_DEBUG_PORT3
654 endchoice
655
656 choice
657 @@ -514,8 +520,7 @@
658 bool "RS-485 support"
659 depends on ETRAX_SERIAL
660 help
661 - Enables support for RS-485 serial communication. For a primer on
662 - RS-485, see <http://www.hw.cz/english/docs/rs485/rs485.html>.
663 + Enables support for RS-485 serial communication.
664
665 config ETRAX_RS485_ON_PA
666 bool "RS-485 mode on PA"
667 @@ -541,6 +546,27 @@
668 loopback. Not all products are able to do this in software only.
669 Axis 2400/2401 must disable receiver.
670
671 +config ETRAX_SYNCHRONOUS_SERIAL
672 + bool "Synchronous serial port driver"
673 + help
674 + Select this to enable the synchronous serial port driver.
675 +
676 +config ETRAX_SYNCHRONOUS_SERIAL_PORT0
677 + bool "Synchronous serial port 0 enabled (sser1)"
678 + depends on ETRAX_SYNCHRONOUS_SERIAL
679 +
680 +config ETRAX_SYNCHRONOUS_SERIAL0_DMA
681 + bool "Use DMA for synchronous serial port 0"
682 + depends on ETRAX_SYNCHRONOUS_SERIAL_PORT0
683 +
684 +config ETRAX_SYNCHRONOUS_SERIAL_PORT1
685 + bool "Synchronous serial port 1 enabled (sser3)"
686 + depends on ETRAX_SYNCHRONOUS_SERIAL
687 +
688 +config ETRAX_SYNCHRONOUS_SERIAL1_DMA
689 + bool "Use DMA for synchronous serial port 1"
690 + depends on ETRAX_SYNCHRONOUS_SERIAL_PORT1
691 +
692 config ETRAX_IDE
693 bool "ATA/IDE support"
694 select IDE
695 @@ -604,8 +630,7 @@
696 select MTD
697 select MTD_CFI
698 select MTD_CFI_AMDSTD
699 - select MTD_OBSOLETE_CHIPS
700 - select MTD_AMDSTD
701 + select MTD_JEDECPROBE
702 select MTD_CHAR
703 select MTD_BLOCK
704 select MTD_PARTITIONS
705 @@ -615,6 +640,15 @@
706 This option enables MTD mapping of flash devices. Needed to use
707 flash memories. If unsure, say Y.
708
709 +config ETRAX_AXISFLASHMAP_MTD0WHOLE
710 + bool "MTD0 is whole boot flash device"
711 + depends on ETRAX_AXISFLASHMAP
712 + default N
713 + help
714 + When this option is not set, mtd0 refers to the first partition
715 + on the boot flash device. When set, mtd0 refers to the whole
716 + device, with mtd1 referring to the first partition etc.
717 +
718 config ETRAX_PTABLE_SECTOR
719 int "Byte-offset of partition table sector"
720 depends on ETRAX_AXISFLASHMAP
721 @@ -715,19 +749,6 @@
722 Remember that you need to setup the port directions appropriately in
723 the General configuration.
724
725 -config ETRAX_PA_BUTTON_BITMASK
726 - hex "PA-buttons bitmask"
727 - depends on ETRAX_GPIO
728 - default "02"
729 - help
730 - This is a bitmask with information about what bits on PA that
731 - are used for buttons.
732 - Most products has a so called TEST button on PA1, if that's true
733 - use 02 here.
734 - Use 00 if there are no buttons on PA.
735 - If the bitmask is <> 00 a button driver will be included in the gpio
736 - driver. ETRAX general I/O support must be enabled.
737 -
738 config ETRAX_PA_CHANGEABLE_DIR
739 hex "PA user changeable dir mask"
740 depends on ETRAX_GPIO
741 @@ -768,6 +789,40 @@
742 Bit set = changeable.
743 You probably want 00 here.
744
745 +config ETRAX_DEF_R_PORT_G_DIR
746 + bool "Port G Output"
747 + help
748 + CONFIG_ETRAX_DEF_R_PORT_G_DIR:
749 + Set the direction of specified pins to output.
750 +
751 +config ETRAX_DEF_R_PORT_G0_DIR_OUT
752 + bool "G0"
753 + depends on ETRAX_DEF_R_PORT_G_DIR
754 + help
755 + CONFIG_ETRAX_DEF_R_PORT_G0_DIR_OUT:
756 + Set G0 to output.
757 +
758 +config ETRAX_DEF_R_PORT_G8_15_DIR_OUT
759 + bool "G8-G15"
760 + depends on ETRAX_DEF_R_PORT_G_DIR
761 + help
762 + CONFIG_ETRAX_DEF_R_PORT_G8_15_DIR_OUT:
763 + Set G8-G15 to output.
764 +
765 +config ETRAX_DEF_R_PORT_G16_23_DIR_OUT
766 + bool "G16-G23"
767 + depends on ETRAX_DEF_R_PORT_G_DIR
768 + help
769 + CONFIG_ETRAX_DEF_R_PORT_G16_23_DIR_OUT:
770 + Set G16-G23 to output.
771 +
772 +config ETRAX_DEF_R_PORT_G24_DIR_OUT
773 + bool "G24"
774 + depends on ETRAX_DEF_R_PORT_G_DIR
775 + help
776 + CONFIG_ETRAX_DEF_R_PORT_G24_DIR_OUT:
777 + Set G24 to output.
778 +
779 config ETRAX_RTC
780 bool "Real Time Clock support"
781 depends on ETRAX_ARCH_V10
782 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/drivers/Makefile linux-2.6.19.2.dev/arch/cris/arch-v10/drivers/Makefile
783 --- linux-2.6.19.2.old/arch/cris/arch-v10/drivers/Makefile 2007-01-10 20:10:37.000000000 +0100
784 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/drivers/Makefile 2005-12-12 10:05:46.000000000 +0100
785 @@ -8,5 +8,5 @@
786 obj-$(CONFIG_ETRAX_GPIO) += gpio.o
787 obj-$(CONFIG_ETRAX_DS1302) += ds1302.o
788 obj-$(CONFIG_ETRAX_PCF8563) += pcf8563.o
789 -
790 +obj-$(CONFIG_ETRAX_SYNCHRONOUS_SERIAL) += sync_serial.o
791
792 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/drivers/axisflashmap.c linux-2.6.19.2.dev/arch/cris/arch-v10/drivers/axisflashmap.c
793 --- linux-2.6.19.2.old/arch/cris/arch-v10/drivers/axisflashmap.c 2007-01-10 20:10:37.000000000 +0100
794 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/drivers/axisflashmap.c 2006-11-22 13:26:55.000000000 +0100
795 @@ -11,6 +11,26 @@
796 * partition split defined below.
797 *
798 * $Log: axisflashmap.c,v $
799 + * Revision 1.17 2006/11/22 12:26:55 ricardw
800 + * Added CONFIG_ETRAX_AXISFLASHMAP_MTD0WHOLE option which when enabled puts mtd0
801 + * as whole device, with first partition at mtd1, etc.
802 + *
803 + * Revision 1.16 2006/10/30 15:17:57 pkj
804 + * Avoid a compiler warning.
805 + *
806 + * Revision 1.15 2006/10/13 12:43:10 starvik
807 + * Merge of 2.6.18
808 + *
809 + * Revision 1.14 2006/08/30 13:20:00 karljope
810 + * Do not use deprecated amd_flash to probe flash memory.
811 + * Probe for flash chip with CFI first and if no chip was found try jedec_probe.
812 + *
813 + * Revision 1.13 2006/01/04 06:09:45 starvik
814 + * Merge of Linux 2.6.15
815 + *
816 + * Revision 1.12 2005/06/21 09:13:06 starvik
817 + * Change const char* to const char[] to save space (from domen@coderock.org).
818 + *
819 * Revision 1.11 2004/11/15 10:27:14 starvik
820 * Corrected typo (Thanks to Milton Miller <miltonm@bga.com>).
821 *
822 @@ -300,6 +320,15 @@
823 },
824 };
825
826 +#ifdef CONFIG_ETRAX_AXISFLASHMAP_MTD0WHOLE
827 +/* Main flash device */
828 +static struct mtd_partition main_partition = {
829 + .name = "main",
830 + .size = 0,
831 + .offset = 0
832 +};
833 +#endif
834 +
835 /*
836 * Probe a chip select for AMD-compatible (JEDEC) or CFI-compatible flash
837 * chips in that order (because the amd_flash-driver is faster).
838 @@ -312,12 +341,12 @@
839 "%s: Probing a 0x%08lx bytes large window at 0x%08lx.\n",
840 map_cs->name, map_cs->size, map_cs->map_priv_1);
841
842 -#ifdef CONFIG_MTD_AMDSTD
843 - mtd_cs = do_map_probe("amd_flash", map_cs);
844 -#endif
845 #ifdef CONFIG_MTD_CFI
846 + mtd_cs = do_map_probe("cfi_probe", map_cs);
847 +#endif
848 +#ifdef CONFIG_MTD_JEDECPROBE
849 if (!mtd_cs) {
850 - mtd_cs = do_map_probe("cfi_probe", map_cs);
851 + mtd_cs = do_map_probe("jedec_probe", map_cs);
852 }
853 #endif
854
855 @@ -396,7 +425,7 @@
856 struct partitiontable_head *ptable_head = NULL;
857 struct partitiontable_entry *ptable;
858 int use_default_ptable = 1; /* Until proven otherwise. */
859 - const char *pmsg = " /dev/flash%d at 0x%08x, size 0x%08x\n";
860 + const char pmsg[] = " /dev/flash%d at 0x%08x, size 0x%08x\n";
861
862 if (!(mymtd = flash_probe())) {
863 /* There's no reason to use this module if no flash chip can
864 @@ -491,6 +520,16 @@
865 pidx++;
866 }
867
868 +#ifdef CONFIG_ETRAX_AXISFLASHMAP_MTD0WHOLE
869 + if (mymtd) {
870 + main_partition.size = mymtd->size;
871 + err = add_mtd_partitions(mymtd, &main_partition, 1);
872 + if (err)
873 + panic("axisflashmap: Could not initialize "
874 + "partition for whole main mtd device!\n");
875 + }
876 +#endif
877 +
878 if (mymtd) {
879 if (use_default_ptable) {
880 printk(KERN_INFO " Using default partition table.\n");
881 @@ -524,7 +563,7 @@
882 }
883
884 printk(KERN_INFO " Adding RAM partition for romfs image:\n");
885 - printk(pmsg, pidx, romfs_start, romfs_length);
886 + printk(pmsg, pidx, (unsigned)romfs_start, (unsigned)romfs_length);
887
888 err = mtdram_init_device(mtd_ram, (void*)romfs_start,
889 romfs_length, "romfs");
890 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/drivers/ds1302.c linux-2.6.19.2.dev/arch/cris/arch-v10/drivers/ds1302.c
891 --- linux-2.6.19.2.old/arch/cris/arch-v10/drivers/ds1302.c 2007-01-10 20:10:37.000000000 +0100
892 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/drivers/ds1302.c 2006-10-27 16:31:23.000000000 +0200
893 @@ -6,136 +6,9 @@
894 *!
895 *! Functions exported: ds1302_readreg, ds1302_writereg, ds1302_init
896 *!
897 -*! $Log: ds1302.c,v $
898 -*! Revision 1.18 2005/01/24 09:11:26 mikaelam
899 -*! Minor changes to get DS1302 RTC chip driver to work
900 -*!
901 -*! Revision 1.17 2005/01/05 06:11:22 starvik
902 -*! No need to do local_irq_disable after local_irq_save.
903 -*!
904 -*! Revision 1.16 2004/12/13 12:21:52 starvik
905 -*! Added I/O and DMA allocators from Linux 2.4
906 -*!
907 -*! Revision 1.14 2004/08/24 06:48:43 starvik
908 -*! Whitespace cleanup
909 -*!
910 -*! Revision 1.13 2004/05/28 09:26:59 starvik
911 -*! Modified I2C initialization to work in 2.6.
912 -*!
913 -*! Revision 1.12 2004/05/14 07:58:03 starvik
914 -*! Merge of changes from 2.4
915 -*!
916 -*! Revision 1.10 2004/02/04 09:25:12 starvik
917 -*! Merge of Linux 2.6.2
918 -*!
919 -*! Revision 1.9 2003/07/04 08:27:37 starvik
920 -*! Merge of Linux 2.5.74
921 -*!
922 -*! Revision 1.8 2003/04/09 05:20:47 starvik
923 -*! Merge of Linux 2.5.67
924 -*!
925 -*! Revision 1.6 2003/01/09 14:42:51 starvik
926 -*! Merge of Linux 2.5.55
927 -*!
928 -*! Revision 1.4 2002/12/11 13:13:57 starvik
929 -*! Added arch/ to v10 specific includes
930 -*! Added fix from Linux 2.4 in serial.c (flush_to_flip_buffer)
931 -*!
932 -*! Revision 1.3 2002/11/20 11:56:10 starvik
933 -*! Merge of Linux 2.5.48
934 -*!
935 -*! Revision 1.2 2002/11/18 13:16:06 starvik
936 -*! Linux 2.5 port of latest 2.4 drivers
937 -*!
938 -*! Revision 1.15 2002/10/11 16:14:33 johana
939 -*! Added CONFIG_ETRAX_DS1302_TRICKLE_CHARGE and initial setting of the
940 -*! trcklecharge register.
941 -*!
942 -*! Revision 1.14 2002/10/10 12:15:38 magnusmn
943 -*! Added support for having the RST signal on bit g0
944 -*!
945 -*! Revision 1.13 2002/05/29 15:16:08 johana
946 -*! Removed unused variables.
947 -*!
948 -*! Revision 1.12 2002/04/10 15:35:25 johana
949 -*! Moved probe function closer to init function and marked it __init.
950 -*!
951 -*! Revision 1.11 2001/06/14 12:35:52 jonashg
952 -*! The ATA hack is back. It is unfortunately the only way to set g27 to output.
953 -*!
954 -*! Revision 1.9 2001/06/14 10:00:14 jonashg
955 -*! No need for tempudelay to be inline anymore (had to adjust the usec to
956 -*! loops conversion because of this to make it slow enough to be a udelay).
957 -*!
958 -*! Revision 1.8 2001/06/14 08:06:32 jonashg
959 -*! Made tempudelay delay usecs (well, just a tad more).
960 -*!
961 -*! Revision 1.7 2001/06/13 14:18:11 jonashg
962 -*! Only allow processes with SYS_TIME capability to set time and charge.
963 -*!
964 -*! Revision 1.6 2001/06/12 15:22:07 jonashg
965 -*! * Made init function __init.
966 -*! * Parameter to out_byte() is unsigned char.
967 -*! * The magic number 42 has got a name.
968 -*! * Removed comment about /proc (nothing is exported there).
969 -*!
970 -*! Revision 1.5 2001/06/12 14:35:13 jonashg
971 -*! Gave the module a name and added it to printk's.
972 -*!
973 -*! Revision 1.4 2001/05/31 14:53:40 jonashg
974 -*! Made tempudelay() inline so that the watchdog doesn't reset (see
975 -*! function comment).
976 -*!
977 -*! Revision 1.3 2001/03/26 16:03:06 bjornw
978 -*! Needs linux/config.h
979 -*!
980 -*! Revision 1.2 2001/03/20 19:42:00 bjornw
981 -*! Use the ETRAX prefix on the DS1302 options
982 -*!
983 -*! Revision 1.1 2001/03/20 09:13:50 magnusmn
984 -*! Linux 2.4 port
985 -*!
986 -*! Revision 1.10 2000/07/05 15:38:23 bjornw
987 -*! Dont update kernel time when a RTC_SET_TIME is done
988 -*!
989 -*! Revision 1.9 2000/03/02 15:42:59 macce
990 -*! * Hack to make RTC work on all 2100/2400
991 -*!
992 -*! Revision 1.8 2000/02/23 16:59:18 torbjore
993 -*! added setup of R_GEN_CONFIG when RTC is connected to the generic port.
994 -*!
995 -*! Revision 1.7 2000/01/17 15:51:43 johana
996 -*! Added RTC_SET_CHARGE ioctl to enable trickle charger.
997 -*!
998 -*! Revision 1.6 1999/10/27 13:19:47 bjornw
999 -*! Added update_xtime_from_cmos which reads back the updated RTC into the kernel.
1000 -*! /dev/rtc calls it now.
1001 -*!
1002 -*! Revision 1.5 1999/10/27 12:39:37 bjornw
1003 -*! Disabled superuser check. Anyone can now set the time.
1004 -*!
1005 -*! Revision 1.4 1999/09/02 13:27:46 pkj
1006 -*! Added shadow for R_PORT_PB_CONFIG.
1007 -*! Renamed port_g_shadow to port_g_data_shadow.
1008 -*!
1009 -*! Revision 1.3 1999/09/02 08:28:06 pkj
1010 -*! Made it possible to select either port PB or the generic port for the RST
1011 -*! signal line to the DS1302 RTC.
1012 -*! Also make sure the RST bit is configured as output on Port PB (if used).
1013 -*!
1014 -*! Revision 1.2 1999/09/01 14:47:20 bjornw
1015 -*! Added support for /dev/rtc operations with ioctl RD_TIME and SET_TIME to read
1016 -*! and set the date. Register as major 121.
1017 -*!
1018 -*! Revision 1.1 1999/09/01 09:45:29 bjornw
1019 -*! Implemented a DS1302 RTC driver.
1020 -*!
1021 -*!
1022 *! ---------------------------------------------------------------------------
1023 *!
1024 -*! (C) Copyright 1999, 2000, 2001, 2002, 2003, 2004 Axis Communications AB, LUND, SWEDEN
1025 -*!
1026 -*! $Id: ds1302.c,v 1.18 2005/01/24 09:11:26 mikaelam Exp $
1027 +*! (C) Copyright 1999-2006 Axis Communications AB, LUND, SWEDEN
1028 *!
1029 *!***************************************************************************/
1030
1031 @@ -305,14 +178,7 @@
1032 void
1033 ds1302_writereg(int reg, unsigned char val)
1034 {
1035 -#ifndef CONFIG_ETRAX_RTC_READONLY
1036 int do_writereg = 1;
1037 -#else
1038 - int do_writereg = 0;
1039 -
1040 - if (reg == RTC_TRICKLECHARGER)
1041 - do_writereg = 1;
1042 -#endif
1043
1044 if (do_writereg) {
1045 ds1302_wenable();
1046 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/drivers/eeprom.c linux-2.6.19.2.dev/arch/cris/arch-v10/drivers/eeprom.c
1047 --- linux-2.6.19.2.old/arch/cris/arch-v10/drivers/eeprom.c 2007-01-10 20:10:37.000000000 +0100
1048 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/drivers/eeprom.c 2006-10-13 14:43:10.000000000 +0200
1049 @@ -20,6 +20,9 @@
1050 *! in the spin-lock.
1051 *!
1052 *! $Log: eeprom.c,v $
1053 +*! Revision 1.13 2006/10/13 12:43:10 starvik
1054 +*! Merge of 2.6.18
1055 +*!
1056 *! Revision 1.12 2005/06/19 17:06:46 starvik
1057 *! Merge of Linux 2.6.12.
1058 *!
1059 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/drivers/gpio.c linux-2.6.19.2.dev/arch/cris/arch-v10/drivers/gpio.c
1060 --- linux-2.6.19.2.old/arch/cris/arch-v10/drivers/gpio.c 2007-01-10 20:10:37.000000000 +0100
1061 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/drivers/gpio.c 2007-02-05 12:54:34.000000000 +0100
1062 @@ -1,4 +1,4 @@
1063 -/* $Id: gpio.c,v 1.17 2005/06/19 17:06:46 starvik Exp $
1064 +/* $Id: gpio.c,v 1.28 2007/02/05 11:54:34 pkj Exp $
1065 *
1066 * Etrax general port I/O device
1067 *
1068 @@ -9,6 +9,40 @@
1069 * Johan Adolfsson (read/set directions, write, port G)
1070 *
1071 * $Log: gpio.c,v $
1072 + * Revision 1.28 2007/02/05 11:54:34 pkj
1073 + * Merge of Linux 2.6.19
1074 + *
1075 + * Revision 1.27 2006/12/12 11:08:30 edgar
1076 + * In etrax_gpio_wake_up_check(), make flags unsigned long.
1077 + *
1078 + * Revision 1.26 2006/11/02 10:54:29 pkj
1079 + * Restored unique device id for request_irq() which was lost in the
1080 + * merge of 2.6.18.
1081 + *
1082 + * Revision 1.25 2006/10/13 12:43:10 starvik
1083 + * Merge of 2.6.18
1084 + *
1085 + * Revision 1.24 2006/07/13 07:42:20 starvik
1086 + * Set unique device id in request_irq
1087 + *
1088 + * Revision 1.23 2006/06/21 09:38:46 starvik
1089 + * Use correct spinlock macros
1090 + *
1091 + * Revision 1.22 2005/08/29 07:32:16 starvik
1092 + * Merge of 2.6.13
1093 + *
1094 + * Revision 1.21 2005/08/16 17:10:54 edgar
1095 + * dont leave locked spinlocks when returning.
1096 + *
1097 + * Revision 1.20 2005/08/15 13:10:47 orjanf
1098 + * Don't link struct into alarmlist until fully initialized.
1099 + *
1100 + * Revision 1.19 2005/07/13 11:43:11 karljope
1101 + * Corrected typo
1102 + *
1103 + * Revision 1.18 2005/06/21 12:26:53 starvik
1104 + * Improved alarm list locking.
1105 + *
1106 * Revision 1.17 2005/06/19 17:06:46 starvik
1107 * Merge of Linux 2.6.12.
1108 *
1109 @@ -277,7 +311,7 @@
1110 unsigned int mask = 0;
1111 struct gpio_private *priv = (struct gpio_private *)file->private_data;
1112 unsigned long data;
1113 - spin_lock(&gpio_lock);
1114 + spin_lock_irq(&gpio_lock);
1115 poll_wait(file, &priv->alarm_wq, wait);
1116 if (priv->minor == GPIO_MINOR_A) {
1117 unsigned long flags;
1118 @@ -297,15 +331,17 @@
1119 data = *R_PORT_PB_DATA;
1120 else if (priv->minor == GPIO_MINOR_G)
1121 data = *R_PORT_G_DATA;
1122 - else
1123 + else {
1124 + spin_unlock_irq(&gpio_lock);
1125 return 0;
1126 + }
1127
1128 if ((data & priv->highalarm) ||
1129 (~data & priv->lowalarm)) {
1130 mask = POLLIN|POLLRDNORM;
1131 }
1132
1133 - spin_unlock(&gpio_lock);
1134 + spin_unlock_irq(&gpio_lock);
1135
1136 DP(printk("gpio_poll ready: mask 0x%08X\n", mask));
1137
1138 @@ -314,10 +350,12 @@
1139
1140 int etrax_gpio_wake_up_check(void)
1141 {
1142 - struct gpio_private *priv = alarmlist;
1143 + struct gpio_private *priv;
1144 unsigned long data = 0;
1145 int ret = 0;
1146 - spin_lock(&gpio_lock);
1147 + unsigned long flags;
1148 + spin_lock_irqsave(&gpio_lock, flags);
1149 + priv = alarmlist;
1150 while (priv) {
1151 if (USE_PORTS(priv)) {
1152 data = *priv->port;
1153 @@ -332,12 +370,12 @@
1154 }
1155 priv = priv->next;
1156 }
1157 - spin_unlock(&gpio_lock);
1158 + spin_unlock_irqrestore(&gpio_lock, flags);
1159 return ret;
1160 }
1161
1162 static irqreturn_t
1163 -gpio_poll_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
1164 +gpio_poll_timer_interrupt(int irq, void *dev_id)
1165 {
1166 if (gpio_some_alarms) {
1167 etrax_gpio_wake_up_check();
1168 @@ -347,7 +385,7 @@
1169 }
1170
1171 static irqreturn_t
1172 -gpio_pa_interrupt(int irq, void *dev_id, struct pt_regs *regs)
1173 +gpio_pa_interrupt(int irq, void *dev_id)
1174 {
1175 unsigned long tmp;
1176 spin_lock(&gpio_lock);
1177 @@ -376,9 +414,6 @@
1178 struct gpio_private *priv = (struct gpio_private *)file->private_data;
1179 unsigned char data, clk_mask, data_mask, write_msb;
1180 unsigned long flags;
1181 -
1182 - spin_lock(&gpio_lock);
1183 -
1184 ssize_t retval = count;
1185 if (priv->minor !=GPIO_MINOR_A && priv->minor != GPIO_MINOR_B) {
1186 return -EFAULT;
1187 @@ -394,6 +429,7 @@
1188 if (clk_mask == 0 || data_mask == 0) {
1189 return -EPERM;
1190 }
1191 + spin_lock_irq(&gpio_lock);
1192 write_msb = priv->write_msb;
1193 D(printk("gpio_write: %lu to data 0x%02X clk 0x%02X msb: %i\n",count, data_mask, clk_mask, write_msb));
1194 while (count--) {
1195 @@ -425,7 +461,7 @@
1196 }
1197 }
1198 }
1199 - spin_unlock(&gpio_lock);
1200 + spin_unlock_irq(&gpio_lock);
1201 return retval;
1202 }
1203
1204 @@ -445,13 +481,12 @@
1205
1206 if (!priv)
1207 return -ENOMEM;
1208 + memset(priv, 0, sizeof(*priv));
1209
1210 priv->minor = p;
1211
1212 - /* initialize the io/alarm struct and link it into our alarmlist */
1213 + /* initialize the io/alarm struct */
1214
1215 - priv->next = alarmlist;
1216 - alarmlist = priv;
1217 if (USE_PORTS(priv)) { /* A and B */
1218 priv->port = ports[p];
1219 priv->shadow = shads[p];
1220 @@ -476,6 +511,12 @@
1221
1222 filp->private_data = (void *)priv;
1223
1224 + /* link it into our alarmlist */
1225 + spin_lock_irq(&gpio_lock);
1226 + priv->next = alarmlist;
1227 + alarmlist = priv;
1228 + spin_unlock_irq(&gpio_lock);
1229 +
1230 return 0;
1231 }
1232
1233 @@ -485,10 +526,10 @@
1234 struct gpio_private *p;
1235 struct gpio_private *todel;
1236
1237 - spin_lock(&gpio_lock);
1238 + spin_lock_irq(&gpio_lock);
1239
1240 - p = alarmlist;
1241 - todel = (struct gpio_private *)filp->private_data;
1242 + p = alarmlist;
1243 + todel = (struct gpio_private *)filp->private_data;
1244
1245 /* unlink from alarmlist and free the private structure */
1246
1247 @@ -506,12 +547,13 @@
1248 while (p) {
1249 if (p->highalarm | p->lowalarm) {
1250 gpio_some_alarms = 1;
1251 + spin_unlock_irq(&gpio_lock);
1252 return 0;
1253 }
1254 p = p->next;
1255 }
1256 gpio_some_alarms = 0;
1257 - spin_unlock(&gpio_lock);
1258 + spin_unlock_irq(&gpio_lock);
1259 return 0;
1260 }
1261
1262 @@ -691,6 +733,8 @@
1263 /* Must update gpio_some_alarms */
1264 struct gpio_private *p = alarmlist;
1265 int some_alarms;
1266 + spin_lock_irq(&gpio_lock);
1267 + p = alarmlist;
1268 some_alarms = 0;
1269 while (p) {
1270 if (p->highalarm | p->lowalarm) {
1271 @@ -700,6 +744,7 @@
1272 p = p->next;
1273 }
1274 gpio_some_alarms = some_alarms;
1275 + spin_unlock_irq(&gpio_lock);
1276 }
1277 break;
1278 case IO_READDIR: /* Use IO_SETGET_INPUT/OUTPUT instead! */
1279 @@ -937,11 +982,11 @@
1280 * in some tests.
1281 */
1282 if (request_irq(TIMER0_IRQ_NBR, gpio_poll_timer_interrupt,
1283 - IRQF_SHARED | IRQF_DISABLED,"gpio poll", NULL)) {
1284 + IRQF_SHARED | IRQF_DISABLED,"gpio poll", gpio_name)) {
1285 printk(KERN_CRIT "err: timer0 irq for gpio\n");
1286 }
1287 if (request_irq(PA_IRQ_NBR, gpio_pa_interrupt,
1288 - IRQF_SHARED | IRQF_DISABLED,"gpio PA", NULL)) {
1289 + IRQF_SHARED | IRQF_DISABLED,"gpio PA", gpio_name)) {
1290 printk(KERN_CRIT "err: PA irq for gpio\n");
1291 }
1292
1293 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/drivers/i2c.c linux-2.6.19.2.dev/arch/cris/arch-v10/drivers/i2c.c
1294 --- linux-2.6.19.2.old/arch/cris/arch-v10/drivers/i2c.c 2007-01-10 20:10:37.000000000 +0100
1295 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/drivers/i2c.c 2006-10-13 14:43:10.000000000 +0200
1296 @@ -11,7 +11,25 @@
1297 *! Jan 14 2000 Johan Adolfsson Fixed PB shadow register stuff -
1298 *! don't use PB_I2C if DS1302 uses same bits,
1299 *! use PB.
1300 +*! June 23 2003 Pieter Grimmerink Added 'i2c_sendnack'. i2c_readreg now
1301 +*! generates nack on last received byte,
1302 +*! instead of ack.
1303 +*! i2c_getack changed data level while clock
1304 +*! was high, causing DS75 to see a stop condition
1305 +*!
1306 *! $Log: i2c.c,v $
1307 +*! Revision 1.17 2006/10/13 12:43:10 starvik
1308 +*! Merge of 2.6.18
1309 +*!
1310 +*! Revision 1.16 2005/09/29 13:33:35 bjarne
1311 +*! If "first" should have any purpos it should probably change value....
1312 +*!
1313 +*! Revision 1.15 2005/08/29 07:32:16 starvik
1314 +*! Merge of 2.6.13
1315 +*!
1316 +*! Revision 1.14 2005/06/30 18:07:31 starvik
1317 +*! Added the sendnack patch from 2.4.
1318 +*!
1319 *! Revision 1.13 2005/03/07 13:13:07 starvik
1320 *! Added spinlocks to protect states etc
1321 *!
1322 @@ -84,7 +102,7 @@
1323 *! (C) Copyright 1999-2002 Axis Communications AB, LUND, SWEDEN
1324 *!
1325 *!***************************************************************************/
1326 -/* $Id: i2c.c,v 1.13 2005/03/07 13:13:07 starvik Exp $ */
1327 +/* $Id: i2c.c,v 1.17 2006/10/13 12:43:10 starvik Exp $ */
1328
1329 /****************** INCLUDE FILES SECTION ***********************************/
1330
1331 @@ -480,7 +498,7 @@
1332 i2c_delay(CLOCK_HIGH_TIME);
1333 i2c_clk(I2C_CLOCK_LOW);
1334 i2c_delay(CLOCK_LOW_TIME);
1335 -
1336 +
1337 i2c_dir_in();
1338 }
1339
1340 @@ -622,7 +640,7 @@
1341 * last received byte needs to be nacked
1342 * instead of acked
1343 */
1344 - i2c_sendack();
1345 + i2c_sendnack();
1346 /*
1347 * end sequence
1348 */
1349 @@ -708,6 +726,7 @@
1350 if (!first) {
1351 return res;
1352 }
1353 + first = 0;
1354
1355 /* Setup and enable the Port B I2C interface */
1356
1357 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/drivers/pcf8563.c linux-2.6.19.2.dev/arch/cris/arch-v10/drivers/pcf8563.c
1358 --- linux-2.6.19.2.old/arch/cris/arch-v10/drivers/pcf8563.c 2007-01-10 20:10:37.000000000 +0100
1359 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/drivers/pcf8563.c 2006-10-27 17:22:12.000000000 +0200
1360 @@ -8,14 +8,13 @@
1361 * low detector are also provided. All address and data are transferred
1362 * serially via two-line bidirectional I2C-bus. Maximum bus speed is
1363 * 400 kbits/s. The built-in word address register is incremented
1364 - * automatically after each written or read bute.
1365 + * automatically after each written or read byte.
1366 *
1367 - * Copyright (c) 2002, Axis Communications AB
1368 + * Copyright (c) 2002-2006, Axis Communications AB
1369 * All rights reserved.
1370 *
1371 * Author: Tobias Anderberg <tobiasa@axis.com>.
1372 *
1373 - * $Id: pcf8563.c,v 1.11 2005/03/07 13:13:07 starvik Exp $
1374 */
1375
1376 #include <linux/module.h>
1377 @@ -27,93 +26,105 @@
1378 #include <linux/ioctl.h>
1379 #include <linux/delay.h>
1380 #include <linux/bcd.h>
1381 -#include <linux/capability.h>
1382
1383 #include <asm/uaccess.h>
1384 #include <asm/system.h>
1385 #include <asm/io.h>
1386 -#include <asm/arch/svinto.h>
1387 #include <asm/rtc.h>
1388 +
1389 #include "i2c.h"
1390
1391 -#define PCF8563_MAJOR 121 /* Local major number. */
1392 -#define DEVICE_NAME "rtc" /* Name which is registered in /proc/devices. */
1393 -#define PCF8563_NAME "PCF8563"
1394 -#define DRIVER_VERSION "$Revision: 1.11 $"
1395 -
1396 -/* I2C bus slave registers. */
1397 -#define RTC_I2C_READ 0xa3
1398 -#define RTC_I2C_WRITE 0xa2
1399 +#define PCF8563_MAJOR 121 /* Local major number. */
1400 +#define DEVICE_NAME "rtc" /* Name which is registered in /proc/devices. */
1401 +#define PCF8563_NAME "PCF8563"
1402 +#define DRIVER_VERSION "$Revision: 1.18 $"
1403
1404 /* Two simple wrapper macros, saves a few keystrokes. */
1405 #define rtc_read(x) i2c_readreg(RTC_I2C_READ, x)
1406 #define rtc_write(x,y) i2c_writereg(RTC_I2C_WRITE, x, y)
1407
1408 static DEFINE_SPINLOCK(rtc_lock); /* Protect state etc */
1409 -
1410 +
1411 static const unsigned char days_in_month[] =
1412 { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
1413
1414 int pcf8563_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
1415
1416 +/* Cache VL bit value read at driver init since writing the RTC_SECOND
1417 + * register clears the VL status.
1418 + */
1419 +static int voltage_low = 0;
1420 +
1421 static struct file_operations pcf8563_fops = {
1422 - .owner = THIS_MODULE,
1423 - .ioctl = pcf8563_ioctl,
1424 + owner: THIS_MODULE,
1425 + ioctl: pcf8563_ioctl,
1426 };
1427
1428 unsigned char
1429 -pcf8563_readreg(int reg)
1430 +pcf8563_readreg(int reg)
1431 {
1432 - unsigned char res = i2c_readreg(RTC_I2C_READ, reg);
1433 + unsigned char res = rtc_read(reg);
1434
1435 - /* The PCF8563 does not return 0 for unimplemented bits */
1436 - switch(reg)
1437 - {
1438 + /* The PCF8563 does not return 0 for unimplemented bits. */
1439 + switch (reg) {
1440 case RTC_SECONDS:
1441 case RTC_MINUTES:
1442 - res &= 0x7f;
1443 - break;
1444 + res &= 0x7F;
1445 + break;
1446 case RTC_HOURS:
1447 case RTC_DAY_OF_MONTH:
1448 - res &= 0x3f;
1449 - break;
1450 + res &= 0x3F;
1451 + break;
1452 + case RTC_WEEKDAY:
1453 + res &= 0x07;
1454 + break;
1455 case RTC_MONTH:
1456 - res = (res & 0x1f) - 1; /* PCF8563 returns month in range 1-12 */
1457 - break;
1458 + res &= 0x1F;
1459 + break;
1460 + case RTC_CONTROL1:
1461 + res &= 0xA8;
1462 + break;
1463 + case RTC_CONTROL2:
1464 + res &= 0x1F;
1465 + break;
1466 + case RTC_CLOCKOUT_FREQ:
1467 + case RTC_TIMER_CONTROL:
1468 + res &= 0x83;
1469 + break;
1470 }
1471 return res;
1472 }
1473
1474 void
1475 -pcf8563_writereg(int reg, unsigned char val)
1476 +pcf8563_writereg(int reg, unsigned char val)
1477 {
1478 -#ifdef CONFIG_ETRAX_RTC_READONLY
1479 - if (reg == RTC_CONTROL1 || (reg >= RTC_SECONDS && reg <= RTC_YEAR))
1480 - return;
1481 -#endif
1482 -
1483 rtc_write(reg, val);
1484 }
1485
1486 void
1487 get_rtc_time(struct rtc_time *tm)
1488 {
1489 - tm->tm_sec = rtc_read(RTC_SECONDS);
1490 - tm->tm_min = rtc_read(RTC_MINUTES);
1491 + tm->tm_sec = rtc_read(RTC_SECONDS);
1492 + tm->tm_min = rtc_read(RTC_MINUTES);
1493 tm->tm_hour = rtc_read(RTC_HOURS);
1494 tm->tm_mday = rtc_read(RTC_DAY_OF_MONTH);
1495 - tm->tm_mon = rtc_read(RTC_MONTH);
1496 + tm->tm_wday = rtc_read(RTC_WEEKDAY);
1497 + tm->tm_mon = rtc_read(RTC_MONTH);
1498 tm->tm_year = rtc_read(RTC_YEAR);
1499
1500 - if (tm->tm_sec & 0x80)
1501 - printk(KERN_WARNING "%s: RTC Low Voltage - date/time is not reliable!\n", PCF8563_NAME);
1502 + if (tm->tm_sec & 0x80) {
1503 + printk(KERN_WARNING "%s: RTC Voltage Low - reliable date/time "
1504 + "information is no longer guaranteed!\n", PCF8563_NAME);
1505 + }
1506
1507 - tm->tm_year = BCD_TO_BIN(tm->tm_year) + ((tm->tm_mon & 0x80) ? 100 : 0);
1508 - tm->tm_sec &= 0x7f;
1509 - tm->tm_min &= 0x7f;
1510 - tm->tm_hour &= 0x3f;
1511 - tm->tm_mday &= 0x3f;
1512 - tm->tm_mon &= 0x1f;
1513 + tm->tm_year = BCD_TO_BIN(tm->tm_year) +
1514 + ((tm->tm_mon & 0x80) ? 100 : 0);
1515 + tm->tm_sec &= 0x7F;
1516 + tm->tm_min &= 0x7F;
1517 + tm->tm_hour &= 0x3F;
1518 + tm->tm_mday &= 0x3F;
1519 + tm->tm_wday &= 0x07; /* Not coded in BCD. */
1520 + tm->tm_mon &= 0x1F;
1521
1522 BCD_TO_BIN(tm->tm_sec);
1523 BCD_TO_BIN(tm->tm_min);
1524 @@ -126,17 +137,25 @@
1525 int __init
1526 pcf8563_init(void)
1527 {
1528 - int ret;
1529 + static int res = 0;
1530 + static int first = 1;
1531 +
1532 + if (!first) {
1533 + return res;
1534 + }
1535 + first = 0;
1536
1537 - if ((ret = i2c_init())) {
1538 - printk(KERN_CRIT "pcf8563_init: failed to init i2c\n");
1539 - return ret;
1540 + /* Initiate the i2c protocol. */
1541 + res = i2c_init();
1542 + if (res < 0) {
1543 + printk(KERN_CRIT "pcf8563_init: Failed to init i2c.\n");
1544 + return res;
1545 }
1546
1547 /*
1548 * First of all we need to reset the chip. This is done by
1549 - * clearing control1, control2 and clk freq, clear the
1550 - * Voltage Low bit, and resetting all alarms.
1551 + * clearing control1, control2 and clk freq and resetting
1552 + * all alarms.
1553 */
1554 if (rtc_write(RTC_CONTROL1, 0x00) < 0)
1555 goto err;
1556 @@ -147,41 +166,44 @@
1557 if (rtc_write(RTC_CLOCKOUT_FREQ, 0x00) < 0)
1558 goto err;
1559
1560 - /* Clear the VL bit in the seconds register. */
1561 - ret = rtc_read(RTC_SECONDS);
1562 -
1563 - if (rtc_write(RTC_SECONDS, (ret & 0x7f)) < 0)
1564 + if (rtc_write(RTC_TIMER_CONTROL, 0x03) < 0)
1565 goto err;
1566 -
1567 +
1568 /* Reset the alarms. */
1569 - if (rtc_write(RTC_MINUTE_ALARM, 0x00) < 0)
1570 + if (rtc_write(RTC_MINUTE_ALARM, 0x80) < 0)
1571 goto err;
1572 -
1573 - if (rtc_write(RTC_HOUR_ALARM, 0x00) < 0)
1574 +
1575 + if (rtc_write(RTC_HOUR_ALARM, 0x80) < 0)
1576 goto err;
1577 -
1578 - if (rtc_write(RTC_DAY_ALARM, 0x00) < 0)
1579 +
1580 + if (rtc_write(RTC_DAY_ALARM, 0x80) < 0)
1581 goto err;
1582 -
1583 - if (rtc_write(RTC_WEEKDAY_ALARM, 0x00) < 0)
1584 +
1585 + if (rtc_write(RTC_WEEKDAY_ALARM, 0x80) < 0)
1586 goto err;
1587 -
1588 - /* Check for low voltage, and warn about it.. */
1589 - if (rtc_read(RTC_SECONDS) & 0x80)
1590 - printk(KERN_WARNING "%s: RTC Low Voltage - date/time is not reliable!\n", PCF8563_NAME);
1591 -
1592 - return 0;
1593 +
1594 + /* Check for low voltage, and warn about it. */
1595 + if (rtc_read(RTC_SECONDS) & 0x80) {
1596 + voltage_low = 1;
1597 + printk(KERN_WARNING "%s: RTC Voltage Low - reliable "
1598 + "date/time information is no longer guaranteed!\n",
1599 + PCF8563_NAME);
1600 + }
1601 +
1602 + return res;
1603
1604 err:
1605 printk(KERN_INFO "%s: Error initializing chip.\n", PCF8563_NAME);
1606 - return -1;
1607 + res = -1;
1608 + return res;
1609 }
1610
1611 void __exit
1612 pcf8563_exit(void)
1613 {
1614 if (unregister_chrdev(PCF8563_MAJOR, DEVICE_NAME) < 0) {
1615 - printk(KERN_INFO "%s: Unable to unregister device.\n", PCF8563_NAME);
1616 + printk(KERN_INFO "%s: Unable to unregister device.\n",
1617 + PCF8563_NAME);
1618 }
1619 }
1620
1621 @@ -190,7 +212,8 @@
1622 * POSIX says so!
1623 */
1624 int
1625 -pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
1626 +pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
1627 + unsigned long arg)
1628 {
1629 /* Some sanity checks. */
1630 if (_IOC_TYPE(cmd) != RTC_MAGIC)
1631 @@ -201,123 +224,151 @@
1632
1633 switch (cmd) {
1634 case RTC_RD_TIME:
1635 - {
1636 - struct rtc_time tm;
1637 -
1638 - spin_lock(&rtc_lock);
1639 - get_rtc_time(&tm);
1640 + {
1641 + struct rtc_time tm;
1642
1643 - if (copy_to_user((struct rtc_time *) arg, &tm, sizeof(struct rtc_time))) {
1644 - spin_unlock(&rtc_lock);
1645 - return -EFAULT;
1646 - }
1647 + spin_lock(&rtc_lock);
1648 + memset(&tm, 0, sizeof tm);
1649 + get_rtc_time(&tm);
1650
1651 + if (copy_to_user((struct rtc_time *) arg, &tm,
1652 + sizeof tm)) {
1653 spin_unlock(&rtc_lock);
1654 - return 0;
1655 + return -EFAULT;
1656 }
1657 - break;
1658 +
1659 + spin_unlock(&rtc_lock);
1660 +
1661 + return 0;
1662 + }
1663 case RTC_SET_TIME:
1664 - {
1665 -#ifdef CONFIG_ETRAX_RTC_READONLY
1666 + {
1667 + int leap;
1668 + int year;
1669 + int century;
1670 + struct rtc_time tm;
1671 +
1672 + memset(&tm, 0, sizeof tm);
1673 + if (!capable(CAP_SYS_TIME))
1674 return -EPERM;
1675 -#else
1676 - int leap;
1677 - int century;
1678 - struct rtc_time tm;
1679 -
1680 - memset(&tm, 0, sizeof (struct rtc_time));
1681 - if (!capable(CAP_SYS_TIME))
1682 - return -EPERM;
1683 -
1684 - if (copy_from_user(&tm, (struct rtc_time *) arg, sizeof(struct rtc_time)))
1685 - return -EFAULT;
1686 -
1687 - /* Convert from struct tm to struct rtc_time. */
1688 - tm.tm_year += 1900;
1689 - tm.tm_mon += 1;
1690 -
1691 - leap = ((tm.tm_mon == 2) && ((tm.tm_year % 4) == 0)) ? 1 : 0;
1692 -
1693 - /* Perform some sanity checks. */
1694 - if ((tm.tm_year < 1970) ||
1695 - (tm.tm_mon > 12) ||
1696 - (tm.tm_mday == 0) ||
1697 - (tm.tm_mday > days_in_month[tm.tm_mon] + leap) ||
1698 - (tm.tm_hour >= 24) ||
1699 - (tm.tm_min >= 60) ||
1700 - (tm.tm_sec >= 60))
1701 - return -EINVAL;
1702 -
1703 - century = (tm.tm_year >= 2000) ? 0x80 : 0;
1704 - tm.tm_year = tm.tm_year % 100;
1705 -
1706 - BIN_TO_BCD(tm.tm_year);
1707 - BIN_TO_BCD(tm.tm_mday);
1708 - BIN_TO_BCD(tm.tm_hour);
1709 - BIN_TO_BCD(tm.tm_min);
1710 - BIN_TO_BCD(tm.tm_sec);
1711 - tm.tm_mon |= century;
1712 -
1713 - spin_lock(&rtc_lock);
1714 -
1715 - rtc_write(RTC_YEAR, tm.tm_year);
1716 - rtc_write(RTC_MONTH, tm.tm_mon);
1717 - rtc_write(RTC_DAY_OF_MONTH, tm.tm_mday);
1718 - rtc_write(RTC_HOURS, tm.tm_hour);
1719 - rtc_write(RTC_MINUTES, tm.tm_min);
1720 - rtc_write(RTC_SECONDS, tm.tm_sec);
1721
1722 - spin_unlock(&rtc_lock);
1723 + if (copy_from_user(&tm, (struct rtc_time *) arg,
1724 + sizeof tm)) {
1725 + return -EFAULT;
1726 + }
1727
1728 - return 0;
1729 -#endif /* !CONFIG_ETRAX_RTC_READONLY */
1730 + /* Convert from struct tm to struct rtc_time. */
1731 + tm.tm_year += 1900;
1732 + tm.tm_mon += 1;
1733 +
1734 + /*
1735 + * Check if tm.tm_year is a leap year. A year is a leap
1736 + * year if it is divisible by 4 but not 100, except
1737 + * that years divisible by 400 _are_ leap years.
1738 + */
1739 + year = tm.tm_year;
1740 + leap = (tm.tm_mon == 2) &&
1741 + ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0);
1742 +
1743 + /* Perform some sanity checks. */
1744 + if ((tm.tm_year < 1970) ||
1745 + (tm.tm_mon > 12) ||
1746 + (tm.tm_mday == 0) ||
1747 + (tm.tm_mday > days_in_month[tm.tm_mon] + leap) ||
1748 + (tm.tm_wday >= 7) ||
1749 + (tm.tm_hour >= 24) ||
1750 + (tm.tm_min >= 60) ||
1751 + (tm.tm_sec >= 60)) {
1752 + return -EINVAL;
1753 }
1754
1755 - case RTC_VLOW_RD:
1756 - {
1757 - int vl_bit = 0;
1758 + century = (tm.tm_year >= 2000) ? 0x80 : 0;
1759 + tm.tm_year = tm.tm_year % 100;
1760
1761 - if (rtc_read(RTC_SECONDS) & 0x80) {
1762 - vl_bit = 1;
1763 - printk(KERN_WARNING "%s: RTC Voltage Low - reliable "
1764 - "date/time information is no longer guaranteed!\n",
1765 - PCF8563_NAME);
1766 - }
1767 - if (copy_to_user((int *) arg, &vl_bit, sizeof(int)))
1768 - return -EFAULT;
1769 + BIN_TO_BCD(tm.tm_year);
1770 + BIN_TO_BCD(tm.tm_mon);
1771 + BIN_TO_BCD(tm.tm_mday);
1772 + BIN_TO_BCD(tm.tm_hour);
1773 + BIN_TO_BCD(tm.tm_min);
1774 + BIN_TO_BCD(tm.tm_sec);
1775 + tm.tm_mon |= century;
1776 +
1777 + spin_lock(&rtc_lock);
1778 +
1779 + rtc_write(RTC_YEAR, tm.tm_year);
1780 + rtc_write(RTC_MONTH, tm.tm_mon);
1781 + rtc_write(RTC_WEEKDAY, tm.tm_wday); /* Not coded in BCD. */
1782 + rtc_write(RTC_DAY_OF_MONTH, tm.tm_mday);
1783 + rtc_write(RTC_HOURS, tm.tm_hour);
1784 + rtc_write(RTC_MINUTES, tm.tm_min);
1785 + rtc_write(RTC_SECONDS, tm.tm_sec);
1786 +
1787 + spin_unlock(&rtc_lock);
1788
1789 return 0;
1790 }
1791 + case RTC_VLOW_RD:
1792 + if (voltage_low) {
1793 + printk(KERN_WARNING "%s: RTC Voltage Low - "
1794 + "reliable date/time information is no "
1795 + "longer guaranteed!\n", PCF8563_NAME);
1796 + }
1797 +
1798 + if (copy_to_user((int *) arg, &voltage_low, sizeof(int))) {
1799 + return -EFAULT;
1800 + }
1801 +
1802 + return 0;
1803
1804 case RTC_VLOW_SET:
1805 {
1806 - /* Clear the VL bit in the seconds register */
1807 + /* Clear the VL bit in the seconds register in case
1808 + * the time has not been set already (which would
1809 + * have cleared it). This does not really matter
1810 + * because of the cached voltage_low value but do it
1811 + * anyway for consistency. */
1812 +
1813 int ret = rtc_read(RTC_SECONDS);
1814
1815 rtc_write(RTC_SECONDS, (ret & 0x7F));
1816
1817 + /* Clear the cached value. */
1818 + voltage_low = 0;
1819 +
1820 return 0;
1821 }
1822 -
1823 default:
1824 - return -ENOTTY;
1825 + return -ENOTTY;
1826 }
1827
1828 return 0;
1829 }
1830
1831 -static int __init
1832 +static int __init
1833 pcf8563_register(void)
1834 {
1835 - pcf8563_init();
1836 + if (pcf8563_init() < 0) {
1837 + printk(KERN_INFO "%s: Unable to initialize Real-Time Clock "
1838 + "Driver, %s\n", PCF8563_NAME, DRIVER_VERSION);
1839 + return -1;
1840 + }
1841 +
1842 if (register_chrdev(PCF8563_MAJOR, DEVICE_NAME, &pcf8563_fops) < 0) {
1843 - printk(KERN_INFO "%s: Unable to get major numer %d for RTC device.\n",
1844 - PCF8563_NAME, PCF8563_MAJOR);
1845 + printk(KERN_INFO "%s: Unable to get major numer %d for RTC "
1846 + "device.\n", PCF8563_NAME, PCF8563_MAJOR);
1847 return -1;
1848 }
1849
1850 - printk(KERN_INFO "%s Real-Time Clock Driver, %s\n", PCF8563_NAME, DRIVER_VERSION);
1851 - return 0;
1852 + printk(KERN_INFO "%s Real-Time Clock Driver, %s\n", PCF8563_NAME,
1853 + DRIVER_VERSION);
1854 +
1855 + /* Check for low voltage, and warn about it. */
1856 + if (voltage_low) {
1857 + printk(KERN_WARNING "%s: RTC Voltage Low - reliable date/time "
1858 + "information is no longer guaranteed!\n", PCF8563_NAME);
1859 + }
1860 +
1861 + return 0;
1862 }
1863
1864 module_init(pcf8563_register);
1865 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/drivers/sync_serial.c linux-2.6.19.2.dev/arch/cris/arch-v10/drivers/sync_serial.c
1866 --- linux-2.6.19.2.old/arch/cris/arch-v10/drivers/sync_serial.c 1970-01-01 01:00:00.000000000 +0100
1867 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/drivers/sync_serial.c 2007-02-05 12:56:34.000000000 +0100
1868 @@ -0,0 +1,1329 @@
1869 +/*
1870 + * Simple synchronous serial port driver for ETRAX 100LX.
1871 + *
1872 + * Synchronous serial ports are used for continuous streamed data like audio.
1873 + * The default setting for this driver is compatible with the STA 013 MP3
1874 + * decoder. The driver can easily be tuned to fit other audio encoder/decoders
1875 + * and SPI
1876 + *
1877 + * Copyright (c) 2001-2006 Axis Communications AB
1878 + *
1879 + * Author: Mikael Starvik, Johan Adolfsson
1880 + *
1881 + */
1882 +#include <linux/module.h>
1883 +#include <linux/kernel.h>
1884 +#include <linux/types.h>
1885 +#include <linux/errno.h>
1886 +#include <linux/major.h>
1887 +#include <linux/sched.h>
1888 +#include <linux/slab.h>
1889 +#include <linux/interrupt.h>
1890 +#include <linux/poll.h>
1891 +#include <linux/init.h>
1892 +#include <linux/timer.h>
1893 +#include <asm/irq.h>
1894 +#include <asm/dma.h>
1895 +#include <asm/io.h>
1896 +#include <asm/arch/svinto.h>
1897 +#include <asm/uaccess.h>
1898 +#include <asm/system.h>
1899 +#include <asm/sync_serial.h>
1900 +#include <asm/arch/io_interface_mux.h>
1901 +
1902 +/* The receiver is a bit tricky beacuse of the continuous stream of data.*/
1903 +/* */
1904 +/* Three DMA descriptors are linked together. Each DMA descriptor is */
1905 +/* responsible for port->bufchunk of a common buffer. */
1906 +/* */
1907 +/* +---------------------------------------------+ */
1908 +/* | +----------+ +----------+ +----------+ | */
1909 +/* +-> | Descr[0] |-->| Descr[1] |-->| Descr[2] |-+ */
1910 +/* +----------+ +----------+ +----------+ */
1911 +/* | | | */
1912 +/* v v v */
1913 +/* +-------------------------------------+ */
1914 +/* | BUFFER | */
1915 +/* +-------------------------------------+ */
1916 +/* |<- data_avail ->| */
1917 +/* readp writep */
1918 +/* */
1919 +/* If the application keeps up the pace readp will be right after writep.*/
1920 +/* If the application can't keep the pace we have to throw away data. */
1921 +/* The idea is that readp should be ready with the data pointed out by */
1922 +/* Descr[i] when the DMA has filled in Descr[i+1]. */
1923 +/* Otherwise we will discard */
1924 +/* the rest of the data pointed out by Descr1 and set readp to the start */
1925 +/* of Descr2 */
1926 +
1927 +#define SYNC_SERIAL_MAJOR 125
1928 +
1929 +/* IN_BUFFER_SIZE should be a multiple of 6 to make sure that 24 bit */
1930 +/* words can be handled */
1931 +#define IN_BUFFER_SIZE 12288
1932 +#define IN_DESCR_SIZE 256
1933 +#define NUM_IN_DESCR (IN_BUFFER_SIZE/IN_DESCR_SIZE)
1934 +#define OUT_BUFFER_SIZE 4096
1935 +
1936 +#define DEFAULT_FRAME_RATE 0
1937 +#define DEFAULT_WORD_RATE 7
1938 +
1939 +/* NOTE: Enabling some debug will likely cause overrun or underrun,
1940 + * especially if manual mode is use.
1941 + */
1942 +#define DEBUG(x)
1943 +#define DEBUGREAD(x)
1944 +#define DEBUGWRITE(x)
1945 +#define DEBUGPOLL(x)
1946 +#define DEBUGRXINT(x)
1947 +#define DEBUGTXINT(x)
1948 +
1949 +/* Define some macros to access ETRAX 100 registers */
1950 +#define SETF(var, reg, field, val) var = (var & ~IO_MASK_(reg##_, field##_)) | \
1951 + IO_FIELD_(reg##_, field##_, val)
1952 +#define SETS(var, reg, field, val) var = (var & ~IO_MASK_(reg##_, field##_)) | \
1953 + IO_STATE_(reg##_, field##_, _##val)
1954 +
1955 +typedef struct sync_port
1956 +{
1957 + /* Etrax registers and bits*/
1958 + const volatile unsigned * const status;
1959 + volatile unsigned * const ctrl_data;
1960 + volatile unsigned * const output_dma_first;
1961 + volatile unsigned char * const output_dma_cmd;
1962 + volatile unsigned char * const output_dma_clr_irq;
1963 + volatile unsigned * const input_dma_first;
1964 + volatile unsigned char * const input_dma_cmd;
1965 + volatile unsigned * const input_dma_descr;
1966 + /* 8*4 */
1967 + volatile unsigned char * const input_dma_clr_irq;
1968 + volatile unsigned * const data_out;
1969 + const volatile unsigned * const data_in;
1970 + char data_avail_bit; /* In R_IRQ_MASK1_RD/SET/CLR */
1971 + char transmitter_ready_bit; /* In R_IRQ_MASK1_RD/SET/CLR */
1972 + char input_dma_descr_bit; /* In R_IRQ_MASK2_RD */
1973 +
1974 + char output_dma_bit; /* In R_IRQ_MASK2_RD */
1975 + /* End of fields initialised in array */
1976 + char started; /* 1 if port has been started */
1977 + char port_nbr; /* Port 0 or 1 */
1978 + char busy; /* 1 if port is busy */
1979 +
1980 + char enabled; /* 1 if port is enabled */
1981 + char use_dma; /* 1 if port uses dma */
1982 + char tr_running;
1983 +
1984 + char init_irqs;
1985 +
1986 + unsigned int ctrl_data_shadow; /* Register shadow */
1987 + volatile unsigned int out_count; /* Remaining bytes for current transfer */
1988 + unsigned char* outp; /* Current position in out_buffer */
1989 + /* 16*4 */
1990 + volatile unsigned char* volatile readp; /* Next byte to be read by application */
1991 + volatile unsigned char* volatile writep; /* Next byte to be written by etrax */
1992 + unsigned int in_buffer_size;
1993 + unsigned int inbufchunk;
1994 + struct etrax_dma_descr out_descr __attribute__ ((aligned(32)));
1995 + struct etrax_dma_descr in_descr[NUM_IN_DESCR] __attribute__ ((aligned(32)));
1996 + unsigned char out_buffer[OUT_BUFFER_SIZE] __attribute__ ((aligned(32)));
1997 + unsigned char in_buffer[IN_BUFFER_SIZE]__attribute__ ((aligned(32)));
1998 + unsigned char flip[IN_BUFFER_SIZE] __attribute__ ((aligned(32)));
1999 + struct etrax_dma_descr* next_rx_desc;
2000 + struct etrax_dma_descr* prev_rx_desc;
2001 + int full;
2002 +
2003 + wait_queue_head_t out_wait_q;
2004 + wait_queue_head_t in_wait_q;
2005 +} sync_port;
2006 +
2007 +
2008 +static int etrax_sync_serial_init(void);
2009 +static void initialize_port(int portnbr);
2010 +static inline int sync_data_avail(struct sync_port *port);
2011 +
2012 +static int sync_serial_open(struct inode *, struct file*);
2013 +static int sync_serial_release(struct inode*, struct file*);
2014 +static unsigned int sync_serial_poll(struct file *filp, poll_table *wait);
2015 +
2016 +static int sync_serial_ioctl(struct inode*, struct file*,
2017 + unsigned int cmd, unsigned long arg);
2018 +static ssize_t sync_serial_write(struct file * file, const char * buf,
2019 + size_t count, loff_t *ppos);
2020 +static ssize_t sync_serial_read(struct file *file, char *buf,
2021 + size_t count, loff_t *ppos);
2022 +
2023 +#if (defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0) && \
2024 + defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL0_DMA)) || \
2025 + (defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1) && \
2026 + defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL1_DMA))
2027 +#define SYNC_SER_DMA
2028 +#endif
2029 +
2030 +static void send_word(sync_port* port);
2031 +static void start_dma(struct sync_port *port, const char* data, int count);
2032 +static void start_dma_in(sync_port* port);
2033 +#ifdef SYNC_SER_DMA
2034 +static irqreturn_t tr_interrupt(int irq, void *dev_id);
2035 +static irqreturn_t rx_interrupt(int irq, void *dev_id);
2036 +#endif
2037 +#if (defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0) && \
2038 + !defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL0_DMA)) || \
2039 + (defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1) && \
2040 + !defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL1_DMA))
2041 +#define SYNC_SER_MANUAL
2042 +#endif
2043 +#ifdef SYNC_SER_MANUAL
2044 +static irqreturn_t manual_interrupt(int irq, void *dev_id);
2045 +#endif
2046 +
2047 +/* The ports */
2048 +static struct sync_port ports[]=
2049 +{
2050 + {
2051 + .status = R_SYNC_SERIAL1_STATUS,
2052 + .ctrl_data = R_SYNC_SERIAL1_CTRL,
2053 + .output_dma_first = R_DMA_CH8_FIRST,
2054 + .output_dma_cmd = R_DMA_CH8_CMD,
2055 + .output_dma_clr_irq = R_DMA_CH8_CLR_INTR,
2056 + .input_dma_first = R_DMA_CH9_FIRST,
2057 + .input_dma_cmd = R_DMA_CH9_CMD,
2058 + .input_dma_descr = R_DMA_CH9_DESCR,
2059 + .input_dma_clr_irq = R_DMA_CH9_CLR_INTR,
2060 + .data_out = R_SYNC_SERIAL1_TR_DATA,
2061 + .data_in = R_SYNC_SERIAL1_REC_DATA,
2062 + .data_avail_bit = IO_BITNR(R_IRQ_MASK1_RD, ser1_data),
2063 + .transmitter_ready_bit = IO_BITNR(R_IRQ_MASK1_RD, ser1_ready),
2064 + .input_dma_descr_bit = IO_BITNR(R_IRQ_MASK2_RD, dma9_descr),
2065 + .output_dma_bit = IO_BITNR(R_IRQ_MASK2_RD, dma8_eop),
2066 + .init_irqs = 1,
2067 +#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL0_DMA)
2068 + .use_dma = 1,
2069 +#else
2070 + .use_dma = 0,
2071 +#endif
2072 + },
2073 + {
2074 + .status = R_SYNC_SERIAL3_STATUS,
2075 + .ctrl_data = R_SYNC_SERIAL3_CTRL,
2076 + .output_dma_first = R_DMA_CH4_FIRST,
2077 + .output_dma_cmd = R_DMA_CH4_CMD,
2078 + .output_dma_clr_irq = R_DMA_CH4_CLR_INTR,
2079 + .input_dma_first = R_DMA_CH5_FIRST,
2080 + .input_dma_cmd = R_DMA_CH5_CMD,
2081 + .input_dma_descr = R_DMA_CH5_DESCR,
2082 + .input_dma_clr_irq = R_DMA_CH5_CLR_INTR,
2083 + .data_out = R_SYNC_SERIAL3_TR_DATA,
2084 + .data_in = R_SYNC_SERIAL3_REC_DATA,
2085 + .data_avail_bit = IO_BITNR(R_IRQ_MASK1_RD, ser3_data),
2086 + .transmitter_ready_bit = IO_BITNR(R_IRQ_MASK1_RD, ser3_ready),
2087 + .input_dma_descr_bit = IO_BITNR(R_IRQ_MASK2_RD, dma5_descr),
2088 + .output_dma_bit = IO_BITNR(R_IRQ_MASK2_RD, dma4_eop),
2089 + .init_irqs = 1,
2090 +#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL1_DMA)
2091 + .use_dma = 1,
2092 +#else
2093 + .use_dma = 0,
2094 +#endif
2095 + }
2096 +};
2097 +
2098 +/* Register shadows */
2099 +static unsigned sync_serial_prescale_shadow = 0;
2100 +
2101 +#define NUMBER_OF_PORTS (sizeof(ports)/sizeof(sync_port))
2102 +
2103 +static struct file_operations sync_serial_fops = {
2104 + .owner = THIS_MODULE,
2105 + .write = sync_serial_write,
2106 + .read = sync_serial_read,
2107 + .poll = sync_serial_poll,
2108 + .ioctl = sync_serial_ioctl,
2109 + .open = sync_serial_open,
2110 + .release = sync_serial_release
2111 +};
2112 +
2113 +static int __init etrax_sync_serial_init(void)
2114 +{
2115 + ports[0].enabled = 0;
2116 + ports[1].enabled = 0;
2117 +
2118 +#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0)
2119 + if (cris_request_io_interface(if_sync_serial_1, "sync_ser1")) {
2120 + printk(KERN_CRIT "ETRAX100LX sync_serial: Could not allocate IO group for port %d\n", 0);
2121 + return -EBUSY;
2122 + }
2123 +#endif
2124 +#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1)
2125 + if (cris_request_io_interface(if_sync_serial_3, "sync_ser3")) {
2126 +#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0)
2127 + cris_free_io_interface(if_sync_serial_1);
2128 +#endif
2129 + printk(KERN_CRIT "ETRAX100LX sync_serial: Could not allocate IO group for port %d\n", 1);
2130 + return -EBUSY;
2131 + }
2132 +#endif
2133 +
2134 + if (register_chrdev(SYNC_SERIAL_MAJOR,"sync serial", &sync_serial_fops) <0 )
2135 + {
2136 +#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1)
2137 + cris_free_io_interface(if_sync_serial_3);
2138 +#endif
2139 +#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0)
2140 + cris_free_io_interface(if_sync_serial_1);
2141 +#endif
2142 + printk("unable to get major for synchronous serial port\n");
2143 + return -EBUSY;
2144 + }
2145 +
2146 + /* Deselect synchronous serial ports while configuring. */
2147 + SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode1, async);
2148 + SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode3, async);
2149 + *R_GEN_CONFIG_II = gen_config_ii_shadow;
2150 +
2151 + /* Initialize Ports */
2152 +#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0)
2153 + ports[0].enabled = 1;
2154 + SETS(port_pb_i2c_shadow, R_PORT_PB_I2C, syncser1, ss1extra);
2155 + SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode1, sync);
2156 +#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL0_DMA)
2157 + ports[0].use_dma = 1;
2158 +#else
2159 + ports[0].use_dma = 0;
2160 +#endif
2161 + initialize_port(0);
2162 +#endif
2163 +
2164 +#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1)
2165 + ports[1].enabled = 1;
2166 + SETS(port_pb_i2c_shadow, R_PORT_PB_I2C, syncser3, ss3extra);
2167 + SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode3, sync);
2168 +#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL1_DMA)
2169 + ports[1].use_dma = 1;
2170 +#else
2171 + ports[1].use_dma = 0;
2172 +#endif
2173 + initialize_port(1);
2174 +#endif
2175 +
2176 + *R_PORT_PB_I2C = port_pb_i2c_shadow; /* Use PB4/PB7 */
2177 +
2178 + /* Set up timing */
2179 + *R_SYNC_SERIAL_PRESCALE = sync_serial_prescale_shadow = (
2180 + IO_STATE(R_SYNC_SERIAL_PRESCALE, clk_sel_u1, codec) |
2181 + IO_STATE(R_SYNC_SERIAL_PRESCALE, word_stb_sel_u1, external) |
2182 + IO_STATE(R_SYNC_SERIAL_PRESCALE, clk_sel_u3, codec) |
2183 + IO_STATE(R_SYNC_SERIAL_PRESCALE, word_stb_sel_u3, external) |
2184 + IO_STATE(R_SYNC_SERIAL_PRESCALE, prescaler, div4) |
2185 + IO_FIELD(R_SYNC_SERIAL_PRESCALE, frame_rate, DEFAULT_FRAME_RATE) |
2186 + IO_FIELD(R_SYNC_SERIAL_PRESCALE, word_rate, DEFAULT_WORD_RATE) |
2187 + IO_STATE(R_SYNC_SERIAL_PRESCALE, warp_mode, normal));
2188 +
2189 + /* Select synchronous ports */
2190 + *R_GEN_CONFIG_II = gen_config_ii_shadow;
2191 +
2192 + printk("ETRAX 100LX synchronous serial port driver\n");
2193 + return 0;
2194 +}
2195 +
2196 +static void __init initialize_port(int portnbr)
2197 +{
2198 + struct sync_port* port = &ports[portnbr];
2199 +
2200 + DEBUG(printk("Init sync serial port %d\n", portnbr));
2201 +
2202 + port->started = 0;
2203 + port->port_nbr = portnbr;
2204 + port->busy = 0;
2205 + port->tr_running = 0;
2206 +
2207 + port->out_count = 0;
2208 + port->outp = port->out_buffer;
2209 +
2210 + port->readp = port->flip;
2211 + port->writep = port->flip;
2212 + port->in_buffer_size = IN_BUFFER_SIZE;
2213 + port->inbufchunk = IN_DESCR_SIZE;
2214 + port->next_rx_desc = &port->in_descr[0];
2215 + port->prev_rx_desc = &port->in_descr[NUM_IN_DESCR-1];
2216 + port->prev_rx_desc->ctrl = d_eol;
2217 +
2218 + init_waitqueue_head(&port->out_wait_q);
2219 + init_waitqueue_head(&port->in_wait_q);
2220 +
2221 + port->ctrl_data_shadow =
2222 + IO_STATE(R_SYNC_SERIAL1_CTRL, tr_baud, c115k2Hz) |
2223 + IO_STATE(R_SYNC_SERIAL1_CTRL, mode, master_output) |
2224 + IO_STATE(R_SYNC_SERIAL1_CTRL, error, ignore) |
2225 + IO_STATE(R_SYNC_SERIAL1_CTRL, rec_enable, disable) |
2226 + IO_STATE(R_SYNC_SERIAL1_CTRL, f_synctype, normal) |
2227 + IO_STATE(R_SYNC_SERIAL1_CTRL, f_syncsize, word) |
2228 + IO_STATE(R_SYNC_SERIAL1_CTRL, f_sync, on) |
2229 + IO_STATE(R_SYNC_SERIAL1_CTRL, clk_mode, normal) |
2230 + IO_STATE(R_SYNC_SERIAL1_CTRL, clk_halt, stopped) |
2231 + IO_STATE(R_SYNC_SERIAL1_CTRL, bitorder, msb) |
2232 + IO_STATE(R_SYNC_SERIAL1_CTRL, tr_enable, disable) |
2233 + IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size8bit) |
2234 + IO_STATE(R_SYNC_SERIAL1_CTRL, buf_empty, lmt_8) |
2235 + IO_STATE(R_SYNC_SERIAL1_CTRL, buf_full, lmt_8) |
2236 + IO_STATE(R_SYNC_SERIAL1_CTRL, flow_ctrl, enabled) |
2237 + IO_STATE(R_SYNC_SERIAL1_CTRL, clk_polarity, neg) |
2238 + IO_STATE(R_SYNC_SERIAL1_CTRL, frame_polarity, normal)|
2239 + IO_STATE(R_SYNC_SERIAL1_CTRL, status_polarity, inverted)|
2240 + IO_STATE(R_SYNC_SERIAL1_CTRL, clk_driver, normal) |
2241 + IO_STATE(R_SYNC_SERIAL1_CTRL, frame_driver, normal) |
2242 + IO_STATE(R_SYNC_SERIAL1_CTRL, status_driver, normal)|
2243 + IO_STATE(R_SYNC_SERIAL1_CTRL, def_out0, high);
2244 +
2245 + if (port->use_dma)
2246 + port->ctrl_data_shadow |= IO_STATE(R_SYNC_SERIAL1_CTRL, dma_enable, on);
2247 + else
2248 + port->ctrl_data_shadow |= IO_STATE(R_SYNC_SERIAL1_CTRL, dma_enable, off);
2249 +
2250 + *port->ctrl_data = port->ctrl_data_shadow;
2251 +}
2252 +
2253 +static inline int sync_data_avail(struct sync_port *port)
2254 +{
2255 + int avail;
2256 + unsigned char *start;
2257 + unsigned char *end;
2258 +
2259 + start = (unsigned char*)port->readp; /* cast away volatile */
2260 + end = (unsigned char*)port->writep; /* cast away volatile */
2261 + /* 0123456789 0123456789
2262 + * ----- - -----
2263 + * ^rp ^wp ^wp ^rp
2264 + */
2265 +
2266 + if (end >= start)
2267 + avail = end - start;
2268 + else
2269 + avail = port->in_buffer_size - (start - end);
2270 + return avail;
2271 +}
2272 +
2273 +static inline int sync_data_avail_to_end(struct sync_port *port)
2274 +{
2275 + int avail;
2276 + unsigned char *start;
2277 + unsigned char *end;
2278 +
2279 + start = (unsigned char*)port->readp; /* cast away volatile */
2280 + end = (unsigned char*)port->writep; /* cast away volatile */
2281 + /* 0123456789 0123456789
2282 + * ----- -----
2283 + * ^rp ^wp ^wp ^rp
2284 + */
2285 +
2286 + if (end >= start)
2287 + avail = end - start;
2288 + else
2289 + avail = port->flip + port->in_buffer_size - start;
2290 + return avail;
2291 +}
2292 +
2293 +
2294 +static int sync_serial_open(struct inode *inode, struct file *file)
2295 +{
2296 + int dev = MINOR(inode->i_rdev);
2297 + sync_port* port;
2298 + int mode;
2299 +
2300 + DEBUG(printk("Open sync serial port %d\n", dev));
2301 +
2302 + if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled)
2303 + {
2304 + DEBUG(printk("Invalid minor %d\n", dev));
2305 + return -ENODEV;
2306 + }
2307 + port = &ports[dev];
2308 + /* Allow open this device twice (assuming one reader and one writer) */
2309 + if (port->busy == 2)
2310 + {
2311 + DEBUG(printk("Device is busy.. \n"));
2312 + return -EBUSY;
2313 + }
2314 + if (port->init_irqs) {
2315 + if (port->use_dma) {
2316 + if (port == &ports[0]){
2317 +#ifdef SYNC_SER_DMA
2318 + if(request_irq(24,
2319 + tr_interrupt,
2320 + 0,
2321 + "synchronous serial 1 dma tr",
2322 + &ports[0])) {
2323 + printk(KERN_CRIT "Can't allocate sync serial port 1 IRQ");
2324 + return -EBUSY;
2325 + } else if(request_irq(25,
2326 + rx_interrupt,
2327 + 0,
2328 + "synchronous serial 1 dma rx",
2329 + &ports[0])) {
2330 + free_irq(24, &port[0]);
2331 + printk(KERN_CRIT "Can't allocate sync serial port 1 IRQ");
2332 + return -EBUSY;
2333 + } else if (cris_request_dma(8,
2334 + "synchronous serial 1 dma tr",
2335 + DMA_VERBOSE_ON_ERROR,
2336 + dma_ser1)) {
2337 + free_irq(24, &port[0]);
2338 + free_irq(25, &port[0]);
2339 + printk(KERN_CRIT "Can't allocate sync serial port 1 TX DMA channel");
2340 + return -EBUSY;
2341 + } else if (cris_request_dma(9,
2342 + "synchronous serial 1 dma rec",
2343 + DMA_VERBOSE_ON_ERROR,
2344 + dma_ser1)) {
2345 + cris_free_dma(8, NULL);
2346 + free_irq(24, &port[0]);
2347 + free_irq(25, &port[0]);
2348 + printk(KERN_CRIT "Can't allocate sync serial port 1 RX DMA channel");
2349 + return -EBUSY;
2350 + }
2351 +#endif
2352 + RESET_DMA(8); WAIT_DMA(8);
2353 + RESET_DMA(9); WAIT_DMA(9);
2354 + *R_DMA_CH8_CLR_INTR = IO_STATE(R_DMA_CH8_CLR_INTR, clr_eop, do) |
2355 + IO_STATE(R_DMA_CH8_CLR_INTR, clr_descr, do);
2356 + *R_DMA_CH9_CLR_INTR = IO_STATE(R_DMA_CH9_CLR_INTR, clr_eop, do) |
2357 + IO_STATE(R_DMA_CH9_CLR_INTR, clr_descr, do);
2358 + *R_IRQ_MASK2_SET =
2359 + IO_STATE(R_IRQ_MASK2_SET, dma8_eop, set) |
2360 + IO_STATE(R_IRQ_MASK2_SET, dma9_descr, set);
2361 + }
2362 + else if (port == &ports[1]){
2363 +#ifdef SYNC_SER_DMA
2364 + if (request_irq(20,
2365 + tr_interrupt,
2366 + 0,
2367 + "synchronous serial 3 dma tr",
2368 + &ports[1])) {
2369 + printk(KERN_CRIT "Can't allocate sync serial port 3 IRQ");
2370 + return -EBUSY;
2371 + } else if (request_irq(21,
2372 + rx_interrupt,
2373 + 0,
2374 + "synchronous serial 3 dma rx",
2375 + &ports[1])) {
2376 + free_irq(20, &ports[1]);
2377 + printk(KERN_CRIT "Can't allocate sync serial port 3 IRQ");
2378 + return -EBUSY;
2379 + } else if (cris_request_dma(4,
2380 + "synchronous serial 3 dma tr",
2381 + DMA_VERBOSE_ON_ERROR,
2382 + dma_ser3)) {
2383 + free_irq(21, &ports[1]);
2384 + free_irq(20, &ports[1]);
2385 + printk(KERN_CRIT "Can't allocate sync serial port 3 TX DMA channel");
2386 + return -EBUSY;
2387 + } else if (cris_request_dma(5,
2388 + "synchronous serial 3 dma rec",
2389 + DMA_VERBOSE_ON_ERROR,
2390 + dma_ser3)) {
2391 + cris_free_dma(4, NULL);
2392 + free_irq(21, &ports[1]);
2393 + free_irq(20, &ports[1]);
2394 + printk(KERN_CRIT "Can't allocate sync serial port 3 RX DMA channel");
2395 + return -EBUSY;
2396 + }
2397 +#endif
2398 + RESET_DMA(4); WAIT_DMA(4);
2399 + RESET_DMA(5); WAIT_DMA(5);
2400 + *R_DMA_CH4_CLR_INTR = IO_STATE(R_DMA_CH4_CLR_INTR, clr_eop, do) |
2401 + IO_STATE(R_DMA_CH4_CLR_INTR, clr_descr, do);
2402 + *R_DMA_CH5_CLR_INTR = IO_STATE(R_DMA_CH5_CLR_INTR, clr_eop, do) |
2403 + IO_STATE(R_DMA_CH5_CLR_INTR, clr_descr, do);
2404 + *R_IRQ_MASK2_SET =
2405 + IO_STATE(R_IRQ_MASK2_SET, dma4_eop, set) |
2406 + IO_STATE(R_IRQ_MASK2_SET, dma5_descr, set);
2407 + }
2408 + start_dma_in(port);
2409 + port->init_irqs = 0;
2410 + } else { /* !port->use_dma */
2411 +#ifdef SYNC_SER_MANUAL
2412 + if (port == &ports[0]) {
2413 + if (request_irq(8,
2414 + manual_interrupt,
2415 + IRQF_SHARED | IRQF_DISABLED,
2416 + "synchronous serial manual irq",
2417 + &ports[0])) {
2418 + printk("Can't allocate sync serial manual irq");
2419 + return -EBUSY;
2420 + }
2421 + } else if (port == &ports[1]) {
2422 + if (request_irq(8,
2423 + manual_interrupt,
2424 + IRQF_SHARED | IRQF_DISABLED,
2425 + "synchronous serial manual irq",
2426 + &ports[1])) {
2427 + printk(KERN_CRIT "Can't allocate sync serial manual irq");
2428 + return -EBUSY;
2429 + }
2430 + }
2431 + port->init_irqs = 0;
2432 +#else
2433 + panic("sync_serial: Manual mode not supported.\n");
2434 +#endif /* SYNC_SER_MANUAL */
2435 + }
2436 + } /* port->init_irqs */
2437 +
2438 + port->busy++;
2439 + /* Start port if we use it as input */
2440 + mode = IO_EXTRACT(R_SYNC_SERIAL1_CTRL, mode, port->ctrl_data_shadow);
2441 + if (mode == IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, mode, master_input) ||
2442 + mode == IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, mode, slave_input) ||
2443 + mode == IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, mode, master_bidir) ||
2444 + mode == IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, mode, slave_bidir)) {
2445 + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_halt, running);
2446 + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, tr_enable, enable);
2447 + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, rec_enable, enable);
2448 + port->started = 1;
2449 + *port->ctrl_data = port->ctrl_data_shadow;
2450 + if (!port->use_dma)
2451 + *R_IRQ_MASK1_SET = 1 << port->data_avail_bit;
2452 + DEBUG(printk("sser%d rec started\n", dev));
2453 + }
2454 + return 0;
2455 +}
2456 +
2457 +static int sync_serial_release(struct inode *inode, struct file *file)
2458 +{
2459 + int dev = MINOR(inode->i_rdev);
2460 + sync_port* port;
2461 +
2462 + if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled)
2463 + {
2464 + DEBUG(printk("Invalid minor %d\n", dev));
2465 + return -ENODEV;
2466 + }
2467 + port = &ports[dev];
2468 + if (port->busy)
2469 + port->busy--;
2470 + if (!port->busy)
2471 + *R_IRQ_MASK1_CLR = ((1 << port->data_avail_bit) |
2472 + (1 << port->transmitter_ready_bit));
2473 +
2474 + return 0;
2475 +}
2476 +
2477 +
2478 +
2479 +static unsigned int sync_serial_poll(struct file *file, poll_table *wait)
2480 +{
2481 + int dev = MINOR(file->f_dentry->d_inode->i_rdev);
2482 + unsigned int mask = 0;
2483 + sync_port* port;
2484 + DEBUGPOLL( static unsigned int prev_mask = 0; );
2485 +
2486 + port = &ports[dev];
2487 + poll_wait(file, &port->out_wait_q, wait);
2488 + poll_wait(file, &port->in_wait_q, wait);
2489 + /* Some room to write */
2490 + if (port->out_count < OUT_BUFFER_SIZE)
2491 + mask |= POLLOUT | POLLWRNORM;
2492 + /* At least an inbufchunk of data */
2493 + if (sync_data_avail(port) >= port->inbufchunk)
2494 + mask |= POLLIN | POLLRDNORM;
2495 +
2496 + DEBUGPOLL(if (mask != prev_mask)
2497 + printk("sync_serial_poll: mask 0x%08X %s %s\n", mask,
2498 + mask&POLLOUT?"POLLOUT":"", mask&POLLIN?"POLLIN":"");
2499 + prev_mask = mask;
2500 + );
2501 + return mask;
2502 +}
2503 +
2504 +static int sync_serial_ioctl(struct inode *inode, struct file *file,
2505 + unsigned int cmd, unsigned long arg)
2506 +{
2507 + int return_val = 0;
2508 + unsigned long flags;
2509 +
2510 + int dev = MINOR(file->f_dentry->d_inode->i_rdev);
2511 + sync_port* port;
2512 +
2513 + if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled)
2514 + {
2515 + DEBUG(printk("Invalid minor %d\n", dev));
2516 + return -1;
2517 + }
2518 + port = &ports[dev];
2519 +
2520 + local_irq_save(flags);
2521 + /* Disable port while changing config */
2522 + if (dev)
2523 + {
2524 + if (port->use_dma) {
2525 + RESET_DMA(4); WAIT_DMA(4);
2526 + port->tr_running = 0;
2527 + port->out_count = 0;
2528 + port->outp = port->out_buffer;
2529 + *R_DMA_CH4_CLR_INTR = IO_STATE(R_DMA_CH4_CLR_INTR, clr_eop, do) |
2530 + IO_STATE(R_DMA_CH4_CLR_INTR, clr_descr, do);
2531 + }
2532 + SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode3, async);
2533 + }
2534 + else
2535 + {
2536 + if (port->use_dma) {
2537 + RESET_DMA(8); WAIT_DMA(8);
2538 + port->tr_running = 0;
2539 + port->out_count = 0;
2540 + port->outp = port->out_buffer;
2541 + *R_DMA_CH8_CLR_INTR = IO_STATE(R_DMA_CH8_CLR_INTR, clr_eop, do) |
2542 + IO_STATE(R_DMA_CH8_CLR_INTR, clr_descr, do);
2543 + }
2544 + SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode1, async);
2545 + }
2546 + *R_GEN_CONFIG_II = gen_config_ii_shadow;
2547 + local_irq_restore(flags);
2548 +
2549 + switch(cmd)
2550 + {
2551 + case SSP_SPEED:
2552 + if (GET_SPEED(arg) == CODEC)
2553 + {
2554 + if (dev)
2555 + SETS(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, clk_sel_u3, codec);
2556 + else
2557 + SETS(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, clk_sel_u1, codec);
2558 +
2559 + SETF(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, prescaler, GET_FREQ(arg));
2560 + SETF(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, frame_rate, GET_FRAME_RATE(arg));
2561 + SETF(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, word_rate, GET_WORD_RATE(arg));
2562 + }
2563 + else
2564 + {
2565 + SETF(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, tr_baud, GET_SPEED(arg));
2566 + if (dev)
2567 + SETS(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, clk_sel_u3, baudrate);
2568 + else
2569 + SETS(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, clk_sel_u1, baudrate);
2570 + }
2571 + break;
2572 + case SSP_MODE:
2573 + if (arg > 5)
2574 + return -EINVAL;
2575 + if (arg == MASTER_OUTPUT || arg == SLAVE_OUTPUT)
2576 + *R_IRQ_MASK1_CLR = 1 << port->data_avail_bit;
2577 + else if (!port->use_dma)
2578 + *R_IRQ_MASK1_SET = 1 << port->data_avail_bit;
2579 + SETF(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, mode, arg);
2580 + break;
2581 + case SSP_FRAME_SYNC:
2582 + if (arg & NORMAL_SYNC)
2583 + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_synctype, normal);
2584 + else if (arg & EARLY_SYNC)
2585 + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_synctype, early);
2586 +
2587 + if (arg & BIT_SYNC)
2588 + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_syncsize, bit);
2589 + else if (arg & WORD_SYNC)
2590 + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_syncsize, word);
2591 + else if (arg & EXTENDED_SYNC)
2592 + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_syncsize, extended);
2593 +
2594 + if (arg & SYNC_ON)
2595 + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_sync, on);
2596 + else if (arg & SYNC_OFF)
2597 + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_sync, off);
2598 +
2599 + if (arg & WORD_SIZE_8)
2600 + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, size8bit);
2601 + else if (arg & WORD_SIZE_12)
2602 + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, size12bit);
2603 + else if (arg & WORD_SIZE_16)
2604 + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, size16bit);
2605 + else if (arg & WORD_SIZE_24)
2606 + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, size24bit);
2607 + else if (arg & WORD_SIZE_32)
2608 + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, size32bit);
2609 +
2610 + if (arg & BIT_ORDER_MSB)
2611 + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, bitorder, msb);
2612 + else if (arg & BIT_ORDER_LSB)
2613 + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, bitorder, lsb);
2614 +
2615 + if (arg & FLOW_CONTROL_ENABLE)
2616 + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, flow_ctrl, enabled);
2617 + else if (arg & FLOW_CONTROL_DISABLE)
2618 + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, flow_ctrl, disabled);
2619 +
2620 + if (arg & CLOCK_NOT_GATED)
2621 + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_mode, normal);
2622 + else if (arg & CLOCK_GATED)
2623 + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_mode, gated);
2624 +
2625 + break;
2626 + case SSP_IPOLARITY:
2627 + /* NOTE!! negedge is considered NORMAL */
2628 + if (arg & CLOCK_NORMAL)
2629 + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_polarity, neg);
2630 + else if (arg & CLOCK_INVERT)
2631 + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_polarity, pos);
2632 +
2633 + if (arg & FRAME_NORMAL)
2634 + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, frame_polarity, normal);
2635 + else if (arg & FRAME_INVERT)
2636 + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, frame_polarity, inverted);
2637 +
2638 + if (arg & STATUS_NORMAL)
2639 + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, status_polarity, normal);
2640 + else if (arg & STATUS_INVERT)
2641 + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, status_polarity, inverted);
2642 + break;
2643 + case SSP_OPOLARITY:
2644 + if (arg & CLOCK_NORMAL)
2645 + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_driver, normal);
2646 + else if (arg & CLOCK_INVERT)
2647 + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_driver, inverted);
2648 +
2649 + if (arg & FRAME_NORMAL)
2650 + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, frame_driver, normal);
2651 + else if (arg & FRAME_INVERT)
2652 + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, frame_driver, inverted);
2653 +
2654 + if (arg & STATUS_NORMAL)
2655 + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, status_driver, normal);
2656 + else if (arg & STATUS_INVERT)
2657 + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, status_driver, inverted);
2658 + break;
2659 + case SSP_SPI:
2660 + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, flow_ctrl, disabled);
2661 + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, bitorder, msb);
2662 + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, size8bit);
2663 + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_sync, on);
2664 + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_syncsize, word);
2665 + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_synctype, normal);
2666 + if (arg & SPI_SLAVE)
2667 + {
2668 + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, frame_polarity, inverted);
2669 + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_polarity, neg);
2670 + SETF(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, mode, SLAVE_INPUT);
2671 + }
2672 + else
2673 + {
2674 + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, frame_driver, inverted);
2675 + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_driver, inverted);
2676 + SETF(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, mode, MASTER_OUTPUT);
2677 + }
2678 + break;
2679 + case SSP_INBUFCHUNK:
2680 +#if 0
2681 + if (arg > port->in_buffer_size/NUM_IN_DESCR)
2682 + return -EINVAL;
2683 + port->inbufchunk = arg;
2684 + /* Make sure in_buffer_size is a multiple of inbufchunk */
2685 + port->in_buffer_size = (port->in_buffer_size/port->inbufchunk) * port->inbufchunk;
2686 + DEBUG(printk("inbufchunk %i in_buffer_size: %i\n", port->inbufchunk, port->in_buffer_size));
2687 + if (port->use_dma) {
2688 + if (port->port_nbr == 0) {
2689 + RESET_DMA(9);
2690 + WAIT_DMA(9);
2691 + } else {
2692 + RESET_DMA(5);
2693 + WAIT_DMA(5);
2694 + }
2695 + start_dma_in(port);
2696 + }
2697 +#endif
2698 + break;
2699 + default:
2700 + return_val = -1;
2701 + }
2702 + /* Make sure we write the config without interruption */
2703 + local_irq_save(flags);
2704 + /* Set config and enable port */
2705 + *port->ctrl_data = port->ctrl_data_shadow;
2706 + nop(); nop(); nop(); nop();
2707 + *R_SYNC_SERIAL_PRESCALE = sync_serial_prescale_shadow;
2708 + nop(); nop(); nop(); nop();
2709 + if (dev)
2710 + SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode3, sync);
2711 + else
2712 + SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode1, sync);
2713 +
2714 + *R_GEN_CONFIG_II = gen_config_ii_shadow;
2715 + /* Reset DMA. At readout from serial port the data could be shifted
2716 + * one byte if not resetting DMA.
2717 + */
2718 + if (port->use_dma) {
2719 + if (port->port_nbr == 0) {
2720 + RESET_DMA(9);
2721 + WAIT_DMA(9);
2722 + } else {
2723 + RESET_DMA(5);
2724 + WAIT_DMA(5);
2725 + }
2726 + start_dma_in(port);
2727 + }
2728 + local_irq_restore(flags);
2729 + return return_val;
2730 +}
2731 +
2732 +
2733 +static ssize_t sync_serial_write(struct file * file, const char * buf,
2734 + size_t count, loff_t *ppos)
2735 +{
2736 + int dev = MINOR(file->f_dentry->d_inode->i_rdev);
2737 + DECLARE_WAITQUEUE(wait, current);
2738 + sync_port *port;
2739 + unsigned long flags;
2740 + unsigned long c, c1;
2741 + unsigned long free_outp;
2742 + unsigned long outp;
2743 + unsigned long out_buffer;
2744 +
2745 + if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled)
2746 + {
2747 + DEBUG(printk("Invalid minor %d\n", dev));
2748 + return -ENODEV;
2749 + }
2750 + port = &ports[dev];
2751 +
2752 + DEBUGWRITE(printk("W d%d c %lu (%d/%d)\n", port->port_nbr, count, port->out_count, OUT_BUFFER_SIZE));
2753 + /* Space to end of buffer */
2754 + /*
2755 + * out_buffer <c1>012345<- c ->OUT_BUFFER_SIZE
2756 + * outp^ +out_count
2757 + ^free_outp
2758 + * out_buffer 45<- c ->0123OUT_BUFFER_SIZE
2759 + * +out_count outp^
2760 + * free_outp
2761 + *
2762 + */
2763 +
2764 + /* Read variables that may be updated by interrupts */
2765 + local_irq_save(flags);
2766 + count = count > OUT_BUFFER_SIZE - port->out_count ? OUT_BUFFER_SIZE - port->out_count : count;
2767 + outp = (unsigned long)port->outp;
2768 + free_outp = outp + port->out_count;
2769 + local_irq_restore(flags);
2770 + out_buffer = (unsigned long)port->out_buffer;
2771 +
2772 + /* Find out where and how much to write */
2773 + if (free_outp >= out_buffer + OUT_BUFFER_SIZE)
2774 + free_outp -= OUT_BUFFER_SIZE;
2775 + if (free_outp >= outp)
2776 + c = out_buffer + OUT_BUFFER_SIZE - free_outp;
2777 + else
2778 + c = outp - free_outp;
2779 + if (c > count)
2780 + c = count;
2781 +
2782 +// DEBUGWRITE(printk("w op %08lX fop %08lX c %lu\n", outp, free_outp, c));
2783 + if (copy_from_user((void*)free_outp, buf, c))
2784 + return -EFAULT;
2785 +
2786 + if (c != count) {
2787 + buf += c;
2788 + c1 = count - c;
2789 + DEBUGWRITE(printk("w2 fi %lu c %lu c1 %lu\n", free_outp-out_buffer, c, c1));
2790 + if (copy_from_user((void*)out_buffer, buf, c1))
2791 + return -EFAULT;
2792 + }
2793 + local_irq_save(flags);
2794 + port->out_count += count;
2795 + local_irq_restore(flags);
2796 +
2797 + /* Make sure transmitter/receiver is running */
2798 + if (!port->started)
2799 + {
2800 + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_halt, running);
2801 + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, tr_enable, enable);
2802 + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, rec_enable, enable);
2803 + port->started = 1;
2804 + }
2805 +
2806 + *port->ctrl_data = port->ctrl_data_shadow;
2807 +
2808 + if (file->f_flags & O_NONBLOCK) {
2809 + local_irq_save(flags);
2810 + if (!port->tr_running) {
2811 + if (!port->use_dma) {
2812 + /* Start sender by writing data */
2813 + send_word(port);
2814 + /* and enable transmitter ready IRQ */
2815 + *R_IRQ_MASK1_SET = 1 << port->transmitter_ready_bit;
2816 + } else {
2817 + start_dma(port, (unsigned char* volatile )port->outp, c);
2818 + }
2819 + }
2820 + local_irq_restore(flags);
2821 + DEBUGWRITE(printk("w d%d c %lu NB\n",
2822 + port->port_nbr, count));
2823 + return count;
2824 + }
2825 +
2826 + /* Sleep until all sent */
2827 +
2828 + add_wait_queue(&port->out_wait_q, &wait);
2829 + set_current_state(TASK_INTERRUPTIBLE);
2830 + local_irq_save(flags);
2831 + if (!port->tr_running) {
2832 + if (!port->use_dma) {
2833 + /* Start sender by writing data */
2834 + send_word(port);
2835 + /* and enable transmitter ready IRQ */
2836 + *R_IRQ_MASK1_SET = 1 << port->transmitter_ready_bit;
2837 + } else {
2838 + start_dma(port, port->outp, c);
2839 + }
2840 + }
2841 + local_irq_restore(flags);
2842 + schedule();
2843 + set_current_state(TASK_RUNNING);
2844 + remove_wait_queue(&port->out_wait_q, &wait);
2845 + if (signal_pending(current))
2846 + {
2847 + return -EINTR;
2848 + }
2849 + DEBUGWRITE(printk("w d%d c %lu\n", port->port_nbr, count));
2850 + return count;
2851 +}
2852 +
2853 +static ssize_t sync_serial_read(struct file * file, char * buf,
2854 + size_t count, loff_t *ppos)
2855 +{
2856 + int dev = MINOR(file->f_dentry->d_inode->i_rdev);
2857 + int avail;
2858 + sync_port *port;
2859 + unsigned char* start;
2860 + unsigned char* end;
2861 + unsigned long flags;
2862 +
2863 + if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled)
2864 + {
2865 + DEBUG(printk("Invalid minor %d\n", dev));
2866 + return -ENODEV;
2867 + }
2868 + port = &ports[dev];
2869 +
2870 + DEBUGREAD(printk("R%d c %d ri %lu wi %lu /%lu\n", dev, count, port->readp - port->flip, port->writep - port->flip, port->in_buffer_size));
2871 +
2872 + if (!port->started)
2873 + {
2874 + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_halt, running);
2875 + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, tr_enable, enable);
2876 + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, rec_enable, enable);
2877 + port->started = 1;
2878 + }
2879 + *port->ctrl_data = port->ctrl_data_shadow;
2880 +
2881 +
2882 + /* Calculate number of available bytes */
2883 + /* Save pointers to avoid that they are modified by interrupt */
2884 + local_irq_save(flags);
2885 + start = (unsigned char*)port->readp; /* cast away volatile */
2886 + end = (unsigned char*)port->writep; /* cast away volatile */
2887 + local_irq_restore(flags);
2888 + while ((start == end) && !port->full) /* No data */
2889 + {
2890 + if (file->f_flags & O_NONBLOCK)
2891 + {
2892 + return -EAGAIN;
2893 + }
2894 +
2895 + interruptible_sleep_on(&port->in_wait_q);
2896 + if (signal_pending(current))
2897 + {
2898 + return -EINTR;
2899 + }
2900 + local_irq_save(flags);
2901 + start = (unsigned char*)port->readp; /* cast away volatile */
2902 + end = (unsigned char*)port->writep; /* cast away volatile */
2903 + local_irq_restore(flags);
2904 + }
2905 +
2906 + /* Lazy read, never return wrapped data. */
2907 + if (port->full)
2908 + avail = port->in_buffer_size;
2909 + else if (end > start)
2910 + avail = end - start;
2911 + else
2912 + avail = port->flip + port->in_buffer_size - start;
2913 +
2914 + count = count > avail ? avail : count;
2915 + if (copy_to_user(buf, start, count))
2916 + return -EFAULT;
2917 + /* Disable interrupts while updating readp */
2918 + local_irq_save(flags);
2919 + port->readp += count;
2920 + if (port->readp >= port->flip + port->in_buffer_size) /* Wrap? */
2921 + port->readp = port->flip;
2922 + port->full = 0;
2923 + local_irq_restore(flags);
2924 + DEBUGREAD(printk("r %d\n", count));
2925 + return count;
2926 +}
2927 +
2928 +static void send_word(sync_port* port)
2929 +{
2930 + switch(IO_EXTRACT(R_SYNC_SERIAL1_CTRL, wordsize, port->ctrl_data_shadow))
2931 + {
2932 + case IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, wordsize, size8bit):
2933 + port->out_count--;
2934 + *port->data_out = *port->outp++;
2935 + if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE)
2936 + port->outp = port->out_buffer;
2937 + break;
2938 + case IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, wordsize, size12bit):
2939 + {
2940 + int data = (*port->outp++) << 8;
2941 + data |= *port->outp++;
2942 + port->out_count-=2;
2943 + *port->data_out = data;
2944 + if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE)
2945 + port->outp = port->out_buffer;
2946 + }
2947 + break;
2948 + case IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, wordsize, size16bit):
2949 + port->out_count-=2;
2950 + *port->data_out = *(unsigned short *)port->outp;
2951 + port->outp+=2;
2952 + if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE)
2953 + port->outp = port->out_buffer;
2954 + break;
2955 + case IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, wordsize, size24bit):
2956 + port->out_count-=3;
2957 + *port->data_out = *(unsigned int *)port->outp;
2958 + port->outp+=3;
2959 + if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE)
2960 + port->outp = port->out_buffer;
2961 + break;
2962 + case IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, wordsize, size32bit):
2963 + port->out_count-=4;
2964 + *port->data_out = *(unsigned int *)port->outp;
2965 + port->outp+=4;
2966 + if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE)
2967 + port->outp = port->out_buffer;
2968 + break;
2969 + }
2970 +}
2971 +
2972 +
2973 +static void start_dma(struct sync_port* port, const char* data, int count)
2974 +{
2975 + port->tr_running = 1;
2976 + port->out_descr.hw_len = 0;
2977 + port->out_descr.next = 0;
2978 + port->out_descr.ctrl = d_eol | d_eop; /* No d_wait to avoid glitches */
2979 + port->out_descr.sw_len = count;
2980 + port->out_descr.buf = virt_to_phys((char*)data);
2981 + port->out_descr.status = 0;
2982 +
2983 + *port->output_dma_first = virt_to_phys(&port->out_descr);
2984 + *port->output_dma_cmd = IO_STATE(R_DMA_CH0_CMD, cmd, start);
2985 + DEBUGTXINT(printk("dma %08lX c %d\n", (unsigned long)data, count));
2986 +}
2987 +
2988 +static void start_dma_in(sync_port* port)
2989 +{
2990 + int i;
2991 + unsigned long buf;
2992 + port->writep = port->flip;
2993 +
2994 + if (port->writep > port->flip + port->in_buffer_size)
2995 + {
2996 + panic("Offset too large in sync serial driver\n");
2997 + return;
2998 + }
2999 + buf = virt_to_phys(port->in_buffer);
3000 + for (i = 0; i < NUM_IN_DESCR; i++) {
3001 + port->in_descr[i].sw_len = port->inbufchunk;
3002 + port->in_descr[i].ctrl = d_int;
3003 + port->in_descr[i].next = virt_to_phys(&port->in_descr[i+1]);
3004 + port->in_descr[i].buf = buf;
3005 + port->in_descr[i].hw_len = 0;
3006 + port->in_descr[i].status = 0;
3007 + port->in_descr[i].fifo_len = 0;
3008 + buf += port->inbufchunk;
3009 + prepare_rx_descriptor(&port->in_descr[i]);
3010 + }
3011 + /* Link the last descriptor to the first */
3012 + port->in_descr[i-1].next = virt_to_phys(&port->in_descr[0]);
3013 + port->in_descr[i-1].ctrl |= d_eol;
3014 + port->next_rx_desc = &port->in_descr[0];
3015 + port->prev_rx_desc = &port->in_descr[NUM_IN_DESCR - 1];
3016 + *port->input_dma_first = virt_to_phys(port->next_rx_desc);
3017 + *port->input_dma_cmd = IO_STATE(R_DMA_CH0_CMD, cmd, start);
3018 +}
3019 +
3020 +#ifdef SYNC_SER_DMA
3021 +static irqreturn_t tr_interrupt(int irq, void *dev_id)
3022 +{
3023 + unsigned long ireg = *R_IRQ_MASK2_RD;
3024 + int i;
3025 + struct etrax_dma_descr *descr;
3026 + unsigned int sentl;
3027 + int handled = 0;
3028 +
3029 + for (i = 0; i < NUMBER_OF_PORTS; i++)
3030 + {
3031 + sync_port *port = &ports[i];
3032 + if (!port->enabled || !port->use_dma )
3033 + continue;
3034 +
3035 + if (ireg & (1 << port->output_dma_bit)) /* IRQ active for the port? */
3036 + {
3037 + handled = 1;
3038 +
3039 + /* Clear IRQ */
3040 + *port->output_dma_clr_irq =
3041 + IO_STATE(R_DMA_CH0_CLR_INTR, clr_eop, do) |
3042 + IO_STATE(R_DMA_CH0_CLR_INTR, clr_descr, do);
3043 +
3044 + descr = &port->out_descr;
3045 + if (!(descr->status & d_stop)) {
3046 + sentl = descr->sw_len;
3047 + } else
3048 + /* otherwise we find the amount of data sent here */
3049 + sentl = descr->hw_len;
3050 + port->out_count -= sentl;
3051 + port->outp += sentl;
3052 + if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE)
3053 + port->outp = port->out_buffer;
3054 + if (port->out_count) {
3055 + int c;
3056 + c = port->out_buffer + OUT_BUFFER_SIZE - port->outp;
3057 + if (c > port->out_count)
3058 + c = port->out_count;
3059 + DEBUGTXINT(printk("tx_int DMAWRITE %i %i\n", sentl, c));
3060 + start_dma(port, port->outp, c);
3061 + } else {
3062 + DEBUGTXINT(printk("tx_int DMA stop %i\n", sentl));
3063 + port->tr_running = 0;
3064 + }
3065 + wake_up_interruptible(&port->out_wait_q); /* wake up the waiting process */
3066 + }
3067 + }
3068 + return IRQ_RETVAL(handled);
3069 +} /* tr_interrupt */
3070 +
3071 +static irqreturn_t rx_interrupt(int irq, void *dev_id)
3072 +{
3073 + unsigned long ireg = *R_IRQ_MASK2_RD;
3074 + int i;
3075 + int handled = 0;
3076 +
3077 + for (i = 0; i < NUMBER_OF_PORTS; i++)
3078 + {
3079 + sync_port *port = &ports[i];
3080 +
3081 + if (!port->enabled || !port->use_dma )
3082 + continue;
3083 +
3084 + if (ireg & (1 << port->input_dma_descr_bit)) /* Descriptor interrupt */
3085 + {
3086 + handled = 1;
3087 + while (*port->input_dma_descr != virt_to_phys(port->next_rx_desc)) {
3088 +
3089 + if (port->writep + port->inbufchunk > port->flip + port->in_buffer_size) {
3090 + int first_size = port->flip + port->in_buffer_size - port->writep;
3091 + memcpy(port->writep, phys_to_virt(port->next_rx_desc->buf), first_size);
3092 + memcpy(port->flip, phys_to_virt(port->next_rx_desc->buf+first_size), port->inbufchunk - first_size);
3093 + port->writep = port->flip + port->inbufchunk - first_size;
3094 + } else {
3095 + memcpy(port->writep, phys_to_virt(port->next_rx_desc->buf), port->inbufchunk);
3096 + port->writep += port->inbufchunk;
3097 + if (port->writep >= port->flip + port->in_buffer_size)
3098 + port->writep = port->flip;
3099 + }
3100 + if (port->writep == port->readp)
3101 + {
3102 + port->full = 1;
3103 + }
3104 +
3105 + prepare_rx_descriptor(port->next_rx_desc);
3106 + port->next_rx_desc->ctrl |= d_eol;
3107 + port->prev_rx_desc->ctrl &= ~d_eol;
3108 + port->prev_rx_desc = phys_to_virt((unsigned)port->next_rx_desc);
3109 + port->next_rx_desc = phys_to_virt((unsigned)port->next_rx_desc->next);
3110 + wake_up_interruptible(&port->in_wait_q); /* wake up the waiting process */
3111 + *port->input_dma_cmd = IO_STATE(R_DMA_CH1_CMD, cmd, restart);
3112 + /* DMA has reached end of descriptor */
3113 + *port->input_dma_clr_irq =
3114 + IO_STATE(R_DMA_CH0_CLR_INTR, clr_descr, do);
3115 + }
3116 + }
3117 + }
3118 +
3119 + return IRQ_RETVAL(handled);
3120 +} /* rx_interrupt */
3121 +#endif /* SYNC_SER_DMA */
3122 +
3123 +#ifdef SYNC_SER_MANUAL
3124 +static irqreturn_t manual_interrupt(int irq, void *dev_id)
3125 +{
3126 + int i;
3127 + int handled = 0;
3128 +
3129 + for (i = 0; i < NUMBER_OF_PORTS; i++)
3130 + {
3131 + sync_port* port = &ports[i];
3132 +
3133 + if (!port->enabled || port->use_dma)
3134 + {
3135 + continue;
3136 + }
3137 +
3138 + if (*R_IRQ_MASK1_RD & (1 << port->data_avail_bit)) /* Data received? */
3139 + {
3140 + handled = 1;
3141 + /* Read data */
3142 + switch(port->ctrl_data_shadow & IO_MASK(R_SYNC_SERIAL1_CTRL, wordsize))
3143 + {
3144 + case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size8bit):
3145 + *port->writep++ = *(volatile char *)port->data_in;
3146 + break;
3147 + case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size12bit):
3148 + {
3149 + int data = *(unsigned short *)port->data_in;
3150 + *port->writep = (data & 0x0ff0) >> 4;
3151 + *(port->writep + 1) = data & 0x0f;
3152 + port->writep+=2;
3153 + }
3154 + break;
3155 + case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size16bit):
3156 + *(unsigned short*)port->writep = *(volatile unsigned short *)port->data_in;
3157 + port->writep+=2;
3158 + break;
3159 + case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size24bit):
3160 + *(unsigned int*)port->writep = *port->data_in;
3161 + port->writep+=3;
3162 + break;
3163 + case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size32bit):
3164 + *(unsigned int*)port->writep = *port->data_in;
3165 + port->writep+=4;
3166 + break;
3167 + }
3168 +
3169 + if (port->writep >= port->flip + port->in_buffer_size) /* Wrap? */
3170 + port->writep = port->flip;
3171 + if (port->writep == port->readp) {
3172 + /* receive buffer overrun, discard oldest data
3173 + */
3174 + port->readp++;
3175 + if (port->readp >= port->flip + port->in_buffer_size) /* Wrap? */
3176 + port->readp = port->flip;
3177 + }
3178 + if (sync_data_avail(port) >= port->inbufchunk)
3179 + wake_up_interruptible(&port->in_wait_q); /* Wake up application */
3180 + }
3181 +
3182 + if (*R_IRQ_MASK1_RD & (1 << port->transmitter_ready_bit)) /* Transmitter ready? */
3183 + {
3184 + if (port->out_count > 0) /* More data to send */
3185 + send_word(port);
3186 + else /* transmission finished */
3187 + {
3188 + *R_IRQ_MASK1_CLR = 1 << port->transmitter_ready_bit; /* Turn off IRQ */
3189 + wake_up_interruptible(&port->out_wait_q); /* Wake up application */
3190 + }
3191 + }
3192 + }
3193 + return IRQ_RETVAL(handled);
3194 +}
3195 +#endif
3196 +
3197 +module_init(etrax_sync_serial_init);
3198 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/kernel/debugport.c linux-2.6.19.2.dev/arch/cris/arch-v10/kernel/debugport.c
3199 --- linux-2.6.19.2.old/arch/cris/arch-v10/kernel/debugport.c 2007-01-10 20:10:37.000000000 +0100
3200 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/kernel/debugport.c 2006-10-30 16:17:57.000000000 +0100
3201 @@ -12,6 +12,34 @@
3202 * init_etrax_debug()
3203 *
3204 * $Log: debugport.c,v $
3205 + * Revision 1.36 2006/10/30 15:17:57 pkj
3206 + * Avoid a compiler warning.
3207 + *
3208 + * Revision 1.35 2006/10/13 12:43:11 starvik
3209 + * Merge of 2.6.18
3210 + *
3211 + * Revision 1.34 2006/09/29 10:32:01 starvik
3212 + * Don't reference serial driver if not present
3213 + *
3214 + * Revision 1.33 2006/09/08 07:59:29 karljope
3215 + * Makes v10 boot again when watchdog is enabled
3216 + *
3217 + * Revision 1.32 2006/06/20 08:23:36 pkj
3218 + * Reverted incorrect merge.
3219 + *
3220 + * Revision 1.31 2006/05/17 12:22:10 edgar
3221 + * check port before disable ints
3222 + *
3223 + * Revision 1.30 2005/11/15 12:08:42 starvik
3224 + * Set index when no debug port is defined
3225 + *
3226 + * Revision 1.29 2005/08/29 07:32:17 starvik
3227 + * Merge of 2.6.13
3228 + *
3229 + * Revision 1.28 2005/07/02 12:29:35 starvik
3230 + * Use the generic oops_in_progress instead of the raw_printk hack.
3231 + * Moved some functions to achr-independent code.
3232 + *
3233 * Revision 1.27 2005/06/10 10:34:14 starvik
3234 * Real console support
3235 *
3236 @@ -112,6 +140,8 @@
3237 #include <asm/arch/svinto.h>
3238 #include <asm/io.h> /* Get SIMCOUT. */
3239
3240 +extern void reset_watchdog(void);
3241 +
3242 struct dbg_port
3243 {
3244 unsigned int index;
3245 @@ -188,7 +218,9 @@
3246 }
3247 };
3248
3249 +#ifdef CONFIG_ETRAX_SERIAL
3250 extern struct tty_driver *serial_driver;
3251 +#endif
3252
3253 struct dbg_port* port =
3254 #if defined(CONFIG_ETRAX_DEBUG_PORT0)
3255 @@ -368,11 +400,12 @@
3256 {
3257 int i;
3258 unsigned long flags;
3259 - local_irq_save(flags);
3260 -
3261 +
3262 if (!port)
3263 return;
3264 -
3265 +
3266 + local_irq_save(flags);
3267 +
3268 /* Send data */
3269 for (i = 0; i < len; i++) {
3270 /* LF -> CRLF */
3271 @@ -386,26 +419,16 @@
3272 ;
3273 *port->write = buf[i];
3274 }
3275 - local_irq_restore(flags);
3276 -}
3277
3278 -int raw_printk(const char *fmt, ...)
3279 -{
3280 - static char buf[1024];
3281 - int printed_len;
3282 - static int first = 1;
3283 - if (first) {
3284 - /* Force reinitialization of the port to get manual mode. */
3285 - port->started = 0;
3286 - start_port(port);
3287 - first = 0;
3288 - }
3289 - va_list args;
3290 - va_start(args, fmt);
3291 - printed_len = vsnprintf(buf, sizeof(buf), fmt, args);
3292 - va_end(args);
3293 - console_write_direct(NULL, buf, strlen(buf));
3294 - return printed_len;
3295 + /*
3296 + * Feed the watchdog, otherwise it will reset the chip during boot.
3297 + * The time to send an ordinary boot message line (10-90 chars)
3298 + * varies between 1-8ms at 115200. What makes up for the additional
3299 + * 90ms that allows the watchdog to bite?
3300 + */
3301 + reset_watchdog();
3302 +
3303 + local_irq_restore(flags);
3304 }
3305
3306 static void
3307 @@ -500,6 +523,7 @@
3308 return 0;
3309 }
3310
3311 +
3312 /* This is a dummy serial device that throws away anything written to it.
3313 * This is used when no debug output is wanted.
3314 */
3315 @@ -555,7 +579,13 @@
3316 {
3317 if (port)
3318 *index = port->index;
3319 + else
3320 + *index = 0;
3321 +#ifdef CONFIG_ETRAX_SERIAL
3322 return port ? serial_driver : &dummy_driver;
3323 +#else
3324 + return &dummy_driver;
3325 +#endif
3326 }
3327
3328 static struct console sercons = {
3329 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/kernel/entry.S linux-2.6.19.2.dev/arch/cris/arch-v10/kernel/entry.S
3330 --- linux-2.6.19.2.old/arch/cris/arch-v10/kernel/entry.S 2007-01-10 20:10:37.000000000 +0100
3331 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/kernel/entry.S 2007-01-09 10:36:17.000000000 +0100
3332 @@ -1,4 +1,4 @@
3333 -/* $Id: entry.S,v 1.28 2005/06/20 05:06:30 starvik Exp $
3334 +/* $Id: entry.S,v 1.38 2007/01/09 09:36:17 starvik Exp $
3335 *
3336 * linux/arch/cris/entry.S
3337 *
3338 @@ -7,6 +7,41 @@
3339 * Authors: Bjorn Wesen (bjornw@axis.com)
3340 *
3341 * $Log: entry.S,v $
3342 + * Revision 1.38 2007/01/09 09:36:17 starvik
3343 + * Corrected kernel_execve
3344 + *
3345 + * Revision 1.37 2007/01/09 09:29:18 starvik
3346 + * Merge of Linux 2.6.19
3347 + *
3348 + * Revision 1.36 2006/12/08 13:08:54 orjanf
3349 + * Copied from Linux 2.4:
3350 + * * Return from an pin-generated NMI the same way as for other interrupts.
3351 + * * Reverse check order between external nmi and watchdog nmi to avoid false
3352 + * watchdog oops in case of a glitch on the nmi pin.
3353 + *
3354 + * Revision 1.35 2006/10/13 12:43:11 starvik
3355 + * Merge of 2.6.18
3356 + *
3357 + * Revision 1.34 2006/06/25 15:00:09 starvik
3358 + * Merge of Linux 2.6.17
3359 + *
3360 + * Revision 1.33 2006/05/19 12:23:09 orjanf
3361 + * * Moved blocking of ethernet rx/tx irq from ethernet interrupt handler to
3362 + * low-level asm interrupt handlers. Fixed in the multiple interrupt handler
3363 + * also. Copied from Linux 2.4.
3364 + *
3365 + * Revision 1.32 2006/03/23 14:53:57 starvik
3366 + * Corrected signal handling.
3367 + *
3368 + * Revision 1.31 2006/03/22 09:56:55 starvik
3369 + * Merge of Linux 2.6.16
3370 + *
3371 + * Revision 1.30 2005/10/31 08:48:03 starvik
3372 + * Merge of Linux 2.6.14
3373 + *
3374 + * Revision 1.29 2005/08/29 07:32:17 starvik
3375 + * Merge of 2.6.13
3376 + *
3377 * Revision 1.28 2005/06/20 05:06:30 starvik
3378 * Remove unnecessary diff to kernel.org tree
3379 *
3380 @@ -500,9 +535,8 @@
3381 ;; deal with pending signals and notify-resume requests
3382
3383 move.d $r9, $r10 ; do_notify_resume syscall/irq param
3384 - moveq 0, $r11 ; oldset param - 0 in this case
3385 - move.d $sp, $r12 ; the regs param
3386 - move.d $r1, $r13 ; the thread_info_flags parameter
3387 + move.d $sp, $r11 ; the regs param
3388 + move.d $r1, $r12 ; the thread_info_flags parameter
3389 jsr do_notify_resume
3390
3391 ba _Rexit
3392 @@ -653,7 +687,7 @@
3393 ;; special handlers for breakpoint and NMI
3394 hwbreakpoint:
3395 push $dccr
3396 - di
3397 + di
3398 push $r10
3399 push $r11
3400 move.d [hw_bp_trig_ptr],$r10
3401 @@ -678,13 +712,19 @@
3402 push $r10 ; push orig_r10
3403 clear.d [$sp=$sp-4] ; frametype == 0, normal frame
3404
3405 + ;; If there is a glitch on the NMI pin shorter than ~100ns
3406 + ;; (i.e. non-active by the time we get here) then the nmi_pin bit
3407 + ;; in R_IRQ_MASK0_RD will already be cleared. The watchdog_nmi bit
3408 + ;; is cleared by us however (when feeding the watchdog), which is why
3409 + ;; we use that bit to determine what brought us here.
3410 +
3411 move.d [R_IRQ_MASK0_RD], $r1 ; External NMI or watchdog?
3412 - and.d 0x80000000, $r1
3413 - beq wdog
3414 + and.d (1<<30), $r1
3415 + bne wdog
3416 move.d $sp, $r10
3417 jsr handle_nmi
3418 setf m ; Enable NMI again
3419 - retb ; Return from NMI
3420 + ba _Rexit ; Return the standard way
3421 nop
3422 wdog:
3423 #if defined(CONFIG_ETRAX_WATCHDOG) && !defined(CONFIG_SVINTO_SIM)
3424 @@ -774,23 +814,10 @@
3425 movem $r13, [$sp]
3426 push $r10 ; push orig_r10
3427 clear.d [$sp=$sp-4] ; frametype == 0, normal frame
3428 -
3429 - moveq 2, $r2 ; first bit we care about is the timer0 irq
3430 - move.d [R_VECT_MASK_RD], $r0; read the irq bits that triggered the multiple irq
3431 - move.d $r0, [R_VECT_MASK_CLR] ; Block all active IRQs
3432 -1:
3433 - btst $r2, $r0 ; check for the irq given by bit r2
3434 - bpl 2f
3435 - move.d $r2, $r10 ; First argument to do_IRQ
3436 - move.d $sp, $r11 ; second argument to do_IRQ
3437 - jsr do_IRQ
3438 -2:
3439 - addq 1, $r2 ; next vector bit
3440 - cmp.b 32, $r2
3441 - bne 1b ; process all irq's up to and including number 31
3442 - moveq 0, $r9 ; make ret_from_intr realise we came from an ir
3443 -
3444 - move.d $r0, [R_VECT_MASK_SET] ; Unblock all the IRQs
3445 +
3446 + move.d $sp, $r10
3447 + jsr do_multiple_IRQ
3448 +
3449 jump ret_from_intr
3450
3451 do_sigtrap:
3452 @@ -836,6 +863,13 @@
3453 pop $r0 ; Restore r0.
3454 ba do_sigtrap ; SIGTRAP the offending process.
3455 pop $dccr ; Restore dccr in delay slot.
3456 +
3457 + .global kernel_execve
3458 +kernel_execve:
3459 + move.d __NR_execve, $r9
3460 + break 13
3461 + ret
3462 + nop
3463
3464 .data
3465
3466 @@ -1135,7 +1169,38 @@
3467 .long sys_add_key
3468 .long sys_request_key
3469 .long sys_keyctl
3470 -
3471 + .long sys_ioprio_set
3472 + .long sys_ioprio_get /* 290 */
3473 + .long sys_inotify_init
3474 + .long sys_inotify_add_watch
3475 + .long sys_inotify_rm_watch
3476 + .long sys_migrate_pages
3477 + .long sys_openat /* 295 */
3478 + .long sys_mkdirat
3479 + .long sys_mknodat
3480 + .long sys_fchownat
3481 + .long sys_futimesat
3482 + .long sys_fstatat64 /* 300 */
3483 + .long sys_unlinkat
3484 + .long sys_renameat
3485 + .long sys_linkat
3486 + .long sys_symlinkat
3487 + .long sys_readlinkat /* 305 */
3488 + .long sys_fchmodat
3489 + .long sys_faccessat
3490 + .long sys_pselect6
3491 + .long sys_ppoll
3492 + .long sys_unshare /* 310 */
3493 + .long sys_set_robust_list
3494 + .long sys_get_robust_list
3495 + .long sys_splice
3496 + .long sys_sync_file_range
3497 + .long sys_tee /* 315 */
3498 + .long sys_vmsplice
3499 + .long sys_move_pages
3500 + .long sys_getcpu
3501 + .long sys_epoll_pwait
3502 +
3503 /*
3504 * NOTE!! This doesn't have to be exact - we just have
3505 * to make sure we have _enough_ of the "sys_ni_syscall"
3506 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/kernel/fasttimer.c linux-2.6.19.2.dev/arch/cris/arch-v10/kernel/fasttimer.c
3507 --- linux-2.6.19.2.old/arch/cris/arch-v10/kernel/fasttimer.c 2007-01-10 20:10:37.000000000 +0100
3508 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/kernel/fasttimer.c 2007-02-05 12:54:34.000000000 +0100
3509 @@ -1,97 +1,10 @@
3510 -/* $Id: fasttimer.c,v 1.9 2005/03/04 08:16:16 starvik Exp $
3511 +/*
3512 * linux/arch/cris/kernel/fasttimer.c
3513 *
3514 * Fast timers for ETRAX100/ETRAX100LX
3515 * This may be useful in other OS than Linux so use 2 space indentation...
3516 *
3517 - * $Log: fasttimer.c,v $
3518 - * Revision 1.9 2005/03/04 08:16:16 starvik
3519 - * Merge of Linux 2.6.11.
3520 - *
3521 - * Revision 1.8 2005/01/05 06:09:29 starvik
3522 - * cli()/sti() will be obsolete in 2.6.11.
3523 - *
3524 - * Revision 1.7 2005/01/03 13:35:46 starvik
3525 - * Removed obsolete stuff.
3526 - * Mark fast timer IRQ as not shared.
3527 - *
3528 - * Revision 1.6 2004/05/14 10:18:39 starvik
3529 - * Export fast_timer_list
3530 - *
3531 - * Revision 1.5 2004/05/14 07:58:01 starvik
3532 - * Merge of changes from 2.4
3533 - *
3534 - * Revision 1.4 2003/07/04 08:27:41 starvik
3535 - * Merge of Linux 2.5.74
3536 - *
3537 - * Revision 1.3 2002/12/12 08:26:32 starvik
3538 - * Don't use C-comments inside CVS comments
3539 - *
3540 - * Revision 1.2 2002/12/11 15:42:02 starvik
3541 - * Extracted v10 (ETRAX 100LX) specific stuff from arch/cris/kernel/
3542 - *
3543 - * Revision 1.1 2002/11/18 07:58:06 starvik
3544 - * Fast timers (from Linux 2.4)
3545 - *
3546 - * Revision 1.5 2002/10/15 06:21:39 starvik
3547 - * Added call to init_waitqueue_head
3548 - *
3549 - * Revision 1.4 2002/05/28 17:47:59 johana
3550 - * Added del_fast_timer()
3551 - *
3552 - * Revision 1.3 2002/05/28 16:16:07 johana
3553 - * Handle empty fast_timer_list
3554 - *
3555 - * Revision 1.2 2002/05/27 15:38:42 johana
3556 - * Made it compile without warnings on Linux 2.4.
3557 - * (includes, wait_queue, PROC_FS and snprintf)
3558 - *
3559 - * Revision 1.1 2002/05/27 15:32:25 johana
3560 - * arch/etrax100/kernel/fasttimer.c v1.8 from the elinux tree.
3561 - *
3562 - * Revision 1.8 2001/11/27 13:50:40 pkj
3563 - * Disable interrupts while stopping the timer and while modifying the
3564 - * list of active timers in timer1_handler() as it may be interrupted
3565 - * by other interrupts (e.g., the serial interrupt) which may add fast
3566 - * timers.
3567 - *
3568 - * Revision 1.7 2001/11/22 11:50:32 pkj
3569 - * * Only store information about the last 16 timers.
3570 - * * proc_fasttimer_read() now uses an allocated buffer, since it
3571 - * requires more space than just a page even for only writing the
3572 - * last 16 timers. The buffer is only allocated on request, so
3573 - * unless /proc/fasttimer is read, it is never allocated.
3574 - * * Renamed fast_timer_started to fast_timers_started to match
3575 - * fast_timers_added and fast_timers_expired.
3576 - * * Some clean-up.
3577 - *
3578 - * Revision 1.6 2000/12/13 14:02:08 johana
3579 - * Removed volatile for fast_timer_list
3580 - *
3581 - * Revision 1.5 2000/12/13 13:55:35 johana
3582 - * Added DEBUG_LOG, added som cli() and cleanup
3583 - *
3584 - * Revision 1.4 2000/12/05 13:48:50 johana
3585 - * Added range check when writing proc file, modified timer int handling
3586 - *
3587 - * Revision 1.3 2000/11/23 10:10:20 johana
3588 - * More debug/logging possibilities.
3589 - * Moved GET_JIFFIES_USEC() to timex.h and time.c
3590 - *
3591 - * Revision 1.2 2000/11/01 13:41:04 johana
3592 - * Clean up and bugfixes.
3593 - * Created new do_gettimeofday_fast() that gets a timeval struct
3594 - * with time based on jiffies and *R_TIMER0_DATA, uses a table
3595 - * for fast conversion of timer value to microseconds.
3596 - * (Much faster the standard do_gettimeofday() and we don't really
3597 - * wan't to use the true time - we wan't the "uptime" so timers don't screw up
3598 - * when we change the time.
3599 - * TODO: Add efficient support for continuous timers as well.
3600 - *
3601 - * Revision 1.1 2000/10/26 15:49:16 johana
3602 - * Added fasttimer, highresolution timers.
3603 - *
3604 - * Copyright (C) 2000,2001 2002 Axis Communications AB, Lund, Sweden
3605 + * Copyright (C) 2000-2006 Axis Communications AB, Lund, Sweden
3606 */
3607
3608 #include <linux/errno.h>
3609 @@ -136,13 +49,13 @@
3610
3611 #define __INLINE__ inline
3612
3613 -static int fast_timer_running = 0;
3614 -static int fast_timers_added = 0;
3615 -static int fast_timers_started = 0;
3616 -static int fast_timers_expired = 0;
3617 -static int fast_timers_deleted = 0;
3618 -static int fast_timer_is_init = 0;
3619 -static int fast_timer_ints = 0;
3620 +static unsigned int fast_timer_running = 0;
3621 +static unsigned int fast_timers_added = 0;
3622 +static unsigned int fast_timers_started = 0;
3623 +static unsigned int fast_timers_expired = 0;
3624 +static unsigned int fast_timers_deleted = 0;
3625 +static unsigned int fast_timer_is_init = 0;
3626 +static unsigned int fast_timer_ints = 0;
3627
3628 struct fast_timer *fast_timer_list = NULL;
3629
3630 @@ -150,8 +63,8 @@
3631 #define DEBUG_LOG_MAX 128
3632 static const char * debug_log_string[DEBUG_LOG_MAX];
3633 static unsigned long debug_log_value[DEBUG_LOG_MAX];
3634 -static int debug_log_cnt = 0;
3635 -static int debug_log_cnt_wrapped = 0;
3636 +static unsigned int debug_log_cnt = 0;
3637 +static unsigned int debug_log_cnt_wrapped = 0;
3638
3639 #define DEBUG_LOG(string, value) \
3640 { \
3641 @@ -206,41 +119,25 @@
3642 int timer_delay_settings[NUM_TIMER_STATS];
3643
3644 /* Not true gettimeofday, only checks the jiffies (uptime) + useconds */
3645 -void __INLINE__ do_gettimeofday_fast(struct timeval *tv)
3646 +void __INLINE__ do_gettimeofday_fast(struct fasttime_t *tv)
3647 {
3648 - unsigned long sec = jiffies;
3649 - unsigned long usec = GET_JIFFIES_USEC();
3650 -
3651 - usec += (sec % HZ) * (1000000 / HZ);
3652 - sec = sec / HZ;
3653 -
3654 - if (usec > 1000000)
3655 - {
3656 - usec -= 1000000;
3657 - sec++;
3658 - }
3659 - tv->tv_sec = sec;
3660 - tv->tv_usec = usec;
3661 + tv->tv_jiff = jiffies;
3662 + tv->tv_usec = GET_JIFFIES_USEC();
3663 }
3664
3665 -int __INLINE__ timeval_cmp(struct timeval *t0, struct timeval *t1)
3666 +int __INLINE__ timeval_cmp(struct fasttime_t *t0, struct fasttime_t *t1)
3667 {
3668 - if (t0->tv_sec < t1->tv_sec)
3669 - {
3670 + /* Compare jiffies. Takes care of wrapping */
3671 + if (time_before(t0->tv_jiff, t1->tv_jiff))
3672 return -1;
3673 - }
3674 - else if (t0->tv_sec > t1->tv_sec)
3675 - {
3676 + else if (time_after(t0->tv_jiff, t1->tv_jiff))
3677 return 1;
3678 - }
3679 +
3680 + /* Compare us */
3681 if (t0->tv_usec < t1->tv_usec)
3682 - {
3683 return -1;
3684 - }
3685 else if (t0->tv_usec > t1->tv_usec)
3686 - {
3687 return 1;
3688 - }
3689 return 0;
3690 }
3691
3692 @@ -340,7 +237,7 @@
3693 printk(KERN_WARNING
3694 "timer name: %s data: 0x%08lX already in list!\n", name, data);
3695 sanity_failed++;
3696 - return;
3697 + goto done;
3698 }
3699 else
3700 {
3701 @@ -356,11 +253,11 @@
3702 t->name = name;
3703
3704 t->tv_expires.tv_usec = t->tv_set.tv_usec + delay_us % 1000000;
3705 - t->tv_expires.tv_sec = t->tv_set.tv_sec + delay_us / 1000000;
3706 + t->tv_expires.tv_jiff = t->tv_set.tv_jiff + delay_us / 1000000 / HZ;
3707 if (t->tv_expires.tv_usec > 1000000)
3708 {
3709 t->tv_expires.tv_usec -= 1000000;
3710 - t->tv_expires.tv_sec++;
3711 + t->tv_expires.tv_jiff += HZ;
3712 }
3713 #ifdef FAST_TIMER_LOG
3714 timer_added_log[fast_timers_added % NUM_TIMER_STATS] = *t;
3715 @@ -401,6 +298,7 @@
3716
3717 D2(printk("start_one_shot_timer: %d us done\n", delay_us));
3718
3719 +done:
3720 local_irq_restore(flags);
3721 } /* start_one_shot_timer */
3722
3723 @@ -444,11 +342,18 @@
3724 /* Timer 1 interrupt handler */
3725
3726 static irqreturn_t
3727 -timer1_handler(int irq, void *dev_id, struct pt_regs *regs)
3728 +timer1_handler(int irq, void *dev_id)
3729 {
3730 struct fast_timer *t;
3731 unsigned long flags;
3732
3733 + /* We keep interrupts disabled not only when we modify the
3734 + * fast timer list, but any time we hold a reference to a
3735 + * timer in the list, since del_fast_timer may be called
3736 + * from (another) interrupt context. Thus, the only time
3737 + * when interrupts are enabled is when calling the timer
3738 + * callback function.
3739 + */
3740 local_irq_save(flags);
3741
3742 /* Clear timer1 irq */
3743 @@ -466,16 +371,16 @@
3744 fast_timer_running = 0;
3745 fast_timer_ints++;
3746
3747 - local_irq_restore(flags);
3748 -
3749 t = fast_timer_list;
3750 while (t)
3751 {
3752 - struct timeval tv;
3753 + struct fasttime_t tv;
3754 + fast_timer_function_type *f;
3755 + unsigned long d;
3756
3757 /* Has it really expired? */
3758 do_gettimeofday_fast(&tv);
3759 - D1(printk("t: %is %06ius\n", tv.tv_sec, tv.tv_usec));
3760 + D1(printk("t: %is %06ius\n", tv.tv_jiff, tv.tv_usec));
3761
3762 if (timeval_cmp(&t->tv_expires, &tv) <= 0)
3763 {
3764 @@ -486,7 +391,6 @@
3765 fast_timers_expired++;
3766
3767 /* Remove this timer before call, since it may reuse the timer */
3768 - local_irq_save(flags);
3769 if (t->prev)
3770 {
3771 t->prev->next = t->next;
3772 @@ -501,11 +405,21 @@
3773 }
3774 t->prev = NULL;
3775 t->next = NULL;
3776 - local_irq_restore(flags);
3777
3778 - if (t->function != NULL)
3779 + /* Save function callback data before enabling interrupts,
3780 + * since the timer may be removed and we don't know how it
3781 + * was allocated (e.g. ->function and ->data may become
3782 + * overwritten after deletion if the timer was stack-allocated).
3783 + */
3784 + f = t->function;
3785 + d = t->data;
3786 +
3787 + if (f != NULL)
3788 {
3789 - t->function(t->data);
3790 + /* Run the callback function with interrupts enabled. */
3791 + local_irq_restore(flags);
3792 + f(d);
3793 + local_irq_save(flags);
3794 }
3795 else
3796 {
3797 @@ -518,16 +432,19 @@
3798 D1(printk(".\n"));
3799 }
3800
3801 - local_irq_save(flags);
3802 if ((t = fast_timer_list) != NULL)
3803 {
3804 /* Start next timer.. */
3805 - long us;
3806 - struct timeval tv;
3807 + long us = 0;
3808 + struct fasttime_t tv;
3809
3810 do_gettimeofday_fast(&tv);
3811 - us = ((t->tv_expires.tv_sec - tv.tv_sec) * 1000000 +
3812 - t->tv_expires.tv_usec - tv.tv_usec);
3813 +
3814 + /* time_after_eq takes care of wrapping */
3815 + if (time_after_eq(t->tv_expires.tv_jiff, tv.tv_jiff))
3816 + us = ((t->tv_expires.tv_jiff - tv.tv_jiff) * 1000000 / HZ +
3817 + t->tv_expires.tv_usec - tv.tv_usec);
3818 +
3819 if (us > 0)
3820 {
3821 if (!fast_timer_running)
3822 @@ -537,7 +454,6 @@
3823 #endif
3824 start_timer1(us);
3825 }
3826 - local_irq_restore(flags);
3827 break;
3828 }
3829 else
3830 @@ -548,9 +464,10 @@
3831 D1(printk("e! %d\n", us));
3832 }
3833 }
3834 - local_irq_restore(flags);
3835 }
3836
3837 + local_irq_restore(flags);
3838 +
3839 if (!t)
3840 {
3841 D1(printk("t1 stop!\n"));
3842 @@ -575,28 +492,17 @@
3843 void schedule_usleep(unsigned long us)
3844 {
3845 struct fast_timer t;
3846 -#ifdef DECLARE_WAITQUEUE
3847 wait_queue_head_t sleep_wait;
3848 init_waitqueue_head(&sleep_wait);
3849 - {
3850 - DECLARE_WAITQUEUE(wait, current);
3851 -#else
3852 - struct wait_queue *sleep_wait = NULL;
3853 - struct wait_queue wait = { current, NULL };
3854 -#endif
3855
3856 D1(printk("schedule_usleep(%d)\n", us));
3857 - add_wait_queue(&sleep_wait, &wait);
3858 - set_current_state(TASK_INTERRUPTIBLE);
3859 start_one_shot_timer(&t, wake_up_func, (unsigned long)&sleep_wait, us,
3860 "usleep");
3861 - schedule();
3862 - set_current_state(TASK_RUNNING);
3863 - remove_wait_queue(&sleep_wait, &wait);
3864 + /* Uninterruptible sleep on the fast timer. (The condition is somewhat
3865 + redundant since the timer is what wakes us up.) */
3866 + wait_event(sleep_wait, !fast_timer_pending(&t));
3867 +
3868 D1(printk("done schedule_usleep(%d)\n", us));
3869 -#ifdef DECLARE_WAITQUEUE
3870 - }
3871 -#endif
3872 }
3873
3874 #ifdef CONFIG_PROC_FS
3875 @@ -616,7 +522,7 @@
3876 unsigned long flags;
3877 int i = 0;
3878 int num_to_show;
3879 - struct timeval tv;
3880 + struct fasttime_t tv;
3881 struct fast_timer *t, *nextt;
3882 static char *bigbuf = NULL;
3883 static unsigned long used;
3884 @@ -624,7 +530,8 @@
3885 if (!bigbuf && !(bigbuf = vmalloc(BIG_BUF_SIZE)))
3886 {
3887 used = 0;
3888 - bigbuf[0] = '\0';
3889 + if (buf)
3890 + buf[0] = '\0';
3891 return 0;
3892 }
3893
3894 @@ -646,7 +553,7 @@
3895 used += sprintf(bigbuf + used, "Fast timer running: %s\n",
3896 fast_timer_running ? "yes" : "no");
3897 used += sprintf(bigbuf + used, "Current time: %lu.%06lu\n",
3898 - (unsigned long)tv.tv_sec,
3899 + (unsigned long)tv.tv_jiff,
3900 (unsigned long)tv.tv_usec);
3901 #ifdef FAST_TIMER_SANITY_CHECKS
3902 used += sprintf(bigbuf + used, "Sanity failed: %i\n",
3903 @@ -696,9 +603,9 @@
3904 "d: %6li us data: 0x%08lX"
3905 "\n",
3906 t->name,
3907 - (unsigned long)t->tv_set.tv_sec,
3908 + (unsigned long)t->tv_set.tv_jiff,
3909 (unsigned long)t->tv_set.tv_usec,
3910 - (unsigned long)t->tv_expires.tv_sec,
3911 + (unsigned long)t->tv_expires.tv_jiff,
3912 (unsigned long)t->tv_expires.tv_usec,
3913 t->delay_us,
3914 t->data
3915 @@ -718,9 +625,9 @@
3916 "d: %6li us data: 0x%08lX"
3917 "\n",
3918 t->name,
3919 - (unsigned long)t->tv_set.tv_sec,
3920 + (unsigned long)t->tv_set.tv_jiff,
3921 (unsigned long)t->tv_set.tv_usec,
3922 - (unsigned long)t->tv_expires.tv_sec,
3923 + (unsigned long)t->tv_expires.tv_jiff,
3924 (unsigned long)t->tv_expires.tv_usec,
3925 t->delay_us,
3926 t->data
3927 @@ -738,9 +645,9 @@
3928 "d: %6li us data: 0x%08lX"
3929 "\n",
3930 t->name,
3931 - (unsigned long)t->tv_set.tv_sec,
3932 + (unsigned long)t->tv_set.tv_jiff,
3933 (unsigned long)t->tv_set.tv_usec,
3934 - (unsigned long)t->tv_expires.tv_sec,
3935 + (unsigned long)t->tv_expires.tv_jiff,
3936 (unsigned long)t->tv_expires.tv_usec,
3937 t->delay_us,
3938 t->data
3939 @@ -761,15 +668,15 @@
3940 /* " func: 0x%08lX" */
3941 "\n",
3942 t->name,
3943 - (unsigned long)t->tv_set.tv_sec,
3944 + (unsigned long)t->tv_set.tv_jiff,
3945 (unsigned long)t->tv_set.tv_usec,
3946 - (unsigned long)t->tv_expires.tv_sec,
3947 + (unsigned long)t->tv_expires.tv_jiff,
3948 (unsigned long)t->tv_expires.tv_usec,
3949 t->delay_us,
3950 t->data
3951 /* , t->function */
3952 );
3953 - local_irq_disable();
3954 + local_irq_save(flags);
3955 if (t->next != nextt)
3956 {
3957 printk(KERN_WARNING "timer removed!\n");
3958 @@ -798,7 +705,7 @@
3959 static struct fast_timer tr[10];
3960 static int exp_num[10];
3961
3962 -static struct timeval tv_exp[100];
3963 +static struct fasttime_t tv_exp[100];
3964
3965 static void test_timeout(unsigned long data)
3966 {
3967 @@ -836,7 +743,7 @@
3968 int prev_num;
3969 int j;
3970
3971 - struct timeval tv, tv0, tv1, tv2;
3972 + struct fasttime_t tv, tv0, tv1, tv2;
3973
3974 printk("fast_timer_test() start\n");
3975 do_gettimeofday_fast(&tv);
3976 @@ -849,7 +756,7 @@
3977 {
3978 do_gettimeofday_fast(&tv_exp[j]);
3979 }
3980 - printk("fast_timer_test() %is %06i\n", tv.tv_sec, tv.tv_usec);
3981 + printk("fast_timer_test() %is %06i\n", tv.tv_jiff, tv.tv_usec);
3982
3983 for (j = 0; j < 1000; j++)
3984 {
3985 @@ -859,11 +766,11 @@
3986 for (j = 0; j < 100; j++)
3987 {
3988 printk("%i.%i %i.%i %i.%i %i.%i %i.%i\n",
3989 - tv_exp[j].tv_sec,tv_exp[j].tv_usec,
3990 - tv_exp[j+1].tv_sec,tv_exp[j+1].tv_usec,
3991 - tv_exp[j+2].tv_sec,tv_exp[j+2].tv_usec,
3992 - tv_exp[j+3].tv_sec,tv_exp[j+3].tv_usec,
3993 - tv_exp[j+4].tv_sec,tv_exp[j+4].tv_usec);
3994 + tv_exp[j].tv_jiff,tv_exp[j].tv_usec,
3995 + tv_exp[j+1].tv_jiff,tv_exp[j+1].tv_usec,
3996 + tv_exp[j+2].tv_jiff,tv_exp[j+2].tv_usec,
3997 + tv_exp[j+3].tv_jiff,tv_exp[j+3].tv_usec,
3998 + tv_exp[j+4].tv_jiff,tv_exp[j+4].tv_usec);
3999 j += 4;
4000 }
4001 do_gettimeofday_fast(&tv0);
4002 @@ -895,9 +802,9 @@
4003 }
4004 }
4005 do_gettimeofday_fast(&tv2);
4006 - printk("Timers started %is %06i\n", tv0.tv_sec, tv0.tv_usec);
4007 - printk("Timers started at %is %06i\n", tv1.tv_sec, tv1.tv_usec);
4008 - printk("Timers done %is %06i\n", tv2.tv_sec, tv2.tv_usec);
4009 + printk("Timers started %is %06i\n", tv0.tv_jiff, tv0.tv_usec);
4010 + printk("Timers started at %is %06i\n", tv1.tv_jiff, tv1.tv_usec);
4011 + printk("Timers done %is %06i\n", tv2.tv_jiff, tv2.tv_usec);
4012 DP(printk("buf0:\n");
4013 printk(buf0);
4014 printk("buf1:\n");
4015 @@ -919,9 +826,9 @@
4016 printk("%-10s set: %6is %06ius exp: %6is %06ius "
4017 "data: 0x%08X func: 0x%08X\n",
4018 t->name,
4019 - t->tv_set.tv_sec,
4020 + t->tv_set.tv_jiff,
4021 t->tv_set.tv_usec,
4022 - t->tv_expires.tv_sec,
4023 + t->tv_expires.tv_jiff,
4024 t->tv_expires.tv_usec,
4025 t->data,
4026 t->function
4027 @@ -929,10 +836,10 @@
4028
4029 printk(" del: %6ius did exp: %6is %06ius as #%i error: %6li\n",
4030 t->delay_us,
4031 - tv_exp[j].tv_sec,
4032 + tv_exp[j].tv_jiff,
4033 tv_exp[j].tv_usec,
4034 exp_num[j],
4035 - (tv_exp[j].tv_sec - t->tv_expires.tv_sec)*1000000 + tv_exp[j].tv_usec - t->tv_expires.tv_usec);
4036 + (tv_exp[j].tv_jiff - t->tv_expires.tv_jiff)*1000000 + tv_exp[j].tv_usec - t->tv_expires.tv_usec);
4037 }
4038 proc_fasttimer_read(buf5, NULL, 0, 0, 0);
4039 printk("buf5 after all done:\n");
4040 @@ -942,7 +849,7 @@
4041 #endif
4042
4043
4044 -void fast_timer_init(void)
4045 +int fast_timer_init(void)
4046 {
4047 /* For some reason, request_irq() hangs when called froom time_init() */
4048 if (!fast_timer_is_init)
4049 @@ -975,4 +882,6 @@
4050 fast_timer_test();
4051 #endif
4052 }
4053 + return 0;
4054 }
4055 +__initcall(fast_timer_init);
4056 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/kernel/head.S linux-2.6.19.2.dev/arch/cris/arch-v10/kernel/head.S
4057 --- linux-2.6.19.2.old/arch/cris/arch-v10/kernel/head.S 2007-01-10 20:10:37.000000000 +0100
4058 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/kernel/head.S 2006-10-20 09:33:26.000000000 +0200
4059 @@ -1,4 +1,4 @@
4060 -/* $Id: head.S,v 1.10 2005/06/20 05:12:54 starvik Exp $
4061 +/* $Id: head.S,v 1.13 2006/10/20 07:33:26 kjelld Exp $
4062 *
4063 * Head of the kernel - alter with care
4064 *
4065 @@ -7,6 +7,19 @@
4066 * Authors: Bjorn Wesen (bjornw@axis.com)
4067 *
4068 * $Log: head.S,v $
4069 + * Revision 1.13 2006/10/20 07:33:26 kjelld
4070 + * If serial port 2 is used, select it in R_GEN_CONFIG.
4071 + * If serial port 2 is used, setup the control registers for the port.
4072 + * This is done to avoid a puls on the TXD line during start up.
4073 + * This puls could disturbe some units (e.g. some Axis 214 with internal
4074 + * ver. 1.08).
4075 + *
4076 + * Revision 1.12 2006/10/13 12:43:11 starvik
4077 + * Merge of 2.6.18
4078 + *
4079 + * Revision 1.11 2005/08/29 07:32:17 starvik
4080 + * Merge of 2.6.13
4081 + *
4082 * Revision 1.10 2005/06/20 05:12:54 starvik
4083 * Remove unnecessary diff to kernel.org tree
4084 *
4085 @@ -595,11 +608,17 @@
4086
4087 moveq 0,$r0
4088
4089 + ;; Select or disable serial port 2
4090 +#ifdef CONFIG_ETRAX_SERIAL_PORT2
4091 + or.d IO_STATE (R_GEN_CONFIG, ser2, select),$r0
4092 +#else
4093 + or.d IO_STATE (R_GEN_CONFIG, ser2, disable),$r0
4094 +#endif
4095 +
4096 ;; Init interfaces (disable them).
4097 or.d IO_STATE (R_GEN_CONFIG, scsi0, disable) \
4098 | IO_STATE (R_GEN_CONFIG, ata, disable) \
4099 | IO_STATE (R_GEN_CONFIG, par0, disable) \
4100 - | IO_STATE (R_GEN_CONFIG, ser2, disable) \
4101 | IO_STATE (R_GEN_CONFIG, mio, disable) \
4102 | IO_STATE (R_GEN_CONFIG, scsi1, disable) \
4103 | IO_STATE (R_GEN_CONFIG, scsi0w, disable) \
4104 @@ -801,6 +820,41 @@
4105 | IO_STATE (R_SERIAL1_TR_CTRL, tr_bitnr, tr_8bit),$r0
4106 move.b $r0,[R_SERIAL1_TR_CTRL]
4107
4108 +#ifdef CONFIG_ETRAX_SERIAL_PORT2
4109 + ;; setup the serial port 2 at 115200 baud for debug purposes
4110 +
4111 + moveq IO_STATE (R_SERIAL2_XOFF, tx_stop, enable) \
4112 + | IO_STATE (R_SERIAL2_XOFF, auto_xoff, disable) \
4113 + | IO_FIELD (R_SERIAL2_XOFF, xoff_char, 0),$r0
4114 + move.d $r0,[R_SERIAL2_XOFF]
4115 +
4116 + ; 115.2kbaud for both transmit and receive
4117 + move.b IO_STATE (R_SERIAL2_BAUD, tr_baud, c115k2Hz) \
4118 + | IO_STATE (R_SERIAL2_BAUD, rec_baud, c115k2Hz),$r0
4119 + move.b $r0,[R_SERIAL2_BAUD]
4120 +
4121 + ; Set up and enable the serial2 receiver.
4122 + move.b IO_STATE (R_SERIAL2_REC_CTRL, dma_err, stop) \
4123 + | IO_STATE (R_SERIAL2_REC_CTRL, rec_enable, enable) \
4124 + | IO_STATE (R_SERIAL2_REC_CTRL, rts_, active) \
4125 + | IO_STATE (R_SERIAL2_REC_CTRL, sampling, middle) \
4126 + | IO_STATE (R_SERIAL2_REC_CTRL, rec_stick_par, normal) \
4127 + | IO_STATE (R_SERIAL2_REC_CTRL, rec_par, even) \
4128 + | IO_STATE (R_SERIAL2_REC_CTRL, rec_par_en, disable) \
4129 + | IO_STATE (R_SERIAL2_REC_CTRL, rec_bitnr, rec_8bit),$r0
4130 + move.b $r0,[R_SERIAL2_REC_CTRL]
4131 +
4132 + ; Set up and enable the serial2 transmitter.
4133 + move.b IO_FIELD (R_SERIAL2_TR_CTRL, txd, 0) \
4134 + | IO_STATE (R_SERIAL2_TR_CTRL, tr_enable, enable) \
4135 + | IO_STATE (R_SERIAL2_TR_CTRL, auto_cts, disabled) \
4136 + | IO_STATE (R_SERIAL2_TR_CTRL, stop_bits, one_bit) \
4137 + | IO_STATE (R_SERIAL2_TR_CTRL, tr_stick_par, normal) \
4138 + | IO_STATE (R_SERIAL2_TR_CTRL, tr_par, even) \
4139 + | IO_STATE (R_SERIAL2_TR_CTRL, tr_par_en, disable) \
4140 + | IO_STATE (R_SERIAL2_TR_CTRL, tr_bitnr, tr_8bit),$r0
4141 + move.b $r0,[R_SERIAL2_TR_CTRL]
4142 +#endif
4143
4144 #ifdef CONFIG_ETRAX_SERIAL_PORT3
4145 ;; setup the serial port 3 at 115200 baud for debug purposes
4146 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/kernel/io_interface_mux.c linux-2.6.19.2.dev/arch/cris/arch-v10/kernel/io_interface_mux.c
4147 --- linux-2.6.19.2.old/arch/cris/arch-v10/kernel/io_interface_mux.c 2007-01-10 20:10:37.000000000 +0100
4148 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/kernel/io_interface_mux.c 2006-10-04 20:21:18.000000000 +0200
4149 @@ -1,10 +1,10 @@
4150 /* IO interface mux allocator for ETRAX100LX.
4151 - * Copyright 2004, Axis Communications AB
4152 - * $Id: io_interface_mux.c,v 1.2 2004/12/21 12:08:38 starvik Exp $
4153 + * Copyright 2004-2006, Axis Communications AB
4154 + * $Id: io_interface_mux.c,v 1.4 2006/10/04 18:21:18 henriken Exp $
4155 */
4156
4157
4158 -/* C.f. ETRAX100LX Designer's Reference 20.9 */
4159 +/* C.f. ETRAX100LX Designer's Reference 19.9 */
4160
4161 #include <linux/kernel.h>
4162 #include <linux/slab.h>
4163 @@ -35,7 +35,7 @@
4164 struct watcher
4165 {
4166 void (*notify)(const unsigned int gpio_in_available,
4167 - const unsigned int gpio_out_available,
4168 + const unsigned int gpio_out_available,
4169 const unsigned char pa_available,
4170 const unsigned char pb_available);
4171 struct watcher *next;
4172 @@ -45,17 +45,40 @@
4173 struct if_group
4174 {
4175 enum io_if_group group;
4176 - unsigned char used;
4177 - enum cris_io_interface owner;
4178 + // name - the name of the group 'A' to 'F'
4179 + char *name;
4180 + // used - a bit mask of all pins in the group in the order listed
4181 + // in in the tables in 19.9.1 to 19.9.6. Note that no
4182 + // distinction is made between in, out and in/out pins.
4183 + unsigned int used;
4184 };
4185
4186
4187 struct interface
4188 {
4189 enum cris_io_interface ioif;
4190 + // name - the name of the interface
4191 + char *name;
4192 + // groups - OR'ed together io_if_group flags describing what pin groups
4193 + // the interface uses pins in.
4194 unsigned char groups;
4195 + // used - set when the interface is allocated.
4196 unsigned char used;
4197 char *owner;
4198 + // group_a through group_f - bit masks describing what pins in the
4199 + // pin groups the interface uses.
4200 + unsigned int group_a;
4201 + unsigned int group_b;
4202 + unsigned int group_c;
4203 + unsigned int group_d;
4204 + unsigned int group_e;
4205 + unsigned int group_f;
4206 +
4207 + // gpio_g_in, gpio_g_out, gpio_b - bit masks telling what pins in the
4208 + // GPIO ports the interface uses. This
4209 + // could be reconstucted using the group_X
4210 + // masks and a table of what pins the GPIO
4211 + // ports use, but that would be messy.
4212 unsigned int gpio_g_in;
4213 unsigned int gpio_g_out;
4214 unsigned char gpio_b;
4215 @@ -64,26 +87,32 @@
4216 static struct if_group if_groups[6] = {
4217 {
4218 .group = group_a,
4219 + .name = "A",
4220 .used = 0,
4221 },
4222 {
4223 .group = group_b,
4224 + .name = "B",
4225 .used = 0,
4226 },
4227 {
4228 .group = group_c,
4229 + .name = "C",
4230 .used = 0,
4231 },
4232 {
4233 .group = group_d,
4234 + .name = "D",
4235 .used = 0,
4236 },
4237 {
4238 .group = group_e,
4239 + .name = "E",
4240 .used = 0,
4241 },
4242 {
4243 .group = group_f,
4244 + .name = "F",
4245 .used = 0,
4246 }
4247 };
4248 @@ -94,14 +123,32 @@
4249 /* Begin Non-multiplexed interfaces */
4250 {
4251 .ioif = if_eth,
4252 + .name = "ethernet",
4253 .groups = 0,
4254 +
4255 + .group_a = 0,
4256 + .group_b = 0,
4257 + .group_c = 0,
4258 + .group_d = 0,
4259 + .group_e = 0,
4260 + .group_f = 0,
4261 +
4262 .gpio_g_in = 0,
4263 .gpio_g_out = 0,
4264 .gpio_b = 0
4265 },
4266 {
4267 .ioif = if_serial_0,
4268 + .name = "serial_0",
4269 .groups = 0,
4270 +
4271 + .group_a = 0,
4272 + .group_b = 0,
4273 + .group_c = 0,
4274 + .group_d = 0,
4275 + .group_e = 0,
4276 + .group_f = 0,
4277 +
4278 .gpio_g_in = 0,
4279 .gpio_g_out = 0,
4280 .gpio_b = 0
4281 @@ -109,172 +156,385 @@
4282 /* End Non-multiplexed interfaces */
4283 {
4284 .ioif = if_serial_1,
4285 + .name = "serial_1",
4286 .groups = group_e,
4287 +
4288 + .group_a = 0,
4289 + .group_b = 0,
4290 + .group_c = 0,
4291 + .group_d = 0,
4292 + .group_e = 0x0f,
4293 + .group_f = 0,
4294 +
4295 .gpio_g_in = 0x00000000,
4296 .gpio_g_out = 0x00000000,
4297 .gpio_b = 0x00
4298 },
4299 {
4300 .ioif = if_serial_2,
4301 + .name = "serial_2",
4302 .groups = group_b,
4303 +
4304 + .group_a = 0,
4305 + .group_b = 0x0f,
4306 + .group_c = 0,
4307 + .group_d = 0,
4308 + .group_e = 0,
4309 + .group_f = 0,
4310 +
4311 .gpio_g_in = 0x000000c0,
4312 .gpio_g_out = 0x000000c0,
4313 .gpio_b = 0x00
4314 },
4315 {
4316 .ioif = if_serial_3,
4317 + .name = "serial_3",
4318 .groups = group_c,
4319 +
4320 + .group_a = 0,
4321 + .group_b = 0,
4322 + .group_c = 0x0f,
4323 + .group_d = 0,
4324 + .group_e = 0,
4325 + .group_f = 0,
4326 +
4327 .gpio_g_in = 0xc0000000,
4328 .gpio_g_out = 0xc0000000,
4329 .gpio_b = 0x00
4330 },
4331 {
4332 .ioif = if_sync_serial_1,
4333 - .groups = group_e | group_f, /* if_sync_serial_1 and if_sync_serial_3
4334 - can be used simultaneously */
4335 + .name = "sync_serial_1",
4336 + .groups = group_e | group_f,
4337 +
4338 + .group_a = 0,
4339 + .group_b = 0,
4340 + .group_c = 0,
4341 + .group_d = 0,
4342 + .group_e = 0x0f,
4343 + .group_f = 0x10,
4344 +
4345 .gpio_g_in = 0x00000000,
4346 .gpio_g_out = 0x00000000,
4347 .gpio_b = 0x10
4348 },
4349 {
4350 .ioif = if_sync_serial_3,
4351 + .name = "sync_serial_3",
4352 .groups = group_c | group_f,
4353 +
4354 + .group_a = 0,
4355 + .group_b = 0,
4356 + .group_c = 0x0f,
4357 + .group_d = 0,
4358 + .group_e = 0,
4359 + .group_f = 0x80,
4360 +
4361 .gpio_g_in = 0xc0000000,
4362 .gpio_g_out = 0xc0000000,
4363 .gpio_b = 0x80
4364 },
4365 {
4366 .ioif = if_shared_ram,
4367 + .name = "shared_ram",
4368 .groups = group_a,
4369 +
4370 + .group_a = 0x7f8ff,
4371 + .group_b = 0,
4372 + .group_c = 0,
4373 + .group_d = 0,
4374 + .group_e = 0,
4375 + .group_f = 0,
4376 +
4377 .gpio_g_in = 0x0000ff3e,
4378 .gpio_g_out = 0x0000ff38,
4379 .gpio_b = 0x00
4380 },
4381 {
4382 .ioif = if_shared_ram_w,
4383 + .name = "shared_ram_w",
4384 .groups = group_a | group_d,
4385 +
4386 + .group_a = 0x7f8ff,
4387 + .group_b = 0,
4388 + .group_c = 0,
4389 + .group_d = 0xff,
4390 + .group_e = 0,
4391 + .group_f = 0,
4392 +
4393 .gpio_g_in = 0x00ffff3e,
4394 .gpio_g_out = 0x00ffff38,
4395 .gpio_b = 0x00
4396 },
4397 {
4398 .ioif = if_par_0,
4399 + .name = "par_0",
4400 .groups = group_a,
4401 +
4402 + .group_a = 0x7fbff,
4403 + .group_b = 0,
4404 + .group_c = 0,
4405 + .group_d = 0,
4406 + .group_e = 0,
4407 + .group_f = 0,
4408 +
4409 .gpio_g_in = 0x0000ff3e,
4410 .gpio_g_out = 0x0000ff3e,
4411 .gpio_b = 0x00
4412 },
4413 {
4414 .ioif = if_par_1,
4415 + .name = "par_1",
4416 .groups = group_d,
4417 +
4418 + .group_a = 0,
4419 + .group_b = 0,
4420 + .group_c = 0,
4421 + .group_d = 0x7feff,
4422 + .group_e = 0,
4423 + .group_f = 0,
4424 +
4425 .gpio_g_in = 0x3eff0000,
4426 .gpio_g_out = 0x3eff0000,
4427 .gpio_b = 0x00
4428 },
4429 {
4430 .ioif = if_par_w,
4431 + .name = "par_w",
4432 .groups = group_a | group_d,
4433 +
4434 + .group_a = 0x7fbff,
4435 + .group_b = 0,
4436 + .group_c = 0,
4437 + .group_d = 0xff,
4438 + .group_e = 0,
4439 + .group_f = 0,
4440 +
4441 .gpio_g_in = 0x00ffff3e,
4442 .gpio_g_out = 0x00ffff3e,
4443 .gpio_b = 0x00
4444 },
4445 {
4446 .ioif = if_scsi8_0,
4447 - .groups = group_a | group_b | group_f, /* if_scsi8_0 and if_scsi8_1
4448 - can be used simultaneously */
4449 + .name = "scsi8_0",
4450 + .groups = group_a | group_b | group_f,
4451 +
4452 + .group_a = 0x7ffff,
4453 + .group_b = 0x0f,
4454 + .group_c = 0,
4455 + .group_d = 0,
4456 + .group_e = 0,
4457 + .group_f = 0x10,
4458 +
4459 .gpio_g_in = 0x0000ffff,
4460 .gpio_g_out = 0x0000ffff,
4461 .gpio_b = 0x10
4462 },
4463 {
4464 .ioif = if_scsi8_1,
4465 - .groups = group_c | group_d | group_f, /* if_scsi8_0 and if_scsi8_1
4466 - can be used simultaneously */
4467 + .name = "scsi8_1",
4468 + .groups = group_c | group_d | group_f,
4469 +
4470 + .group_a = 0,
4471 + .group_b = 0,
4472 + .group_c = 0x0f,
4473 + .group_d = 0x7ffff,
4474 + .group_e = 0,
4475 + .group_f = 0x80,
4476 +
4477 .gpio_g_in = 0xffff0000,
4478 .gpio_g_out = 0xffff0000,
4479 .gpio_b = 0x80
4480 },
4481 {
4482 .ioif = if_scsi_w,
4483 + .name = "scsi_w",
4484 .groups = group_a | group_b | group_d | group_f,
4485 +
4486 + .group_a = 0x7ffff,
4487 + .group_b = 0x0f,
4488 + .group_c = 0,
4489 + .group_d = 0x601ff,
4490 + .group_e = 0,
4491 + .group_f = 0x90,
4492 +
4493 .gpio_g_in = 0x01ffffff,
4494 .gpio_g_out = 0x07ffffff,
4495 .gpio_b = 0x80
4496 },
4497 {
4498 .ioif = if_ata,
4499 + .name = "ata",
4500 .groups = group_a | group_b | group_c | group_d,
4501 +
4502 + .group_a = 0x7ffff,
4503 + .group_b = 0x0f,
4504 + .group_c = 0x0f,
4505 + .group_d = 0x7cfff,
4506 + .group_e = 0,
4507 + .group_f = 0,
4508 +
4509 .gpio_g_in = 0xf9ffffff,
4510 .gpio_g_out = 0xffffffff,
4511 .gpio_b = 0x80
4512 },
4513 {
4514 .ioif = if_csp,
4515 - .groups = group_f, /* if_csp and if_i2c can be used simultaneously */
4516 + .name = "csp",
4517 + .groups = group_f,
4518 +
4519 + .group_a = 0,
4520 + .group_b = 0,
4521 + .group_c = 0,
4522 + .group_d = 0,
4523 + .group_e = 0,
4524 + .group_f = 0xfc,
4525 +
4526 .gpio_g_in = 0x00000000,
4527 .gpio_g_out = 0x00000000,
4528 .gpio_b = 0xfc
4529 },
4530 {
4531 .ioif = if_i2c,
4532 - .groups = group_f, /* if_csp and if_i2c can be used simultaneously */
4533 + .name = "i2c",
4534 + .groups = group_f,
4535 +
4536 + .group_a = 0,
4537 + .group_b = 0,
4538 + .group_c = 0,
4539 + .group_d = 0,
4540 + .group_e = 0,
4541 + .group_f = 0x03,
4542 +
4543 .gpio_g_in = 0x00000000,
4544 .gpio_g_out = 0x00000000,
4545 .gpio_b = 0x03
4546 },
4547 {
4548 .ioif = if_usb_1,
4549 + .name = "usb_1",
4550 .groups = group_e | group_f,
4551 +
4552 + .group_a = 0,
4553 + .group_b = 0,
4554 + .group_c = 0,
4555 + .group_d = 0,
4556 + .group_e = 0x0f,
4557 + .group_f = 0x2c,
4558 +
4559 .gpio_g_in = 0x00000000,
4560 .gpio_g_out = 0x00000000,
4561 .gpio_b = 0x2c
4562 },
4563 {
4564 .ioif = if_usb_2,
4565 + .name = "usb_2",
4566 .groups = group_d,
4567 - .gpio_g_in = 0x0e000000,
4568 - .gpio_g_out = 0x3c000000,
4569 +
4570 + .group_a = 0,
4571 + .group_b = 0,
4572 + .group_c = 0,
4573 + .group_d = 0,
4574 + .group_e = 0x33e00,
4575 + .group_f = 0,
4576 +
4577 + .gpio_g_in = 0x3e000000,
4578 + .gpio_g_out = 0x0c000000,
4579 .gpio_b = 0x00
4580 },
4581 /* GPIO pins */
4582 {
4583 .ioif = if_gpio_grp_a,
4584 + .name = "gpio_a",
4585 .groups = group_a,
4586 +
4587 + .group_a = 0,
4588 + .group_b = 0,
4589 + .group_c = 0,
4590 + .group_d = 0,
4591 + .group_e = 0,
4592 + .group_f = 0,
4593 +
4594 .gpio_g_in = 0x0000ff3f,
4595 .gpio_g_out = 0x0000ff3f,
4596 .gpio_b = 0x00
4597 },
4598 {
4599 .ioif = if_gpio_grp_b,
4600 + .name = "gpio_b",
4601 .groups = group_b,
4602 +
4603 + .group_a = 0,
4604 + .group_b = 0,
4605 + .group_c = 0,
4606 + .group_d = 0,
4607 + .group_e = 0,
4608 + .group_f = 0,
4609 +
4610 .gpio_g_in = 0x000000c0,
4611 .gpio_g_out = 0x000000c0,
4612 .gpio_b = 0x00
4613 },
4614 {
4615 .ioif = if_gpio_grp_c,
4616 + .name = "gpio_c",
4617 .groups = group_c,
4618 +
4619 + .group_a = 0,
4620 + .group_b = 0,
4621 + .group_c = 0,
4622 + .group_d = 0,
4623 + .group_e = 0,
4624 + .group_f = 0,
4625 +
4626 .gpio_g_in = 0xc0000000,
4627 .gpio_g_out = 0xc0000000,
4628 .gpio_b = 0x00
4629 },
4630 {
4631 .ioif = if_gpio_grp_d,
4632 + .name = "gpio_d",
4633 .groups = group_d,
4634 +
4635 + .group_a = 0,
4636 + .group_b = 0,
4637 + .group_c = 0,
4638 + .group_d = 0,
4639 + .group_e = 0,
4640 + .group_f = 0,
4641 +
4642 .gpio_g_in = 0x3fff0000,
4643 .gpio_g_out = 0x3fff0000,
4644 .gpio_b = 0x00
4645 },
4646 {
4647 .ioif = if_gpio_grp_e,
4648 + .name = "gpio_e",
4649 .groups = group_e,
4650 +
4651 + .group_a = 0,
4652 + .group_b = 0,
4653 + .group_c = 0,
4654 + .group_d = 0,
4655 + .group_e = 0,
4656 + .group_f = 0,
4657 +
4658 .gpio_g_in = 0x00000000,
4659 .gpio_g_out = 0x00000000,
4660 .gpio_b = 0x00
4661 },
4662 {
4663 .ioif = if_gpio_grp_f,
4664 + .name = "gpio_f",
4665 .groups = group_f,
4666 +
4667 + .group_a = 0,
4668 + .group_b = 0,
4669 + .group_c = 0,
4670 + .group_d = 0,
4671 + .group_e = 0,
4672 + .group_f = 0,
4673 +
4674 .gpio_g_in = 0x00000000,
4675 .gpio_g_out = 0x00000000,
4676 .gpio_b = 0xff
4677 @@ -284,11 +544,13 @@
4678
4679 static struct watcher *watchers = NULL;
4680
4681 +// The pins that are free to use in the GPIO ports.
4682 static unsigned int gpio_in_pins = 0xffffffff;
4683 static unsigned int gpio_out_pins = 0xffffffff;
4684 static unsigned char gpio_pb_pins = 0xff;
4685 static unsigned char gpio_pa_pins = 0xff;
4686
4687 +// Identifiers for the owners of the GPIO pins.
4688 static enum cris_io_interface gpio_pa_owners[8];
4689 static enum cris_io_interface gpio_pb_owners[8];
4690 static enum cris_io_interface gpio_pg_owners[32];
4691 @@ -318,7 +580,7 @@
4692 struct watcher *w = watchers;
4693
4694 DBG(printk("io_interface_mux: notifying watchers\n"));
4695 -
4696 +
4697 while (NULL != w) {
4698 w->notify((const unsigned int)gpio_in_pins,
4699 (const unsigned int)gpio_out_pins,
4700 @@ -354,37 +616,48 @@
4701
4702 if (interfaces[ioif].used) {
4703 local_irq_restore(flags);
4704 - printk(KERN_CRIT "cris_io_interface: Cannot allocate interface for %s, in use by %s\n",
4705 + printk(KERN_CRIT "cris_io_interface: Cannot allocate interface %s for %s, in use by %s\n",
4706 + interfaces[ioif].name,
4707 device_id,
4708 interfaces[ioif].owner);
4709 return -EBUSY;
4710 }
4711
4712 - /* Check that all required groups are free before allocating, */
4713 + /* Check that all required pins in the used groups are free
4714 + * before allocating. */
4715 group_set = interfaces[ioif].groups;
4716 while (NULL != (grp = get_group(group_set))) {
4717 - if (grp->used) {
4718 - if (grp->group == group_f) {
4719 - if ((if_sync_serial_1 == ioif) ||
4720 - (if_sync_serial_3 == ioif)) {
4721 - if ((grp->owner != if_sync_serial_1) &&
4722 - (grp->owner != if_sync_serial_3)) {
4723 - local_irq_restore(flags);
4724 - return -EBUSY;
4725 - }
4726 - } else if ((if_scsi8_0 == ioif) ||
4727 - (if_scsi8_1 == ioif)) {
4728 - if ((grp->owner != if_scsi8_0) &&
4729 - (grp->owner != if_scsi8_1)) {
4730 - local_irq_restore(flags);
4731 - return -EBUSY;
4732 - }
4733 - }
4734 - } else {
4735 - local_irq_restore(flags);
4736 - return -EBUSY;
4737 - }
4738 + unsigned int if_group_use = 0;
4739 +
4740 + switch(grp->group) {
4741 + case group_a:
4742 + if_group_use = interfaces[ioif].group_a;
4743 + break;
4744 + case group_b:
4745 + if_group_use = interfaces[ioif].group_b;
4746 + break;
4747 + case group_c:
4748 + if_group_use = interfaces[ioif].group_c;
4749 + break;
4750 + case group_d:
4751 + if_group_use = interfaces[ioif].group_d;
4752 + break;
4753 + case group_e:
4754 + if_group_use = interfaces[ioif].group_e;
4755 + break;
4756 + case group_f:
4757 + if_group_use = interfaces[ioif].group_f;
4758 + break;
4759 + default:
4760 + BUG_ON(1);
4761 }
4762 +
4763 + if(if_group_use & grp->used) {
4764 + local_irq_restore(flags);
4765 + printk(KERN_INFO "cris_request_io_interface: group %s needed by %s not available\n", grp->name, interfaces[ioif].name);
4766 + return -EBUSY;
4767 + }
4768 +
4769 group_set = clear_group_from_set(group_set, grp);
4770 }
4771
4772 @@ -392,22 +665,16 @@
4773 if (((interfaces[ioif].gpio_g_in & gpio_in_pins) != interfaces[ioif].gpio_g_in) ||
4774 ((interfaces[ioif].gpio_g_out & gpio_out_pins) != interfaces[ioif].gpio_g_out) ||
4775 ((interfaces[ioif].gpio_b & gpio_pb_pins) != interfaces[ioif].gpio_b)) {
4776 - printk(KERN_CRIT "cris_request_io_interface: Could not get required pins for interface %u\n",
4777 - ioif);
4778 + local_irq_restore(flags);
4779 + printk(KERN_CRIT "cris_request_io_interface: Could not get required pins for interface %s\n",
4780 + interfaces[ioif].name);
4781 return -EBUSY;
4782 }
4783
4784 - /* All needed I/O pins and pin groups are free, allocate. */
4785 - group_set = interfaces[ioif].groups;
4786 - while (NULL != (grp = get_group(group_set))) {
4787 - grp->used = 1;
4788 - grp->owner = ioif;
4789 - group_set = clear_group_from_set(group_set, grp);
4790 - }
4791 -
4792 + /* Check which registers need to be reconfigured. */
4793 gens = genconfig_shadow;
4794 gens_ii = gen_config_ii_shadow;
4795 -
4796 +
4797 set_gen_config = 1;
4798 switch (ioif)
4799 {
4800 @@ -494,9 +761,43 @@
4801 set_gen_config = 0;
4802 break;
4803 default:
4804 - panic("cris_request_io_interface: Bad interface %u submitted for %s\n",
4805 - ioif,
4806 - device_id);
4807 + local_irq_restore(flags);
4808 + printk(KERN_INFO "cris_request_io_interface: Bad interface %u submitted for %s\n",
4809 + ioif,
4810 + device_id);
4811 + return -EBUSY;
4812 + }
4813 +
4814 + /* All needed I/O pins and pin groups are free, allocate. */
4815 + group_set = interfaces[ioif].groups;
4816 + while (NULL != (grp = get_group(group_set))) {
4817 + unsigned int if_group_use = 0;
4818 +
4819 + switch(grp->group) {
4820 + case group_a:
4821 + if_group_use = interfaces[ioif].group_a;
4822 + break;
4823 + case group_b:
4824 + if_group_use = interfaces[ioif].group_b;
4825 + break;
4826 + case group_c:
4827 + if_group_use = interfaces[ioif].group_c;
4828 + break;
4829 + case group_d:
4830 + if_group_use = interfaces[ioif].group_d;
4831 + break;
4832 + case group_e:
4833 + if_group_use = interfaces[ioif].group_e;
4834 + break;
4835 + case group_f:
4836 + if_group_use = interfaces[ioif].group_f;
4837 + break;
4838 + default:
4839 + BUG_ON(1);
4840 + }
4841 + grp->used |= if_group_use;
4842 +
4843 + group_set = clear_group_from_set(group_set, grp);
4844 }
4845
4846 interfaces[ioif].used = 1;
4847 @@ -528,7 +829,7 @@
4848
4849 DBG(printk("GPIO pins: available after: g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
4850 gpio_in_pins, gpio_out_pins, gpio_pb_pins));
4851 -
4852 +
4853 local_irq_restore(flags);
4854
4855 notify_watchers();
4856 @@ -559,43 +860,36 @@
4857 }
4858 group_set = interfaces[ioif].groups;
4859 while (NULL != (grp = get_group(group_set))) {
4860 - if (grp->group == group_f) {
4861 - switch (ioif)
4862 - {
4863 - case if_sync_serial_1:
4864 - if ((grp->owner == if_sync_serial_1) &&
4865 - interfaces[if_sync_serial_3].used) {
4866 - grp->owner = if_sync_serial_3;
4867 - } else
4868 - grp->used = 0;
4869 - break;
4870 - case if_sync_serial_3:
4871 - if ((grp->owner == if_sync_serial_3) &&
4872 - interfaces[if_sync_serial_1].used) {
4873 - grp->owner = if_sync_serial_1;
4874 - } else
4875 - grp->used = 0;
4876 - break;
4877 - case if_scsi8_0:
4878 - if ((grp->owner == if_scsi8_0) &&
4879 - interfaces[if_scsi8_1].used) {
4880 - grp->owner = if_scsi8_1;
4881 - } else
4882 - grp->used = 0;
4883 - break;
4884 - case if_scsi8_1:
4885 - if ((grp->owner == if_scsi8_1) &&
4886 - interfaces[if_scsi8_0].used) {
4887 - grp->owner = if_scsi8_0;
4888 - } else
4889 - grp->used = 0;
4890 - break;
4891 - default:
4892 - grp->used = 0;
4893 - }
4894 - } else {
4895 - grp->used = 0;
4896 + unsigned int if_group_use = 0;
4897 +
4898 + switch(grp->group) {
4899 + case group_a:
4900 + if_group_use = interfaces[ioif].group_a;
4901 + break;
4902 + case group_b:
4903 + if_group_use = interfaces[ioif].group_b;
4904 + break;
4905 + case group_c:
4906 + if_group_use = interfaces[ioif].group_c;
4907 + break;
4908 + case group_d:
4909 + if_group_use = interfaces[ioif].group_d;
4910 + break;
4911 + case group_e:
4912 + if_group_use = interfaces[ioif].group_e;
4913 + break;
4914 + case group_f:
4915 + if_group_use = interfaces[ioif].group_f;
4916 + break;
4917 + default:
4918 + BUG_ON(1);
4919 }
4920 +
4921 + if ((grp->used & if_group_use) != if_group_use) {
4922 + BUG_ON(1);
4923 + }
4924 + grp->used = grp->used & ~if_group_use;
4925 +
4926 group_set = clear_group_from_set(group_set, grp);
4927 }
4928 interfaces[ioif].used = 0;
4929 @@ -784,7 +1078,7 @@
4930
4931 for (i = start_bit; i <= stop_bit; i++) {
4932 owners[i] = if_unclaimed;
4933 - }
4934 + }
4935 local_irq_restore(flags);
4936 notify_watchers();
4937
4938 @@ -821,7 +1115,7 @@
4939 }
4940
4941 void cris_io_interface_delete_watcher(void (*notify)(const unsigned int gpio_in_available,
4942 - const unsigned int gpio_out_available,
4943 + const unsigned int gpio_out_available,
4944 const unsigned char pa_available,
4945 const unsigned char pb_available))
4946 {
4947 @@ -870,7 +1164,7 @@
4948
4949 module_init(cris_io_interface_init);
4950
4951 -
4952 +
4953 EXPORT_SYMBOL(cris_request_io_interface);
4954 EXPORT_SYMBOL(cris_free_io_interface);
4955 EXPORT_SYMBOL(cris_io_interface_allocate_pins);
4956 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/kernel/irq.c linux-2.6.19.2.dev/arch/cris/arch-v10/kernel/irq.c
4957 --- linux-2.6.19.2.old/arch/cris/arch-v10/kernel/irq.c 2007-01-10 20:10:37.000000000 +0100
4958 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/kernel/irq.c 2006-10-30 16:17:03.000000000 +0100
4959 @@ -1,4 +1,4 @@
4960 -/* $Id: irq.c,v 1.4 2005/01/04 12:22:28 starvik Exp $
4961 +/* $Id: irq.c,v 1.9 2006/10/30 15:17:03 pkj Exp $
4962 *
4963 * linux/arch/cris/kernel/irq.c
4964 *
4965 @@ -12,7 +12,9 @@
4966 */
4967
4968 #include <asm/irq.h>
4969 +#include <asm/current.h>
4970 #include <linux/irq.h>
4971 +#include <linux/interrupt.h>
4972 #include <linux/kernel.h>
4973 #include <linux/init.h>
4974
4975 @@ -75,8 +77,8 @@
4976 BUILD_IRQ(13, 0x2000)
4977 void mmu_bus_fault(void); /* IRQ 14 is the bus fault interrupt */
4978 void multiple_interrupt(void); /* IRQ 15 is the multiple IRQ interrupt */
4979 -BUILD_IRQ(16, 0x10000)
4980 -BUILD_IRQ(17, 0x20000)
4981 +BUILD_IRQ(16, 0x10000 | 0x20000) /* ethernet tx interrupt needs to block rx */
4982 +BUILD_IRQ(17, 0x20000 | 0x10000) /* ...and vice versa */
4983 BUILD_IRQ(18, 0x40000)
4984 BUILD_IRQ(19, 0x80000)
4985 BUILD_IRQ(20, 0x100000)
4986 @@ -147,6 +149,55 @@
4987 void do_sigtrap(void); /* from entry.S */
4988 void gdb_handle_breakpoint(void); /* from entry.S */
4989
4990 +extern void do_IRQ(int irq, struct pt_regs * regs);
4991 +
4992 +/* Handle multiple IRQs */
4993 +void do_multiple_IRQ(struct pt_regs* regs)
4994 +{
4995 + int bit;
4996 + unsigned masked;
4997 + unsigned mask;
4998 + unsigned ethmask = 0;
4999 +
5000 + /* Get interrupts to mask and handle */
5001 + mask = masked = *R_VECT_MASK_RD;
5002 +
5003 + /* Never mask timer IRQ */
5004 + mask &= ~(IO_MASK(R_VECT_MASK_RD, timer0));
5005 +
5006 + /*
5007 + * If either ethernet interrupt (rx or tx) is active then block
5008 + * the other one too. Unblock afterwards also.
5009 + */
5010 + if (mask &
5011 + (IO_STATE(R_VECT_MASK_RD, dma0, active) |
5012 + IO_STATE(R_VECT_MASK_RD, dma1, active))) {
5013 + ethmask = (IO_MASK(R_VECT_MASK_RD, dma0) |
5014 + IO_MASK(R_VECT_MASK_RD, dma1));
5015 + }
5016 +
5017 + /* Block them */
5018 + *R_VECT_MASK_CLR = (mask | ethmask);
5019 +
5020 + /* An extra irq_enter here to prevent softIRQs to run after
5021 + * each do_IRQ. This will decrease the interrupt latency.
5022 + */
5023 + irq_enter();
5024 +
5025 + /* Handle all IRQs */
5026 + for (bit = 2; bit < 32; bit++) {
5027 + if (masked & (1 << bit)) {
5028 + do_IRQ(bit, regs);
5029 + }
5030 + }
5031 +
5032 + /* This irq_exit() will trigger the soft IRQs. */
5033 + irq_exit();
5034 +
5035 + /* Unblock the IRQs again */
5036 + *R_VECT_MASK_SET = (masked | ethmask);
5037 +}
5038 +
5039 /* init_IRQ() is called by start_kernel and is responsible for fixing IRQ masks and
5040 setting the irq vector table.
5041 */
5042 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/kernel/kgdb.c linux-2.6.19.2.dev/arch/cris/arch-v10/kernel/kgdb.c
5043 --- linux-2.6.19.2.old/arch/cris/arch-v10/kernel/kgdb.c 2007-01-10 20:10:37.000000000 +0100
5044 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/kernel/kgdb.c 2006-03-22 10:56:55.000000000 +0100
5045 @@ -18,6 +18,10 @@
5046 *! Jul 21 1999 Bjorn Wesen eLinux port
5047 *!
5048 *! $Log: kgdb.c,v $
5049 +*! Revision 1.7 2006/03/22 09:56:55 starvik
5050 +*! Merge of Linux 2.6.16
5051 +*!
5052 +*!
5053 *! Revision 1.6 2005/01/14 10:12:17 starvik
5054 *! KGDB on separate port.
5055 *! Console fixes from 2.4.
5056 @@ -75,7 +79,7 @@
5057 *!
5058 *!---------------------------------------------------------------------------
5059 *!
5060 -*! $Id: kgdb.c,v 1.6 2005/01/14 10:12:17 starvik Exp $
5061 +*! $Id: kgdb.c,v 1.7 2006/03/22 09:56:55 starvik Exp $
5062 *!
5063 *! (C) Copyright 1999, Axis Communications AB, LUND, SWEDEN
5064 *!
5065 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/kernel/process.c linux-2.6.19.2.dev/arch/cris/arch-v10/kernel/process.c
5066 --- linux-2.6.19.2.old/arch/cris/arch-v10/kernel/process.c 2007-01-10 20:10:37.000000000 +0100
5067 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/kernel/process.c 2006-10-13 14:43:11.000000000 +0200
5068 @@ -1,4 +1,4 @@
5069 -/* $Id: process.c,v 1.12 2004/12/27 11:18:32 starvik Exp $
5070 +/* $Id: process.c,v 1.14 2006/10/13 12:43:11 starvik Exp $
5071 *
5072 * linux/arch/cris/kernel/process.c
5073 *
5074 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/kernel/ptrace.c linux-2.6.19.2.dev/arch/cris/arch-v10/kernel/ptrace.c
5075 --- linux-2.6.19.2.old/arch/cris/arch-v10/kernel/ptrace.c 2007-01-10 20:10:37.000000000 +0100
5076 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/kernel/ptrace.c 2006-10-30 16:17:57.000000000 +0100
5077 @@ -66,6 +66,7 @@
5078 ptrace_disable(struct task_struct *child)
5079 {
5080 /* Todo - pending singlesteps? */
5081 + clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
5082 }
5083
5084 /*
5085 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/kernel/setup.c linux-2.6.19.2.dev/arch/cris/arch-v10/kernel/setup.c
5086 --- linux-2.6.19.2.old/arch/cris/arch-v10/kernel/setup.c 2007-01-10 20:10:37.000000000 +0100
5087 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/kernel/setup.c 2006-10-13 14:43:11.000000000 +0200
5088 @@ -1,4 +1,4 @@
5089 -/*
5090 +/*
5091 *
5092 * linux/arch/cris/arch-v10/kernel/setup.c
5093 *
5094 @@ -13,6 +13,7 @@
5095 #include <linux/seq_file.h>
5096 #include <linux/proc_fs.h>
5097 #include <linux/delay.h>
5098 +#include <linux/param.h>
5099
5100 #ifdef CONFIG_PROC_FS
5101 #define HAS_FPU 0x0001
5102 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/kernel/signal.c linux-2.6.19.2.dev/arch/cris/arch-v10/kernel/signal.c
5103 --- linux-2.6.19.2.old/arch/cris/arch-v10/kernel/signal.c 2007-01-10 20:10:37.000000000 +0100
5104 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/kernel/signal.c 2006-03-22 10:56:55.000000000 +0100
5105 @@ -41,7 +41,7 @@
5106 */
5107 #define RESTART_CRIS_SYS(regs) regs->r10 = regs->orig_r10; regs->irp -= 2;
5108
5109 -int do_signal(int canrestart, sigset_t *oldset, struct pt_regs *regs);
5110 +void do_signal(int canrestart, struct pt_regs *regs);
5111
5112 /*
5113 * Atomically swap in the new signal mask, and wait for a signal. Define
5114 @@ -52,68 +52,16 @@
5115 sys_sigsuspend(old_sigset_t mask, long r11, long r12, long r13, long mof,
5116 long srp, struct pt_regs *regs)
5117 {
5118 - sigset_t saveset;
5119 -
5120 mask &= _BLOCKABLE;
5121 spin_lock_irq(&current->sighand->siglock);
5122 - saveset = current->blocked;
5123 - siginitset(&current->blocked, mask);
5124 - recalc_sigpending();
5125 - spin_unlock_irq(&current->sighand->siglock);
5126 -
5127 - regs->r10 = -EINTR;
5128 - while (1) {
5129 - current->state = TASK_INTERRUPTIBLE;
5130 - schedule();
5131 - if (do_signal(0, &saveset, regs))
5132 - /* We will get here twice: once to call the signal
5133 - handler, then again to return from the
5134 - sigsuspend system call. When calling the
5135 - signal handler, R10 holds the signal number as
5136 - set through do_signal. The sigsuspend call
5137 - will return with the restored value set above;
5138 - always -EINTR. */
5139 - return regs->r10;
5140 - }
5141 -}
5142 -
5143 -/* Define dummy arguments to be able to reach the regs argument. (Note that
5144 - * this arrangement relies on size_t occupying one register.)
5145 - */
5146 -int
5147 -sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, long r12, long r13,
5148 - long mof, long srp, struct pt_regs *regs)
5149 -{
5150 - sigset_t saveset, newset;
5151 -
5152 - /* XXX: Don't preclude handling different sized sigset_t's. */
5153 - if (sigsetsize != sizeof(sigset_t))
5154 - return -EINVAL;
5155 -
5156 - if (copy_from_user(&newset, unewset, sizeof(newset)))
5157 - return -EFAULT;
5158 - sigdelsetmask(&newset, ~_BLOCKABLE);
5159 -
5160 - spin_lock_irq(&current->sighand->siglock);
5161 - saveset = current->blocked;
5162 - current->blocked = newset;
5163 + current->saved_sigmask = current->blocked;
5164 + siginitset(&current->blocked, mask);
5165 recalc_sigpending();
5166 spin_unlock_irq(&current->sighand->siglock);
5167 -
5168 - regs->r10 = -EINTR;
5169 - while (1) {
5170 - current->state = TASK_INTERRUPTIBLE;
5171 - schedule();
5172 - if (do_signal(0, &saveset, regs))
5173 - /* We will get here twice: once to call the signal
5174 - handler, then again to return from the
5175 - sigsuspend system call. When calling the
5176 - signal handler, R10 holds the signal number as
5177 - set through do_signal. The sigsuspend call
5178 - will return with the restored value set above;
5179 - always -EINTR. */
5180 - return regs->r10;
5181 - }
5182 + current->state = TASK_INTERRUPTIBLE;
5183 + schedule();
5184 + set_thread_flag(TIF_RESTORE_SIGMASK);
5185 + return -ERESTARTNOHAND;
5186 }
5187
5188 int
5189 @@ -353,8 +301,8 @@
5190 * user-mode trampoline.
5191 */
5192
5193 -static void setup_frame(int sig, struct k_sigaction *ka,
5194 - sigset_t *set, struct pt_regs * regs)
5195 +static int setup_frame(int sig, struct k_sigaction *ka,
5196 + sigset_t *set, struct pt_regs * regs)
5197 {
5198 struct sigframe __user *frame;
5199 unsigned long return_ip;
5200 @@ -402,14 +350,15 @@
5201
5202 wrusp((unsigned long)frame);
5203
5204 - return;
5205 + return 0;
5206
5207 give_sigsegv:
5208 force_sigsegv(sig, current);
5209 + return -EFAULT;
5210 }
5211
5212 -static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
5213 - sigset_t *set, struct pt_regs * regs)
5214 +static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
5215 + sigset_t *set, struct pt_regs * regs)
5216 {
5217 struct rt_sigframe __user *frame;
5218 unsigned long return_ip;
5219 @@ -466,21 +415,24 @@
5220
5221 wrusp((unsigned long)frame);
5222
5223 - return;
5224 + return 0;
5225
5226 give_sigsegv:
5227 force_sigsegv(sig, current);
5228 + return -EFAULT;
5229 }
5230
5231 /*
5232 * OK, we're invoking a handler
5233 */
5234
5235 -static inline void
5236 +static inline int
5237 handle_signal(int canrestart, unsigned long sig,
5238 siginfo_t *info, struct k_sigaction *ka,
5239 sigset_t *oldset, struct pt_regs * regs)
5240 {
5241 + int ret;
5242 +
5243 /* Are we from a system call? */
5244 if (canrestart) {
5245 /* If so, check system call restarting.. */
5246 @@ -510,19 +462,20 @@
5247
5248 /* Set up the stack frame */
5249 if (ka->sa.sa_flags & SA_SIGINFO)
5250 - setup_rt_frame(sig, ka, info, oldset, regs);
5251 + ret = setup_rt_frame(sig, ka, info, oldset, regs);
5252 else
5253 - setup_frame(sig, ka, oldset, regs);
5254 + ret = setup_frame(sig, ka, oldset, regs);
5255
5256 - if (ka->sa.sa_flags & SA_ONESHOT)
5257 - ka->sa.sa_handler = SIG_DFL;
5258 + if (ret == 0) {
5259 + spin_lock_irq(&current->sighand->siglock);
5260 + sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
5261 + if (!(ka->sa.sa_flags & SA_NODEFER))
5262 + sigaddset(&current->blocked,sig);
5263 + recalc_sigpending();
5264 + spin_unlock_irq(&current->sighand->siglock);
5265 + }
5266
5267 - spin_lock_irq(&current->sighand->siglock);
5268 - sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
5269 - if (!(ka->sa.sa_flags & SA_NODEFER))
5270 - sigaddset(&current->blocked,sig);
5271 - recalc_sigpending();
5272 - spin_unlock_irq(&current->sighand->siglock);
5273 + return ret;
5274 }
5275
5276 /*
5277 @@ -537,12 +490,13 @@
5278 * mode below.
5279 */
5280
5281 -int do_signal(int canrestart, sigset_t *oldset, struct pt_regs *regs)
5282 +void do_signal(int canrestart, struct pt_regs *regs)
5283 {
5284 siginfo_t info;
5285 int signr;
5286 struct k_sigaction ka;
5287 -
5288 + sigset_t *oldset;
5289 +
5290 /*
5291 * We want the common case to go fast, which
5292 * is why we may in certain cases get here from
5293 @@ -550,16 +504,26 @@
5294 * if so.
5295 */
5296 if (!user_mode(regs))
5297 - return 1;
5298 + return;
5299
5300 - if (!oldset)
5301 + if (test_thread_flag(TIF_RESTORE_SIGMASK))
5302 + oldset = &current->saved_sigmask;
5303 + else
5304 oldset = &current->blocked;
5305
5306 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
5307 if (signr > 0) {
5308 /* Whee! Actually deliver the signal. */
5309 - handle_signal(canrestart, signr, &info, &ka, oldset, regs);
5310 - return 1;
5311 + if (handle_signal(canrestart, signr, &info, &ka, oldset, regs)) {
5312 + /* a signal was successfully delivered; the saved
5313 + * sigmask will have been stored in the signal frame,
5314 + * and will be restored by sigreturn, so we can simply
5315 + * clear the TIF_RESTORE_SIGMASK flag */
5316 + if (test_thread_flag(TIF_RESTORE_SIGMASK))
5317 + clear_thread_flag(TIF_RESTORE_SIGMASK);
5318 + }
5319 +
5320 + return;
5321 }
5322
5323 /* Did we come from a system call? */
5324 @@ -575,5 +539,11 @@
5325 regs->irp -= 2;
5326 }
5327 }
5328 - return 0;
5329 +
5330 + /* if there's no signal to deliver, we just put the saved sigmask
5331 + * back */
5332 + if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
5333 + clear_thread_flag(TIF_RESTORE_SIGMASK);
5334 + sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
5335 + }
5336 }
5337 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/kernel/time.c linux-2.6.19.2.dev/arch/cris/arch-v10/kernel/time.c
5338 --- linux-2.6.19.2.old/arch/cris/arch-v10/kernel/time.c 2007-01-10 20:10:37.000000000 +0100
5339 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/kernel/time.c 2007-01-09 10:29:18.000000000 +0100
5340 @@ -1,4 +1,4 @@
5341 -/* $Id: time.c,v 1.5 2004/09/29 06:12:46 starvik Exp $
5342 +/* $Id: time.c,v 1.10 2007/01/09 09:29:18 starvik Exp $
5343 *
5344 * linux/arch/cris/arch-v10/kernel/time.c
5345 *
5346 @@ -20,6 +20,7 @@
5347 #include <asm/io.h>
5348 #include <asm/delay.h>
5349 #include <asm/rtc.h>
5350 +#include <asm/irq_regs.h>
5351
5352 /* define this if you need to use print_timestamp */
5353 /* it will make jiffies at 96 hz instead of 100 hz though */
5354 @@ -202,8 +203,9 @@
5355 extern void cris_do_profile(struct pt_regs *regs);
5356
5357 static inline irqreturn_t
5358 -timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
5359 +timer_interrupt(int irq, void *dev_id)
5360 {
5361 + struct pt_regs* regs = get_irq_regs();
5362 /* acknowledge the timer irq */
5363
5364 #ifdef USE_CASCADE_TIMERS
5365 @@ -222,9 +224,11 @@
5366 #endif
5367
5368 /* reset watchdog otherwise it resets us! */
5369 -
5370 reset_watchdog();
5371
5372 + /* Update statistics. */
5373 + update_process_times(user_mode(regs));
5374 +
5375 /* call the real timer interrupt handler */
5376
5377 do_timer(1);
5378 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/kernel/traps.c linux-2.6.19.2.dev/arch/cris/arch-v10/kernel/traps.c
5379 --- linux-2.6.19.2.old/arch/cris/arch-v10/kernel/traps.c 2007-01-10 20:10:37.000000000 +0100
5380 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/kernel/traps.c 2006-12-11 14:04:24.000000000 +0100
5381 @@ -1,13 +1,10 @@
5382 -/* $Id: traps.c,v 1.4 2005/04/24 18:47:55 starvik Exp $
5383 +/*
5384 + * Helper functions for trap handlers
5385 *
5386 - * linux/arch/cris/arch-v10/traps.c
5387 + * Copyright (C) 2000-2006, Axis Communications AB.
5388 *
5389 - * Heler functions for trap handlers
5390 - *
5391 - * Copyright (C) 2000-2002 Axis Communications AB
5392 - *
5393 - * Authors: Bjorn Wesen
5394 - * Hans-Peter Nilsson
5395 + * Authors: Bjorn Wesen
5396 + * Hans-Peter Nilsson
5397 *
5398 */
5399
5400 @@ -15,124 +12,118 @@
5401 #include <asm/uaccess.h>
5402 #include <asm/arch/sv_addr_ag.h>
5403
5404 -extern int raw_printk(const char *fmt, ...);
5405 -
5406 -void
5407 -show_registers(struct pt_regs * regs)
5408 +void
5409 +show_registers(struct pt_regs *regs)
5410 {
5411 - /* We either use rdusp() - the USP register, which might not
5412 - correspond to the current process for all cases we're called,
5413 - or we use the current->thread.usp, which is not up to date for
5414 - the current process. Experience shows we want the USP
5415 - register. */
5416 + /*
5417 + * It's possible to use either the USP register or current->thread.usp.
5418 + * USP might not correspond to the current process for all cases this
5419 + * function is called, and current->thread.usp isn't up to date for the
5420 + * current process. Experience shows that using USP is the way to go.
5421 + */
5422 unsigned long usp = rdusp();
5423
5424 - raw_printk("IRP: %08lx SRP: %08lx DCCR: %08lx USP: %08lx MOF: %08lx\n",
5425 - regs->irp, regs->srp, regs->dccr, usp, regs->mof );
5426 - raw_printk(" r0: %08lx r1: %08lx r2: %08lx r3: %08lx\n",
5427 + printk("IRP: %08lx SRP: %08lx DCCR: %08lx USP: %08lx MOF: %08lx\n",
5428 + regs->irp, regs->srp, regs->dccr, usp, regs->mof);
5429 +
5430 + printk(" r0: %08lx r1: %08lx r2: %08lx r3: %08lx\n",
5431 regs->r0, regs->r1, regs->r2, regs->r3);
5432 - raw_printk(" r4: %08lx r5: %08lx r6: %08lx r7: %08lx\n",
5433 +
5434 + printk(" r4: %08lx r5: %08lx r6: %08lx r7: %08lx\n",
5435 regs->r4, regs->r5, regs->r6, regs->r7);
5436 - raw_printk(" r8: %08lx r9: %08lx r10: %08lx r11: %08lx\n",
5437 +
5438 + printk(" r8: %08lx r9: %08lx r10: %08lx r11: %08lx\n",
5439 regs->r8, regs->r9, regs->r10, regs->r11);
5440 - raw_printk("r12: %08lx r13: %08lx oR10: %08lx sp: %08lx\n",
5441 - regs->r12, regs->r13, regs->orig_r10, regs);
5442 - raw_printk("R_MMU_CAUSE: %08lx\n", (unsigned long)*R_MMU_CAUSE);
5443 - raw_printk("Process %s (pid: %d, stackpage=%08lx)\n",
5444 +
5445 + printk("r12: %08lx r13: %08lx oR10: %08lx sp: %08lx\n",
5446 + regs->r12, regs->r13, regs->orig_r10, (long unsigned)regs);
5447 +
5448 + printk("R_MMU_CAUSE: %08lx\n", (unsigned long)*R_MMU_CAUSE);
5449 +
5450 + printk("Process %s (pid: %d, stackpage=%08lx)\n",
5451 current->comm, current->pid, (unsigned long)current);
5452
5453 /*
5454 - * When in-kernel, we also print out the stack and code at the
5455 - * time of the fault..
5456 - */
5457 - if (! user_mode(regs)) {
5458 - int i;
5459 + * When in-kernel, we also print out the stack and code at the
5460 + * time of the fault..
5461 + */
5462 + if (!user_mode(regs)) {
5463 + int i;
5464
5465 - show_stack(NULL, (unsigned long*)usp);
5466 + show_stack(NULL, (unsigned long *)usp);
5467
5468 - /* Dump kernel stack if the previous dump wasn't one. */
5469 + /*
5470 + * If the previous stack-dump wasn't a kernel one, dump the
5471 + * kernel stack now.
5472 + */
5473 if (usp != 0)
5474 - show_stack (NULL, NULL);
5475 + show_stack(NULL, NULL);
5476
5477 - raw_printk("\nCode: ");
5478 - if(regs->irp < PAGE_OFFSET)
5479 - goto bad;
5480 -
5481 - /* Often enough the value at regs->irp does not point to
5482 - the interesting instruction, which is most often the
5483 - _previous_ instruction. So we dump at an offset large
5484 - enough that instruction decoding should be in sync at
5485 - the interesting point, but small enough to fit on a row
5486 - (sort of). We point out the regs->irp location in a
5487 - ksymoops-friendly way by wrapping the byte for that
5488 - address in parentheses. */
5489 - for(i = -12; i < 12; i++)
5490 - {
5491 - unsigned char c;
5492 - if(__get_user(c, &((unsigned char*)regs->irp)[i])) {
5493 -bad:
5494 - raw_printk(" Bad IP value.");
5495 - break;
5496 - }
5497 + printk("\nCode: ");
5498 +
5499 + if (regs->irp < PAGE_OFFSET)
5500 + goto bad_value;
5501 +
5502 + /*
5503 + * Quite often the value at regs->irp doesn't point to the
5504 + * interesting instruction, which often is the previous
5505 + * instruction. So dump at an offset large enough that the
5506 + * instruction decoding should be in sync at the interesting
5507 + * point, but small enough to fit on a row. The regs->irp
5508 + * location is pointed out in a ksymoops-friendly way by
5509 + * wrapping the byte for that address in parenthesises.
5510 + */
5511 + for (i = -12; i < 12; i++) {
5512 + unsigned char c;
5513 +
5514 + if (__get_user(c, &((unsigned char *)regs->irp)[i])) {
5515 +bad_value:
5516 + printk(" Bad IP value.");
5517 + break;
5518 + }
5519
5520 if (i == 0)
5521 - raw_printk("(%02x) ", c);
5522 + printk("(%02x) ", c);
5523 else
5524 - raw_printk("%02x ", c);
5525 - }
5526 - raw_printk("\n");
5527 - }
5528 + printk("%02x ", c);
5529 + }
5530 + printk("\n");
5531 + }
5532 }
5533
5534 -/* Called from entry.S when the watchdog has bitten
5535 - * We print out something resembling an oops dump, and if
5536 - * we have the nice doggy development flag set, we halt here
5537 - * instead of rebooting.
5538 - */
5539 -
5540 -extern void reset_watchdog(void);
5541 -extern void stop_watchdog(void);
5542 -
5543 -
5544 void
5545 -watchdog_bite_hook(struct pt_regs *regs)
5546 +arch_enable_nmi(void)
5547 {
5548 -#ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY
5549 - local_irq_disable();
5550 - stop_watchdog();
5551 - show_registers(regs);
5552 - while(1) /* nothing */;
5553 -#else
5554 - show_registers(regs);
5555 -#endif
5556 + asm volatile ("setf m");
5557 }
5558
5559 -/* This is normally the 'Oops' routine */
5560 -void
5561 -die_if_kernel(const char * str, struct pt_regs * regs, long err)
5562 +extern void (*nmi_handler)(struct pt_regs*);
5563 +void handle_nmi(struct pt_regs* regs)
5564 {
5565 - if(user_mode(regs))
5566 - return;
5567 -
5568 -#ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY
5569 - /* This printout might take too long and trigger the
5570 - * watchdog normally. If we're in the nice doggy
5571 - * development mode, stop the watchdog during printout.
5572 - */
5573 - stop_watchdog();
5574 -#endif
5575 -
5576 - raw_printk("%s: %04lx\n", str, err & 0xffff);
5577 -
5578 - show_registers(regs);
5579 + if (nmi_handler)
5580 + nmi_handler(regs);
5581
5582 -#ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY
5583 - reset_watchdog();
5584 -#endif
5585 - do_exit(SIGSEGV);
5586 + /* Wait until nmi is no longer active. (We enable NMI immediately after
5587 + returning from this function, and we don't want it happening while
5588 + exiting from the NMI interrupt handler.) */
5589 + while(*R_IRQ_MASK0_RD & IO_STATE(R_IRQ_MASK0_RD, nmi_pin, active));
5590 }
5591
5592 -void arch_enable_nmi(void)
5593 +#ifdef CONFIG_DEBUG_BUGVERBOSE
5594 +void
5595 +handle_BUG(struct pt_regs *regs)
5596 {
5597 - asm volatile("setf m");
5598 + struct bug_frame f;
5599 + unsigned char c;
5600 + unsigned long irp = regs->irp;
5601 +
5602 + if (__copy_from_user(&f, (const void __user *)(irp - 8), sizeof f))
5603 + return;
5604 + if (f.prefix != BUG_PREFIX || f.magic != BUG_MAGIC)
5605 + return;
5606 + if (__get_user(c, f.filename))
5607 + f.filename = "<bad filename>";
5608 +
5609 + printk("kernel BUG at %s:%d!\n", f.filename, f.line);
5610 }
5611 +#endif
5612 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/lib/checksum.S linux-2.6.19.2.dev/arch/cris/arch-v10/lib/checksum.S
5613 --- linux-2.6.19.2.old/arch/cris/arch-v10/lib/checksum.S 2007-01-10 20:10:37.000000000 +0100
5614 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/lib/checksum.S 2005-08-16 12:38:52.000000000 +0200
5615 @@ -1,4 +1,4 @@
5616 -/* $Id: checksum.S,v 1.1 2001/12/17 13:59:27 bjornw Exp $
5617 +/* $Id: checksum.S,v 1.2 2005/08/16 10:38:52 edgar Exp $
5618 * A fast checksum routine using movem
5619 * Copyright (c) 1998-2001 Axis Communications AB
5620 *
5621 @@ -61,8 +61,6 @@
5622
5623 ax
5624 addq 0,$r12
5625 - ax ; do it again, since we might have generated a carry
5626 - addq 0,$r12
5627
5628 subq 10*4,$r11
5629 bge _mloop
5630 @@ -88,10 +86,6 @@
5631 lsrq 16,$r13 ; r13 = checksum >> 16
5632 and.d $r9,$r12 ; checksum = checksum & 0xffff
5633 add.d $r13,$r12 ; checksum += r13
5634 - move.d $r12,$r13 ; do the same again, maybe we got a carry last add
5635 - lsrq 16,$r13
5636 - and.d $r9,$r12
5637 - add.d $r13,$r12
5638
5639 _no_fold:
5640 cmpq 2,$r11
5641 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/lib/checksumcopy.S linux-2.6.19.2.dev/arch/cris/arch-v10/lib/checksumcopy.S
5642 --- linux-2.6.19.2.old/arch/cris/arch-v10/lib/checksumcopy.S 2007-01-10 20:10:37.000000000 +0100
5643 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/lib/checksumcopy.S 2005-08-16 12:38:52.000000000 +0200
5644 @@ -1,4 +1,4 @@
5645 -/* $Id: checksumcopy.S,v 1.1 2001/12/17 13:59:27 bjornw Exp $
5646 +/* $Id: checksumcopy.S,v 1.2 2005/08/16 10:38:52 edgar Exp $
5647 * A fast checksum+copy routine using movem
5648 * Copyright (c) 1998, 2001 Axis Communications AB
5649 *
5650 @@ -67,8 +67,6 @@
5651
5652 ax
5653 addq 0,$r13
5654 - ax ; do it again, since we might have generated a carry
5655 - addq 0,$r13
5656
5657 subq 10*4,$r12
5658 bge _mloop
5659 @@ -91,10 +89,6 @@
5660 lsrq 16,$r9 ; r0 = checksum >> 16
5661 and.d 0xffff,$r13 ; checksum = checksum & 0xffff
5662 add.d $r9,$r13 ; checksum += r0
5663 - move.d $r13,$r9 ; do the same again, maybe we got a carry last add
5664 - lsrq 16,$r9
5665 - and.d 0xffff,$r13
5666 - add.d $r9,$r13
5667
5668 _no_fold:
5669 cmpq 2,$r12
5670 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/lib/dram_init.S linux-2.6.19.2.dev/arch/cris/arch-v10/lib/dram_init.S
5671 --- linux-2.6.19.2.old/arch/cris/arch-v10/lib/dram_init.S 2007-01-10 20:10:37.000000000 +0100
5672 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/lib/dram_init.S 2006-10-13 14:43:11.000000000 +0200
5673 @@ -1,4 +1,4 @@
5674 -/* $Id: dram_init.S,v 1.4 2003/09/22 09:21:59 starvik Exp $
5675 +/* $Id: dram_init.S,v 1.5 2006/10/13 12:43:11 starvik Exp $
5676 *
5677 * DRAM/SDRAM initialization - alter with care
5678 * This file is intended to be included from other assembler files
5679 @@ -11,6 +11,9 @@
5680 * Authors: Mikael Starvik (starvik@axis.com)
5681 *
5682 * $Log: dram_init.S,v $
5683 + * Revision 1.5 2006/10/13 12:43:11 starvik
5684 + * Merge of 2.6.18
5685 + *
5686 * Revision 1.4 2003/09/22 09:21:59 starvik
5687 * Decompresser is linked to 0x407xxxxx and sdram commands are at 0x000xxxxx
5688 * so we need to mask off 12 bits.
5689 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/mm/fault.c linux-2.6.19.2.dev/arch/cris/arch-v10/mm/fault.c
5690 --- linux-2.6.19.2.old/arch/cris/arch-v10/mm/fault.c 2007-01-10 20:10:37.000000000 +0100
5691 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/mm/fault.c 2006-12-11 12:32:10.000000000 +0100
5692 @@ -73,7 +73,7 @@
5693 /* leave it to the MM system fault handler */
5694 if (miss)
5695 do_page_fault(address, regs, 0, writeac);
5696 - else
5697 + else
5698 do_page_fault(address, regs, 1, we);
5699
5700 /* Reload TLB with new entry to avoid an extra miss exception.
5701 @@ -84,12 +84,13 @@
5702 local_irq_disable();
5703 pmd = (pmd_t *)(pgd + pgd_index(address));
5704 if (pmd_none(*pmd))
5705 - return;
5706 + goto exit;
5707 pte = *pte_offset_kernel(pmd, address);
5708 if (!pte_present(pte))
5709 - return;
5710 + goto exit;
5711 *R_TLB_SELECT = select;
5712 *R_TLB_HI = cause;
5713 *R_TLB_LO = pte_val(pte);
5714 +exit:
5715 local_irq_restore(flags);
5716 }
5717 diff -urN linux-2.6.19.2.old/arch/cris/arch-v10/mm/tlb.c linux-2.6.19.2.dev/arch/cris/arch-v10/mm/tlb.c
5718 --- linux-2.6.19.2.old/arch/cris/arch-v10/mm/tlb.c 2007-01-10 20:10:37.000000000 +0100
5719 +++ linux-2.6.19.2.dev/arch/cris/arch-v10/mm/tlb.c 2006-08-07 12:08:35.000000000 +0200
5720 @@ -179,23 +179,26 @@
5721 switch_mm(struct mm_struct *prev, struct mm_struct *next,
5722 struct task_struct *tsk)
5723 {
5724 - /* make sure we have a context */
5725 + if (prev != next) {
5726 + /* make sure we have a context */
5727 + get_mmu_context(next);
5728 +
5729 + /* remember the pgd for the fault handlers
5730 + * this is similar to the pgd register in some other CPU's.
5731 + * we need our own copy of it because current and active_mm
5732 + * might be invalid at points where we still need to derefer
5733 + * the pgd.
5734 + */
5735
5736 - get_mmu_context(next);
5737 + per_cpu(current_pgd, smp_processor_id()) = next->pgd;
5738
5739 - /* remember the pgd for the fault handlers
5740 - * this is similar to the pgd register in some other CPU's.
5741 - * we need our own copy of it because current and active_mm
5742 - * might be invalid at points where we still need to derefer
5743 - * the pgd.
5744 - */
5745 -
5746 - per_cpu(current_pgd, smp_processor_id()) = next->pgd;
5747 -
5748 - /* switch context in the MMU */
5749 + /* switch context in the MMU */
5750
5751 - D(printk("switching mmu_context to %d (%p)\n", next->context, next));
5752 + D(printk("switching mmu_context to %d (%p)\n",
5753 + next->context, next));
5754
5755 - *R_MMU_CONTEXT = IO_FIELD(R_MMU_CONTEXT, page_id, next->context.page_id);
5756 + *R_MMU_CONTEXT = IO_FIELD(R_MMU_CONTEXT,
5757 + page_id, next->context.page_id);
5758 + }
5759 }
5760
5761 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/Kconfig linux-2.6.19.2.dev/arch/cris/arch-v32/Kconfig
5762 --- linux-2.6.19.2.old/arch/cris/arch-v32/Kconfig 2007-01-10 20:10:37.000000000 +0100
5763 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/Kconfig 2007-01-09 10:29:18.000000000 +0100
5764 @@ -1,23 +1,66 @@
5765 +source drivers/cpufreq/Kconfig
5766 +
5767 config ETRAX_DRAM_VIRTUAL_BASE
5768 hex
5769 depends on ETRAX_ARCH_V32
5770 default "c0000000"
5771
5772 -config ETRAX_LED1G
5773 - string "First green LED bit"
5774 +choice
5775 + prompt "Nbr of Ethernet LED groups"
5776 depends on ETRAX_ARCH_V32
5777 + default ETRAX_NBR_LED_GRP_ONE
5778 + help
5779 + Select how many Ethernet LED groups that can be used. Usually one per Ethernet
5780 + interface is a good choice.
5781 +
5782 +config ETRAX_NBR_LED_GRP_ZERO
5783 + bool "Use zero LED groups"
5784 + help
5785 + Select this if you do not want any Ethernet LEDs.
5786 +
5787 +config ETRAX_NBR_LED_GRP_ONE
5788 + bool "Use one LED group"
5789 + help
5790 + Select this if you want one Ethernet LED group. This LED group can be used for
5791 + one or more Ethernet interfaces. However, it is recomended that each Ethernet
5792 + interface use a dedicated LED group.
5793 +
5794 +config ETRAX_NBR_LED_GRP_TWO
5795 + bool "Use two LED groups"
5796 + help
5797 + Select this if you want two Ethernet LED groups. This is the best choice if you
5798 + have more than one Ethernet interface and would like to have separate LEDs for
5799 + the interfaces.
5800 +
5801 +endchoice
5802 +
5803 +config ETRAX_LED_G_NET0
5804 + string "Ethernet LED group 0 green LED bit"
5805 + depends on ETRAX_ARCH_V32 && (ETRAX_NBR_LED_GRP_ONE || ETRAX_NBR_LED_GRP_TWO)
5806 default "PA3"
5807 help
5808 - Bit to use for the first green LED (network LED).
5809 - Most Axis products use bit A3 here.
5810 + Bit to use for the green LED in Ethernet LED group 0.
5811
5812 -config ETRAX_LED1R
5813 - string "First red LED bit"
5814 - depends on ETRAX_ARCH_V32
5815 +config ETRAX_LED_R_NET0
5816 + string "Ethernet LED group 0 red LED bit"
5817 + depends on ETRAX_ARCH_V32 && (ETRAX_NBR_LED_GRP_ONE || ETRAX_NBR_LED_GRP_TWO)
5818 default "PA4"
5819 help
5820 - Bit to use for the first red LED (network LED).
5821 - Most Axis products use bit A4 here.
5822 + Bit to use for the red LED in Ethernet LED group 0.
5823 +
5824 +config ETRAX_LED_G_NET1
5825 + string "Ethernet group 1 green LED bit"
5826 + depends on ETRAX_ARCH_V32 && ETRAX_NBR_LED_GRP_TWO
5827 + default ""
5828 + help
5829 + Bit to use for the green LED in Ethernet LED group 1.
5830 +
5831 +config ETRAX_LED_R_NET1
5832 + string "Ethernet group 1 red LED bit"
5833 + depends on ETRAX_ARCH_V32 && ETRAX_NBR_LED_GRP_TWO
5834 + default ""
5835 + help
5836 + Bit to use for the red LED in Ethernet LED group 1.
5837
5838 config ETRAX_LED2G
5839 string "Second green LED bit"
5840 @@ -294,3 +337,22 @@
5841 help
5842 Configures the initial data for the general port E bits. Most
5843 products should use 00000 here.
5844 +
5845 +config ETRAX_DEF_GIO_PV_OE
5846 + hex "GIO_PV_OE"
5847 + depends on ETRAX_VIRTUAL_GPIO
5848 + default "0000"
5849 + help
5850 + Configures the direction of virtual general port V bits. 1 is out,
5851 + 0 is in. This is often totally different depending on the product
5852 + used. These bits are used for all kinds of stuff. If you don't know
5853 + what to use, it is always safe to put all as inputs, although
5854 + floating inputs isn't good.
5855 +
5856 +config ETRAX_DEF_GIO_PV_OUT
5857 + hex "GIO_PV_OUT"
5858 + depends on ETRAX_VIRTUAL_GPIO
5859 + default "0000"
5860 + help
5861 + Configures the initial data for the virtual general port V bits.
5862 + Most products should use 0000 here.
5863 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/boot/Makefile linux-2.6.19.2.dev/arch/cris/arch-v32/boot/Makefile
5864 --- linux-2.6.19.2.old/arch/cris/arch-v32/boot/Makefile 2007-01-10 20:10:37.000000000 +0100
5865 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/boot/Makefile 2006-11-29 17:05:41.000000000 +0100
5866 @@ -1,14 +1,21 @@
5867 #
5868 # arch/cris/arch-v32/boot/Makefile
5869 #
5870 -target = $(target_boot_dir)
5871 -src = $(src_boot_dir)
5872
5873 -zImage: compressed/vmlinuz
5874 +OBJCOPY = objcopy-cris
5875 +OBJCOPYFLAGS = -O binary -R .note -R .comment
5876
5877 -compressed/vmlinuz: $(objtree)/vmlinux
5878 - @$(MAKE) -f $(src)/compressed/Makefile $(objtree)/vmlinuz
5879 +subdir- := compressed rescue
5880 +targets := Image
5881
5882 -clean:
5883 - rm -f zImage tools/build compressed/vmlinux.out
5884 - @$(MAKE) -f $(src)/compressed/Makefile clean
5885 +$(obj)/Image: vmlinux FORCE
5886 + $(call if_changed,objcopy)
5887 + @echo ' Kernel: $@ is ready'
5888 +
5889 +$(obj)/compressed/vmlinux: $(obj)/Image FORCE
5890 + $(Q)$(MAKE) $(build)=$(obj)/compressed $@
5891 + $(Q)$(MAKE) $(build)=$(obj)/rescue $(obj)/rescue/rescue.bin
5892 +
5893 +$(obj)/zImage: $(obj)/compressed/vmlinux
5894 + @cp $< $@
5895 + @echo ' Kernel: $@ is ready'
5896 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/boot/compressed/Makefile linux-2.6.19.2.dev/arch/cris/arch-v32/boot/compressed/Makefile
5897 --- linux-2.6.19.2.old/arch/cris/arch-v32/boot/compressed/Makefile 2007-01-10 20:10:37.000000000 +0100
5898 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/boot/compressed/Makefile 2006-11-29 17:05:42.000000000 +0100
5899 @@ -1,41 +1,29 @@
5900 #
5901 -# lx25/arch/cris/arch-v32/boot/compressed/Makefile
5902 +# arch/cris/arch-v32/boot/compressed/Makefile
5903 #
5904 -# create a compressed vmlinux image from the original vmlinux files and romfs
5905 -#
5906 -
5907 -target = $(target_compressed_dir)
5908 -src = $(src_compressed_dir)
5909
5910 CC = gcc-cris -mlinux -march=v32 -I $(TOPDIR)/include
5911 CFLAGS = -O2
5912 LD = gcc-cris -mlinux -march=v32 -nostdlib
5913 +LDFLAGS = -T $(obj)/decompress.ld
5914 +obj-y = head.o misc.o
5915 +OBJECTS = $(obj)/head.o $(obj)/misc.o
5916 OBJCOPY = objcopy-cris
5917 OBJCOPYFLAGS = -O binary --remove-section=.bss
5918 -OBJECTS = $(target)/head.o $(target)/misc.o
5919 -
5920 -# files to compress
5921 -SYSTEM = $(objtree)/vmlinux.bin
5922 -
5923 -all: vmlinuz
5924 -
5925 -$(target)/decompress.bin: $(OBJECTS)
5926 - $(LD) -T $(src)/decompress.ld -o $(target)/decompress.o $(OBJECTS)
5927 - $(OBJCOPY) $(OBJCOPYFLAGS) $(target)/decompress.o $(target)/decompress.bin
5928
5929 -$(objtree)/vmlinuz: $(target) piggy.img $(target)/decompress.bin
5930 - cat $(target)/decompress.bin piggy.img > $(objtree)/vmlinuz
5931 - rm -f piggy.img
5932 - cp $(objtree)/vmlinuz $(src)
5933 +quiet_cmd_image = BUILD $@
5934 +cmd_image = cat $(obj)/decompress.bin $(obj)/piggy.gz > $@
5935
5936 -$(target)/head.o: $(src)/head.S
5937 - $(CC) -D__ASSEMBLY__ -c $< -o $@
5938 +targets := vmlinux piggy.gz decompress.o decompress.bin
5939
5940 -# gzip the kernel image
5941 +$(obj)/decompress.o: $(OBJECTS) FORCE
5942 + $(call if_changed,ld)
5943
5944 -piggy.img: $(SYSTEM)
5945 - cat $(SYSTEM) | gzip -f -9 > piggy.img
5946 +$(obj)/decompress.bin: $(obj)/decompress.o FORCE
5947 + $(call if_changed,objcopy)
5948
5949 -clean:
5950 - rm -f piggy.img $(objtree)/vmlinuz vmlinuz.o decompress.o decompress.bin $(OBJECTS)
5951 +$(obj)/vmlinux: $(obj)/piggy.gz $(obj)/decompress.bin FORCE
5952 + $(call if_changed,image)
5953
5954 +$(obj)/piggy.gz: $(obj)/../Image FORCE
5955 + $(call if_changed,gzip)
5956 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/boot/compressed/README linux-2.6.19.2.dev/arch/cris/arch-v32/boot/compressed/README
5957 --- linux-2.6.19.2.old/arch/cris/arch-v32/boot/compressed/README 2007-01-10 20:10:37.000000000 +0100
5958 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/boot/compressed/README 2003-08-21 11:37:03.000000000 +0200
5959 @@ -5,14 +5,14 @@
5960 This can be slightly confusing because it's a process with many steps.
5961
5962 The kernel object built by the arch/etrax100/Makefile, vmlinux, is split
5963 -by that makefile into text and data binary files, vmlinux.text and
5964 +by that makefile into text and data binary files, vmlinux.text and
5965 vmlinux.data.
5966
5967 Those files together with a ROM filesystem can be catted together and
5968 burned into a flash or executed directly at the DRAM origin.
5969
5970 They can also be catted together and compressed with gzip, which is what
5971 -happens in this makefile. Together they make up piggy.img.
5972 +happens in this makefile. Together they make up piggy.img.
5973
5974 The decompressor is built into the file decompress.o. It is turned into
5975 the binary file decompress.bin, which is catted together with piggy.img
5976 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/boot/compressed/decompress.ld linux-2.6.19.2.dev/arch/cris/arch-v32/boot/compressed/decompress.ld
5977 --- linux-2.6.19.2.old/arch/cris/arch-v32/boot/compressed/decompress.ld 2007-01-10 20:10:37.000000000 +0100
5978 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/boot/compressed/decompress.ld 2003-08-21 11:57:56.000000000 +0200
5979 @@ -1,7 +1,7 @@
5980 /*#OUTPUT_FORMAT(elf32-us-cris) */
5981 OUTPUT_ARCH (crisv32)
5982
5983 -MEMORY
5984 +MEMORY
5985 {
5986 dram : ORIGIN = 0x40700000,
5987 LENGTH = 0x00100000
5988 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/boot/compressed/head.S linux-2.6.19.2.dev/arch/cris/arch-v32/boot/compressed/head.S
5989 --- linux-2.6.19.2.old/arch/cris/arch-v32/boot/compressed/head.S 2007-01-10 20:10:37.000000000 +0100
5990 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/boot/compressed/head.S 2007-01-09 10:29:20.000000000 +0100
5991 @@ -2,19 +2,19 @@
5992 * Code that sets up the DRAM registers, calls the
5993 * decompressor to unpack the piggybacked kernel, and jumps.
5994 *
5995 - * Copyright (C) 1999 - 2003, Axis Communications AB
5996 + * Copyright (C) 1999 - 2006, Axis Communications AB
5997 */
5998
5999 #define ASSEMBLER_MACROS_ONLY
6000 #include <asm/arch/hwregs/asm/reg_map_asm.h>
6001 #include <asm/arch/hwregs/asm/gio_defs_asm.h>
6002 #include <asm/arch/hwregs/asm/config_defs_asm.h>
6003 -
6004 +
6005 #define RAM_INIT_MAGIC 0x56902387
6006 #define COMMAND_LINE_MAGIC 0x87109563
6007
6008 ;; Exported symbols
6009 -
6010 +
6011 .globl input_data
6012
6013 .text
6014 @@ -29,53 +29,16 @@
6015 REG_STATE(config, rw_clk_ctrl, fix_io, yes), $r0
6016 move.d $r0, [$r1]
6017
6018 - ;; If booting from NAND flash we first have to copy some
6019 - ;; data from NAND flash to internal RAM to get the code
6020 - ;; that initializes the SDRAM. Lets copy 20 KB. This
6021 - ;; code executes at 0x38010000 if booting from NAND and
6022 - ;; we are guaranted that at least 0x200 bytes are good so
6023 - ;; lets start from there. The first 8192 bytes in the nand
6024 - ;; flash is spliced with zeroes and is thus 16384 bytes.
6025 - move.d 0x38010200, $r10
6026 - move.d 0x14200, $r11 ; Start offset in NAND flash 0x10200 + 16384
6027 - move.d 0x5000, $r12 ; Length of copy
6028 -
6029 - ;; Before this code the tools add a partitiontable so the PC
6030 - ;; has an offset from the linked address.
6031 -offset1:
6032 - lapcq ., $r13 ; get PC
6033 - add.d first_copy_complete-offset1, $r13
6034 -
6035 -#include "../../lib/nand_init.S"
6036 -
6037 -first_copy_complete:
6038 - ;; Initialze the DRAM registers.
6039 + ;; Initialize the DRAM registers.
6040 cmp.d RAM_INIT_MAGIC, $r8 ; Already initialized?
6041 beq dram_init_finished
6042 nop
6043
6044 #include "../../lib/dram_init.S"
6045 -
6046 +
6047 dram_init_finished:
6048 - lapcq ., $r13 ; get PC
6049 - add.d second_copy_complete-dram_init_finished, $r13
6050 -
6051 - move.d REG_ADDR(config, regi_config, r_bootsel), $r0
6052 - move.d [$r0], $r0
6053 - and.d REG_MASK(config, r_bootsel, boot_mode), $r0
6054 - cmp.d REG_STATE(config, r_bootsel, boot_mode, nand), $r0
6055 - bne second_copy_complete ; No NAND boot
6056 - nop
6057 -
6058 - ;; Copy 2MB from NAND flash to SDRAM (at 2-4MB into the SDRAM)
6059 - move.d 0x40204000, $r10
6060 - move.d 0x8000, $r11
6061 - move.d 0x200000, $r12
6062 - ba copy_nand_to_ram
6063 - nop
6064 -second_copy_complete:
6065 -
6066 - ;; Initiate the PA port.
6067 +
6068 + ;; Initiate the GIO ports.
6069 move.d CONFIG_ETRAX_DEF_GIO_PA_OUT, $r0
6070 move.d REG_ADDR(gio, regi_gio, rw_pa_dout), $r1
6071 move.d $r0, [$r1]
6072 @@ -84,57 +47,74 @@
6073 move.d REG_ADDR(gio, regi_gio, rw_pa_oe), $r1
6074 move.d $r0, [$r1]
6075
6076 + move.d CONFIG_ETRAX_DEF_GIO_PB_OUT, $r0
6077 + move.d REG_ADDR(gio, regi_gio, rw_pb_dout), $r1
6078 + move.d $r0, [$r1]
6079 +
6080 + move.d CONFIG_ETRAX_DEF_GIO_PB_OE, $r0
6081 + move.d REG_ADDR(gio, regi_gio, rw_pb_oe), $r1
6082 + move.d $r0, [$r1]
6083 +
6084 + move.d CONFIG_ETRAX_DEF_GIO_PC_OUT, $r0
6085 + move.d REG_ADDR(gio, regi_gio, rw_pc_dout), $r1
6086 + move.d $r0, [$r1]
6087 +
6088 + move.d CONFIG_ETRAX_DEF_GIO_PC_OE, $r0
6089 + move.d REG_ADDR(gio, regi_gio, rw_pc_oe), $r1
6090 + move.d $r0, [$r1]
6091 +
6092 + move.d CONFIG_ETRAX_DEF_GIO_PD_OUT, $r0
6093 + move.d REG_ADDR(gio, regi_gio, rw_pd_dout), $r1
6094 + move.d $r0, [$r1]
6095 +
6096 + move.d CONFIG_ETRAX_DEF_GIO_PD_OE, $r0
6097 + move.d REG_ADDR(gio, regi_gio, rw_pd_oe), $r1
6098 + move.d $r0, [$r1]
6099 +
6100 + move.d CONFIG_ETRAX_DEF_GIO_PE_OUT, $r0
6101 + move.d REG_ADDR(gio, regi_gio, rw_pe_dout), $r1
6102 + move.d $r0, [$r1]
6103 +
6104 + move.d CONFIG_ETRAX_DEF_GIO_PE_OE, $r0
6105 + move.d REG_ADDR(gio, regi_gio, rw_pe_oe), $r1
6106 + move.d $r0, [$r1]
6107 +
6108 ;; Setup the stack to a suitably high address.
6109 - ;; We assume 8 MB is the minimum DRAM and put
6110 + ;; We assume 8 MB is the minimum DRAM and put
6111 ;; the SP at the top for now.
6112
6113 move.d 0x40800000, $sp
6114
6115 - ;; Figure out where the compressed piggyback image is
6116 - ;; in the flash (since we wont try to copy it to DRAM
6117 - ;; before unpacking). It is at _edata, but in flash.
6118 + ;; Figure out where the compressed piggyback image is.
6119 + ;; It is either in [NOR] flash (we don't want to copy it
6120 + ;; to DRAM before unpacking), or copied to DRAM
6121 + ;; by the [NAND] flash boot loader.
6122 + ;; The piggyback image is at _edata, but relative to where the
6123 + ;; image is actually located in memory, not where it is linked
6124 + ;; (the decompressor is linked at 0x40700000+ and runs there).
6125 ;; Use (_edata - herami) as offset to the current PC.
6126
6127 - move.d REG_ADDR(config, regi_config, r_bootsel), $r0
6128 - move.d [$r0], $r0
6129 - and.d REG_MASK(config, r_bootsel, boot_mode), $r0
6130 - cmp.d REG_STATE(config, r_bootsel, boot_mode, nand), $r0
6131 - beq hereami2
6132 - nop
6133 -hereami:
6134 +hereami:
6135 lapcq ., $r5 ; get PC
6136 and.d 0x7fffffff, $r5 ; strip any non-cache bit
6137 - move.d $r5, $r0 ; save for later - flash address of 'herami'
6138 + move.d $r5, $r0 ; source address of 'herami'
6139 add.d _edata, $r5
6140 sub.d hereami, $r5 ; r5 = flash address of '_edata'
6141 move.d hereami, $r1 ; destination
6142 - ba 2f
6143 - nop
6144 -hereami2:
6145 - lapcq ., $r5 ; get PC
6146 - and.d 0x00ffffff, $r5 ; strip any non-cache bit
6147 - move.d $r5, $r6
6148 - or.d 0x40200000, $r6
6149 - move.d $r6, $r0 ; save for later - flash address of 'herami'
6150 - add.d _edata, $r5
6151 - sub.d hereami2, $r5 ; r5 = flash address of '_edata'
6152 - add.d 0x40200000, $r5
6153 - move.d hereami2, $r1 ; destination
6154 -2:
6155 - ;; Copy text+data to DRAM
6156
6157 + ;; Copy text+data to DRAM
6158 +
6159 move.d _edata, $r2 ; end destination
6160 -1: move.w [$r0+], $r3
6161 - move.w $r3, [$r1+]
6162 - cmp.d $r2, $r1
6163 +1: move.w [$r0+], $r3 ; from herami+ source
6164 + move.w $r3, [$r1+] ; to hereami+ destination (linked address)
6165 + cmp.d $r2, $r1 ; finish when destination == _edata
6166 bcs 1b
6167 nop
6168 -
6169 - move.d input_data, $r0 ; for the decompressor
6170 + move.d input_data, $r0 ; for the decompressor
6171 move.d $r5, [$r0] ; for the decompressor
6172
6173 ;; Clear the decompressors BSS (between _edata and _end)
6174 -
6175 +
6176 moveq 0, $r0
6177 move.d _edata, $r1
6178 move.d _end, $r2
6179 @@ -144,40 +124,47 @@
6180 nop
6181
6182 ;; Save command line magic and address.
6183 - move.d _cmd_line_magic, $r12
6184 - move.d $r10, [$r12]
6185 - move.d _cmd_line_addr, $r12
6186 - move.d $r11, [$r12]
6187 -
6188 + move.d _cmd_line_magic, $r0
6189 + move.d $r10, [$r0]
6190 + move.d _cmd_line_addr, $r0
6191 + move.d $r11, [$r0]
6192 +
6193 + ;; Save boot source indicator
6194 + move.d _boot_source, $r0
6195 + move.d $r12, [$r0]
6196 +
6197 ;; Do the decompression and save compressed size in _inptr
6198
6199 jsr decompress_kernel
6200 nop
6201
6202 + ;; Restore boot source indicator
6203 + move.d _boot_source, $r12
6204 + move.d [$r12], $r12
6205 +
6206 ;; Restore command line magic and address.
6207 move.d _cmd_line_magic, $r10
6208 move.d [$r10], $r10
6209 move.d _cmd_line_addr, $r11
6210 move.d [$r11], $r11
6211 -
6212 +
6213 ;; Put start address of root partition in r9 so the kernel can use it
6214 ;; when mounting from flash
6215 move.d input_data, $r0
6216 move.d [$r0], $r9 ; flash address of compressed kernel
6217 move.d inptr, $r0
6218 add.d [$r0], $r9 ; size of compressed kernel
6219 - cmp.d 0x40200000, $r9
6220 - blo enter_kernel
6221 - nop
6222 - sub.d 0x40200000, $r9
6223 - add.d 0x4000, $r9
6224 -
6225 -enter_kernel:
6226 + cmp.d 0x40000000, $r9 ; image in DRAM ?
6227 + blo enter_kernel ; no, must be [NOR] flash, jump
6228 + nop ; delay slot
6229 + and.d 0x001fffff, $r9 ; assume compressed kernel was < 2M
6230 +
6231 +enter_kernel:
6232 ;; Enter the decompressed kernel
6233 move.d RAM_INIT_MAGIC, $r8 ; Tell kernel that DRAM is initialized
6234 jump 0x40004000 ; kernel is linked to this address
6235 nop
6236 -
6237 +
6238 .data
6239
6240 input_data:
6241 @@ -185,8 +172,8 @@
6242 _cmd_line_magic:
6243 .dword 0
6244 _cmd_line_addr:
6245 + .dword 0
6246 +_boot_source:
6247 .dword 0
6248 -is_nand_boot:
6249 - .dword 0
6250 -
6251 +
6252 #include "../../lib/hw_settings.S"
6253 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/boot/compressed/misc.c linux-2.6.19.2.dev/arch/cris/arch-v32/boot/compressed/misc.c
6254 --- linux-2.6.19.2.old/arch/cris/arch-v32/boot/compressed/misc.c 2007-01-10 20:10:37.000000000 +0100
6255 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/boot/compressed/misc.c 2006-11-03 11:35:51.000000000 +0100
6256 @@ -1,15 +1,15 @@
6257 /*
6258 * misc.c
6259 *
6260 - * $Id: misc.c,v 1.8 2005/04/24 18:34:29 starvik Exp $
6261 - *
6262 - * This is a collection of several routines from gzip-1.0.3
6263 + * $Id: misc.c,v 1.12 2006/11/03 10:35:51 pkj Exp $
6264 + *
6265 + * This is a collection of several routines from gzip-1.0.3
6266 * adapted for Linux.
6267 *
6268 * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
6269 * puts by Nick Holloway 1993, better puts by Martin Mares 1995
6270 * adoptation for Linux/CRIS Axis Communications AB, 1999
6271 - *
6272 + *
6273 */
6274
6275 /* where the piggybacked kernel image expects itself to live.
6276 @@ -20,11 +20,11 @@
6277
6278 #define KERNEL_LOAD_ADR 0x40004000
6279
6280 -
6281 #include <linux/types.h>
6282 #include <asm/arch/hwregs/reg_rdwr.h>
6283 #include <asm/arch/hwregs/reg_map.h>
6284 #include <asm/arch/hwregs/ser_defs.h>
6285 +#include <asm/arch/hwregs/pinmux_defs.h>
6286
6287 /*
6288 * gzip declarations
6289 @@ -66,8 +66,8 @@
6290 #define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */
6291 #define RESERVED 0xC0 /* bit 6,7: reserved */
6292
6293 -#define get_byte() inbuf[inptr++]
6294 -
6295 +#define get_byte() inbuf[inptr++]
6296 +
6297 /* Diagnostic functions */
6298 #ifdef DEBUG
6299 # define Assert(cond,msg) {if(!(cond)) error(msg);}
6300 @@ -96,20 +96,20 @@
6301 static long bytes_out = 0;
6302 static uch *output_data;
6303 static unsigned long output_ptr = 0;
6304 -
6305 +
6306 static void *malloc(int size);
6307 static void free(void *where);
6308 static void error(char *m);
6309 static void gzip_mark(void **);
6310 static void gzip_release(void **);
6311 -
6312 +
6313 static void puts(const char *);
6314
6315 /* the "heap" is put directly after the BSS ends, at end */
6316 -
6317 +
6318 extern int _end;
6319 static long free_mem_ptr = (long)&_end;
6320 -
6321 +
6322 #include "../../../../../lib/inflate.c"
6323
6324 static void *malloc(int size)
6325 @@ -152,7 +152,7 @@
6326 rs = REG_RD(ser, regi_ser, rs_stat_din);
6327 }
6328 while (!rs.tr_rdy);/* Wait for tranceiver. */
6329 -
6330 +
6331 REG_WR(ser, regi_ser, rw_dout, dout);
6332 }
6333
6334 @@ -209,9 +209,9 @@
6335 ulg c = crc; /* temporary variable */
6336 unsigned n;
6337 uch *in, *out, ch;
6338 -
6339 +
6340 in = window;
6341 - out = &output_data[output_ptr];
6342 + out = &output_data[output_ptr];
6343 for (n = 0; n < outcnt; n++) {
6344 ch = *out++ = *in++;
6345 c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
6346 @@ -225,9 +225,9 @@
6347 static void
6348 error(char *x)
6349 {
6350 - puts("\n\n");
6351 + puts("\r\n\n");
6352 puts(x);
6353 - puts("\n\n -- System halted\n");
6354 + puts("\r\n\n -- System halted\n");
6355
6356 while(1); /* Halt */
6357 }
6358 @@ -246,13 +246,13 @@
6359 reg_ser_rw_rec_ctrl rec_ctrl;
6360 reg_ser_rw_tr_baud_div tr_baud;
6361 reg_ser_rw_rec_baud_div rec_baud;
6362 -
6363 +
6364 /* Turn off XOFF. */
6365 xoff = REG_RD(ser, regi_ser, rw_xoff);
6366 -
6367 +
6368 xoff.chr = 0;
6369 xoff.automatic = regk_ser_no;
6370 -
6371 +
6372 REG_WR(ser, regi_ser, rw_xoff, xoff);
6373
6374 /* Set baudrate and stopbits. */
6375 @@ -260,19 +260,21 @@
6376 rec_ctrl = REG_RD(ser, regi_ser, rw_rec_ctrl);
6377 tr_baud = REG_RD(ser, regi_ser, rw_tr_baud_div);
6378 rec_baud = REG_RD(ser, regi_ser, rw_rec_baud_div);
6379 -
6380 +
6381 tr_ctrl.stop_bits = 1; /* 2 stop bits. */
6382 -
6383 - /*
6384 - * The baudrate setup is a bit fishy, but in the end the tranceiver is
6385 - * set to 4800 and the receiver to 115200. The magic value is
6386 - * 29.493 MHz.
6387 + tr_ctrl.en = 1; /* enable transmitter */
6388 + rec_ctrl.en = 1; /* enabler receiver */
6389 +
6390 + /*
6391 + * The baudrate setup used to be a bit fishy, but now transmitter and
6392 + * receiver are both set to the intended baud rate, 115200.
6393 + * The magic value is 29.493 MHz.
6394 */
6395 tr_ctrl.base_freq = regk_ser_f29_493;
6396 rec_ctrl.base_freq = regk_ser_f29_493;
6397 - tr_baud.div = (29493000 / 8) / 4800;
6398 + tr_baud.div = (29493000 / 8) / 115200;
6399 rec_baud.div = (29493000 / 8) / 115200;
6400 -
6401 +
6402 REG_WR(ser, regi_ser, rw_tr_ctrl, tr_ctrl);
6403 REG_WR(ser, regi_ser, rw_tr_baud_div, tr_baud);
6404 REG_WR(ser, regi_ser, rw_rec_ctrl, rec_ctrl);
6405 @@ -283,22 +285,28 @@
6406 decompress_kernel()
6407 {
6408 char revision;
6409 -
6410 + reg_pinmux_rw_hwprot hwprot;
6411 +
6412 /* input_data is set in head.S */
6413 inbuf = input_data;
6414 -
6415 +
6416 + hwprot = REG_RD(pinmux, regi_pinmux, rw_hwprot);
6417 #ifdef CONFIG_ETRAX_DEBUG_PORT0
6418 serial_setup(regi_ser0);
6419 #endif
6420 #ifdef CONFIG_ETRAX_DEBUG_PORT1
6421 + hwprot.ser1 = regk_pinmux_yes;
6422 serial_setup(regi_ser1);
6423 #endif
6424 #ifdef CONFIG_ETRAX_DEBUG_PORT2
6425 + hwprot.ser2 = regk_pinmux_yes;
6426 serial_setup(regi_ser2);
6427 #endif
6428 #ifdef CONFIG_ETRAX_DEBUG_PORT3
6429 + hwprot.ser3 = regk_pinmux_yes;
6430 serial_setup(regi_ser3);
6431 #endif
6432 + REG_WR(pinmux, regi_pinmux, rw_hwprot, hwprot);
6433
6434 setup_normal_output_buffer();
6435
6436 @@ -307,11 +315,11 @@
6437 __asm__ volatile ("move $vr,%0" : "=rm" (revision));
6438 if (revision < 32)
6439 {
6440 - puts("You need an ETRAX FS to run Linux 2.6/crisv32.\n");
6441 + puts("You need an ETRAX FS to run Linux 2.6/crisv32.\r\n");
6442 while(1);
6443 }
6444
6445 - puts("Uncompressing Linux...\n");
6446 + puts("Uncompressing Linux...\r\n");
6447 gunzip();
6448 - puts("Done. Now booting the kernel.\n");
6449 + puts("Done. Now booting the kernel.\r\n");
6450 }
6451 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/boot/rescue/Makefile linux-2.6.19.2.dev/arch/cris/arch-v32/boot/rescue/Makefile
6452 --- linux-2.6.19.2.old/arch/cris/arch-v32/boot/rescue/Makefile 2007-01-10 20:10:37.000000000 +0100
6453 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/boot/rescue/Makefile 2007-01-17 14:24:50.000000000 +0100
6454 @@ -1,36 +1,29 @@
6455 #
6456 -# Makefile for rescue code
6457 +# Makefile for rescue (bootstrap) code
6458 #
6459 -target = $(target_rescue_dir)
6460 -src = $(src_rescue_dir)
6461
6462 CC = gcc-cris -mlinux -march=v32 $(LINUXINCLUDE)
6463 CFLAGS = -O2
6464 -LD = gcc-cris -mlinux -march=v32 -nostdlib
6465 +LD = gcc-cris -mlinux -march=v32 -nostdlib
6466 +LDFLAGS = -T $(obj)/rescue.ld
6467 +LDPOSTFLAGS = -lgcc
6468 OBJCOPY = objcopy-cris
6469 OBJCOPYFLAGS = -O binary --remove-section=.bss
6470 -
6471 -all: $(target)/rescue.bin
6472 -
6473 -rescue: rescue.bin
6474 - # do nothing
6475 -
6476 -$(target)/rescue.bin: $(target) $(target)/head.o
6477 - $(LD) -T $(src)/rescue.ld -o $(target)/rescue.o $(target)/head.o
6478 - $(OBJCOPY) $(OBJCOPYFLAGS) $(target)/rescue.o $(target)/rescue.bin
6479 - cp -p $(target)/rescue.bin $(objtree)
6480 -
6481 -$(target):
6482 - mkdir -p $(target)
6483 -
6484 -$(target)/head.o: $(src)/head.S
6485 - $(CC) -D__ASSEMBLY__ -c $< -o $*.o
6486 -
6487 -clean:
6488 - rm -f $(target)/*.o $(target)/*.bin
6489 -
6490 -fastdep:
6491 -
6492 -modules:
6493 -
6494 -modules-install:
6495 +obj-y = head.o bootload.o crisv32_nand.o nand_base.o nand_ids.o nand_ecc.o \
6496 + lib.o
6497 +OBJECTS = $(obj)/head.o $(obj)/bootload.o \
6498 + $(obj)/crisv32_nand.o $(obj)/nand_base.o \
6499 + $(obj)/nand_ids.o $(obj)/nand_ecc.o \
6500 + $(obj)/lib.o $(obj)/../../lib/lib.a
6501 +
6502 +targets := rescue.o rescue.bin
6503 +
6504 +quiet_cmd_ldlibgcc = LD $@
6505 +cmd_ldlibgcc = $(LD) $(LDFLAGS) $(filter-out FORCE,$^) $(LDPOSTFLAGS) -o $@
6506 +
6507 +$(obj)/rescue.o: $(OBJECTS) FORCE
6508 + $(call if_changed,ldlibgcc)
6509 +
6510 +$(obj)/rescue.bin: $(obj)/rescue.o FORCE
6511 + $(call if_changed,objcopy)
6512 + cp -p $(obj)/rescue.bin $(objtree)
6513 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/boot/rescue/bootload.c linux-2.6.19.2.dev/arch/cris/arch-v32/boot/rescue/bootload.c
6514 --- linux-2.6.19.2.old/arch/cris/arch-v32/boot/rescue/bootload.c 1970-01-01 01:00:00.000000000 +0100
6515 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/boot/rescue/bootload.c 2006-11-28 11:05:39.000000000 +0100
6516 @@ -0,0 +1,277 @@
6517 +/*
6518 + * bootload.c
6519 + * Simple boot loader for NAND chips on Etrax FS
6520 + *
6521 + * $Id: bootload.c,v 1.8 2006/11/28 10:05:39 ricardw Exp $
6522 + *
6523 + */
6524 +
6525 +#include <linux/types.h>
6526 +#include <linux/delay.h>
6527 +
6528 +#include "mtd.h"
6529 +#include "nand.h"
6530 +
6531 +#include <asm/arch/hwregs/reg_rdwr.h>
6532 +#include <asm/arch/hwregs/reg_map.h>
6533 +#include <asm/arch/hwregs/pinmux_defs.h>
6534 +
6535 +#include "lib.h"
6536 +
6537 +#define BOOT_ADDR (CONFIG_ETRAX_PTABLE_SECTOR + 0x40200000)
6538 +
6539 +/* bits for nand_rw() `cmd'; or together as needed */
6540 +
6541 +#define NANDRW_READ 0x01
6542 +#define NANDRW_WRITE 0x00
6543 +#define NANDRW_JFFS2 0x02
6544 +#define NANDRW_JFFS2_SKIP 0x04
6545 +
6546 +#define ROUND_DOWN(value, boundary) ((value) & (~((boundary)-1)))
6547 +
6548 +/* set $r8 to RAM_INIT_MAGIC, $r12 to NAND_BOOT_MAGIC then jump */
6549 +#define BOOT(addr) __asm__ volatile (" \
6550 + move.d 0x56902387, $r8\n\
6551 + move.d 0x9A9DB001, $r12\n\
6552 + jump %0\n\
6553 + nop\n\
6554 + " : : "r" (addr))
6555 +
6556 +#define D(x)
6557 +
6558 +extern struct mtd_info *crisv32_nand_flash_probe(void);
6559 +
6560 +extern int _end, _bss, _edata;
6561 +
6562 +/*
6563 + * NAND read/write from U-Boot 1.4.4
6564 + * Modified for newer mtd and use of mtd interface instead of nand directly.
6565 + *
6566 + * cmd: 0: NANDRW_WRITE write, fail on bad block
6567 + * 1: NANDRW_READ read, fail on bad block
6568 + * 2: NANDRW_WRITE | NANDRW_JFFS2 write, skip bad blocks
6569 + * 3: NANDRW_READ | NANDRW_JFFS2 read, data all 0xff for bad blocks
6570 + * 7: NANDRW_READ | NANDRW_JFFS2 | NANDRW_JFFS2_SKIP read, skip bad blocks
6571 + */
6572 +static int
6573 +nand_rw (struct mtd_info* mtd, int cmd,
6574 + size_t start, size_t len,
6575 + size_t *retlen, u_char * buf)
6576 +{
6577 + int ret = 0, n, total = 0;
6578 +
6579 + /* eblk (once set) is the start of the erase block containing the
6580 + * data being processed.
6581 + */
6582 + size_t eblk = ~0; /* force mismatch on first pass */
6583 + size_t erasesize = mtd->erasesize;
6584 +
6585 + while (len) {
6586 + if ((start & (-erasesize)) != eblk) {
6587 + /* have crossed into new erase block, deal with
6588 + * it if it is marked bad.
6589 + */
6590 + eblk = start & (-erasesize); /* start of block */
6591 + D(
6592 + puts("New block ");
6593 + putx(eblk);
6594 + putnl();
6595 + )
6596 + if (mtd->block_isbad(mtd, eblk)) {
6597 + if (cmd == (NANDRW_READ | NANDRW_JFFS2)) {
6598 + while (len > 0 &&
6599 + start - eblk < erasesize) {
6600 + *(buf++) = 0xff;
6601 + ++start;
6602 + ++total;
6603 + --len;
6604 + }
6605 + continue;
6606 + } else if (cmd == (NANDRW_READ | NANDRW_JFFS2 | NANDRW_JFFS2_SKIP)) {
6607 + start += erasesize;
6608 + continue;
6609 + } else if (cmd == (NANDRW_WRITE | NANDRW_JFFS2)) {
6610 + /* skip bad block */
6611 + start += erasesize;
6612 + continue;
6613 + } else {
6614 + ret = 1;
6615 + break;
6616 + }
6617 + }
6618 + }
6619 + /* The ECC will not be calculated correctly if
6620 + less than 512 is written or read */
6621 + /* Is request at least 512 bytes AND it starts on a proper boundry */
6622 + if((start != ROUND_DOWN(start, 0x200)) || (len < 0x200))
6623 + puts("Warning block writes should be at least 512 bytes and start on a 512 byte boundry\r\n");
6624 +
6625 +#if 0
6626 + buf = (void *) 0x38008000; /* to fixed address, for testing */
6627 +#endif
6628 +
6629 + if (cmd & NANDRW_READ) {
6630 + ret = mtd->read_ecc(mtd, start,
6631 + min(len, eblk + erasesize - start),
6632 + (size_t *)&n, (u_char*)buf,
6633 + NULL, NULL);
6634 + } else {
6635 + ret = mtd->write_ecc(mtd, start,
6636 + min(len, eblk + erasesize - start),
6637 + (size_t *)&n, (u_char*)buf,
6638 + NULL, NULL);
6639 + }
6640 +
6641 + if (ret) {
6642 + break;
6643 + }
6644 +
6645 + start += n;
6646 + buf += n;
6647 + total += n;
6648 + len -= n;
6649 + }
6650 + if (retlen)
6651 + *retlen = total;
6652 +
6653 + return ret;
6654 +}
6655 +
6656 +
6657 +void
6658 +bootload()
6659 +{
6660 + char revision;
6661 + struct mtd_info *mtd;
6662 +
6663 + serial_init();
6664 +
6665 + __asm__ volatile ("move $vr,%0" : "=rm" (revision));
6666 + if (revision < 32)
6667 + {
6668 + puts("You need an ETRAX FS to run Linux 2.6/crisv32.\r\n");
6669 + while(1);
6670 + }
6671 +
6672 + puts("\r\n\nETRAX FS NAND boot loader\r\n");
6673 + puts("=========================\r\n");
6674 + puts("Rev 1, " __DATE__ " " __TIME__ "\r\n");
6675 +
6676 + puts("CPU revision: ");
6677 + putx(revision);
6678 + putnl();
6679 +
6680 + puts("Bootloader main at ") ;
6681 + putx((int) bootload);
6682 + putnl();
6683 +
6684 + puts("Data end: ");
6685 + putx((long) &_edata);
6686 + putnl();
6687 +
6688 + puts("Bss: ");
6689 + putx((long) &_bss);
6690 + putnl();
6691 +
6692 + puts("Heap: ");
6693 + putx((long) &_end);
6694 + putnl();
6695 +
6696 +#if 0 /* loop calibration */
6697 + volatile int i;
6698 + puts ("10000 loops...");
6699 + for (i = 0; i < 10000; i++)
6700 + udelay(1000);
6701 + puts("done\r\n");
6702 +#endif
6703 +
6704 + puts("Identifying nand chip...\r\n");
6705 + mtd = crisv32_nand_flash_probe();
6706 + puts("Done.\r\n");
6707 +
6708 + if (mtd) {
6709 + puts("Chip identified. ");
6710 +#if 0 /* print chip parameters */
6711 + if (mtd->name)
6712 + puts(mtd->name);
6713 +
6714 + puts("\r\ntype: ");
6715 + putx(mtd->type);
6716 + puts("\r\nflags: ");
6717 + putx(mtd->flags);
6718 + puts("\r\nsize: ");
6719 + putx(mtd->size);
6720 + puts("\r\nerasesize: ");
6721 + putx(mtd->erasesize);
6722 + puts("\r\noobblock: ");
6723 + putx(mtd->oobblock);
6724 + puts("\r\noobsize: ");
6725 + putx(mtd->oobsize);
6726 + puts("\r\necctype: ");
6727 + putx(mtd->ecctype);
6728 + puts("\r\neccsize: ");
6729 + putx(mtd->eccsize);
6730 +#endif
6731 + putnl();
6732 +
6733 + puts("Bad blocks:\r\n");
6734 +
6735 + int i;
6736 + for (i = 0; i < mtd->size; i += mtd->erasesize) {
6737 + if (mtd->block_isbad(mtd, i)) {
6738 + putx(i);
6739 + putnl();
6740 + }
6741 + }
6742 +
6743 +#if 0 /* print oob parameters */
6744 + puts("Oob info:\r\n");
6745 + puts("useecc: ");
6746 + putx(mtd->oobinfo.useecc);
6747 + puts("\r\neccbytes: ");
6748 + putx(mtd->oobinfo.eccbytes);
6749 + puts("\r\neccpos: ");
6750 + for (i = 0; i < mtd->oobinfo.eccbytes; i++) {
6751 + putx(mtd->oobinfo.eccpos[i]);
6752 + putc(' ');
6753 + }
6754 + putnl();
6755 +#endif
6756 +
6757 + puts("Bootload in progress...");
6758 + int res, copied;
6759 + res = nand_rw(mtd,
6760 + NANDRW_READ | NANDRW_JFFS2 | NANDRW_JFFS2_SKIP,
6761 + CONFIG_ETRAX_PTABLE_SECTOR,
6762 + 0x200000, /* 2 megs */
6763 + &copied,
6764 + (void *) BOOT_ADDR);
6765 +
6766 + puts("complete, status ");
6767 + putx(res);
6768 + puts(", loaded ");
6769 + putx(copied);
6770 + puts(" bytes\r\n");
6771 +#if 1
6772 + puts("Data in DRAM:\r\n");
6773 + putx(* (int *) (BOOT_ADDR + 0));
6774 + putc(' ');
6775 + putx(* (int *) (BOOT_ADDR + 4));
6776 + putc(' ');
6777 + putx(* (int *) (BOOT_ADDR + 8));
6778 + putnl();
6779 +#endif
6780 +
6781 + if (res)
6782 + error("Corrupt data in NAND flash.");
6783 + else
6784 + {
6785 + puts("Booting...\r\n");
6786 + BOOT(BOOT_ADDR);
6787 + }
6788 + } else
6789 + error("No NAND flash chip found to boot from.");
6790 +
6791 + while (1)
6792 + ; /* hang around until hell freezes over */
6793 +}
6794 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/boot/rescue/crisv32_nand.c linux-2.6.19.2.dev/arch/cris/arch-v32/boot/rescue/crisv32_nand.c
6795 --- linux-2.6.19.2.old/arch/cris/arch-v32/boot/rescue/crisv32_nand.c 1970-01-01 01:00:00.000000000 +0100
6796 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/boot/rescue/crisv32_nand.c 2006-11-21 15:40:02.000000000 +0100
6797 @@ -0,0 +1,157 @@
6798 +/*
6799 + * Taken from arch/cris/arch-v32/drivers/nandflash.c
6800 + * and modified to use for boot loader.
6801 + *
6802 + * Copyright (c) 2004
6803 + *
6804 + * Derived from drivers/mtd/nand/spia.c
6805 + * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
6806 + *
6807 + * $Id: crisv32_nand.c,v 1.2 2006/11/21 14:40:02 ricardw Exp $
6808 + *
6809 + * This program is free software; you can redistribute it and/or modify
6810 + * it under the terms of the GNU General Public License version 2 as
6811 + * published by the Free Software Foundation.
6812 + *
6813 + */
6814 +
6815 +#include "mtd.h"
6816 +#include "nand.h"
6817 +
6818 +#if 0
6819 +#include <linux/mtd/partitions.h>
6820 +#endif
6821 +
6822 +#if 0
6823 +#include <asm/arch/memmap.h>
6824 +#endif
6825 +
6826 +#include <asm/arch/hwregs/reg_map.h>
6827 +#include <asm/arch/hwregs/reg_rdwr.h>
6828 +#include <asm/arch/hwregs/gio_defs.h>
6829 +#include <asm/arch/hwregs/bif_core_defs.h>
6830 +
6831 +#include "lib.h"
6832 +
6833 +/* Hardware */
6834 +
6835 +#define CE_BIT 4
6836 +#define CLE_BIT 5
6837 +#define ALE_BIT 6
6838 +#define BY_BIT 7
6839 +
6840 +#define NAND_RD_ADDR 0x90000000 /* read address */
6841 +#define NAND_WR_ADDR 0x94000000 /* write address */
6842 +
6843 +static struct mtd_info *crisv32_mtd = NULL;
6844 +
6845 +/*
6846 + * hardware specific access to control-lines
6847 + */
6848 +static void crisv32_hwcontrol(struct mtd_info *mtd, int cmd)
6849 +{
6850 + unsigned long flags;
6851 + reg_gio_rw_pa_dout dout = REG_RD(gio, regi_gio, rw_pa_dout);
6852 +
6853 + switch(cmd){
6854 + case NAND_CTL_SETCLE:
6855 + dout.data |= (1<<CLE_BIT);
6856 + break;
6857 + case NAND_CTL_CLRCLE:
6858 + dout.data &= ~(1<<CLE_BIT);
6859 + break;
6860 + case NAND_CTL_SETALE:
6861 + dout.data |= (1<<ALE_BIT);
6862 + break;
6863 + case NAND_CTL_CLRALE:
6864 + dout.data &= ~(1<<ALE_BIT);
6865 + break;
6866 + case NAND_CTL_SETNCE:
6867 + dout.data &= ~(1<<CE_BIT);
6868 + break;
6869 + case NAND_CTL_CLRNCE:
6870 + dout.data |= (1<<CE_BIT);
6871 + break;
6872 + }
6873 + REG_WR(gio, regi_gio, rw_pa_dout, dout);
6874 +#if 0
6875 + /* read from gpio reg to flush pipeline.
6876 + * doesn't seem to be necessary.
6877 + */
6878 + (void) REG_RD(gio, regi_gio, rw_pa_dout); /* gpio sync */
6879 +#endif
6880 +}
6881 +
6882 +/*
6883 + * read device ready pin
6884 + */
6885 +int crisv32_device_ready(struct mtd_info *mtd)
6886 +{
6887 + reg_gio_r_pa_din din = REG_RD(gio, regi_gio, r_pa_din);
6888 + return ((din.data & (1 << BY_BIT)) >> BY_BIT);
6889 +}
6890 +
6891 +/*
6892 + * Main initialization routine
6893 + */
6894 +struct mtd_info* crisv32_nand_flash_probe (void)
6895 +{
6896 + reg_bif_core_rw_grp3_cfg bif_cfg = REG_RD(bif_core, regi_bif_core, rw_grp3_cfg);
6897 + reg_gio_rw_pa_oe pa_oe = REG_RD(gio, regi_gio, rw_pa_oe);
6898 + struct nand_chip *this;
6899 + int err = 0;
6900 +
6901 + /* Allocate memory for MTD device structure and private data */
6902 + crisv32_mtd = malloc (sizeof(struct mtd_info) + sizeof (struct nand_chip));
6903 + if (!crisv32_mtd) {
6904 + puts ("Unable to allocate CRISv32 NAND MTD device structure.\r\n");
6905 + err = -ENOMEM;
6906 + return NULL;
6907 + }
6908 +
6909 + /* Get pointer to private data */
6910 + this = (struct nand_chip *) (&crisv32_mtd[1]);
6911 +
6912 + pa_oe.oe |= 1 << CE_BIT;
6913 + pa_oe.oe |= 1 << ALE_BIT;
6914 + pa_oe.oe |= 1 << CLE_BIT;
6915 + pa_oe.oe &= ~ (1 << BY_BIT);
6916 + REG_WR(gio, regi_gio, rw_pa_oe, pa_oe);
6917 +
6918 + bif_cfg.gated_csp0 = regk_bif_core_rd;
6919 + bif_cfg.gated_csp1 = regk_bif_core_wr;
6920 + REG_WR(bif_core, regi_bif_core, rw_grp3_cfg, bif_cfg);
6921 +
6922 + /* Initialize structures */
6923 + memset((char *) crisv32_mtd, 0, sizeof(struct mtd_info));
6924 + memset((char *) this, 0, sizeof(struct nand_chip));
6925 +
6926 + /* Link the private data with the MTD structure */
6927 + crisv32_mtd->priv = this;
6928 +
6929 + /* Set address of NAND IO lines */
6930 + this->IO_ADDR_R = (void *) NAND_RD_ADDR;
6931 + this->IO_ADDR_W = (void *) NAND_WR_ADDR;
6932 + this->hwcontrol = crisv32_hwcontrol;
6933 + this->dev_ready = crisv32_device_ready;
6934 + /* 20 us command delay time */
6935 + this->chip_delay = 20;
6936 + this->eccmode = NAND_ECC_SOFT;
6937 +
6938 +#if 0 /* don't use BBT in boot loader */
6939 + /* Enable the following for a flash based bad block table */
6940 + this->options = NAND_USE_FLASH_BBT;
6941 +#endif
6942 + /* don't scan for BBT */
6943 + this->options = NAND_SKIP_BBTSCAN;
6944 +
6945 + /* Scan to find existance of the device */
6946 + if (nand_scan (crisv32_mtd, 1)) {
6947 + err = -ENXIO;
6948 + puts ("nand_scan failed\r\n");
6949 + free (crisv32_mtd);
6950 + return NULL;
6951 + }
6952 +
6953 + return crisv32_mtd;
6954 +}
6955 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/boot/rescue/head.S linux-2.6.19.2.dev/arch/cris/arch-v32/boot/rescue/head.S
6956 --- linux-2.6.19.2.old/arch/cris/arch-v32/boot/rescue/head.S 2007-01-10 20:10:37.000000000 +0100
6957 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/boot/rescue/head.S 2007-01-31 16:52:19.000000000 +0100
6958 @@ -1,14 +1,85 @@
6959 -/* $Id: head.S,v 1.4 2004/11/01 16:10:28 starvik Exp $
6960 - *
6961 - * This used to be the rescue code but now that is handled by the
6962 - * RedBoot based RFL instead. Nothing to see here, move along.
6963 +/* $Id: head.S,v 1.16 2007/01/31 15:52:19 pkj Exp $
6964 + *
6965 + * Simple boot loader which can also handle NAND chips.
6966 */
6967
6968 -#include <asm/arch/hwregs/reg_map_asm.h>
6969 -#include <asm/arch/hwregs/config_defs_asm.h>
6970 +#include <asm/arch/hwregs/asm/reg_map_asm.h>
6971 +#include <asm/arch/hwregs/asm/config_defs_asm.h>
6972 +
6973 +#define RAM_INIT_MAGIC 0x56902387
6974 +#define NAND_BOOT_MAGIC 0x9A9DB001
6975 +
6976 +;; Debugging. Normally all these are set to 0.
6977 +#define LEDS (0)
6978 +#define LEDTEST (0)
6979 +#define FLASH_LEDS_INSTEAD_OF_BOOT (0)
6980 +#define SERIAL_DUMP (0)
6981 +#define SERIAL_PORT (0)
6982 +#define SERIAL_RECEIVE (0)
6983 +
6984 +#if LEDS
6985 +#include <asm/arch/hwregs/asm/gio_defs_asm.h>
6986 +#include <asm/arch/hwregs/asm/pinmux_defs_asm.h>
6987 +#include <asm/arch/hwregs/asm/bif_core_defs_asm.h>
6988 +#endif
6989 +
6990 +#if SERIAL_DUMP
6991 +#include <asm/arch/hwregs/asm/ser_defs_asm.h>
6992 +#include <asm/arch/hwregs/asm/pinmux_defs_asm.h>
6993 +#endif
6994 +
6995 +
6996 +#if (SERIAL_PORT == 0)
6997 +#define regi_serial regi_ser0
6998 +#endif
6999 +#if (SERIAL_PORT == 1)
7000 +#define regi_serial regi_ser1
7001 +#endif
7002 +
7003 +;; Macros
7004 +
7005 +#if LEDS
7006 +.macro SAY x
7007 + orq 31, $r9
7008 + and.d ~(\x), $r9
7009 + move.d $r9, [$r8]
7010 +.endm
7011 +#else
7012 +.macro SAY x
7013 + ;; nothing
7014 +.endm
7015 +#endif
7016 +
7017 +#if SERIAL_DUMP
7018 +.macro DISPLAY x
7019 + move.d \x, $r6 ; save value
7020 + moveq 28, $r5 ; counter / shift amount
7021 +8:
7022 + move.d $r6, $r3 ; fetch value
7023 + bsr nybbleout
7024 + lsr.d $r5, $r3 ; shift nybble we want (delay slot)
7025 + subq 4, $r5 ; count down bits
7026 + bpl 8b ; loop
7027 + nop
7028 + bsr serout
7029 + moveq 13, $r3 ; delay slot
7030 + bsr serout
7031 + moveq 10, $r3 ; delay slot
7032 +.endm
7033 +#else
7034 +.macro DISPLAY x
7035 + ;; nothing
7036 +.endm
7037 +#endif
7038 +
7039 +
7040 +;; Code
7041
7042 .text
7043 +start:
7044
7045 + ;; TODO: Add code for Ronny's search-for-good-block boot rom algorithm
7046 +
7047 ;; Start clocks for used blocks.
7048 move.d REG_ADDR(config, regi_config, rw_clk_ctrl), $r1
7049 move.d [$r1], $r0
7050 @@ -17,22 +88,258 @@
7051 REG_STATE(config, rw_clk_ctrl, fix_io, yes), $r0
7052 move.d $r0, [$r1]
7053
7054 - ;; Copy 68KB NAND flash to Internal RAM (if NAND boot)
7055 - move.d 0x38004000, $r10
7056 - move.d 0x8000, $r11
7057 - move.d 0x11000, $r12
7058 - move.d copy_complete, $r13
7059 - and.d 0x000fffff, $r13
7060 - or.d 0x38000000, $r13
7061 +
7062 +#if LEDS
7063 + ;; set up for led control on PB 0..4
7064 + move.d REG_ADDR(gio, regi_gio, rw_pb_dout), $r8 ; output reg
7065 + move.d [$r8], $r9 ; shadow
7066 +
7067 + ;; set up pinmux
7068 + move.d REG_ADDR(pinmux, regi_pinmux, rw_pb_gio), $r2
7069 + move.d [$r2], $r3
7070 + orq 31, $r3
7071 + move.d $r3, [$r2]
7072 +
7073 + ;; set up GPIO
7074 + ;; set to outputs
7075 + move.d REG_ADDR(gio, regi_gio, rw_pb_oe), $r2
7076 + move.d [$r2], $r3
7077 + orq 31, $r3
7078 + move.d $r3, [$r2]
7079 +
7080 +
7081 +#if LEDTEST
7082 + ;; led test
7083 +
7084 + moveq 0, $r1 ; led 5-bit binary counter
7085 +1:
7086 + or.d 31, $r9
7087 + xor $r1, $r9
7088 + move.d $r9, [$r8]
7089 + addq 1, $r1
7090 +
7091 + move.d 100000000, $r2 ; delay loop (100e6 => 1s @200Mc)
7092 +2:
7093 + bne 2b
7094 + subq 1, $r2
7095 +
7096 + ba 1b ; loop
7097 + nop
7098 +#endif
7099 +
7100 +#endif
7101 +
7102 +
7103 +check_nand_boot:
7104 + ;; Check boot source by checking highest nybble of PC:
7105 + ;; If we're running at address 0x0XXXXXXX, we're in flash/eprom/sram
7106 + ;; If we're running at address 0x38000000, we're in internal RAM,
7107 + ;; so we're most likely coming from NAND.
7108 + ;; If we're running at address 0x40000000, we're in SDRAM,
7109 + ;; so we've most likely been started by some sort of bootstrapper
7110 + ;; e.g. fsboot, which in turn implies NAND, else we would be booting
7111 + ;; normally at 0x0XXXXXXX
7112 +
7113 + SAY 1
7114 +
7115 +here:
7116 + lapcq ., $r0 ; get PC
7117 + sub.d (here-start), $r0 ; offset from here
7118 + beq normal_boot ; running at address 0 - normal boot
7119 + move.d $r0, $r13 ; save offset for later (unused delay slot)
7120 + lsrq 28, $r0 ; get highest nybble
7121 +
7122 + SAY 2
7123 +
7124 + ;; Prepare to copy 128KB of the NAND flash to internal RAM
7125 + move.d 0x38000200, $r10 ; dest in internal RAM
7126 + move.d 0x1fe00, $r12 ; #bytes
7127 + cmpq 4, $r0 ; running in RAM => started by fsboot
7128 + bhs copy_from_ram
7129 + movu.w 0x0200, $r11 ; source in flash (byte address) (DELAY SLOT)
7130
7131 #include "../../lib/nand_init.S"
7132
7133 - ;; No NAND found
7134 +#if LEDS
7135 + ;; must set up registers again (clobbered by nand_init)
7136 + move.d REG_ADDR(gio, regi_gio, rw_pb_dout), $r8 ; output reg
7137 + move.d [$r8], $r9 ; shadow
7138 +#endif
7139 +
7140 + SAY 3
7141 +
7142 + ba copy_complete
7143 + nop
7144 +
7145 + ; Since the code above has to reside within the first 256 bytes of
7146 + ; NAND flash, verify that the code so far hasn't gone past this
7147 + ; limit. If you're considering removing this, you haven't
7148 + ; properly understood the problem; see nand_init.S for details.
7149 + .org PAGE_SIZE_ADDRESSES ; from nand_init.S
7150 + .org PAGE_SIZE_BYTES ; from nand_init.S
7151 +
7152 +normal_boot:
7153 + SAY 4
7154 +
7155 + ;; Normal NOR boot
7156 move.d CONFIG_ETRAX_PTABLE_SECTOR, $r10
7157 - jump $r10 ; Jump to decompresser
7158 + jump $r10 ; Jump to decompresser
7159 + nop
7160 +
7161 +copy_from_ram:
7162 + add.d $r13, $r11 ; mem offs + src offs -> src addr
7163 +1:
7164 + move.d [$r11+], $r0 ; read source
7165 + subq 4, $r12 ; 4 bytes at a time
7166 + bne 1b ; loop until done
7167 + move.d $r0, [$r10+] ; write dest (DELAY SLOT)
7168 + jump copy_complete ; jump to internal RAM
7169 + nop ; delay slot
7170 +
7171 +copy_complete:
7172 + SAY 5
7173 +
7174 +#if FLASH_LEDS_INSTEAD_OF_BOOT
7175 +
7176 +flash:
7177 +
7178 + ;; led test
7179 +
7180 + moveq 0, $r1 ; led binary counter
7181 +1:
7182 + or.d 31, $r9
7183 + xor $r1, $r9
7184 + move.d $r9, [$r8]
7185 + addq 1, $r1
7186 +
7187 + move.d 100000000, $r2 ; delay loop (100e6 => 1s)
7188 +2:
7189 + bne 2b
7190 + subq 1, $r2
7191 +
7192 + ba 1b ; loop forever
7193 nop
7194 +#endif
7195
7196 -copy_complete:
7197 - move.d 0x38000000 + CONFIG_ETRAX_PTABLE_SECTOR, $r10
7198 - jump $r10 ; Jump to decompresser
7199 +
7200 +#if SERIAL_DUMP
7201 + ;; dump memory to serial port
7202 +
7203 +#if (SERIAL_PORT == 1)
7204 + ;; set up serial-1 pins
7205 + move.d REG_ADDR(pinmux, regi_pinmux, rw_hwprot), $r1
7206 + move.d [$r1], $r0
7207 + or.d REG_STATE(pinmux, rw_hwprot, ser1, yes), $r0
7208 + move.d $r0, [$r1]
7209 +#endif
7210 +
7211 + ;; rw_xoff: chr and automatic = 0
7212 + move.d REG_ADDR(ser, regi_serial, rw_xoff), $r1
7213 + move.d [$r1], $r0
7214 + and.d ~(REG_MASK(ser, rw_xoff, automatic) | REG_MASK(ser, rw_xoff, chr)), $r0
7215 + move.d $r0, [$r1]
7216 +
7217 + ;; tr control
7218 + move.d REG_ADDR(ser, regi_serial, rw_tr_ctrl), $r1
7219 + move.d [$r1], $r0
7220 + and.d ~(REG_MASK(ser, rw_tr_ctrl, base_freq) | REG_MASK(ser, rw_tr_ctrl, stop_bits)), $r0
7221 + or.d REG_STATE(ser, rw_tr_ctrl, stop_bits, bits2) | REG_STATE(ser, rw_tr_ctrl, base_freq, f29_493) | REG_STATE(ser, rw_tr_ctrl, en, yes), $r0
7222 + move.d $r0, [$r1]
7223 +
7224 + ;; tr baud
7225 + move.d REG_ADDR(ser, regi_serial, rw_tr_baud_div), $r1
7226 + move.d [$r1], $r0
7227 + move.w (29493000 / 8) / 115200, $r0
7228 + move.d $r0, [$r1]
7229 +
7230 +#if SERIAL_RECEIVE
7231 + ;; rec control
7232 + move.d REG_ADDR(ser, regi_serial, rw_rec_ctrl), $r1
7233 + move.d [$r1], $r0
7234 + and.d ~(REG_MASK(ser, rw_rec_ctrl, base_freq)), $r0
7235 + or.d REG_STATE(ser, rw_rec_ctrl, base_freq, f29_493) | REG_STATE(ser, rw_tr_ctrl, en, yes), $r0
7236 + move.d $r0, [$r1]
7237 +
7238 + ;; rec baud
7239 + move.d REG_ADDR(ser, regi_serial, rw_rec_baud_div), $r1
7240 + move.d [$r1], $r0
7241 + move.w (29493000 / 8) / 115200, $r0
7242 + move.d $r0, [$r1]
7243 +#endif
7244 +
7245 + ;; dump memory
7246 +
7247 + move.d 0x38000000, $r5 ; pointer
7248 +
7249 + bsr serout
7250 + moveq 13, $r3
7251 + bsr serout
7252 + moveq 10, $r3
7253 + bsr serout
7254 + moveq 10, $r3
7255 +
7256 +1:
7257 + movu.b [$r5+], $r3 ; get value
7258 + move.d $r3, $r6 ; save
7259 +
7260 + bsr nybbleout
7261 + lsrq 4, $r3 ; high nybble (delay slot)
7262 +
7263 + move.d $r6, $r3 ; restore
7264 + bsr nybbleout
7265 + andq 15, $r3 ; delay slot
7266 +
7267 + movu.b 32, $r3
7268 + bsr serout
7269 nop
7270 +
7271 + move.d $r5, $r3
7272 + andq 15, $r3
7273 + bne 1b
7274 + nop
7275 +
7276 + bsr serout
7277 + moveq 13, $r3 ; delay slot
7278 + bsr serout
7279 + moveq 10, $r3 ; delay slot
7280 +
7281 + ba 1b ; loop forever
7282 + nop
7283 +
7284 +nybbleout:
7285 + cmpq 10, $r3
7286 + blo 1f
7287 + addq 48, $r3 ; delay slot
7288 + addq 7, $r3
7289 +1:
7290 +serout:
7291 + move.d REG_ADDR(ser, regi_serial, rs_stat_din), $r1
7292 + move.d REG_ADDR(ser, regi_serial, rw_dout), $r2
7293 +2:
7294 + move.d [$r1], $r4
7295 + btstq REG_BIT(ser, rs_stat_din, tr_rdy), $r4
7296 + bpl 2b
7297 + nop
7298 + ret
7299 + move.d $r3, [$r2] ; delay slot
7300 +
7301 +#endif
7302 +
7303 +;; Init DRAM
7304 +
7305 +#include "../../lib/dram_init.S"
7306 + move.d RAM_INIT_MAGIC, $r8 ; tell kernel boot loader dram init'd
7307 + move.d NAND_BOOT_MAGIC, $r12 ; booted from NAND flash
7308 +
7309 +;; TODO: Clear .bss (not needed yet because size of .bss is zero)
7310 +;; TODO: Change .ld script so that BSS is in DRAM?
7311 +
7312 +;; Ok, time to do something. Continue with boot loader in C.
7313 +;; Must set up minimal C environment first though.
7314 +
7315 + move.d 0x38020000, $sp ; stack pointer at top of internal RAM
7316 +
7317 + move.d bootload, $r10
7318 + jump $r10 ; Jump to boot loader
7319 + nop
7320 +
7321 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/boot/rescue/lib.c linux-2.6.19.2.dev/arch/cris/arch-v32/boot/rescue/lib.c
7322 --- linux-2.6.19.2.old/arch/cris/arch-v32/boot/rescue/lib.c 1970-01-01 01:00:00.000000000 +0100
7323 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/boot/rescue/lib.c 2006-11-03 11:35:52.000000000 +0100
7324 @@ -0,0 +1,243 @@
7325 +/*
7326 + * lib.c
7327 + * Small practical functions for boot loader
7328 + * malloc/free
7329 + * memcpy/memset
7330 + * writeb/writew/readb/readw
7331 + * putc/puts/putnybble/putx
7332 + * error/error2/BUG
7333 + * serial_init
7334 + *
7335 + * $Id: lib.c,v 1.4 2006/11/03 10:35:52 pkj Exp $
7336 + *
7337 + */
7338 +
7339 +#include <linux/types.h>
7340 +#include <asm/arch/hwregs/reg_rdwr.h>
7341 +#include <asm/arch/hwregs/reg_map.h>
7342 +#include <asm/arch/hwregs/ser_defs.h>
7343 +#include <asm/arch/hwregs/pinmux_defs.h>
7344 +
7345 +#include "lib.h"
7346 +
7347 +/* the "heap" is put directly after BSS ends, at _end */
7348 +
7349 +extern int _end;
7350 +static long free_mem_ptr = (long)&_end;
7351 +
7352 +void *malloc(int size)
7353 +{
7354 + void *p;
7355 +
7356 + if (size <0) error("Malloc error");
7357 +
7358 + free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
7359 +
7360 + p = (void *)free_mem_ptr;
7361 + free_mem_ptr += size;
7362 +
7363 + return p;
7364 +}
7365 +
7366 +void free(void *where)
7367 +{ /* Don't care */
7368 +}
7369 +
7370 +/* I/O */
7371 +
7372 +unsigned char readb(const volatile void *addr)
7373 +{
7374 + return *(volatile unsigned char *) addr;
7375 +}
7376 +
7377 +unsigned short readw(const volatile void *addr)
7378 +{
7379 + return *(volatile unsigned short *) addr;
7380 +}
7381 +
7382 +void writeb(unsigned char b, volatile void *addr)
7383 +{
7384 + *(volatile unsigned char *) addr = b;
7385 +}
7386 +
7387 +void writew(unsigned short b, volatile void *addr)
7388 +{
7389 + *(volatile unsigned short *) addr = b;
7390 +}
7391 +
7392 +/* info and error messages to serial console */
7393 +
7394 +#ifndef CONFIG_ETRAX_DEBUG_PORT_NULL
7395 +static inline void
7396 +serout(const char c, reg_scope_instances regi_ser)
7397 +{
7398 + reg_ser_rs_stat_din rs;
7399 + reg_ser_rw_dout dout = {.data = c};
7400 +
7401 + do {
7402 + rs = REG_RD(ser, regi_ser, rs_stat_din);
7403 + }
7404 + while (!rs.tr_rdy);/* Wait for tranceiver. */
7405 +
7406 + REG_WR(ser, regi_ser, rw_dout, dout);
7407 +}
7408 +
7409 +
7410 +void
7411 +putc(const char c)
7412 +{
7413 +#ifdef CONFIG_ETRAX_DEBUG_PORT0
7414 + serout(c, regi_ser0);
7415 +#endif
7416 +#ifdef CONFIG_ETRAX_DEBUG_PORT1
7417 + serout(c, regi_ser1);
7418 +#endif
7419 +#ifdef CONFIG_ETRAX_DEBUG_PORT2
7420 + serout(c, regi_ser2);
7421 +#endif
7422 +#ifdef CONFIG_ETRAX_DEBUG_PORT3
7423 + serout(c, regi_ser3);
7424 +#endif
7425 +}
7426 +
7427 +
7428 +void
7429 +puts(const char *s)
7430 +{
7431 + while (*s)
7432 + putc(*s++);
7433 +}
7434 +
7435 +void
7436 +putnybble(int n)
7437 +{
7438 + putc("0123456789abcdef"[n & 15]);
7439 +}
7440 +
7441 +void
7442 +putx(int x)
7443 +{
7444 + int i;
7445 +
7446 + puts("0x");
7447 + for (i = 7; i >= 0; i--)
7448 + putnybble(x >> 4*i);
7449 +}
7450 +
7451 +void
7452 +putnl()
7453 +{
7454 + puts("\r\n");
7455 +}
7456 +
7457 +#endif /* CONFIG_ETRAX_DEBUG_PORT_NULL */
7458 +
7459 +void*
7460 +memset(void* s, int c, size_t n)
7461 +{
7462 + int i;
7463 + char *ss = (char*)s;
7464 +
7465 + for (i=0;i<n;i++) ss[i] = c;
7466 +}
7467 +
7468 +void*
7469 +memcpy(void* __dest, __const void* __src,
7470 + size_t __n)
7471 +{
7472 + int i;
7473 + char *d = (char *)__dest, *s = (char *)__src;
7474 +
7475 + for (i=0;i<__n;i++) d[i] = s[i];
7476 +}
7477 +
7478 +void
7479 +error(const char *x)
7480 +{
7481 + puts("\r\n\n");
7482 + puts(x);
7483 + puts("\r\n\n -- System halted\n");
7484 +
7485 + while(1); /* Halt */
7486 +}
7487 +
7488 +void
7489 +error2(const char *x, int y, const char *z)
7490 +{
7491 + puts("\r\n\n");
7492 + puts(x);
7493 + putc(':');
7494 + putx(y);
7495 + putc(':');
7496 + puts(z);
7497 + puts("\r\n\n -- System halted\n");
7498 +
7499 + while(1); /* Halt */
7500 +}
7501 +
7502 +static inline void
7503 +serial_setup(reg_scope_instances regi_ser)
7504 +{
7505 + reg_ser_rw_xoff xoff;
7506 + reg_ser_rw_tr_ctrl tr_ctrl;
7507 + reg_ser_rw_rec_ctrl rec_ctrl;
7508 + reg_ser_rw_tr_baud_div tr_baud;
7509 + reg_ser_rw_rec_baud_div rec_baud;
7510 +
7511 + /* Turn off XOFF. */
7512 + xoff = REG_RD(ser, regi_ser, rw_xoff);
7513 +
7514 + xoff.chr = 0;
7515 + xoff.automatic = regk_ser_no;
7516 +
7517 + REG_WR(ser, regi_ser, rw_xoff, xoff);
7518 +
7519 + /* Set baudrate and stopbits. */
7520 + tr_ctrl = REG_RD(ser, regi_ser, rw_tr_ctrl);
7521 + rec_ctrl = REG_RD(ser, regi_ser, rw_rec_ctrl);
7522 + tr_baud = REG_RD(ser, regi_ser, rw_tr_baud_div);
7523 + rec_baud = REG_RD(ser, regi_ser, rw_rec_baud_div);
7524 +
7525 + tr_ctrl.stop_bits = 1; /* 2 stop bits. */
7526 + tr_ctrl.en = 1; /* enable transmitter */
7527 + rec_ctrl.en = 1; /* enabler receiver */
7528 +
7529 + /*
7530 + * The baudrate setup used to be a bit fishy, but now transmitter and
7531 + * receiver are both set to the intended baud rate, 115200.
7532 + * The magic value is 29.493 MHz.
7533 + */
7534 + tr_ctrl.base_freq = regk_ser_f29_493;
7535 + rec_ctrl.base_freq = regk_ser_f29_493;
7536 + tr_baud.div = (29493000 / 8) / 115200;
7537 + rec_baud.div = (29493000 / 8) / 115200;
7538 +
7539 + REG_WR(ser, regi_ser, rw_tr_ctrl, tr_ctrl);
7540 + REG_WR(ser, regi_ser, rw_tr_baud_div, tr_baud);
7541 + REG_WR(ser, regi_ser, rw_rec_ctrl, rec_ctrl);
7542 + REG_WR(ser, regi_ser, rw_rec_baud_div, rec_baud);
7543 +}
7544 +
7545 +void
7546 +serial_init()
7547 +{
7548 + reg_pinmux_rw_hwprot hwprot;
7549 +
7550 + hwprot = REG_RD(pinmux, regi_pinmux, rw_hwprot);
7551 +#ifdef CONFIG_ETRAX_DEBUG_PORT0
7552 + serial_setup(regi_ser0);
7553 +#endif
7554 +#ifdef CONFIG_ETRAX_DEBUG_PORT1
7555 + hwprot.ser1 = regk_pinmux_yes;
7556 + serial_setup(regi_ser1);
7557 +#endif
7558 +#ifdef CONFIG_ETRAX_DEBUG_PORT2
7559 + hwprot.ser2 = regk_pinmux_yes;
7560 + serial_setup(regi_ser2);
7561 +#endif
7562 +#ifdef CONFIG_ETRAX_DEBUG_PORT3
7563 + hwprot.ser3 = regk_pinmux_yes;
7564 + serial_setup(regi_ser3);
7565 +#endif
7566 + REG_WR(pinmux, regi_pinmux, rw_hwprot, hwprot);
7567 +}
7568 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/boot/rescue/lib.h linux-2.6.19.2.dev/arch/cris/arch-v32/boot/rescue/lib.h
7569 --- linux-2.6.19.2.old/arch/cris/arch-v32/boot/rescue/lib.h 1970-01-01 01:00:00.000000000 +0100
7570 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/boot/rescue/lib.h 2006-11-03 11:35:52.000000000 +0100
7571 @@ -0,0 +1,56 @@
7572 +/*
7573 + * lib.c
7574 + * Small practical functions for boot loader
7575 + * malloc/free
7576 + * memset/memcpy
7577 + * putc/puts/putnybble/putd
7578 + * writeb/writew/readb/readw
7579 + * error/error2/BUG
7580 + * serial_init
7581 + *
7582 + * $Id: lib.h,v 1.3 2006/11/03 10:35:52 pkj Exp $
7583 + *
7584 + */
7585 +
7586 +#ifndef _LIB_H
7587 +#define _LIB_H
7588 +
7589 +#include <linux/types.h>
7590 +
7591 +/* nice stuff we need without having any library around */
7592 +
7593 +void* memset(void* s, int c, size_t n);
7594 +void* memcpy(void* __dest, __const void* __src,
7595 + size_t __n);
7596 +
7597 +#define memzero(s, n) memset ((s), 0, (n))
7598 +
7599 +#undef BUG
7600 +#define BUG() error2("BUG in " __FILE__, __LINE__, __FUNCTION__)
7601 +
7602 +void *malloc(int size);
7603 +void free(void *where);
7604 +void error(const char *m);
7605 +void error2(const char *m, int l, const char *f);
7606 +void serial_init(void);
7607 +
7608 +#ifndef CONFIG_ETRAX_DEBUG_PORT_NULL
7609 +void putc(const char);
7610 +void puts(const char *);
7611 +void putnybble(int n);
7612 +void putx(int x);
7613 +void putnl();
7614 +#else
7615 +#define putc(ch)
7616 +#define puts(str)
7617 +#define putnybble(nyb)
7618 +#define putx(x)
7619 +#define putnl()
7620 +#endif /* CONFIG_ETRAX_DEBUG_PORT_NULL */
7621 +
7622 +unsigned char readb(const volatile void *addr);
7623 +unsigned short readw(const volatile void *addr);
7624 +void writeb(unsigned char b, volatile void *addr);
7625 +void writew(unsigned short b, volatile void *addr);
7626 +
7627 +#endif /* _LIB_H */
7628 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/boot/rescue/mtd-abi.h linux-2.6.19.2.dev/arch/cris/arch-v32/boot/rescue/mtd-abi.h
7629 --- linux-2.6.19.2.old/arch/cris/arch-v32/boot/rescue/mtd-abi.h 1970-01-01 01:00:00.000000000 +0100
7630 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/boot/rescue/mtd-abi.h 2006-09-06 11:21:07.000000000 +0200
7631 @@ -0,0 +1,121 @@
7632 +/*
7633 + * $Id: mtd-abi.h,v 1.1 2006/09/06 09:21:07 ricardw Exp $
7634 + *
7635 + * Portions of MTD ABI definition which are shared by kernel and user space
7636 + */
7637 +
7638 +#ifndef __MTD_ABI_H__
7639 +#define __MTD_ABI_H__
7640 +
7641 +#ifndef __KERNEL__ /* Urgh. The whole point of splitting this out into
7642 + separate files was to avoid #ifdef __KERNEL__ */
7643 +#define __user
7644 +#endif
7645 +
7646 +struct erase_info_user {
7647 + uint32_t start;
7648 + uint32_t length;
7649 +};
7650 +
7651 +struct mtd_oob_buf {
7652 + uint32_t start;
7653 + uint32_t length;
7654 + unsigned char __user *ptr;
7655 +};
7656 +
7657 +#define MTD_ABSENT 0
7658 +#define MTD_RAM 1
7659 +#define MTD_ROM 2
7660 +#define MTD_NORFLASH 3
7661 +#define MTD_NANDFLASH 4
7662 +#define MTD_PEROM 5
7663 +#define MTD_DATAFLASH 6
7664 +#define MTD_OTHER 14
7665 +#define MTD_UNKNOWN 15
7666 +
7667 +#define MTD_CLEAR_BITS 1 // Bits can be cleared (flash)
7668 +#define MTD_SET_BITS 2 // Bits can be set
7669 +#define MTD_ERASEABLE 4 // Has an erase function
7670 +#define MTD_WRITEB_WRITEABLE 8 // Direct IO is possible
7671 +#define MTD_VOLATILE 16 // Set for RAMs
7672 +#define MTD_XIP 32 // eXecute-In-Place possible
7673 +#define MTD_OOB 64 // Out-of-band data (NAND flash)
7674 +#define MTD_ECC 128 // Device capable of automatic ECC
7675 +#define MTD_NO_VIRTBLOCKS 256 // Virtual blocks not allowed
7676 +#define MTD_PROGRAM_REGIONS 512 // Configurable Programming Regions
7677 +
7678 +// Some common devices / combinations of capabilities
7679 +#define MTD_CAP_ROM 0
7680 +#define MTD_CAP_RAM (MTD_CLEAR_BITS|MTD_SET_BITS|MTD_WRITEB_WRITEABLE)
7681 +#define MTD_CAP_NORFLASH (MTD_CLEAR_BITS|MTD_ERASEABLE)
7682 +#define MTD_CAP_NANDFLASH (MTD_CLEAR_BITS|MTD_ERASEABLE|MTD_OOB)
7683 +#define MTD_WRITEABLE (MTD_CLEAR_BITS|MTD_SET_BITS)
7684 +
7685 +
7686 +// Types of automatic ECC/Checksum available
7687 +#define MTD_ECC_NONE 0 // No automatic ECC available
7688 +#define MTD_ECC_RS_DiskOnChip 1 // Automatic ECC on DiskOnChip
7689 +#define MTD_ECC_SW 2 // SW ECC for Toshiba & Samsung devices
7690 +
7691 +/* ECC byte placement */
7692 +#define MTD_NANDECC_OFF 0 // Switch off ECC (Not recommended)
7693 +#define MTD_NANDECC_PLACE 1 // Use the given placement in the structure (YAFFS1 legacy mode)
7694 +#define MTD_NANDECC_AUTOPLACE 2 // Use the default placement scheme
7695 +#define MTD_NANDECC_PLACEONLY 3 // Use the given placement in the structure (Do not store ecc result on read)
7696 +#define MTD_NANDECC_AUTOPL_USR 4 // Use the given autoplacement scheme rather than using the default
7697 +
7698 +/* OTP mode selection */
7699 +#define MTD_OTP_OFF 0
7700 +#define MTD_OTP_FACTORY 1
7701 +#define MTD_OTP_USER 2
7702 +
7703 +struct mtd_info_user {
7704 + uint8_t type;
7705 + uint32_t flags;
7706 + uint32_t size; // Total size of the MTD
7707 + uint32_t erasesize;
7708 + uint32_t oobblock; // Size of OOB blocks (e.g. 512)
7709 + uint32_t oobsize; // Amount of OOB data per block (e.g. 16)
7710 + uint32_t ecctype;
7711 + uint32_t eccsize;
7712 +};
7713 +
7714 +struct region_info_user {
7715 + uint32_t offset; /* At which this region starts,
7716 + * from the beginning of the MTD */
7717 + uint32_t erasesize; /* For this region */
7718 + uint32_t numblocks; /* Number of blocks in this region */
7719 + uint32_t regionindex;
7720 +};
7721 +
7722 +struct otp_info {
7723 + uint32_t start;
7724 + uint32_t length;
7725 + uint32_t locked;
7726 +};
7727 +
7728 +#define MEMGETINFO _IOR('M', 1, struct mtd_info_user)
7729 +#define MEMERASE _IOW('M', 2, struct erase_info_user)
7730 +#define MEMWRITEOOB _IOWR('M', 3, struct mtd_oob_buf)
7731 +#define MEMREADOOB _IOWR('M', 4, struct mtd_oob_buf)
7732 +#define MEMLOCK _IOW('M', 5, struct erase_info_user)
7733 +#define MEMUNLOCK _IOW('M', 6, struct erase_info_user)
7734 +#define MEMGETREGIONCOUNT _IOR('M', 7, int)
7735 +#define MEMGETREGIONINFO _IOWR('M', 8, struct region_info_user)
7736 +#define MEMSETOOBSEL _IOW('M', 9, struct nand_oobinfo)
7737 +#define MEMGETOOBSEL _IOR('M', 10, struct nand_oobinfo)
7738 +#define MEMGETBADBLOCK _IOW('M', 11, loff_t)
7739 +#define MEMSETBADBLOCK _IOW('M', 12, loff_t)
7740 +#define OTPSELECT _IOR('M', 13, int)
7741 +#define OTPGETREGIONCOUNT _IOW('M', 14, int)
7742 +#define OTPGETREGIONINFO _IOW('M', 15, struct otp_info)
7743 +#define OTPLOCK _IOR('M', 16, struct otp_info)
7744 +
7745 +struct nand_oobinfo {
7746 + uint32_t useecc;
7747 + uint32_t eccbytes;
7748 + uint32_t oobfree[8][2];
7749 + uint32_t eccpos[32];
7750 +};
7751 +
7752 +#endif /* __MTD_ABI_H__ */
7753 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/boot/rescue/mtd.h linux-2.6.19.2.dev/arch/cris/arch-v32/boot/rescue/mtd.h
7754 --- linux-2.6.19.2.old/arch/cris/arch-v32/boot/rescue/mtd.h 1970-01-01 01:00:00.000000000 +0100
7755 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/boot/rescue/mtd.h 2006-12-14 07:59:24.000000000 +0100
7756 @@ -0,0 +1,270 @@
7757 +/*
7758 + * $Id: mtd.h,v 1.5 2006/12/14 06:59:24 ricardw Exp $
7759 + *
7760 + * Copyright (C) 1999-2003 David Woodhouse <dwmw2@infradead.org> et al.
7761 + *
7762 + * Released under GPL
7763 + */
7764 +
7765 +#ifndef __MTD_MTD_H__
7766 +#define __MTD_MTD_H__
7767 +
7768 +#ifndef __KERNEL__
7769 +#error This is a kernel header. Perhaps include mtd-user.h instead?
7770 +#endif
7771 +
7772 +/* only include absolutely necessary linux headers which will not change
7773 + * significantly
7774 + */
7775 +#include <linux/types.h>
7776 +#include <linux/errno.h>
7777 +
7778 +#if 0
7779 +#include <linux/module.h>
7780 +#include <linux/uio.h>
7781 +#include <linux/notifier.h>
7782 +
7783 +#include <linux/mtd/compatmac.h>
7784 +#include <mtd/mtd-abi.h>
7785 +#endif
7786 +
7787 +#include "mtd-abi.h"
7788 +
7789 +/* local config, we don't want linux/config.h here */
7790 +/* any undef/define pairs here avoid warnings due to linux autoconf includes */
7791 +#undef CONFIG_MTD_PARTITIONS
7792 +#undef CONFIG_MTD_DEBUG
7793 +#undef CONFIG_MTD_NAND_VERIFY_WRITE
7794 +#define CONFIG_MTD_NAND_VERIFY_WRITE
7795 +
7796 +/* our MTD config */
7797 +
7798 +#define NAND_BBT_SUPPORT 0
7799 +#define NAND_WRITE_SUPPORT 0
7800 +#define NAND_ERASE_SUPPORT 0
7801 +#define NAND_MULTICHIP_SUPPORT 0
7802 +#define NAND_HWECC_SUPPORT 0
7803 +#define NAND_KVEC_SUPPORT 0
7804 +
7805 +
7806 +#define MTD_CHAR_MAJOR 90
7807 +#define MTD_BLOCK_MAJOR 31
7808 +#define MAX_MTD_DEVICES 16
7809 +
7810 +#define MTD_ERASE_PENDING 0x01
7811 +#define MTD_ERASING 0x02
7812 +#define MTD_ERASE_SUSPEND 0x04
7813 +#define MTD_ERASE_DONE 0x08
7814 +#define MTD_ERASE_FAILED 0x10
7815 +
7816 +/* If the erase fails, fail_addr might indicate exactly which block failed. If
7817 + fail_addr = 0xffffffff, the failure was not at the device level or was not
7818 + specific to any particular block. */
7819 +struct erase_info {
7820 + struct mtd_info *mtd;
7821 + u_int32_t addr;
7822 + u_int32_t len;
7823 + u_int32_t fail_addr;
7824 + u_long time;
7825 + u_long retries;
7826 + u_int dev;
7827 + u_int cell;
7828 + void (*callback) (struct erase_info *self);
7829 + u_long priv;
7830 + u_char state;
7831 + struct erase_info *next;
7832 +};
7833 +
7834 +struct mtd_erase_region_info {
7835 + u_int32_t offset; /* At which this region starts, from the beginning of the MTD */
7836 + u_int32_t erasesize; /* For this region */
7837 + u_int32_t numblocks; /* Number of blocks of erasesize in this region */
7838 +};
7839 +
7840 +struct mtd_info {
7841 + u_char type;
7842 + u_int32_t flags;
7843 + u_int32_t size; // Total size of the MTD
7844 +
7845 + /* "Major" erase size for the device. Naïve users may take this
7846 + * to be the only erase size available, or may use the more detailed
7847 + * information below if they desire
7848 + */
7849 + u_int32_t erasesize;
7850 +
7851 + u_int32_t oobblock; // Size of OOB blocks (e.g. 512)
7852 + u_int32_t oobsize; // Amount of OOB data per block (e.g. 16)
7853 + u_int32_t ecctype;
7854 + u_int32_t eccsize;
7855 +
7856 + /*
7857 + * Reuse some of the above unused fields in the case of NOR flash
7858 + * with configurable programming regions to avoid modifying the
7859 + * user visible structure layout/size. Only valid when the
7860 + * MTD_PROGRAM_REGIONS flag is set.
7861 + * (Maybe we should have an union for those?)
7862 + */
7863 +#define MTD_PROGREGION_SIZE(mtd) (mtd)->oobblock
7864 +#define MTD_PROGREGION_CTRLMODE_VALID(mtd) (mtd)->oobsize
7865 +#define MTD_PROGREGION_CTRLMODE_INVALID(mtd) (mtd)->ecctype
7866 +
7867 + // Kernel-only stuff starts here.
7868 + char *name;
7869 + int index;
7870 +
7871 + // oobinfo is a nand_oobinfo structure, which can be set by iotcl (MEMSETOOBINFO)
7872 + struct nand_oobinfo oobinfo;
7873 + u_int32_t oobavail; // Number of bytes in OOB area available for fs
7874 +
7875 + /* Data for variable erase regions. If numeraseregions is zero,
7876 + * it means that the whole device has erasesize as given above.
7877 + */
7878 + int numeraseregions;
7879 + struct mtd_erase_region_info *eraseregions;
7880 +
7881 + /* This really shouldn't be here. It can go away in 2.5 */
7882 + u_int32_t bank_size;
7883 +
7884 + int (*erase) (struct mtd_info *mtd, struct erase_info *instr);
7885 +
7886 + /* This stuff for eXecute-In-Place */
7887 + int (*point) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf);
7888 +
7889 + /* We probably shouldn't allow XIP if the unpoint isn't a NULL */
7890 + void (*unpoint) (struct mtd_info *mtd, u_char * addr, loff_t from, size_t len);
7891 +
7892 +
7893 + int (*read) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
7894 + int (*write) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf);
7895 +
7896 + int (*read_ecc) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel);
7897 + int (*write_ecc) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel);
7898 +
7899 + int (*read_oob) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
7900 + int (*write_oob) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf);
7901 +
7902 + /*
7903 + * Methods to access the protection register area, present in some
7904 + * flash devices. The user data is one time programmable but the
7905 + * factory data is read only.
7906 + */
7907 + int (*get_fact_prot_info) (struct mtd_info *mtd, struct otp_info *buf, size_t len);
7908 + int (*read_fact_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
7909 + int (*get_user_prot_info) (struct mtd_info *mtd, struct otp_info *buf, size_t len);
7910 + int (*read_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
7911 + int (*write_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
7912 + int (*lock_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len);
7913 +
7914 +#if NAND_KVEC_SUPPORT
7915 + /* kvec-based read/write methods. We need these especially for NAND flash,
7916 + with its limited number of write cycles per erase.
7917 + NB: The 'count' parameter is the number of _vectors_, each of
7918 + which contains an (ofs, len) tuple.
7919 + */
7920 + int (*readv) (struct mtd_info *mtd, struct kvec *vecs, unsigned long count, loff_t from, size_t *retlen);
7921 + int (*readv_ecc) (struct mtd_info *mtd, struct kvec *vecs, unsigned long count, loff_t from,
7922 + size_t *retlen, u_char *eccbuf, struct nand_oobinfo *oobsel);
7923 + int (*writev) (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen);
7924 + int (*writev_ecc) (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to,
7925 + size_t *retlen, u_char *eccbuf, struct nand_oobinfo *oobsel);
7926 +#endif
7927 +
7928 + /* Sync */
7929 + void (*sync) (struct mtd_info *mtd);
7930 +
7931 + /* Chip-supported device locking */
7932 + int (*lock) (struct mtd_info *mtd, loff_t ofs, size_t len);
7933 + int (*unlock) (struct mtd_info *mtd, loff_t ofs, size_t len);
7934 +
7935 + /* Power Management functions */
7936 + int (*suspend) (struct mtd_info *mtd);
7937 + void (*resume) (struct mtd_info *mtd);
7938 +
7939 + /* Bad block management functions */
7940 + int (*block_isbad) (struct mtd_info *mtd, loff_t ofs);
7941 + int (*block_markbad) (struct mtd_info *mtd, loff_t ofs);
7942 +
7943 +#if 0 /* don't know what this is for */
7944 + struct notifier_block reboot_notifier; /* default mode before reboot */
7945 +#endif
7946 +
7947 + void *priv;
7948 +
7949 + struct module *owner;
7950 + int usecount;
7951 +};
7952 +
7953 +#if 0 /* don't need these */
7954 + /* Kernel-side ioctl definitions */
7955 +
7956 +extern int add_mtd_device(struct mtd_info *mtd);
7957 +extern int del_mtd_device (struct mtd_info *mtd);
7958 +
7959 +extern struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num);
7960 +
7961 +extern void put_mtd_device(struct mtd_info *mtd);
7962 +
7963 +
7964 +struct mtd_notifier {
7965 + void (*add)(struct mtd_info *mtd);
7966 + void (*remove)(struct mtd_info *mtd);
7967 + struct list_head list;
7968 +};
7969 +
7970 +
7971 +extern void register_mtd_user (struct mtd_notifier *new);
7972 +extern int unregister_mtd_user (struct mtd_notifier *old);
7973 +#endif
7974 +
7975 +#if NAND_KVEC_SUPPORT
7976 +int default_mtd_writev(struct mtd_info *mtd, const struct kvec *vecs,
7977 + unsigned long count, loff_t to, size_t *retlen);
7978 +
7979 +int default_mtd_readv(struct mtd_info *mtd, struct kvec *vecs,
7980 + unsigned long count, loff_t from, size_t *retlen);
7981 +#endif
7982 +
7983 +#define MTD_ERASE(mtd, args...) (*(mtd->erase))(mtd, args)
7984 +#define MTD_POINT(mtd, a,b,c,d) (*(mtd->point))(mtd, a,b,c, (u_char **)(d))
7985 +#define MTD_UNPOINT(mtd, arg) (*(mtd->unpoint))(mtd, (u_char *)arg)
7986 +#define MTD_READ(mtd, args...) (*(mtd->read))(mtd, args)
7987 +#define MTD_WRITE(mtd, args...) (*(mtd->write))(mtd, args)
7988 +#define MTD_READV(mtd, args...) (*(mtd->readv))(mtd, args)
7989 +#define MTD_WRITEV(mtd, args...) (*(mtd->writev))(mtd, args)
7990 +#define MTD_READECC(mtd, args...) (*(mtd->read_ecc))(mtd, args)
7991 +#define MTD_WRITEECC(mtd, args...) (*(mtd->write_ecc))(mtd, args)
7992 +#define MTD_READOOB(mtd, args...) (*(mtd->read_oob))(mtd, args)
7993 +#define MTD_WRITEOOB(mtd, args...) (*(mtd->write_oob))(mtd, args)
7994 +#define MTD_SYNC(mtd) do { if (mtd->sync) (*(mtd->sync))(mtd); } while (0)
7995 +
7996 +
7997 +#ifdef CONFIG_MTD_PARTITIONS
7998 +void mtd_erase_callback(struct erase_info *instr);
7999 +#else
8000 +static inline void mtd_erase_callback(struct erase_info *instr)
8001 +{
8002 + if (instr->callback)
8003 + instr->callback(instr);
8004 +}
8005 +#endif
8006 +
8007 +/*
8008 + * Debugging macro and defines
8009 + */
8010 +#define MTD_DEBUG_LEVEL0 (0) /* Quiet */
8011 +#define MTD_DEBUG_LEVEL1 (1) /* Audible */
8012 +#define MTD_DEBUG_LEVEL2 (2) /* Loud */
8013 +#define MTD_DEBUG_LEVEL3 (3) /* Noisy */
8014 +
8015 +#ifdef CONFIG_MTD_DEBUG
8016 +#define DEBUG(n, args...) \
8017 + do { \
8018 + if (n <= CONFIG_MTD_DEBUG_VERBOSE) \
8019 + printk(KERN_INFO args); \
8020 + } while(0)
8021 +#else /* CONFIG_MTD_DEBUG */
8022 +#define DEBUG(n, args...) do { } while(0)
8023 +
8024 +#endif /* CONFIG_MTD_DEBUG */
8025 +
8026 +#endif /* __MTD_MTD_H__ */
8027 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/boot/rescue/nand.h linux-2.6.19.2.dev/arch/cris/arch-v32/boot/rescue/nand.h
8028 --- linux-2.6.19.2.old/arch/cris/arch-v32/boot/rescue/nand.h 1970-01-01 01:00:00.000000000 +0100
8029 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/boot/rescue/nand.h 2006-11-03 11:35:52.000000000 +0100
8030 @@ -0,0 +1,521 @@
8031 +/*
8032 + * linux/include/linux/mtd/nand.h
8033 + *
8034 + * Copyright (c) 2000 David Woodhouse <dwmw2@mvhi.com>
8035 + * Steven J. Hill <sjhill@realitydiluted.com>
8036 + * Thomas Gleixner <tglx@linutronix.de>
8037 + *
8038 + * $Id: nand.h,v 1.4 2006/11/03 10:35:52 pkj Exp $
8039 + *
8040 + * This program is free software; you can redistribute it and/or modify
8041 + * it under the terms of the GNU General Public License version 2 as
8042 + * published by the Free Software Foundation.
8043 + *
8044 + * Info:
8045 + * Contains standard defines and IDs for NAND flash devices
8046 + *
8047 + * Changelog:
8048 + * 01-31-2000 DMW Created
8049 + * 09-18-2000 SJH Moved structure out of the Disk-On-Chip drivers
8050 + * so it can be used by other NAND flash device
8051 + * drivers. I also changed the copyright since none
8052 + * of the original contents of this file are specific
8053 + * to DoC devices. David can whack me with a baseball
8054 + * bat later if I did something naughty.
8055 + * 10-11-2000 SJH Added private NAND flash structure for driver
8056 + * 10-24-2000 SJH Added prototype for 'nand_scan' function
8057 + * 10-29-2001 TG changed nand_chip structure to support
8058 + * hardwarespecific function for accessing control lines
8059 + * 02-21-2002 TG added support for different read/write adress and
8060 + * ready/busy line access function
8061 + * 02-26-2002 TG added chip_delay to nand_chip structure to optimize
8062 + * command delay times for different chips
8063 + * 04-28-2002 TG OOB config defines moved from nand.c to avoid duplicate
8064 + * defines in jffs2/wbuf.c
8065 + * 08-07-2002 TG forced bad block location to byte 5 of OOB, even if
8066 + * CONFIG_MTD_NAND_ECC_JFFS2 is not set
8067 + * 08-10-2002 TG extensions to nand_chip structure to support HW-ECC
8068 + *
8069 + * 08-29-2002 tglx nand_chip structure: data_poi for selecting
8070 + * internal / fs-driver buffer
8071 + * support for 6byte/512byte hardware ECC
8072 + * read_ecc, write_ecc extended for different oob-layout
8073 + * oob layout selections: NAND_NONE_OOB, NAND_JFFS2_OOB,
8074 + * NAND_YAFFS_OOB
8075 + * 11-25-2002 tglx Added Manufacturer code FUJITSU, NATIONAL
8076 + * Split manufacturer and device ID structures
8077 + *
8078 + * 02-08-2004 tglx added option field to nand structure for chip anomalities
8079 + * 05-25-2004 tglx added bad block table support, ST-MICRO manufacturer id
8080 + * update of nand_chip structure description
8081 + * 01-17-2005 dmarlin added extended commands for AG-AND device and added option
8082 + * for BBT_AUTO_REFRESH.
8083 + * 01-20-2005 dmarlin added optional pointer to hardware specific callback for
8084 + * extra error status checks.
8085 + */
8086 +#ifndef __LINUX_MTD_NAND_H
8087 +#define __LINUX_MTD_NAND_H
8088 +
8089 +#if 0 /* avoid these as much as possible */
8090 +#include <linux/wait.h>
8091 +#include <linux/spinlock.h>
8092 +#include <linux/mtd/mtd.h>
8093 +#endif
8094 +
8095 +#include "mtd.h" /* local */
8096 +
8097 +#include <linux/kernel.h> /* we do need this though ... */
8098 +
8099 +struct mtd_info;
8100 +/* Scan and identify a NAND device */
8101 +extern int nand_scan (struct mtd_info *mtd, int max_chips);
8102 +/* Free resources held by the NAND device */
8103 +extern void nand_release (struct mtd_info *mtd);
8104 +
8105 +/* Read raw data from the device without ECC */
8106 +extern int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_t len, size_t ooblen);
8107 +
8108 +
8109 +/* The maximum number of NAND chips in an array */
8110 +#define NAND_MAX_CHIPS 8
8111 +
8112 +/* This constant declares the max. oobsize / page, which
8113 + * is supported now. If you add a chip with bigger oobsize/page
8114 + * adjust this accordingly.
8115 + */
8116 +#define NAND_MAX_OOBSIZE 64
8117 +
8118 +/*
8119 + * Constants for hardware specific CLE/ALE/NCE function
8120 +*/
8121 +/* Select the chip by setting nCE to low */
8122 +#define NAND_CTL_SETNCE 1
8123 +/* Deselect the chip by setting nCE to high */
8124 +#define NAND_CTL_CLRNCE 2
8125 +/* Select the command latch by setting CLE to high */
8126 +#define NAND_CTL_SETCLE 3
8127 +/* Deselect the command latch by setting CLE to low */
8128 +#define NAND_CTL_CLRCLE 4
8129 +/* Select the address latch by setting ALE to high */
8130 +#define NAND_CTL_SETALE 5
8131 +/* Deselect the address latch by setting ALE to low */
8132 +#define NAND_CTL_CLRALE 6
8133 +/* Set write protection by setting WP to high. Not used! */
8134 +#define NAND_CTL_SETWP 7
8135 +/* Clear write protection by setting WP to low. Not used! */
8136 +#define NAND_CTL_CLRWP 8
8137 +
8138 +/*
8139 + * Standard NAND flash commands
8140 + */
8141 +#define NAND_CMD_READ0 0
8142 +#define NAND_CMD_READ1 1
8143 +#define NAND_CMD_PAGEPROG 0x10
8144 +#define NAND_CMD_READOOB 0x50
8145 +#define NAND_CMD_ERASE1 0x60
8146 +#define NAND_CMD_STATUS 0x70
8147 +#define NAND_CMD_STATUS_MULTI 0x71
8148 +#define NAND_CMD_SEQIN 0x80
8149 +#define NAND_CMD_READID 0x90
8150 +#define NAND_CMD_ERASE2 0xd0
8151 +#define NAND_CMD_RESET 0xff
8152 +
8153 +/* Extended commands for large page devices */
8154 +#define NAND_CMD_READSTART 0x30
8155 +#define NAND_CMD_CACHEDPROG 0x15
8156 +
8157 +/* Extended commands for AG-AND device */
8158 +/*
8159 + * Note: the command for NAND_CMD_DEPLETE1 is really 0x00 but
8160 + * there is no way to distinguish that from NAND_CMD_READ0
8161 + * until the remaining sequence of commands has been completed
8162 + * so add a high order bit and mask it off in the command.
8163 + */
8164 +#define NAND_CMD_DEPLETE1 0x100
8165 +#define NAND_CMD_DEPLETE2 0x38
8166 +#define NAND_CMD_STATUS_MULTI 0x71
8167 +#define NAND_CMD_STATUS_ERROR 0x72
8168 +/* multi-bank error status (banks 0-3) */
8169 +#define NAND_CMD_STATUS_ERROR0 0x73
8170 +#define NAND_CMD_STATUS_ERROR1 0x74
8171 +#define NAND_CMD_STATUS_ERROR2 0x75
8172 +#define NAND_CMD_STATUS_ERROR3 0x76
8173 +#define NAND_CMD_STATUS_RESET 0x7f
8174 +#define NAND_CMD_STATUS_CLEAR 0xff
8175 +
8176 +/* Status bits */
8177 +#define NAND_STATUS_FAIL 0x01
8178 +#define NAND_STATUS_FAIL_N1 0x02
8179 +#define NAND_STATUS_TRUE_READY 0x20
8180 +#define NAND_STATUS_READY 0x40
8181 +#define NAND_STATUS_WP 0x80
8182 +
8183 +/*
8184 + * Constants for ECC_MODES
8185 + */
8186 +
8187 +/* No ECC. Usage is not recommended ! */
8188 +#define NAND_ECC_NONE 0
8189 +/* Software ECC 3 byte ECC per 256 Byte data */
8190 +#define NAND_ECC_SOFT 1
8191 +/* Hardware ECC 3 byte ECC per 256 Byte data */
8192 +#define NAND_ECC_HW3_256 2
8193 +/* Hardware ECC 3 byte ECC per 512 Byte data */
8194 +#define NAND_ECC_HW3_512 3
8195 +/* Hardware ECC 3 byte ECC per 512 Byte data */
8196 +#define NAND_ECC_HW6_512 4
8197 +/* Hardware ECC 8 byte ECC per 512 Byte data */
8198 +#define NAND_ECC_HW8_512 6
8199 +/* Hardware ECC 12 byte ECC per 2048 Byte data */
8200 +#define NAND_ECC_HW12_2048 7
8201 +
8202 +/*
8203 + * Constants for Hardware ECC
8204 + */
8205 +/* Reset Hardware ECC for read */
8206 +#define NAND_ECC_READ 0
8207 +/* Reset Hardware ECC for write */
8208 +#define NAND_ECC_WRITE 1
8209 +/* Enable Hardware ECC before syndrom is read back from flash */
8210 +#define NAND_ECC_READSYN 2
8211 +
8212 +/* Bit mask for flags passed to do_nand_read_ecc */
8213 +#define NAND_GET_DEVICE 0x80
8214 +
8215 +
8216 +/* Option constants for bizarre disfunctionality and real
8217 +* features
8218 +*/
8219 +/* Chip can not auto increment pages */
8220 +#define NAND_NO_AUTOINCR 0x00000001
8221 +/* Buswitdh is 16 bit */
8222 +#define NAND_BUSWIDTH_16 0x00000002
8223 +/* Device supports partial programming without padding */
8224 +#define NAND_NO_PADDING 0x00000004
8225 +/* Chip has cache program function */
8226 +#define NAND_CACHEPRG 0x00000008
8227 +/* Chip has copy back function */
8228 +#define NAND_COPYBACK 0x00000010
8229 +/* AND Chip which has 4 banks and a confusing page / block
8230 + * assignment. See Renesas datasheet for further information */
8231 +#define NAND_IS_AND 0x00000020
8232 +/* Chip has a array of 4 pages which can be read without
8233 + * additional ready /busy waits */
8234 +#define NAND_4PAGE_ARRAY 0x00000040
8235 +/* Chip requires that BBT is periodically rewritten to prevent
8236 + * bits from adjacent blocks from 'leaking' in altering data.
8237 + * This happens with the Renesas AG-AND chips, possibly others. */
8238 +#define BBT_AUTO_REFRESH 0x00000080
8239 +
8240 +/* Options valid for Samsung large page devices */
8241 +#define NAND_SAMSUNG_LP_OPTIONS \
8242 + (NAND_NO_PADDING | NAND_CACHEPRG | NAND_COPYBACK)
8243 +
8244 +/* Macros to identify the above */
8245 +#define NAND_CANAUTOINCR(chip) (!(chip->options & NAND_NO_AUTOINCR))
8246 +#define NAND_MUST_PAD(chip) (!(chip->options & NAND_NO_PADDING))
8247 +#define NAND_HAS_CACHEPROG(chip) ((chip->options & NAND_CACHEPRG))
8248 +#define NAND_HAS_COPYBACK(chip) ((chip->options & NAND_COPYBACK))
8249 +
8250 +/* Mask to zero out the chip options, which come from the id table */
8251 +#define NAND_CHIPOPTIONS_MSK (0x0000ffff & ~NAND_NO_AUTOINCR)
8252 +
8253 +/* Non chip related options */
8254 +/* Use a flash based bad block table. This option is passed to the
8255 + * default bad block table function. */
8256 +#define NAND_USE_FLASH_BBT 0x00010000
8257 +/* The hw ecc generator provides a syndrome instead a ecc value on read
8258 + * This can only work if we have the ecc bytes directly behind the
8259 + * data bytes. Applies for DOC and AG-AND Renesas HW Reed Solomon generators */
8260 +#define NAND_HWECC_SYNDROME 0x00020000
8261 +/* This option skips the bbt scan during initialization. */
8262 +#define NAND_SKIP_BBTSCAN 0x00040000
8263 +
8264 +/* Options set by nand scan */
8265 +/* Nand scan has allocated oob_buf */
8266 +#define NAND_OOBBUF_ALLOC 0x40000000
8267 +/* Nand scan has allocated data_buf */
8268 +#define NAND_DATABUF_ALLOC 0x80000000
8269 +
8270 +
8271 +/*
8272 + * nand_state_t - chip states
8273 + * Enumeration for NAND flash chip state
8274 + */
8275 +typedef enum {
8276 + FL_READY,
8277 + FL_READING,
8278 + FL_WRITING,
8279 + FL_ERASING,
8280 + FL_SYNCING,
8281 + FL_CACHEDPRG,
8282 + FL_PM_SUSPENDED,
8283 +} nand_state_t;
8284 +
8285 +/* Keep gcc happy */
8286 +struct nand_chip;
8287 +
8288 +/**
8289 + * struct nand_hw_control - Control structure for hardware controller (e.g ECC generator) shared among independend devices
8290 + * @lock: protection lock
8291 + * @active: the mtd device which holds the controller currently
8292 + * @wq: wait queue to sleep on if a NAND operation is in progress
8293 + * used instead of the per chip wait queue when a hw controller is available
8294 + */
8295 +#if NAND_HWECC_SUPPORT
8296 +struct nand_hw_control {
8297 + spinlock_t lock;
8298 + struct nand_chip *active;
8299 + wait_queue_head_t wq;
8300 +};
8301 +#endif
8302 +
8303 +/**
8304 + * struct nand_chip - NAND Private Flash Chip Data
8305 + * @IO_ADDR_R: [BOARDSPECIFIC] address to read the 8 I/O lines of the flash device
8306 + * @IO_ADDR_W: [BOARDSPECIFIC] address to write the 8 I/O lines of the flash device
8307 + * @read_byte: [REPLACEABLE] read one byte from the chip
8308 + * @write_byte: [REPLACEABLE] write one byte to the chip
8309 + * @read_word: [REPLACEABLE] read one word from the chip
8310 + * @write_word: [REPLACEABLE] write one word to the chip
8311 + * @write_buf: [REPLACEABLE] write data from the buffer to the chip
8312 + * @read_buf: [REPLACEABLE] read data from the chip into the buffer
8313 + * @verify_buf: [REPLACEABLE] verify buffer contents against the chip data
8314 + * @select_chip: [REPLACEABLE] select chip nr
8315 + * @block_bad: [REPLACEABLE] check, if the block is bad
8316 + * @block_markbad: [REPLACEABLE] mark the block bad
8317 + * @hwcontrol: [BOARDSPECIFIC] hardwarespecific function for accesing control-lines
8318 + * @dev_ready: [BOARDSPECIFIC] hardwarespecific function for accesing device ready/busy line
8319 + * If set to NULL no access to ready/busy is available and the ready/busy information
8320 + * is read from the chip status register
8321 + * @cmdfunc: [REPLACEABLE] hardwarespecific function for writing commands to the chip
8322 + * @waitfunc: [REPLACEABLE] hardwarespecific function for wait on ready
8323 + * @calculate_ecc: [REPLACEABLE] function for ecc calculation or readback from ecc hardware
8324 + * @correct_data: [REPLACEABLE] function for ecc correction, matching to ecc generator (sw/hw)
8325 + * @enable_hwecc: [BOARDSPECIFIC] function to enable (reset) hardware ecc generator. Must only
8326 + * be provided if a hardware ECC is available
8327 + * @erase_cmd: [INTERN] erase command write function, selectable due to AND support
8328 + * @scan_bbt: [REPLACEABLE] function to scan bad block table
8329 + * @eccmode: [BOARDSPECIFIC] mode of ecc, see defines
8330 + * @eccsize: [INTERN] databytes used per ecc-calculation
8331 + * @eccbytes: [INTERN] number of ecc bytes per ecc-calculation step
8332 + * @eccsteps: [INTERN] number of ecc calculation steps per page
8333 + * @chip_delay: [BOARDSPECIFIC] chip dependent delay for transfering data from array to read regs (tR)
8334 + * @chip_lock: [INTERN] spinlock used to protect access to this structure and the chip
8335 + * @wq: [INTERN] wait queue to sleep on if a NAND operation is in progress
8336 + * @state: [INTERN] the current state of the NAND device
8337 + * @page_shift: [INTERN] number of address bits in a page (column address bits)
8338 + * @phys_erase_shift: [INTERN] number of address bits in a physical eraseblock
8339 + * @bbt_erase_shift: [INTERN] number of address bits in a bbt entry
8340 + * @chip_shift: [INTERN] number of address bits in one chip
8341 + * @data_buf: [INTERN] internal buffer for one page + oob
8342 + * @oob_buf: [INTERN] oob buffer for one eraseblock
8343 + * @oobdirty: [INTERN] indicates that oob_buf must be reinitialized
8344 + * @data_poi: [INTERN] pointer to a data buffer
8345 + * @options: [BOARDSPECIFIC] various chip options. They can partly be set to inform nand_scan about
8346 + * special functionality. See the defines for further explanation
8347 + * @badblockpos: [INTERN] position of the bad block marker in the oob area
8348 + * @numchips: [INTERN] number of physical chips
8349 + * @chipsize: [INTERN] the size of one chip for multichip arrays
8350 + * @pagemask: [INTERN] page number mask = number of (pages / chip) - 1
8351 + * @pagebuf: [INTERN] holds the pagenumber which is currently in data_buf
8352 + * @autooob: [REPLACEABLE] the default (auto)placement scheme
8353 + * @bbt: [INTERN] bad block table pointer
8354 + * @bbt_td: [REPLACEABLE] bad block table descriptor for flash lookup
8355 + * @bbt_md: [REPLACEABLE] bad block table mirror descriptor
8356 + * @badblock_pattern: [REPLACEABLE] bad block scan pattern used for initial bad block scan
8357 + * @controller: [OPTIONAL] a pointer to a hardware controller structure which is shared among multiple independend devices
8358 + * @priv: [OPTIONAL] pointer to private chip date
8359 + * @errstat: [OPTIONAL] hardware specific function to perform additional error status checks
8360 + * (determine if errors are correctable)
8361 + */
8362 +
8363 +struct nand_chip {
8364 + void __iomem *IO_ADDR_R;
8365 + void __iomem *IO_ADDR_W;
8366 +
8367 + u_char (*read_byte)(struct mtd_info *mtd);
8368 + void (*write_byte)(struct mtd_info *mtd, u_char byte);
8369 + u16 (*read_word)(struct mtd_info *mtd);
8370 + void (*write_word)(struct mtd_info *mtd, u16 word);
8371 +
8372 + void (*write_buf)(struct mtd_info *mtd, const u_char *buf, int len);
8373 + void (*read_buf)(struct mtd_info *mtd, u_char *buf, int len);
8374 + int (*verify_buf)(struct mtd_info *mtd, const u_char *buf, int len);
8375 + void (*select_chip)(struct mtd_info *mtd, int chip);
8376 + int (*block_bad)(struct mtd_info *mtd, loff_t ofs, int getchip);
8377 + int (*block_markbad)(struct mtd_info *mtd, loff_t ofs);
8378 + void (*hwcontrol)(struct mtd_info *mtd, int cmd);
8379 + int (*dev_ready)(struct mtd_info *mtd);
8380 + void (*cmdfunc)(struct mtd_info *mtd, unsigned command, int column, int page_addr);
8381 + int (*waitfunc)(struct mtd_info *mtd, struct nand_chip *this, int state);
8382 + int (*calculate_ecc)(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code);
8383 + int (*correct_data)(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc);
8384 + void (*enable_hwecc)(struct mtd_info *mtd, int mode);
8385 + void (*erase_cmd)(struct mtd_info *mtd, int page);
8386 + int (*scan_bbt)(struct mtd_info *mtd);
8387 + int eccmode;
8388 + int eccsize;
8389 + int eccbytes;
8390 + int eccsteps;
8391 + int chip_delay;
8392 +#if 0 /* no spinlocks or wait queues in boot loader */
8393 + spinlock_t chip_lock;
8394 + wait_queue_head_t wq;
8395 +#endif
8396 + nand_state_t state;
8397 + int page_shift;
8398 + int phys_erase_shift;
8399 + int bbt_erase_shift;
8400 + int chip_shift;
8401 + u_char *data_buf;
8402 + u_char *oob_buf;
8403 + int oobdirty;
8404 + u_char *data_poi;
8405 + unsigned int options;
8406 + int badblockpos;
8407 + int numchips;
8408 + unsigned long chipsize;
8409 + int pagemask;
8410 + int pagebuf;
8411 + struct nand_oobinfo *autooob;
8412 + uint8_t *bbt;
8413 + struct nand_bbt_descr *bbt_td;
8414 + struct nand_bbt_descr *bbt_md;
8415 + struct nand_bbt_descr *badblock_pattern;
8416 + struct nand_hw_control *controller;
8417 + void *priv;
8418 + int (*errstat)(struct mtd_info *mtd, struct nand_chip *this, int state, int status, int page);
8419 +};
8420 +
8421 +/*
8422 + * NAND Flash Manufacturer ID Codes
8423 + */
8424 +#define NAND_MFR_TOSHIBA 0x98
8425 +#define NAND_MFR_SAMSUNG 0xec
8426 +#define NAND_MFR_FUJITSU 0x04
8427 +#define NAND_MFR_NATIONAL 0x8f
8428 +#define NAND_MFR_RENESAS 0x07
8429 +#define NAND_MFR_STMICRO 0x20
8430 +#define NAND_MFR_HYNIX 0xad
8431 +
8432 +/**
8433 + * struct nand_flash_dev - NAND Flash Device ID Structure
8434 + *
8435 + * @name: Identify the device type
8436 + * @id: device ID code
8437 + * @pagesize: Pagesize in bytes. Either 256 or 512 or 0
8438 + * If the pagesize is 0, then the real pagesize
8439 + * and the eraseize are determined from the
8440 + * extended id bytes in the chip
8441 + * @erasesize: Size of an erase block in the flash device.
8442 + * @chipsize: Total chipsize in Mega Bytes
8443 + * @options: Bitfield to store chip relevant options
8444 + */
8445 +struct nand_flash_dev {
8446 + char *name;
8447 + int id;
8448 + unsigned long pagesize;
8449 + unsigned long chipsize;
8450 + unsigned long erasesize;
8451 + unsigned long options;
8452 +};
8453 +
8454 +/**
8455 + * struct nand_manufacturers - NAND Flash Manufacturer ID Structure
8456 + * @name: Manufacturer name
8457 + * @id: manufacturer ID code of device.
8458 +*/
8459 +struct nand_manufacturers {
8460 + int id;
8461 + char * name;
8462 +};
8463 +
8464 +extern struct nand_flash_dev nand_flash_ids[];
8465 +extern struct nand_manufacturers nand_manuf_ids[];
8466 +
8467 +/**
8468 + * struct nand_bbt_descr - bad block table descriptor
8469 + * @options: options for this descriptor
8470 + * @pages: the page(s) where we find the bbt, used with option BBT_ABSPAGE
8471 + * when bbt is searched, then we store the found bbts pages here.
8472 + * Its an array and supports up to 8 chips now
8473 + * @offs: offset of the pattern in the oob area of the page
8474 + * @veroffs: offset of the bbt version counter in the oob are of the page
8475 + * @version: version read from the bbt page during scan
8476 + * @len: length of the pattern, if 0 no pattern check is performed
8477 + * @maxblocks: maximum number of blocks to search for a bbt. This number of
8478 + * blocks is reserved at the end of the device where the tables are
8479 + * written.
8480 + * @reserved_block_code: if non-0, this pattern denotes a reserved (rather than
8481 + * bad) block in the stored bbt
8482 + * @pattern: pattern to identify bad block table or factory marked good /
8483 + * bad blocks, can be NULL, if len = 0
8484 + *
8485 + * Descriptor for the bad block table marker and the descriptor for the
8486 + * pattern which identifies good and bad blocks. The assumption is made
8487 + * that the pattern and the version count are always located in the oob area
8488 + * of the first block.
8489 + */
8490 +struct nand_bbt_descr {
8491 + int options;
8492 + int pages[NAND_MAX_CHIPS];
8493 + int offs;
8494 + int veroffs;
8495 + uint8_t version[NAND_MAX_CHIPS];
8496 + int len;
8497 + int maxblocks;
8498 + int reserved_block_code;
8499 + uint8_t *pattern;
8500 +};
8501 +
8502 +/* Options for the bad block table descriptors */
8503 +
8504 +/* The number of bits used per block in the bbt on the device */
8505 +#define NAND_BBT_NRBITS_MSK 0x0000000F
8506 +#define NAND_BBT_1BIT 0x00000001
8507 +#define NAND_BBT_2BIT 0x00000002
8508 +#define NAND_BBT_4BIT 0x00000004
8509 +#define NAND_BBT_8BIT 0x00000008
8510 +/* The bad block table is in the last good block of the device */
8511 +#define NAND_BBT_LASTBLOCK 0x00000010
8512 +/* The bbt is at the given page, else we must scan for the bbt */
8513 +#define NAND_BBT_ABSPAGE 0x00000020
8514 +/* The bbt is at the given page, else we must scan for the bbt */
8515 +#define NAND_BBT_SEARCH 0x00000040
8516 +/* bbt is stored per chip on multichip devices */
8517 +#define NAND_BBT_PERCHIP 0x00000080
8518 +/* bbt has a version counter at offset veroffs */
8519 +#define NAND_BBT_VERSION 0x00000100
8520 +/* Create a bbt if none axists */
8521 +#define NAND_BBT_CREATE 0x00000200
8522 +/* Search good / bad pattern through all pages of a block */
8523 +#define NAND_BBT_SCANALLPAGES 0x00000400
8524 +/* Scan block empty during good / bad block scan */
8525 +#define NAND_BBT_SCANEMPTY 0x00000800
8526 +/* Write bbt if neccecary */
8527 +#define NAND_BBT_WRITE 0x00001000
8528 +/* Read and write back block contents when writing bbt */
8529 +#define NAND_BBT_SAVECONTENT 0x00002000
8530 +/* Search good / bad pattern on the first and the second page */
8531 +#define NAND_BBT_SCAN2NDPAGE 0x00004000
8532 +
8533 +/* The maximum number of blocks to scan for a bbt */
8534 +#define NAND_BBT_SCAN_MAXBLOCKS 4
8535 +
8536 +extern int nand_scan_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd);
8537 +extern int nand_update_bbt (struct mtd_info *mtd, loff_t offs);
8538 +extern int nand_default_bbt (struct mtd_info *mtd);
8539 +extern int nand_isbad_bbt (struct mtd_info *mtd, loff_t offs, int allowbbt);
8540 +extern int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbbt);
8541 +extern int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
8542 + size_t * retlen, u_char * buf, u_char * oob_buf,
8543 + struct nand_oobinfo *oobsel, int flags);
8544 +
8545 +/*
8546 +* Constants for oob configuration
8547 +*/
8548 +#define NAND_SMALL_BADBLOCK_POS 5
8549 +#define NAND_LARGE_BADBLOCK_POS 0
8550 +
8551 +#endif /* __LINUX_MTD_NAND_H */
8552 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/boot/rescue/nand_base.c linux-2.6.19.2.dev/arch/cris/arch-v32/boot/rescue/nand_base.c
8553 --- linux-2.6.19.2.old/arch/cris/arch-v32/boot/rescue/nand_base.c 1970-01-01 01:00:00.000000000 +0100
8554 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/boot/rescue/nand_base.c 2006-11-10 09:55:58.000000000 +0100
8555 @@ -0,0 +1,2910 @@
8556 +/*
8557 + * Snitched from drivers/mtd/nand_base.c
8558 + * Modified to run outside Linux.
8559 + * #if 0'd to remove non-essential functionality
8560 + *
8561 + * Overview:
8562 + * This is the generic MTD driver for NAND flash devices. It should be
8563 + * capable of working with almost all NAND chips currently available.
8564 + * Basic support for AG-AND chips is provided.
8565 + *
8566 + * Additional technical information is available on
8567 + * http://www.linux-mtd.infradead.org/tech/nand.html
8568 + *
8569 + * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
8570 + * 2002 Thomas Gleixner (tglx@linutronix.de)
8571 + *
8572 + * 02-08-2004 tglx: support for strange chips, which cannot auto increment
8573 + * pages on read / read_oob
8574 + *
8575 + * 03-17-2004 tglx: Check ready before auto increment check. Simon Bayes
8576 + * pointed this out, as he marked an auto increment capable chip
8577 + * as NOAUTOINCR in the board driver.
8578 + * Make reads over block boundaries work too
8579 + *
8580 + * 04-14-2004 tglx: first working version for 2k page size chips
8581 + *
8582 + * 05-19-2004 tglx: Basic support for Renesas AG-AND chips
8583 + *
8584 + * 09-24-2004 tglx: add support for hardware controllers (e.g. ECC) shared
8585 + * among multiple independend devices. Suggestions and initial patch
8586 + * from Ben Dooks <ben-mtd@fluff.org>
8587 + *
8588 + * 12-05-2004 dmarlin: add workaround for Renesas AG-AND chips "disturb" issue.
8589 + * Basically, any block not rewritten may lose data when surrounding blocks
8590 + * are rewritten many times. JFFS2 ensures this doesn't happen for blocks
8591 + * it uses, but the Bad Block Table(s) may not be rewritten. To ensure they
8592 + * do not lose data, force them to be rewritten when some of the surrounding
8593 + * blocks are erased. Rather than tracking a specific nearby block (which
8594 + * could itself go bad), use a page address 'mask' to select several blocks
8595 + * in the same area, and rewrite the BBT when any of them are erased.
8596 + *
8597 + * 01-03-2005 dmarlin: added support for the device recovery command sequence for Renesas
8598 + * AG-AND chips. If there was a sudden loss of power during an erase operation,
8599 + * a "device recovery" operation must be performed when power is restored
8600 + * to ensure correct operation.
8601 + *
8602 + * 01-20-2005 dmarlin: added support for optional hardware specific callback routine to
8603 + * perform extra error status checks on erase and write failures. This required
8604 + * adding a wrapper function for nand_read_ecc.
8605 + *
8606 + * 08-20-2005 vwool: suspend/resume added
8607 + *
8608 + * Credits:
8609 + * David Woodhouse for adding multichip support
8610 + *
8611 + * Aleph One Ltd. and Toby Churchill Ltd. for supporting the
8612 + * rework for 2K page size chips
8613 + *
8614 + * TODO:
8615 + * Enable cached programming for 2k page size chips
8616 + * Check, if mtd->ecctype should be set to MTD_ECC_HW
8617 + * if we have HW ecc support.
8618 + * The AG-AND chips have nice features for speed improvement,
8619 + * which are not supported yet. Read / program 4 pages in one go.
8620 + *
8621 + * $Id: nand_base.c,v 1.11 2006/11/10 08:55:58 ricardw Exp $
8622 + *
8623 + * This program is free software; you can redistribute it and/or modify
8624 + * it under the terms of the GNU General Public License version 2 as
8625 + * published by the Free Software Foundation.
8626 + *
8627 + */
8628 +
8629 +#include <linux/types.h>
8630 +#include <linux/delay.h>
8631 +#include <linux/errno.h>
8632 +#if 0
8633 +#include <linux/sched.h>
8634 +#include <linux/slab.h>
8635 +#endif
8636 +
8637 +#include "mtd.h"
8638 +#include "nand.h"
8639 +#include "nand_ecc.h"
8640 +
8641 +#if 0
8642 +#include <linux/mtd/compatmac.h>
8643 +#include <linux/interrupt.h>
8644 +#include <linux/bitops.h>
8645 +#include <asm/io.h>
8646 +#endif
8647 +
8648 +#ifdef CONFIG_MTD_PARTITIONS
8649 +#include <linux/mtd/partitions.h>
8650 +
8651 +#endif
8652 +
8653 +#include "lib.h"
8654 +
8655 +#define GPIO_SYNC 0
8656 +
8657 +#undef DEBUG /* from mtd.h */
8658 +#define DEBUG(n, args...) do { } while(0)
8659 +
8660 +#define D(x)
8661 +
8662 +/* Define default oob placement schemes for large and small page devices */
8663 +static struct nand_oobinfo nand_oob_8 = {
8664 + .useecc = MTD_NANDECC_AUTOPLACE,
8665 + .eccbytes = 3,
8666 + .eccpos = {0, 1, 2},
8667 + .oobfree = { {3, 2}, {6, 2} }
8668 +};
8669 +
8670 +static struct nand_oobinfo nand_oob_16 = {
8671 + .useecc = MTD_NANDECC_AUTOPLACE,
8672 + .eccbytes = 6,
8673 + .eccpos = {0, 1, 2, 3, 6, 7},
8674 + .oobfree = { {8, 8} }
8675 +};
8676 +
8677 +static struct nand_oobinfo nand_oob_64 = {
8678 + .useecc = MTD_NANDECC_AUTOPLACE,
8679 + .eccbytes = 24,
8680 + .eccpos = {
8681 + 40, 41, 42, 43, 44, 45, 46, 47,
8682 + 48, 49, 50, 51, 52, 53, 54, 55,
8683 + 56, 57, 58, 59, 60, 61, 62, 63},
8684 + .oobfree = { {2, 38} }
8685 +};
8686 +
8687 +/* This is used for padding purposes in nand_write_oob */
8688 +#if NAND_WRITE_SUPPORT
8689 +static u_char ffchars[] = {
8690 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
8691 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
8692 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
8693 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
8694 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
8695 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
8696 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
8697 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
8698 +};
8699 +#endif
8700 +
8701 +/*
8702 + * NAND low-level MTD interface functions
8703 + */
8704 +static void nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len);
8705 +static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len);
8706 +static int nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len);
8707 +
8708 +static int nand_read (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf);
8709 +static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
8710 + size_t * retlen, u_char * buf, u_char * eccbuf, struct nand_oobinfo *oobsel);
8711 +static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf);
8712 +static int nand_write (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char * buf);
8713 +static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
8714 + size_t * retlen, const u_char * buf, u_char * eccbuf, struct nand_oobinfo *oobsel);
8715 +static int nand_write_oob (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char *buf);
8716 +#if NAND_KVEC_SUPPORT
8717 +static int nand_writev (struct mtd_info *mtd, const struct kvec *vecs,
8718 + unsigned long count, loff_t to, size_t * retlen);
8719 +static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs,
8720 + unsigned long count, loff_t to, size_t * retlen, u_char *eccbuf, struct nand_oobinfo *oobsel);
8721 +#endif
8722 +static int nand_erase (struct mtd_info *mtd, struct erase_info *instr);
8723 +static void nand_sync (struct mtd_info *mtd);
8724 +
8725 +/* Some internal functions */
8726 +static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page, u_char *oob_buf,
8727 + struct nand_oobinfo *oobsel, int mode);
8728 +#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
8729 +static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int page, int numpages,
8730 + u_char *oob_buf, struct nand_oobinfo *oobsel, int chipnr, int oobmode);
8731 +#else
8732 +#define nand_verify_pages(...) (0)
8733 +#endif
8734 +
8735 +static int nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state);
8736 +
8737 +/**
8738 + * nand_release_device - [GENERIC] release chip
8739 + * @mtd: MTD device structure
8740 + *
8741 + * Deselect, release chip lock and wake up anyone waiting on the device
8742 + */
8743 +static void nand_release_device (struct mtd_info *mtd)
8744 +{
8745 + struct nand_chip *this = mtd->priv;
8746 +
8747 + /* De-select the NAND device */
8748 + this->select_chip(mtd, -1);
8749 +#if 0
8750 +
8751 + if (this->controller) {
8752 + /* Release the controller and the chip */
8753 + spin_lock(&this->controller->lock);
8754 + this->controller->active = NULL;
8755 + this->state = FL_READY;
8756 + wake_up(&this->controller->wq);
8757 + spin_unlock(&this->controller->lock);
8758 + } else {
8759 + /* Release the chip */
8760 + spin_lock(&this->chip_lock);
8761 + this->state = FL_READY;
8762 + wake_up(&this->wq);
8763 + spin_unlock(&this->chip_lock);
8764 + }
8765 +#endif
8766 +}
8767 +
8768 +/**
8769 + * nand_read_byte - [DEFAULT] read one byte from the chip
8770 + * @mtd: MTD device structure
8771 + *
8772 + * Default read function for 8bit buswith
8773 + */
8774 +static u_char nand_read_byte(struct mtd_info *mtd)
8775 +{
8776 + struct nand_chip *this = mtd->priv;
8777 + return readb(this->IO_ADDR_R);
8778 +}
8779 +
8780 +/**
8781 + * nand_write_byte - [DEFAULT] write one byte to the chip
8782 + * @mtd: MTD device structure
8783 + * @byte: pointer to data byte to write
8784 + *
8785 + * Default write function for 8it buswith
8786 + */
8787 +static void nand_write_byte(struct mtd_info *mtd, u_char byte)
8788 +{
8789 + struct nand_chip *this = mtd->priv;
8790 + writeb(byte, this->IO_ADDR_W);
8791 +
8792 +#if GPIO_SYNC
8793 + /* Bus sync: Read from address we just wrote.
8794 + * This generates no signal to the NAND flash, since only chip
8795 + * select lines are pulled out to the chip, and read is not
8796 + * gated with chip select for the write area.
8797 + * Turns out this is (probably) the wrong way to do it; the
8798 + * right way is to set up suitable wait states in the kernel
8799 + * config (CONFIG_ETRAX_MEM_GRP3_CONFIG).
8800 + */
8801 + (void) readb(this->IO_ADDR_W); /* that's right, IO_ADDR_W */
8802 +#endif
8803 +}
8804 +
8805 +/**
8806 + * nand_read_byte16 - [DEFAULT] read one byte endianess aware from the chip
8807 + * @mtd: MTD device structure
8808 + *
8809 + * Default read function for 16bit buswith with
8810 + * endianess conversion
8811 + */
8812 +static u_char nand_read_byte16(struct mtd_info *mtd)
8813 +{
8814 + struct nand_chip *this = mtd->priv;
8815 + return (u_char) cpu_to_le16(readw(this->IO_ADDR_R));
8816 +}
8817 +
8818 +/**
8819 + * nand_write_byte16 - [DEFAULT] write one byte endianess aware to the chip
8820 + * @mtd: MTD device structure
8821 + * @byte: pointer to data byte to write
8822 + *
8823 + * Default write function for 16bit buswith with
8824 + * endianess conversion
8825 + */
8826 +static void nand_write_byte16(struct mtd_info *mtd, u_char byte)
8827 +{
8828 + struct nand_chip *this = mtd->priv;
8829 + writew(le16_to_cpu((u16) byte), this->IO_ADDR_W);
8830 +}
8831 +
8832 +/**
8833 + * nand_read_word - [DEFAULT] read one word from the chip
8834 + * @mtd: MTD device structure
8835 + *
8836 + * Default read function for 16bit buswith without
8837 + * endianess conversion
8838 + */
8839 +static u16 nand_read_word(struct mtd_info *mtd)
8840 +{
8841 + struct nand_chip *this = mtd->priv;
8842 + return readw(this->IO_ADDR_R);
8843 +}
8844 +
8845 +/**
8846 + * nand_write_word - [DEFAULT] write one word to the chip
8847 + * @mtd: MTD device structure
8848 + * @word: data word to write
8849 + *
8850 + * Default write function for 16bit buswith without
8851 + * endianess conversion
8852 + */
8853 +static void nand_write_word(struct mtd_info *mtd, u16 word)
8854 +{
8855 + struct nand_chip *this = mtd->priv;
8856 + writew(word, this->IO_ADDR_W);
8857 +}
8858 +
8859 +/**
8860 + * nand_select_chip - [DEFAULT] control CE line
8861 + * @mtd: MTD device structure
8862 + * @chip: chipnumber to select, -1 for deselect
8863 + *
8864 + * Default select function for 1 chip devices.
8865 + */
8866 +static void nand_select_chip(struct mtd_info *mtd, int chip)
8867 +{
8868 + struct nand_chip *this = mtd->priv;
8869 + switch(chip) {
8870 + case -1:
8871 + this->hwcontrol(mtd, NAND_CTL_CLRNCE);
8872 + break;
8873 + case 0:
8874 + this->hwcontrol(mtd, NAND_CTL_SETNCE);
8875 + break;
8876 +
8877 + default:
8878 + BUG();
8879 + }
8880 +}
8881 +
8882 +/**
8883 + * nand_write_buf - [DEFAULT] write buffer to chip
8884 + * @mtd: MTD device structure
8885 + * @buf: data buffer
8886 + * @len: number of bytes to write
8887 + *
8888 + * Default write function for 8bit buswith
8889 + */
8890 +static void nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
8891 +{
8892 + int i;
8893 + struct nand_chip *this = mtd->priv;
8894 +
8895 + for (i=0; i<len; i++)
8896 + writeb(buf[i], this->IO_ADDR_W);
8897 +}
8898 +
8899 +/**
8900 + * nand_read_buf - [DEFAULT] read chip data into buffer
8901 + * @mtd: MTD device structure
8902 + * @buf: buffer to store date
8903 + * @len: number of bytes to read
8904 + *
8905 + * Default read function for 8bit buswith
8906 + */
8907 +static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
8908 +{
8909 + int i;
8910 + struct nand_chip *this = mtd->priv;
8911 +
8912 + for (i=0; i<len; i++)
8913 + buf[i] = readb(this->IO_ADDR_R);
8914 +}
8915 +
8916 +/**
8917 + * nand_verify_buf - [DEFAULT] Verify chip data against buffer
8918 + * @mtd: MTD device structure
8919 + * @buf: buffer containing the data to compare
8920 + * @len: number of bytes to compare
8921 + *
8922 + * Default verify function for 8bit buswith
8923 + */
8924 +static int nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
8925 +{
8926 + int i;
8927 + struct nand_chip *this = mtd->priv;
8928 +
8929 + for (i=0; i<len; i++)
8930 + if (buf[i] != readb(this->IO_ADDR_R))
8931 + return -EFAULT;
8932 +
8933 + return 0;
8934 +}
8935 +
8936 +/**
8937 + * nand_write_buf16 - [DEFAULT] write buffer to chip
8938 + * @mtd: MTD device structure
8939 + * @buf: data buffer
8940 + * @len: number of bytes to write
8941 + *
8942 + * Default write function for 16bit buswith
8943 + */
8944 +static void nand_write_buf16(struct mtd_info *mtd, const u_char *buf, int len)
8945 +{
8946 + int i;
8947 + struct nand_chip *this = mtd->priv;
8948 + u16 *p = (u16 *) buf;
8949 + len >>= 1;
8950 +
8951 + for (i=0; i<len; i++)
8952 + writew(p[i], this->IO_ADDR_W);
8953 +
8954 +}
8955 +
8956 +/**
8957 + * nand_read_buf16 - [DEFAULT] read chip data into buffer
8958 + * @mtd: MTD device structure
8959 + * @buf: buffer to store date
8960 + * @len: number of bytes to read
8961 + *
8962 + * Default read function for 16bit buswith
8963 + */
8964 +static void nand_read_buf16(struct mtd_info *mtd, u_char *buf, int len)
8965 +{
8966 + int i;
8967 + struct nand_chip *this = mtd->priv;
8968 + u16 *p = (u16 *) buf;
8969 + len >>= 1;
8970 +
8971 + for (i=0; i<len; i++)
8972 + p[i] = readw(this->IO_ADDR_R);
8973 +}
8974 +
8975 +/**
8976 + * nand_verify_buf16 - [DEFAULT] Verify chip data against buffer
8977 + * @mtd: MTD device structure
8978 + * @buf: buffer containing the data to compare
8979 + * @len: number of bytes to compare
8980 + *
8981 + * Default verify function for 16bit buswith
8982 + */
8983 +static int nand_verify_buf16(struct mtd_info *mtd, const u_char *buf, int len)
8984 +{
8985 + int i;
8986 + struct nand_chip *this = mtd->priv;
8987 + u16 *p = (u16 *) buf;
8988 + len >>= 1;
8989 +
8990 + for (i=0; i<len; i++)
8991 + if (p[i] != readw(this->IO_ADDR_R))
8992 + return -EFAULT;
8993 +
8994 + return 0;
8995 +}
8996 +
8997 +/**
8998 + * nand_block_bad - [DEFAULT] Read bad block marker from the chip
8999 + * @mtd: MTD device structure
9000 + * @ofs: offset from device start
9001 + * @getchip: 0, if the chip is already selected
9002 + *
9003 + * Check, if the block is bad.
9004 + */
9005 +static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
9006 +{
9007 + int page, chipnr, res = 0;
9008 + struct nand_chip *this = mtd->priv;
9009 + u16 bad;
9010 +
9011 + if (getchip) {
9012 + page = (int)(ofs >> this->page_shift);
9013 + chipnr = (int)(ofs >> this->chip_shift);
9014 +
9015 + /* Grab the lock and see if the device is available */
9016 + nand_get_device (this, mtd, FL_READING);
9017 +
9018 + /* Select the NAND device */
9019 + this->select_chip(mtd, chipnr);
9020 + } else
9021 + page = (int) ofs;
9022 +
9023 + if (this->options & NAND_BUSWIDTH_16) {
9024 + this->cmdfunc (mtd, NAND_CMD_READOOB, this->badblockpos & 0xFE, page & this->pagemask);
9025 + bad = cpu_to_le16(this->read_word(mtd));
9026 + if (this->badblockpos & 0x1)
9027 + bad >>= 8;
9028 + if ((bad & 0xFF) != 0xff)
9029 + res = 1;
9030 + } else {
9031 + this->cmdfunc (mtd, NAND_CMD_READOOB, this->badblockpos, page & this->pagemask);
9032 + if (this->read_byte(mtd) != 0xff)
9033 + res = 1;
9034 + }
9035 +
9036 + if (getchip) {
9037 + /* Deselect and wake up anyone waiting on the device */
9038 + nand_release_device(mtd);
9039 + }
9040 +
9041 + return res;
9042 +}
9043 +
9044 +/**
9045 + * nand_default_block_markbad - [DEFAULT] mark a block bad
9046 + * @mtd: MTD device structure
9047 + * @ofs: offset from device start
9048 + *
9049 + * This is the default implementation, which can be overridden by
9050 + * a hardware specific driver.
9051 +*/
9052 +#if NAND_WRITE_SUPPORT
9053 +static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
9054 +{
9055 + struct nand_chip *this = mtd->priv;
9056 + u_char buf[2] = {0, 0};
9057 + size_t retlen;
9058 + int block;
9059 +
9060 + /* Get block number */
9061 + block = ((int) ofs) >> this->bbt_erase_shift;
9062 + if (this->bbt)
9063 + this->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1);
9064 +
9065 +#if NAND_BBT_SUPPORT
9066 + /* Do we have a flash based bad block table ? */
9067 + if (this->options & NAND_USE_FLASH_BBT)
9068 + return nand_update_bbt (mtd, ofs);
9069 +#endif
9070 +
9071 + /* We write two bytes, so we dont have to mess with 16 bit access */
9072 + ofs += mtd->oobsize + (this->badblockpos & ~0x01);
9073 + return nand_write_oob (mtd, ofs , 2, &retlen, buf);
9074 +}
9075 +#endif
9076 +
9077 +/**
9078 + * nand_check_wp - [GENERIC] check if the chip is write protected
9079 + * @mtd: MTD device structure
9080 + * Check, if the device is write protected
9081 + *
9082 + * The function expects, that the device is already selected
9083 + */
9084 +#if NAND_WRITE_SUPPORT
9085 +static int nand_check_wp (struct mtd_info *mtd)
9086 +{
9087 + struct nand_chip *this = mtd->priv;
9088 + /* Check the WP bit */
9089 + this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1);
9090 + return (this->read_byte(mtd) & NAND_STATUS_WP) ? 0 : 1;
9091 +}
9092 +#endif
9093 +
9094 +/**
9095 + * nand_block_checkbad - [GENERIC] Check if a block is marked bad
9096 + * @mtd: MTD device structure
9097 + * @ofs: offset from device start
9098 + * @getchip: 0, if the chip is already selected
9099 + * @allowbbt: 1, if its allowed to access the bbt area
9100 + *
9101 + * Check, if the block is bad. Either by reading the bad block table or
9102 + * calling of the scan function.
9103 + */
9104 +static int nand_block_checkbad (struct mtd_info *mtd, loff_t ofs, int getchip, int allowbbt)
9105 +{
9106 + struct nand_chip *this = mtd->priv;
9107 +
9108 + if (!this->bbt)
9109 + return this->block_bad(mtd, ofs, getchip);
9110 +
9111 +#if NAND_BBT_SUPPORT
9112 + /* Return info from the table */
9113 + return nand_isbad_bbt (mtd, ofs, allowbbt);
9114 +#endif
9115 + BUG(); /* should not happen */
9116 +}
9117 +
9118 +/*
9119 + * Wait for the ready pin, after a command
9120 + * The timeout is catched later.
9121 + */
9122 +static void nand_wait_ready(struct mtd_info *mtd)
9123 +{
9124 + struct nand_chip *this = mtd->priv;
9125 +#if 0
9126 + unsigned long timeo = jiffies + 2;
9127 +#endif
9128 +
9129 + /* wait until command is processed or timeout occures */
9130 + do {
9131 + if (this->dev_ready(mtd))
9132 + return;
9133 +#if 0
9134 + touch_softlockup_watchdog();
9135 + } while (time_before(jiffies, timeo));
9136 +#endif
9137 + } while (1);
9138 +}
9139 +
9140 +/**
9141 + * nand_command - [DEFAULT] Send command to NAND device
9142 + * @mtd: MTD device structure
9143 + * @command: the command to be sent
9144 + * @column: the column address for this command, -1 if none
9145 + * @page_addr: the page address for this command, -1 if none
9146 + *
9147 + * Send command to NAND device. This function is used for small page
9148 + * devices (256/512 Bytes per page)
9149 + */
9150 +static void nand_command (struct mtd_info *mtd, unsigned command, int column, int page_addr)
9151 +{
9152 + register struct nand_chip *this = mtd->priv;
9153 +
9154 + /* Begin command latch cycle */
9155 + this->hwcontrol(mtd, NAND_CTL_SETCLE);
9156 + /*
9157 + * Write out the command to the device.
9158 + */
9159 + if (command == NAND_CMD_SEQIN) {
9160 + int readcmd;
9161 +
9162 + if (column >= mtd->oobblock) {
9163 + /* OOB area */
9164 + column -= mtd->oobblock;
9165 + readcmd = NAND_CMD_READOOB;
9166 + } else if (column < 256) {
9167 + /* First 256 bytes --> READ0 */
9168 + readcmd = NAND_CMD_READ0;
9169 + } else {
9170 + column -= 256;
9171 + readcmd = NAND_CMD_READ1;
9172 + }
9173 + this->write_byte(mtd, readcmd);
9174 + }
9175 + this->write_byte(mtd, command);
9176 +
9177 + /* Set ALE and clear CLE to start address cycle */
9178 + this->hwcontrol(mtd, NAND_CTL_CLRCLE);
9179 +
9180 + if (column != -1 || page_addr != -1) {
9181 + this->hwcontrol(mtd, NAND_CTL_SETALE);
9182 +
9183 + /* Serially input address */
9184 + if (column != -1) {
9185 + /* Adjust columns for 16 bit buswidth */
9186 + if (this->options & NAND_BUSWIDTH_16)
9187 + column >>= 1;
9188 + this->write_byte(mtd, column);
9189 + }
9190 + if (page_addr != -1) {
9191 + this->write_byte(mtd, (unsigned char) (page_addr & 0xff));
9192 + this->write_byte(mtd, (unsigned char) ((page_addr >> 8) & 0xff));
9193 + /* One more address cycle for devices > 32MiB */
9194 + if (this->chipsize > (32 << 20))
9195 + this->write_byte(mtd, (unsigned char) ((page_addr >> 16) & 0x0f));
9196 + }
9197 + /* Latch in address */
9198 + this->hwcontrol(mtd, NAND_CTL_CLRALE);
9199 + }
9200 +
9201 + /*
9202 + * program and erase have their own busy handlers
9203 + * status and sequential in needs no delay
9204 + */
9205 + switch (command) {
9206 +
9207 + case NAND_CMD_PAGEPROG:
9208 + case NAND_CMD_ERASE1:
9209 + case NAND_CMD_ERASE2:
9210 + case NAND_CMD_SEQIN:
9211 + case NAND_CMD_STATUS:
9212 + return;
9213 +
9214 + case NAND_CMD_RESET:
9215 + if (this->dev_ready)
9216 + break;
9217 + udelay(this->chip_delay);
9218 + this->hwcontrol(mtd, NAND_CTL_SETCLE);
9219 + this->write_byte(mtd, NAND_CMD_STATUS);
9220 + this->hwcontrol(mtd, NAND_CTL_CLRCLE);
9221 + while ( !(this->read_byte(mtd) & NAND_STATUS_READY));
9222 + return;
9223 +
9224 + /* This applies to read commands */
9225 + default:
9226 + /*
9227 + * If we don't have access to the busy pin, we apply the given
9228 + * command delay
9229 + */
9230 + if (!this->dev_ready) {
9231 + udelay (this->chip_delay);
9232 + return;
9233 + }
9234 + }
9235 + /* Apply this short delay always to ensure that we do wait tWB in
9236 + * any case on any machine. */
9237 + ndelay (100);
9238 +
9239 + nand_wait_ready(mtd);
9240 +}
9241 +
9242 +/**
9243 + * nand_command_lp - [DEFAULT] Send command to NAND large page device
9244 + * @mtd: MTD device structure
9245 + * @command: the command to be sent
9246 + * @column: the column address for this command, -1 if none
9247 + * @page_addr: the page address for this command, -1 if none
9248 + *
9249 + * Send command to NAND device. This is the version for the new large page devices
9250 + * We dont have the seperate regions as we have in the small page devices.
9251 + * We must emulate NAND_CMD_READOOB to keep the code compatible.
9252 + *
9253 + */
9254 +static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column, int page_addr)
9255 +{
9256 + register struct nand_chip *this = mtd->priv;
9257 +
9258 + /* Emulate NAND_CMD_READOOB */
9259 + if (command == NAND_CMD_READOOB) {
9260 + column += mtd->oobblock;
9261 + command = NAND_CMD_READ0;
9262 + }
9263 +
9264 +
9265 + /* Begin command latch cycle */
9266 + this->hwcontrol(mtd, NAND_CTL_SETCLE);
9267 + /* Write out the command to the device. */
9268 + this->write_byte(mtd, (command & 0xff));
9269 + /* End command latch cycle */
9270 + this->hwcontrol(mtd, NAND_CTL_CLRCLE);
9271 +
9272 + if (column != -1 || page_addr != -1) {
9273 + this->hwcontrol(mtd, NAND_CTL_SETALE);
9274 +
9275 + /* Serially input address */
9276 + if (column != -1) {
9277 + /* Adjust columns for 16 bit buswidth */
9278 + if (this->options & NAND_BUSWIDTH_16)
9279 + column >>= 1;
9280 + this->write_byte(mtd, column & 0xff);
9281 + this->write_byte(mtd, column >> 8);
9282 + }
9283 + if (page_addr != -1) {
9284 + this->write_byte(mtd, (unsigned char) (page_addr & 0xff));
9285 + this->write_byte(mtd, (unsigned char) ((page_addr >> 8) & 0xff));
9286 + /* One more address cycle for devices > 128MiB */
9287 + if (this->chipsize > (128 << 20))
9288 + this->write_byte(mtd, (unsigned char) ((page_addr >> 16) & 0xff));
9289 + }
9290 + /* Latch in address */
9291 + this->hwcontrol(mtd, NAND_CTL_CLRALE);
9292 + }
9293 +
9294 + /*
9295 + * program and erase have their own busy handlers
9296 + * status, sequential in, and deplete1 need no delay
9297 + */
9298 + switch (command) {
9299 +
9300 + case NAND_CMD_CACHEDPROG:
9301 + case NAND_CMD_PAGEPROG:
9302 + case NAND_CMD_ERASE1:
9303 + case NAND_CMD_ERASE2:
9304 + case NAND_CMD_SEQIN:
9305 + case NAND_CMD_STATUS:
9306 + case NAND_CMD_DEPLETE1:
9307 + return;
9308 +
9309 + /*
9310 + * read error status commands require only a short delay
9311 + */
9312 + case NAND_CMD_STATUS_ERROR:
9313 + case NAND_CMD_STATUS_ERROR0:
9314 + case NAND_CMD_STATUS_ERROR1:
9315 + case NAND_CMD_STATUS_ERROR2:
9316 + case NAND_CMD_STATUS_ERROR3:
9317 + udelay(this->chip_delay);
9318 + return;
9319 +
9320 + case NAND_CMD_RESET:
9321 + if (this->dev_ready)
9322 + break;
9323 + udelay(this->chip_delay);
9324 + this->hwcontrol(mtd, NAND_CTL_SETCLE);
9325 + this->write_byte(mtd, NAND_CMD_STATUS);
9326 + this->hwcontrol(mtd, NAND_CTL_CLRCLE);
9327 + while ( !(this->read_byte(mtd) & NAND_STATUS_READY));
9328 + return;
9329 +
9330 + case NAND_CMD_READ0:
9331 + /* Begin command latch cycle */
9332 + this->hwcontrol(mtd, NAND_CTL_SETCLE);
9333 + /* Write out the start read command */
9334 + this->write_byte(mtd, NAND_CMD_READSTART);
9335 + /* End command latch cycle */
9336 + this->hwcontrol(mtd, NAND_CTL_CLRCLE);
9337 + /* Fall through into ready check */
9338 +
9339 + /* This applies to read commands */
9340 + default:
9341 + /*
9342 + * If we don't have access to the busy pin, we apply the given
9343 + * command delay
9344 + */
9345 + if (!this->dev_ready) {
9346 + udelay (this->chip_delay);
9347 + return;
9348 + }
9349 + }
9350 +
9351 + /* Apply this short delay always to ensure that we do wait tWB in
9352 + * any case on any machine. */
9353 + ndelay (100);
9354 +
9355 + nand_wait_ready(mtd);
9356 +}
9357 +
9358 +/**
9359 + * nand_get_device - [GENERIC] Get chip for selected access
9360 + * @this: the nand chip descriptor
9361 + * @mtd: MTD device structure
9362 + * @new_state: the state which is requested
9363 + *
9364 + * Get the device and lock it for exclusive access
9365 + */
9366 +static int nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state)
9367 +{
9368 + this->state = new_state;
9369 + return 0;
9370 +#if 0
9371 + struct nand_chip *active;
9372 + spinlock_t *lock;
9373 + wait_queue_head_t *wq;
9374 + DECLARE_WAITQUEUE (wait, current);
9375 +
9376 + lock = (this->controller) ? &this->controller->lock : &this->chip_lock;
9377 + wq = (this->controller) ? &this->controller->wq : &this->wq;
9378 +retry:
9379 + active = this;
9380 + spin_lock(lock);
9381 +
9382 + /* Hardware controller shared among independend devices */
9383 + if (this->controller) {
9384 + if (this->controller->active)
9385 + active = this->controller->active;
9386 + else
9387 + this->controller->active = this;
9388 + }
9389 + if (active == this && this->state == FL_READY) {
9390 + this->state = new_state;
9391 + spin_unlock(lock);
9392 + return 0;
9393 + }
9394 + if (new_state == FL_PM_SUSPENDED) {
9395 + spin_unlock(lock);
9396 + return (this->state == FL_PM_SUSPENDED) ? 0 : -EAGAIN;
9397 + }
9398 + set_current_state(TASK_UNINTERRUPTIBLE);
9399 + add_wait_queue(wq, &wait);
9400 + spin_unlock(lock);
9401 + schedule();
9402 + remove_wait_queue(wq, &wait);
9403 + goto retry;
9404 +#endif
9405 +}
9406 +
9407 +/**
9408 + * nand_wait - [DEFAULT] wait until the command is done
9409 + * @mtd: MTD device structure
9410 + * @this: NAND chip structure
9411 + * @state: state to select the max. timeout value
9412 + *
9413 + * Wait for command done. This applies to erase and program only
9414 + * Erase can take up to 400ms and program up to 20ms according to
9415 + * general NAND and SmartMedia specs
9416 + *
9417 +*/
9418 +static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state)
9419 +{
9420 +
9421 +#if 0
9422 + unsigned long timeo = jiffies;
9423 +#endif
9424 + int status;
9425 +
9426 +#if 0
9427 + if (state == FL_ERASING)
9428 + timeo += (HZ * 400) / 1000;
9429 + else
9430 + timeo += (HZ * 20) / 1000;
9431 +#endif
9432 +
9433 + /* Apply this short delay always to ensure that we do wait tWB in
9434 + * any case on any machine. */
9435 + ndelay (100);
9436 +
9437 + if ((state == FL_ERASING) && (this->options & NAND_IS_AND))
9438 + this->cmdfunc (mtd, NAND_CMD_STATUS_MULTI, -1, -1);
9439 + else
9440 + this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1);
9441 +
9442 +#if 0
9443 + while (time_before(jiffies, timeo)) {
9444 + /* Check, if we were interrupted */
9445 + if (this->state != state)
9446 + return 0;
9447 +#endif
9448 + while (1) { /* wait indefinitely */
9449 +
9450 + if (this->dev_ready) {
9451 + if (this->dev_ready(mtd))
9452 + break;
9453 + } else {
9454 + if (this->read_byte(mtd) & NAND_STATUS_READY)
9455 + break;
9456 + }
9457 +
9458 +#if 0
9459 + cond_resched();
9460 +#endif
9461 + }
9462 + status = (int) this->read_byte(mtd);
9463 + return status;
9464 +}
9465 +
9466 +/**
9467 + * nand_write_page - [GENERIC] write one page
9468 + * @mtd: MTD device structure
9469 + * @this: NAND chip structure
9470 + * @page: startpage inside the chip, must be called with (page & this->pagemask)
9471 + * @oob_buf: out of band data buffer
9472 + * @oobsel: out of band selecttion structre
9473 + * @cached: 1 = enable cached programming if supported by chip
9474 + *
9475 + * Nand_page_program function is used for write and writev !
9476 + * This function will always program a full page of data
9477 + * If you call it with a non page aligned buffer, you're lost :)
9478 + *
9479 + * Cached programming is not supported yet.
9480 + */
9481 +#if NAND_WRITE_SUPPORT
9482 +static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page,
9483 + u_char *oob_buf, struct nand_oobinfo *oobsel, int cached)
9484 +{
9485 + int i, status;
9486 + u_char ecc_code[32];
9487 + int eccmode = oobsel->useecc ? this->eccmode : NAND_ECC_NONE;
9488 + int *oob_config = oobsel->eccpos;
9489 + int datidx = 0, eccidx = 0, eccsteps = this->eccsteps;
9490 + int eccbytes = 0;
9491 +
9492 + /* FIXME: Enable cached programming */
9493 + cached = 0;
9494 +
9495 + /* Send command to begin auto page programming */
9496 + this->cmdfunc (mtd, NAND_CMD_SEQIN, 0x00, page);
9497 +
9498 + /* Write out complete page of data, take care of eccmode */
9499 + switch (eccmode) {
9500 + /* No ecc, write all */
9501 + case NAND_ECC_NONE:
9502 + puts ("Writing data without ECC to NAND-FLASH is not recommended\r\n");
9503 + this->write_buf(mtd, this->data_poi, mtd->oobblock);
9504 + break;
9505 +
9506 + /* Software ecc 3/256, write all */
9507 + case NAND_ECC_SOFT:
9508 + for (; eccsteps; eccsteps--) {
9509 + this->calculate_ecc(mtd, &this->data_poi[datidx], ecc_code);
9510 + for (i = 0; i < 3; i++, eccidx++)
9511 + oob_buf[oob_config[eccidx]] = ecc_code[i];
9512 + datidx += this->eccsize;
9513 + }
9514 + this->write_buf(mtd, this->data_poi, mtd->oobblock);
9515 + break;
9516 + default:
9517 + eccbytes = this->eccbytes;
9518 + for (; eccsteps; eccsteps--) {
9519 + /* enable hardware ecc logic for write */
9520 + this->enable_hwecc(mtd, NAND_ECC_WRITE);
9521 + this->write_buf(mtd, &this->data_poi[datidx], this->eccsize);
9522 + this->calculate_ecc(mtd, &this->data_poi[datidx], ecc_code);
9523 + for (i = 0; i < eccbytes; i++, eccidx++)
9524 + oob_buf[oob_config[eccidx]] = ecc_code[i];
9525 + /* If the hardware ecc provides syndromes then
9526 + * the ecc code must be written immidiately after
9527 + * the data bytes (words) */
9528 + if (this->options & NAND_HWECC_SYNDROME)
9529 + this->write_buf(mtd, ecc_code, eccbytes);
9530 + datidx += this->eccsize;
9531 + }
9532 + break;
9533 + }
9534 +
9535 + /* Write out OOB data */
9536 + if (this->options & NAND_HWECC_SYNDROME)
9537 + this->write_buf(mtd, &oob_buf[oobsel->eccbytes], mtd->oobsize - oobsel->eccbytes);
9538 + else
9539 + this->write_buf(mtd, oob_buf, mtd->oobsize);
9540 +
9541 + /* Send command to actually program the data */
9542 + this->cmdfunc (mtd, cached ? NAND_CMD_CACHEDPROG : NAND_CMD_PAGEPROG, -1, -1);
9543 +
9544 + if (!cached) {
9545 + /* call wait ready function */
9546 + status = this->waitfunc (mtd, this, FL_WRITING);
9547 +
9548 + /* See if operation failed and additional status checks are available */
9549 + if ((status & NAND_STATUS_FAIL) && (this->errstat)) {
9550 + status = this->errstat(mtd, this, FL_WRITING, status, page);
9551 + }
9552 +
9553 + /* See if device thinks it succeeded */
9554 + if (status & NAND_STATUS_FAIL) {
9555 + DEBUG (MTD_DEBUG_LEVEL0, "%s: " "Failed write, page 0x%08x, ", __FUNCTION__, page);
9556 + return -EIO;
9557 + }
9558 + } else {
9559 + /* FIXME: Implement cached programming ! */
9560 + /* wait until cache is ready*/
9561 + // status = this->waitfunc (mtd, this, FL_CACHEDRPG);
9562 + }
9563 + return 0;
9564 +}
9565 +#endif
9566 +
9567 +#if NAND_WRITE_SUPPORT
9568 +#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
9569 +/**
9570 + * nand_verify_pages - [GENERIC] verify the chip contents after a write
9571 + * @mtd: MTD device structure
9572 + * @this: NAND chip structure
9573 + * @page: startpage inside the chip, must be called with (page & this->pagemask)
9574 + * @numpages: number of pages to verify
9575 + * @oob_buf: out of band data buffer
9576 + * @oobsel: out of band selecttion structre
9577 + * @chipnr: number of the current chip
9578 + * @oobmode: 1 = full buffer verify, 0 = ecc only
9579 + *
9580 + * The NAND device assumes that it is always writing to a cleanly erased page.
9581 + * Hence, it performs its internal write verification only on bits that
9582 + * transitioned from 1 to 0. The device does NOT verify the whole page on a
9583 + * byte by byte basis. It is possible that the page was not completely erased
9584 + * or the page is becoming unusable due to wear. The read with ECC would catch
9585 + * the error later when the ECC page check fails, but we would rather catch
9586 + * it early in the page write stage. Better to write no data than invalid data.
9587 + */
9588 +static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int page, int numpages,
9589 + u_char *oob_buf, struct nand_oobinfo *oobsel, int chipnr, int oobmode)
9590 +{
9591 + int i, j, datidx = 0, oobofs = 0, res = -EIO;
9592 + int eccsteps = this->eccsteps;
9593 + int hweccbytes;
9594 + u_char oobdata[64];
9595 +
9596 + hweccbytes = (this->options & NAND_HWECC_SYNDROME) ? (oobsel->eccbytes / eccsteps) : 0;
9597 +
9598 + /* Send command to read back the first page */
9599 + this->cmdfunc (mtd, NAND_CMD_READ0, 0, page);
9600 +
9601 + for(;;) {
9602 + for (j = 0; j < eccsteps; j++) {
9603 + /* Loop through and verify the data */
9604 + if (this->verify_buf(mtd, &this->data_poi[datidx], mtd->eccsize)) {
9605 + DEBUG (MTD_DEBUG_LEVEL0, "%s: " "Failed write verify, page 0x%08x ", __FUNCTION__, page);
9606 + goto out;
9607 + }
9608 + datidx += mtd->eccsize;
9609 + /* Have we a hw generator layout ? */
9610 + if (!hweccbytes)
9611 + continue;
9612 + if (this->verify_buf(mtd, &this->oob_buf[oobofs], hweccbytes)) {
9613 + DEBUG (MTD_DEBUG_LEVEL0, "%s: " "Failed write verify, page 0x%08x ", __FUNCTION__, page);
9614 + goto out;
9615 + }
9616 + oobofs += hweccbytes;
9617 + }
9618 +
9619 + /* check, if we must compare all data or if we just have to
9620 + * compare the ecc bytes
9621 + */
9622 + if (oobmode) {
9623 + if (this->verify_buf(mtd, &oob_buf[oobofs], mtd->oobsize - hweccbytes * eccsteps)) {
9624 + DEBUG (MTD_DEBUG_LEVEL0, "%s: " "Failed write verify, page 0x%08x ", __FUNCTION__, page);
9625 + goto out;
9626 + }
9627 + } else {
9628 + /* Read always, else autoincrement fails */
9629 + this->read_buf(mtd, oobdata, mtd->oobsize - hweccbytes * eccsteps);
9630 +
9631 + if (oobsel->useecc != MTD_NANDECC_OFF && !hweccbytes) {
9632 + int ecccnt = oobsel->eccbytes;
9633 +
9634 + for (i = 0; i < ecccnt; i++) {
9635 + int idx = oobsel->eccpos[i];
9636 + if (oobdata[idx] != oob_buf[oobofs + idx] ) {
9637 + DEBUG (MTD_DEBUG_LEVEL0,
9638 + "%s: Failed ECC write "
9639 + "verify, page 0x%08x, " "%6i bytes were succesful\n", __FUNCTION__, page, i);
9640 + goto out;
9641 + }
9642 + }
9643 + }
9644 + }
9645 + oobofs += mtd->oobsize - hweccbytes * eccsteps;
9646 + page++;
9647 + numpages--;
9648 +
9649 + /* Apply delay or wait for ready/busy pin
9650 + * Do this before the AUTOINCR check, so no problems
9651 + * arise if a chip which does auto increment
9652 + * is marked as NOAUTOINCR by the board driver.
9653 + * Do this also before returning, so the chip is
9654 + * ready for the next command.
9655 + */
9656 + if (!this->dev_ready)
9657 + udelay (this->chip_delay);
9658 + else
9659 + nand_wait_ready(mtd);
9660 +
9661 + /* All done, return happy */
9662 + if (!numpages)
9663 + return 0;
9664 +
9665 +
9666 + /* Check, if the chip supports auto page increment */
9667 + if (!NAND_CANAUTOINCR(this))
9668 + this->cmdfunc (mtd, NAND_CMD_READ0, 0x00, page);
9669 + }
9670 + /*
9671 + * Terminate the read command. We come here in case of an error
9672 + * So we must issue a reset command.
9673 + */
9674 +out:
9675 + this->cmdfunc (mtd, NAND_CMD_RESET, -1, -1);
9676 + return res;
9677 +}
9678 +#endif
9679 +#endif
9680 +
9681 +/**
9682 + * nand_read - [MTD Interface] MTD compability function for nand_do_read_ecc
9683 + * @mtd: MTD device structure
9684 + * @from: offset to read from
9685 + * @len: number of bytes to read
9686 + * @retlen: pointer to variable to store the number of read bytes
9687 + * @buf: the databuffer to put data
9688 + *
9689 + * This function simply calls nand_do_read_ecc with oob buffer and oobsel = NULL
9690 + * and flags = 0xff
9691 + */
9692 +static int nand_read (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf)
9693 +{
9694 + return nand_do_read_ecc (mtd, from, len, retlen, buf, NULL, &mtd->oobinfo, 0xff);
9695 +}
9696 +
9697 +
9698 +/**
9699 + * nand_read_ecc - [MTD Interface] MTD compability function for nand_do_read_ecc
9700 + * @mtd: MTD device structure
9701 + * @from: offset to read from
9702 + * @len: number of bytes to read
9703 + * @retlen: pointer to variable to store the number of read bytes
9704 + * @buf: the databuffer to put data
9705 + * @oob_buf: filesystem supplied oob data buffer
9706 + * @oobsel: oob selection structure
9707 + *
9708 + * This function simply calls nand_do_read_ecc with flags = 0xff
9709 + */
9710 +static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
9711 + size_t * retlen, u_char * buf, u_char * oob_buf, struct nand_oobinfo *oobsel)
9712 +{
9713 + /* use userspace supplied oobinfo, if zero */
9714 + if (oobsel == NULL)
9715 + oobsel = &mtd->oobinfo;
9716 + return nand_do_read_ecc(mtd, from, len, retlen, buf, oob_buf, oobsel, 0xff);
9717 +}
9718 +
9719 +
9720 +/**
9721 + * nand_do_read_ecc - [MTD Interface] Read data with ECC
9722 + * @mtd: MTD device structure
9723 + * @from: offset to read from
9724 + * @len: number of bytes to read
9725 + * @retlen: pointer to variable to store the number of read bytes
9726 + * @buf: the databuffer to put data
9727 + * @oob_buf: filesystem supplied oob data buffer (can be NULL)
9728 + * @oobsel: oob selection structure
9729 + * @flags: flag to indicate if nand_get_device/nand_release_device should be preformed
9730 + * and how many corrected error bits are acceptable:
9731 + * bits 0..7 - number of tolerable errors
9732 + * bit 8 - 0 == do not get/release chip, 1 == get/release chip
9733 + *
9734 + * NAND read with ECC
9735 + */
9736 +int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
9737 + size_t * retlen, u_char * buf, u_char * oob_buf,
9738 + struct nand_oobinfo *oobsel, int flags)
9739 +{
9740 +
9741 + int i, j, col, realpage, page, end, ecc, chipnr, sndcmd = 1;
9742 + int read = 0, oob = 0, ecc_status = 0, ecc_failed = 0;
9743 + struct nand_chip *this = mtd->priv;
9744 + u_char *data_poi, *oob_data = oob_buf;
9745 + u_char ecc_calc[32];
9746 + u_char ecc_code[32];
9747 + int eccmode, eccsteps;
9748 + int *oob_config, datidx;
9749 + int blockcheck = (1 << (this->phys_erase_shift - this->page_shift)) - 1;
9750 + int eccbytes;
9751 + int compareecc = 1;
9752 + int oobreadlen;
9753 +
9754 +
9755 + DEBUG (MTD_DEBUG_LEVEL3, "nand_read_ecc: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
9756 + D(
9757 + puts ("nand_read_ecc: from = ");
9758 + putx (from);
9759 + puts (", len = ");
9760 + putx(len);
9761 + putnl();
9762 + )
9763 +
9764 + /* Do not allow reads past end of device */
9765 + if ((from + len) > mtd->size) {
9766 + DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: Attempt read beyond end of device\n");
9767 + D(puts("nand_read_ecc: Attempt read beyond end of device\r\n"));
9768 + *retlen = 0;
9769 + return -EINVAL;
9770 + }
9771 +
9772 + /* Grab the lock and see if the device is available */
9773 + if (flags & NAND_GET_DEVICE)
9774 + nand_get_device (this, mtd, FL_READING);
9775 +
9776 + /* Autoplace of oob data ? Use the default placement scheme */
9777 + if (oobsel->useecc == MTD_NANDECC_AUTOPLACE)
9778 + oobsel = this->autooob;
9779 +
9780 + eccmode = oobsel->useecc ? this->eccmode : NAND_ECC_NONE;
9781 + oob_config = oobsel->eccpos;
9782 +
9783 + /* Select the NAND device */
9784 + chipnr = (int)(from >> this->chip_shift);
9785 + this->select_chip(mtd, chipnr);
9786 +
9787 + /* First we calculate the starting page */
9788 + realpage = (int) (from >> this->page_shift);
9789 + page = realpage & this->pagemask;
9790 +
9791 + /* Get raw starting column */
9792 + col = from & (mtd->oobblock - 1);
9793 +
9794 + end = mtd->oobblock;
9795 + ecc = this->eccsize;
9796 + eccbytes = this->eccbytes;
9797 +
9798 + if ((eccmode == NAND_ECC_NONE) || (this->options & NAND_HWECC_SYNDROME))
9799 + compareecc = 0;
9800 +
9801 + oobreadlen = mtd->oobsize;
9802 + if (this->options & NAND_HWECC_SYNDROME)
9803 + oobreadlen -= oobsel->eccbytes;
9804 +
9805 + /* Loop until all data read */
9806 + while (read < len) {
9807 +
9808 + int aligned = (!col && (len - read) >= end);
9809 + /*
9810 + * If the read is not page aligned, we have to read into data buffer
9811 + * due to ecc, else we read into return buffer direct
9812 + */
9813 + if (aligned)
9814 + data_poi = &buf[read];
9815 + else
9816 + data_poi = this->data_buf;
9817 +
9818 + /* Check, if we have this page in the buffer
9819 + *
9820 + * FIXME: Make it work when we must provide oob data too,
9821 + * check the usage of data_buf oob field
9822 + */
9823 + if (realpage == this->pagebuf && !oob_buf) {
9824 + /* aligned read ? */
9825 + if (aligned)
9826 + memcpy (data_poi, this->data_buf, end);
9827 + goto readdata;
9828 + }
9829 +
9830 + /* Check, if we must send the read command */
9831 + if (sndcmd) {
9832 + this->cmdfunc (mtd, NAND_CMD_READ0, 0x00, page);
9833 + sndcmd = 0;
9834 + }
9835 +
9836 + /* get oob area, if we have no oob buffer from fs-driver */
9837 + if (!oob_buf || oobsel->useecc == MTD_NANDECC_AUTOPLACE ||
9838 + oobsel->useecc == MTD_NANDECC_AUTOPL_USR)
9839 + oob_data = &this->data_buf[end];
9840 +
9841 + eccsteps = this->eccsteps;
9842 +
9843 + switch (eccmode) {
9844 + case NAND_ECC_NONE: { /* No ECC, Read in a page */
9845 +#if 0
9846 + static unsigned long lastwhinge = 0;
9847 + if ((lastwhinge / HZ) != (jiffies / HZ)) {
9848 + puts ("Reading data from NAND FLASH without ECC is not recommended\r\n");
9849 + lastwhinge = jiffies;
9850 + }
9851 +#endif
9852 + this->read_buf(mtd, data_poi, end);
9853 + break;
9854 + }
9855 +
9856 + case NAND_ECC_SOFT: /* Software ECC 3/256: Read in a page + oob data */
9857 + this->read_buf(mtd, data_poi, end);
9858 + for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=3, datidx += ecc)
9859 + this->calculate_ecc(mtd, &data_poi[datidx], &ecc_calc[i]);
9860 + break;
9861 +
9862 + default:
9863 +#if NAND_HWECC_SUPPORT
9864 + for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=eccbytes, datidx += ecc) {
9865 + this->enable_hwecc(mtd, NAND_ECC_READ);
9866 + this->read_buf(mtd, &data_poi[datidx], ecc);
9867 +
9868 + /* HW ecc with syndrome calculation must read the
9869 + * syndrome from flash immidiately after the data */
9870 + if (!compareecc) {
9871 + /* Some hw ecc generators need to know when the
9872 + * syndrome is read from flash */
9873 + this->enable_hwecc(mtd, NAND_ECC_READSYN);
9874 + this->read_buf(mtd, &oob_data[i], eccbytes);
9875 + /* We calc error correction directly, it checks the hw
9876 + * generator for an error, reads back the syndrome and
9877 + * does the error correction on the fly */
9878 + ecc_status = this->correct_data(mtd, &data_poi[datidx], &oob_data[i], &ecc_code[i]);
9879 + if ((ecc_status == -1) || (ecc_status > (flags && 0xff))) {
9880 + DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: "
9881 + "Failed ECC read, page 0x%08x on chip %d\n", page, chipnr);
9882 + ecc_failed++;
9883 + }
9884 + } else {
9885 + this->calculate_ecc(mtd, &data_poi[datidx], &ecc_calc[i]);
9886 + }
9887 + }
9888 +#endif
9889 + break;
9890 + }
9891 +
9892 + /* read oobdata */
9893 + this->read_buf(mtd, &oob_data[mtd->oobsize - oobreadlen], oobreadlen);
9894 +
9895 + /* Skip ECC check, if not requested (ECC_NONE or HW_ECC with syndromes) */
9896 + if (!compareecc)
9897 + goto readoob;
9898 +
9899 + /* Pick the ECC bytes out of the oob data */
9900 + for (j = 0; j < oobsel->eccbytes; j++)
9901 + ecc_code[j] = oob_data[oob_config[j]];
9902 +
9903 + /* correct data, if neccecary */
9904 + for (i = 0, j = 0, datidx = 0; i < this->eccsteps; i++, datidx += ecc) {
9905 + ecc_status = this->correct_data(mtd, &data_poi[datidx], &ecc_code[j], &ecc_calc[j]);
9906 +
9907 + /* Get next chunk of ecc bytes */
9908 + j += eccbytes;
9909 +
9910 + /* Check, if we have a fs supplied oob-buffer,
9911 + * This is the legacy mode. Used by YAFFS1
9912 + * Should go away some day
9913 + */
9914 + if (oob_buf && oobsel->useecc == MTD_NANDECC_PLACE) {
9915 + int *p = (int *)(&oob_data[mtd->oobsize]);
9916 + p[i] = ecc_status;
9917 + }
9918 +
9919 + if ((ecc_status == -1) || (ecc_status > (flags && 0xff))) {
9920 + DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: " "Failed ECC read, page 0x%08x\n", page);
9921 + D(
9922 + puts ("nand_read_ecc: " "Failed ECC read, page ");
9923 + putx (page);
9924 + putnl();
9925 + )
9926 + ecc_failed++;
9927 + }
9928 + }
9929 +
9930 + readoob:
9931 + /* check, if we have a fs supplied oob-buffer */
9932 + if (oob_buf) {
9933 + /* without autoplace. Legacy mode used by YAFFS1 */
9934 + switch(oobsel->useecc) {
9935 + case MTD_NANDECC_AUTOPLACE:
9936 + case MTD_NANDECC_AUTOPL_USR:
9937 + /* Walk through the autoplace chunks */
9938 + for (i = 0; oobsel->oobfree[i][1]; i++) {
9939 + int from = oobsel->oobfree[i][0];
9940 + int num = oobsel->oobfree[i][1];
9941 + memcpy(&oob_buf[oob], &oob_data[from], num);
9942 + oob += num;
9943 + }
9944 + break;
9945 + case MTD_NANDECC_PLACE:
9946 + /* YAFFS1 legacy mode */
9947 + oob_data += this->eccsteps * sizeof (int);
9948 + default:
9949 + oob_data += mtd->oobsize;
9950 + }
9951 + }
9952 + readdata:
9953 + /* Partial page read, transfer data into fs buffer */
9954 + if (!aligned) {
9955 + for (j = col; j < end && read < len; j++)
9956 + buf[read++] = data_poi[j];
9957 + this->pagebuf = realpage;
9958 + } else
9959 + read += mtd->oobblock;
9960 +
9961 + /* Apply delay or wait for ready/busy pin
9962 + * Do this before the AUTOINCR check, so no problems
9963 + * arise if a chip which does auto increment
9964 + * is marked as NOAUTOINCR by the board driver.
9965 + */
9966 + if (!this->dev_ready)
9967 + udelay (this->chip_delay);
9968 + else
9969 + nand_wait_ready(mtd);
9970 +
9971 + if (read == len)
9972 + break;
9973 +
9974 + /* For subsequent reads align to page boundary. */
9975 + col = 0;
9976 + /* Increment page address */
9977 + realpage++;
9978 +
9979 + page = realpage & this->pagemask;
9980 + /* Check, if we cross a chip boundary */
9981 + if (!page) {
9982 + chipnr++;
9983 + this->select_chip(mtd, -1);
9984 + this->select_chip(mtd, chipnr);
9985 + }
9986 + /* Check, if the chip supports auto page increment
9987 + * or if we have hit a block boundary.
9988 + */
9989 + if (!NAND_CANAUTOINCR(this) || !(page & blockcheck))
9990 + sndcmd = 1;
9991 + }
9992 +
9993 + /* Deselect and wake up anyone waiting on the device */
9994 + if (flags & NAND_GET_DEVICE)
9995 + nand_release_device(mtd);
9996 +
9997 + /*
9998 + * Return success, if no ECC failures, else -EBADMSG
9999 + * fs driver will take care of that, because
10000 + * retlen == desired len and result == -EBADMSG
10001 + */
10002 + *retlen = read;
10003 + return ecc_failed ? -EBADMSG : 0;
10004 +}
10005 +
10006 +/**
10007 + * nand_read_oob - [MTD Interface] NAND read out-of-band
10008 + * @mtd: MTD device structure
10009 + * @from: offset to read from
10010 + * @len: number of bytes to read
10011 + * @retlen: pointer to variable to store the number of read bytes
10012 + * @buf: the databuffer to put data
10013 + *
10014 + * NAND read out-of-band data from the spare area
10015 + */
10016 +static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf)
10017 +{
10018 + int i, col, page, chipnr;
10019 + struct nand_chip *this = mtd->priv;
10020 + int blockcheck = (1 << (this->phys_erase_shift - this->page_shift)) - 1;
10021 +
10022 + DEBUG (MTD_DEBUG_LEVEL3, "nand_read_oob: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
10023 +
10024 + /* Shift to get page */
10025 + page = (int)(from >> this->page_shift);
10026 + chipnr = (int)(from >> this->chip_shift);
10027 +
10028 + /* Mask to get column */
10029 + col = from & (mtd->oobsize - 1);
10030 +
10031 + /* Initialize return length value */
10032 + *retlen = 0;
10033 +
10034 + /* Do not allow reads past end of device */
10035 + if ((from + len) > mtd->size) {
10036 + DEBUG (MTD_DEBUG_LEVEL0, "nand_read_oob: Attempt read beyond end of device\n");
10037 + *retlen = 0;
10038 + return -EINVAL;
10039 + }
10040 +
10041 + /* Grab the lock and see if the device is available */
10042 + nand_get_device (this, mtd , FL_READING);
10043 +
10044 + /* Select the NAND device */
10045 + this->select_chip(mtd, chipnr);
10046 +
10047 + /* Send the read command */
10048 + this->cmdfunc (mtd, NAND_CMD_READOOB, col, page & this->pagemask);
10049 + /*
10050 + * Read the data, if we read more than one page
10051 + * oob data, let the device transfer the data !
10052 + */
10053 + i = 0;
10054 + while (i < len) {
10055 + int thislen = mtd->oobsize - col;
10056 + thislen = min_t(int, thislen, len);
10057 + this->read_buf(mtd, &buf[i], thislen);
10058 + i += thislen;
10059 +
10060 + /* Read more ? */
10061 + if (i < len) {
10062 + page++;
10063 + col = 0;
10064 +
10065 + /* Check, if we cross a chip boundary */
10066 + if (!(page & this->pagemask)) {
10067 + chipnr++;
10068 + this->select_chip(mtd, -1);
10069 + this->select_chip(mtd, chipnr);
10070 + }
10071 +
10072 + /* Apply delay or wait for ready/busy pin
10073 + * Do this before the AUTOINCR check, so no problems
10074 + * arise if a chip which does auto increment
10075 + * is marked as NOAUTOINCR by the board driver.
10076 + */
10077 + if (!this->dev_ready)
10078 + udelay (this->chip_delay);
10079 + else
10080 + nand_wait_ready(mtd);
10081 +
10082 + /* Check, if the chip supports auto page increment
10083 + * or if we have hit a block boundary.
10084 + */
10085 + if (!NAND_CANAUTOINCR(this) || !(page & blockcheck)) {
10086 + /* For subsequent page reads set offset to 0 */
10087 + this->cmdfunc (mtd, NAND_CMD_READOOB, 0x0, page & this->pagemask);
10088 + }
10089 + }
10090 + }
10091 +
10092 + /* Deselect and wake up anyone waiting on the device */
10093 + nand_release_device(mtd);
10094 +
10095 + /* Return happy */
10096 + *retlen = len;
10097 + return 0;
10098 +}
10099 +
10100 +/**
10101 + * nand_read_raw - [GENERIC] Read raw data including oob into buffer
10102 + * @mtd: MTD device structure
10103 + * @buf: temporary buffer
10104 + * @from: offset to read from
10105 + * @len: number of bytes to read
10106 + * @ooblen: number of oob data bytes to read
10107 + *
10108 + * Read raw data including oob into buffer
10109 + */
10110 +int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_t len, size_t ooblen)
10111 +{
10112 + struct nand_chip *this = mtd->priv;
10113 + int page = (int) (from >> this->page_shift);
10114 + int chip = (int) (from >> this->chip_shift);
10115 + int sndcmd = 1;
10116 + int cnt = 0;
10117 + int pagesize = mtd->oobblock + mtd->oobsize;
10118 + int blockcheck = (1 << (this->phys_erase_shift - this->page_shift)) - 1;
10119 +
10120 + /* Do not allow reads past end of device */
10121 + if ((from + len) > mtd->size) {
10122 + DEBUG (MTD_DEBUG_LEVEL0, "nand_read_raw: Attempt read beyond end of device\n");
10123 + return -EINVAL;
10124 + }
10125 +
10126 + /* Grab the lock and see if the device is available */
10127 + nand_get_device (this, mtd , FL_READING);
10128 +
10129 + this->select_chip (mtd, chip);
10130 +
10131 + /* Add requested oob length */
10132 + len += ooblen;
10133 +
10134 + while (len) {
10135 + if (sndcmd)
10136 + this->cmdfunc (mtd, NAND_CMD_READ0, 0, page & this->pagemask);
10137 + sndcmd = 0;
10138 +
10139 + this->read_buf (mtd, &buf[cnt], pagesize);
10140 +
10141 + len -= pagesize;
10142 + cnt += pagesize;
10143 + page++;
10144 +
10145 + if (!this->dev_ready)
10146 + udelay (this->chip_delay);
10147 + else
10148 + nand_wait_ready(mtd);
10149 +
10150 + /* Check, if the chip supports auto page increment */
10151 + if (!NAND_CANAUTOINCR(this) || !(page & blockcheck))
10152 + sndcmd = 1;
10153 + }
10154 +
10155 + /* Deselect and wake up anyone waiting on the device */
10156 + nand_release_device(mtd);
10157 + return 0;
10158 +}
10159 +
10160 +
10161 +/**
10162 + * nand_prepare_oobbuf - [GENERIC] Prepare the out of band buffer
10163 + * @mtd: MTD device structure
10164 + * @fsbuf: buffer given by fs driver
10165 + * @oobsel: out of band selection structre
10166 + * @autoplace: 1 = place given buffer into the oob bytes
10167 + * @numpages: number of pages to prepare
10168 + *
10169 + * Return:
10170 + * 1. Filesystem buffer available and autoplacement is off,
10171 + * return filesystem buffer
10172 + * 2. No filesystem buffer or autoplace is off, return internal
10173 + * buffer
10174 + * 3. Filesystem buffer is given and autoplace selected
10175 + * put data from fs buffer into internal buffer and
10176 + * retrun internal buffer
10177 + *
10178 + * Note: The internal buffer is filled with 0xff. This must
10179 + * be done only once, when no autoplacement happens
10180 + * Autoplacement sets the buffer dirty flag, which
10181 + * forces the 0xff fill before using the buffer again.
10182 + *
10183 +*/
10184 +#if NAND_WRITE_SUPPORT
10185 +static u_char * nand_prepare_oobbuf (struct mtd_info *mtd, u_char *fsbuf, struct nand_oobinfo *oobsel,
10186 + int autoplace, int numpages)
10187 +{
10188 + struct nand_chip *this = mtd->priv;
10189 + int i, len, ofs;
10190 +
10191 + /* Zero copy fs supplied buffer */
10192 + if (fsbuf && !autoplace)
10193 + return fsbuf;
10194 +
10195 + /* Check, if the buffer must be filled with ff again */
10196 + if (this->oobdirty) {
10197 + memset (this->oob_buf, 0xff,
10198 + mtd->oobsize << (this->phys_erase_shift - this->page_shift));
10199 + this->oobdirty = 0;
10200 + }
10201 +
10202 + /* If we have no autoplacement or no fs buffer use the internal one */
10203 + if (!autoplace || !fsbuf)
10204 + return this->oob_buf;
10205 +
10206 + /* Walk through the pages and place the data */
10207 + this->oobdirty = 1;
10208 + ofs = 0;
10209 + while (numpages--) {
10210 + for (i = 0, len = 0; len < mtd->oobavail; i++) {
10211 + int to = ofs + oobsel->oobfree[i][0];
10212 + int num = oobsel->oobfree[i][1];
10213 + memcpy (&this->oob_buf[to], fsbuf, num);
10214 + len += num;
10215 + fsbuf += num;
10216 + }
10217 + ofs += mtd->oobavail;
10218 + }
10219 + return this->oob_buf;
10220 +}
10221 +#endif
10222 +
10223 +#define NOTALIGNED(x) (x & (mtd->oobblock-1)) != 0
10224 +
10225 +/**
10226 + * nand_write - [MTD Interface] compability function for nand_write_ecc
10227 + * @mtd: MTD device structure
10228 + * @to: offset to write to
10229 + * @len: number of bytes to write
10230 + * @retlen: pointer to variable to store the number of written bytes
10231 + * @buf: the data to write
10232 + *
10233 + * This function simply calls nand_write_ecc with oob buffer and oobsel = NULL
10234 + *
10235 +*/
10236 +#if NAND_WRITE_SUPPORT
10237 +static int nand_write (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char * buf)
10238 +{
10239 + return (nand_write_ecc (mtd, to, len, retlen, buf, NULL, NULL));
10240 +}
10241 +#endif
10242 +
10243 +/**
10244 + * nand_write_ecc - [MTD Interface] NAND write with ECC
10245 + * @mtd: MTD device structure
10246 + * @to: offset to write to
10247 + * @len: number of bytes to write
10248 + * @retlen: pointer to variable to store the number of written bytes
10249 + * @buf: the data to write
10250 + * @eccbuf: filesystem supplied oob data buffer
10251 + * @oobsel: oob selection structure
10252 + *
10253 + * NAND write with ECC
10254 + */
10255 +#if NAND_WRITE_SUPPORT
10256 +static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
10257 + size_t * retlen, const u_char * buf, u_char * eccbuf, struct nand_oobinfo *oobsel)
10258 +{
10259 + int startpage, page, ret = -EIO, oob = 0, written = 0, chipnr;
10260 + int autoplace = 0, numpages, totalpages;
10261 + struct nand_chip *this = mtd->priv;
10262 + u_char *oobbuf, *bufstart;
10263 + int ppblock = (1 << (this->phys_erase_shift - this->page_shift));
10264 +
10265 + DEBUG (MTD_DEBUG_LEVEL3, "nand_write_ecc: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);
10266 +
10267 + /* Initialize retlen, in case of early exit */
10268 + *retlen = 0;
10269 +
10270 + /* Do not allow write past end of device */
10271 + if ((to + len) > mtd->size) {
10272 + DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: Attempt to write past end of page\n");
10273 + return -EINVAL;
10274 + }
10275 +
10276 + /* reject writes, which are not page aligned */
10277 + if (NOTALIGNED (to) || NOTALIGNED(len)) {
10278 + puts ("nand_write_ecc: Attempt to write not page aligned data\r\n");
10279 + return -EINVAL;
10280 + }
10281 +
10282 + /* Grab the lock and see if the device is available */
10283 + nand_get_device (this, mtd, FL_WRITING);
10284 +
10285 + /* Calculate chipnr */
10286 + chipnr = (int)(to >> this->chip_shift);
10287 + /* Select the NAND device */
10288 + this->select_chip(mtd, chipnr);
10289 +
10290 + /* Check, if it is write protected */
10291 + if (nand_check_wp(mtd))
10292 + goto out;
10293 +
10294 + /* if oobsel is NULL, use chip defaults */
10295 + if (oobsel == NULL)
10296 + oobsel = &mtd->oobinfo;
10297 +
10298 + /* Autoplace of oob data ? Use the default placement scheme */
10299 + if (oobsel->useecc == MTD_NANDECC_AUTOPLACE) {
10300 + oobsel = this->autooob;
10301 + autoplace = 1;
10302 + }
10303 + if (oobsel->useecc == MTD_NANDECC_AUTOPL_USR)
10304 + autoplace = 1;
10305 +
10306 + /* Setup variables and oob buffer */
10307 + totalpages = len >> this->page_shift;
10308 + page = (int) (to >> this->page_shift);
10309 + /* Invalidate the page cache, if we write to the cached page */
10310 + if (page <= this->pagebuf && this->pagebuf < (page + totalpages))
10311 + this->pagebuf = -1;
10312 +
10313 + /* Set it relative to chip */
10314 + page &= this->pagemask;
10315 + startpage = page;
10316 + /* Calc number of pages we can write in one go */
10317 + numpages = min (ppblock - (startpage & (ppblock - 1)), totalpages);
10318 + oobbuf = nand_prepare_oobbuf (mtd, eccbuf, oobsel, autoplace, numpages);
10319 + bufstart = (u_char *)buf;
10320 +
10321 + /* Loop until all data is written */
10322 + while (written < len) {
10323 +
10324 + this->data_poi = (u_char*) &buf[written];
10325 + /* Write one page. If this is the last page to write
10326 + * or the last page in this block, then use the
10327 + * real pageprogram command, else select cached programming
10328 + * if supported by the chip.
10329 + */
10330 + ret = nand_write_page (mtd, this, page, &oobbuf[oob], oobsel, (--numpages > 0));
10331 + if (ret) {
10332 + DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: write_page failed %d\n", ret);
10333 + goto out;
10334 + }
10335 + /* Next oob page */
10336 + oob += mtd->oobsize;
10337 + /* Update written bytes count */
10338 + written += mtd->oobblock;
10339 + if (written == len)
10340 + goto cmp;
10341 +
10342 + /* Increment page address */
10343 + page++;
10344 +
10345 + /* Have we hit a block boundary ? Then we have to verify and
10346 + * if verify is ok, we have to setup the oob buffer for
10347 + * the next pages.
10348 + */
10349 + if (!(page & (ppblock - 1))){
10350 + int ofs;
10351 + this->data_poi = bufstart;
10352 + ret = nand_verify_pages (mtd, this, startpage,
10353 + page - startpage,
10354 + oobbuf, oobsel, chipnr, (eccbuf != NULL));
10355 + if (ret) {
10356 + DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: verify_pages failed %d\n", ret);
10357 + goto out;
10358 + }
10359 + *retlen = written;
10360 +
10361 + ofs = autoplace ? mtd->oobavail : mtd->oobsize;
10362 + if (eccbuf)
10363 + eccbuf += (page - startpage) * ofs;
10364 + totalpages -= page - startpage;
10365 + numpages = min (totalpages, ppblock);
10366 + page &= this->pagemask;
10367 + startpage = page;
10368 + oobbuf = nand_prepare_oobbuf (mtd, eccbuf, oobsel,
10369 + autoplace, numpages);
10370 + oob = 0;
10371 + /* Check, if we cross a chip boundary */
10372 + if (!page) {
10373 + chipnr++;
10374 + this->select_chip(mtd, -1);
10375 + this->select_chip(mtd, chipnr);
10376 + }
10377 + }
10378 + }
10379 + /* Verify the remaining pages */
10380 +cmp:
10381 + this->data_poi = bufstart;
10382 + ret = nand_verify_pages (mtd, this, startpage, totalpages,
10383 + oobbuf, oobsel, chipnr, (eccbuf != NULL));
10384 + if (!ret)
10385 + *retlen = written;
10386 + else
10387 + DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: verify_pages failed %d\n", ret);
10388 +
10389 +out:
10390 + /* Deselect and wake up anyone waiting on the device */
10391 + nand_release_device(mtd);
10392 +
10393 + return ret;
10394 +}
10395 +#endif
10396 +
10397 +
10398 +/**
10399 + * nand_write_oob - [MTD Interface] NAND write out-of-band
10400 + * @mtd: MTD device structure
10401 + * @to: offset to write to
10402 + * @len: number of bytes to write
10403 + * @retlen: pointer to variable to store the number of written bytes
10404 + * @buf: the data to write
10405 + *
10406 + * NAND write out-of-band
10407 + */
10408 +#if NAND_WRITE_SUPPORT
10409 +static int nand_write_oob (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char * buf)
10410 +{
10411 + int column, page, status, ret = -EIO, chipnr;
10412 + struct nand_chip *this = mtd->priv;
10413 +
10414 + DEBUG (MTD_DEBUG_LEVEL3, "nand_write_oob: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);
10415 +
10416 + /* Shift to get page */
10417 + page = (int) (to >> this->page_shift);
10418 + chipnr = (int) (to >> this->chip_shift);
10419 +
10420 + /* Mask to get column */
10421 + column = to & (mtd->oobsize - 1);
10422 +
10423 + /* Initialize return length value */
10424 + *retlen = 0;
10425 +
10426 + /* Do not allow write past end of page */
10427 + if ((column + len) > mtd->oobsize) {
10428 + DEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: Attempt to write past end of page\n");
10429 + return -EINVAL;
10430 + }
10431 +
10432 + /* Grab the lock and see if the device is available */
10433 + nand_get_device (this, mtd, FL_WRITING);
10434 +
10435 + /* Select the NAND device */
10436 + this->select_chip(mtd, chipnr);
10437 +
10438 + /* Reset the chip. Some chips (like the Toshiba TC5832DC found
10439 + in one of my DiskOnChip 2000 test units) will clear the whole
10440 + data page too if we don't do this. I have no clue why, but
10441 + I seem to have 'fixed' it in the doc2000 driver in
10442 + August 1999. dwmw2. */
10443 + this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
10444 +
10445 + /* Check, if it is write protected */
10446 + if (nand_check_wp(mtd))
10447 + goto out;
10448 +
10449 + /* Invalidate the page cache, if we write to the cached page */
10450 + if (page == this->pagebuf)
10451 + this->pagebuf = -1;
10452 +
10453 + if (NAND_MUST_PAD(this)) {
10454 + /* Write out desired data */
10455 + this->cmdfunc (mtd, NAND_CMD_SEQIN, mtd->oobblock, page & this->pagemask);
10456 + /* prepad 0xff for partial programming */
10457 + this->write_buf(mtd, ffchars, column);
10458 + /* write data */
10459 + this->write_buf(mtd, buf, len);
10460 + /* postpad 0xff for partial programming */
10461 + this->write_buf(mtd, ffchars, mtd->oobsize - (len+column));
10462 + } else {
10463 + /* Write out desired data */
10464 + this->cmdfunc (mtd, NAND_CMD_SEQIN, mtd->oobblock + column, page & this->pagemask);
10465 + /* write data */
10466 + this->write_buf(mtd, buf, len);
10467 + }
10468 + /* Send command to program the OOB data */
10469 + this->cmdfunc (mtd, NAND_CMD_PAGEPROG, -1, -1);
10470 +
10471 + status = this->waitfunc (mtd, this, FL_WRITING);
10472 +
10473 + /* See if device thinks it succeeded */
10474 + if (status & NAND_STATUS_FAIL) {
10475 + DEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: " "Failed write, page 0x%08x\n", page);
10476 + ret = -EIO;
10477 + goto out;
10478 + }
10479 + /* Return happy */
10480 + *retlen = len;
10481 +
10482 +#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
10483 + /* Send command to read back the data */
10484 + this->cmdfunc (mtd, NAND_CMD_READOOB, column, page & this->pagemask);
10485 +
10486 + if (this->verify_buf(mtd, buf, len)) {
10487 + DEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: " "Failed write verify, page 0x%08x\n", page);
10488 + ret = -EIO;
10489 + goto out;
10490 + }
10491 +#endif
10492 + ret = 0;
10493 +out:
10494 + /* Deselect and wake up anyone waiting on the device */
10495 + nand_release_device(mtd);
10496 +
10497 + return ret;
10498 +}
10499 +#endif
10500 +
10501 +
10502 +/**
10503 + * nand_writev - [MTD Interface] compabilty function for nand_writev_ecc
10504 + * @mtd: MTD device structure
10505 + * @vecs: the iovectors to write
10506 + * @count: number of vectors
10507 + * @to: offset to write to
10508 + * @retlen: pointer to variable to store the number of written bytes
10509 + *
10510 + * NAND write with kvec. This just calls the ecc function
10511 + */
10512 +#if NAND_KVEC_SUPPORT
10513 +#if NAND_WRITE_SUPPORT
10514 +static int nand_writev (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count,
10515 + loff_t to, size_t * retlen)
10516 +{
10517 + return (nand_writev_ecc (mtd, vecs, count, to, retlen, NULL, NULL));
10518 +}
10519 +#endif
10520 +#endif
10521 +
10522 +/**
10523 + * nand_writev_ecc - [MTD Interface] write with iovec with ecc
10524 + * @mtd: MTD device structure
10525 + * @vecs: the iovectors to write
10526 + * @count: number of vectors
10527 + * @to: offset to write to
10528 + * @retlen: pointer to variable to store the number of written bytes
10529 + * @eccbuf: filesystem supplied oob data buffer
10530 + * @oobsel: oob selection structure
10531 + *
10532 + * NAND write with iovec with ecc
10533 + */
10534 +#if NAND_KVEC_SUPPORT
10535 +#if NAND_WRITE_SUPPORT
10536 +static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count,
10537 + loff_t to, size_t * retlen, u_char *eccbuf, struct nand_oobinfo *oobsel)
10538 +{
10539 + int i, page, len, total_len, ret = -EIO, written = 0, chipnr;
10540 + int oob, numpages, autoplace = 0, startpage;
10541 + struct nand_chip *this = mtd->priv;
10542 + int ppblock = (1 << (this->phys_erase_shift - this->page_shift));
10543 + u_char *oobbuf, *bufstart;
10544 +
10545 + /* Preset written len for early exit */
10546 + *retlen = 0;
10547 +
10548 + /* Calculate total length of data */
10549 + total_len = 0;
10550 + for (i = 0; i < count; i++)
10551 + total_len += (int) vecs[i].iov_len;
10552 +
10553 + DEBUG (MTD_DEBUG_LEVEL3,
10554 + "nand_writev: to = 0x%08x, len = %i, count = %ld\n", (unsigned int) to, (unsigned int) total_len, count);
10555 +
10556 + /* Do not allow write past end of page */
10557 + if ((to + total_len) > mtd->size) {
10558 + DEBUG (MTD_DEBUG_LEVEL0, "nand_writev: Attempted write past end of device\n");
10559 + return -EINVAL;
10560 + }
10561 +
10562 + /* reject writes, which are not page aligned */
10563 + if (NOTALIGNED (to) || NOTALIGNED(total_len)) {
10564 + puts ("nand_write_ecc: Attempt to write not page aligned data\r\n");
10565 + return -EINVAL;
10566 + }
10567 +
10568 + /* Grab the lock and see if the device is available */
10569 + nand_get_device (this, mtd, FL_WRITING);
10570 +
10571 + /* Get the current chip-nr */
10572 + chipnr = (int) (to >> this->chip_shift);
10573 + /* Select the NAND device */
10574 + this->select_chip(mtd, chipnr);
10575 +
10576 + /* Check, if it is write protected */
10577 + if (nand_check_wp(mtd))
10578 + goto out;
10579 +
10580 + /* if oobsel is NULL, use chip defaults */
10581 + if (oobsel == NULL)
10582 + oobsel = &mtd->oobinfo;
10583 +
10584 + /* Autoplace of oob data ? Use the default placement scheme */
10585 + if (oobsel->useecc == MTD_NANDECC_AUTOPLACE) {
10586 + oobsel = this->autooob;
10587 + autoplace = 1;
10588 + }
10589 + if (oobsel->useecc == MTD_NANDECC_AUTOPL_USR)
10590 + autoplace = 1;
10591 +
10592 + /* Setup start page */
10593 + page = (int) (to >> this->page_shift);
10594 + /* Invalidate the page cache, if we write to the cached page */
10595 + if (page <= this->pagebuf && this->pagebuf < ((to + total_len) >> this->page_shift))
10596 + this->pagebuf = -1;
10597 +
10598 + startpage = page & this->pagemask;
10599 +
10600 + /* Loop until all kvec' data has been written */
10601 + len = 0;
10602 + while (count) {
10603 + /* If the given tuple is >= pagesize then
10604 + * write it out from the iov
10605 + */
10606 + if ((vecs->iov_len - len) >= mtd->oobblock) {
10607 + /* Calc number of pages we can write
10608 + * out of this iov in one go */
10609 + numpages = (vecs->iov_len - len) >> this->page_shift;
10610 + /* Do not cross block boundaries */
10611 + numpages = min (ppblock - (startpage & (ppblock - 1)), numpages);
10612 + oobbuf = nand_prepare_oobbuf (mtd, NULL, oobsel, autoplace, numpages);
10613 + bufstart = (u_char *)vecs->iov_base;
10614 + bufstart += len;
10615 + this->data_poi = bufstart;
10616 + oob = 0;
10617 + for (i = 1; i <= numpages; i++) {
10618 + /* Write one page. If this is the last page to write
10619 + * then use the real pageprogram command, else select
10620 + * cached programming if supported by the chip.
10621 + */
10622 + ret = nand_write_page (mtd, this, page & this->pagemask,
10623 + &oobbuf[oob], oobsel, i != numpages);
10624 + if (ret)
10625 + goto out;
10626 + this->data_poi += mtd->oobblock;
10627 + len += mtd->oobblock;
10628 + oob += mtd->oobsize;
10629 + page++;
10630 + }
10631 + /* Check, if we have to switch to the next tuple */
10632 + if (len >= (int) vecs->iov_len) {
10633 + vecs++;
10634 + len = 0;
10635 + count--;
10636 + }
10637 + } else {
10638 + /* We must use the internal buffer, read data out of each
10639 + * tuple until we have a full page to write
10640 + */
10641 + int cnt = 0;
10642 + while (cnt < mtd->oobblock) {
10643 + if (vecs->iov_base != NULL && vecs->iov_len)
10644 + this->data_buf[cnt++] = ((u_char *) vecs->iov_base)[len++];
10645 + /* Check, if we have to switch to the next tuple */
10646 + if (len >= (int) vecs->iov_len) {
10647 + vecs++;
10648 + len = 0;
10649 + count--;
10650 + }
10651 + }
10652 + this->pagebuf = page;
10653 + this->data_poi = this->data_buf;
10654 + bufstart = this->data_poi;
10655 + numpages = 1;
10656 + oobbuf = nand_prepare_oobbuf (mtd, NULL, oobsel, autoplace, numpages);
10657 + ret = nand_write_page (mtd, this, page & this->pagemask,
10658 + oobbuf, oobsel, 0);
10659 + if (ret)
10660 + goto out;
10661 + page++;
10662 + }
10663 +
10664 + this->data_poi = bufstart;
10665 + ret = nand_verify_pages (mtd, this, startpage, numpages, oobbuf, oobsel, chipnr, 0);
10666 + if (ret)
10667 + goto out;
10668 +
10669 + written += mtd->oobblock * numpages;
10670 + /* All done ? */
10671 + if (!count)
10672 + break;
10673 +
10674 + startpage = page & this->pagemask;
10675 + /* Check, if we cross a chip boundary */
10676 + if (!startpage) {
10677 + chipnr++;
10678 + this->select_chip(mtd, -1);
10679 + this->select_chip(mtd, chipnr);
10680 + }
10681 + }
10682 + ret = 0;
10683 +out:
10684 + /* Deselect and wake up anyone waiting on the device */
10685 + nand_release_device(mtd);
10686 +
10687 + *retlen = written;
10688 + return ret;
10689 +}
10690 +#endif
10691 +#endif
10692 +
10693 +/**
10694 + * single_erease_cmd - [GENERIC] NAND standard block erase command function
10695 + * @mtd: MTD device structure
10696 + * @page: the page address of the block which will be erased
10697 + *
10698 + * Standard erase command for NAND chips
10699 + */
10700 +#if NAND_ERASE_SUPPORT
10701 +static void single_erase_cmd (struct mtd_info *mtd, int page)
10702 +{
10703 + struct nand_chip *this = mtd->priv;
10704 + /* Send commands to erase a block */
10705 + this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page);
10706 + this->cmdfunc (mtd, NAND_CMD_ERASE2, -1, -1);
10707 +}
10708 +#endif
10709 +
10710 +/**
10711 + * multi_erease_cmd - [GENERIC] AND specific block erase command function
10712 + * @mtd: MTD device structure
10713 + * @page: the page address of the block which will be erased
10714 + *
10715 + * AND multi block erase command function
10716 + * Erase 4 consecutive blocks
10717 + */
10718 +#if NAND_ERASE_SUPPORT
10719 +static void multi_erase_cmd (struct mtd_info *mtd, int page)
10720 +{
10721 + struct nand_chip *this = mtd->priv;
10722 + /* Send commands to erase a block */
10723 + this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page++);
10724 + this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page++);
10725 + this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page++);
10726 + this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page);
10727 + this->cmdfunc (mtd, NAND_CMD_ERASE2, -1, -1);
10728 +}
10729 +#endif
10730 +
10731 +/**
10732 + * nand_erase - [MTD Interface] erase block(s)
10733 + * @mtd: MTD device structure
10734 + * @instr: erase instruction
10735 + *
10736 + * Erase one ore more blocks
10737 + */
10738 +#if NAND_ERASE_SUPPORT
10739 +static int nand_erase (struct mtd_info *mtd, struct erase_info *instr)
10740 +{
10741 + return nand_erase_nand (mtd, instr, 0);
10742 +}
10743 +#endif
10744 +
10745 +#define BBT_PAGE_MASK 0xffffff3f
10746 +/**
10747 + * nand_erase_intern - [NAND Interface] erase block(s)
10748 + * @mtd: MTD device structure
10749 + * @instr: erase instruction
10750 + * @allowbbt: allow erasing the bbt area
10751 + *
10752 + * Erase one ore more blocks
10753 + */
10754 +#if NAND_ERASE_SUPPORT
10755 +int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbbt)
10756 +{
10757 + int page, len, status, pages_per_block, ret, chipnr;
10758 + struct nand_chip *this = mtd->priv;
10759 + int rewrite_bbt[NAND_MAX_CHIPS]={0}; /* flags to indicate the page, if bbt needs to be rewritten. */
10760 + unsigned int bbt_masked_page; /* bbt mask to compare to page being erased. */
10761 + /* It is used to see if the current page is in the same */
10762 + /* 256 block group and the same bank as the bbt. */
10763 +
10764 + DEBUG (MTD_DEBUG_LEVEL3,
10765 + "nand_erase: start = 0x%08x, len = %i\n", (unsigned int) instr->addr, (unsigned int) instr->len);
10766 +
10767 + /* Start address must align on block boundary */
10768 + if (instr->addr & ((1 << this->phys_erase_shift) - 1)) {
10769 + DEBUG (MTD_DEBUG_LEVEL0, "nand_erase: Unaligned address\n");
10770 + return -EINVAL;
10771 + }
10772 +
10773 + /* Length must align on block boundary */
10774 + if (instr->len & ((1 << this->phys_erase_shift) - 1)) {
10775 + DEBUG (MTD_DEBUG_LEVEL0, "nand_erase: Length not block aligned\n");
10776 + return -EINVAL;
10777 + }
10778 +
10779 + /* Do not allow erase past end of device */
10780 + if ((instr->len + instr->addr) > mtd->size) {
10781 + DEBUG (MTD_DEBUG_LEVEL0, "nand_erase: Erase past end of device\n");
10782 + return -EINVAL;
10783 + }
10784 +
10785 + instr->fail_addr = 0xffffffff;
10786 +
10787 + /* Grab the lock and see if the device is available */
10788 + nand_get_device (this, mtd, FL_ERASING);
10789 +
10790 + /* Shift to get first page */
10791 + page = (int) (instr->addr >> this->page_shift);
10792 + chipnr = (int) (instr->addr >> this->chip_shift);
10793 +
10794 + /* Calculate pages in each block */
10795 + pages_per_block = 1 << (this->phys_erase_shift - this->page_shift);
10796 +
10797 + /* Select the NAND device */
10798 + this->select_chip(mtd, chipnr);
10799 +
10800 + /* Check the WP bit */
10801 + /* Check, if it is write protected */
10802 + if (nand_check_wp(mtd)) {
10803 + DEBUG (MTD_DEBUG_LEVEL0, "nand_erase: Device is write protected!!!\n");
10804 + instr->state = MTD_ERASE_FAILED;
10805 + goto erase_exit;
10806 + }
10807 +
10808 + /* if BBT requires refresh, set the BBT page mask to see if the BBT should be rewritten */
10809 + if (this->options & BBT_AUTO_REFRESH) {
10810 + bbt_masked_page = this->bbt_td->pages[chipnr] & BBT_PAGE_MASK;
10811 + } else {
10812 + bbt_masked_page = 0xffffffff; /* should not match anything */
10813 + }
10814 +
10815 + /* Loop through the pages */
10816 + len = instr->len;
10817 +
10818 + instr->state = MTD_ERASING;
10819 +
10820 + while (len) {
10821 + /* Check if we have a bad block, we do not erase bad blocks ! */
10822 + if (nand_block_checkbad(mtd, ((loff_t) page) << this->page_shift, 0, allowbbt)) {
10823 + puts ("nand_erase: attempt to erase a bad block at page ");
10824 + putx (page);
10825 + putnl ();
10826 + instr->state = MTD_ERASE_FAILED;
10827 + goto erase_exit;
10828 + }
10829 +
10830 + /* Invalidate the page cache, if we erase the block which contains
10831 + the current cached page */
10832 + if (page <= this->pagebuf && this->pagebuf < (page + pages_per_block))
10833 + this->pagebuf = -1;
10834 +
10835 + this->erase_cmd (mtd, page & this->pagemask);
10836 +
10837 + status = this->waitfunc (mtd, this, FL_ERASING);
10838 +
10839 + /* See if operation failed and additional status checks are available */
10840 + if ((status & NAND_STATUS_FAIL) && (this->errstat)) {
10841 + status = this->errstat(mtd, this, FL_ERASING, status, page);
10842 + }
10843 +
10844 + /* See if block erase succeeded */
10845 + if (status & NAND_STATUS_FAIL) {
10846 + DEBUG (MTD_DEBUG_LEVEL0, "nand_erase: " "Failed erase, page 0x%08x\n", page);
10847 + instr->state = MTD_ERASE_FAILED;
10848 + instr->fail_addr = (page << this->page_shift);
10849 + goto erase_exit;
10850 + }
10851 +
10852 + /* if BBT requires refresh, set the BBT rewrite flag to the page being erased */
10853 + if (this->options & BBT_AUTO_REFRESH) {
10854 + if (((page & BBT_PAGE_MASK) == bbt_masked_page) &&
10855 + (page != this->bbt_td->pages[chipnr])) {
10856 + rewrite_bbt[chipnr] = (page << this->page_shift);
10857 + }
10858 + }
10859 +
10860 + /* Increment page address and decrement length */
10861 + len -= (1 << this->phys_erase_shift);
10862 + page += pages_per_block;
10863 +
10864 + /* Check, if we cross a chip boundary */
10865 + if (len && !(page & this->pagemask)) {
10866 + chipnr++;
10867 + this->select_chip(mtd, -1);
10868 + this->select_chip(mtd, chipnr);
10869 +
10870 + /* if BBT requires refresh and BBT-PERCHIP,
10871 + * set the BBT page mask to see if this BBT should be rewritten */
10872 + if ((this->options & BBT_AUTO_REFRESH) && (this->bbt_td->options & NAND_BBT_PERCHIP)) {
10873 + bbt_masked_page = this->bbt_td->pages[chipnr] & BBT_PAGE_MASK;
10874 + }
10875 +
10876 + }
10877 + }
10878 + instr->state = MTD_ERASE_DONE;
10879 +
10880 +erase_exit:
10881 +
10882 + ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO;
10883 +#if 0
10884 + /* Do call back function */
10885 + if (!ret)
10886 + mtd_erase_callback(instr);
10887 +#endif
10888 +
10889 + /* Deselect and wake up anyone waiting on the device */
10890 + nand_release_device(mtd);
10891 +
10892 +#if NAND_BBT_SUPPORT
10893 + /* if BBT requires refresh and erase was successful, rewrite any selected bad block tables */
10894 + if ((this->options & BBT_AUTO_REFRESH) && (!ret)) {
10895 + for (chipnr = 0; chipnr < this->numchips; chipnr++) {
10896 + if (rewrite_bbt[chipnr]) {
10897 + /* update the BBT for chip */
10898 + DEBUG (MTD_DEBUG_LEVEL0, "nand_erase_nand: nand_update_bbt (%d:0x%0x 0x%0x)\n",
10899 + chipnr, rewrite_bbt[chipnr], this->bbt_td->pages[chipnr]);
10900 + nand_update_bbt (mtd, rewrite_bbt[chipnr]);
10901 + }
10902 + }
10903 + }
10904 +#endif
10905 +
10906 + /* Return more or less happy */
10907 + return ret;
10908 +}
10909 +#endif
10910 +
10911 +/**
10912 + * nand_sync - [MTD Interface] sync
10913 + * @mtd: MTD device structure
10914 + *
10915 + * Sync is actually a wait for chip ready function
10916 + */
10917 +#if 0 /* not needed */
10918 +static void nand_sync (struct mtd_info *mtd)
10919 +{
10920 + struct nand_chip *this = mtd->priv;
10921 +
10922 + DEBUG (MTD_DEBUG_LEVEL3, "nand_sync: called\n");
10923 +
10924 + /* Grab the lock and see if the device is available */
10925 + nand_get_device (this, mtd, FL_SYNCING);
10926 + /* Release it and go back */
10927 + nand_release_device (mtd);
10928 +}
10929 +#endif
10930 +
10931 +
10932 +/**
10933 + * nand_block_isbad - [MTD Interface] Check whether the block at the given offset is bad
10934 + * @mtd: MTD device structure
10935 + * @ofs: offset relative to mtd start
10936 + */
10937 +static int nand_block_isbad (struct mtd_info *mtd, loff_t ofs)
10938 +{
10939 + /* Check for invalid offset */
10940 + if (ofs > mtd->size)
10941 + return -EINVAL;
10942 +
10943 + return nand_block_checkbad (mtd, ofs, 1, 0);
10944 +}
10945 +
10946 +/**
10947 + * nand_block_markbad - [MTD Interface] Mark the block at the given offset as bad
10948 + * @mtd: MTD device structure
10949 + * @ofs: offset relative to mtd start
10950 + */
10951 +#if NAND_WRITE_SUPPORT
10952 +static int nand_block_markbad (struct mtd_info *mtd, loff_t ofs)
10953 +{
10954 + struct nand_chip *this = mtd->priv;
10955 + int ret;
10956 +
10957 + if ((ret = nand_block_isbad(mtd, ofs))) {
10958 + /* If it was bad already, return success and do nothing. */
10959 + if (ret > 0)
10960 + return 0;
10961 + return ret;
10962 + }
10963 +
10964 + return this->block_markbad(mtd, ofs);
10965 +}
10966 +#endif
10967 +
10968 +/**
10969 + * nand_suspend - [MTD Interface] Suspend the NAND flash
10970 + * @mtd: MTD device structure
10971 + */
10972 +#if 0 /* don't need it */
10973 +static int nand_suspend(struct mtd_info *mtd)
10974 +{
10975 + struct nand_chip *this = mtd->priv;
10976 +
10977 + return nand_get_device (this, mtd, FL_PM_SUSPENDED);
10978 +}
10979 +#endif
10980 +
10981 +/**
10982 + * nand_resume - [MTD Interface] Resume the NAND flash
10983 + * @mtd: MTD device structure
10984 + */
10985 +#if 0 /* don't need it */
10986 +static void nand_resume(struct mtd_info *mtd)
10987 +{
10988 + struct nand_chip *this = mtd->priv;
10989 +
10990 + if (this->state == FL_PM_SUSPENDED)
10991 + nand_release_device(mtd);
10992 + else
10993 + puts("resume() called for the chip which is not in suspended state\n");
10994 +
10995 +}
10996 +#endif
10997 +
10998 +
10999 +/**
11000 + * nand_scan - [NAND Interface] Scan for the NAND device
11001 + * @mtd: MTD device structure
11002 + * @maxchips: Number of chips to scan for
11003 + *
11004 + * This fills out all the not initialized function pointers
11005 + * with the defaults.
11006 + * The flash ID is read and the mtd/chip structures are
11007 + * filled with the appropriate values. Buffers are allocated if
11008 + * they are not provided by the board driver
11009 + *
11010 + */
11011 +int nand_scan (struct mtd_info *mtd, int maxchips)
11012 +{
11013 + int i, nand_maf_id, nand_dev_id, busw, maf_id;
11014 + struct nand_chip *this = mtd->priv;
11015 +
11016 + /* Get buswidth to select the correct functions*/
11017 + busw = this->options & NAND_BUSWIDTH_16;
11018 +
11019 + /* check for proper chip_delay setup, set 20us if not */
11020 + if (!this->chip_delay)
11021 + this->chip_delay = 20;
11022 +
11023 + /* check, if a user supplied command function given */
11024 + if (this->cmdfunc == NULL)
11025 + this->cmdfunc = nand_command;
11026 +
11027 + /* check, if a user supplied wait function given */
11028 + if (this->waitfunc == NULL)
11029 + this->waitfunc = nand_wait;
11030 +
11031 + if (!this->select_chip)
11032 + this->select_chip = nand_select_chip;
11033 + if (!this->write_byte)
11034 + this->write_byte = busw ? nand_write_byte16 : nand_write_byte;
11035 + if (!this->read_byte)
11036 + this->read_byte = busw ? nand_read_byte16 : nand_read_byte;
11037 + if (!this->write_word)
11038 + this->write_word = nand_write_word;
11039 + if (!this->read_word)
11040 + this->read_word = nand_read_word;
11041 + if (!this->block_bad)
11042 + this->block_bad = nand_block_bad;
11043 +#if NAND_WRITE_SUPPORT
11044 + if (!this->block_markbad)
11045 + this->block_markbad = nand_default_block_markbad;
11046 +#endif
11047 + if (!this->write_buf)
11048 + this->write_buf = busw ? nand_write_buf16 : nand_write_buf;
11049 + if (!this->read_buf)
11050 + this->read_buf = busw ? nand_read_buf16 : nand_read_buf;
11051 + if (!this->verify_buf)
11052 + this->verify_buf = busw ? nand_verify_buf16 : nand_verify_buf;
11053 +#if NAND_BBT_SUPPORT
11054 + if (!this->scan_bbt)
11055 + this->scan_bbt = nand_default_bbt;
11056 +#endif
11057 +
11058 + /* Select the device */
11059 + this->select_chip(mtd, 0);
11060 +
11061 + /* Send the command for reading device ID */
11062 + this->cmdfunc (mtd, NAND_CMD_READID, 0x00, -1);
11063 +
11064 + /* Read manufacturer and device IDs */
11065 + nand_maf_id = this->read_byte(mtd);
11066 + nand_dev_id = this->read_byte(mtd);
11067 +
11068 + /* Print and store flash device information */
11069 + for (i = 0; nand_flash_ids[i].name != NULL; i++) {
11070 +
11071 + if (nand_dev_id != nand_flash_ids[i].id)
11072 + continue;
11073 +
11074 + if (!mtd->name) mtd->name = nand_flash_ids[i].name;
11075 + this->chipsize = nand_flash_ids[i].chipsize << 20;
11076 +
11077 + /* New devices have all the information in additional id bytes */
11078 + if (!nand_flash_ids[i].pagesize) {
11079 + int extid;
11080 + /* The 3rd id byte contains non relevant data ATM */
11081 + extid = this->read_byte(mtd);
11082 + /* The 4th id byte is the important one */
11083 + extid = this->read_byte(mtd);
11084 + /* Calc pagesize */
11085 + mtd->oobblock = 1024 << (extid & 0x3);
11086 + extid >>= 2;
11087 + /* Calc oobsize */
11088 + mtd->oobsize = (8 << (extid & 0x01)) * (mtd->oobblock >> 9);
11089 + extid >>= 2;
11090 + /* Calc blocksize. Blocksize is multiples of 64KiB */
11091 + mtd->erasesize = (64 * 1024) << (extid & 0x03);
11092 + extid >>= 2;
11093 + /* Get buswidth information */
11094 + busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0;
11095 +
11096 + } else {
11097 + /* Old devices have this data hardcoded in the
11098 + * device id table */
11099 + mtd->erasesize = nand_flash_ids[i].erasesize;
11100 + mtd->oobblock = nand_flash_ids[i].pagesize;
11101 + mtd->oobsize = mtd->oobblock / 32;
11102 + busw = nand_flash_ids[i].options & NAND_BUSWIDTH_16;
11103 + }
11104 +
11105 + /* Try to identify manufacturer */
11106 + for (maf_id = 0; nand_manuf_ids[maf_id].id != 0x0; maf_id++) {
11107 + if (nand_manuf_ids[maf_id].id == nand_maf_id)
11108 + break;
11109 + }
11110 +
11111 + /* Check, if buswidth is correct. Hardware drivers should set
11112 + * this correct ! */
11113 + if (busw != (this->options & NAND_BUSWIDTH_16)) {
11114 +#if 0
11115 + puts ("Manufacturer ID: ");
11116 + putx (nand_maf_id);
11117 + puts (", Chip ID: ");
11118 + putx (nand_dev_id);
11119 + puts (" (");
11120 + puts (nand_manuf_ids[maf_id].name);
11121 + putc (' ');
11122 + puts (mtd->name);
11123 + puts (")\r\n");
11124 +#endif
11125 + puts ("Expected NAND bus width ");
11126 + putx ((this->options & NAND_BUSWIDTH_16) ? 16 : 8);
11127 + puts (",found ");
11128 + putx (busw ? 16 : 8);
11129 + putnl();
11130 + this->select_chip(mtd, -1);
11131 + return 1;
11132 + }
11133 +
11134 + /* Calculate the address shift from the page size */
11135 + this->page_shift = ffs(mtd->oobblock) - 1;
11136 + this->bbt_erase_shift = this->phys_erase_shift = ffs(mtd->erasesize) - 1;
11137 + this->chip_shift = ffs(this->chipsize) - 1;
11138 +
11139 + /* Set the bad block position */
11140 + this->badblockpos = mtd->oobblock > 512 ?
11141 + NAND_LARGE_BADBLOCK_POS : NAND_SMALL_BADBLOCK_POS;
11142 +
11143 + /* Get chip options, preserve non chip based options */
11144 + this->options &= ~NAND_CHIPOPTIONS_MSK;
11145 + this->options |= nand_flash_ids[i].options & NAND_CHIPOPTIONS_MSK;
11146 + /* Set this as a default. Board drivers can override it, if neccecary */
11147 + this->options |= NAND_NO_AUTOINCR;
11148 + /* Check if this is a not a samsung device. Do not clear the options
11149 + * for chips which are not having an extended id.
11150 + */
11151 + if (nand_maf_id != NAND_MFR_SAMSUNG && !nand_flash_ids[i].pagesize)
11152 + this->options &= ~NAND_SAMSUNG_LP_OPTIONS;
11153 +
11154 +#if NAND_ERASE_SUPPORT
11155 + /* Check for AND chips with 4 page planes */
11156 + if (this->options & NAND_4PAGE_ARRAY)
11157 + this->erase_cmd = multi_erase_cmd;
11158 + else
11159 + this->erase_cmd = single_erase_cmd;
11160 +#endif
11161 +
11162 + /* Do not replace user supplied command function ! */
11163 + if (mtd->oobblock > 512 && this->cmdfunc == nand_command)
11164 + this->cmdfunc = nand_command_lp;
11165 +
11166 + puts ("Manufacturer ID / Chip ID: ");
11167 + putx (nand_maf_id << 8 | nand_dev_id);
11168 + puts (" (");
11169 + puts (nand_manuf_ids[maf_id].name);
11170 + putc (' ');
11171 + puts (nand_flash_ids[i].name);
11172 + puts (")\r\n");
11173 + break;
11174 + }
11175 +
11176 + if (!nand_flash_ids[i].name) {
11177 + puts ("No NAND device found!!!\r\n");
11178 + this->select_chip(mtd, -1);
11179 + return 1;
11180 + }
11181 +
11182 +#if NAND_MULTICHIP_SUPPORT
11183 + for (i=1; i < maxchips; i++) {
11184 + this->select_chip(mtd, i);
11185 +
11186 + /* Send the command for reading device ID */
11187 + this->cmdfunc (mtd, NAND_CMD_READID, 0x00, -1);
11188 +
11189 + /* Read manufacturer and device IDs */
11190 + if (nand_maf_id != this->read_byte(mtd) ||
11191 + nand_dev_id != this->read_byte(mtd))
11192 + break;
11193 + }
11194 + if (i > 1) {
11195 + putx (i);
11196 + puts (" NAND chips detected\r\n");
11197 + }
11198 +#endif
11199 +
11200 + /* Allocate buffers, if neccecary */
11201 + if (!this->oob_buf) {
11202 + size_t len;
11203 + len = mtd->oobsize << (this->phys_erase_shift - this->page_shift);
11204 + this->oob_buf = malloc (len);
11205 + if (!this->oob_buf) {
11206 + puts ("nand_scan(): Cannot allocate oob_buf\r\n");
11207 + return -ENOMEM;
11208 + }
11209 + this->options |= NAND_OOBBUF_ALLOC;
11210 + }
11211 +
11212 + if (!this->data_buf) {
11213 + size_t len;
11214 + len = mtd->oobblock + mtd->oobsize;
11215 + this->data_buf = malloc (len);
11216 + if (!this->data_buf) {
11217 + if (this->options & NAND_OOBBUF_ALLOC)
11218 + free (this->oob_buf);
11219 + puts ("nand_scan(): Cannot allocate data_buf\r\n");
11220 + return -ENOMEM;
11221 + }
11222 + this->options |= NAND_DATABUF_ALLOC;
11223 + }
11224 +
11225 +#if NAND_MULTICHIP_SUPP0RT
11226 + /* Store the number of chips and calc total size for mtd */
11227 + this->numchips = i;
11228 + mtd->size = i * this->chipsize;
11229 +#else
11230 + /* Store the number of chips and calc total size for mtd */
11231 + this->numchips = 1;
11232 + mtd->size = this->chipsize;
11233 +#endif
11234 +
11235 + /* Convert chipsize to number of pages per chip -1. */
11236 + this->pagemask = (this->chipsize >> this->page_shift) - 1;
11237 + /* Preset the internal oob buffer */
11238 + memset(this->oob_buf, 0xff, mtd->oobsize << (this->phys_erase_shift - this->page_shift));
11239 +
11240 + /* If no default placement scheme is given, select an
11241 + * appropriate one */
11242 + if (!this->autooob) {
11243 + /* Select the appropriate default oob placement scheme for
11244 + * placement agnostic filesystems */
11245 + switch (mtd->oobsize) {
11246 + case 8:
11247 + this->autooob = &nand_oob_8;
11248 + break;
11249 + case 16:
11250 + this->autooob = &nand_oob_16;
11251 + break;
11252 + case 64:
11253 + this->autooob = &nand_oob_64;
11254 + break;
11255 + default:
11256 + puts ("No oob scheme defined for oobsize ");
11257 + putx (mtd->oobsize);
11258 + putnl ();
11259 + BUG();
11260 + }
11261 + }
11262 +
11263 + /* The number of bytes available for the filesystem to place fs dependend
11264 + * oob data */
11265 + mtd->oobavail = 0;
11266 + for (i = 0; this->autooob->oobfree[i][1]; i++)
11267 + mtd->oobavail += this->autooob->oobfree[i][1];
11268 +
11269 + /*
11270 + * check ECC mode, default to software
11271 + * if 3byte/512byte hardware ECC is selected and we have 256 byte pagesize
11272 + * fallback to software ECC
11273 + */
11274 + this->eccsize = 256; /* set default eccsize */
11275 + this->eccbytes = 3;
11276 +
11277 + switch (this->eccmode) {
11278 +#if NAND_HWECC_SUPPORT
11279 + case NAND_ECC_HW12_2048:
11280 + if (mtd->oobblock < 2048) {
11281 + puts ("2048 byte HW ECC not possible on ");
11282 + putx (mtd->oobblock);
11283 + puts (" byte page size, fallback to SW ECC\r\n");
11284 + this->eccmode = NAND_ECC_SOFT;
11285 + this->calculate_ecc = nand_calculate_ecc;
11286 + this->correct_data = nand_correct_data;
11287 + } else
11288 + this->eccsize = 2048;
11289 + break;
11290 +
11291 + case NAND_ECC_HW3_512:
11292 + case NAND_ECC_HW6_512:
11293 + case NAND_ECC_HW8_512:
11294 + if (mtd->oobblock == 256) {
11295 + puts ("512 byte HW ECC not possible on 256 Byte pagesize, fallback to SW ECC\r\n");
11296 + this->eccmode = NAND_ECC_SOFT;
11297 + this->calculate_ecc = nand_calculate_ecc;
11298 + this->correct_data = nand_correct_data;
11299 + } else
11300 + this->eccsize = 512; /* set eccsize to 512 */
11301 + break;
11302 +
11303 + case NAND_ECC_HW3_256:
11304 + break;
11305 +#endif
11306 +
11307 + case NAND_ECC_NONE:
11308 + puts ("NAND_ECC_NONE selected by board driver. This is not recommended !!\r\n");
11309 + this->eccmode = NAND_ECC_NONE;
11310 + break;
11311 +
11312 + case NAND_ECC_SOFT:
11313 + this->calculate_ecc = nand_calculate_ecc;
11314 + this->correct_data = nand_correct_data;
11315 + break;
11316 +
11317 + default:
11318 + puts ("Invalid NAND_ECC_MODE ");
11319 + putx (this->eccmode);
11320 + putnl ();
11321 + BUG();
11322 + }
11323 +
11324 + /* Check hardware ecc function availability and adjust number of ecc bytes per
11325 + * calculation step
11326 + */
11327 + switch (this->eccmode) {
11328 + case NAND_ECC_HW12_2048:
11329 + this->eccbytes += 4;
11330 + case NAND_ECC_HW8_512:
11331 + this->eccbytes += 2;
11332 + case NAND_ECC_HW6_512:
11333 + this->eccbytes += 3;
11334 + case NAND_ECC_HW3_512:
11335 + case NAND_ECC_HW3_256:
11336 + if (this->calculate_ecc && this->correct_data && this->enable_hwecc)
11337 + break;
11338 + puts ("No ECC functions supplied, Hardware ECC not possible\r\n");
11339 + BUG();
11340 + }
11341 +
11342 + mtd->eccsize = this->eccsize;
11343 +
11344 + /* Set the number of read / write steps for one page to ensure ECC generation */
11345 + switch (this->eccmode) {
11346 + case NAND_ECC_HW12_2048:
11347 + this->eccsteps = mtd->oobblock / 2048;
11348 + break;
11349 + case NAND_ECC_HW3_512:
11350 + case NAND_ECC_HW6_512:
11351 + case NAND_ECC_HW8_512:
11352 + this->eccsteps = mtd->oobblock / 512;
11353 + break;
11354 + case NAND_ECC_HW3_256:
11355 + case NAND_ECC_SOFT:
11356 + this->eccsteps = mtd->oobblock / 256;
11357 + break;
11358 +
11359 + case NAND_ECC_NONE:
11360 + this->eccsteps = 1;
11361 + break;
11362 + }
11363 +
11364 + /* Initialize state, waitqueue and spinlock */
11365 + this->state = FL_READY;
11366 +#if 0
11367 + init_waitqueue_head (&this->wq);
11368 + spin_lock_init (&this->chip_lock);
11369 +#endif
11370 +
11371 + /* De-select the device */
11372 + this->select_chip(mtd, -1);
11373 +
11374 + /* Invalidate the pagebuffer reference */
11375 + this->pagebuf = -1;
11376 +
11377 + /* Fill in remaining MTD driver data */
11378 + mtd->type = MTD_NANDFLASH;
11379 + mtd->flags = MTD_CAP_NANDFLASH | MTD_ECC;
11380 + mtd->ecctype = MTD_ECC_SW;
11381 +#if NAND_ERASE_SUPPORT
11382 + mtd->erase = nand_erase;
11383 +#endif
11384 +#if 0 /* not needed */
11385 + mtd->point = NULL;
11386 + mtd->unpoint = NULL;
11387 +#endif
11388 + mtd->read = nand_read;
11389 +#if NAND_WRITE_SUPPORT
11390 + mtd->write = nand_write;
11391 +#endif
11392 + mtd->read_ecc = nand_read_ecc;
11393 +#if NAND_WRITE_SUPPORT
11394 + mtd->write_ecc = nand_write_ecc;
11395 +#endif
11396 + mtd->read_oob = nand_read_oob;
11397 +#if NAND_WRITE_SUPPORT
11398 + mtd->write_oob = nand_write_oob;
11399 +#endif
11400 +#if NAND_KVEC_SUPPORT
11401 + mtd->readv = NULL;
11402 +#endif
11403 +#if NAND_WRITE_SUPPORT && NAND_KVEC_SUPPORT
11404 + mtd->writev = nand_writev;
11405 + mtd->writev_ecc = nand_writev_ecc;
11406 +#endif
11407 +#if 0 /* not needed */
11408 + mtd->sync = nand_sync;
11409 + mtd->lock = NULL;
11410 + mtd->unlock = NULL;
11411 + mtd->suspend = nand_suspend;
11412 + mtd->resume = nand_resume;
11413 +#endif
11414 + mtd->block_isbad = nand_block_isbad;
11415 +#if NAND_WRITE_SUPPORT
11416 + mtd->block_markbad = nand_block_markbad;
11417 +#endif
11418 +
11419 + /* and make the autooob the default one */
11420 + memcpy(&mtd->oobinfo, this->autooob, sizeof(mtd->oobinfo));
11421 +
11422 +#ifdef THIS_MODULE /* normally isn't for us */
11423 + mtd->owner = THIS_MODULE;
11424 +#endif
11425 +
11426 + /* Check, if we should skip the bad block table scan */
11427 + if (this->options & NAND_SKIP_BBTSCAN)
11428 + return 0;
11429 +
11430 +#if NAND_BBT_SUPPORT
11431 + /* Build bad block table */
11432 + return this->scan_bbt (mtd);
11433 +#else
11434 + return -1;
11435 +#endif
11436 +}
11437 +
11438 +/**
11439 + * nand_release - [NAND Interface] Free resources held by the NAND device
11440 + * @mtd: MTD device structure
11441 +*/
11442 +#if 0 /* don't need it */
11443 +void nand_release (struct mtd_info *mtd)
11444 +{
11445 + struct nand_chip *this = mtd->priv;
11446 +
11447 +#if 0
11448 +#ifdef CONFIG_MTD_PARTITIONS
11449 + /* Deregister partitions */
11450 + del_mtd_partitions (mtd);
11451 +#endif
11452 + /* Deregister the device */
11453 + del_mtd_device (mtd);
11454 +#endif
11455 +
11456 + /* Free bad block table memory */
11457 + free (this->bbt);
11458 + /* Buffer allocated by nand_scan ? */
11459 + if (this->options & NAND_OOBBUF_ALLOC)
11460 + free (this->oob_buf);
11461 + /* Buffer allocated by nand_scan ? */
11462 + if (this->options & NAND_DATABUF_ALLOC)
11463 + free (this->data_buf);
11464 +}
11465 +#endif
11466 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/boot/rescue/nand_bbt.c linux-2.6.19.2.dev/arch/cris/arch-v32/boot/rescue/nand_bbt.c
11467 --- linux-2.6.19.2.old/arch/cris/arch-v32/boot/rescue/nand_bbt.c 1970-01-01 01:00:00.000000000 +0100
11468 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/boot/rescue/nand_bbt.c 2006-11-10 09:55:58.000000000 +0100
11469 @@ -0,0 +1,1151 @@
11470 +/*
11471 + * drivers/mtd/nand_bbt.c
11472 + *
11473 + * Overview:
11474 + * Bad block table support for the NAND driver
11475 + *
11476 + * Copyright (C) 2004 Thomas Gleixner (tglx@linutronix.de)
11477 + *
11478 + * $Id: nand_bbt.c,v 1.5 2006/11/10 08:55:58 ricardw Exp $
11479 + *
11480 + * This program is free software; you can redistribute it and/or modify
11481 + * it under the terms of the GNU General Public License version 2 as
11482 + * published by the Free Software Foundation.
11483 + *
11484 + * Description:
11485 + *
11486 + * When nand_scan_bbt is called, then it tries to find the bad block table
11487 + * depending on the options in the bbt descriptor(s). If a bbt is found
11488 + * then the contents are read and the memory based bbt is created. If a
11489 + * mirrored bbt is selected then the mirror is searched too and the
11490 + * versions are compared. If the mirror has a greater version number
11491 + * than the mirror bbt is used to build the memory based bbt.
11492 + * If the tables are not versioned, then we "or" the bad block information.
11493 + * If one of the bbt's is out of date or does not exist it is (re)created.
11494 + * If no bbt exists at all then the device is scanned for factory marked
11495 + * good / bad blocks and the bad block tables are created.
11496 + *
11497 + * For manufacturer created bbts like the one found on M-SYS DOC devices
11498 + * the bbt is searched and read but never created
11499 + *
11500 + * The autogenerated bad block table is located in the last good blocks
11501 + * of the device. The table is mirrored, so it can be updated eventually.
11502 + * The table is marked in the oob area with an ident pattern and a version
11503 + * number which indicates which of both tables is more up to date.
11504 + *
11505 + * The table uses 2 bits per block
11506 + * 11b: block is good
11507 + * 00b: block is factory marked bad
11508 + * 01b, 10b: block is marked bad due to wear
11509 + *
11510 + * The memory bad block table uses the following scheme:
11511 + * 00b: block is good
11512 + * 01b: block is marked bad due to wear
11513 + * 10b: block is reserved (to protect the bbt area)
11514 + * 11b: block is factory marked bad
11515 + *
11516 + * Multichip devices like DOC store the bad block info per floor.
11517 + *
11518 + * Following assumptions are made:
11519 + * - bbts start at a page boundary, if autolocated on a block boundary
11520 + * - the space neccecary for a bbt in FLASH does not exceed a block boundary
11521 + *
11522 + */
11523 +
11524 +#if 0
11525 +#include <linux/slab.h>
11526 +#endif
11527 +
11528 +#include <linux/types.h>
11529 +#include "mtd.h"
11530 +#include "nand.h"
11531 +#include "nand_ecc.h"
11532 +
11533 +#if 0
11534 +#include <linux/mtd/compatmac.h>
11535 +#include <linux/bitops.h>
11536 +#endif
11537 +
11538 +#include <linux/delay.h>
11539 +
11540 +#include "lib.h"
11541 +
11542 +
11543 +/**
11544 + * check_pattern - [GENERIC] check if a pattern is in the buffer
11545 + * @buf: the buffer to search
11546 + * @len: the length of buffer to search
11547 + * @paglen: the pagelength
11548 + * @td: search pattern descriptor
11549 + *
11550 + * Check for a pattern at the given place. Used to search bad block
11551 + * tables and good / bad block identifiers.
11552 + * If the SCAN_EMPTY option is set then check, if all bytes except the
11553 + * pattern area contain 0xff
11554 + *
11555 +*/
11556 +static int check_pattern (uint8_t *buf, int len, int paglen, struct nand_bbt_descr *td)
11557 +{
11558 + int i, end = 0;
11559 + uint8_t *p = buf;
11560 +
11561 + end = paglen + td->offs;
11562 + if (td->options & NAND_BBT_SCANEMPTY) {
11563 + for (i = 0; i < end; i++) {
11564 + if (p[i] != 0xff)
11565 + return -1;
11566 + }
11567 + }
11568 + p += end;
11569 +
11570 + /* Compare the pattern */
11571 + for (i = 0; i < td->len; i++) {
11572 + if (p[i] != td->pattern[i])
11573 + return -1;
11574 + }
11575 +
11576 + if (td->options & NAND_BBT_SCANEMPTY) {
11577 + p += td->len;
11578 + end += td->len;
11579 + for (i = end; i < len; i++) {
11580 + if (*p++ != 0xff)
11581 + return -1;
11582 + }
11583 + }
11584 + return 0;
11585 +}
11586 +
11587 +/**
11588 + * check_short_pattern - [GENERIC] check if a pattern is in the buffer
11589 + * @buf: the buffer to search
11590 + * @td: search pattern descriptor
11591 + *
11592 + * Check for a pattern at the given place. Used to search bad block
11593 + * tables and good / bad block identifiers. Same as check_pattern, but
11594 + * no optional empty check
11595 + *
11596 +*/
11597 +static int check_short_pattern (uint8_t *buf, struct nand_bbt_descr *td)
11598 +{
11599 + int i;
11600 + uint8_t *p = buf;
11601 +
11602 + /* Compare the pattern */
11603 + for (i = 0; i < td->len; i++) {
11604 + if (p[td->offs + i] != td->pattern[i])
11605 + return -1;
11606 + }
11607 + return 0;
11608 +}
11609 +
11610 +/**
11611 + * read_bbt - [GENERIC] Read the bad block table starting from page
11612 + * @mtd: MTD device structure
11613 + * @buf: temporary buffer
11614 + * @page: the starting page
11615 + * @num: the number of bbt descriptors to read
11616 + * @bits: number of bits per block
11617 + * @offs: offset in the memory table
11618 + * @reserved_block_code: Pattern to identify reserved blocks
11619 + *
11620 + * Read the bad block table starting from page.
11621 + *
11622 + */
11623 +static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num,
11624 + int bits, int offs, int reserved_block_code)
11625 +{
11626 + int res, i, j, act = 0;
11627 + struct nand_chip *this = mtd->priv;
11628 + size_t retlen, len, totlen;
11629 + loff_t from;
11630 + uint8_t msk = (uint8_t) ((1 << bits) - 1);
11631 +
11632 + totlen = (num * bits) >> 3;
11633 + from = ((loff_t)page) << this->page_shift;
11634 +
11635 + while (totlen) {
11636 + len = min (totlen, (size_t) (1 << this->bbt_erase_shift));
11637 + res = mtd->read_ecc (mtd, from, len, &retlen, buf, NULL, this->autooob);
11638 + if (res < 0) {
11639 + if (retlen != len) {
11640 + puts ("nand_bbt: Error reading bad block table\n");
11641 + return res;
11642 + }
11643 + puts ("nand_bbt: ECC error while reading bad block table\n");
11644 + }
11645 +
11646 + /* Analyse data */
11647 + for (i = 0; i < len; i++) {
11648 + uint8_t dat = buf[i];
11649 + for (j = 0; j < 8; j += bits, act += 2) {
11650 + uint8_t tmp = (dat >> j) & msk;
11651 + if (tmp == msk)
11652 + continue;
11653 + if (reserved_block_code &&
11654 + (tmp == reserved_block_code)) {
11655 + puts ("nand_read_bbt: Reserved block at");
11656 + putx (((offs << 2) + (act >> 1)) << this->bbt_erase_shift);
11657 + putnl ();
11658 + this->bbt[offs + (act >> 3)] |= 0x2 << (act & 0x06);
11659 + continue;
11660 + }
11661 + /* Leave it for now, if its matured we can move this
11662 + * message to MTD_DEBUG_LEVEL0 */
11663 + puts ("nand_read_bbt: Bad block at ");
11664 + putx (((offs << 2) + (act >> 1)) << this->bbt_erase_shift);
11665 + putnl ();
11666 + /* Factory marked bad or worn out ? */
11667 + if (tmp == 0)
11668 + this->bbt[offs + (act >> 3)] |= 0x3 << (act & 0x06);
11669 + else
11670 + this->bbt[offs + (act >> 3)] |= 0x1 << (act & 0x06);
11671 + }
11672 + }
11673 + totlen -= len;
11674 + from += len;
11675 + }
11676 + return 0;
11677 +}
11678 +
11679 +/**
11680 + * read_abs_bbt - [GENERIC] Read the bad block table starting at a given page
11681 + * @mtd: MTD device structure
11682 + * @buf: temporary buffer
11683 + * @td: descriptor for the bad block table
11684 + * @chip: read the table for a specific chip, -1 read all chips.
11685 + * Applies only if NAND_BBT_PERCHIP option is set
11686 + *
11687 + * Read the bad block table for all chips starting at a given page
11688 + * We assume that the bbt bits are in consecutive order.
11689 +*/
11690 +static int read_abs_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td, int chip)
11691 +{
11692 + struct nand_chip *this = mtd->priv;
11693 + int res = 0, i;
11694 + int bits;
11695 +
11696 + bits = td->options & NAND_BBT_NRBITS_MSK;
11697 + if (td->options & NAND_BBT_PERCHIP) {
11698 + int offs = 0;
11699 + for (i = 0; i < this->numchips; i++) {
11700 + if (chip == -1 || chip == i)
11701 + res = read_bbt (mtd, buf, td->pages[i], this->chipsize >> this->bbt_erase_shift, bits, offs, td->reserved_block_code);
11702 + if (res)
11703 + return res;
11704 + offs += this->chipsize >> (this->bbt_erase_shift + 2);
11705 + }
11706 + } else {
11707 + res = read_bbt (mtd, buf, td->pages[0], mtd->size >> this->bbt_erase_shift, bits, 0, td->reserved_block_code);
11708 + if (res)
11709 + return res;
11710 + }
11711 + return 0;
11712 +}
11713 +
11714 +/**
11715 + * read_abs_bbts - [GENERIC] Read the bad block table(s) for all chips starting at a given page
11716 + * @mtd: MTD device structure
11717 + * @buf: temporary buffer
11718 + * @td: descriptor for the bad block table
11719 + * @md: descriptor for the bad block table mirror
11720 + *
11721 + * Read the bad block table(s) for all chips starting at a given page
11722 + * We assume that the bbt bits are in consecutive order.
11723 + *
11724 +*/
11725 +static int read_abs_bbts (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td,
11726 + struct nand_bbt_descr *md)
11727 +{
11728 + struct nand_chip *this = mtd->priv;
11729 +
11730 + /* Read the primary version, if available */
11731 + if (td->options & NAND_BBT_VERSION) {
11732 + nand_read_raw (mtd, buf, td->pages[0] << this->page_shift, mtd->oobblock, mtd->oobsize);
11733 + td->version[0] = buf[mtd->oobblock + td->veroffs];
11734 + puts ("Bad block table at page ");
11735 + putx (td->pages[0]);
11736 + puts (", version ");
11737 + putx (td->version[0]);
11738 + putnl ();
11739 + }
11740 +
11741 + /* Read the mirror version, if available */
11742 + if (md && (md->options & NAND_BBT_VERSION)) {
11743 + nand_read_raw (mtd, buf, md->pages[0] << this->page_shift, mtd->oobblock, mtd->oobsize);
11744 + md->version[0] = buf[mtd->oobblock + md->veroffs];
11745 + puts ("Bad block table at page ");
11746 + putx (md->pages[0]);
11747 + puts (", version ");
11748 + putx (md->version[0]);
11749 + putnl ();
11750 + }
11751 +
11752 + return 1;
11753 +}
11754 +
11755 +/**
11756 + * create_bbt - [GENERIC] Create a bad block table by scanning the device
11757 + * @mtd: MTD device structure
11758 + * @buf: temporary buffer
11759 + * @bd: descriptor for the good/bad block search pattern
11760 + * @chip: create the table for a specific chip, -1 read all chips.
11761 + * Applies only if NAND_BBT_PERCHIP option is set
11762 + *
11763 + * Create a bad block table by scanning the device
11764 + * for the given good/bad block identify pattern
11765 + */
11766 +static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd, int chip)
11767 +{
11768 + struct nand_chip *this = mtd->priv;
11769 + int i, j, numblocks, len, scanlen;
11770 + int startblock;
11771 + loff_t from;
11772 + size_t readlen, ooblen;
11773 +
11774 + puts ("Scanning device for bad blocks\n");
11775 +
11776 + if (bd->options & NAND_BBT_SCANALLPAGES)
11777 + len = 1 << (this->bbt_erase_shift - this->page_shift);
11778 + else {
11779 + if (bd->options & NAND_BBT_SCAN2NDPAGE)
11780 + len = 2;
11781 + else
11782 + len = 1;
11783 + }
11784 +
11785 + if (!(bd->options & NAND_BBT_SCANEMPTY)) {
11786 + /* We need only read few bytes from the OOB area */
11787 + scanlen = ooblen = 0;
11788 + readlen = bd->len;
11789 + } else {
11790 + /* Full page content should be read */
11791 + scanlen = mtd->oobblock + mtd->oobsize;
11792 + readlen = len * mtd->oobblock;
11793 + ooblen = len * mtd->oobsize;
11794 + }
11795 +
11796 + if (chip == -1) {
11797 + /* Note that numblocks is 2 * (real numblocks) here, see i+=2 below as it
11798 + * makes shifting and masking less painful */
11799 + numblocks = mtd->size >> (this->bbt_erase_shift - 1);
11800 + startblock = 0;
11801 + from = 0;
11802 + } else {
11803 + if (chip >= this->numchips) {
11804 + puts ("create_bbt(): chipnr (");
11805 + putx (chip + 1);
11806 + puts (" > available chips ");
11807 + putx (this->numchips);
11808 + putnl ();
11809 + return -EINVAL;
11810 + }
11811 + numblocks = this->chipsize >> (this->bbt_erase_shift - 1);
11812 + startblock = chip * numblocks;
11813 + numblocks += startblock;
11814 + from = startblock << (this->bbt_erase_shift - 1);
11815 + }
11816 +
11817 + for (i = startblock; i < numblocks;) {
11818 + int ret;
11819 +
11820 + if (bd->options & NAND_BBT_SCANEMPTY)
11821 + if ((ret = nand_read_raw (mtd, buf, from, readlen, ooblen)))
11822 + return ret;
11823 +
11824 + for (j = 0; j < len; j++) {
11825 + if (!(bd->options & NAND_BBT_SCANEMPTY)) {
11826 + size_t retlen;
11827 +
11828 + /* Read the full oob until read_oob is fixed to
11829 + * handle single byte reads for 16 bit buswidth */
11830 + ret = mtd->read_oob(mtd, from + j * mtd->oobblock,
11831 + mtd->oobsize, &retlen, buf);
11832 + if (ret)
11833 + return ret;
11834 +
11835 + if (check_short_pattern (buf, bd)) {
11836 + this->bbt[i >> 3] |= 0x03 << (i & 0x6);
11837 + puts ("Bad eraseblock ");
11838 + putx (i >> 1);
11839 + puts (" at ");
11840 + putx ((unsigned int) from);
11841 + putnl ();
11842 + break;
11843 + }
11844 + } else {
11845 + if (check_pattern (&buf[j * scanlen], scanlen, mtd->oobblock, bd)) {
11846 + this->bbt[i >> 3] |= 0x03 << (i & 0x6);
11847 + puts ("Bad eraseblock ");
11848 + putx (i >> 1);
11849 + puts (" at ");
11850 + putx ((unsigned int) from);
11851 + putnl ();
11852 + break;
11853 + }
11854 + }
11855 + }
11856 + i += 2;
11857 + from += (1 << this->bbt_erase_shift);
11858 + }
11859 + return 0;
11860 +}
11861 +
11862 +/**
11863 + * search_bbt - [GENERIC] scan the device for a specific bad block table
11864 + * @mtd: MTD device structure
11865 + * @buf: temporary buffer
11866 + * @td: descriptor for the bad block table
11867 + *
11868 + * Read the bad block table by searching for a given ident pattern.
11869 + * Search is preformed either from the beginning up or from the end of
11870 + * the device downwards. The search starts always at the start of a
11871 + * block.
11872 + * If the option NAND_BBT_PERCHIP is given, each chip is searched
11873 + * for a bbt, which contains the bad block information of this chip.
11874 + * This is neccecary to provide support for certain DOC devices.
11875 + *
11876 + * The bbt ident pattern resides in the oob area of the first page
11877 + * in a block.
11878 + */
11879 +static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td)
11880 +{
11881 + struct nand_chip *this = mtd->priv;
11882 + int i, chips;
11883 + int bits, startblock, block, dir;
11884 + int scanlen = mtd->oobblock + mtd->oobsize;
11885 + int bbtblocks;
11886 +
11887 + /* Search direction top -> down ? */
11888 + if (td->options & NAND_BBT_LASTBLOCK) {
11889 + startblock = (mtd->size >> this->bbt_erase_shift) -1;
11890 + dir = -1;
11891 + } else {
11892 + startblock = 0;
11893 + dir = 1;
11894 + }
11895 +
11896 + /* Do we have a bbt per chip ? */
11897 + if (td->options & NAND_BBT_PERCHIP) {
11898 + chips = this->numchips;
11899 + bbtblocks = this->chipsize >> this->bbt_erase_shift;
11900 + startblock &= bbtblocks - 1;
11901 + } else {
11902 + chips = 1;
11903 + bbtblocks = mtd->size >> this->bbt_erase_shift;
11904 + }
11905 +
11906 + /* Number of bits for each erase block in the bbt */
11907 + bits = td->options & NAND_BBT_NRBITS_MSK;
11908 +
11909 + for (i = 0; i < chips; i++) {
11910 + /* Reset version information */
11911 + td->version[i] = 0;
11912 + td->pages[i] = -1;
11913 + /* Scan the maximum number of blocks */
11914 + for (block = 0; block < td->maxblocks; block++) {
11915 + int actblock = startblock + dir * block;
11916 + /* Read first page */
11917 + nand_read_raw (mtd, buf, actblock << this->bbt_erase_shift, mtd->oobblock, mtd->oobsize);
11918 + if (!check_pattern(buf, scanlen, mtd->oobblock, td)) {
11919 + td->pages[i] = actblock << (this->bbt_erase_shift - this->page_shift);
11920 + if (td->options & NAND_BBT_VERSION) {
11921 + td->version[i] = buf[mtd->oobblock + td->veroffs];
11922 + }
11923 + break;
11924 + }
11925 + }
11926 + startblock += this->chipsize >> this->bbt_erase_shift;
11927 + }
11928 + /* Check, if we found a bbt for each requested chip */
11929 + for (i = 0; i < chips; i++) {
11930 + if (td->pages[i] == -1) {
11931 + puts ("Bad block table not found for chip ");
11932 + putx (i);
11933 + putnl ();
11934 + } else {
11935 + puts ("Bad block table found at page ");
11936 + putx (td->pages[i]);
11937 + puts (" version ");
11938 + putx (td->version[i]);
11939 + putnl ();
11940 + }
11941 + }
11942 + return 0;
11943 +}
11944 +
11945 +/**
11946 + * search_read_bbts - [GENERIC] scan the device for bad block table(s)
11947 + * @mtd: MTD device structure
11948 + * @buf: temporary buffer
11949 + * @td: descriptor for the bad block table
11950 + * @md: descriptor for the bad block table mirror
11951 + *
11952 + * Search and read the bad block table(s)
11953 +*/
11954 +static int search_read_bbts (struct mtd_info *mtd, uint8_t *buf,
11955 + struct nand_bbt_descr *td, struct nand_bbt_descr *md)
11956 +{
11957 + /* Search the primary table */
11958 + search_bbt (mtd, buf, td);
11959 +
11960 + /* Search the mirror table */
11961 + if (md)
11962 + search_bbt (mtd, buf, md);
11963 +
11964 + /* Force result check */
11965 + return 1;
11966 +}
11967 +
11968 +
11969 +/**
11970 + * write_bbt - [GENERIC] (Re)write the bad block table
11971 + *
11972 + * @mtd: MTD device structure
11973 + * @buf: temporary buffer
11974 + * @td: descriptor for the bad block table
11975 + * @md: descriptor for the bad block table mirror
11976 + * @chipsel: selector for a specific chip, -1 for all
11977 + *
11978 + * (Re)write the bad block table
11979 + *
11980 +*/
11981 +static int write_bbt (struct mtd_info *mtd, uint8_t *buf,
11982 + struct nand_bbt_descr *td, struct nand_bbt_descr *md, int chipsel)
11983 +{
11984 + struct nand_chip *this = mtd->priv;
11985 + struct nand_oobinfo oobinfo;
11986 + struct erase_info einfo;
11987 + int i, j, res, chip = 0;
11988 + int bits, startblock, dir, page, offs, numblocks, sft, sftmsk;
11989 + int nrchips, bbtoffs, pageoffs;
11990 + uint8_t msk[4];
11991 + uint8_t rcode = td->reserved_block_code;
11992 + size_t retlen, len = 0;
11993 + loff_t to;
11994 +
11995 + if (!rcode)
11996 + rcode = 0xff;
11997 + /* Write bad block table per chip rather than per device ? */
11998 + if (td->options & NAND_BBT_PERCHIP) {
11999 + numblocks = (int) (this->chipsize >> this->bbt_erase_shift);
12000 + /* Full device write or specific chip ? */
12001 + if (chipsel == -1) {
12002 + nrchips = this->numchips;
12003 + } else {
12004 + nrchips = chipsel + 1;
12005 + chip = chipsel;
12006 + }
12007 + } else {
12008 + numblocks = (int) (mtd->size >> this->bbt_erase_shift);
12009 + nrchips = 1;
12010 + }
12011 +
12012 + /* Loop through the chips */
12013 + for (; chip < nrchips; chip++) {
12014 +
12015 + /* There was already a version of the table, reuse the page
12016 + * This applies for absolute placement too, as we have the
12017 + * page nr. in td->pages.
12018 + */
12019 + if (td->pages[chip] != -1) {
12020 + page = td->pages[chip];
12021 + goto write;
12022 + }
12023 +
12024 + /* Automatic placement of the bad block table */
12025 + /* Search direction top -> down ? */
12026 + if (td->options & NAND_BBT_LASTBLOCK) {
12027 + startblock = numblocks * (chip + 1) - 1;
12028 + dir = -1;
12029 + } else {
12030 + startblock = chip * numblocks;
12031 + dir = 1;
12032 + }
12033 +
12034 + for (i = 0; i < td->maxblocks; i++) {
12035 + int block = startblock + dir * i;
12036 + /* Check, if the block is bad */
12037 + switch ((this->bbt[block >> 2] >> (2 * (block & 0x03))) & 0x03) {
12038 + case 0x01:
12039 + case 0x03:
12040 + continue;
12041 + }
12042 + page = block << (this->bbt_erase_shift - this->page_shift);
12043 + /* Check, if the block is used by the mirror table */
12044 + if (!md || md->pages[chip] != page)
12045 + goto write;
12046 + }
12047 + puts ("No space left to write bad block table\r\n");
12048 + return -ENOSPC;
12049 +write:
12050 +
12051 + /* Set up shift count and masks for the flash table */
12052 + bits = td->options & NAND_BBT_NRBITS_MSK;
12053 + switch (bits) {
12054 + case 1: sft = 3; sftmsk = 0x07; msk[0] = 0x00; msk[1] = 0x01; msk[2] = ~rcode; msk[3] = 0x01; break;
12055 + case 2: sft = 2; sftmsk = 0x06; msk[0] = 0x00; msk[1] = 0x01; msk[2] = ~rcode; msk[3] = 0x03; break;
12056 + case 4: sft = 1; sftmsk = 0x04; msk[0] = 0x00; msk[1] = 0x0C; msk[2] = ~rcode; msk[3] = 0x0f; break;
12057 + case 8: sft = 0; sftmsk = 0x00; msk[0] = 0x00; msk[1] = 0x0F; msk[2] = ~rcode; msk[3] = 0xff; break;
12058 + default: return -EINVAL;
12059 + }
12060 +
12061 + bbtoffs = chip * (numblocks >> 2);
12062 +
12063 + to = ((loff_t) page) << this->page_shift;
12064 +
12065 + memcpy (&oobinfo, this->autooob, sizeof(oobinfo));
12066 + oobinfo.useecc = MTD_NANDECC_PLACEONLY;
12067 +
12068 + /* Must we save the block contents ? */
12069 + if (td->options & NAND_BBT_SAVECONTENT) {
12070 + /* Make it block aligned */
12071 + to &= ~((loff_t) ((1 << this->bbt_erase_shift) - 1));
12072 + len = 1 << this->bbt_erase_shift;
12073 + res = mtd->read_ecc (mtd, to, len, &retlen, buf, &buf[len], &oobinfo);
12074 + if (res < 0) {
12075 + if (retlen != len) {
12076 + puts ("nand_bbt: Error reading block for writing the bad block table\r\n");
12077 + return res;
12078 + }
12079 + puts ("nand_bbt: ECC error while reading block for writing bad block table\r\n");
12080 + }
12081 + /* Calc the byte offset in the buffer */
12082 + pageoffs = page - (int)(to >> this->page_shift);
12083 + offs = pageoffs << this->page_shift;
12084 + /* Preset the bbt area with 0xff */
12085 + memset (&buf[offs], 0xff, (size_t)(numblocks >> sft));
12086 + /* Preset the bbt's oob area with 0xff */
12087 + memset (&buf[len + pageoffs * mtd->oobsize], 0xff,
12088 + ((len >> this->page_shift) - pageoffs) * mtd->oobsize);
12089 + if (td->options & NAND_BBT_VERSION) {
12090 + buf[len + (pageoffs * mtd->oobsize) + td->veroffs] = td->version[chip];
12091 + }
12092 + } else {
12093 + /* Calc length */
12094 + len = (size_t) (numblocks >> sft);
12095 + /* Make it page aligned ! */
12096 + len = (len + (mtd->oobblock-1)) & ~(mtd->oobblock-1);
12097 + /* Preset the buffer with 0xff */
12098 + memset (buf, 0xff, len + (len >> this->page_shift) * mtd->oobsize);
12099 + offs = 0;
12100 + /* Pattern is located in oob area of first page */
12101 + memcpy (&buf[len + td->offs], td->pattern, td->len);
12102 + if (td->options & NAND_BBT_VERSION) {
12103 + buf[len + td->veroffs] = td->version[chip];
12104 + }
12105 + }
12106 +
12107 + /* walk through the memory table */
12108 + for (i = 0; i < numblocks; ) {
12109 + uint8_t dat;
12110 + dat = this->bbt[bbtoffs + (i >> 2)];
12111 + for (j = 0; j < 4; j++ , i++) {
12112 + int sftcnt = (i << (3 - sft)) & sftmsk;
12113 + /* Do not store the reserved bbt blocks ! */
12114 + buf[offs + (i >> sft)] &= ~(msk[dat & 0x03] << sftcnt);
12115 + dat >>= 2;
12116 + }
12117 + }
12118 +
12119 + memset (&einfo, 0, sizeof (einfo));
12120 + einfo.mtd = mtd;
12121 + einfo.addr = (unsigned long) to;
12122 + einfo.len = 1 << this->bbt_erase_shift;
12123 + res = nand_erase_nand (mtd, &einfo, 1);
12124 + if (res < 0) {
12125 + puts ("nand_bbt: Error during block erase: ");
12126 + putx (res);
12127 + putnl();
12128 + return res;
12129 + }
12130 +
12131 + res = mtd->write_ecc (mtd, to, len, &retlen, buf, &buf[len], &oobinfo);
12132 + if (res < 0) {
12133 + puts ("nand_bbt: Error while writing bad block table ");
12134 + putx (res);
12135 + putnl ();
12136 + return res;
12137 + }
12138 + puts ("Bad block table written to ");
12139 + putx ((unsigned int) to);
12140 + puts (", version ");
12141 + putx (td->version[chip]);
12142 + putnl ();
12143 +
12144 + /* Mark it as used */
12145 + td->pages[chip] = page;
12146 + }
12147 + return 0;
12148 +}
12149 +
12150 +/**
12151 + * nand_memory_bbt - [GENERIC] create a memory based bad block table
12152 + * @mtd: MTD device structure
12153 + * @bd: descriptor for the good/bad block search pattern
12154 + *
12155 + * The function creates a memory based bbt by scanning the device
12156 + * for manufacturer / software marked good / bad blocks
12157 +*/
12158 +static inline int nand_memory_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd)
12159 +{
12160 + struct nand_chip *this = mtd->priv;
12161 +
12162 + bd->options &= ~NAND_BBT_SCANEMPTY;
12163 + return create_bbt (mtd, this->data_buf, bd, -1);
12164 +}
12165 +
12166 +/**
12167 + * check_create - [GENERIC] create and write bbt(s) if neccecary
12168 + * @mtd: MTD device structure
12169 + * @buf: temporary buffer
12170 + * @bd: descriptor for the good/bad block search pattern
12171 + *
12172 + * The function checks the results of the previous call to read_bbt
12173 + * and creates / updates the bbt(s) if neccecary
12174 + * Creation is neccecary if no bbt was found for the chip/device
12175 + * Update is neccecary if one of the tables is missing or the
12176 + * version nr. of one table is less than the other
12177 +*/
12178 +static int check_create (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd)
12179 +{
12180 + int i, chips, writeops, chipsel, res;
12181 + struct nand_chip *this = mtd->priv;
12182 + struct nand_bbt_descr *td = this->bbt_td;
12183 + struct nand_bbt_descr *md = this->bbt_md;
12184 + struct nand_bbt_descr *rd, *rd2;
12185 +
12186 + /* Do we have a bbt per chip ? */
12187 + if (td->options & NAND_BBT_PERCHIP)
12188 + chips = this->numchips;
12189 + else
12190 + chips = 1;
12191 +
12192 + for (i = 0; i < chips; i++) {
12193 + writeops = 0;
12194 + rd = NULL;
12195 + rd2 = NULL;
12196 + /* Per chip or per device ? */
12197 + chipsel = (td->options & NAND_BBT_PERCHIP) ? i : -1;
12198 + /* Mirrored table avilable ? */
12199 + if (md) {
12200 + if (td->pages[i] == -1 && md->pages[i] == -1) {
12201 + writeops = 0x03;
12202 + goto create;
12203 + }
12204 +
12205 + if (td->pages[i] == -1) {
12206 + rd = md;
12207 + td->version[i] = md->version[i];
12208 + writeops = 1;
12209 + goto writecheck;
12210 + }
12211 +
12212 + if (md->pages[i] == -1) {
12213 + rd = td;
12214 + md->version[i] = td->version[i];
12215 + writeops = 2;
12216 + goto writecheck;
12217 + }
12218 +
12219 + if (td->version[i] == md->version[i]) {
12220 + rd = td;
12221 + if (!(td->options & NAND_BBT_VERSION))
12222 + rd2 = md;
12223 + goto writecheck;
12224 + }
12225 +
12226 + if (((int8_t) (td->version[i] - md->version[i])) > 0) {
12227 + rd = td;
12228 + md->version[i] = td->version[i];
12229 + writeops = 2;
12230 + } else {
12231 + rd = md;
12232 + td->version[i] = md->version[i];
12233 + writeops = 1;
12234 + }
12235 +
12236 + goto writecheck;
12237 +
12238 + } else {
12239 + if (td->pages[i] == -1) {
12240 + writeops = 0x01;
12241 + goto create;
12242 + }
12243 + rd = td;
12244 + goto writecheck;
12245 + }
12246 +create:
12247 + /* Create the bad block table by scanning the device ? */
12248 + if (!(td->options & NAND_BBT_CREATE))
12249 + continue;
12250 +
12251 + /* Create the table in memory by scanning the chip(s) */
12252 + create_bbt (mtd, buf, bd, chipsel);
12253 +
12254 + td->version[i] = 1;
12255 + if (md)
12256 + md->version[i] = 1;
12257 +writecheck:
12258 + /* read back first ? */
12259 + if (rd)
12260 + read_abs_bbt (mtd, buf, rd, chipsel);
12261 + /* If they weren't versioned, read both. */
12262 + if (rd2)
12263 + read_abs_bbt (mtd, buf, rd2, chipsel);
12264 +
12265 + /* Write the bad block table to the device ? */
12266 + if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) {
12267 + res = write_bbt (mtd, buf, td, md, chipsel);
12268 + if (res < 0)
12269 + return res;
12270 + }
12271 +
12272 + /* Write the mirror bad block table to the device ? */
12273 + if ((writeops & 0x02) && md && (md->options & NAND_BBT_WRITE)) {
12274 + res = write_bbt (mtd, buf, md, td, chipsel);
12275 + if (res < 0)
12276 + return res;
12277 + }
12278 + }
12279 + return 0;
12280 +}
12281 +
12282 +/**
12283 + * mark_bbt_regions - [GENERIC] mark the bad block table regions
12284 + * @mtd: MTD device structure
12285 + * @td: bad block table descriptor
12286 + *
12287 + * The bad block table regions are marked as "bad" to prevent
12288 + * accidental erasures / writes. The regions are identified by
12289 + * the mark 0x02.
12290 +*/
12291 +static void mark_bbt_region (struct mtd_info *mtd, struct nand_bbt_descr *td)
12292 +{
12293 + struct nand_chip *this = mtd->priv;
12294 + int i, j, chips, block, nrblocks, update;
12295 + uint8_t oldval, newval;
12296 +
12297 + /* Do we have a bbt per chip ? */
12298 + if (td->options & NAND_BBT_PERCHIP) {
12299 + chips = this->numchips;
12300 + nrblocks = (int)(this->chipsize >> this->bbt_erase_shift);
12301 + } else {
12302 + chips = 1;
12303 + nrblocks = (int)(mtd->size >> this->bbt_erase_shift);
12304 + }
12305 +
12306 + for (i = 0; i < chips; i++) {
12307 + if ((td->options & NAND_BBT_ABSPAGE) ||
12308 + !(td->options & NAND_BBT_WRITE)) {
12309 + if (td->pages[i] == -1) continue;
12310 + block = td->pages[i] >> (this->bbt_erase_shift - this->page_shift);
12311 + block <<= 1;
12312 + oldval = this->bbt[(block >> 3)];
12313 + newval = oldval | (0x2 << (block & 0x06));
12314 + this->bbt[(block >> 3)] = newval;
12315 + if ((oldval != newval) && td->reserved_block_code)
12316 + nand_update_bbt(mtd, block << (this->bbt_erase_shift - 1));
12317 + continue;
12318 + }
12319 + update = 0;
12320 + if (td->options & NAND_BBT_LASTBLOCK)
12321 + block = ((i + 1) * nrblocks) - td->maxblocks;
12322 + else
12323 + block = i * nrblocks;
12324 + block <<= 1;
12325 + for (j = 0; j < td->maxblocks; j++) {
12326 + oldval = this->bbt[(block >> 3)];
12327 + newval = oldval | (0x2 << (block & 0x06));
12328 + this->bbt[(block >> 3)] = newval;
12329 + if (oldval != newval) update = 1;
12330 + block += 2;
12331 + }
12332 + /* If we want reserved blocks to be recorded to flash, and some
12333 + new ones have been marked, then we need to update the stored
12334 + bbts. This should only happen once. */
12335 + if (update && td->reserved_block_code)
12336 + nand_update_bbt(mtd, (block - 2) << (this->bbt_erase_shift - 1));
12337 + }
12338 +}
12339 +
12340 +/**
12341 + * nand_scan_bbt - [NAND Interface] scan, find, read and maybe create bad block table(s)
12342 + * @mtd: MTD device structure
12343 + * @bd: descriptor for the good/bad block search pattern
12344 + *
12345 + * The function checks, if a bad block table(s) is/are already
12346 + * available. If not it scans the device for manufacturer
12347 + * marked good / bad blocks and writes the bad block table(s) to
12348 + * the selected place.
12349 + *
12350 + * The bad block table memory is allocated here. It must be freed
12351 + * by calling the nand_free_bbt function.
12352 + *
12353 +*/
12354 +int nand_scan_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd)
12355 +{
12356 + struct nand_chip *this = mtd->priv;
12357 + int len, res = 0;
12358 + uint8_t *buf;
12359 + struct nand_bbt_descr *td = this->bbt_td;
12360 + struct nand_bbt_descr *md = this->bbt_md;
12361 +
12362 + len = mtd->size >> (this->bbt_erase_shift + 2);
12363 + /* Allocate memory (2bit per block) */
12364 + this->bbt = malloc (len);
12365 + if (!this->bbt) {
12366 + puts ("nand_scan_bbt: Out of memory\r\n");
12367 + return -ENOMEM;
12368 + }
12369 + /* Clear the memory bad block table */
12370 + memset (this->bbt, 0x00, len);
12371 +
12372 + /* If no primary table decriptor is given, scan the device
12373 + * to build a memory based bad block table
12374 + */
12375 + if (!td) {
12376 + if ((res = nand_memory_bbt(mtd, bd))) {
12377 + puts ("nand_bbt: Can't scan flash and build the RAM-based BBT\r\n");
12378 + free (this->bbt);
12379 + this->bbt = NULL;
12380 + }
12381 + return res;
12382 + }
12383 +
12384 + /* Allocate a temporary buffer for one eraseblock incl. oob */
12385 + len = (1 << this->bbt_erase_shift);
12386 + len += (len >> this->page_shift) * mtd->oobsize;
12387 + buf = malloc (len);
12388 + if (!buf) {
12389 + puts ("nand_bbt: Out of memory\r\n");
12390 + free (this->bbt);
12391 + this->bbt = NULL;
12392 + return -ENOMEM;
12393 + }
12394 +
12395 + /* Is the bbt at a given page ? */
12396 + if (td->options & NAND_BBT_ABSPAGE) {
12397 + res = read_abs_bbts (mtd, buf, td, md);
12398 + } else {
12399 + /* Search the bad block table using a pattern in oob */
12400 + res = search_read_bbts (mtd, buf, td, md);
12401 + }
12402 +
12403 + if (res)
12404 + res = check_create (mtd, buf, bd);
12405 +
12406 + /* Prevent the bbt regions from erasing / writing */
12407 + mark_bbt_region (mtd, td);
12408 + if (md)
12409 + mark_bbt_region (mtd, md);
12410 +
12411 + free (buf);
12412 + return res;
12413 +}
12414 +
12415 +
12416 +/**
12417 + * nand_update_bbt - [NAND Interface] update bad block table(s)
12418 + * @mtd: MTD device structure
12419 + * @offs: the offset of the newly marked block
12420 + *
12421 + * The function updates the bad block table(s)
12422 +*/
12423 +int nand_update_bbt (struct mtd_info *mtd, loff_t offs)
12424 +{
12425 + struct nand_chip *this = mtd->priv;
12426 + int len, res = 0, writeops = 0;
12427 + int chip, chipsel;
12428 + uint8_t *buf;
12429 + struct nand_bbt_descr *td = this->bbt_td;
12430 + struct nand_bbt_descr *md = this->bbt_md;
12431 +
12432 + if (!this->bbt || !td)
12433 + return -EINVAL;
12434 +
12435 + len = mtd->size >> (this->bbt_erase_shift + 2);
12436 + /* Allocate a temporary buffer for one eraseblock incl. oob */
12437 + len = (1 << this->bbt_erase_shift);
12438 + len += (len >> this->page_shift) * mtd->oobsize;
12439 + buf = malloc (len);
12440 + if (!buf) {
12441 + puts ("nand_update_bbt: Out of memory\r\n");
12442 + return -ENOMEM;
12443 + }
12444 +
12445 + writeops = md != NULL ? 0x03 : 0x01;
12446 +
12447 + /* Do we have a bbt per chip ? */
12448 + if (td->options & NAND_BBT_PERCHIP) {
12449 + chip = (int) (offs >> this->chip_shift);
12450 + chipsel = chip;
12451 + } else {
12452 + chip = 0;
12453 + chipsel = -1;
12454 + }
12455 +
12456 + td->version[chip]++;
12457 + if (md)
12458 + md->version[chip]++;
12459 +
12460 + /* Write the bad block table to the device ? */
12461 + if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) {
12462 + res = write_bbt (mtd, buf, td, md, chipsel);
12463 + if (res < 0)
12464 + goto out;
12465 + }
12466 + /* Write the mirror bad block table to the device ? */
12467 + if ((writeops & 0x02) && md && (md->options & NAND_BBT_WRITE)) {
12468 + res = write_bbt (mtd, buf, md, td, chipsel);
12469 + }
12470 +
12471 +out:
12472 + free (buf);
12473 + return res;
12474 +}
12475 +
12476 +/* Define some generic bad / good block scan pattern which are used
12477 + * while scanning a device for factory marked good / bad blocks. */
12478 +static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
12479 +
12480 +static struct nand_bbt_descr smallpage_memorybased = {
12481 + .options = NAND_BBT_SCAN2NDPAGE,
12482 + .offs = 5,
12483 + .len = 1,
12484 + .pattern = scan_ff_pattern
12485 +};
12486 +
12487 +static struct nand_bbt_descr largepage_memorybased = {
12488 + .options = 0,
12489 + .offs = 0,
12490 + .len = 2,
12491 + .pattern = scan_ff_pattern
12492 +};
12493 +
12494 +static struct nand_bbt_descr smallpage_flashbased = {
12495 + .options = NAND_BBT_SCANEMPTY | NAND_BBT_SCANALLPAGES,
12496 + .offs = 5,
12497 + .len = 1,
12498 + .pattern = scan_ff_pattern
12499 +};
12500 +
12501 +static struct nand_bbt_descr largepage_flashbased = {
12502 + .options = NAND_BBT_SCANEMPTY | NAND_BBT_SCANALLPAGES,
12503 + .offs = 0,
12504 + .len = 2,
12505 + .pattern = scan_ff_pattern
12506 +};
12507 +
12508 +static uint8_t scan_agand_pattern[] = { 0x1C, 0x71, 0xC7, 0x1C, 0x71, 0xC7 };
12509 +
12510 +static struct nand_bbt_descr agand_flashbased = {
12511 + .options = NAND_BBT_SCANEMPTY | NAND_BBT_SCANALLPAGES,
12512 + .offs = 0x20,
12513 + .len = 6,
12514 + .pattern = scan_agand_pattern
12515 +};
12516 +
12517 +/* Generic flash bbt decriptors
12518 +*/
12519 +static uint8_t bbt_pattern[] = {'B', 'b', 't', '0' };
12520 +static uint8_t mirror_pattern[] = {'1', 't', 'b', 'B' };
12521 +
12522 +static struct nand_bbt_descr bbt_main_descr = {
12523 + .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
12524 + | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
12525 + .offs = 8,
12526 + .len = 4,
12527 + .veroffs = 12,
12528 + .maxblocks = 4,
12529 + .pattern = bbt_pattern
12530 +};
12531 +
12532 +static struct nand_bbt_descr bbt_mirror_descr = {
12533 + .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
12534 + | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
12535 + .offs = 8,
12536 + .len = 4,
12537 + .veroffs = 12,
12538 + .maxblocks = 4,
12539 + .pattern = mirror_pattern
12540 +};
12541 +
12542 +/**
12543 + * nand_default_bbt - [NAND Interface] Select a default bad block table for the device
12544 + * @mtd: MTD device structure
12545 + *
12546 + * This function selects the default bad block table
12547 + * support for the device and calls the nand_scan_bbt function
12548 + *
12549 +*/
12550 +int nand_default_bbt (struct mtd_info *mtd)
12551 +{
12552 + struct nand_chip *this = mtd->priv;
12553 +
12554 + /* Default for AG-AND. We must use a flash based
12555 + * bad block table as the devices have factory marked
12556 + * _good_ blocks. Erasing those blocks leads to loss
12557 + * of the good / bad information, so we _must_ store
12558 + * this information in a good / bad table during
12559 + * startup
12560 + */
12561 + if (this->options & NAND_IS_AND) {
12562 + /* Use the default pattern descriptors */
12563 + if (!this->bbt_td) {
12564 + this->bbt_td = &bbt_main_descr;
12565 + this->bbt_md = &bbt_mirror_descr;
12566 + }
12567 + this->options |= NAND_USE_FLASH_BBT;
12568 + return nand_scan_bbt (mtd, &agand_flashbased);
12569 + }
12570 +
12571 +
12572 + /* Is a flash based bad block table requested ? */
12573 + if (this->options & NAND_USE_FLASH_BBT) {
12574 + /* Use the default pattern descriptors */
12575 + if (!this->bbt_td) {
12576 + this->bbt_td = &bbt_main_descr;
12577 + this->bbt_md = &bbt_mirror_descr;
12578 + }
12579 + if (!this->badblock_pattern) {
12580 + this->badblock_pattern = (mtd->oobblock > 512) ?
12581 + &largepage_flashbased : &smallpage_flashbased;
12582 + }
12583 + } else {
12584 + this->bbt_td = NULL;
12585 + this->bbt_md = NULL;
12586 + if (!this->badblock_pattern) {
12587 + this->badblock_pattern = (mtd->oobblock > 512) ?
12588 + &largepage_memorybased : &smallpage_memorybased;
12589 + }
12590 + }
12591 + return nand_scan_bbt (mtd, this->badblock_pattern);
12592 +}
12593 +
12594 +/**
12595 + * nand_isbad_bbt - [NAND Interface] Check if a block is bad
12596 + * @mtd: MTD device structure
12597 + * @offs: offset in the device
12598 + * @allowbbt: allow access to bad block table region
12599 + *
12600 +*/
12601 +int nand_isbad_bbt (struct mtd_info *mtd, loff_t offs, int allowbbt)
12602 +{
12603 + struct nand_chip *this = mtd->priv;
12604 + int block;
12605 + uint8_t res;
12606 +
12607 + /* Get block number * 2 */
12608 + block = (int) (offs >> (this->bbt_erase_shift - 1));
12609 + res = (this->bbt[block >> 3] >> (block & 0x06)) & 0x03;
12610 +
12611 + DEBUG (MTD_DEBUG_LEVEL2, "nand_isbad_bbt(): bbt info for offs 0x%08x: (block %d) 0x%02x\n",
12612 + (unsigned int)offs, block >> 1, res);
12613 +
12614 + switch ((int)res) {
12615 + case 0x00: return 0;
12616 + case 0x01: return 1;
12617 + case 0x02: return allowbbt ? 0 : 1;
12618 + }
12619 + return 1;
12620 +}
12621 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/boot/rescue/nand_ecc.c linux-2.6.19.2.dev/arch/cris/arch-v32/boot/rescue/nand_ecc.c
12622 --- linux-2.6.19.2.old/arch/cris/arch-v32/boot/rescue/nand_ecc.c 1970-01-01 01:00:00.000000000 +0100
12623 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/boot/rescue/nand_ecc.c 2006-08-04 16:38:14.000000000 +0200
12624 @@ -0,0 +1,246 @@
12625 +/*
12626 + * This file contains an ECC algorithm from Toshiba that detects and
12627 + * corrects 1 bit errors in a 256 byte block of data.
12628 + *
12629 + * Taken from drivers/mtd/nand/nand_ecc.c, modified for
12630 + * NAND flash boot on Etrax FS.
12631 + *
12632 + * Copyright (C) 2000-2004 Steven J. Hill (sjhill@realitydiluted.com)
12633 + * Toshiba America Electronics Components, Inc.
12634 + *
12635 + * $Id: nand_ecc.c,v 1.1 2006/08/04 14:38:14 ricardw Exp $
12636 + *
12637 + * This file is free software; you can redistribute it and/or modify it
12638 + * under the terms of the GNU General Public License as published by the
12639 + * Free Software Foundation; either version 2 or (at your option) any
12640 + * later version.
12641 + *
12642 + * This file is distributed in the hope that it will be useful, but WITHOUT
12643 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12644 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12645 + * for more details.
12646 + *
12647 + * You should have received a copy of the GNU General Public License along
12648 + * with this file; if not, write to the Free Software Foundation, Inc.,
12649 + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
12650 + *
12651 + * As a special exception, if other files instantiate templates or use
12652 + * macros or inline functions from these files, or you compile these
12653 + * files and link them with other works to produce a work based on these
12654 + * files, these files do not by themselves cause the resulting work to be
12655 + * covered by the GNU General Public License. However the source code for
12656 + * these files must still be made available in accordance with section (3)
12657 + * of the GNU General Public License.
12658 + *
12659 + * This exception does not invalidate any other reasons why a work based on
12660 + * this file might be covered by the GNU General Public License.
12661 + */
12662 +
12663 +#include <linux/types.h>
12664 +#if 0
12665 +#include <linux/kernel.h>
12666 +#include <linux/module.h>
12667 +#endif
12668 +#include "nand_ecc.h"
12669 +
12670 +/*
12671 + * Pre-calculated 256-way 1 byte column parity
12672 + */
12673 +static const u_char nand_ecc_precalc_table[] = {
12674 + 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00,
12675 + 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
12676 + 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
12677 + 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
12678 + 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
12679 + 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
12680 + 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
12681 + 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
12682 + 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
12683 + 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
12684 + 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
12685 + 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
12686 + 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
12687 + 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
12688 + 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
12689 + 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00
12690 +};
12691 +
12692 +
12693 +/**
12694 + * nand_trans_result - [GENERIC] create non-inverted ECC
12695 + * @reg2: line parity reg 2
12696 + * @reg3: line parity reg 3
12697 + * @ecc_code: ecc
12698 + *
12699 + * Creates non-inverted ECC code from line parity
12700 + */
12701 +static void nand_trans_result(u_char reg2, u_char reg3,
12702 + u_char *ecc_code)
12703 +{
12704 + u_char a, b, i, tmp1, tmp2;
12705 +
12706 + /* Initialize variables */
12707 + a = b = 0x80;
12708 + tmp1 = tmp2 = 0;
12709 +
12710 + /* Calculate first ECC byte */
12711 + for (i = 0; i < 4; i++) {
12712 + if (reg3 & a) /* LP15,13,11,9 --> ecc_code[0] */
12713 + tmp1 |= b;
12714 + b >>= 1;
12715 + if (reg2 & a) /* LP14,12,10,8 --> ecc_code[0] */
12716 + tmp1 |= b;
12717 + b >>= 1;
12718 + a >>= 1;
12719 + }
12720 +
12721 + /* Calculate second ECC byte */
12722 + b = 0x80;
12723 + for (i = 0; i < 4; i++) {
12724 + if (reg3 & a) /* LP7,5,3,1 --> ecc_code[1] */
12725 + tmp2 |= b;
12726 + b >>= 1;
12727 + if (reg2 & a) /* LP6,4,2,0 --> ecc_code[1] */
12728 + tmp2 |= b;
12729 + b >>= 1;
12730 + a >>= 1;
12731 + }
12732 +
12733 + /* Store two of the ECC bytes */
12734 + ecc_code[0] = tmp1;
12735 + ecc_code[1] = tmp2;
12736 +}
12737 +
12738 +/**
12739 + * nand_calculate_ecc - [NAND Interface] Calculate 3 byte ECC code for 256 byte block
12740 + * @mtd: MTD block structure
12741 + * @dat: raw data
12742 + * @ecc_code: buffer for ECC
12743 + */
12744 +int nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code)
12745 +{
12746 + u_char idx, reg1, reg2, reg3;
12747 + int j;
12748 +
12749 + /* Initialize variables */
12750 + reg1 = reg2 = reg3 = 0;
12751 + ecc_code[0] = ecc_code[1] = ecc_code[2] = 0;
12752 +
12753 + /* Build up column parity */
12754 + for(j = 0; j < 256; j++) {
12755 +
12756 + /* Get CP0 - CP5 from table */
12757 + idx = nand_ecc_precalc_table[dat[j]];
12758 + reg1 ^= (idx & 0x3f);
12759 +
12760 + /* All bit XOR = 1 ? */
12761 + if (idx & 0x40) {
12762 + reg3 ^= (u_char) j;
12763 + reg2 ^= ~((u_char) j);
12764 + }
12765 + }
12766 +
12767 + /* Create non-inverted ECC code from line parity */
12768 + nand_trans_result(reg2, reg3, ecc_code);
12769 +
12770 + /* Calculate final ECC code */
12771 + ecc_code[0] = ~ecc_code[0];
12772 + ecc_code[1] = ~ecc_code[1];
12773 + ecc_code[2] = ((~reg1) << 2) | 0x03;
12774 + return 0;
12775 +}
12776 +
12777 +/**
12778 + * nand_correct_data - [NAND Interface] Detect and correct bit error(s)
12779 + * @mtd: MTD block structure
12780 + * @dat: raw data read from the chip
12781 + * @read_ecc: ECC from the chip
12782 + * @calc_ecc: the ECC calculated from raw data
12783 + *
12784 + * Detect and correct a 1 bit error for 256 byte block
12785 + */
12786 +int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc)
12787 +{
12788 + u_char a, b, c, d1, d2, d3, add, bit, i;
12789 +
12790 + /* Do error detection */
12791 + d1 = calc_ecc[0] ^ read_ecc[0];
12792 + d2 = calc_ecc[1] ^ read_ecc[1];
12793 + d3 = calc_ecc[2] ^ read_ecc[2];
12794 +
12795 + if ((d1 | d2 | d3) == 0) {
12796 + /* No errors */
12797 + return 0;
12798 + }
12799 + else {
12800 + a = (d1 ^ (d1 >> 1)) & 0x55;
12801 + b = (d2 ^ (d2 >> 1)) & 0x55;
12802 + c = (d3 ^ (d3 >> 1)) & 0x54;
12803 +
12804 + /* Found and will correct single bit error in the data */
12805 + if ((a == 0x55) && (b == 0x55) && (c == 0x54)) {
12806 + c = 0x80;
12807 + add = 0;
12808 + a = 0x80;
12809 + for (i=0; i<4; i++) {
12810 + if (d1 & c)
12811 + add |= a;
12812 + c >>= 2;
12813 + a >>= 1;
12814 + }
12815 + c = 0x80;
12816 + for (i=0; i<4; i++) {
12817 + if (d2 & c)
12818 + add |= a;
12819 + c >>= 2;
12820 + a >>= 1;
12821 + }
12822 + bit = 0;
12823 + b = 0x04;
12824 + c = 0x80;
12825 + for (i=0; i<3; i++) {
12826 + if (d3 & c)
12827 + bit |= b;
12828 + c >>= 2;
12829 + b >>= 1;
12830 + }
12831 + b = 0x01;
12832 + a = dat[add];
12833 + a ^= (b << bit);
12834 + dat[add] = a;
12835 + return 1;
12836 + }
12837 + else {
12838 + i = 0;
12839 + while (d1) {
12840 + if (d1 & 0x01)
12841 + ++i;
12842 + d1 >>= 1;
12843 + }
12844 + while (d2) {
12845 + if (d2 & 0x01)
12846 + ++i;
12847 + d2 >>= 1;
12848 + }
12849 + while (d3) {
12850 + if (d3 & 0x01)
12851 + ++i;
12852 + d3 >>= 1;
12853 + }
12854 + if (i == 1) {
12855 + /* ECC Code Error Correction */
12856 + read_ecc[0] = calc_ecc[0];
12857 + read_ecc[1] = calc_ecc[1];
12858 + read_ecc[2] = calc_ecc[2];
12859 + return 2;
12860 + }
12861 + else {
12862 + /* Uncorrectable Error */
12863 + return -1;
12864 + }
12865 + }
12866 + }
12867 +
12868 + /* Should never happen */
12869 + return -1;
12870 +}
12871 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/boot/rescue/nand_ecc.h linux-2.6.19.2.dev/arch/cris/arch-v32/boot/rescue/nand_ecc.h
12872 --- linux-2.6.19.2.old/arch/cris/arch-v32/boot/rescue/nand_ecc.h 1970-01-01 01:00:00.000000000 +0100
12873 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/boot/rescue/nand_ecc.h 2006-08-04 16:38:14.000000000 +0200
12874 @@ -0,0 +1,30 @@
12875 +/*
12876 + * drivers/mtd/nand_ecc.h
12877 + *
12878 + * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
12879 + *
12880 + * $Id: nand_ecc.h,v 1.1 2006/08/04 14:38:14 ricardw Exp $
12881 + *
12882 + * This program is free software; you can redistribute it and/or modify
12883 + * it under the terms of the GNU General Public License version 2 as
12884 + * published by the Free Software Foundation.
12885 + *
12886 + * This file is the header for the ECC algorithm.
12887 + */
12888 +
12889 +#ifndef __MTD_NAND_ECC_H__
12890 +#define __MTD_NAND_ECC_H__
12891 +
12892 +struct mtd_info;
12893 +
12894 +/*
12895 + * Calculate 3 byte ECC code for 256 byte block
12896 + */
12897 +int nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code);
12898 +
12899 +/*
12900 + * Detect and correct a 1 bit error for 256 byte block
12901 + */
12902 +int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc);
12903 +
12904 +#endif /* __MTD_NAND_ECC_H__ */
12905 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/boot/rescue/nand_ids.c linux-2.6.19.2.dev/arch/cris/arch-v32/boot/rescue/nand_ids.c
12906 --- linux-2.6.19.2.old/arch/cris/arch-v32/boot/rescue/nand_ids.c 1970-01-01 01:00:00.000000000 +0100
12907 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/boot/rescue/nand_ids.c 2006-08-04 16:38:14.000000000 +0200
12908 @@ -0,0 +1,133 @@
12909 +/*
12910 + * drivers/mtd/nandids.c
12911 + *
12912 + * Copyright (C) 2002 Thomas Gleixner (tglx@linutronix.de)
12913 + *
12914 + * $Id: nand_ids.c,v 1.1 2006/08/04 14:38:14 ricardw Exp $
12915 + *
12916 + * This program is free software; you can redistribute it and/or modify
12917 + * it under the terms of the GNU General Public License version 2 as
12918 + * published by the Free Software Foundation.
12919 + *
12920 + */
12921 +#if 0
12922 +#include <linux/module.h>
12923 +#endif
12924 +
12925 +#include "nand.h"
12926 +/*
12927 +* Chip ID list
12928 +*
12929 +* Name. ID code, pagesize, chipsize in MegaByte, eraseblock size,
12930 +* options
12931 +*
12932 +* Pagesize; 0, 256, 512
12933 +* 0 get this information from the extended chip ID
12934 ++ 256 256 Byte page size
12935 +* 512 512 Byte page size
12936 +*/
12937 +struct nand_flash_dev nand_flash_ids[] = {
12938 + {"NAND 1MiB 5V 8-bit", 0x6e, 256, 1, 0x1000, 0},
12939 + {"NAND 2MiB 5V 8-bit", 0x64, 256, 2, 0x1000, 0},
12940 + {"NAND 4MiB 5V 8-bit", 0x6b, 512, 4, 0x2000, 0},
12941 + {"NAND 1MiB 3,3V 8-bit", 0xe8, 256, 1, 0x1000, 0},
12942 + {"NAND 1MiB 3,3V 8-bit", 0xec, 256, 1, 0x1000, 0},
12943 + {"NAND 2MiB 3,3V 8-bit", 0xea, 256, 2, 0x1000, 0},
12944 + {"NAND 4MiB 3,3V 8-bit", 0xd5, 512, 4, 0x2000, 0},
12945 + {"NAND 4MiB 3,3V 8-bit", 0xe3, 512, 4, 0x2000, 0},
12946 + {"NAND 4MiB 3,3V 8-bit", 0xe5, 512, 4, 0x2000, 0},
12947 + {"NAND 8MiB 3,3V 8-bit", 0xd6, 512, 8, 0x2000, 0},
12948 +
12949 + {"NAND 8MiB 1,8V 8-bit", 0x39, 512, 8, 0x2000, 0},
12950 + {"NAND 8MiB 3,3V 8-bit", 0xe6, 512, 8, 0x2000, 0},
12951 + {"NAND 8MiB 1,8V 16-bit", 0x49, 512, 8, 0x2000, NAND_BUSWIDTH_16},
12952 + {"NAND 8MiB 3,3V 16-bit", 0x59, 512, 8, 0x2000, NAND_BUSWIDTH_16},
12953 +
12954 + {"NAND 16MiB 1,8V 8-bit", 0x33, 512, 16, 0x4000, 0},
12955 + {"NAND 16MiB 3,3V 8-bit", 0x73, 512, 16, 0x4000, 0},
12956 + {"NAND 16MiB 1,8V 16-bit", 0x43, 512, 16, 0x4000, NAND_BUSWIDTH_16},
12957 + {"NAND 16MiB 3,3V 16-bit", 0x53, 512, 16, 0x4000, NAND_BUSWIDTH_16},
12958 +
12959 + {"NAND 32MiB 1,8V 8-bit", 0x35, 512, 32, 0x4000, 0},
12960 + {"NAND 32MiB 3,3V 8-bit", 0x75, 512, 32, 0x4000, 0},
12961 + {"NAND 32MiB 1,8V 16-bit", 0x45, 512, 32, 0x4000, NAND_BUSWIDTH_16},
12962 + {"NAND 32MiB 3,3V 16-bit", 0x55, 512, 32, 0x4000, NAND_BUSWIDTH_16},
12963 +
12964 + {"NAND 64MiB 1,8V 8-bit", 0x36, 512, 64, 0x4000, 0},
12965 + {"NAND 64MiB 3,3V 8-bit", 0x76, 512, 64, 0x4000, 0},
12966 + {"NAND 64MiB 1,8V 16-bit", 0x46, 512, 64, 0x4000, NAND_BUSWIDTH_16},
12967 + {"NAND 64MiB 3,3V 16-bit", 0x56, 512, 64, 0x4000, NAND_BUSWIDTH_16},
12968 +
12969 + {"NAND 128MiB 1,8V 8-bit", 0x78, 512, 128, 0x4000, 0},
12970 + {"NAND 128MiB 1,8V 8-bit", 0x39, 512, 128, 0x4000, 0},
12971 + {"NAND 128MiB 3,3V 8-bit", 0x79, 512, 128, 0x4000, 0},
12972 + {"NAND 128MiB 1,8V 16-bit", 0x72, 512, 128, 0x4000, NAND_BUSWIDTH_16},
12973 + {"NAND 128MiB 1,8V 16-bit", 0x49, 512, 128, 0x4000, NAND_BUSWIDTH_16},
12974 + {"NAND 128MiB 3,3V 16-bit", 0x74, 512, 128, 0x4000, NAND_BUSWIDTH_16},
12975 + {"NAND 128MiB 3,3V 16-bit", 0x59, 512, 128, 0x4000, NAND_BUSWIDTH_16},
12976 +
12977 + {"NAND 256MiB 3,3V 8-bit", 0x71, 512, 256, 0x4000, 0},
12978 +
12979 + /* These are the new chips with large page size. The pagesize
12980 + * and the erasesize is determined from the extended id bytes
12981 + */
12982 + /*512 Megabit */
12983 + {"NAND 64MiB 1,8V 8-bit", 0xA2, 0, 64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
12984 + {"NAND 64MiB 3,3V 8-bit", 0xF2, 0, 64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
12985 + {"NAND 64MiB 1,8V 16-bit", 0xB2, 0, 64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
12986 + {"NAND 64MiB 3,3V 16-bit", 0xC2, 0, 64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
12987 +
12988 + /* 1 Gigabit */
12989 + {"NAND 128MiB 1,8V 8-bit", 0xA1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
12990 + {"NAND 128MiB 3,3V 8-bit", 0xF1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
12991 + {"NAND 128MiB 1,8V 16-bit", 0xB1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
12992 + {"NAND 128MiB 3,3V 16-bit", 0xC1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
12993 +
12994 + /* 2 Gigabit */
12995 + {"NAND 256MiB 1,8V 8-bit", 0xAA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
12996 + {"NAND 256MiB 3,3V 8-bit", 0xDA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
12997 + {"NAND 256MiB 1,8V 16-bit", 0xBA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
12998 + {"NAND 256MiB 3,3V 16-bit", 0xCA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
12999 +
13000 + /* 4 Gigabit */
13001 + {"NAND 512MiB 1,8V 8-bit", 0xAC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
13002 + {"NAND 512MiB 3,3V 8-bit", 0xDC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
13003 + {"NAND 512MiB 1,8V 16-bit", 0xBC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
13004 + {"NAND 512MiB 3,3V 16-bit", 0xCC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
13005 +
13006 + /* 8 Gigabit */
13007 + {"NAND 1GiB 1,8V 8-bit", 0xA3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
13008 + {"NAND 1GiB 3,3V 8-bit", 0xD3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
13009 + {"NAND 1GiB 1,8V 16-bit", 0xB3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
13010 + {"NAND 1GiB 3,3V 16-bit", 0xC3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
13011 +
13012 + /* 16 Gigabit */
13013 + {"NAND 2GiB 1,8V 8-bit", 0xA5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
13014 + {"NAND 2GiB 3,3V 8-bit", 0xD5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
13015 + {"NAND 2GiB 1,8V 16-bit", 0xB5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
13016 + {"NAND 2GiB 3,3V 16-bit", 0xC5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
13017 +
13018 + /* Renesas AND 1 Gigabit. Those chips do not support extended id and have a strange page/block layout !
13019 + * The chosen minimum erasesize is 4 * 2 * 2048 = 16384 Byte, as those chips have an array of 4 page planes
13020 + * 1 block = 2 pages, but due to plane arrangement the blocks 0-3 consists of page 0 + 4,1 + 5, 2 + 6, 3 + 7
13021 + * Anyway JFFS2 would increase the eraseblock size so we chose a combined one which can be erased in one go
13022 + * There are more speed improvements for reads and writes possible, but not implemented now
13023 + */
13024 + {"AND 128MiB 3,3V 8-bit", 0x01, 2048, 128, 0x4000, NAND_IS_AND | NAND_NO_AUTOINCR | NAND_4PAGE_ARRAY | BBT_AUTO_REFRESH},
13025 +
13026 + {NULL,}
13027 +};
13028 +
13029 +/*
13030 +* Manufacturer ID list
13031 +*/
13032 +struct nand_manufacturers nand_manuf_ids[] = {
13033 + {NAND_MFR_TOSHIBA, "Toshiba"},
13034 + {NAND_MFR_SAMSUNG, "Samsung"},
13035 + {NAND_MFR_FUJITSU, "Fujitsu"},
13036 + {NAND_MFR_NATIONAL, "National"},
13037 + {NAND_MFR_RENESAS, "Renesas"},
13038 + {NAND_MFR_STMICRO, "ST Micro"},
13039 + {NAND_MFR_HYNIX, "Hynix"},
13040 + {0x0, "Unknown"}
13041 +};
13042 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/boot/rescue/rescue.ld linux-2.6.19.2.dev/arch/cris/arch-v32/boot/rescue/rescue.ld
13043 --- linux-2.6.19.2.old/arch/cris/arch-v32/boot/rescue/rescue.ld 2007-01-10 20:10:37.000000000 +0100
13044 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/boot/rescue/rescue.ld 2006-10-18 10:52:47.000000000 +0200
13045 @@ -1,20 +1,40 @@
13046 -MEMORY
13047 +/*#OUTPUT_FORMAT(elf32-us-cris) */
13048 +OUTPUT_ARCH (crisv32)
13049 +
13050 +MEMORY
13051 {
13052 - flash : ORIGIN = 0x00000000,
13053 - LENGTH = 0x00100000
13054 + bootblk : ORIGIN = 0x38000000,
13055 + LENGTH = 0x00004000
13056 + intmem : ORIGIN = 0x38004000,
13057 + LENGTH = 0x00005000
13058 }
13059
13060 SECTIONS
13061 {
13062 .text :
13063 {
13064 - stext = . ;
13065 + _stext = . ;
13066 *(.text)
13067 - etext = . ;
13068 - } > flash
13069 + *(.rodata)
13070 + *(.rodata.*)
13071 + _etext = . ;
13072 + } > bootblk
13073 .data :
13074 {
13075 *(.data)
13076 - edata = . ;
13077 - } > flash
13078 + _edata = . ;
13079 + } > bootblk
13080 + .bss :
13081 + {
13082 + _bss = . ;
13083 + *(.bss)
13084 + _end = ALIGN( 0x10 ) ;
13085 + } > intmem
13086 +
13087 + /* Get rid of stuff from EXPORT_SYMBOL(foo). */
13088 + /DISCARD/ :
13089 + {
13090 + *(__ksymtab_strings)
13091 + *(__ksymtab)
13092 + }
13093 }
13094 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/drivers/Kconfig linux-2.6.19.2.dev/arch/cris/arch-v32/drivers/Kconfig
13095 --- linux-2.6.19.2.old/arch/cris/arch-v32/drivers/Kconfig 2007-01-10 20:10:37.000000000 +0100
13096 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/drivers/Kconfig 2007-01-29 16:14:16.000000000 +0100
13097 @@ -6,14 +6,6 @@
13098 This option enables the ETRAX FS built-in 10/100Mbit Ethernet
13099 controller.
13100
13101 -config ETRAX_ETHERNET_HW_CSUM
13102 - bool "Hardware accelerated ethernet checksum and scatter/gather"
13103 - depends on ETRAX_ETHERNET
13104 - depends on ETRAX_STREAMCOPROC
13105 - default y
13106 - help
13107 - Hardware acceleration of checksumming and scatter/gather
13108 -
13109 config ETRAX_ETHERNET_IFACE0
13110 depends on ETRAX_ETHERNET
13111 bool "Enable network interface 0"
13112 @@ -23,6 +15,52 @@
13113 bool "Enable network interface 1 (uses DMA6 and DMA7)"
13114
13115 choice
13116 + prompt "Eth0 led group"
13117 + depends on ETRAX_ETHERNET_IFACE0
13118 + default ETRAX_ETH0_USE_LEDGRP0
13119 +
13120 +config ETRAX_ETH0_USE_LEDGRP0
13121 + bool "Use LED grp 0"
13122 + depends on ETRAX_NBR_LED_GRP_ONE || ETRAX_NBR_LED_GRP_TWO
13123 + help
13124 + Use LED grp 0 for eth0
13125 +
13126 +config ETRAX_ETH0_USE_LEDGRP1
13127 + bool "Use LED grp 1"
13128 + depends on ETRAX_NBR_LED_GRP_TWO
13129 + help
13130 + Use LED grp 1 for eth0
13131 +
13132 +config ETRAX_ETH0_USE_LEDGRPNULL
13133 + bool "Use no LEDs for eth0"
13134 + help
13135 + Use no LEDs for eth0
13136 +endchoice
13137 +
13138 +choice
13139 + prompt "Eth1 led group"
13140 + depends on ETRAX_ETHERNET_IFACE1
13141 + default ETRAX_ETH1_USE_LEDGRP1
13142 +
13143 +config ETRAX_ETH1_USE_LEDGRP0
13144 + bool "Use LED grp 0"
13145 + depends on ETRAX_NBR_LED_GRP_ONE || ETRAX_NBR_LED_GRP_TWO
13146 + help
13147 + Use LED grp 0 for eth1
13148 +
13149 +config ETRAX_ETH1_USE_LEDGRP1
13150 + bool "Use LED grp 1"
13151 + depends on ETRAX_NBR_LED_GRP_TWO
13152 + help
13153 + Use LED grp 1 for eth1
13154 +
13155 +config ETRAX_ETH1_USE_LEDGRPNULL
13156 + bool "Use no LEDs for eth1"
13157 + help
13158 + Use no LEDs for eth1
13159 +endchoice
13160 +
13161 +choice
13162 prompt "Network LED behavior"
13163 depends on ETRAX_ETHERNET
13164 default ETRAX_NETWORK_LED_ON_WHEN_ACTIVITY
13165 @@ -56,10 +94,25 @@
13166 config ETRAXFS_SERIAL
13167 bool "Serial-port support"
13168 depends on ETRAX_ARCH_V32
13169 + select SERIAL_CORE
13170 + select SERIAL_CORE_CONSOLE
13171 help
13172 Enables the ETRAX FS serial driver for ser0 (ttyS0)
13173 You probably want this enabled.
13174
13175 +config ETRAX_RS485
13176 + bool "RS-485 support"
13177 + depends on ETRAXFS_SERIAL
13178 + help
13179 + Enables support for RS-485 serial communication.
13180 +
13181 +config ETRAX_RS485_DISABLE_RECEIVER
13182 + bool "Disable serial receiver"
13183 + depends on ETRAX_RS485
13184 + help
13185 + It is necessary to disable the serial receiver to avoid serial
13186 + loopback. Not all products are able to do this in software only.
13187 +
13188 config ETRAX_SERIAL_PORT0
13189 bool "Serial port 0 enabled"
13190 depends on ETRAXFS_SERIAL
13191 @@ -70,6 +123,31 @@
13192 ser0 can use dma4 or dma6 for output and dma5 or dma7 for input.
13193
13194 choice
13195 + prompt "Ser0 default port type "
13196 + depends on ETRAX_SERIAL_PORT0
13197 + default ETRAX_SERIAL_PORT0_TYPE_232
13198 + help
13199 + Type of serial port.
13200 +
13201 +config ETRAX_SERIAL_PORT0_TYPE_232
13202 + bool "Ser0 is a RS-232 port"
13203 + help
13204 + Configure serial port 0 to be a RS-232 port.
13205 +
13206 +config ETRAX_SERIAL_PORT0_TYPE_485HD
13207 + bool "Ser0 is a half duplex RS-485 port"
13208 + depends on ETRAX_RS485
13209 + help
13210 + Configure serial port 0 to be a half duplex (two wires) RS-485 port.
13211 +
13212 +config ETRAX_SERIAL_PORT0_TYPE_485FD
13213 + bool "Ser0 is a full duplex RS-485 port"
13214 + depends on ETRAX_RS485
13215 + help
13216 + Configure serial port 0 to be a full duplex (four wires) RS-485 port.
13217 +endchoice
13218 +
13219 +choice
13220 prompt "Ser0 DMA in channel "
13221 depends on ETRAX_SERIAL_PORT0
13222 default ETRAX_SERIAL_PORT0_NO_DMA_IN
13223 @@ -139,6 +217,31 @@
13224 Enables the ETRAX FS serial driver for ser1 (ttyS1).
13225
13226 choice
13227 + prompt "Ser1 default port type"
13228 + depends on ETRAX_SERIAL_PORT1
13229 + default ETRAX_SERIAL_PORT1_TYPE_232
13230 + help
13231 + Type of serial port.
13232 +
13233 +config ETRAX_SERIAL_PORT1_TYPE_232
13234 + bool "Ser1 is a RS-232 port"
13235 + help
13236 + Configure serial port 1 to be a RS-232 port.
13237 +
13238 +config ETRAX_SERIAL_PORT1_TYPE_485HD
13239 + bool "Ser1 is a half duplex RS-485 port"
13240 + depends on ETRAX_RS485
13241 + help
13242 + Configure serial port 1 to be a half duplex (two wires) RS-485 port.
13243 +
13244 +config ETRAX_SERIAL_PORT1_TYPE_485FD
13245 + bool "Ser1 is a full duplex RS-485 port"
13246 + depends on ETRAX_RS485
13247 + help
13248 + Configure serial port 1 to be a full duplex (four wires) RS-485 port.
13249 +endchoice
13250 +
13251 +choice
13252 prompt "Ser1 DMA in channel "
13253 depends on ETRAX_SERIAL_PORT1
13254 default ETRAX_SERIAL_PORT1_NO_DMA_IN
13255 @@ -210,6 +313,31 @@
13256 Enables the ETRAX FS serial driver for ser2 (ttyS2).
13257
13258 choice
13259 + prompt "Ser2 default port type"
13260 + depends on ETRAX_SERIAL_PORT2
13261 + default ETRAX_SERIAL_PORT2_TYPE_232
13262 + help
13263 + What DMA channel to use for ser2
13264 +
13265 +config ETRAX_SERIAL_PORT2_TYPE_232
13266 + bool "Ser2 is a RS-232 port"
13267 + help
13268 + Configure serial port 2 to be a RS-232 port.
13269 +
13270 +config ETRAX_SERIAL_PORT2_TYPE_485HD
13271 + bool "Ser2 is a half duplex RS-485 port"
13272 + depends on ETRAX_RS485
13273 + help
13274 + Configure serial port 2 to be a half duplex (two wires) RS-485 port.
13275 +
13276 +config ETRAX_SERIAL_PORT2_TYPE_485FD
13277 + bool "Ser2 is a full duplex RS-485 port"
13278 + depends on ETRAX_RS485
13279 + help
13280 + Configure serial port 2 to be a full duplex (four wires) RS-485 port.
13281 +endchoice
13282 +
13283 +choice
13284 prompt "Ser2 DMA in channel "
13285 depends on ETRAX_SERIAL_PORT2
13286 default ETRAX_SERIAL_PORT2_NO_DMA_IN
13287 @@ -279,6 +407,31 @@
13288 Enables the ETRAX FS serial driver for ser3 (ttyS3).
13289
13290 choice
13291 + prompt "Ser3 default port type"
13292 + depends on ETRAX_SERIAL_PORT3
13293 + default ETRAX_SERIAL_PORT3_TYPE_232
13294 + help
13295 + What DMA channel to use for ser3.
13296 +
13297 +config ETRAX_SERIAL_PORT3_TYPE_232
13298 + bool "Ser3 is a RS-232 port"
13299 + help
13300 + Configure serial port 3 to be a RS-232 port.
13301 +
13302 +config ETRAX_SERIAL_PORT3_TYPE_485HD
13303 + bool "Ser3 is a half duplex RS-485 port"
13304 + depends on ETRAX_RS485
13305 + help
13306 + Configure serial port 3 to be a half duplex (two wires) RS-485 port.
13307 +
13308 +config ETRAX_SERIAL_PORT3_TYPE_485FD
13309 + bool "Ser3 is a full duplex RS-485 port"
13310 + depends on ETRAX_RS485
13311 + help
13312 + Configure serial port 3 to be a full duplex (four wires) RS-485 port.
13313 +endchoice
13314 +
13315 +choice
13316 prompt "Ser3 DMA in channel "
13317 depends on ETRAX_SERIAL_PORT3
13318 default ETRAX_SERIAL_PORT3_NO_DMA_IN
13319 @@ -341,38 +494,6 @@
13320 string "Ser 3 CD bit (empty = not used)"
13321 depends on ETRAX_SERIAL_PORT3
13322
13323 -config ETRAX_RS485
13324 - bool "RS-485 support"
13325 - depends on ETRAX_SERIAL
13326 - help
13327 - Enables support for RS-485 serial communication. For a primer on
13328 - RS-485, see <http://www.hw.cz/english/docs/rs485/rs485.html>.
13329 -
13330 -config ETRAX_RS485_DISABLE_RECEIVER
13331 - bool "Disable serial receiver"
13332 - depends on ETRAX_RS485
13333 - help
13334 - It is necessary to disable the serial receiver to avoid serial
13335 - loopback. Not all products are able to do this in software only.
13336 - Axis 2400/2401 must disable receiver.
13337 -
13338 -config ETRAX_AXISFLASHMAP
13339 - bool "Axis flash-map support"
13340 - depends on ETRAX_ARCH_V32
13341 - select MTD
13342 - select MTD_CFI
13343 - select MTD_CFI_AMDSTD
13344 - select MTD_OBSOLETE_CHIPS
13345 - select MTD_AMDSTD
13346 - select MTD_CHAR
13347 - select MTD_BLOCK
13348 - select MTD_PARTITIONS
13349 - select MTD_CONCAT
13350 - select MTD_COMPLEX_MAPPINGS
13351 - help
13352 - This option enables MTD mapping of flash devices. Needed to use
13353 - flash memories. If unsure, say Y.
13354 -
13355 config ETRAX_SYNCHRONOUS_SERIAL
13356 bool "Synchronous serial-port support"
13357 depends on ETRAX_ARCH_V32
13358 @@ -405,6 +526,31 @@
13359 A synchronous serial port can run in manual or DMA mode.
13360 Selecting this option will make it run in DMA mode.
13361
13362 +config ETRAX_AXISFLASHMAP
13363 + bool "Axis flash-map support"
13364 + depends on ETRAX_ARCH_V32
13365 + select MTD
13366 + select MTD_CFI
13367 + select MTD_CFI_AMDSTD
13368 + select MTD_JEDECPROBE
13369 + select MTD_CHAR
13370 + select MTD_BLOCK
13371 + select MTD_PARTITIONS
13372 + select MTD_CONCAT
13373 + select MTD_COMPLEX_MAPPINGS
13374 + help
13375 + This option enables MTD mapping of flash devices. Needed to use
13376 + flash memories. If unsure, say Y.
13377 +
13378 +config ETRAX_AXISFLASHMAP_MTD0WHOLE
13379 + bool "MTD0 is whole boot flash device"
13380 + depends on ETRAX_AXISFLASHMAP
13381 + default N
13382 + help
13383 + When this option is not set, mtd0 refers to the first partition
13384 + on the boot flash device. When set, mtd0 refers to the whole
13385 + device, with mtd1 referring to the first partition etc.
13386 +
13387 config ETRAX_PTABLE_SECTOR
13388 int "Byte-offset of partition table sector"
13389 depends on ETRAX_AXISFLASHMAP
13390 @@ -425,11 +571,19 @@
13391 This option enables MTD mapping of NAND flash devices. Needed to use
13392 NAND flash memories. If unsure, say Y.
13393
13394 +config ETRAX_NANDBOOT
13395 + bool "Boot from NAND flash"
13396 + depends on ETRAX_NANDFLASH
13397 + help
13398 + This options enables booting from NAND flash devices.
13399 + Say Y if your boot code, kernel and root file system is in
13400 + NAND flash. Say N if they are in NOR flash.
13401 +
13402 config ETRAX_I2C
13403 bool "I2C driver"
13404 depends on ETRAX_ARCH_V32
13405 help
13406 - This option enabled the I2C driver used by e.g. the RTC driver.
13407 + This option enables the I2C driver used by e.g. the RTC driver.
13408
13409 config ETRAX_I2C_DATA_PORT
13410 string "I2C data pin"
13411 @@ -476,18 +630,19 @@
13412 Remember that you need to setup the port directions appropriately in
13413 the General configuration.
13414
13415 -config ETRAX_PA_BUTTON_BITMASK
13416 - hex "PA-buttons bitmask"
13417 +config ETRAX_VIRTUAL_GPIO
13418 + bool "Virtual GPIO support"
13419 depends on ETRAX_GPIO
13420 - default "0x02"
13421 help
13422 - This is a bitmask (8 bits) with information about what bits on PA
13423 - that are used for buttons.
13424 - Most products has a so called TEST button on PA1, if that is true
13425 - use 0x02 here.
13426 - Use 00 if there are no buttons on PA.
13427 - If the bitmask is <> 00 a button driver will be included in the gpio
13428 - driver. ETRAX general I/O support must be enabled.
13429 + Enables the virtual Etrax general port device (major 120, minor 6).
13430 + It uses an I/O expander for the I2C-bus.
13431 +
13432 +config ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN
13433 + int "Virtual GPIO interrupt pin on PA pin"
13434 + range 0 7
13435 + depends on ETRAX_VIRTUAL_GPIO
13436 + help
13437 + The pin to use on PA for virtual gpio interrupt.
13438
13439 config ETRAX_PA_CHANGEABLE_DIR
13440 hex "PA user changeable dir mask"
13441 @@ -584,6 +739,25 @@
13442 that a user can change the value on using ioctl's.
13443 Bit set = changeable.
13444
13445 +config ETRAX_PV_CHANGEABLE_DIR
13446 + hex "PV user changeable dir mask"
13447 + depends on ETRAX_VIRTUAL_GPIO
13448 + default "0x0000"
13449 + help
13450 + This is a bitmask (16 bits) with information of what bits in PV
13451 + that a user can change direction on using ioctl's.
13452 + Bit set = changeable.
13453 + You probably want 0x0000 here, but it depends on your hardware.
13454 +
13455 +config ETRAX_PV_CHANGEABLE_BITS
13456 + hex "PV user changeable bits mask"
13457 + depends on ETRAX_VIRTUAL_GPIO
13458 + default "0x0000"
13459 + help
13460 + This is a bitmask (16 bits) with information of what bits in PV
13461 + that a user can change the value on using ioctl's.
13462 + Bit set = changeable.
13463 +
13464 config ETRAX_IDE
13465 bool "ATA/IDE support"
13466 depends on ETRAX_ARCH_V32
13467 @@ -603,11 +777,11 @@
13468 select HOTPLUG
13469 select PCCARD_NONSTATIC
13470 help
13471 - Enabled the ETRAX Carbus driver.
13472 + Enabled the ETRAX Carbus driver.
13473
13474 config PCI
13475 bool
13476 - depends on ETRAX_CARDBUS
13477 + depends on ETRAX_CARDBUS
13478 default y
13479
13480 config ETRAX_IOP_FW_LOAD
13481 @@ -623,3 +797,175 @@
13482 help
13483 This option enables a driver for the stream co-processor
13484 for cryptographic operations.
13485 +
13486 +source drivers/mmc/Kconfig
13487 +
13488 +config ETRAX_SPI_MMC
13489 +# Make this one of several "choices" (possible simultaneously but
13490 +# suggested uniquely) when an IOP driver emerges for "real" MMC/SD
13491 +# protocol support.
13492 + tristate
13493 + depends on MMC
13494 + default MMC
13495 + select SPI
13496 + select MMC_SPI
13497 + select ETRAX_SPI_MMC_BOARD
13498 +
13499 +# For the parts that can't be a module (due to restrictions in
13500 +# framework elsewhere).
13501 +config ETRAX_SPI_MMC_BOARD
13502 + boolean
13503 + default n
13504 +
13505 +# While the board info is MMC_SPI only, the drivers are written to be
13506 +# independent of MMC_SPI, so we'll keep SPI non-dependent on the
13507 +# MMC_SPI config choices (well, except for a single depends-on-line
13508 +# for the board-info file until a separate non-MMC SPI board file
13509 +# emerges).
13510 +# FIXME: When that happens, we'll need to be able to ask for and
13511 +# configure non-MMC SPI ports together with MMC_SPI ports (if multiple
13512 +# SPI ports are enabled).
13513 +
13514 +config ETRAX_SPI_SSER0
13515 + tristate "SPI using synchronous serial port 0 (sser0)"
13516 + depends on ETRAX_SPI_MMC
13517 + default m if MMC_SPI=m
13518 + default y if MMC_SPI=y
13519 + default y if MMC_SPI=n
13520 + select SPI_ETRAX_SSER
13521 + help
13522 + Say Y for an MMC/SD socket connected to synchronous serial port 0,
13523 + or for devices using the SPI protocol on that port. Say m if you
13524 + want to build it as a module, which will be named spi_crisv32_sser.
13525 + (You need to select MMC separately.)
13526 +
13527 +config ETRAX_SPI_SSER0_DMA
13528 + bool "DMA for SPI on sser0 enabled"
13529 + depends on ETRAX_SPI_SSER0
13530 + depends on !ETRAX_SERIAL_PORT1_DMA4_OUT && !ETRAX_SERIAL_PORT1_DMA5_IN
13531 + default y
13532 + help
13533 + Say Y if using DMA (dma4/dma5) for SPI on synchronous serial port 0.
13534 +
13535 +config ETRAX_SPI_MMC_CD_SSER0_PIN
13536 + string "MMC/SD card detect pin for SPI on sser0"
13537 + depends on ETRAX_SPI_SSER0 && MMC_SPI
13538 + default "pd11"
13539 + help
13540 + The pin to use for SD/MMC card detect. This pin should be pulled up
13541 + and grounded when a card is present. If defined as " " (space), no
13542 + pin is selected. A card must then always be inserted for proper
13543 + action.
13544 +
13545 +config ETRAX_SPI_MMC_WP_SSER0_PIN
13546 + string "MMC/SD card write-protect pin for SPI on sser0"
13547 + depends on ETRAX_SPI_SSER0 && MMC_SPI
13548 + default "pd10"
13549 + help
13550 + The pin to use for the SD/MMC write-protect signal for a memory
13551 + card. If defined as " " (space), the card is considered writable.
13552 +
13553 +config ETRAX_SPI_SSER1
13554 + tristate "SPI using synchronous serial port 1 (sser1)"
13555 + depends on ETRAX_SPI_MMC
13556 + default m if MMC_SPI=m && ETRAX_SPI_SSER0=n
13557 + default y if MMC_SPI=y && ETRAX_SPI_SSER0=n
13558 + default y if MMC_SPI=n && ETRAX_SPI_SSER0=n
13559 + select SPI_ETRAX_SSER
13560 + help
13561 + Say Y for an MMC/SD socket connected to synchronous serial port 1,
13562 + or for devices using the SPI protocol on that port. Say m if you
13563 + want to build it as a module, which will be named spi_crisv32_sser.
13564 + (You need to select MMC separately.)
13565 +
13566 +config ETRAX_SPI_SSER1_DMA
13567 + bool "DMA for SPI on sser1 enabled"
13568 + depends on ETRAX_SPI_SSER1 && !ETRAX_ETHERNET_IFACE1
13569 + depends on !ETRAX_SERIAL_PORT0_DMA6_OUT && !ETRAX_SERIAL_PORT0_DMA7_IN
13570 + default y
13571 + help
13572 + Say Y if using DMA (dma6/dma7) for SPI on synchronous serial port 1.
13573 +
13574 +config ETRAX_SPI_MMC_CD_SSER1_PIN
13575 + string "MMC/SD card detect pin for SPI on sser1"
13576 + depends on ETRAX_SPI_SSER1 && MMC_SPI
13577 + default "pd12"
13578 + help
13579 + The pin to use for SD/MMC card detect. This pin should be pulled up
13580 + and grounded when a card is present. If defined as " " (space), no
13581 + pin is selected. A card must then always be inserted for proper
13582 + action.
13583 +
13584 +config ETRAX_SPI_MMC_WP_SSER1_PIN
13585 + string "MMC/SD card write-protect pin for SPI on sser1"
13586 + depends on ETRAX_SPI_SSER1 && MMC_SPI
13587 + default "pd9"
13588 + help
13589 + The pin to use for the SD/MMC write-protect signal for a memory
13590 + card. If defined as " " (space), the card is considered writable.
13591 +
13592 +config ETRAX_SPI_GPIO
13593 + tristate "Bitbanged SPI using gpio pins"
13594 + depends on ETRAX_SPI_MMC
13595 + select SPI_ETRAX_GPIO
13596 + default m if MMC_SPI=m && ETRAX_SPI_SSER0=n && ETRAX_SPI_SSER1=n
13597 + default y if MMC_SPI=y && ETRAX_SPI_SSER0=n && ETRAX_SPI_SSER1=n
13598 + default y if MMC_SPI=n && ETRAX_SPI_SSER0=n && ETRAX_SPI_SSER1=n
13599 + help
13600 + Say Y for an MMC/SD socket connected to general I/O pins (but not
13601 + a complete synchronous serial ports), or for devices using the SPI
13602 + protocol on general I/O pins. Slow and slows down the system.
13603 + Say m to build it as a module, which will be called spi_crisv32_gpio.
13604 + (You need to select MMC separately.)
13605 +
13606 +# The default match that of sser0, only because that's how it was tested.
13607 +config ETRAX_SPI_CS_PIN
13608 + string "SPI chip select pin"
13609 + depends on ETRAX_SPI_GPIO
13610 + default "pc3"
13611 + help
13612 + The pin to use for SPI chip select.
13613 +
13614 +config ETRAX_SPI_CLK_PIN
13615 + string "SPI clock pin"
13616 + depends on ETRAX_SPI_GPIO
13617 + default "pc1"
13618 + help
13619 + The pin to use for the SPI clock.
13620 +
13621 +config ETRAX_SPI_DATAIN_PIN
13622 + string "SPI MISO (data in) pin"
13623 + depends on ETRAX_SPI_GPIO
13624 + default "pc16"
13625 + help
13626 + The pin to use for SPI data in from the device.
13627 +
13628 +config ETRAX_SPI_DATAOUT_PIN
13629 + string "SPI MOSI (data out) pin"
13630 + depends on ETRAX_SPI_GPIO
13631 + default "pc0"
13632 + help
13633 + The pin to use for SPI data out to the device.
13634 +
13635 +config ETRAX_SPI_MMC_CD_GPIO_PIN
13636 + string "MMC/SD card detect pin for SPI using gpio (space for none)"
13637 + depends on ETRAX_SPI_GPIO && MMC_SPI
13638 + default "pd11"
13639 + help
13640 + The pin to use for SD/MMC card detect. This pin should be pulled up
13641 + and grounded when a card is present. If defined as " " (space), no
13642 + pin is selected. A card must then always be inserted for proper
13643 + action.
13644 +
13645 +config ETRAX_SPI_MMC_WP_GPIO_PIN
13646 + string "MMC/SD card write-protect pin for SPI using gpio (space for none)"
13647 + depends on ETRAX_SPI_GPIO && MMC_SPI
13648 + default "pd10"
13649 + help
13650 + The pin to use for the SD/MMC write-protect signal for a memory
13651 + card. If defined as " " (space), the card is considered writable.
13652 +
13653 +# Avoid choices causing non-working configs by conditionalizing the inclusion.
13654 +if ETRAX_SPI_MMC
13655 +source drivers/spi/Kconfig
13656 +endif
13657 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/drivers/Makefile linux-2.6.19.2.dev/arch/cris/arch-v32/drivers/Makefile
13658 --- linux-2.6.19.2.old/arch/cris/arch-v32/drivers/Makefile 2007-01-10 20:10:37.000000000 +0100
13659 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/drivers/Makefile 2007-01-29 16:14:16.000000000 +0100
13660 @@ -11,3 +11,4 @@
13661 obj-$(CONFIG_ETRAX_I2C) += i2c.o
13662 obj-$(CONFIG_ETRAX_SYNCHRONOUS_SERIAL) += sync_serial.o
13663 obj-$(CONFIG_PCI) += pci/
13664 +obj-$(CONFIG_ETRAX_SPI_MMC_BOARD) += board_mmcspi.o
13665 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/drivers/axisflashmap.c linux-2.6.19.2.dev/arch/cris/arch-v32/drivers/axisflashmap.c
13666 --- linux-2.6.19.2.old/arch/cris/arch-v32/drivers/axisflashmap.c 2007-01-10 20:10:37.000000000 +0100
13667 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/drivers/axisflashmap.c 2007-02-06 17:37:50.000000000 +0100
13668 @@ -11,7 +11,7 @@
13669 * partition split defined below.
13670 *
13671 * Copy of os/lx25/arch/cris/arch-v10/drivers/axisflashmap.c 1.5
13672 - * with minor changes.
13673 + * with quite a few changes now.
13674 *
13675 */
13676
13677 @@ -27,6 +27,8 @@
13678 #include <linux/mtd/mtdram.h>
13679 #include <linux/mtd/partitions.h>
13680
13681 +#include <linux/cramfs_fs.h>
13682 +
13683 #include <asm/arch/hwregs/config_defs.h>
13684 #include <asm/axisflashmap.h>
13685 #include <asm/mmu.h>
13686 @@ -37,16 +39,24 @@
13687 #define FLASH_UNCACHED_ADDR KSEG_E
13688 #define FLASH_CACHED_ADDR KSEG_F
13689
13690 +#define PAGESIZE (512)
13691 +
13692 #if CONFIG_ETRAX_FLASH_BUSWIDTH==1
13693 #define flash_data __u8
13694 #elif CONFIG_ETRAX_FLASH_BUSWIDTH==2
13695 #define flash_data __u16
13696 #elif CONFIG_ETRAX_FLASH_BUSWIDTH==4
13697 -#define flash_data __u16
13698 +#define flash_data __u32
13699 #endif
13700
13701 /* From head.S */
13702 -extern unsigned long romfs_start, romfs_length, romfs_in_flash;
13703 +extern unsigned long romfs_in_flash; /* 1 when romfs_start, _length in flash */
13704 +extern unsigned long romfs_start, romfs_length;
13705 +extern unsigned long nand_boot; /* 1 when booted from nand flash */
13706 +
13707 +struct partition_name {
13708 + char name[6];
13709 +};
13710
13711 /* The master mtd for the entire flash. */
13712 struct mtd_info* axisflash_mtd = NULL;
13713 @@ -112,32 +122,20 @@
13714 .map_priv_1 = FLASH_UNCACHED_ADDR + MEM_CSE0_SIZE
13715 };
13716
13717 -/* If no partition-table was found, we use this default-set. */
13718 -#define MAX_PARTITIONS 7
13719 -#define NUM_DEFAULT_PARTITIONS 3
13720 +#define MAX_PARTITIONS 7
13721 +#ifdef CONFIG_ETRAX_NANDBOOT
13722 +#define NUM_DEFAULT_PARTITIONS 4
13723 +#define DEFAULT_ROOTFS_PARTITION_NO 2
13724 +#define DEFAULT_MEDIA_SIZE 0x2000000 /* 32 megs */
13725 +#else
13726 +#define NUM_DEFAULT_PARTITIONS 3
13727 +#define DEFAULT_ROOTFS_PARTITION_NO (-1)
13728 +#define DEFAULT_MEDIA_SIZE 0x800000 /* 8 megs */
13729 +#endif
13730
13731 -/*
13732 - * Default flash size is 2MB. CONFIG_ETRAX_PTABLE_SECTOR is most likely the
13733 - * size of one flash block and "filesystem"-partition needs 5 blocks to be able
13734 - * to use JFFS.
13735 - */
13736 -static struct mtd_partition axis_default_partitions[NUM_DEFAULT_PARTITIONS] = {
13737 - {
13738 - .name = "boot firmware",
13739 - .size = CONFIG_ETRAX_PTABLE_SECTOR,
13740 - .offset = 0
13741 - },
13742 - {
13743 - .name = "kernel",
13744 - .size = 0x200000 - (6 * CONFIG_ETRAX_PTABLE_SECTOR),
13745 - .offset = CONFIG_ETRAX_PTABLE_SECTOR
13746 - },
13747 - {
13748 - .name = "filesystem",
13749 - .size = 5 * CONFIG_ETRAX_PTABLE_SECTOR,
13750 - .offset = 0x200000 - (5 * CONFIG_ETRAX_PTABLE_SECTOR)
13751 - }
13752 -};
13753 +#if (MAX_PARTITIONS < NUM_DEFAULT_PARTITIONS)
13754 +#error MAX_PARTITIONS must be >= than NUM_DEFAULT_PARTITIONS
13755 +#endif
13756
13757 /* Initialize the ones normally used. */
13758 static struct mtd_partition axis_partitions[MAX_PARTITIONS] = {
13759 @@ -178,6 +176,56 @@
13760 },
13761 };
13762
13763 +
13764 +/* If no partition-table was found, we use this default-set.
13765 + * Default flash size is 8MB (NOR). CONFIG_ETRAX_PTABLE_SECTOR is most
13766 + * likely the size of one flash block and "filesystem"-partition needs
13767 + * to be >=5 blocks to be able to use JFFS.
13768 + */
13769 +static struct mtd_partition axis_default_partitions[NUM_DEFAULT_PARTITIONS] = {
13770 + {
13771 + .name = "boot firmware",
13772 + .size = CONFIG_ETRAX_PTABLE_SECTOR,
13773 + .offset = 0
13774 + },
13775 + {
13776 + .name = "kernel",
13777 + .size = 10 * CONFIG_ETRAX_PTABLE_SECTOR,
13778 + .offset = CONFIG_ETRAX_PTABLE_SECTOR
13779 + },
13780 +#define FILESYSTEM_SECTOR (11 * CONFIG_ETRAX_PTABLE_SECTOR)
13781 +#ifdef CONFIG_ETRAX_NANDBOOT
13782 + {
13783 + .name = "rootfs",
13784 + .size = 10 * CONFIG_ETRAX_PTABLE_SECTOR,
13785 + .offset = FILESYSTEM_SECTOR
13786 + },
13787 +#undef FILESYSTEM_SECTOR
13788 +#define FILESYSTEM_SECTOR (21 * CONFIG_ETRAX_PTABLE_SECTOR)
13789 +#endif
13790 + {
13791 + .name = "rwfs",
13792 + .size = DEFAULT_MEDIA_SIZE - FILESYSTEM_SECTOR,
13793 + .offset = FILESYSTEM_SECTOR
13794 + }
13795 +};
13796 +
13797 +#ifdef CONFIG_ETRAX_AXISFLASHMAP_MTD0WHOLE
13798 +/* Main flash device */
13799 +static struct mtd_partition main_partition = {
13800 + .name = "main",
13801 + .size = 0,
13802 + .offset = 0
13803 +};
13804 +#endif
13805 +
13806 +/* Auxilliary partition if we find another flash */
13807 +static struct mtd_partition aux_partition = {
13808 + .name = "aux",
13809 + .size = 0,
13810 + .offset = 0
13811 +};
13812 +
13813 /*
13814 * Probe a chip select for AMD-compatible (JEDEC) or CFI-compatible flash
13815 * chips in that order (because the amd_flash-driver is faster).
13816 @@ -186,23 +234,23 @@
13817 {
13818 struct mtd_info *mtd_cs = NULL;
13819
13820 - printk(KERN_INFO
13821 + printk(KERN_INFO
13822 "%s: Probing a 0x%08lx bytes large window at 0x%08lx.\n",
13823 map_cs->name, map_cs->size, map_cs->map_priv_1);
13824
13825 -#ifdef CONFIG_MTD_AMDSTD
13826 - mtd_cs = do_map_probe("amd_flash", map_cs);
13827 -#endif
13828 #ifdef CONFIG_MTD_CFI
13829 + mtd_cs = do_map_probe("cfi_probe", map_cs);
13830 +#endif
13831 +#ifdef CONFIG_MTD_JEDECPROBE
13832 if (!mtd_cs) {
13833 - mtd_cs = do_map_probe("cfi_probe", map_cs);
13834 + mtd_cs = do_map_probe("jedec_probe", map_cs);
13835 }
13836 #endif
13837
13838 return mtd_cs;
13839 }
13840
13841 -/*
13842 +/*
13843 * Probe each chip select individually for flash chips. If there are chips on
13844 * both cse0 and cse1, the mtd_info structs will be concatenated to one struct
13845 * so that MTD partitions can cross chip boundries.
13846 @@ -217,22 +265,17 @@
13847 {
13848 struct mtd_info *mtd_cse0;
13849 struct mtd_info *mtd_cse1;
13850 - struct mtd_info *mtd_nand = NULL;
13851 struct mtd_info *mtd_total;
13852 - struct mtd_info *mtds[3];
13853 + struct mtd_info *mtds[2];
13854 int count = 0;
13855
13856 if ((mtd_cse0 = probe_cs(&map_cse0)) != NULL)
13857 mtds[count++] = mtd_cse0;
13858 if ((mtd_cse1 = probe_cs(&map_cse1)) != NULL)
13859 mtds[count++] = mtd_cse1;
13860 +
13861
13862 -#ifdef CONFIG_ETRAX_NANDFLASH
13863 - if ((mtd_nand = crisv32_nand_flash_probe()) != NULL)
13864 - mtds[count++] = mtd_nand;
13865 -#endif
13866 -
13867 - if (!mtd_cse0 && !mtd_cse1 && !mtd_nand) {
13868 + if (!mtd_cse0 && !mtd_cse1) {
13869 /* No chip found. */
13870 return NULL;
13871 }
13872 @@ -248,7 +291,7 @@
13873 */
13874 mtd_total = mtd_concat_create(mtds,
13875 count,
13876 - "cse0+cse1+nand");
13877 + "cse0+cse1");
13878 #else
13879 printk(KERN_ERR "%s and %s: Cannot concatenate due to kernel "
13880 "(mis)configuration!\n", map_cse0.name, map_cse1.name);
13881 @@ -260,57 +303,155 @@
13882
13883 /* The best we can do now is to only use what we found
13884 * at cse0.
13885 - */
13886 + */
13887 mtd_total = mtd_cse0;
13888 map_destroy(mtd_cse1);
13889 }
13890 } else {
13891 - mtd_total = mtd_cse0? mtd_cse0 : mtd_cse1 ? mtd_cse1 : mtd_nand;
13892 -
13893 + mtd_total = mtd_cse0 ? mtd_cse0 : mtd_cse1;
13894 +
13895 }
13896
13897 return mtd_total;
13898 }
13899
13900 -extern unsigned long crisv32_nand_boot;
13901 -extern unsigned long crisv32_nand_cramfs_offset;
13902 -
13903 /*
13904 * Probe the flash chip(s) and, if it succeeds, read the partition-table
13905 * and register the partitions with MTD.
13906 */
13907 static int __init init_axis_flash(void)
13908 {
13909 - struct mtd_info *mymtd;
13910 + struct mtd_info *main_mtd;
13911 + struct mtd_info *aux_mtd = NULL;
13912 int err = 0;
13913 int pidx = 0;
13914 struct partitiontable_head *ptable_head = NULL;
13915 struct partitiontable_entry *ptable;
13916 - int use_default_ptable = 1; /* Until proven otherwise. */
13917 - const char *pmsg = KERN_INFO " /dev/flash%d at 0x%08x, size 0x%08x\n";
13918 - static char page[512];
13919 + int ptable_ok = 0;
13920 + static char page[PAGESIZE];
13921 size_t len;
13922 + int ram_rootfs_partition = -1; /* -1 => no RAM rootfs partition */
13923 + int part;
13924 +
13925 + /* We need a root fs. If it resides in RAM, we need to use an
13926 + * MTDRAM device, so it must be enabled in the kernel config,
13927 + * but its size must be configured as 0 so as not to conflict
13928 + * with our usage.
13929 + */
13930 +#if !defined(CONFIG_MTD_MTDRAM) || (CONFIG_MTDRAM_TOTAL_SIZE != 0) || (CONFIG_MTDRAM_ABS_POS != 0)
13931 + if (!romfs_in_flash && !nand_boot) {
13932 + printk(KERN_EMERG "axisflashmap: Cannot create an MTD RAM "
13933 + "device; configure CONFIG_MTD_MTDRAM with size = 0!\n");
13934 + panic("This kernel cannot boot from RAM!\n");
13935 + }
13936 +#endif
13937
13938 #ifndef CONFIG_ETRAXFS_SIM
13939 - mymtd = flash_probe();
13940 - mymtd->read(mymtd, CONFIG_ETRAX_PTABLE_SECTOR, 512, &len, page);
13941 - ptable_head = (struct partitiontable_head *)(page + PARTITION_TABLE_OFFSET);
13942 + main_mtd = flash_probe();
13943 + if (main_mtd)
13944 + printk(KERN_INFO "%s: 0x%08x bytes of NOR flash memory.\n",
13945 + main_mtd->name, main_mtd->size);
13946 +
13947 +#ifdef CONFIG_ETRAX_NANDFLASH
13948 + aux_mtd = crisv32_nand_flash_probe();
13949 + if (aux_mtd)
13950 + printk(KERN_INFO "%s: 0x%08x bytes of NAND flash memory.\n",
13951 + aux_mtd->name, aux_mtd->size);
13952
13953 - if (!mymtd) {
13954 +#ifdef CONFIG_ETRAX_NANDBOOT
13955 + {
13956 + struct mtd_info *tmp_mtd;
13957 +
13958 + printk(KERN_INFO "axisflashmap: Set to boot from NAND flash, "
13959 + "making NAND flash primary device.\n");
13960 + tmp_mtd = main_mtd;
13961 + main_mtd = aux_mtd;
13962 + aux_mtd = tmp_mtd;
13963 + }
13964 +#endif /* CONFIG_ETRAX_NANDBOOT */
13965 +#endif /* CONFIG_ETRAX_NANDFLASH */
13966 +
13967 + if (!main_mtd && !aux_mtd) {
13968 /* There's no reason to use this module if no flash chip can
13969 * be identified. Make sure that's understood.
13970 */
13971 printk(KERN_INFO "axisflashmap: Found no flash chip.\n");
13972 - } else {
13973 - printk(KERN_INFO "%s: 0x%08x bytes of flash memory.\n",
13974 - mymtd->name, mymtd->size);
13975 - axisflash_mtd = mymtd;
13976 }
13977
13978 - if (mymtd) {
13979 - mymtd->owner = THIS_MODULE;
13980 +#if 0 /* Dump flash memory so we can see what is going on */
13981 + if (main_mtd) {
13982 + int sectoraddr, i;
13983 + for (sectoraddr = 0; sectoraddr < 2*65536+4096; sectoraddr += PAGESIZE) {
13984 + main_mtd->read(main_mtd, sectoraddr, PAGESIZE, &len, page);
13985 + printk(KERN_INFO
13986 + "Sector at %d (length %d):\n",
13987 + sectoraddr, len);
13988 + for (i = 0; i < PAGESIZE; i += 16) {
13989 + printk(KERN_INFO
13990 + "%02x %02x %02x %02x %02x %02x %02x %02x "
13991 + "%02x %02x %02x %02x %02x %02x %02x %02x\n",
13992 + page[i] & 255, page[i+1] & 255,
13993 + page[i+2] & 255, page[i+3] & 255,
13994 + page[i+4] & 255, page[i+5] & 255,
13995 + page[i+6] & 255, page[i+7] & 255,
13996 + page[i+8] & 255, page[i+9] & 255,
13997 + page[i+10] & 255, page[i+11] & 255,
13998 + page[i+12] & 255, page[i+13] & 255,
13999 + page[i+14] & 255, page[i+15] & 255);
14000 + }
14001 +
14002 + }
14003 + }
14004 +#endif
14005 +
14006 + if (main_mtd) {
14007 + main_mtd->owner = THIS_MODULE;
14008 + axisflash_mtd = main_mtd;
14009 +
14010 + loff_t ptable_sector = CONFIG_ETRAX_PTABLE_SECTOR;
14011 +
14012 + pidx++; /* First partition (rescue) is always set to the default. */
14013 +#ifdef CONFIG_ETRAX_NANDBOOT
14014 + /* We know where the partition table should be located,
14015 + * it will be in first good block after that.
14016 + */
14017 + int blockstat;
14018 + do {
14019 + blockstat = main_mtd->block_isbad(main_mtd, ptable_sector);
14020 + if (blockstat < 0)
14021 + ptable_sector = 0; /* read error */
14022 + else if (blockstat)
14023 + ptable_sector += main_mtd->erasesize;
14024 + } while (blockstat && ptable_sector);
14025 +#endif
14026 + if (ptable_sector) {
14027 + main_mtd->read(main_mtd, ptable_sector, PAGESIZE, &len, page);
14028 + ptable_head = &((struct partitiontable *) page)->head;
14029 + }
14030 +
14031 +#if 0 /* Dump partition table so we can see what is going on */
14032 + printk(KERN_INFO
14033 + "axisflashmap: flash read %d bytes at 0x%08x, data: "
14034 + "%02x %02x %02x %02x %02x %02x %02x %02x\n",
14035 + len, CONFIG_ETRAX_PTABLE_SECTOR,
14036 + page[0] & 255, page[1] & 255,
14037 + page[2] & 255, page[3] & 255,
14038 + page[4] & 255, page[5] & 255,
14039 + page[6] & 255, page[7] & 255);
14040 + printk(KERN_INFO
14041 + "axisflashmap: partition table offset %d, data: "
14042 + "%02x %02x %02x %02x %02x %02x %02x %02x\n",
14043 + PARTITION_TABLE_OFFSET,
14044 + page[PARTITION_TABLE_OFFSET+0] & 255,
14045 + page[PARTITION_TABLE_OFFSET+1] & 255,
14046 + page[PARTITION_TABLE_OFFSET+2] & 255,
14047 + page[PARTITION_TABLE_OFFSET+3] & 255,
14048 + page[PARTITION_TABLE_OFFSET+4] & 255,
14049 + page[PARTITION_TABLE_OFFSET+5] & 255,
14050 + page[PARTITION_TABLE_OFFSET+6] & 255,
14051 + page[PARTITION_TABLE_OFFSET+7] & 255);
14052 +#endif
14053 }
14054 - pidx++; /* First partition is always set to the default. */
14055
14056 if (ptable_head && (ptable_head->magic == PARTITION_TABLE_MAGIC)
14057 && (ptable_head->size <
14058 @@ -323,7 +464,6 @@
14059 /* Looks like a start, sane length and end of a
14060 * partition table, lets check csum etc.
14061 */
14062 - int ptable_ok = 0;
14063 struct partitiontable_entry *max_addr =
14064 (struct partitiontable_entry *)
14065 ((unsigned long)ptable_head + sizeof(*ptable_head) +
14066 @@ -331,7 +471,7 @@
14067 unsigned long offset = CONFIG_ETRAX_PTABLE_SECTOR;
14068 unsigned char *p;
14069 unsigned long csum = 0;
14070 -
14071 +
14072 ptable = (struct partitiontable_entry *)
14073 ((unsigned long)ptable_head + sizeof(*ptable_head));
14074
14075 @@ -343,108 +483,177 @@
14076 csum += *p++;
14077 csum += *p++;
14078 csum += *p++;
14079 - }
14080 + }
14081 ptable_ok = (csum == ptable_head->checksum);
14082
14083 /* Read the entries and use/show the info. */
14084 - printk(KERN_INFO " Found a%s partition table at 0x%p-0x%p.\n",
14085 + printk(KERN_INFO "axisflashmap: "
14086 + "Found a%s partition table at 0x%p-0x%p.\n",
14087 (ptable_ok ? " valid" : "n invalid"), ptable_head,
14088 max_addr);
14089
14090 /* We have found a working bootblock. Now read the
14091 - * partition table. Scan the table. It ends when
14092 - * there is 0xffffffff, that is, empty flash.
14093 + * partition table. Scan the table. It ends with 0xffffffff.
14094 */
14095 while (ptable_ok
14096 - && ptable->offset != 0xffffffff
14097 + && ptable->offset != PARTITIONTABLE_END_MARKER
14098 && ptable < max_addr
14099 - && pidx < MAX_PARTITIONS) {
14100 + && pidx < MAX_PARTITIONS - 1) {
14101
14102 - axis_partitions[pidx].offset = offset + ptable->offset + (crisv32_nand_boot ? 16384 : 0);
14103 - axis_partitions[pidx].size = ptable->size;
14104 -
14105 - printk(pmsg, pidx, axis_partitions[pidx].offset,
14106 - axis_partitions[pidx].size);
14107 + axis_partitions[pidx].offset = offset + ptable->offset;
14108 +#ifdef CONFIG_ETRAX_NANDFLASH
14109 + if (main_mtd->type == MTD_NANDFLASH) {
14110 + axis_partitions[pidx].size =
14111 + (((ptable+1)->offset ==
14112 + PARTITIONTABLE_END_MARKER) ?
14113 + main_mtd->size :
14114 + ((ptable+1)->offset + offset)) -
14115 + (ptable->offset + offset);
14116 +
14117 + } else
14118 +#endif /* CONFIG_ETRAX_NANDFLASH */
14119 + axis_partitions[pidx].size = ptable->size;
14120 +#ifdef CONFIG_ETRAX_NANDBOOT
14121 + /* Save partition number of jffs2 ro partition.
14122 + * Needed if RAM booting or root file system in RAM.
14123 + */
14124 + if (!nand_boot &&
14125 + ram_rootfs_partition < 0 && /* not already set */
14126 + ptable->type == PARTITION_TYPE_JFFS2 &&
14127 + (ptable->flags & PARTITION_FLAGS_READONLY_MASK) ==
14128 + PARTITION_FLAGS_READONLY)
14129 + ram_rootfs_partition = pidx;
14130 +#endif /* CONFIG_ETRAX_NANDBOOT */
14131 pidx++;
14132 ptable++;
14133 }
14134 - use_default_ptable = !ptable_ok;
14135 }
14136
14137 - if (romfs_in_flash) {
14138 - /* Add an overlapping device for the root partition (romfs). */
14139 + /* Decide whether to use default partition table. */
14140 + /* Only use default table if we actually have a device (main_mtd) */
14141
14142 - axis_partitions[pidx].name = "romfs";
14143 - if (crisv32_nand_boot) {
14144 - char* data = kmalloc(1024, GFP_KERNEL);
14145 - int len;
14146 - int offset = crisv32_nand_cramfs_offset & ~(1024-1);
14147 - char* tmp;
14148 -
14149 - mymtd->read(mymtd, offset, 1024, &len, data);
14150 - tmp = &data[crisv32_nand_cramfs_offset % 512];
14151 - axis_partitions[pidx].size = *(unsigned*)(tmp + 4);
14152 - axis_partitions[pidx].offset = crisv32_nand_cramfs_offset;
14153 - kfree(data);
14154 - } else {
14155 - axis_partitions[pidx].size = romfs_length;
14156 - axis_partitions[pidx].offset = romfs_start - FLASH_CACHED_ADDR;
14157 - }
14158 + struct mtd_partition *partition = &axis_partitions[0];
14159 + if (main_mtd && !ptable_ok) {
14160 + memcpy(axis_partitions, axis_default_partitions,
14161 + sizeof(axis_default_partitions));
14162 + pidx = NUM_DEFAULT_PARTITIONS;
14163 + ram_rootfs_partition = DEFAULT_ROOTFS_PARTITION_NO;
14164 + }
14165
14166 + /* Add artificial partitions for rootfs if necessary */
14167 + if (romfs_in_flash) {
14168 + /* rootfs is in directly accessible flash memory = NOR flash.
14169 + Add an overlapping device for the rootfs partition. */
14170 + printk(KERN_INFO "axisflashmap: Adding partition for "
14171 + "overlapping root file system image\n");
14172 + axis_partitions[pidx].size = romfs_length;
14173 + axis_partitions[pidx].offset = romfs_start - FLASH_CACHED_ADDR;
14174 + axis_partitions[pidx].name = "romfs";
14175 axis_partitions[pidx].mask_flags |= MTD_WRITEABLE;
14176 -
14177 - printk(KERN_INFO
14178 - " Adding readonly flash partition for romfs image:\n");
14179 - printk(pmsg, pidx, axis_partitions[pidx].offset,
14180 - axis_partitions[pidx].size);
14181 + ram_rootfs_partition = -1;
14182 pidx++;
14183 }
14184 -
14185 - if (mymtd) {
14186 - if (use_default_ptable) {
14187 - printk(KERN_INFO " Using default partition table.\n");
14188 - err = add_mtd_partitions(mymtd, axis_default_partitions,
14189 - NUM_DEFAULT_PARTITIONS);
14190 - } else {
14191 - err = add_mtd_partitions(mymtd, axis_partitions, pidx);
14192 + else if (romfs_length && !nand_boot) {
14193 + /* romfs exists in memory, but not in flash, so must be in RAM.
14194 + * Configure an MTDRAM partition. */
14195 + if (ram_rootfs_partition < 0) { /* none set yet */
14196 + ram_rootfs_partition = pidx; /* put it at the end */
14197 + pidx++;
14198 }
14199 + printk(KERN_INFO "axisflashmap: Adding partition for "
14200 + "root file system image in RAM\n");
14201 + axis_partitions[ram_rootfs_partition].size = romfs_length;
14202 + axis_partitions[ram_rootfs_partition].offset = romfs_start;
14203 + axis_partitions[ram_rootfs_partition].name = "romfs";
14204 + axis_partitions[ram_rootfs_partition].mask_flags |=
14205 + MTD_WRITEABLE;
14206 + }
14207
14208 - if (err) {
14209 - panic("axisflashmap could not add MTD partitions!\n");
14210 - }
14211 +#ifdef CONFIG_ETRAX_AXISFLASHMAP_MTD0WHOLE
14212 + if (main_mtd) {
14213 + main_partition.size = main_mtd->size;
14214 + err = add_mtd_partitions(main_mtd, &main_partition, 1);
14215 + if (err)
14216 + panic("axisflashmap: Could not initialize "
14217 + "partition for whole main mtd device!\n");
14218 }
14219 -/* CONFIG_EXTRAXFS_SIM */
14220 #endif
14221
14222 - if (!romfs_in_flash) {
14223 - /* Create an RAM device for the root partition (romfs). */
14224 + /* Now, register all partitions with mtd.
14225 + * We do this one at a time so we can slip in an MTDRAM device
14226 + * in the proper place if required. */
14227 +
14228 + for (part = 0; part < pidx; part++) {
14229 + if (part == ram_rootfs_partition) {
14230 + /* add MTDRAM partition here */
14231 + struct mtd_info *mtd_ram;
14232 +
14233 + mtd_ram = kmalloc(sizeof(struct mtd_info), GFP_KERNEL);
14234 + if (!mtd_ram)
14235 + panic("axisflashmap: Couldn't allocate memory "
14236 + "for mtd_info!\n");
14237 + printk(KERN_INFO "axisflashmap: Adding RAM partition "
14238 + "for rootfs image.\n");
14239 + err = mtdram_init_device(mtd_ram,
14240 + (void *)partition[part].offset,
14241 + partition[part].size,
14242 + partition[part].name);
14243 + if (err)
14244 + panic("axisflashmap: Could not initialize "
14245 + "MTD RAM device!\n");
14246 + /* JFFS2 likes to have an erasesize. Keep potential
14247 + * JFFS2 rootfs happy by providing one. Since image
14248 + * was most likely created for main mtd, use that
14249 + * erasesize, if available. Otherwise, make a guess. */
14250 + mtd_ram->erasesize = (main_mtd ? main_mtd->erasesize :
14251 + CONFIG_ETRAX_PTABLE_SECTOR);
14252 + } else {
14253 + err = add_mtd_partitions(main_mtd,
14254 + &partition[part], 1);
14255 + if (err)
14256 + panic("axisflashmap: Could not add mtd "
14257 + "partition %d\n", part);
14258 + }
14259 + }
14260
14261 -#if !defined(CONFIG_MTD_MTDRAM) || (CONFIG_MTDRAM_TOTAL_SIZE != 0) || (CONFIG_MTDRAM_ABS_POS != 0)
14262 - /* No use trying to boot this kernel from RAM. Panic! */
14263 - printk(KERN_EMERG "axisflashmap: Cannot create an MTD RAM "
14264 - "device due to kernel (mis)configuration!\n");
14265 - panic("This kernel cannot boot from RAM!\n");
14266 -#else
14267 - struct mtd_info *mtd_ram;
14268 +#endif /* CONFIG_EXTRAXFS_SIM */
14269
14270 - mtd_ram = (struct mtd_info *)kmalloc(sizeof(struct mtd_info),
14271 - GFP_KERNEL);
14272 - if (!mtd_ram) {
14273 - panic("axisflashmap couldn't allocate memory for "
14274 - "mtd_info!\n");
14275 - }
14276 +#ifdef CONFIG_ETRAXFS_SIM
14277 + /* For simulator, always use a RAM partition.
14278 + * The rootfs will be found after the kernel in RAM,
14279 + * with romfs_start and romfs_end indicating location and size.
14280 + */
14281 + struct mtd_info *mtd_ram;
14282 +
14283 + mtd_ram = (struct mtd_info *)kmalloc(sizeof(struct mtd_info),
14284 + GFP_KERNEL);
14285 + if (!mtd_ram) {
14286 + panic("axisflashmap: Couldn't allocate memory for "
14287 + "mtd_info!\n");
14288 + }
14289
14290 - printk(KERN_INFO " Adding RAM partition for romfs image:\n");
14291 - printk(pmsg, pidx, romfs_start, romfs_length);
14292 + printk(KERN_INFO "axisflashmap: Adding RAM partition for romfs, "
14293 + "at %u, size %u\n",
14294 + (unsigned) romfs_start, (unsigned) romfs_length);
14295 +
14296 + err = mtdram_init_device(mtd_ram, (void*)romfs_start,
14297 + romfs_length, "romfs");
14298 + if (err) {
14299 + panic("axisflashmap: Could not initialize MTD RAM "
14300 + "device!\n");
14301 + }
14302 +#endif /* CONFIG_EXTRAXFS_SIM */
14303 +
14304 +#ifndef CONFIG_ETRAXFS_SIM
14305 + if (aux_mtd) {
14306 + aux_partition.size = aux_mtd->size;
14307 + err = add_mtd_partitions(aux_mtd, &aux_partition, 1);
14308 + if (err)
14309 + panic("axisflashmap: Could not initialize "
14310 + "aux mtd device!\n");
14311
14312 - err = mtdram_init_device(mtd_ram, (void*)romfs_start,
14313 - romfs_length, "romfs");
14314 - if (err) {
14315 - panic("axisflashmap could not initialize MTD RAM "
14316 - "device!\n");
14317 - }
14318 -#endif
14319 }
14320 +#endif /* CONFIG_EXTRAXFS_SIM */
14321
14322 return err;
14323 }
14324 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/drivers/board_mmcspi.c linux-2.6.19.2.dev/arch/cris/arch-v32/drivers/board_mmcspi.c
14325 --- linux-2.6.19.2.old/arch/cris/arch-v32/drivers/board_mmcspi.c 1970-01-01 01:00:00.000000000 +0100
14326 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/drivers/board_mmcspi.c 2007-01-29 15:51:19.000000000 +0100
14327 @@ -0,0 +1,686 @@
14328 +/*
14329 + * Somewhat generic "board-side" code to support SPI drivers for chips
14330 + * with a CRIS v32 and later. Not really board-specific, and only for
14331 + * registration of SPI devices for MMC, hence the "mmcspi" part of the
14332 + * name instead of a proper board name.
14333 + *
14334 + * Copyright (c) 2007 Axis Communications AB
14335 + *
14336 + * TODO: SDIO interrupt-pin support (though can't be done until
14337 + * there's support added in both the mmc_spi and the mmc frameworks).
14338 + *
14339 + * This program is free software; you can redistribute it and/or modify
14340 + * it under the terms of the GNU General Public License as published by
14341 + * the Free Software Foundation; either version 2 of the License, or
14342 + * (at your option) any later version.
14343 + */
14344 +
14345 +#include <linux/types.h>
14346 +#include <linux/platform_device.h>
14347 +#include <linux/spi/spi.h>
14348 +#include <linux/spi/mmc_spi.h>
14349 +#include <linux/mmc/host.h>
14350 +#include <asm/arch/board.h>
14351 +#include <asm/arch/pinmux.h>
14352 +#include <asm/arch/dma.h>
14353 +#include <linux/err.h>
14354 +
14355 +#include <asm/io.h>
14356 +
14357 +/* We need some housekeeping. */
14358 +#define CONCAT_(a, b) a ## b
14359 +#define CONCAT(a, b) CONCAT_(a, b)
14360 +#define CONCAT3(a, b, c) CONCAT(CONCAT(a, b), c)
14361 +
14362 +/* Grr. Why not define them as usual in autoconf, #ifdef REVEAL_MODULES? */
14363 +#if !defined(CONFIG_SPI_ETRAX_SSER) && defined(CONFIG_SPI_ETRAX_SSER_MODULE)
14364 +#define CONFIG_SPI_ETRAX_SSER
14365 +#endif
14366 +
14367 +#if !defined(CONFIG_ETRAX_SPI_SSER0) && defined(CONFIG_ETRAX_SPI_SSER0_MODULE)
14368 +#define CONFIG_ETRAX_SPI_SSER0
14369 +#endif
14370 +
14371 +#if !defined(CONFIG_ETRAX_SPI_SSER1) && defined(CONFIG_ETRAX_SPI_SSER1_MODULE)
14372 +#define CONFIG_ETRAX_SPI_SSER1
14373 +#endif
14374 +
14375 +#if !defined(CONFIG_SPI_ETRAX_GPIO) && defined(CONFIG_SPI_ETRAX_GPIO_MODULE)
14376 +#define CONFIG_SPI_ETRAX_GPIO
14377 +#endif
14378 +
14379 +#define CONFIGURED_PIN(x) ((x) != NULL && *(x) != 0 && *(x) != ' ')
14380 +
14381 +/* Helper function to configure an iopin for input. */
14382 +
14383 +static int crisv32_config_pin_in(struct crisv32_iopin *pin, const char *name)
14384 +{
14385 + int ret = crisv32_io_get_name(pin, name);
14386 + if (ret)
14387 + return ret;
14388 +
14389 + crisv32_io_set_dir(pin, crisv32_io_dir_in);
14390 + return 0;
14391 +}
14392 +
14393 +/*
14394 + * Writable data pointed to by the constant parts of each MMC_SPI bus
14395 + * interface. Should only hold MMC-specific state (for the
14396 + * MMC-specific pins), nothing SPI-generic.
14397 + */
14398 +
14399 +struct crisv32_mmc_spi_pinstate {
14400 + struct crisv32_iopin write_protect_pin;
14401 + struct crisv32_iopin card_detect_pin;
14402 +
14403 + /* We must poll for card-detect, which we do each: */
14404 +#define CARD_DETECT_CHECK_INTERVAL (2*HZ)
14405 + /* We poll using a self-arming workqueue function. */
14406 + struct work_struct cd_work;
14407 +
14408 + /* When we detect a change in card presence, we call this
14409 + * function, supplied by the mmc_spi framework: */
14410 + irqreturn_t (*detectfunc)(int, void *);
14411 +
14412 + /*
14413 + * We call that function with this parameter as the second
14414 + * one. We must assume the other parameters are unused, as we
14415 + * don't have an interrupt context.
14416 + */
14417 + void *detectfunc_param2;
14418 +
14419 + /* State for the card-detect worker. */
14420 + int card_present;
14421 +};
14422 +
14423 +/* Rearming "work" function for card-detect polling. */
14424 +
14425 +static void crisv32_cd_worker(void *x)
14426 +{
14427 + struct crisv32_mmc_spi_pinstate *state = x;
14428 +
14429 + /* It's a pull-up, so a card is present when 0. */
14430 + int card_present = crisv32_io_rd(&state->card_detect_pin) == 0;
14431 +
14432 + if (card_present != state->card_present) {
14433 + state->card_present = card_present;
14434 + state->detectfunc(0, state->detectfunc_param2);
14435 + }
14436 + schedule_delayed_work(&state->cd_work, CARD_DETECT_CHECK_INTERVAL);
14437 +}
14438 +
14439 +/* The parts of MMC-specific configuration common to GPIO and SSER. */
14440 +
14441 +static int crisv32_mmcspi_config_common(struct spi_device *spidev,
14442 + irqreturn_t (*intfunc)(int, void *),
14443 + struct mmc_host *mmc_host,
14444 + const struct crisv32_mmc_spi_pindata *pd)
14445 +{
14446 + int ret = 0;
14447 + struct crisv32_mmc_spi_pinstate *ps = pd->pinstate;
14448 +
14449 + /*
14450 + * If we don't have a card-detect pin, the card must be
14451 + * present at startup (including insmod/modprobe). No
14452 + * re-scans are done if no card is present at that time.
14453 + */
14454 + if (CONFIGURED_PIN(pd->card_detect)) {
14455 + ret = crisv32_config_pin_in(&ps->card_detect_pin,
14456 + pd->card_detect);
14457 +
14458 + if (ret != 0)
14459 + goto bad_card_detect;
14460 +
14461 + /* Need to cast away const from pd, unfortunately. */
14462 + INIT_WORK(&ps->cd_work, crisv32_cd_worker, (void *) ps);
14463 + ps->card_present = 1;
14464 + ps->detectfunc = intfunc;
14465 + ps->detectfunc_param2 = mmc_host;
14466 + crisv32_cd_worker(ps);
14467 + } else
14468 + ps->detectfunc = NULL;
14469 +
14470 + /*
14471 + * We set up for checking for presence of a write-protect pin
14472 + * as pin.port being non-NULL.
14473 + */
14474 + memset(&ps->write_protect_pin, 0, sizeof ps->write_protect_pin);
14475 + if (CONFIGURED_PIN(pd->write_protect)) {
14476 + ret = crisv32_config_pin_in(&ps->write_protect_pin,
14477 + pd->write_protect);
14478 +
14479 + if (ret != 0)
14480 + goto bad_write_protect;
14481 + }
14482 +
14483 + return 0;
14484 +
14485 + bad_write_protect:
14486 + if (ps->detectfunc) {
14487 + cancel_rearming_delayed_work(&ps->cd_work);
14488 + ps->detectfunc = NULL;
14489 + }
14490 +
14491 + bad_card_detect:
14492 + return ret;
14493 +}
14494 +
14495 +/* A function to undo crisv32_mmcspi_config_common. */
14496 +
14497 +static void crisv32_mmcspi_deconfig_common(const struct
14498 + crisv32_mmc_spi_pindata *pd)
14499 +{
14500 + if (pd->pinstate->detectfunc) {
14501 + cancel_rearming_delayed_work(&pd->pinstate->cd_work);
14502 + pd->pinstate->detectfunc = NULL;
14503 + }
14504 +
14505 + /* We don't have to undo the pin allocations, being GPIO. */
14506 +}
14507 +
14508 +/* Helper function for write-protect sense. */
14509 +
14510 +static int crisv32_mmcspi_get_ro_helper(struct crisv32_mmc_spi_pinstate *ps)
14511 +{
14512 + return ps->write_protect_pin.port != NULL
14513 + && crisv32_io_rd(&ps->write_protect_pin) != 0;
14514 +}
14515 +
14516 +/* The hardware-interface-specific SPI+MMC parts. */
14517 +
14518 +#ifdef CONFIG_SPI_ETRAX_SSER
14519 +static const char crisv32_matching_spi_sser_driver_name[] __init_or_module
14520 + = "spi_crisv32_sser";
14521 +
14522 +/*
14523 + * Make up something we can use in tables and function without
14524 + * #ifdef-cluttering.
14525 + */
14526 +#ifdef CONFIG_ETRAX_SPI_SSER0_DMA
14527 +#define WITH_ETRAX_SPI_SSER0_DMA 1
14528 +#else
14529 +#define WITH_ETRAX_SPI_SSER0_DMA 0
14530 +#endif
14531 +#ifdef CONFIG_ETRAX_SPI_SSER1_DMA
14532 +#define WITH_ETRAX_SPI_SSER1_DMA 1
14533 +#else
14534 +#define WITH_ETRAX_SPI_SSER1_DMA 0
14535 +#endif
14536 +
14537 +/* Write-protect sense for the SSER interface. */
14538 +
14539 +static int crisv32_mmcspi_sser_get_ro(struct device *dev)
14540 +{
14541 + struct spi_device *spidev = to_spi_device(dev);
14542 + struct crisv32_mmc_spi_sser_hwdata *sser_defs
14543 + = spidev->controller_data;
14544 + struct crisv32_mmc_spi_pindata *pd = &sser_defs->mmc;
14545 + return crisv32_mmcspi_get_ro_helper(pd->pinstate);
14546 +}
14547 +
14548 +/* Initialize the MMC-specific parts of the MMC+SPI interface, SSER. */
14549 +
14550 +static int crisv32_mmcspi_sser_init(struct device *dev,
14551 + irqreturn_t (*intfunc)(int, void *),
14552 + void *xmmc_host)
14553 +{
14554 + struct mmc_host *mmc_host = xmmc_host;
14555 + struct spi_device *spidev = to_spi_device(dev);
14556 + struct crisv32_mmc_spi_sser_hwdata *sser_defs
14557 + = spidev->controller_data;
14558 + int ret = crisv32_mmcspi_config_common(spidev, intfunc, mmc_host,
14559 + &sser_defs->mmc);
14560 + if (ret != 0)
14561 + return ret;
14562 +
14563 + mmc_host->f_max = spidev->max_speed_hz;
14564 +
14565 + /*
14566 + * Let's just set this to ceil(100e6/65536). It wouldn't be
14567 + * hard to change the base frequency to support down to 450Hz,
14568 + * but there's no apparent requirement from known hardware.
14569 + * Would also require adjustments to the SPI code, not just
14570 + * here.
14571 + *
14572 + * On second thought, let's not set f_min unconditionally, as
14573 + * mmc doesn't treat it as a limit, but as the frequency to
14574 + * use at initialization. We stick with what mmc_spi sets, if
14575 + * it fits.
14576 + */
14577 + if (mmc_host->f_min < 1526)
14578 + mmc_host->f_min = 1526;
14579 +
14580 + dev_info(dev, "CRIS v32 mmc_spi support hooked to SPI on sser%d"
14581 + " (cd: %s, wp: %s)\n",
14582 + spidev->master->bus_num,
14583 + CONFIGURED_PIN(sser_defs->mmc.card_detect)
14584 + ? sser_defs->mmc.card_detect : "(none)",
14585 + CONFIGURED_PIN(sser_defs->mmc.write_protect)
14586 + ? sser_defs->mmc.write_protect : "(none)");
14587 + return 0;
14588 +}
14589 +
14590 +/* Similarly, to undo crisv32_mmcspi_sser_init. */
14591 +
14592 +static void crisv32_mmcspi_sser_exit(struct device *dev, void *xmmc_host)
14593 +{
14594 + struct spi_device *spidev = to_spi_device(dev);
14595 + struct crisv32_mmc_spi_sser_hwdata *sser_defs
14596 + = spidev->controller_data;
14597 +
14598 + crisv32_mmcspi_deconfig_common(&sser_defs->mmc);
14599 +}
14600 +
14601 +/*
14602 + * Connect sser and DMA channels and return the proper numbers to use.
14603 + *
14604 + * This function exists really only to avoid having the following constants
14605 + * tabled: regi_sserN, SSERn_INTR_VECT, pinmux_sserN, SYNC_SERn_TX_DMA_NBR,
14606 + * SYNC_SERn_RX_DMA_NBR dma_sserN, regi_dmaM, regi_dmaN, DMAm_INTR_VECT,
14607 + * DMAn_INTR_VECT. I might have missed some. :-)
14608 + */
14609 +static int crisv32_allocate_sser(struct crisv32_regi_n_int *sserp,
14610 + struct crisv32_regi_n_int *dmainp,
14611 + struct crisv32_regi_n_int *dmaoutp,
14612 + u32 sserno)
14613 +{
14614 + int ret;
14615 + u32 regi_sser = sserno == 0 ? regi_sser0 : regi_sser1;
14616 + u32 sser_irq = sserno == 0 ? SSER0_INTR_VECT : SSER1_INTR_VECT;
14617 + BUG_ON(sserno > 1 || sserp == NULL);
14618 +
14619 + ret = crisv32_pinmux_alloc_fixed(sserno == 0
14620 + ? pinmux_sser0 : pinmux_sser1);
14621 + if (ret != 0)
14622 + return ret;
14623 +
14624 + sserp->regi = regi_sser;
14625 + sserp->irq = sser_irq;
14626 +
14627 + if (dmaoutp) {
14628 + crisv32_request_dma(sserno == 0
14629 + ? SYNC_SER0_TX_DMA_NBR
14630 + : SYNC_SER1_TX_DMA_NBR,
14631 + "SD/MMC SPI dma tr",
14632 + DMA_VERBOSE_ON_ERROR | DMA_PANIC_ON_ERROR,
14633 + /* Let's be brave and ask for the
14634 + max. Except it's simplex, so
14635 + let's request half the max
14636 + speed in either direction. */
14637 + 50 * 1000 * 1000 / 8 / 2,
14638 + sserno == 0 ? dma_sser0 : dma_sser1);
14639 + dmaoutp->regi = sserno == 0
14640 + ? CONCAT(regi_dma, SYNC_SER0_TX_DMA_NBR)
14641 + : CONCAT(regi_dma, SYNC_SER1_TX_DMA_NBR);
14642 + dmaoutp->irq = sserno == 0
14643 + ? CONCAT3(DMA, SYNC_SER0_TX_DMA_NBR, _INTR_VECT)
14644 + : CONCAT3(DMA, SYNC_SER1_TX_DMA_NBR, _INTR_VECT);
14645 + }
14646 +
14647 + if (dmainp) {
14648 + crisv32_request_dma(sserno == 0
14649 + ? SYNC_SER0_RX_DMA_NBR
14650 + : SYNC_SER1_RX_DMA_NBR,
14651 + "SD/MMC SPI dma rec",
14652 + DMA_VERBOSE_ON_ERROR | DMA_PANIC_ON_ERROR,
14653 + 50 * 1000 * 1000 / 8 / 2,
14654 + sserno == 0 ? dma_sser0 : dma_sser1);
14655 + dmainp->regi = sserno == 0
14656 + ? CONCAT(regi_dma, SYNC_SER0_RX_DMA_NBR)
14657 + : CONCAT(regi_dma, SYNC_SER1_RX_DMA_NBR);
14658 + dmainp->irq = sserno == 0
14659 + ? CONCAT3(DMA, SYNC_SER0_RX_DMA_NBR, _INTR_VECT)
14660 + : CONCAT3(DMA, SYNC_SER1_RX_DMA_NBR, _INTR_VECT);
14661 + }
14662 +
14663 + return 0;
14664 +}
14665 +
14666 +/* Undo whatever allocations et. al. that crisv32_allocate_sser did. */
14667 +
14668 +static void crisv32_free_sser(u32 sserno, int with_dma)
14669 +{
14670 + int ret;
14671 +
14672 + if (with_dma) {
14673 + crisv32_free_dma(sserno == 0
14674 + ? SYNC_SER0_RX_DMA_NBR
14675 + : SYNC_SER1_RX_DMA_NBR);
14676 + crisv32_free_dma(sserno == 0
14677 + ? SYNC_SER0_TX_DMA_NBR
14678 + : SYNC_SER1_TX_DMA_NBR);
14679 + }
14680 +
14681 + ret = crisv32_pinmux_dealloc_fixed(sserno == 0
14682 + ? pinmux_sser0 : pinmux_sser1);
14683 +
14684 + if (ret != 0)
14685 + panic("%s: crisv32_pinmux_dealloc_fixed returned %d\n",
14686 + __FUNCTION__, ret);
14687 +}
14688 +
14689 +/* Convenience-macro to avoid typos causing diffs between sser ports. */
14690 +
14691 +#define SSER_CDATA(n) \
14692 + { \
14693 + { \
14694 + .using_dma = WITH_ETRAX_SPI_SSER##n##_DMA, \
14695 + .iface_allocate = crisv32_allocate_sser##n, \
14696 + .iface_free = crisv32_free_sser##n \
14697 + }, \
14698 + { \
14699 + .card_detect \
14700 + = CONFIG_ETRAX_SPI_MMC_CD_SSER##n##_PIN,\
14701 + .write_protect \
14702 + = CONFIG_ETRAX_SPI_MMC_WP_SSER##n##_PIN,\
14703 + .pinstate \
14704 + = &crisv32_mmcspi_sser##n##_pinstate \
14705 + } \
14706 + }
14707 +
14708 +#ifdef CONFIG_ETRAX_SPI_SSER0
14709 +
14710 +/* Allocate hardware to go with sser0 and fill in the right numbers. */
14711 +
14712 +static int crisv32_allocate_sser0(struct crisv32_regi_n_int *sserp,
14713 + struct crisv32_regi_n_int *dmainp,
14714 + struct crisv32_regi_n_int *dmaoutp)
14715 +{
14716 + return crisv32_allocate_sser(sserp, dmainp, dmaoutp, 0);
14717 +}
14718 +
14719 +/* Undo those allocations. */
14720 +
14721 +static void crisv32_free_sser0(void)
14722 +{
14723 + crisv32_free_sser(0, WITH_ETRAX_SPI_SSER0_DMA);
14724 +}
14725 +
14726 +static struct crisv32_mmc_spi_pinstate crisv32_mmcspi_sser0_pinstate;
14727 +static const struct crisv32_mmc_spi_sser_hwdata crisv32_mmcspi_sser0_cdata
14728 + = SSER_CDATA(0);
14729 +#endif /* CONFIG_ETRAX_SPI_SSER0 */
14730 +
14731 +#ifdef CONFIG_ETRAX_SPI_SSER1
14732 +
14733 +/* Allocate hardware to go with sser0 and fill in the right numbers. */
14734 +
14735 +static int crisv32_allocate_sser1(struct crisv32_regi_n_int *sserp,
14736 + struct crisv32_regi_n_int *dmainp,
14737 + struct crisv32_regi_n_int *dmaoutp)
14738 +{
14739 + return crisv32_allocate_sser(sserp, dmainp, dmaoutp, 1);
14740 +}
14741 +
14742 +/* Undo those allocations. */
14743 +
14744 +static void crisv32_free_sser1(void)
14745 +{
14746 + crisv32_free_sser(1, WITH_ETRAX_SPI_SSER1_DMA);
14747 +}
14748 +
14749 +static struct crisv32_mmc_spi_pinstate crisv32_mmcspi_sser1_pinstate;
14750 +static const struct crisv32_mmc_spi_sser_hwdata crisv32_mmcspi_sser1_cdata
14751 + = SSER_CDATA(1);
14752 +
14753 +#endif /* CONFIG_ETRAX_SPI_SSER1 */
14754 +
14755 +static struct mmc_spi_platform_data crisv32_mmcspi_sser_pdata = {
14756 + .init = crisv32_mmcspi_sser_init,
14757 + .exit = __devexit_p(crisv32_mmcspi_sser_exit),
14758 + .detect_delay = 0,
14759 + .get_ro = crisv32_mmcspi_sser_get_ro,
14760 + .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
14761 + .setpower = NULL
14762 +};
14763 +
14764 +#endif /* CONFIG_SPI_ETRAX_SSER */
14765 +
14766 +#ifdef CONFIG_SPI_ETRAX_GPIO
14767 +
14768 +static const char crisv32_matching_spi_gpio_driver_name[] __init_or_module
14769 + = "spi_crisv32_gpio";
14770 +
14771 +/* Write-protect sense for the GPIO interface. */
14772 +
14773 +static int crisv32_mmcspi_gpio_get_ro(struct device *dev)
14774 +{
14775 + struct spi_device *spidev = to_spi_device(dev);
14776 + struct crisv32_mmc_spi_gpio_hwdata *gpio_defs
14777 + = spidev->controller_data;
14778 + struct crisv32_mmc_spi_pindata *pd = &gpio_defs->mmc;
14779 +
14780 + return crisv32_mmcspi_get_ro_helper(pd->pinstate);
14781 +}
14782 +
14783 +/* Initialize the MMC-specific parts of the MMC+SPI interface, GPIO. */
14784 +
14785 +static int crisv32_mmcspi_gpio_init(struct device *dev,
14786 + irqreturn_t (*intfunc)(int, void *),
14787 + void *xmmc_host)
14788 +{
14789 + struct mmc_host *mmc_host = xmmc_host;
14790 + struct spi_device *spidev = to_spi_device(dev);
14791 + struct crisv32_mmc_spi_gpio_hwdata *gpio_defs
14792 + = spidev->controller_data;
14793 + int ret = crisv32_mmcspi_config_common(spidev, intfunc, mmc_host,
14794 + &gpio_defs->mmc);
14795 + if (ret)
14796 + return ret;
14797 +
14798 + mmc_host->f_max = spidev->max_speed_hz;
14799 +
14800 + /*
14801 + * We don't set f_min, as the mmc code doesn't treat it as a
14802 + * limit, but as the frequency to use at initialization. We
14803 + * stick with what mmc_spi sets.
14804 + */
14805 + dev_info(dev, "CRIS v32 mmc_spi support hooked to SPI on GPIO"
14806 + " (bus #%d, cd: %s, wp: %s)\n",
14807 + spidev->master->bus_num,
14808 + CONFIGURED_PIN(gpio_defs->mmc.card_detect)
14809 + ? gpio_defs->mmc.card_detect : "(none)",
14810 + CONFIGURED_PIN(gpio_defs->mmc.write_protect)
14811 + ? gpio_defs->mmc.write_protect : "(none)");
14812 + return 0;
14813 +}
14814 +
14815 +/* Similarly, to undo crisv32_mmcspi_gpio_init. */
14816 +
14817 +static void crisv32_mmcspi_gpio_exit(struct device *dev, void *xmmc_host)
14818 +{
14819 + struct spi_device *spidev = to_spi_device(dev);
14820 + struct crisv32_mmc_spi_gpio_hwdata *gpio_defs
14821 + = spidev->controller_data;
14822 +
14823 + crisv32_mmcspi_deconfig_common(&gpio_defs->mmc);
14824 +}
14825 +
14826 +static const struct mmc_spi_platform_data crisv32_mmcspi_gpio_pdata = {
14827 + .init = crisv32_mmcspi_gpio_init,
14828 + .exit = __devexit_p(crisv32_mmcspi_gpio_exit),
14829 + .detect_delay = 0,
14830 + .get_ro = crisv32_mmcspi_gpio_get_ro,
14831 + .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
14832 + .setpower = NULL
14833 +};
14834 +
14835 +static struct crisv32_mmc_spi_pinstate crisv32_mmcspi_gpio_pinstate;
14836 +static const struct crisv32_mmc_spi_gpio_hwdata crisv32_mmcspi_gpio_cdata = {
14837 + {
14838 + .cs = CONFIG_ETRAX_SPI_CS_PIN,
14839 + .miso = CONFIG_ETRAX_SPI_DATAIN_PIN,
14840 + .mosi = CONFIG_ETRAX_SPI_DATAOUT_PIN,
14841 + .sclk = CONFIG_ETRAX_SPI_CLK_PIN
14842 + },
14843 + {
14844 + .card_detect = CONFIG_ETRAX_SPI_MMC_CD_GPIO_PIN,
14845 + .write_protect = CONFIG_ETRAX_SPI_MMC_WP_GPIO_PIN,
14846 + .pinstate = &crisv32_mmcspi_gpio_pinstate
14847 + }
14848 +};
14849 +#endif /* CONFIG_SPI_ETRAX_GPIO */
14850 +
14851 +struct crisv32_s_b_i_and_driver_info {
14852 + struct spi_board_info sbi;
14853 + const char *driver_name;
14854 +
14855 + /*
14856 + * We have to adjust the platform device at time of creation
14857 + * below, to allow the Linux DMA framework to handle DMA. In
14858 + * the name of simplicity, we state the dma:able property
14859 + * twice, a bit redundantly; here and in the controller_data
14860 + * structure pointed to by spi_board_info.
14861 + */
14862 + int dma_able;
14863 +};
14864 +
14865 +/* Convenience-macro to avoid typos causing diffs between sser ports. */
14866 +
14867 +#define SSER_CONFIG(n) \
14868 + { \
14869 + /* \
14870 + * No meaningful values for .irq or .chip_select, \
14871 + * so we leave them out. \
14872 + */ \
14873 + { \
14874 + .modalias = "mmc_spi", \
14875 + .platform_data \
14876 + = &crisv32_mmcspi_sser_pdata, \
14877 + /* \
14878 + * Casting to avoid a compiler const-warning. \
14879 + */ \
14880 + .controller_data \
14881 + = ((void *) \
14882 + &crisv32_mmcspi_sser##n##_cdata), \
14883 + .max_speed_hz = 50 * 1000 * 1000, \
14884 + .bus_num = n, \
14885 + /* \
14886 + * We only provide one mode, so it must be \
14887 + * default. \
14888 + */ \
14889 + .mode = SPI_MODE_3 \
14890 + }, \
14891 + crisv32_matching_spi_sser_driver_name, \
14892 + WITH_ETRAX_SPI_SSER##n##_DMA \
14893 + }
14894 +
14895 +static const struct crisv32_s_b_i_and_driver_info
14896 +crisv32_mmcspi_devices[] __initdata = {
14897 +#ifdef CONFIG_ETRAX_SPI_SSER0
14898 + SSER_CONFIG(0),
14899 +#endif
14900 +#ifdef CONFIG_ETRAX_SPI_SSER1
14901 + SSER_CONFIG(1),
14902 +#endif
14903 +#ifdef CONFIG_SPI_ETRAX_GPIO
14904 + {
14905 + {
14906 + .modalias = "mmc_spi",
14907 + .platform_data = &crisv32_mmcspi_gpio_pdata,
14908 + /* Casting to avoid a compiler const-warning. */
14909 + .controller_data
14910 + = (void *) &crisv32_mmcspi_gpio_cdata,
14911 +
14912 + /* No, we can't even reach this number with GPIO. */
14913 + .max_speed_hz = 5 * 1000 * 1000,
14914 + .bus_num = 2
14915 + },
14916 + crisv32_matching_spi_gpio_driver_name,
14917 + 0
14918 + },
14919 +#endif
14920 +};
14921 +
14922 +/* Must not be __initdata. */
14923 +static const char controller_data_ptr_name[] = "controller_data_ptr";
14924 +static u64 allmem_mask = ~(u32) 0;
14925 +
14926 +/*
14927 + * We have to register the SSER and GPIO "platform_device"s separately
14928 + * from the "spi_board_info"s in order to have the drivers separated
14929 + * from the hardware instance info.
14930 + */
14931 +
14932 +static int __init crisv32_register_mmcspi(void)
14933 +{
14934 + int ret;
14935 + void *retp;
14936 + const struct crisv32_s_b_i_and_driver_info *sbip;
14937 +
14938 + for (sbip = crisv32_mmcspi_devices;
14939 + sbip < crisv32_mmcspi_devices
14940 + + ARRAY_SIZE(crisv32_mmcspi_devices);
14941 + sbip++) {
14942 +
14943 + /*
14944 + * We have to pass the controller data as a device
14945 + * "resource" (FIXME: too?), so it can be available
14946 + * for the setup *before* starting the SPI core -
14947 + * which is where .controller_data makes it to the SPI
14948 + * structure!
14949 + */
14950 + struct resource mmcspi_res = {
14951 + .start = (resource_size_t) sbip->sbi.controller_data,
14952 + .end = (resource_size_t) sbip->sbi.controller_data,
14953 + .name = controller_data_ptr_name
14954 + };
14955 +
14956 + /*
14957 + * Presumably we could pass the irqs and register
14958 + * addresses and... as individual resources here
14959 + * instead of privately in spi_board_info
14960 + * .controller_data, and make that part a bit more
14961 + * readable. Maybe not worthwhile.
14962 + */
14963 + /* Need to cast away const here. FIXME: fix the pdrs API. */
14964 + retp = platform_device_alloc(sbip->driver_name,
14965 + sbip->sbi.bus_num);
14966 + if (IS_ERR_VALUE(PTR_ERR(retp)))
14967 + return PTR_ERR(retp);
14968 +
14969 + /*
14970 + * We can't use platform_device_register_simple as we
14971 + * want to set stuff in the device to mark that we'd
14972 + * prefer buffers explicitly passed as DMA-able.
14973 + * Disabling/omitting the "if" below, cause testing of
14974 + * the non-DMA-mem execution path of a DMA-capable
14975 + * driver.
14976 + */
14977 + if (sbip->dma_able) {
14978 + struct platform_device *pdev = retp;
14979 +
14980 + pdev->dev.dma_mask = &allmem_mask;
14981 + pdev->dev.coherent_dma_mask = allmem_mask;
14982 + }
14983 +
14984 + if ((ret = platform_device_add_resources(retp, &mmcspi_res, 1)) != 0
14985 + || (ret = platform_device_add(retp)) != 0) {
14986 + platform_device_put(retp);
14987 + return ret;
14988 + }
14989 +
14990 + /*
14991 + * The cost of keeping all info rooted at
14992 + * crisv32_mmcspi_devices is the allocation overhead
14993 + * for allocating separately each board info (in the
14994 + * unlikely event that there's more than one).
14995 + */
14996 + ret = spi_register_board_info(&sbip->sbi, 1);
14997 + if (ret != 0)
14998 + return ret;
14999 + }
15000 +
15001 + return 0;
15002 +}
15003 +#ifdef MODULE
15004 +#error "Non-module because spi_register_board_info is one-way; there's no unregister function"
15005 +#endif
15006 +
15007 +/*
15008 + * Needs to be called before __initcall/module_init because the SPI
15009 + * bus scanning happens when the actual driver registers with the SPI
15010 + * machinery (spi_bitbang_start/spi_register_master), not when the
15011 + * device registers (spi_register_board_info).
15012 + */
15013 +subsys_initcall(crisv32_register_mmcspi);
15014 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/drivers/cryptocop.c linux-2.6.19.2.dev/arch/cris/arch-v32/drivers/cryptocop.c
15015 --- linux-2.6.19.2.old/arch/cris/arch-v32/drivers/cryptocop.c 2007-01-10 20:10:37.000000000 +0100
15016 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/drivers/cryptocop.c 2007-01-09 10:29:20.000000000 +0100
15017 @@ -1,4 +1,4 @@
15018 -/* $Id: cryptocop.c,v 1.13 2005/04/21 17:27:55 henriken Exp $
15019 +/* $Id: cryptocop.c,v 1.22 2007/01/09 09:29:20 starvik Exp $
15020 *
15021 * Stream co-processor driver for the ETRAX FS
15022 *
15023 @@ -1718,7 +1718,7 @@
15024 * i = i + 1
15025 * }
15026 * i = Nk
15027 - *
15028 + *
15029 * while (i < (Nb * (Nr + 1))) {
15030 * temp = w[i - 1]
15031 * if ((i mod Nk) == 0) {
15032 @@ -1886,7 +1886,7 @@
15033 }
15034
15035 static irqreturn_t
15036 -dma_done_interrupt(int irq, void *dev_id, struct pt_regs * regs)
15037 +dma_done_interrupt(int irq, void *dev_id)
15038 {
15039 struct cryptocop_prio_job *done_job;
15040 reg_dma_rw_ack_intr ack_intr = {
15041 @@ -2226,6 +2226,7 @@
15042 &pj->iop->ctx_out, (char*)virt_to_phys(&pj->iop->ctx_out)));
15043
15044 /* Start input DMA. */
15045 + flush_dma_context(&pj->iop->ctx_in);
15046 DMA_START_CONTEXT(regi_dma9, virt_to_phys(&pj->iop->ctx_in));
15047
15048 /* Start output DMA. */
15049 @@ -3459,7 +3460,7 @@
15050 int err;
15051 int i;
15052 static int initialized = 0;
15053 -
15054 +
15055 if (initialized)
15056 return 0;
15057
15058 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/drivers/gpio.c linux-2.6.19.2.dev/arch/cris/arch-v32/drivers/gpio.c
15059 --- linux-2.6.19.2.old/arch/cris/arch-v32/drivers/gpio.c 2007-01-10 20:10:37.000000000 +0100
15060 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/drivers/gpio.c 2007-01-09 10:29:20.000000000 +0100
15061 @@ -1,68 +1,15 @@
15062 -/* $Id: gpio.c,v 1.16 2005/06/19 17:06:49 starvik Exp $
15063 - *
15064 +/*
15065 * ETRAX CRISv32 general port I/O device
15066 *
15067 - * Copyright (c) 1999, 2000, 2001, 2002, 2003 Axis Communications AB
15068 + * Copyright (c) 1999-2006 Axis Communications AB
15069 *
15070 * Authors: Bjorn Wesen (initial version)
15071 * Ola Knutsson (LED handling)
15072 * Johan Adolfsson (read/set directions, write, port G,
15073 * port to ETRAX FS.
15074 *
15075 - * $Log: gpio.c,v $
15076 - * Revision 1.16 2005/06/19 17:06:49 starvik
15077 - * Merge of Linux 2.6.12.
15078 - *
15079 - * Revision 1.15 2005/05/25 08:22:20 starvik
15080 - * Changed GPIO port order to fit packages/devices/axis-2.4.
15081 - *
15082 - * Revision 1.14 2005/04/24 18:35:08 starvik
15083 - * Updated with final register headers.
15084 - *
15085 - * Revision 1.13 2005/03/15 15:43:00 starvik
15086 - * dev_id needs to be supplied for shared IRQs.
15087 - *
15088 - * Revision 1.12 2005/03/10 17:12:00 starvik
15089 - * Protect alarm list with spinlock.
15090 - *
15091 - * Revision 1.11 2005/01/05 06:08:59 starvik
15092 - * No need to do local_irq_disable after local_irq_save.
15093 - *
15094 - * Revision 1.10 2004/11/19 08:38:31 starvik
15095 - * Removed old crap.
15096 - *
15097 - * Revision 1.9 2004/05/14 07:58:02 starvik
15098 - * Merge of changes from 2.4
15099 - *
15100 - * Revision 1.8 2003/09/11 07:29:50 starvik
15101 - * Merge of Linux 2.6.0-test5
15102 - *
15103 - * Revision 1.7 2003/07/10 13:25:46 starvik
15104 - * Compiles for 2.5.74
15105 - * Lindented ethernet.c
15106 - *
15107 - * Revision 1.6 2003/07/04 08:27:46 starvik
15108 - * Merge of Linux 2.5.74
15109 - *
15110 - * Revision 1.5 2003/06/10 08:26:37 johana
15111 - * Etrax -> ETRAX CRISv32
15112 - *
15113 - * Revision 1.4 2003/06/05 14:22:48 johana
15114 - * Initialise some_alarms.
15115 - *
15116 - * Revision 1.3 2003/06/05 10:15:46 johana
15117 - * New INTR_VECT macros.
15118 - * Enable interrupts in global config.
15119 - *
15120 - * Revision 1.2 2003/06/03 15:52:50 johana
15121 - * Initial CRIS v32 version.
15122 - *
15123 - * Revision 1.1 2003/06/03 08:53:15 johana
15124 - * Copy of os/lx25/arch/cris/arch-v10/drivers/gpio.c version 1.7.
15125 - *
15126 */
15127
15128 -
15129 #include <linux/module.h>
15130 #include <linux/sched.h>
15131 #include <linux/slab.h>
15132 @@ -85,6 +32,13 @@
15133 #include <asm/system.h>
15134 #include <asm/irq.h>
15135
15136 +#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
15137 +#include "i2c.h"
15138 +
15139 +#define VIRT_I2C_ADDR 0x40
15140 +#endif
15141 +
15142 +
15143 /* The following gio ports on ETRAX FS is available:
15144 * pa 8 bits, supports interrupts off, hi, low, set, posedge, negedge anyedge
15145 * pb 18 bits
15146 @@ -111,6 +65,10 @@
15147 static wait_queue_head_t *gpio_wq;
15148 #endif
15149
15150 +#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
15151 +static int virtual_gpio_ioctl(struct file *file, unsigned int cmd,
15152 + unsigned long arg);
15153 +#endif
15154 static int gpio_ioctl(struct inode *inode, struct file *file,
15155 unsigned int cmd, unsigned long arg);
15156 static ssize_t gpio_write(struct file * file, const char * buf, size_t count,
15157 @@ -148,55 +106,75 @@
15158 #define GIO_REG_RD_ADDR(reg) (volatile unsigned long*) (regi_gio + REG_RD_ADDR_gio_##reg )
15159 #define GIO_REG_WR_ADDR(reg) (volatile unsigned long*) (regi_gio + REG_RD_ADDR_gio_##reg )
15160 unsigned long led_dummy;
15161 +#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
15162 +static unsigned long virtual_dummy;
15163 +static unsigned long virtual_rw_pv_oe = CONFIG_ETRAX_DEF_GIO_PV_OE;
15164 +static unsigned short cached_virtual_gpio_read = 0;
15165 +#endif
15166
15167 -static volatile unsigned long *data_out[NUM_PORTS] = {
15168 - GIO_REG_WR_ADDR(rw_pa_dout),
15169 - GIO_REG_WR_ADDR(rw_pb_dout),
15170 +static volatile unsigned long *data_out[NUM_PORTS] = {
15171 + GIO_REG_WR_ADDR(rw_pa_dout),
15172 + GIO_REG_WR_ADDR(rw_pb_dout),
15173 &led_dummy,
15174 - GIO_REG_WR_ADDR(rw_pc_dout),
15175 - GIO_REG_WR_ADDR(rw_pd_dout),
15176 + GIO_REG_WR_ADDR(rw_pc_dout),
15177 + GIO_REG_WR_ADDR(rw_pd_dout),
15178 GIO_REG_WR_ADDR(rw_pe_dout),
15179 +#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
15180 + &virtual_dummy,
15181 +#endif
15182 };
15183
15184 -static volatile unsigned long *data_in[NUM_PORTS] = {
15185 - GIO_REG_RD_ADDR(r_pa_din),
15186 - GIO_REG_RD_ADDR(r_pb_din),
15187 +static volatile unsigned long *data_in[NUM_PORTS] = {
15188 + GIO_REG_RD_ADDR(r_pa_din),
15189 + GIO_REG_RD_ADDR(r_pb_din),
15190 &led_dummy,
15191 - GIO_REG_RD_ADDR(r_pc_din),
15192 - GIO_REG_RD_ADDR(r_pd_din),
15193 + GIO_REG_RD_ADDR(r_pc_din),
15194 + GIO_REG_RD_ADDR(r_pd_din),
15195 GIO_REG_RD_ADDR(r_pe_din),
15196 +#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
15197 + &virtual_dummy,
15198 +#endif
15199 };
15200
15201 -static unsigned long changeable_dir[NUM_PORTS] = {
15202 +static unsigned long changeable_dir[NUM_PORTS] = {
15203 CONFIG_ETRAX_PA_CHANGEABLE_DIR,
15204 CONFIG_ETRAX_PB_CHANGEABLE_DIR,
15205 0,
15206 CONFIG_ETRAX_PC_CHANGEABLE_DIR,
15207 - CONFIG_ETRAX_PD_CHANGEABLE_DIR,
15208 + CONFIG_ETRAX_PD_CHANGEABLE_DIR,
15209 CONFIG_ETRAX_PE_CHANGEABLE_DIR,
15210 +#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
15211 + CONFIG_ETRAX_PV_CHANGEABLE_DIR,
15212 +#endif
15213 };
15214
15215 -static unsigned long changeable_bits[NUM_PORTS] = {
15216 +static unsigned long changeable_bits[NUM_PORTS] = {
15217 CONFIG_ETRAX_PA_CHANGEABLE_BITS,
15218 CONFIG_ETRAX_PB_CHANGEABLE_BITS,
15219 0,
15220 CONFIG_ETRAX_PC_CHANGEABLE_BITS,
15221 CONFIG_ETRAX_PD_CHANGEABLE_BITS,
15222 CONFIG_ETRAX_PE_CHANGEABLE_BITS,
15223 +#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
15224 + CONFIG_ETRAX_PV_CHANGEABLE_BITS,
15225 +#endif
15226 };
15227
15228 -static volatile unsigned long *dir_oe[NUM_PORTS] = {
15229 - GIO_REG_WR_ADDR(rw_pa_oe),
15230 - GIO_REG_WR_ADDR(rw_pb_oe),
15231 +static volatile unsigned long *dir_oe[NUM_PORTS] = {
15232 + GIO_REG_WR_ADDR(rw_pa_oe),
15233 + GIO_REG_WR_ADDR(rw_pb_oe),
15234 &led_dummy,
15235 - GIO_REG_WR_ADDR(rw_pc_oe),
15236 - GIO_REG_WR_ADDR(rw_pd_oe),
15237 + GIO_REG_WR_ADDR(rw_pc_oe),
15238 + GIO_REG_WR_ADDR(rw_pd_oe),
15239 GIO_REG_WR_ADDR(rw_pe_oe),
15240 +#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
15241 + &virtual_rw_pv_oe,
15242 +#endif
15243 };
15244
15245
15246
15247 -static unsigned int
15248 +static unsigned int
15249 gpio_poll(struct file *file,
15250 poll_table *wait)
15251 {
15252 @@ -278,7 +256,7 @@
15253 return 0;
15254
15255 if ((data & priv->highalarm) ||
15256 - (~data & priv->lowalarm)) {
15257 + (~data & priv->lowalarm)) {
15258 mask = POLLIN|POLLRDNORM;
15259 }
15260
15261 @@ -288,11 +266,26 @@
15262
15263 int etrax_gpio_wake_up_check(void)
15264 {
15265 - struct gpio_private *priv = alarmlist;
15266 + struct gpio_private *priv;
15267 unsigned long data = 0;
15268 + unsigned long flags;
15269 int ret = 0;
15270 + spin_lock_irqsave(&alarm_lock, flags);
15271 + priv = alarmlist;
15272 while (priv) {
15273 +#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
15274 + if (priv->minor == GPIO_MINOR_V) {
15275 + data = (unsigned long)cached_virtual_gpio_read;
15276 + }
15277 + else {
15278 + data = *data_in[priv->minor];
15279 + if (priv->minor == GPIO_MINOR_A) {
15280 + priv->lowalarm |= (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN);
15281 + }
15282 + }
15283 +#else
15284 data = *data_in[priv->minor];
15285 +#endif
15286 if ((data & priv->highalarm) ||
15287 (~data & priv->lowalarm)) {
15288 DP(printk("etrax_gpio_wake_up_check %i\n",priv->minor));
15289 @@ -301,11 +294,12 @@
15290 }
15291 priv = priv->next;
15292 }
15293 + spin_unlock_irqrestore(&alarm_lock, flags);
15294 return ret;
15295 }
15296
15297 -static irqreturn_t
15298 -gpio_poll_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
15299 +static irqreturn_t
15300 +gpio_poll_timer_interrupt(int irq, void *dev_id)
15301 {
15302 if (gpio_some_alarms) {
15303 return IRQ_RETVAL(etrax_gpio_wake_up_check());
15304 @@ -314,14 +308,17 @@
15305 }
15306
15307 static irqreturn_t
15308 -gpio_pa_interrupt(int irq, void *dev_id, struct pt_regs *regs)
15309 +gpio_pa_interrupt(int irq, void *dev_id)
15310 {
15311 reg_gio_rw_intr_mask intr_mask;
15312 reg_gio_r_masked_intr masked_intr;
15313 reg_gio_rw_ack_intr ack_intr;
15314 unsigned long tmp;
15315 unsigned long tmp2;
15316 -
15317 +#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
15318 + unsigned char enable_gpiov_ack = 0;
15319 +#endif
15320 +
15321 /* Find what PA interrupts are active */
15322 masked_intr = REG_RD(gio, regi_gio, r_masked_intr);
15323 tmp = REG_TYPE_CONV(unsigned long, reg_gio_r_masked_intr, masked_intr);
15324 @@ -331,6 +328,17 @@
15325 tmp &= (gpio_pa_high_alarms | gpio_pa_low_alarms);
15326 spin_unlock(&alarm_lock);
15327
15328 +#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
15329 + /* Something changed on virtual GPIO. Interrupt is acked by
15330 + * reading the device.
15331 + */
15332 + if (tmp & (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN)) {
15333 + i2c_read(VIRT_I2C_ADDR, (void *)&cached_virtual_gpio_read,
15334 + sizeof(cached_virtual_gpio_read));
15335 + enable_gpiov_ack = 1;
15336 + }
15337 +#endif
15338 +
15339 /* Ack them */
15340 ack_intr = REG_TYPE_CONV(reg_gio_rw_ack_intr, unsigned long, tmp);
15341 REG_WR(gio, regi_gio, rw_ack_intr, ack_intr);
15342 @@ -339,13 +347,21 @@
15343 intr_mask = REG_RD(gio, regi_gio, rw_intr_mask);
15344 tmp2 = REG_TYPE_CONV(unsigned long, reg_gio_rw_intr_mask, intr_mask);
15345 tmp2 &= ~tmp;
15346 +#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
15347 + /* Do not disable interrupt on virtual GPIO. Changes on virtual
15348 + * pins are only noticed by an interrupt.
15349 + */
15350 + if (enable_gpiov_ack) {
15351 + tmp2 |= (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN);
15352 + }
15353 +#endif
15354 intr_mask = REG_TYPE_CONV(reg_gio_rw_intr_mask, unsigned long, tmp2);
15355 REG_WR(gio, regi_gio, rw_intr_mask, intr_mask);
15356
15357 if (gpio_some_alarms) {
15358 return IRQ_RETVAL(etrax_gpio_wake_up_check());
15359 }
15360 - return IRQ_NONE;
15361 + return IRQ_NONE;
15362 }
15363
15364
15365 @@ -358,8 +374,13 @@
15366 unsigned long shadow;
15367 volatile unsigned long *port;
15368 ssize_t retval = count;
15369 - /* Only bits 0-7 may be used for write operations but allow all
15370 + /* Only bits 0-7 may be used for write operations but allow all
15371 devices except leds... */
15372 +#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
15373 + if (priv->minor == GPIO_MINOR_V) {
15374 + return -EFAULT;
15375 + }
15376 +#endif
15377 if (priv->minor == GPIO_MINOR_LEDS) {
15378 return -EFAULT;
15379 }
15380 @@ -416,25 +437,24 @@
15381
15382 static int
15383 gpio_open(struct inode *inode, struct file *filp)
15384 -{
15385 +{
15386 struct gpio_private *priv;
15387 int p = iminor(inode);
15388
15389 if (p > GPIO_MINOR_LAST)
15390 return -EINVAL;
15391
15392 - priv = (struct gpio_private *)kmalloc(sizeof(struct gpio_private),
15393 + priv = (struct gpio_private *)kmalloc(sizeof(struct gpio_private),
15394 GFP_KERNEL);
15395
15396 if (!priv)
15397 return -ENOMEM;
15398 + memset(priv, 0, sizeof(*priv));
15399
15400 priv->minor = p;
15401
15402 - /* initialize the io/alarm struct and link it into our alarmlist */
15403 + /* initialize the io/alarm struct */
15404
15405 - priv->next = alarmlist;
15406 - alarmlist = priv;
15407 priv->clk_mask = 0;
15408 priv->data_mask = 0;
15409 priv->highalarm = 0;
15410 @@ -443,20 +463,30 @@
15411
15412 filp->private_data = (void *)priv;
15413
15414 + /* link it into our alarmlist */
15415 + spin_lock_irq(&alarm_lock);
15416 + priv->next = alarmlist;
15417 + alarmlist = priv;
15418 + spin_unlock_irq(&alarm_lock);
15419 +
15420 return 0;
15421 }
15422
15423 static int
15424 gpio_release(struct inode *inode, struct file *filp)
15425 {
15426 - struct gpio_private *p = alarmlist;
15427 - struct gpio_private *todel = (struct gpio_private *)filp->private_data;
15428 + struct gpio_private *p;
15429 + struct gpio_private *todel;
15430 /* local copies while updating them: */
15431 unsigned long a_high, a_low;
15432 unsigned long some_alarms;
15433
15434 /* unlink from alarmlist and free the private structure */
15435
15436 + spin_lock_irq(&alarm_lock);
15437 + p = alarmlist;
15438 + todel = (struct gpio_private *)filp->private_data;
15439 +
15440 if (p == todel) {
15441 alarmlist = todel->next;
15442 } else {
15443 @@ -473,6 +503,9 @@
15444 a_low = 0;
15445 while (p) {
15446 if (p->minor == GPIO_MINOR_A) {
15447 +#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
15448 + p->lowalarm |= (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN);
15449 +#endif
15450 a_high |= p->highalarm;
15451 a_low |= p->lowalarm;
15452 }
15453 @@ -483,23 +516,30 @@
15454 p = p->next;
15455 }
15456
15457 - spin_lock(&alarm_lock);
15458 +#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
15459 + /* Variables 'some_alarms' and 'a_low' needs to be set here again
15460 + * to ensure that interrupt for virtual GPIO is handled.
15461 + */
15462 + some_alarms = 1;
15463 + a_low |= (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN);
15464 +#endif
15465 +
15466 gpio_some_alarms = some_alarms;
15467 gpio_pa_high_alarms = a_high;
15468 gpio_pa_low_alarms = a_low;
15469 - spin_unlock(&alarm_lock);
15470 + spin_unlock_irq(&alarm_lock);
15471
15472 return 0;
15473 }
15474
15475 -/* Main device API. ioctl's to read/set/clear bits, as well as to
15476 +/* Main device API. ioctl's to read/set/clear bits, as well as to
15477 * set alarms to wait for using a subsequent select().
15478 */
15479
15480 unsigned long inline setget_input(struct gpio_private *priv, unsigned long arg)
15481 {
15482 - /* Set direction 0=unchanged 1=input,
15483 - * return mask with 1=input
15484 + /* Set direction 0=unchanged 1=input,
15485 + * return mask with 1=input
15486 */
15487 unsigned long flags;
15488 unsigned long dir_shadow;
15489 @@ -512,6 +552,10 @@
15490
15491 if (priv->minor == GPIO_MINOR_A)
15492 dir_shadow ^= 0xFF; /* Only 8 bits */
15493 +#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
15494 + else if (priv->minor == GPIO_MINOR_V)
15495 + dir_shadow ^= 0xFFFF; /* Only 16 bits */
15496 +#endif
15497 else
15498 dir_shadow ^= 0x3FFFF; /* Only 18 bits */
15499 return dir_shadow;
15500 @@ -546,6 +590,11 @@
15501 return -EINVAL;
15502 }
15503
15504 +#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
15505 + if (priv->minor == GPIO_MINOR_V)
15506 + return virtual_gpio_ioctl(file, cmd, arg);
15507 +#endif
15508 +
15509 switch (_IOC_NR(cmd)) {
15510 case IO_READBITS: /* Use IO_READ_INBITS and IO_READ_OUTBITS instead */
15511 // read the port
15512 @@ -553,8 +602,6 @@
15513 break;
15514 case IO_SETBITS:
15515 local_irq_save(flags);
15516 - if (arg & 0x04)
15517 - printk("GPIO SET 2\n");
15518 // set changeable bits with a 1 in arg
15519 shadow = *data_out[priv->minor];
15520 shadow |= (arg & changeable_bits[priv->minor]);
15521 @@ -563,8 +610,6 @@
15522 break;
15523 case IO_CLRBITS:
15524 local_irq_save(flags);
15525 - if (arg & 0x04)
15526 - printk("GPIO CLR 2\n");
15527 // clear changeable bits with a 1 in arg
15528 shadow = *data_out[priv->minor];
15529 shadow &= ~(arg & changeable_bits[priv->minor]);
15530 @@ -574,52 +619,52 @@
15531 case IO_HIGHALARM:
15532 // set alarm when bits with 1 in arg go high
15533 priv->highalarm |= arg;
15534 - spin_lock(&alarm_lock);
15535 + spin_lock_irqsave(&alarm_lock, flags);
15536 gpio_some_alarms = 1;
15537 if (priv->minor == GPIO_MINOR_A) {
15538 gpio_pa_high_alarms |= arg;
15539 }
15540 - spin_unlock(&alarm_lock);
15541 + spin_unlock_irqrestore(&alarm_lock, flags);
15542 break;
15543 case IO_LOWALARM:
15544 // set alarm when bits with 1 in arg go low
15545 priv->lowalarm |= arg;
15546 - spin_lock(&alarm_lock);
15547 + spin_lock_irqsave(&alarm_lock, flags);
15548 gpio_some_alarms = 1;
15549 if (priv->minor == GPIO_MINOR_A) {
15550 gpio_pa_low_alarms |= arg;
15551 }
15552 - spin_unlock(&alarm_lock);
15553 + spin_unlock_irqrestore(&alarm_lock, flags);
15554 break;
15555 case IO_CLRALARM:
15556 // clear alarm for bits with 1 in arg
15557 priv->highalarm &= ~arg;
15558 priv->lowalarm &= ~arg;
15559 - spin_lock(&alarm_lock);
15560 + spin_lock_irqsave(&alarm_lock, flags);
15561 if (priv->minor == GPIO_MINOR_A) {
15562 - if (gpio_pa_high_alarms & arg ||
15563 + if (gpio_pa_high_alarms & arg ||
15564 gpio_pa_low_alarms & arg) {
15565 /* Must update the gpio_pa_*alarms masks */
15566 }
15567 }
15568 - spin_unlock(&alarm_lock);
15569 + spin_unlock_irqrestore(&alarm_lock, flags);
15570 break;
15571 case IO_READDIR: /* Use IO_SETGET_INPUT/OUTPUT instead! */
15572 /* Read direction 0=input 1=output */
15573 return *dir_oe[priv->minor];
15574 case IO_SETINPUT: /* Use IO_SETGET_INPUT instead! */
15575 - /* Set direction 0=unchanged 1=input,
15576 - * return mask with 1=input
15577 + /* Set direction 0=unchanged 1=input,
15578 + * return mask with 1=input
15579 */
15580 return setget_input(priv, arg);
15581 break;
15582 case IO_SETOUTPUT: /* Use IO_SETGET_OUTPUT instead! */
15583 - /* Set direction 0=unchanged 1=output,
15584 - * return mask with 1=output
15585 + /* Set direction 0=unchanged 1=output,
15586 + * return mask with 1=output
15587 */
15588 return setget_output(priv, arg);
15589
15590 - case IO_CFG_WRITE_MODE:
15591 + case IO_CFG_WRITE_MODE:
15592 {
15593 unsigned long dir_shadow;
15594 dir_shadow = *dir_oe[priv->minor];
15595 @@ -641,7 +686,7 @@
15596 }
15597 break;
15598 }
15599 - case IO_READ_INBITS:
15600 + case IO_READ_INBITS:
15601 /* *arg is result of reading the input pins */
15602 val = *data_in[priv->minor];
15603 if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
15604 @@ -654,7 +699,7 @@
15605 if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
15606 return -EFAULT;
15607 break;
15608 - case IO_SETGET_INPUT:
15609 + case IO_SETGET_INPUT:
15610 /* bits set in *arg is set to input,
15611 * *arg updated with current input pins.
15612 */
15613 @@ -684,6 +729,132 @@
15614 return 0;
15615 }
15616
15617 +#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
15618 +static int
15619 +virtual_gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
15620 +{
15621 + unsigned long flags;
15622 + unsigned short val;
15623 + unsigned short shadow;
15624 + struct gpio_private *priv = (struct gpio_private *)file->private_data;
15625 +
15626 + switch (_IOC_NR(cmd)) {
15627 + case IO_SETBITS:
15628 + local_irq_save(flags);
15629 + // set changeable bits with a 1 in arg
15630 + i2c_read(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow));
15631 + shadow |= ~*dir_oe[priv->minor];
15632 + shadow |= (arg & changeable_bits[priv->minor]);
15633 + i2c_write(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow));
15634 + local_irq_restore(flags);
15635 + break;
15636 + case IO_CLRBITS:
15637 + local_irq_save(flags);
15638 + // clear changeable bits with a 1 in arg
15639 + i2c_read(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow));
15640 + shadow |= ~*dir_oe[priv->minor];
15641 + shadow &= ~(arg & changeable_bits[priv->minor]);
15642 + i2c_write(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow));
15643 + local_irq_restore(flags);
15644 + break;
15645 + case IO_HIGHALARM:
15646 + // set alarm when bits with 1 in arg go high
15647 + priv->highalarm |= arg;
15648 + spin_lock(&alarm_lock);
15649 + gpio_some_alarms = 1;
15650 + spin_unlock(&alarm_lock);
15651 + break;
15652 + case IO_LOWALARM:
15653 + // set alarm when bits with 1 in arg go low
15654 + priv->lowalarm |= arg;
15655 + spin_lock(&alarm_lock);
15656 + gpio_some_alarms = 1;
15657 + spin_unlock(&alarm_lock);
15658 + break;
15659 + case IO_CLRALARM:
15660 + // clear alarm for bits with 1 in arg
15661 + priv->highalarm &= ~arg;
15662 + priv->lowalarm &= ~arg;
15663 + spin_lock(&alarm_lock);
15664 + spin_unlock(&alarm_lock);
15665 + break;
15666 + case IO_CFG_WRITE_MODE:
15667 + {
15668 + unsigned long dir_shadow;
15669 + dir_shadow = *dir_oe[priv->minor];
15670 +
15671 + priv->clk_mask = arg & 0xFF;
15672 + priv->data_mask = (arg >> 8) & 0xFF;
15673 + priv->write_msb = (arg >> 16) & 0x01;
15674 + /* Check if we're allowed to change the bits and
15675 + * the direction is correct
15676 + */
15677 + if (!((priv->clk_mask & changeable_bits[priv->minor]) &&
15678 + (priv->data_mask & changeable_bits[priv->minor]) &&
15679 + (priv->clk_mask & dir_shadow) &&
15680 + (priv->data_mask & dir_shadow)))
15681 + {
15682 + priv->clk_mask = 0;
15683 + priv->data_mask = 0;
15684 + return -EPERM;
15685 + }
15686 + break;
15687 + }
15688 + case IO_READ_INBITS:
15689 + /* *arg is result of reading the input pins */
15690 + val = cached_virtual_gpio_read;
15691 + val &= ~*dir_oe[priv->minor];
15692 + if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
15693 + return -EFAULT;
15694 + return 0;
15695 + break;
15696 + case IO_READ_OUTBITS:
15697 + /* *arg is result of reading the output shadow */
15698 + i2c_read(VIRT_I2C_ADDR, (void *)&val, sizeof(val));
15699 + val &= *dir_oe[priv->minor];
15700 + if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
15701 + return -EFAULT;
15702 + break;
15703 + case IO_SETGET_INPUT:
15704 + {
15705 + /* bits set in *arg is set to input,
15706 + * *arg updated with current input pins.
15707 + */
15708 + unsigned short input_mask = ~*dir_oe[priv->minor];
15709 + if (copy_from_user(&val, (unsigned long*)arg, sizeof(val)))
15710 + return -EFAULT;
15711 + val = setget_input(priv, val);
15712 + if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
15713 + return -EFAULT;
15714 + if ((input_mask & val) != input_mask) {
15715 + /* Input pins changed. All ports desired as input
15716 + * should be set to logic 1.
15717 + */
15718 + unsigned short change = input_mask ^ val;
15719 + i2c_read(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow));
15720 + shadow &= ~change;
15721 + shadow |= val;
15722 + i2c_write(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow));
15723 + }
15724 + break;
15725 + }
15726 + case IO_SETGET_OUTPUT:
15727 + /* bits set in *arg is set to output,
15728 + * *arg updated with current output pins.
15729 + */
15730 + if (copy_from_user(&val, (unsigned long*)arg, sizeof(val)))
15731 + return -EFAULT;
15732 + val = setget_output(priv, val);
15733 + if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
15734 + return -EFAULT;
15735 + break;
15736 + default:
15737 + return -EINVAL;
15738 + } /* switch */
15739 + return 0;
15740 +}
15741 +#endif /* CONFIG_ETRAX_VIRTUAL_GPIO */
15742 +
15743 static int
15744 gpio_leds_ioctl(unsigned int cmd, unsigned long arg)
15745 {
15746 @@ -714,6 +885,66 @@
15747 .release = gpio_release,
15748 };
15749
15750 +#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
15751 +static void
15752 +virtual_gpio_init(void)
15753 +{
15754 + reg_gio_rw_intr_cfg intr_cfg;
15755 + reg_gio_rw_intr_mask intr_mask;
15756 + unsigned short shadow;
15757 +
15758 + shadow = ~virtual_rw_pv_oe; /* Input ports should be set to logic 1 */
15759 + shadow |= CONFIG_ETRAX_DEF_GIO_PV_OUT;
15760 + i2c_write(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow));
15761 +
15762 + /* Set interrupt mask and on what state the interrupt shall trigger.
15763 + * For virtual gpio the interrupt shall trigger on logic '0'.
15764 + */
15765 + intr_cfg = REG_RD(gio, regi_gio, rw_intr_cfg);
15766 + intr_mask = REG_RD(gio, regi_gio, rw_intr_mask);
15767 +
15768 + switch (CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN) {
15769 + case 0:
15770 + intr_cfg.pa0 = regk_gio_lo;
15771 + intr_mask.pa0 = regk_gio_yes;
15772 + break;
15773 + case 1:
15774 + intr_cfg.pa1 = regk_gio_lo;
15775 + intr_mask.pa1 = regk_gio_yes;
15776 + break;
15777 + case 2:
15778 + intr_cfg.pa2 = regk_gio_lo;
15779 + intr_mask.pa2 = regk_gio_yes;
15780 + break;
15781 + case 3:
15782 + intr_cfg.pa3 = regk_gio_lo;
15783 + intr_mask.pa3 = regk_gio_yes;
15784 + break;
15785 + case 4:
15786 + intr_cfg.pa4 = regk_gio_lo;
15787 + intr_mask.pa4 = regk_gio_yes;
15788 + break;
15789 + case 5:
15790 + intr_cfg.pa5 = regk_gio_lo;
15791 + intr_mask.pa5 = regk_gio_yes;
15792 + break;
15793 + case 6:
15794 + intr_cfg.pa6 = regk_gio_lo;
15795 + intr_mask.pa6 = regk_gio_yes;
15796 + break;
15797 + case 7:
15798 + intr_cfg.pa7 = regk_gio_lo;
15799 + intr_mask.pa7 = regk_gio_yes;
15800 + break;
15801 + }
15802 +
15803 + REG_WR(gio, regi_gio, rw_intr_cfg, intr_cfg);
15804 + REG_WR(gio, regi_gio, rw_intr_mask, intr_mask);
15805 +
15806 + gpio_pa_low_alarms |= (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN);
15807 + gpio_some_alarms = 1;
15808 +}
15809 +#endif
15810
15811 /* main driver initialization routine, called from mem.c */
15812
15813 @@ -732,17 +963,18 @@
15814 }
15815
15816 /* Clear all leds */
15817 - LED_NETWORK_SET(0);
15818 + LED_NETWORK_GRP0_SET(0);
15819 + LED_NETWORK_GRP1_SET(0);
15820 LED_ACTIVE_SET(0);
15821 LED_DISK_READ(0);
15822 LED_DISK_WRITE(0);
15823
15824 - printk("ETRAX FS GPIO driver v2.5, (c) 2003-2005 Axis Communications AB\n");
15825 + printk("ETRAX FS GPIO driver v2.5, (c) 2003-2006 Axis Communications AB\n");
15826 /* We call etrax_gpio_wake_up_check() from timer interrupt and
15827 * from cpu_idle() in kernel/process.c
15828 * The check in cpu_idle() reduces latency from ~15 ms to ~6 ms
15829 * in some tests.
15830 - */
15831 + */
15832 if (request_irq(TIMER_INTR_VECT, gpio_poll_timer_interrupt,
15833 IRQF_SHARED | IRQF_DISABLED,"gpio poll", &alarmlist)) {
15834 printk("err: timer0 irq for gpio\n");
15835 @@ -757,6 +989,10 @@
15836 intr_mask.gen_io = 1;
15837 REG_WR(intr_vect, regi_irq, rw_mask, intr_mask);
15838
15839 +#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
15840 + virtual_gpio_init();
15841 +#endif
15842 +
15843 return res;
15844 }
15845
15846 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/drivers/i2c.c linux-2.6.19.2.dev/arch/cris/arch-v32/drivers/i2c.c
15847 --- linux-2.6.19.2.old/arch/cris/arch-v32/drivers/i2c.c 2007-01-10 20:10:37.000000000 +0100
15848 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/drivers/i2c.c 2006-11-06 16:48:06.000000000 +0100
15849 @@ -8,11 +8,11 @@
15850 *!
15851 *! Nov 30 1998 Torbjorn Eliasson Initial version.
15852 *! Bjorn Wesen Elinux kernel version.
15853 -*! Jan 14 2000 Johan Adolfsson Fixed PB shadow register stuff -
15854 +*! Jan 14 2000 Johan Adolfsson Fixed PB shadow register stuff -
15855 *! don't use PB_I2C if DS1302 uses same bits,
15856 *! use PB.
15857 *| June 23 2003 Pieter Grimmerink Added 'i2c_sendnack'. i2c_readreg now
15858 -*| generates nack on last received byte,
15859 +*| generates nack on last received byte,
15860 *| instead of ack.
15861 *| i2c_getack changed data level while clock
15862 *| was high, causing DS75 to see a stop condition
15863 @@ -22,7 +22,7 @@
15864 *! (C) Copyright 1999-2002 Axis Communications AB, LUND, SWEDEN
15865 *!
15866 *!***************************************************************************/
15867 -/* $Id: i2c.c,v 1.2 2005/05/09 15:29:49 starvik Exp $ */
15868 +/* $Id: i2c.c,v 1.6 2006/11/06 15:48:06 imres Exp $ */
15869 /****************** INCLUDE FILES SECTION ***********************************/
15870
15871 #include <linux/module.h>
15872 @@ -60,8 +60,8 @@
15873 #define I2C_DATA_HIGH 1
15874 #define I2C_DATA_LOW 0
15875
15876 -#define i2c_enable()
15877 -#define i2c_disable()
15878 +#define i2c_enable()
15879 +#define i2c_disable()
15880
15881 /* enable or disable output-enable, to select output or input on the i2c bus */
15882
15883 @@ -79,6 +79,8 @@
15884
15885 #define i2c_delay(usecs) udelay(usecs)
15886
15887 +static DEFINE_SPINLOCK(i2c_lock); /* Protect directions etc */
15888 +
15889 /****************** VARIABLE SECTION ************************************/
15890
15891 static struct crisv32_iopin cris_i2c_clk;
15892 @@ -154,7 +156,7 @@
15893 } else {
15894 i2c_data(I2C_DATA_LOW);
15895 }
15896 -
15897 +
15898 i2c_delay(CLOCK_LOW_TIME/2);
15899 i2c_clk(I2C_CLOCK_HIGH);
15900 i2c_delay(CLOCK_HIGH_TIME);
15901 @@ -213,7 +215,7 @@
15902 }
15903 i2c_clk(I2C_CLOCK_HIGH);
15904 i2c_delay(CLOCK_HIGH_TIME);
15905 -
15906 +
15907 /*
15908 * we leave the clock low, getbyte is usually followed
15909 * by sendack/nack, they assume the clock to be low
15910 @@ -252,6 +254,7 @@
15911 * generate ACK clock pulse
15912 */
15913 i2c_clk(I2C_CLOCK_HIGH);
15914 +#if 0
15915 /*
15916 * Use PORT PB instead of I2C
15917 * for input. (I2C not working)
15918 @@ -264,6 +267,8 @@
15919 i2c_data(1);
15920 i2c_disable();
15921 i2c_dir_in();
15922 +#endif
15923 +
15924 /*
15925 * now wait for ack
15926 */
15927 @@ -285,13 +290,15 @@
15928 * before we enable our output. If we keep data high
15929 * and enable output, we would generate a stop condition.
15930 */
15931 +#if 0
15932 i2c_data(I2C_DATA_LOW);
15933 -
15934 +
15935 /*
15936 * end clock pulse
15937 */
15938 i2c_enable();
15939 i2c_dir_out();
15940 +#endif
15941 i2c_clk(I2C_CLOCK_LOW);
15942 i2c_delay(CLOCK_HIGH_TIME/4);
15943 /*
15944 @@ -338,7 +345,7 @@
15945 */
15946 i2c_data(I2C_DATA_HIGH);
15947 i2c_delay(CLOCK_LOW_TIME);
15948 -
15949 +
15950 i2c_dir_in();
15951 }
15952
15953 @@ -369,24 +376,160 @@
15954 i2c_delay(CLOCK_HIGH_TIME);
15955 i2c_clk(I2C_CLOCK_LOW);
15956 i2c_delay(CLOCK_LOW_TIME);
15957 -
15958 +
15959 i2c_dir_in();
15960 }
15961
15962 /*#---------------------------------------------------------------------------
15963 *#
15964 +*# FUNCTION NAME: i2c_write
15965 +*#
15966 +*# DESCRIPTION : Writes a value to an I2C device
15967 +*#
15968 +*#--------------------------------------------------------------------------*/
15969 +int
15970 +i2c_write(unsigned char theSlave, void *data, size_t nbytes)
15971 +{
15972 + int error, cntr = 3;
15973 + unsigned char bytes_wrote = 0;
15974 + unsigned char value;
15975 + unsigned long flags;
15976 +
15977 + spin_lock(&i2c_lock);
15978 +
15979 + do {
15980 + error = 0;
15981 + /*
15982 + * we don't like to be interrupted
15983 + */
15984 + local_irq_save(flags);
15985 +
15986 + i2c_start();
15987 + /*
15988 + * send slave address
15989 + */
15990 + i2c_outbyte((theSlave & 0xfe));
15991 + /*
15992 + * wait for ack
15993 + */
15994 + if(!i2c_getack())
15995 + error = 1;
15996 + /*
15997 + * send data
15998 + */
15999 + for (bytes_wrote = 0; bytes_wrote < nbytes; bytes_wrote++) {
16000 + memcpy(&value, data + bytes_wrote, sizeof value);
16001 + i2c_outbyte(value);
16002 + /*
16003 + * now it's time to wait for ack
16004 + */
16005 + if (!i2c_getack())
16006 + error |= 4;
16007 + }
16008 + /*
16009 + * end byte stream
16010 + */
16011 + i2c_stop();
16012 + /*
16013 + * enable interrupt again
16014 + */
16015 + local_irq_restore(flags);
16016 +
16017 + } while(error && cntr--);
16018 +
16019 + i2c_delay(CLOCK_LOW_TIME);
16020 +
16021 + spin_unlock(&i2c_lock);
16022 +
16023 + return -error;
16024 +}
16025 +
16026 +/*#---------------------------------------------------------------------------
16027 +*#
16028 +*# FUNCTION NAME: i2c_read
16029 +*#
16030 +*# DESCRIPTION : Reads a value from an I2C device
16031 +*#
16032 +*#--------------------------------------------------------------------------*/
16033 +int
16034 +i2c_read(unsigned char theSlave, void *data, size_t nbytes)
16035 +{
16036 + unsigned char b = 0;
16037 + unsigned char bytes_read = 0;
16038 + int error, cntr = 3;
16039 + unsigned long flags;
16040 +
16041 + spin_lock(&i2c_lock);
16042 +
16043 + do {
16044 + error = 0;
16045 + memset(data, 0, nbytes);
16046 + /*
16047 + * we don't like to be interrupted
16048 + */
16049 + local_irq_save(flags);
16050 + /*
16051 + * generate start condition
16052 + */
16053 + i2c_start();
16054 +
16055 + /*
16056 + * send slave address
16057 + */
16058 + i2c_outbyte((theSlave | 0x01));
16059 + /*
16060 + * wait for ack
16061 + */
16062 + if(!i2c_getack())
16063 + error = 1;
16064 + /*
16065 + * fetch data
16066 + */
16067 + for (bytes_read = 0; bytes_read < nbytes; bytes_read++) {
16068 + b = i2c_inbyte();
16069 + memcpy(data + bytes_read, &b, sizeof b);
16070 +
16071 + if (bytes_read < (nbytes - 1)) {
16072 + i2c_sendack();
16073 + }
16074 + }
16075 + /*
16076 + * last received byte needs to be nacked
16077 + * instead of acked
16078 + */
16079 + i2c_sendnack();
16080 + /*
16081 + * end sequence
16082 + */
16083 + i2c_stop();
16084 + /*
16085 + * enable interrupt again
16086 + */
16087 + local_irq_restore(flags);
16088 +
16089 + } while(error && cntr--);
16090 +
16091 + spin_unlock(&i2c_lock);
16092 +
16093 + return -error;
16094 +}
16095 +
16096 +/*#---------------------------------------------------------------------------
16097 +*#
16098 *# FUNCTION NAME: i2c_writereg
16099 *#
16100 *# DESCRIPTION : Writes a value to an I2C device
16101 *#
16102 *#--------------------------------------------------------------------------*/
16103 int
16104 -i2c_writereg(unsigned char theSlave, unsigned char theReg,
16105 +i2c_writereg(unsigned char theSlave, unsigned char theReg,
16106 unsigned char theValue)
16107 {
16108 int error, cntr = 3;
16109 unsigned long flags;
16110
16111 + spin_lock(&i2c_lock);
16112 +
16113 do {
16114 error = 0;
16115 /*
16116 @@ -431,10 +574,12 @@
16117 * enable interrupt again
16118 */
16119 local_irq_restore(flags);
16120 -
16121 +
16122 } while(error && cntr--);
16123
16124 i2c_delay(CLOCK_LOW_TIME);
16125 +
16126 + spin_unlock(&i2c_lock);
16127
16128 return -error;
16129 }
16130 @@ -453,6 +598,8 @@
16131 int error, cntr = 3;
16132 unsigned long flags;
16133
16134 + spin_lock(&i2c_lock);
16135 +
16136 do {
16137 error = 0;
16138 /*
16139 @@ -463,7 +610,7 @@
16140 * generate start condition
16141 */
16142 i2c_start();
16143 -
16144 +
16145 /*
16146 * send slave address
16147 */
16148 @@ -482,7 +629,7 @@
16149 * now it's time to wait for ack
16150 */
16151 if(!i2c_getack())
16152 - error = 1;
16153 + error |= 2;
16154 /*
16155 * repeat start condition
16156 */
16157 @@ -496,7 +643,7 @@
16158 * wait for ack
16159 */
16160 if(!i2c_getack())
16161 - error = 1;
16162 + error |= 4;
16163 /*
16164 * fetch register
16165 */
16166 @@ -514,9 +661,11 @@
16167 * enable interrupt again
16168 */
16169 local_irq_restore(flags);
16170 -
16171 +
16172 } while(error && cntr--);
16173
16174 + spin_unlock(&i2c_lock);
16175 +
16176 return b;
16177 }
16178
16179 @@ -546,7 +695,7 @@
16180 switch (_IOC_NR(cmd)) {
16181 case I2C_WRITEREG:
16182 /* write to an i2c slave */
16183 - D(printk("i2cw %d %d %d\n",
16184 + D(printk("i2cw %d %d %d\n",
16185 I2C_ARGSLAVE(arg),
16186 I2C_ARGREG(arg),
16187 I2C_ARGVALUE(arg)));
16188 @@ -558,18 +707,18 @@
16189 {
16190 unsigned char val;
16191 /* read from an i2c slave */
16192 - D(printk("i2cr %d %d ",
16193 + D(printk("i2cr %d %d ",
16194 I2C_ARGSLAVE(arg),
16195 I2C_ARGREG(arg)));
16196 val = i2c_readreg(I2C_ARGSLAVE(arg), I2C_ARGREG(arg));
16197 D(printk("= %d\n", val));
16198 return val;
16199 - }
16200 + }
16201 default:
16202 return -EINVAL;
16203
16204 }
16205 -
16206 +
16207 return 0;
16208 }
16209
16210 @@ -583,28 +732,53 @@
16211 int __init
16212 i2c_init(void)
16213 {
16214 - int res;
16215 + static int res = 0;
16216 + static int first = 1;
16217 +
16218 + if (!first) {
16219 + return res;
16220 + }
16221 + first = 0;
16222
16223 - /* Setup and enable the Port B I2C interface */
16224 + /* Setup and enable the DATA and CLK pins */
16225
16226 - crisv32_io_get_name(&cris_i2c_data, CONFIG_ETRAX_I2C_DATA_PORT);
16227 - crisv32_io_get_name(&cris_i2c_clk, CONFIG_ETRAX_I2C_CLK_PORT);
16228 + res = crisv32_io_get_name(&cris_i2c_data, CONFIG_ETRAX_I2C_DATA_PORT);
16229 + if (res < 0) {
16230 + return res;
16231 + }
16232 +
16233 + res = crisv32_io_get_name(&cris_i2c_clk, CONFIG_ETRAX_I2C_CLK_PORT);
16234 + crisv32_io_set_dir(&cris_i2c_clk, crisv32_io_dir_out);
16235 +
16236 + return res;
16237 +}
16238
16239 - /* register char device */
16240
16241 +int __init
16242 +i2c_register(void)
16243 +{
16244 +
16245 + int res;
16246 +
16247 + res = i2c_init();
16248 + if (res < 0) {
16249 + return res;
16250 + }
16251 +
16252 + /* register char device */
16253 res = register_chrdev(I2C_MAJOR, i2c_name, &i2c_fops);
16254 if(res < 0) {
16255 printk(KERN_ERR "i2c: couldn't get a major number.\n");
16256 return res;
16257 }
16258
16259 - printk(KERN_INFO "I2C driver v2.2, (c) 1999-2001 Axis Communications AB\n");
16260 -
16261 + printk(KERN_INFO "I2C driver v2.2, (c) 1999-2004 Axis Communications AB\n");
16262 +
16263 return 0;
16264 }
16265
16266 /* this makes sure that i2c_init is called during boot */
16267
16268 -module_init(i2c_init);
16269 +module_init(i2c_register);
16270
16271 /****************** END OF FILE i2c.c ********************************/
16272 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/drivers/i2c.h linux-2.6.19.2.dev/arch/cris/arch-v32/drivers/i2c.h
16273 --- linux-2.6.19.2.old/arch/cris/arch-v32/drivers/i2c.h 2007-01-10 20:10:37.000000000 +0100
16274 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/drivers/i2c.h 2006-11-06 16:48:06.000000000 +0100
16275 @@ -3,6 +3,8 @@
16276
16277 /* High level I2C actions */
16278 int __init i2c_init(void);
16279 +int i2c_write(unsigned char theSlave, void *data, size_t nbytes);
16280 +int i2c_read(unsigned char theSlave, void *data, size_t nbytes);
16281 int i2c_writereg(unsigned char theSlave, unsigned char theReg, unsigned char theValue);
16282 unsigned char i2c_readreg(unsigned char theSlave, unsigned char theReg);
16283
16284 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/drivers/iop_fw_load.c linux-2.6.19.2.dev/arch/cris/arch-v32/drivers/iop_fw_load.c
16285 --- linux-2.6.19.2.old/arch/cris/arch-v32/drivers/iop_fw_load.c 2007-01-10 20:10:37.000000000 +0100
16286 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/drivers/iop_fw_load.c 2005-04-07 11:27:46.000000000 +0200
16287 @@ -67,12 +67,12 @@
16288 return -ENODEV;
16289
16290 /* get firmware */
16291 - retval = request_firmware(&fw_entry,
16292 - fw_name,
16293 + retval = request_firmware(&fw_entry,
16294 + fw_name,
16295 &iop_spu_device[spu_inst]);
16296 if (retval != 0)
16297 {
16298 - printk(KERN_ERR
16299 + printk(KERN_ERR
16300 "iop_load_spu: Failed to load firmware \"%s\"\n",
16301 fw_name);
16302 return retval;
16303 @@ -123,7 +123,7 @@
16304 return retval;
16305 }
16306
16307 -int iop_fw_load_mpu(unsigned char *fw_name)
16308 +int iop_fw_load_mpu(unsigned char *fw_name)
16309 {
16310 const unsigned int start_addr = 0;
16311 reg_iop_mpu_rw_ctrl mpu_ctrl;
16312 @@ -135,13 +135,13 @@
16313 retval = request_firmware(&fw_entry, fw_name, &iop_mpu_device);
16314 if (retval != 0)
16315 {
16316 - printk(KERN_ERR
16317 + printk(KERN_ERR
16318 "iop_load_spu: Failed to load firmware \"%s\"\n",
16319 fw_name);
16320 return retval;
16321 }
16322 data = (u32 *) fw_entry->data;
16323 -
16324 +
16325 /* disable MPU */
16326 mpu_ctrl.en = regk_iop_mpu_no;
16327 REG_WR(iop_mpu, regi_iop_mpu, rw_ctrl, mpu_ctrl);
16328 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/drivers/nandflash.c linux-2.6.19.2.dev/arch/cris/arch-v32/drivers/nandflash.c
16329 --- linux-2.6.19.2.old/arch/cris/arch-v32/drivers/nandflash.c 2007-01-10 20:10:37.000000000 +0100
16330 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/drivers/nandflash.c 2006-10-16 14:56:46.000000000 +0200
16331 @@ -5,8 +5,8 @@
16332 *
16333 * Derived from drivers/mtd/nand/spia.c
16334 * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
16335 - *
16336 - * $Id: nandflash.c,v 1.3 2005/06/01 10:57:12 starvik Exp $
16337 + *
16338 + * $Id: nandflash.c,v 1.8 2006/10/16 12:56:46 ricardw Exp $
16339 *
16340 * This program is free software; you can redistribute it and/or modify
16341 * it under the terms of the GNU General Public License version 2 as
16342 @@ -32,37 +32,53 @@
16343 #define ALE_BIT 6
16344 #define BY_BIT 7
16345
16346 +/* Bitmask for control pins */
16347 +#define PIN_BITMASK ((1 << CE_BIT) | (1 << CLE_BIT) | (1 << ALE_BIT))
16348 +
16349 +/* Bitmask for mtd nand control bits */
16350 +#define CTRL_BITMASK (NAND_NCE | NAND_CLE | NAND_ALE)
16351 +
16352 +
16353 static struct mtd_info *crisv32_mtd = NULL;
16354 -/*
16355 +/*
16356 * hardware specific access to control-lines
16357 */
16358 -static void crisv32_hwcontrol(struct mtd_info *mtd, int cmd)
16359 +static void crisv32_hwcontrol(struct mtd_info *mtd, int cmd,
16360 + unsigned int ctrl)
16361 {
16362 unsigned long flags;
16363 - reg_gio_rw_pa_dout dout = REG_RD(gio, regi_gio, rw_pa_dout);
16364 + reg_gio_rw_pa_dout dout;
16365 + struct nand_chip *this = mtd->priv;
16366
16367 local_irq_save(flags);
16368 - switch(cmd){
16369 - case NAND_CTL_SETCLE:
16370 - dout.data |= (1<<CLE_BIT);
16371 - break;
16372 - case NAND_CTL_CLRCLE:
16373 - dout.data &= ~(1<<CLE_BIT);
16374 - break;
16375 - case NAND_CTL_SETALE:
16376 - dout.data |= (1<<ALE_BIT);
16377 - break;
16378 - case NAND_CTL_CLRALE:
16379 - dout.data &= ~(1<<ALE_BIT);
16380 - break;
16381 - case NAND_CTL_SETNCE:
16382 - dout.data |= (1<<CE_BIT);
16383 - break;
16384 - case NAND_CTL_CLRNCE:
16385 - dout.data &= ~(1<<CE_BIT);
16386 - break;
16387 +
16388 + /* control bits change */
16389 + if (ctrl & NAND_CTRL_CHANGE) {
16390 + dout = REG_RD(gio, regi_gio, rw_pa_dout);
16391 + dout.data &= ~PIN_BITMASK;
16392 +
16393 +#if (CE_BIT == 4 && NAND_NCE == 1 && \
16394 + CLE_BIT == 5 && NAND_CLE == 2 && \
16395 + ALE_BIT == 6 && NAND_ALE == 4)
16396 + /* Pins in same order as control bits, but shifted.
16397 + * Optimize for this case; works for 2.6.18 */
16398 + dout.data |= ((ctrl & CTRL_BITMASK) ^ NAND_NCE) << CE_BIT;
16399 +#else
16400 + /* the slow way */
16401 + if (!(ctrl & NAND_NCE))
16402 + dout.data |= (1 << CE_BIT);
16403 + if (ctrl & NAND_CLE)
16404 + dout.data |= (1 << CLE_BIT);
16405 + if (ctrl & NAND_ALE)
16406 + dout.data |= (1 << ALE_BIT);
16407 +#endif
16408 + REG_WR(gio, regi_gio, rw_pa_dout, dout);
16409 }
16410 - REG_WR(gio, regi_gio, rw_pa_dout, dout);
16411 +
16412 + /* command to chip */
16413 + if (cmd != NAND_CMD_NONE)
16414 + writeb(cmd, this->IO_ADDR_W);
16415 +
16416 local_irq_restore(flags);
16417 }
16418
16419 @@ -129,26 +145,26 @@
16420 /* Set address of NAND IO lines */
16421 this->IO_ADDR_R = read_cs;
16422 this->IO_ADDR_W = write_cs;
16423 - this->hwcontrol = crisv32_hwcontrol;
16424 + this->cmd_ctrl = crisv32_hwcontrol;
16425 this->dev_ready = crisv32_device_ready;
16426 /* 20 us command delay time */
16427 - this->chip_delay = 20;
16428 - this->eccmode = NAND_ECC_SOFT;
16429 + this->chip_delay = 20;
16430 + this->ecc.mode = NAND_ECC_SOFT;
16431
16432 /* Enable the following for a flash based bad block table */
16433 - this->options = NAND_USE_FLASH_BBT;
16434 + /* this->options = NAND_USE_FLASH_BBT; */
16435
16436 /* Scan to find existance of the device */
16437 if (nand_scan (crisv32_mtd, 1)) {
16438 err = -ENXIO;
16439 goto out_ior;
16440 }
16441 -
16442 +
16443 return crisv32_mtd;
16444 -
16445 +
16446 out_ior:
16447 iounmap((void *)read_cs);
16448 - iounmap((void *)write_cs);
16449 + iounmap((void *)write_cs);
16450 out_mtd:
16451 kfree (crisv32_mtd);
16452 return NULL;
16453 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/drivers/pcf8563.c linux-2.6.19.2.dev/arch/cris/arch-v32/drivers/pcf8563.c
16454 --- linux-2.6.19.2.old/arch/cris/arch-v32/drivers/pcf8563.c 2007-01-10 20:10:37.000000000 +0100
16455 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/drivers/pcf8563.c 2006-10-27 17:22:13.000000000 +0200
16456 @@ -10,7 +10,7 @@
16457 * 400 kbits/s. The built-in word address register is incremented
16458 * automatically after each written or read byte.
16459 *
16460 - * Copyright (c) 2002-2003, Axis Communications AB
16461 + * Copyright (c) 2002-2006, Axis Communications AB
16462 * All rights reserved.
16463 *
16464 * Author: Tobias Anderberg <tobiasa@axis.com>.
16465 @@ -37,24 +37,27 @@
16466 #define PCF8563_MAJOR 121 /* Local major number. */
16467 #define DEVICE_NAME "rtc" /* Name which is registered in /proc/devices. */
16468 #define PCF8563_NAME "PCF8563"
16469 -#define DRIVER_VERSION "$Revision: 1.1 $"
16470 +#define DRIVER_VERSION "$Revision: 1.9 $"
16471
16472 /* Two simple wrapper macros, saves a few keystrokes. */
16473 #define rtc_read(x) i2c_readreg(RTC_I2C_READ, x)
16474 #define rtc_write(x,y) i2c_writereg(RTC_I2C_WRITE, x, y)
16475
16476 +static DEFINE_SPINLOCK(rtc_lock); /* Protect state etc */
16477 +
16478 static const unsigned char days_in_month[] =
16479 { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
16480
16481 int pcf8563_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
16482 -int pcf8563_open(struct inode *, struct file *);
16483 -int pcf8563_release(struct inode *, struct file *);
16484 +
16485 +/* Cache VL bit value read at driver init since writing the RTC_SECOND
16486 + * register clears the VL status.
16487 + */
16488 +static int voltage_low = 0;
16489
16490 static struct file_operations pcf8563_fops = {
16491 owner: THIS_MODULE,
16492 ioctl: pcf8563_ioctl,
16493 - open: pcf8563_open,
16494 - release: pcf8563_release,
16495 };
16496
16497 unsigned char
16498 @@ -62,7 +65,7 @@
16499 {
16500 unsigned char res = rtc_read(reg);
16501
16502 - /* The PCF8563 does not return 0 for unimplemented bits */
16503 + /* The PCF8563 does not return 0 for unimplemented bits. */
16504 switch (reg) {
16505 case RTC_SECONDS:
16506 case RTC_MINUTES:
16507 @@ -95,11 +98,6 @@
16508 void
16509 pcf8563_writereg(int reg, unsigned char val)
16510 {
16511 -#ifdef CONFIG_ETRAX_RTC_READONLY
16512 - if (reg == RTC_CONTROL1 || (reg >= RTC_SECONDS && reg <= RTC_YEAR))
16513 - return;
16514 -#endif
16515 -
16516 rtc_write(reg, val);
16517 }
16518
16519 @@ -114,11 +112,13 @@
16520 tm->tm_mon = rtc_read(RTC_MONTH);
16521 tm->tm_year = rtc_read(RTC_YEAR);
16522
16523 - if (tm->tm_sec & 0x80)
16524 + if (tm->tm_sec & 0x80) {
16525 printk(KERN_WARNING "%s: RTC Voltage Low - reliable date/time "
16526 "information is no longer guaranteed!\n", PCF8563_NAME);
16527 + }
16528
16529 - tm->tm_year = BCD_TO_BIN(tm->tm_year) + ((tm->tm_mon & 0x80) ? 100 : 0);
16530 + tm->tm_year = BCD_TO_BIN(tm->tm_year) +
16531 + ((tm->tm_mon & 0x80) ? 100 : 0);
16532 tm->tm_sec &= 0x7F;
16533 tm->tm_min &= 0x7F;
16534 tm->tm_hour &= 0x3F;
16535 @@ -137,8 +137,20 @@
16536 int __init
16537 pcf8563_init(void)
16538 {
16539 + static int res = 0;
16540 + static int first = 1;
16541 +
16542 + if (!first) {
16543 + return res;
16544 + }
16545 + first = 0;
16546 +
16547 /* Initiate the i2c protocol. */
16548 - i2c_init();
16549 + res = i2c_init();
16550 + if (res < 0) {
16551 + printk(KERN_CRIT "pcf8563_init: Failed to init i2c.\n");
16552 + return res;
16553 + }
16554
16555 /*
16556 * First of all we need to reset the chip. This is done by
16557 @@ -170,31 +182,28 @@
16558 if (rtc_write(RTC_WEEKDAY_ALARM, 0x80) < 0)
16559 goto err;
16560
16561 - if (register_chrdev(PCF8563_MAJOR, DEVICE_NAME, &pcf8563_fops) < 0) {
16562 - printk(KERN_INFO "%s: Unable to get major numer %d for RTC device.\n",
16563 - PCF8563_NAME, PCF8563_MAJOR);
16564 - return -1;
16565 + /* Check for low voltage, and warn about it. */
16566 + if (rtc_read(RTC_SECONDS) & 0x80) {
16567 + voltage_low = 1;
16568 + printk(KERN_WARNING "%s: RTC Voltage Low - reliable "
16569 + "date/time information is no longer guaranteed!\n",
16570 + PCF8563_NAME);
16571 }
16572
16573 - printk(KERN_INFO "%s Real-Time Clock Driver, %s\n", PCF8563_NAME, DRIVER_VERSION);
16574 -
16575 - /* Check for low voltage, and warn about it.. */
16576 - if (rtc_read(RTC_SECONDS) & 0x80)
16577 - printk(KERN_WARNING "%s: RTC Voltage Low - reliable date/time "
16578 - "information is no longer guaranteed!\n", PCF8563_NAME);
16579 -
16580 - return 0;
16581 + return res;
16582
16583 err:
16584 printk(KERN_INFO "%s: Error initializing chip.\n", PCF8563_NAME);
16585 - return -1;
16586 + res = -1;
16587 + return res;
16588 }
16589
16590 void __exit
16591 pcf8563_exit(void)
16592 {
16593 if (unregister_chrdev(PCF8563_MAJOR, DEVICE_NAME) < 0) {
16594 - printk(KERN_INFO "%s: Unable to unregister device.\n", PCF8563_NAME);
16595 + printk(KERN_INFO "%s: Unable to unregister device.\n",
16596 + PCF8563_NAME);
16597 }
16598 }
16599
16600 @@ -203,7 +212,8 @@
16601 * POSIX says so!
16602 */
16603 int
16604 -pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
16605 +pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
16606 + unsigned long arg)
16607 {
16608 /* Some sanity checks. */
16609 if (_IOC_TYPE(cmd) != RTC_MAGIC)
16610 @@ -217,31 +227,35 @@
16611 {
16612 struct rtc_time tm;
16613
16614 - memset(&tm, 0, sizeof (struct rtc_time));
16615 + spin_lock(&rtc_lock);
16616 + memset(&tm, 0, sizeof tm);
16617 get_rtc_time(&tm);
16618
16619 - if (copy_to_user((struct rtc_time *) arg, &tm, sizeof tm)) {
16620 + if (copy_to_user((struct rtc_time *) arg, &tm,
16621 + sizeof tm)) {
16622 + spin_unlock(&rtc_lock);
16623 return -EFAULT;
16624 }
16625
16626 + spin_unlock(&rtc_lock);
16627 +
16628 return 0;
16629 }
16630 -
16631 case RTC_SET_TIME:
16632 {
16633 -#ifdef CONFIG_ETRAX_RTC_READONLY
16634 - return -EPERM;
16635 -#else
16636 int leap;
16637 int year;
16638 int century;
16639 struct rtc_time tm;
16640
16641 + memset(&tm, 0, sizeof tm);
16642 if (!capable(CAP_SYS_TIME))
16643 return -EPERM;
16644
16645 - if (copy_from_user(&tm, (struct rtc_time *) arg, sizeof tm))
16646 + if (copy_from_user(&tm, (struct rtc_time *) arg,
16647 + sizeof tm)) {
16648 return -EFAULT;
16649 + }
16650
16651 /* Convert from struct tm to struct rtc_time. */
16652 tm.tm_year += 1900;
16653 @@ -253,7 +267,8 @@
16654 * that years divisible by 400 _are_ leap years.
16655 */
16656 year = tm.tm_year;
16657 - leap = (tm.tm_mon == 2) && ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0);
16658 + leap = (tm.tm_mon == 2) &&
16659 + ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0);
16660
16661 /* Perform some sanity checks. */
16662 if ((tm.tm_year < 1970) ||
16663 @@ -263,19 +278,23 @@
16664 (tm.tm_wday >= 7) ||
16665 (tm.tm_hour >= 24) ||
16666 (tm.tm_min >= 60) ||
16667 - (tm.tm_sec >= 60))
16668 + (tm.tm_sec >= 60)) {
16669 return -EINVAL;
16670 + }
16671
16672 century = (tm.tm_year >= 2000) ? 0x80 : 0;
16673 tm.tm_year = tm.tm_year % 100;
16674
16675 BIN_TO_BCD(tm.tm_year);
16676 + BIN_TO_BCD(tm.tm_mon);
16677 BIN_TO_BCD(tm.tm_mday);
16678 BIN_TO_BCD(tm.tm_hour);
16679 BIN_TO_BCD(tm.tm_min);
16680 BIN_TO_BCD(tm.tm_sec);
16681 tm.tm_mon |= century;
16682
16683 + spin_lock(&rtc_lock);
16684 +
16685 rtc_write(RTC_YEAR, tm.tm_year);
16686 rtc_write(RTC_MONTH, tm.tm_mon);
16687 rtc_write(RTC_WEEKDAY, tm.tm_wday); /* Not coded in BCD. */
16688 @@ -284,36 +303,40 @@
16689 rtc_write(RTC_MINUTES, tm.tm_min);
16690 rtc_write(RTC_SECONDS, tm.tm_sec);
16691
16692 + spin_unlock(&rtc_lock);
16693 +
16694 return 0;
16695 -#endif /* !CONFIG_ETRAX_RTC_READONLY */
16696 }
16697 -
16698 case RTC_VLOW_RD:
16699 - {
16700 - int vl_bit = 0;
16701 -
16702 - if (rtc_read(RTC_SECONDS) & 0x80) {
16703 - vl_bit = 1;
16704 - printk(KERN_WARNING "%s: RTC Voltage Low - reliable "
16705 - "date/time information is no longer guaranteed!\n",
16706 - PCF8563_NAME);
16707 + if (voltage_low) {
16708 + printk(KERN_WARNING "%s: RTC Voltage Low - "
16709 + "reliable date/time information is no "
16710 + "longer guaranteed!\n", PCF8563_NAME);
16711 }
16712 - if (copy_to_user((int *) arg, &vl_bit, sizeof(int)))
16713 - return -EFAULT;
16714
16715 + if (copy_to_user((int *) arg, &voltage_low, sizeof(int))) {
16716 + return -EFAULT;
16717 + }
16718 +
16719 return 0;
16720 - }
16721
16722 case RTC_VLOW_SET:
16723 {
16724 - /* Clear the VL bit in the seconds register */
16725 + /* Clear the VL bit in the seconds register in case
16726 + * the time has not been set already (which would
16727 + * have cleared it). This does not really matter
16728 + * because of the cached voltage_low value but do it
16729 + * anyway for consistency. */
16730 +
16731 int ret = rtc_read(RTC_SECONDS);
16732
16733 rtc_write(RTC_SECONDS, (ret & 0x7F));
16734
16735 + /* Clear the cached value. */
16736 + voltage_low = 0;
16737 +
16738 return 0;
16739 }
16740 -
16741 default:
16742 return -ENOTTY;
16743 }
16744 @@ -321,17 +344,32 @@
16745 return 0;
16746 }
16747
16748 -int
16749 -pcf8563_open(struct inode *inode, struct file *filp)
16750 +static int __init
16751 +pcf8563_register(void)
16752 {
16753 - return 0;
16754 -}
16755 + if (pcf8563_init() < 0) {
16756 + printk(KERN_INFO "%s: Unable to initialize Real-Time Clock "
16757 + "Driver, %s\n", PCF8563_NAME, DRIVER_VERSION);
16758 + return -1;
16759 + }
16760 +
16761 + if (register_chrdev(PCF8563_MAJOR, DEVICE_NAME, &pcf8563_fops) < 0) {
16762 + printk(KERN_INFO "%s: Unable to get major numer %d for RTC "
16763 + "device.\n", PCF8563_NAME, PCF8563_MAJOR);
16764 + return -1;
16765 + }
16766 +
16767 + printk(KERN_INFO "%s Real-Time Clock Driver, %s\n", PCF8563_NAME,
16768 + DRIVER_VERSION);
16769 +
16770 + /* Check for low voltage, and warn about it. */
16771 + if (voltage_low) {
16772 + printk(KERN_WARNING "%s: RTC Voltage Low - reliable date/time "
16773 + "information is no longer guaranteed!\n", PCF8563_NAME);
16774 + }
16775
16776 -int
16777 -pcf8563_release(struct inode *inode, struct file *filp)
16778 -{
16779 return 0;
16780 }
16781
16782 -module_init(pcf8563_init);
16783 +module_init(pcf8563_register);
16784 module_exit(pcf8563_exit);
16785 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/drivers/pci/bios.c linux-2.6.19.2.dev/arch/cris/arch-v32/drivers/pci/bios.c
16786 --- linux-2.6.19.2.old/arch/cris/arch-v32/drivers/pci/bios.c 2007-01-10 20:10:37.000000000 +0100
16787 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/drivers/pci/bios.c 2006-10-13 14:43:15.000000000 +0200
16788 @@ -60,7 +60,7 @@
16789 u16 cmd, old_cmd;
16790 int idx;
16791 struct resource *r;
16792 -
16793 +
16794 pci_read_config_word(dev, PCI_COMMAND, &cmd);
16795 old_cmd = cmd;
16796 for(idx=0; idx<6; idx++) {
16797 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/drivers/pci/dma.c linux-2.6.19.2.dev/arch/cris/arch-v32/drivers/pci/dma.c
16798 --- linux-2.6.19.2.old/arch/cris/arch-v32/drivers/pci/dma.c 2007-01-10 20:10:37.000000000 +0100
16799 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/drivers/pci/dma.c 2005-10-31 09:48:04.000000000 +0100
16800 @@ -62,7 +62,7 @@
16801 {
16802 struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL;
16803 int order = get_order(size);
16804 -
16805 +
16806 if (mem && vaddr >= mem->virt_base && vaddr < (mem->virt_base + (mem->size << PAGE_SHIFT))) {
16807 int page = (vaddr - mem->virt_base) >> PAGE_SHIFT;
16808
16809 @@ -120,7 +120,7 @@
16810 void dma_release_declared_memory(struct device *dev)
16811 {
16812 struct dma_coherent_mem *mem = dev->dma_mem;
16813 -
16814 +
16815 if(!mem)
16816 return;
16817 dev->dma_mem = NULL;
16818 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/drivers/sync_serial.c linux-2.6.19.2.dev/arch/cris/arch-v32/drivers/sync_serial.c
16819 --- linux-2.6.19.2.old/arch/cris/arch-v32/drivers/sync_serial.c 2007-01-10 20:10:37.000000000 +0100
16820 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/drivers/sync_serial.c 2007-01-09 10:29:20.000000000 +0100
16821 @@ -50,7 +50,7 @@
16822 /* readp writep */
16823 /* */
16824 /* If the application keeps up the pace readp will be right after writep.*/
16825 -/* If the application can't keep the pace we have to throw away data. */
16826 +/* If the application can't keep the pace we have to throw away data. */
16827 /* The idea is that readp should be ready with the data pointed out by */
16828 /* Descr[i] when the DMA has filled in Descr[i+1]. */
16829 /* Otherwise we will discard */
16830 @@ -65,6 +65,7 @@
16831 #define IN_DESCR_SIZE 256
16832 #define NUM_IN_DESCR (IN_BUFFER_SIZE/IN_DESCR_SIZE)
16833 #define OUT_BUFFER_SIZE 4096
16834 +#define NUM_OUT_DESCRS 4
16835
16836 #define DEFAULT_FRAME_RATE 0
16837 #define DEFAULT_WORD_RATE 7
16838 @@ -112,7 +113,7 @@
16839
16840 dma_descr_data in_descr[NUM_IN_DESCR] __attribute__ ((__aligned__(16)));
16841 dma_descr_context in_context __attribute__ ((__aligned__(32)));
16842 - dma_descr_data out_descr __attribute__ ((__aligned__(16)));
16843 + dma_descr_data out_descr[NUM_OUT_DESCRS] __attribute__ ((__aligned__(16)));
16844 dma_descr_context out_context __attribute__ ((__aligned__(32)));
16845 wait_queue_head_t out_wait_q;
16846 wait_queue_head_t in_wait_q;
16847 @@ -130,9 +131,9 @@
16848
16849 static int sync_serial_ioctl(struct inode*, struct file*,
16850 unsigned int cmd, unsigned long arg);
16851 -static ssize_t sync_serial_write(struct file * file, const char * buf,
16852 +static ssize_t sync_serial_write(struct file * file, const char * buf,
16853 size_t count, loff_t *ppos);
16854 -static ssize_t sync_serial_read(struct file *file, char *buf,
16855 +static ssize_t sync_serial_read(struct file *file, char *buf,
16856 size_t count, loff_t *ppos);
16857
16858 #if (defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0) && \
16859 @@ -146,8 +147,8 @@
16860 static void start_dma(struct sync_port *port, const char* data, int count);
16861 static void start_dma_in(sync_port* port);
16862 #ifdef SYNC_SER_DMA
16863 -static irqreturn_t tr_interrupt(int irq, void *dev_id, struct pt_regs * regs);
16864 -static irqreturn_t rx_interrupt(int irq, void *dev_id, struct pt_regs * regs);
16865 +static irqreturn_t tr_interrupt(int irq, void *dev_id);
16866 +static irqreturn_t rx_interrupt(int irq, void *dev_id);
16867 #endif
16868
16869 #if (defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0) && \
16870 @@ -157,7 +158,7 @@
16871 #define SYNC_SER_MANUAL
16872 #endif
16873 #ifdef SYNC_SER_MANUAL
16874 -static irqreturn_t manual_interrupt(int irq, void *dev_id, struct pt_regs * regs);
16875 +static irqreturn_t manual_interrupt(int irq, void *dev_id);
16876 #endif
16877
16878 /* The ports */
16879 @@ -201,8 +202,8 @@
16880 {
16881 ports[0].enabled = 0;
16882 ports[1].enabled = 0;
16883 -
16884 - if (register_chrdev(SYNC_SERIAL_MAJOR,"sync serial", &sync_serial_fops) <0 )
16885 +
16886 + if (register_chrdev(SYNC_SERIAL_MAJOR,"sync serial", &sync_serial_fops) <0 )
16887 {
16888 printk("unable to get major for synchronous serial port\n");
16889 return -EBUSY;
16890 @@ -243,13 +244,13 @@
16891
16892 DEBUG(printk("Init sync serial port %d\n", portnbr));
16893
16894 - port->port_nbr = portnbr;
16895 + port->port_nbr = portnbr;
16896 port->init_irqs = 1;
16897
16898 port->outp = port->out_buffer;
16899 port->output = 1;
16900 port->input = 0;
16901 -
16902 +
16903 port->readp = port->flip;
16904 port->writep = port->flip;
16905 port->in_buffer_size = IN_BUFFER_SIZE;
16906 @@ -286,11 +287,16 @@
16907 tr_cfg.sample_size = 7;
16908 tr_cfg.sh_dir = regk_sser_msbfirst;
16909 tr_cfg.use_dma = port->use_dma ? regk_sser_yes : regk_sser_no;
16910 +#if 0
16911 tr_cfg.rate_ctrl = regk_sser_bulk;
16912 tr_cfg.data_pin_use = regk_sser_dout;
16913 +#else
16914 + tr_cfg.rate_ctrl = regk_sser_iso;
16915 + tr_cfg.data_pin_use = regk_sser_dout;
16916 +#endif
16917 tr_cfg.bulk_wspace = 1;
16918 REG_WR(sser, port->regi_sser, rw_tr_cfg, tr_cfg);
16919 -
16920 +
16921 rec_cfg.sample_size = 7;
16922 rec_cfg.sh_dir = regk_sser_msbfirst;
16923 rec_cfg.use_dma = port->use_dma ? regk_sser_yes : regk_sser_no;
16924 @@ -303,17 +309,17 @@
16925 int avail;
16926 unsigned char *start;
16927 unsigned char *end;
16928 -
16929 +
16930 start = (unsigned char*)port->readp; /* cast away volatile */
16931 end = (unsigned char*)port->writep; /* cast away volatile */
16932 /* 0123456789 0123456789
16933 * ----- - -----
16934 * ^rp ^wp ^wp ^rp
16935 */
16936 -
16937 +
16938 if (end >= start)
16939 avail = end - start;
16940 - else
16941 + else
16942 avail = port->in_buffer_size - (start - end);
16943 return avail;
16944 }
16945 @@ -323,17 +329,17 @@
16946 int avail;
16947 unsigned char *start;
16948 unsigned char *end;
16949 -
16950 +
16951 start = (unsigned char*)port->readp; /* cast away volatile */
16952 end = (unsigned char*)port->writep; /* cast away volatile */
16953 /* 0123456789 0123456789
16954 * ----- -----
16955 * ^rp ^wp ^wp ^rp
16956 */
16957 -
16958 +
16959 if (end >= start)
16960 avail = end - start;
16961 - else
16962 + else
16963 avail = port->flip + port->in_buffer_size - start;
16964 return avail;
16965 }
16966 @@ -343,10 +349,10 @@
16967 int dev = iminor(inode);
16968 sync_port* port;
16969 reg_dma_rw_cfg cfg = {.en = regk_dma_yes};
16970 - reg_dma_rw_intr_mask intr_mask = {.data = regk_dma_yes};
16971 -
16972 - DEBUG(printk("Open sync serial port %d\n", dev));
16973 + reg_dma_rw_intr_mask intr_mask = {.data = regk_dma_yes};
16974
16975 + DEBUG(printk("Open sync serial port %d\n", dev));
16976 +
16977 if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled)
16978 {
16979 DEBUG(printk("Invalid minor %d\n", dev));
16980 @@ -354,7 +360,7 @@
16981 }
16982 port = &ports[dev];
16983 /* Allow open this device twice (assuming one reader and one writer) */
16984 - if (port->busy == 2)
16985 + if (port->busy == 2)
16986 {
16987 DEBUG(printk("Device is busy.. \n"));
16988 return -EBUSY;
16989 @@ -422,8 +428,8 @@
16990 DMA_VERBOSE_ON_ERROR,
16991 0,
16992 dma_sser1)) {
16993 - free_irq(21, &ports[1]);
16994 - free_irq(20, &ports[1]);
16995 + free_irq(DMA6_INTR_VECT, &ports[1]);
16996 + free_irq(DMA7_INTR_VECT, &ports[1]);
16997 printk(KERN_CRIT "Can't allocate sync serial port 3 TX DMA channel");
16998 return -EBUSY;
16999 } else if (crisv32_request_dma(SYNC_SER1_RX_DMA_NBR,
17000 @@ -446,7 +452,7 @@
17001 /* Enable DMA IRQs */
17002 REG_WR(dma, port->regi_dmain, rw_intr_mask, intr_mask);
17003 REG_WR(dma, port->regi_dmaout, rw_intr_mask, intr_mask);
17004 - /* Set up wordsize = 2 for DMAs. */
17005 + /* Set up wordsize = 1 for DMAs. */
17006 DMA_WR_CMD (port->regi_dmain, regk_dma_set_w_size1);
17007 DMA_WR_CMD (port->regi_dmaout, regk_dma_set_w_size1);
17008
17009 @@ -497,7 +503,7 @@
17010 port = &ports[dev];
17011 if (port->busy)
17012 port->busy--;
17013 - if (!port->busy)
17014 + if (!port->busy)
17015 /* XXX */ ;
17016 return 0;
17017 }
17018 @@ -508,17 +514,29 @@
17019 unsigned int mask = 0;
17020 sync_port* port;
17021 DEBUGPOLL( static unsigned int prev_mask = 0; );
17022 -
17023 +
17024 port = &ports[dev];
17025 +
17026 + if (!port->started)
17027 + {
17028 + reg_sser_rw_cfg cfg = REG_RD(sser, port->regi_sser, rw_cfg);
17029 + reg_sser_rw_rec_cfg rec_cfg = REG_RD(sser, port->regi_sser, rw_rec_cfg);
17030 + cfg.en = regk_sser_yes;
17031 + rec_cfg.rec_en = port->input;
17032 + REG_WR(sser, port->regi_sser, rw_cfg, cfg);
17033 + REG_WR(sser, port->regi_sser, rw_rec_cfg, rec_cfg);
17034 + port->started = 1;
17035 + }
17036 +
17037 poll_wait(file, &port->out_wait_q, wait);
17038 poll_wait(file, &port->in_wait_q, wait);
17039 /* Some room to write */
17040 - if (port->out_count < OUT_BUFFER_SIZE)
17041 + if (port->output && port->out_count < OUT_BUFFER_SIZE)
17042 mask |= POLLOUT | POLLWRNORM;
17043 /* At least an inbufchunk of data */
17044 - if (sync_data_avail(port) >= port->inbufchunk)
17045 + if (port->input && sync_data_avail(port) >= port->inbufchunk)
17046 mask |= POLLIN | POLLRDNORM;
17047 -
17048 +
17049 DEBUGPOLL(if (mask != prev_mask)
17050 printk("sync_serial_poll: mask 0x%08X %s %s\n", mask,
17051 mask&POLLOUT?"POLLOUT":"", mask&POLLIN?"POLLIN":"");
17052 @@ -531,14 +549,15 @@
17053 unsigned int cmd, unsigned long arg)
17054 {
17055 int return_val = 0;
17056 + int dma_w_size = regk_dma_set_w_size1;
17057 int dev = iminor(file->f_dentry->d_inode);
17058 sync_port* port;
17059 reg_sser_rw_tr_cfg tr_cfg;
17060 reg_sser_rw_rec_cfg rec_cfg;
17061 - reg_sser_rw_frm_cfg frm_cfg;
17062 + reg_sser_rw_frm_cfg frm_cfg;
17063 reg_sser_rw_cfg gen_cfg;
17064 reg_sser_rw_intr_mask intr_mask;
17065 -
17066 +
17067 if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled)
17068 {
17069 DEBUG(printk("Invalid minor %d\n", dev));
17070 @@ -558,9 +577,32 @@
17071 case SSP_SPEED:
17072 if (GET_SPEED(arg) == CODEC)
17073 {
17074 + unsigned int freq;
17075 +
17076 gen_cfg.base_freq = regk_sser_f32;
17077 - /* FREQ = 0 => 4 MHz => clk_div = 7*/
17078 - gen_cfg.clk_div = 6 + (1 << GET_FREQ(arg));
17079 +
17080 + /* Clock divider will internally be
17081 + * gen_cfg.clk_div + 1.
17082 + */
17083 +
17084 + freq = GET_FREQ(arg);
17085 + switch (freq)
17086 + {
17087 + case FREQ_32kHz:
17088 + case FREQ_64kHz:
17089 + case FREQ_128kHz:
17090 + case FREQ_256kHz:
17091 + gen_cfg.clk_div = 125 * (1 << (freq - FREQ_256kHz)) - 1;
17092 + break;
17093 + case FREQ_512kHz:
17094 + gen_cfg.clk_div = 62;
17095 + break;
17096 + case FREQ_1MHz:
17097 + case FREQ_2MHz:
17098 + case FREQ_4MHz:
17099 + gen_cfg.clk_div = 8 * (1 << freq) - 1;
17100 + break;
17101 + }
17102 }
17103 else
17104 {
17105 @@ -625,87 +667,118 @@
17106 case MASTER_OUTPUT:
17107 port->output = 1;
17108 port->input = 0;
17109 + frm_cfg.out_on = regk_sser_tr;
17110 + frm_cfg.frame_pin_dir = regk_sser_out;
17111 gen_cfg.clk_dir = regk_sser_out;
17112 break;
17113 case SLAVE_OUTPUT:
17114 port->output = 1;
17115 port->input = 0;
17116 + frm_cfg.frame_pin_dir = regk_sser_in;
17117 gen_cfg.clk_dir = regk_sser_in;
17118 break;
17119 case MASTER_INPUT:
17120 port->output = 0;
17121 port->input = 1;
17122 + frm_cfg.frame_pin_dir = regk_sser_out;
17123 + frm_cfg.out_on = regk_sser_intern_tb;
17124 gen_cfg.clk_dir = regk_sser_out;
17125 break;
17126 case SLAVE_INPUT:
17127 port->output = 0;
17128 port->input = 1;
17129 + frm_cfg.frame_pin_dir = regk_sser_in;
17130 gen_cfg.clk_dir = regk_sser_in;
17131 break;
17132 case MASTER_BIDIR:
17133 port->output = 1;
17134 port->input = 1;
17135 + frm_cfg.frame_pin_dir = regk_sser_out;
17136 + frm_cfg.out_on = regk_sser_intern_tb;
17137 gen_cfg.clk_dir = regk_sser_out;
17138 break;
17139 case SLAVE_BIDIR:
17140 port->output = 1;
17141 port->input = 1;
17142 + frm_cfg.frame_pin_dir = regk_sser_in;
17143 gen_cfg.clk_dir = regk_sser_in;
17144 break;
17145 default:
17146 spin_unlock_irq(&port->lock);
17147 return -EINVAL;
17148 -
17149 +
17150 }
17151 if (!port->use_dma || (arg == MASTER_OUTPUT || arg == SLAVE_OUTPUT))
17152 intr_mask.rdav = regk_sser_yes;
17153 break;
17154 case SSP_FRAME_SYNC:
17155 - if (arg & NORMAL_SYNC)
17156 + if (arg & NORMAL_SYNC) {
17157 + frm_cfg.rec_delay = 1;
17158 frm_cfg.tr_delay = 1;
17159 + }
17160 else if (arg & EARLY_SYNC)
17161 - frm_cfg.tr_delay = 0;
17162 + frm_cfg.rec_delay = frm_cfg.tr_delay = 0;
17163 + else if (arg & SECOND_WORD_SYNC) {
17164 + frm_cfg.rec_delay = 17;
17165 + frm_cfg.tr_delay = 1;
17166 + }
17167 +
17168 +
17169
17170 tr_cfg.bulk_wspace = frm_cfg.tr_delay;
17171 frm_cfg.early_wend = regk_sser_yes;
17172 - if (arg & BIT_SYNC)
17173 + if (arg & BIT_SYNC)
17174 frm_cfg.type = regk_sser_edge;
17175 else if (arg & WORD_SYNC)
17176 frm_cfg.type = regk_sser_level;
17177 else if (arg & EXTENDED_SYNC)
17178 frm_cfg.early_wend = regk_sser_no;
17179 -
17180 +
17181 if (arg & SYNC_ON)
17182 frm_cfg.frame_pin_use = regk_sser_frm;
17183 else if (arg & SYNC_OFF)
17184 frm_cfg.frame_pin_use = regk_sser_gio0;
17185 -
17186 - if (arg & WORD_SIZE_8)
17187 +
17188 + if (arg & WORD_SIZE_8) {
17189 rec_cfg.sample_size = tr_cfg.sample_size = 7;
17190 - else if (arg & WORD_SIZE_12)
17191 + dma_w_size = regk_dma_set_w_size1;
17192 + }
17193 + else if (arg & WORD_SIZE_12) {
17194 rec_cfg.sample_size = tr_cfg.sample_size = 11;
17195 - else if (arg & WORD_SIZE_16)
17196 + dma_w_size = regk_dma_set_w_size2;
17197 + }
17198 + else if (arg & WORD_SIZE_16) {
17199 rec_cfg.sample_size = tr_cfg.sample_size = 15;
17200 - else if (arg & WORD_SIZE_24)
17201 + dma_w_size = regk_dma_set_w_size2;
17202 + }
17203 + else if (arg & WORD_SIZE_24) {
17204 rec_cfg.sample_size = tr_cfg.sample_size = 23;
17205 - else if (arg & WORD_SIZE_32)
17206 + dma_w_size = regk_dma_set_w_size2;
17207 + }
17208 + else if (arg & WORD_SIZE_32) {
17209 rec_cfg.sample_size = tr_cfg.sample_size = 31;
17210 + dma_w_size = regk_dma_set_w_size2;
17211 + }
17212
17213 if (arg & BIT_ORDER_MSB)
17214 rec_cfg.sh_dir = tr_cfg.sh_dir = regk_sser_msbfirst;
17215 else if (arg & BIT_ORDER_LSB)
17216 rec_cfg.sh_dir = tr_cfg.sh_dir = regk_sser_lsbfirst;
17217 -
17218 - if (arg & FLOW_CONTROL_ENABLE)
17219 +
17220 + if (arg & FLOW_CONTROL_ENABLE) {
17221 + frm_cfg.status_pin_use = regk_sser_frm;
17222 rec_cfg.fifo_thr = regk_sser_thr16;
17223 - else if (arg & FLOW_CONTROL_DISABLE)
17224 + }
17225 + else if (arg & FLOW_CONTROL_DISABLE) {
17226 + frm_cfg.status_pin_use = regk_sser_gio0;
17227 rec_cfg.fifo_thr = regk_sser_inf;
17228 + }
17229
17230 if (arg & CLOCK_NOT_GATED)
17231 gen_cfg.gate_clk = regk_sser_no;
17232 else if (arg & CLOCK_GATED)
17233 gen_cfg.gate_clk = regk_sser_yes;
17234 -
17235 +
17236 break;
17237 case SSP_IPOLARITY:
17238 /* NOTE!! negedge is considered NORMAL */
17239 @@ -713,12 +786,12 @@
17240 rec_cfg.clk_pol = regk_sser_neg;
17241 else if (arg & CLOCK_INVERT)
17242 rec_cfg.clk_pol = regk_sser_pos;
17243 -
17244 +
17245 if (arg & FRAME_NORMAL)
17246 frm_cfg.level = regk_sser_pos_hi;
17247 else if (arg & FRAME_INVERT)
17248 frm_cfg.level = regk_sser_neg_lo;
17249 -
17250 +
17251 if (arg & STATUS_NORMAL)
17252 gen_cfg.hold_pol = regk_sser_pos;
17253 else if (arg & STATUS_INVERT)
17254 @@ -726,15 +799,15 @@
17255 break;
17256 case SSP_OPOLARITY:
17257 if (arg & CLOCK_NORMAL)
17258 - gen_cfg.out_clk_pol = regk_sser_neg;
17259 - else if (arg & CLOCK_INVERT)
17260 gen_cfg.out_clk_pol = regk_sser_pos;
17261 -
17262 + else if (arg & CLOCK_INVERT)
17263 + gen_cfg.out_clk_pol = regk_sser_neg;
17264 +
17265 if (arg & FRAME_NORMAL)
17266 frm_cfg.level = regk_sser_pos_hi;
17267 else if (arg & FRAME_INVERT)
17268 frm_cfg.level = regk_sser_neg_lo;
17269 -
17270 +
17271 if (arg & STATUS_NORMAL)
17272 gen_cfg.hold_pol = regk_sser_pos;
17273 else if (arg & STATUS_INVERT)
17274 @@ -772,9 +845,10 @@
17275
17276 if (port->started)
17277 {
17278 - tr_cfg.tr_en = port->output;
17279 rec_cfg.rec_en = port->input;
17280 + gen_cfg.en = (port->output | port->input);
17281 }
17282 +
17283
17284 REG_WR(sser, port->regi_sser, rw_tr_cfg, tr_cfg);
17285 REG_WR(sser, port->regi_sser, rw_rec_cfg, rec_cfg);
17286 @@ -782,11 +856,24 @@
17287 REG_WR(sser, port->regi_sser, rw_intr_mask, intr_mask);
17288 REG_WR(sser, port->regi_sser, rw_cfg, gen_cfg);
17289
17290 +
17291 + if (cmd == SSP_FRAME_SYNC &&
17292 + (arg & (WORD_SIZE_8 | WORD_SIZE_12 | WORD_SIZE_16 | WORD_SIZE_24 | WORD_SIZE_32))) {
17293 + int en = gen_cfg.en;
17294 + gen_cfg.en = 0;
17295 + REG_WR(sser, port->regi_sser, rw_cfg, gen_cfg);
17296 + /* ##### Should DMA be stoped before we change dma size? */
17297 + DMA_WR_CMD (port->regi_dmain, dma_w_size);
17298 + DMA_WR_CMD (port->regi_dmaout, dma_w_size);
17299 + gen_cfg.en = en;
17300 + REG_WR(sser, port->regi_sser, rw_cfg, gen_cfg);
17301 + }
17302 +
17303 spin_unlock_irq(&port->lock);
17304 return return_val;
17305 }
17306
17307 -static ssize_t sync_serial_write(struct file * file, const char * buf,
17308 +static ssize_t sync_serial_write(struct file * file, const char * buf,
17309 size_t count, loff_t *ppos)
17310 {
17311 int dev = iminor(file->f_dentry->d_inode);
17312 @@ -807,7 +894,7 @@
17313
17314 DEBUGWRITE(printk("W d%d c %lu (%d/%d)\n", port->port_nbr, count, port->out_count, OUT_BUFFER_SIZE));
17315 /* Space to end of buffer */
17316 - /*
17317 + /*
17318 * out_buffer <c1>012345<- c ->OUT_BUFFER_SIZE
17319 * outp^ +out_count
17320 ^free_outp
17321 @@ -824,7 +911,7 @@
17322 free_outp = outp + port->out_count;
17323 spin_unlock_irqrestore(&port->lock, flags);
17324 out_buffer = (unsigned long)port->out_buffer;
17325 -
17326 +
17327 /* Find out where and how much to write */
17328 if (free_outp >= out_buffer + OUT_BUFFER_SIZE)
17329 free_outp -= OUT_BUFFER_SIZE;
17330 @@ -834,7 +921,7 @@
17331 c = outp - free_outp;
17332 if (c > count)
17333 c = count;
17334 -
17335 +
17336 // DEBUGWRITE(printk("w op %08lX fop %08lX c %lu\n", outp, free_outp, c));
17337 if (copy_from_user((void*)free_outp, buf, c))
17338 return -EFAULT;
17339 @@ -854,13 +941,10 @@
17340 if (!port->started)
17341 {
17342 reg_sser_rw_cfg cfg = REG_RD(sser, port->regi_sser, rw_cfg);
17343 - reg_sser_rw_tr_cfg tr_cfg = REG_RD(sser, port->regi_sser, rw_tr_cfg);
17344 reg_sser_rw_rec_cfg rec_cfg = REG_RD(sser, port->regi_sser, rw_rec_cfg);
17345 cfg.en = regk_sser_yes;
17346 - tr_cfg.tr_en = port->output;
17347 rec_cfg.rec_en = port->input;
17348 REG_WR(sser, port->regi_sser, rw_cfg, cfg);
17349 - REG_WR(sser, port->regi_sser, rw_tr_cfg, tr_cfg);
17350 REG_WR(sser, port->regi_sser, rw_rec_cfg, rec_cfg);
17351 port->started = 1;
17352 }
17353 @@ -887,7 +971,7 @@
17354 }
17355
17356 /* Sleep until all sent */
17357 -
17358 +
17359 add_wait_queue(&port->out_wait_q, &wait);
17360 set_current_state(TASK_INTERRUPTIBLE);
17361 spin_lock_irqsave(&port->lock, flags);
17362 @@ -916,13 +1000,13 @@
17363 return count;
17364 }
17365
17366 -static ssize_t sync_serial_read(struct file * file, char * buf,
17367 +static ssize_t sync_serial_read(struct file * file, char * buf,
17368 size_t count, loff_t *ppos)
17369 {
17370 int dev = iminor(file->f_dentry->d_inode);
17371 int avail;
17372 sync_port *port;
17373 - unsigned char* start;
17374 + unsigned char* start;
17375 unsigned char* end;
17376 unsigned long flags;
17377
17378 @@ -949,7 +1033,7 @@
17379 port->started = 1;
17380 }
17381
17382 -
17383 +
17384 /* Calculate number of available bytes */
17385 /* Save pointers to avoid that they are modified by interrupt */
17386 spin_lock_irqsave(&port->lock, flags);
17387 @@ -958,11 +1042,12 @@
17388 spin_unlock_irqrestore(&port->lock, flags);
17389 while ((start == end) && !port->full) /* No data */
17390 {
17391 + DEBUGREAD(printk("&"));
17392 if (file->f_flags & O_NONBLOCK)
17393 - {
17394 + {
17395 return -EAGAIN;
17396 }
17397 -
17398 +
17399 interruptible_sleep_on(&port->in_wait_q);
17400 if (signal_pending(current))
17401 {
17402 @@ -979,9 +1064,9 @@
17403 avail = port->in_buffer_size;
17404 else if (end > start)
17405 avail = end - start;
17406 - else
17407 + else
17408 avail = port->flip + port->in_buffer_size - start;
17409 -
17410 +
17411 count = count > avail ? avail : count;
17412 if (copy_to_user(buf, start, count))
17413 return -EFAULT;
17414 @@ -1016,7 +1101,7 @@
17415 data |= *port->outp++;
17416 port->out_count-=2;
17417 tr_data.data = data;
17418 - REG_WR(sser, port->regi_sser, rw_tr_data, tr_data);
17419 + REG_WR(sser, port->regi_sser, rw_tr_data, tr_data);
17420 if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE)
17421 port->outp = port->out_buffer;
17422 }
17423 @@ -1032,7 +1117,7 @@
17424 case 24:
17425 port->out_count-=3;
17426 tr_data.data = *(unsigned short *)port->outp;
17427 - REG_WR(sser, port->regi_sser, rw_tr_data, tr_data);
17428 + REG_WR(sser, port->regi_sser, rw_tr_data, tr_data);
17429 port->outp+=2;
17430 tr_data.data = *port->outp++;
17431 REG_WR(sser, port->regi_sser, rw_tr_data, tr_data);
17432 @@ -1042,10 +1127,10 @@
17433 case 32:
17434 port->out_count-=4;
17435 tr_data.data = *(unsigned short *)port->outp;
17436 - REG_WR(sser, port->regi_sser, rw_tr_data, tr_data);
17437 + REG_WR(sser, port->regi_sser, rw_tr_data, tr_data);
17438 port->outp+=2;
17439 tr_data.data = *(unsigned short *)port->outp;
17440 - REG_WR(sser, port->regi_sser, rw_tr_data, tr_data);
17441 + REG_WR(sser, port->regi_sser, rw_tr_data, tr_data);
17442 port->outp+=2;
17443 if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE)
17444 port->outp = port->out_buffer;
17445 @@ -1056,15 +1141,27 @@
17446
17447 static void start_dma(struct sync_port* port, const char* data, int count)
17448 {
17449 + int i;
17450 + reg_sser_rw_tr_cfg tr_cfg = REG_RD(sser, port->regi_sser, rw_tr_cfg);
17451 port->tr_running = 1;
17452 - port->out_descr.buf = (char*)virt_to_phys((char*)data);
17453 - port->out_descr.after = port->out_descr.buf + count;
17454 - port->out_descr.eol = port->out_descr.intr = 1;
17455 + for (i = 0; i < NUM_OUT_DESCRS; i++)
17456 + {
17457 + port->out_descr[i].buf = (char*)virt_to_phys(port->out_buffer + 1024*i);
17458 + port->out_descr[i].after = port->out_descr[i].buf + 1024;
17459 + port->out_descr[i].eol = 0;
17460 + port->out_descr[i].intr = 1;
17461 + port->out_descr[i].next = virt_to_phys(&port->out_descr[i+1]);
17462 + }
17463 + port->out_descr[i-1].next = virt_to_phys(&port->out_descr[0]);
17464
17465 - port->out_context.saved_data = (dma_descr_data*)virt_to_phys(&port->out_descr);
17466 - port->out_context.saved_data_buf = port->out_descr.buf;
17467 + port->out_context.saved_data = (dma_descr_data*)virt_to_phys(&port->out_descr[0]);
17468 + port->out_context.saved_data_buf = port->out_descr[0].buf;
17469
17470 DMA_START_CONTEXT(port->regi_dmaout, virt_to_phys((char*)&port->out_context));
17471 +
17472 + tr_cfg.tr_en = regk_sser_yes;
17473 + REG_WR(sser, port->regi_sser, rw_tr_cfg, tr_cfg);
17474 +
17475 DEBUGTXINT(printk("dma %08lX c %d\n", (unsigned long)data, count));
17476 }
17477
17478 @@ -1073,7 +1170,7 @@
17479 int i;
17480 char* buf;
17481 port->writep = port->flip;
17482 -
17483 +
17484 if (port->writep > port->flip + port->in_buffer_size)
17485 {
17486 panic("Offset too large in sync serial driver\n");
17487 @@ -1099,7 +1196,7 @@
17488 }
17489
17490 #ifdef SYNC_SER_DMA
17491 -static irqreturn_t tr_interrupt(int irq, void *dev_id, struct pt_regs * regs)
17492 +static irqreturn_t tr_interrupt(int irq, void *dev_id)
17493 {
17494 reg_dma_r_masked_intr masked;
17495 reg_dma_rw_ack_intr ack_intr = {.data = regk_dma_yes};
17496 @@ -1108,7 +1205,7 @@
17497 unsigned int sentl;
17498 int found = 0;
17499
17500 - for (i = 0; i < NUMBER_OF_PORTS; i++)
17501 + for (i = 0; i < NUMBER_OF_PORTS; i++)
17502 {
17503 sync_port *port = &ports[i];
17504 if (!port->enabled || !port->use_dma )
17505 @@ -1133,18 +1230,21 @@
17506 if (c > port->out_count)
17507 c = port->out_count;
17508 DEBUGTXINT(printk("tx_int DMAWRITE %i %i\n", sentl, c));
17509 - start_dma(port, port->outp, c);
17510 + //start_dma(port, port->outp, c);
17511 } else {
17512 - DEBUGTXINT(printk("tx_int DMA stop %i\n", sentl));
17513 + reg_sser_rw_tr_cfg tr_cfg = REG_RD(sser, port->regi_sser, rw_tr_cfg);
17514 + DEBUGTXINT(printk("tx_int DMA stop %i\n", sentl));
17515 port->tr_running = 0;
17516 + tr_cfg.tr_en = regk_sser_no;
17517 + REG_WR(sser, port->regi_sser, rw_tr_cfg, tr_cfg);
17518 }
17519 wake_up_interruptible(&port->out_wait_q); /* wake up the waiting process */
17520 - }
17521 + }
17522 }
17523 return IRQ_RETVAL(found);
17524 } /* tr_interrupt */
17525
17526 -static irqreturn_t rx_interrupt(int irq, void *dev_id, struct pt_regs * regs)
17527 +static irqreturn_t rx_interrupt(int irq, void *dev_id)
17528 {
17529 reg_dma_r_masked_intr masked;
17530 reg_dma_rw_ack_intr ack_intr = {.data = regk_dma_yes};
17531 @@ -1152,7 +1252,7 @@
17532 int i;
17533 int found = 0;
17534
17535 - for (i = 0; i < NUMBER_OF_PORTS; i++)
17536 + for (i = 0; i < NUMBER_OF_PORTS; i++)
17537 {
17538 sync_port *port = &ports[i];
17539
17540 @@ -1164,17 +1264,17 @@
17541 if (masked.data) /* Descriptor interrupt */
17542 {
17543 found = 1;
17544 - while (REG_RD(dma, port->regi_dmain, rw_data) !=
17545 + while (REG_RD(dma, port->regi_dmain, rw_data) !=
17546 virt_to_phys(port->next_rx_desc)) {
17547 -
17548 + DEBUGRXINT(printk("!"));
17549 if (port->writep + port->inbufchunk > port->flip + port->in_buffer_size) {
17550 int first_size = port->flip + port->in_buffer_size - port->writep;
17551 memcpy((char*)port->writep, phys_to_virt((unsigned)port->next_rx_desc->buf), first_size);
17552 memcpy(port->flip, phys_to_virt((unsigned)port->next_rx_desc->buf+first_size), port->inbufchunk - first_size);
17553 port->writep = port->flip + port->inbufchunk - first_size;
17554 } else {
17555 - memcpy((char*)port->writep,
17556 - phys_to_virt((unsigned)port->next_rx_desc->buf),
17557 + memcpy((char*)port->writep,
17558 + phys_to_virt((unsigned)port->next_rx_desc->buf),
17559 port->inbufchunk);
17560 port->writep += port->inbufchunk;
17561 if (port->writep >= port->flip + port->in_buffer_size)
17562 @@ -1184,11 +1284,13 @@
17563 {
17564 port->full = 1;
17565 }
17566 -
17567 - port->next_rx_desc->eol = 0;
17568 - port->prev_rx_desc->eol = 1;
17569 - port->prev_rx_desc = phys_to_virt((unsigned)port->next_rx_desc);
17570 +
17571 + port->next_rx_desc->eol = 1;
17572 + port->prev_rx_desc->eol = 0;
17573 + flush_dma_descr(port->prev_rx_desc,0); // Cache bug workaround
17574 + port->prev_rx_desc = port->next_rx_desc;
17575 port->next_rx_desc = phys_to_virt((unsigned)port->next_rx_desc->next);
17576 + flush_dma_descr(port->prev_rx_desc,1); // Cache bug workaround
17577 wake_up_interruptible(&port->in_wait_q); /* wake up the waiting process */
17578 DMA_CONTINUE(port->regi_dmain);
17579 REG_WR(dma, port->regi_dmain, rw_ack_intr, ack_intr);
17580 @@ -1201,7 +1303,7 @@
17581 #endif /* SYNC_SER_DMA */
17582
17583 #ifdef SYNC_SER_MANUAL
17584 -static irqreturn_t manual_interrupt(int irq, void *dev_id, struct pt_regs * regs)
17585 +static irqreturn_t manual_interrupt(int irq, void *dev_id)
17586 {
17587 int i;
17588 int found = 0;
17589 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/kernel/Makefile linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/Makefile
17590 --- linux-2.6.19.2.old/arch/cris/arch-v32/kernel/Makefile 2007-01-10 20:10:37.000000000 +0100
17591 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/Makefile 2006-12-06 14:17:02.000000000 +0100
17592 @@ -1,4 +1,4 @@
17593 -# $Id: Makefile,v 1.11 2004/12/17 10:16:13 starvik Exp $
17594 +# $Id: Makefile,v 1.13 2006/12/06 13:17:02 starvik Exp $
17595 #
17596 # Makefile for the linux kernel.
17597 #
17598 @@ -8,7 +8,7 @@
17599
17600 obj-y := entry.o traps.o irq.o debugport.o dma.o pinmux.o \
17601 process.o ptrace.o setup.o signal.o traps.o time.o \
17602 - arbiter.o io.o
17603 + arbiter.o io.o cache.o cacheflush.o
17604
17605 obj-$(CONFIG_ETRAXFS_SIM) += vcs_hook.o
17606
17607 @@ -16,6 +16,7 @@
17608 obj-$(CONFIG_ETRAX_KGDB) += kgdb.o kgdb_asm.o
17609 obj-$(CONFIG_ETRAX_FAST_TIMER) += fasttimer.o
17610 obj-$(CONFIG_MODULES) += crisksyms.o
17611 +obj-$(CONFIG_CPU_FREQ) += cpufreq.o
17612
17613 clean:
17614
17615 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/kernel/arbiter.c linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/arbiter.c
17616 --- linux-2.6.19.2.old/arch/cris/arch-v32/kernel/arbiter.c 2007-01-10 20:10:37.000000000 +0100
17617 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/arbiter.c 2006-10-13 14:43:13.000000000 +0200
17618 @@ -6,7 +6,7 @@
17619 * bandwidth (e.g. ethernet) and then the remaining slots are divided
17620 * on all the active clients.
17621 *
17622 - * Copyright (c) 2004, 2005 Axis Communications AB.
17623 + * Copyright (c) 2004, 2005, 2006 Axis Communications AB.
17624 */
17625
17626 #include <asm/arch/hwregs/reg_map.h>
17627 @@ -44,35 +44,88 @@
17628 {regi_marb_bp3}
17629 };
17630
17631 -static int requested_slots[NBR_OF_REGIONS][NBR_OF_CLIENTS];
17632 -static int active_clients[NBR_OF_REGIONS][NBR_OF_CLIENTS];
17633 +static u8 requested_slots[NBR_OF_REGIONS][NBR_OF_CLIENTS];
17634 +static u8 active_clients[NBR_OF_REGIONS][NBR_OF_CLIENTS];
17635 static int max_bandwidth[NBR_OF_REGIONS] = {SDRAM_BANDWIDTH, INTMEM_BANDWIDTH};
17636
17637 DEFINE_SPINLOCK(arbiter_lock);
17638
17639 -static irqreturn_t
17640 +static irqreturn_t
17641 crisv32_arbiter_irq(int irq, void* dev_id, struct pt_regs* regs);
17642
17643 -static void crisv32_arbiter_config(int region)
17644 +/*
17645 + * "I'm the arbiter, I know the score.
17646 + * From square one I'll be watching all 64."
17647 + * (memory arbiter slots, that is)
17648 + *
17649 + * Or in other words:
17650 + * Program the memory arbiter slots for "region" according to what's
17651 + * in requested_slots[] and active_clients[], while minimizing
17652 + * latency. A caller may pass a non-zero positive amount for
17653 + * "unused_slots", which must then be the unallocated, remaining
17654 + * number of slots, free to hand out to any client.
17655 + */
17656 +
17657 +static void crisv32_arbiter_config(int region, int unused_slots)
17658 {
17659 int slot;
17660 int client;
17661 int interval = 0;
17662 - int val[NBR_OF_SLOTS];
17663 +
17664 + /*
17665 + * This vector corresponds to the hardware arbiter slots (see
17666 + * the hardware documentation for semantics). We initialize
17667 + * each slot with a suitable sentinel value outside the valid
17668 + * range {0 .. NBR_OF_CLIENTS - 1} and replace them with
17669 + * client indexes. Then it's fed to the hardware.
17670 + */
17671 + s8 val[NBR_OF_SLOTS];
17672
17673 for (slot = 0; slot < NBR_OF_SLOTS; slot++)
17674 - val[slot] = NBR_OF_CLIENTS + 1;
17675 + val[slot] = -1;
17676
17677 for (client = 0; client < NBR_OF_CLIENTS; client++)
17678 {
17679 int pos;
17680 + /* Allocate the requested non-zero number of slots, but
17681 + * also give clients with zero-requests one slot each
17682 + * while stocks last. We do the latter here, in client
17683 + * order. This makes sure zero-request clients are the
17684 + * first to get to any spare slots, else those slots
17685 + * could, when bandwidth is allocated close to the limit,
17686 + * all be allocated to low-index non-zero-request clients
17687 + * in the default-fill loop below. Another positive but
17688 + * secondary effect is a somewhat better spread of the
17689 + * zero-bandwidth clients in the vector, avoiding some of
17690 + * the latency that could otherwise be caused by the
17691 + * partitioning of non-zero-bandwidth clients at low
17692 + * indexes and zero-bandwidth clients at high
17693 + * indexes. (Note that this spreading can only affect the
17694 + * unallocated bandwidth.) All the above only matters for
17695 + * memory-intensive situations, of course.
17696 + */
17697 if (!requested_slots[region][client])
17698 - continue;
17699 - interval = NBR_OF_SLOTS / requested_slots[region][client];
17700 + {
17701 + /*
17702 + * Skip inactive clients. Also skip zero-slot
17703 + * allocations in this pass when there are no known
17704 + * free slots.
17705 + */
17706 + if (!active_clients[region][client] || unused_slots <= 0)
17707 + continue;
17708 +
17709 + unused_slots--;
17710 +
17711 + /* Only allocate one slot for this client. */
17712 + interval = NBR_OF_SLOTS;
17713 + }
17714 + else
17715 + interval = NBR_OF_SLOTS / requested_slots[region][client];
17716 +
17717 pos = 0;
17718 while (pos < NBR_OF_SLOTS)
17719 {
17720 - if (val[pos] != NBR_OF_CLIENTS + 1)
17721 + if (val[pos] >= 0)
17722 pos++;
17723 else
17724 {
17725 @@ -85,7 +138,13 @@
17726 client = 0;
17727 for (slot = 0; slot < NBR_OF_SLOTS; slot++)
17728 {
17729 - if (val[slot] == NBR_OF_CLIENTS + 1)
17730 + /*
17731 + * Allocate remaining slots in round-robin
17732 + * client-number order for active clients. For this
17733 + * pass, we ignore requested bandwidth and previous
17734 + * allocations.
17735 + */
17736 + if (val[slot] < 0)
17737 {
17738 int first = client;
17739 while(!active_clients[region][client]) {
17740 @@ -100,7 +159,7 @@
17741 REG_WR_INT_VECT(marb, regi_marb, rw_ext_slots, slot, val[slot]);
17742 else if (region == INT_REGION)
17743 REG_WR_INT_VECT(marb, regi_marb, rw_int_slots, slot, val[slot]);
17744 - }
17745 + }
17746 }
17747
17748 extern char _stext, _etext;
17749 @@ -111,18 +170,28 @@
17750
17751 if (initialized)
17752 return;
17753 -
17754 +
17755 initialized = 1;
17756
17757 - /* CPU caches are active. */
17758 - active_clients[EXT_REGION][10] = active_clients[EXT_REGION][11] = 1;
17759 - crisv32_arbiter_config(EXT_REGION);
17760 - crisv32_arbiter_config(INT_REGION);
17761 + /*
17762 + * CPU caches are always set to active, but with zero
17763 + * bandwidth allocated. It should be ok to allocate zero
17764 + * bandwidth for the caches, because DMA for other channels
17765 + * will supposedly finish, once their programmed amount is
17766 + * done, and then the caches will get access according to the
17767 + * "fixed scheme" for unclaimed slots. Though, if for some
17768 + * use-case somewhere, there's a maximum CPU latency for
17769 + * e.g. some interrupt, we have to start allocating specific
17770 + * bandwidth for the CPU caches too.
17771 + */
17772 + active_clients[EXT_REGION][10] = active_clients[EXT_REGION][11] = 1;
17773 + crisv32_arbiter_config(EXT_REGION, 0);
17774 + crisv32_arbiter_config(INT_REGION, 0);
17775
17776 if (request_irq(MEMARB_INTR_VECT, crisv32_arbiter_irq, IRQF_DISABLED,
17777 "arbiter", NULL))
17778 printk(KERN_ERR "Couldn't allocate arbiter IRQ\n");
17779 -
17780 +
17781 #ifndef CONFIG_ETRAX_KGDB
17782 /* Global watch for writes to kernel text segment. */
17783 crisv32_arbiter_watch(virt_to_phys(&_stext), &_etext - &_stext,
17784 @@ -130,6 +199,7 @@
17785 #endif
17786 }
17787
17788 +/* Main entry for bandwidth allocation. */
17789
17790
17791 int crisv32_arbiter_allocate_bandwidth(int client, int region,
17792 @@ -141,39 +211,76 @@
17793 int req;
17794
17795 crisv32_arbiter_init();
17796 -
17797 +
17798 for (i = 0; i < NBR_OF_CLIENTS; i++)
17799 {
17800 total_assigned += requested_slots[region][i];
17801 total_clients += active_clients[region][i];
17802 }
17803 - req = NBR_OF_SLOTS / (max_bandwidth[region] / bandwidth);
17804
17805 - if (total_assigned + total_clients + req + 1 > NBR_OF_SLOTS)
17806 + /* Avoid division by 0 for 0-bandwidth requests. */
17807 + req = bandwidth == 0
17808 + ? 0 : NBR_OF_SLOTS / (max_bandwidth[region] / bandwidth);
17809 +
17810 + /*
17811 + * We make sure that there are enough slots only for non-zero
17812 + * requests. Requesting 0 bandwidth *may* allocate slots,
17813 + * though if all bandwidth is allocated, such a client won't
17814 + * get any and will have to rely on getting memory access
17815 + * according to the fixed scheme that's the default when one
17816 + * of the slot-allocated clients doesn't claim their slot.
17817 + */
17818 + if (total_assigned + req > NBR_OF_SLOTS)
17819 return -ENOMEM;
17820
17821 active_clients[region][client] = 1;
17822 requested_slots[region][client] = req;
17823 - crisv32_arbiter_config(region);
17824 + crisv32_arbiter_config(region, NBR_OF_SLOTS - total_assigned);
17825
17826 return 0;
17827 }
17828
17829 +/*
17830 + * Main entry for bandwidth deallocation.
17831 + *
17832 + * Strictly speaking, for a somewhat constant set of clients where
17833 + * each client gets a constant bandwidth and is just enabled or
17834 + * disabled (somewhat dynamically), no action is necessary here to
17835 + * avoid starvation for non-zero-allocation clients, as the allocated
17836 + * slots will just be unused. However, handing out those unused slots
17837 + * to active clients avoids needless latency if the "fixed scheme"
17838 + * would give unclaimed slots to an eager low-index client.
17839 + */
17840 +
17841 +void crisv32_arbiter_deallocate_bandwidth(int client, int region)
17842 +{
17843 + int i;
17844 + int total_assigned = 0;
17845 +
17846 + requested_slots[region][client] = 0;
17847 + active_clients[region][client] = 0;
17848 +
17849 + for (i = 0; i < NBR_OF_CLIENTS; i++)
17850 + total_assigned += requested_slots[region][i];
17851 +
17852 + crisv32_arbiter_config(region, NBR_OF_SLOTS - total_assigned);
17853 +}
17854 +
17855 int crisv32_arbiter_watch(unsigned long start, unsigned long size,
17856 unsigned long clients, unsigned long accesses,
17857 watch_callback* cb)
17858 {
17859 int i;
17860 -
17861 +
17862 crisv32_arbiter_init();
17863 -
17864 +
17865 if (start > 0x80000000) {
17866 printk("Arbiter: %lX doesn't look like a physical address", start);
17867 return -EFAULT;
17868 }
17869
17870 spin_lock(&arbiter_lock);
17871 -
17872 +
17873 for (i = 0; i < NUMBER_OF_BP; i++) {
17874 if (!watches[i].used) {
17875 reg_marb_rw_intr_mask intr_mask = REG_RD(marb, regi_marb, rw_intr_mask);
17876 @@ -214,7 +321,7 @@
17877 crisv32_arbiter_init();
17878
17879 spin_lock(&arbiter_lock);
17880 -
17881 +
17882 if ((id < 0) || (id >= NUMBER_OF_BP) || (!watches[id].used)) {
17883 spin_unlock(&arbiter_lock);
17884 return -EINVAL;
17885 @@ -239,7 +346,7 @@
17886
17887 extern void show_registers(struct pt_regs *regs);
17888
17889 -static irqreturn_t
17890 +static irqreturn_t
17891 crisv32_arbiter_irq(int irq, void* dev_id, struct pt_regs* regs)
17892 {
17893 reg_marb_r_masked_intr masked_intr = REG_RD(marb, regi_marb, r_masked_intr);
17894 @@ -248,10 +355,10 @@
17895 reg_marb_bp_r_brk_op r_op;
17896 reg_marb_bp_r_brk_first_client r_first;
17897 reg_marb_bp_r_brk_size r_size;
17898 - reg_marb_bp_rw_ack ack = {0};
17899 + reg_marb_bp_rw_ack ack = {0};
17900 reg_marb_rw_ack_intr ack_intr = {.bp0=1,.bp1=1,.bp2=1,.bp3=1};
17901 struct crisv32_watch_entry* watch;
17902 -
17903 +
17904 if (masked_intr.bp0) {
17905 watch = &watches[0];
17906 ack_intr.bp0 = regk_marb_yes;
17907 @@ -291,6 +398,6 @@
17908 if (watch->cb)
17909 watch->cb();
17910
17911 -
17912 +
17913 return IRQ_HANDLED;
17914 }
17915 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/kernel/asm-offsets.c linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/asm-offsets.c
17916 --- linux-2.6.19.2.old/arch/cris/arch-v32/kernel/asm-offsets.c 2007-01-10 20:10:37.000000000 +0100
17917 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/asm-offsets.c 2003-06-02 10:39:38.000000000 +0200
17918 @@ -16,8 +16,8 @@
17919 {
17920 #define ENTRY(entry) DEFINE(PT_ ## entry, offsetof(struct pt_regs, entry))
17921 ENTRY(orig_r10);
17922 - ENTRY(r13);
17923 - ENTRY(r12);
17924 + ENTRY(r13);
17925 + ENTRY(r12);
17926 ENTRY(r11);
17927 ENTRY(r10);
17928 ENTRY(r9);
17929 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/kernel/cache.c linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/cache.c
17930 --- linux-2.6.19.2.old/arch/cris/arch-v32/kernel/cache.c 1970-01-01 01:00:00.000000000 +0100
17931 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/cache.c 2007-01-23 13:09:57.000000000 +0100
17932 @@ -0,0 +1,31 @@
17933 +#include <linux/module.h>
17934 +#include <asm/io.h>
17935 +#include <asm/arch/cache.h>
17936 +#include <asm/arch/hwregs/dma.h>
17937 +
17938 +// This file is used to workaround a cache bug, Guinness TR 106
17939 +
17940 +inline void flush_dma_descr(dma_descr_data* descr, int flush_buf)
17941 +{
17942 + // Flush descriptor to make sure we get correct in_eop and after
17943 + asm volatile ("ftagd [%0]" :: "r" (descr));
17944 + // Flush buffer pointed out by descriptor
17945 + if (flush_buf)
17946 + cris_flush_cache_range(phys_to_virt((unsigned)descr->buf), (unsigned)(descr->after - descr->buf));
17947 +}
17948 +
17949 +void flush_dma_list(dma_descr_data* descr)
17950 +{
17951 + while(1)
17952 + {
17953 + flush_dma_descr(descr, 1);
17954 + if (descr->eol)
17955 + break;
17956 + descr = phys_to_virt((unsigned)descr->next);
17957 + }
17958 +}
17959 +
17960 +EXPORT_SYMBOL(flush_dma_list);
17961 +EXPORT_SYMBOL(flush_dma_descr);
17962 +EXPORT_SYMBOL(cris_flush_cache);
17963 +EXPORT_SYMBOL(cris_flush_cache_range);
17964 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/kernel/cacheflush.S linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/cacheflush.S
17965 --- linux-2.6.19.2.old/arch/cris/arch-v32/kernel/cacheflush.S 1970-01-01 01:00:00.000000000 +0100
17966 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/cacheflush.S 2006-12-06 14:17:02.000000000 +0100
17967 @@ -0,0 +1,93 @@
17968 + .global cris_flush_cache_range
17969 +cris_flush_cache_range:
17970 + move.d 1024, $r12
17971 + cmp.d $r11, $r12
17972 + bhi cris_flush_1KB
17973 + nop
17974 + add.d $r10, $r11
17975 +cris_flush_last:
17976 + addq 32, $r10
17977 + cmp.d $r11, $r10
17978 + blt cris_flush_last
17979 + ftagd [$r10]
17980 + ret
17981 + nop
17982 +cris_flush_1KB:
17983 + ftagd [$r10]
17984 + addq 32, $r10
17985 + ftagd [$r10]
17986 + addq 32, $r10
17987 + ftagd [$r10]
17988 + addq 32, $r10
17989 + ftagd [$r10]
17990 + addq 32, $r10
17991 + ftagd [$r10]
17992 + addq 32, $r10
17993 + ftagd [$r10]
17994 + addq 32, $r10
17995 + ftagd [$r10]
17996 + addq 32, $r10
17997 + ftagd [$r10]
17998 + addq 32, $r10
17999 + ftagd [$r10]
18000 + addq 32, $r10
18001 + ftagd [$r10]
18002 + addq 32, $r10
18003 + ftagd [$r10]
18004 + addq 32, $r10
18005 + ftagd [$r10]
18006 + addq 32, $r10
18007 + ftagd [$r10]
18008 + addq 32, $r10
18009 + ftagd [$r10]
18010 + addq 32, $r10
18011 + ftagd [$r10]
18012 + addq 32, $r10
18013 + ftagd [$r10]
18014 + addq 32, $r10
18015 + ftagd [$r10]
18016 + addq 32, $r10
18017 + ftagd [$r10]
18018 + addq 32, $r10
18019 + ftagd [$r10]
18020 + addq 32, $r10
18021 + ftagd [$r10]
18022 + addq 32, $r10
18023 + ftagd [$r10]
18024 + addq 32, $r10
18025 + ftagd [$r10]
18026 + addq 32, $r10
18027 + ftagd [$r10]
18028 + addq 32, $r10
18029 + ftagd [$r10]
18030 + addq 32, $r10
18031 + ftagd [$r10]
18032 + addq 32, $r10
18033 + ftagd [$r10]
18034 + addq 32, $r10
18035 + ftagd [$r10]
18036 + addq 32, $r10
18037 + ftagd [$r10]
18038 + addq 32, $r10
18039 + ftagd [$r10]
18040 + addq 32, $r10
18041 + ftagd [$r10]
18042 + addq 32, $r10
18043 + ftagd [$r10]
18044 + addq 32, $r10
18045 + ftagd [$r10]
18046 + addq 32, $r10
18047 + ba cris_flush_cache_range
18048 + sub.d $r12, $r11
18049 +
18050 + .global cris_flush_cache
18051 +cris_flush_cache:
18052 + moveq 0, $r10
18053 +cris_flush_line:
18054 + move.d 16*1024, $r11
18055 + addq 16, $r10
18056 + cmp.d $r10, $r11
18057 + blt cris_flush_line
18058 + fidxd [$r10]
18059 + ret
18060 + nop
18061 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/kernel/cpufreq.c linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/cpufreq.c
18062 --- linux-2.6.19.2.old/arch/cris/arch-v32/kernel/cpufreq.c 1970-01-01 01:00:00.000000000 +0100
18063 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/cpufreq.c 2006-11-03 11:35:52.000000000 +0100
18064 @@ -0,0 +1,147 @@
18065 +#include <linux/init.h>
18066 +#include <linux/module.h>
18067 +#include <linux/cpufreq.h>
18068 +#include <asm/arch/hwregs/reg_map.h>
18069 +#include <asm/arch/hwregs/reg_rdwr.h>
18070 +#include <asm/arch/hwregs/config_defs.h>
18071 +#include <asm/arch/hwregs/bif_core_defs.h>
18072 +
18073 +static int
18074 +cris_sdram_freq_notifier(struct notifier_block *nb, unsigned long val, void *data);
18075 +
18076 +static struct notifier_block cris_sdram_freq_notifier_block = {
18077 + .notifier_call = cris_sdram_freq_notifier
18078 +};
18079 +
18080 +static struct cpufreq_frequency_table cris_freq_table[] = {
18081 + {0x01, 6000},
18082 + {0x02, 200000},
18083 + {0, CPUFREQ_TABLE_END},
18084 +};
18085 +
18086 +static unsigned int cris_freq_get_cpu_frequency(unsigned int cpu)
18087 +{
18088 + reg_config_rw_clk_ctrl clk_ctrl;
18089 + clk_ctrl = REG_RD(config, regi_config, rw_clk_ctrl);
18090 + return clk_ctrl.pll ? 200000 : 6000;
18091 +}
18092 +
18093 +static void cris_freq_set_cpu_state (unsigned int state)
18094 +{
18095 + int i;
18096 + struct cpufreq_freqs freqs;
18097 + reg_config_rw_clk_ctrl clk_ctrl;
18098 + clk_ctrl = REG_RD(config, regi_config, rw_clk_ctrl);
18099 +
18100 + for_each_cpu(i) {
18101 + freqs.old = cris_freq_get_cpu_frequency(i);
18102 + freqs.new = cris_freq_table[state].frequency;
18103 + freqs.cpu = i;
18104 + }
18105 +
18106 + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
18107 +
18108 + local_irq_disable();
18109 +
18110 + // Even though we may be SMP they will share the same clock
18111 + // so all settings are made on CPU0.
18112 + if (cris_freq_table[state].frequency == 200000)
18113 + clk_ctrl.pll = 1;
18114 + else
18115 + clk_ctrl.pll = 0;
18116 + REG_WR(config, regi_config, rw_clk_ctrl, clk_ctrl);
18117 +
18118 + local_irq_enable();
18119 +
18120 + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
18121 +};
18122 +
18123 +static int cris_freq_verify (struct cpufreq_policy *policy)
18124 +{
18125 + return cpufreq_frequency_table_verify(policy, &cris_freq_table[0]);
18126 +}
18127 +
18128 +static int cris_freq_target (struct cpufreq_policy *policy,
18129 + unsigned int target_freq,
18130 + unsigned int relation)
18131 +{
18132 + unsigned int newstate = 0;
18133 +
18134 + if (cpufreq_frequency_table_target(policy, cris_freq_table, target_freq, relation, &newstate))
18135 + return -EINVAL;
18136 +
18137 + cris_freq_set_cpu_state(newstate);
18138 +
18139 + return 0;
18140 +}
18141 +
18142 +static int cris_freq_cpu_init(struct cpufreq_policy *policy)
18143 +{
18144 + int result;
18145 +
18146 + /* cpuinfo and default policy values */
18147 + policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
18148 + policy->cpuinfo.transition_latency = 1000000; /* 1ms */
18149 + policy->cur = cris_freq_get_cpu_frequency(0);
18150 +
18151 + result = cpufreq_frequency_table_cpuinfo(policy, cris_freq_table);
18152 + if (result)
18153 + return (result);
18154 +
18155 + cpufreq_frequency_table_get_attr(cris_freq_table, policy->cpu);
18156 +
18157 + return 0;
18158 +}
18159 +
18160 +
18161 +static int cris_freq_cpu_exit(struct cpufreq_policy *policy)
18162 +{
18163 + cpufreq_frequency_table_put_attr(policy->cpu);
18164 + return 0;
18165 +}
18166 +
18167 +
18168 +static struct freq_attr* cris_freq_attr[] = {
18169 + &cpufreq_freq_attr_scaling_available_freqs,
18170 + NULL,
18171 +};
18172 +
18173 +static struct cpufreq_driver cris_freq_driver = {
18174 + .get = cris_freq_get_cpu_frequency,
18175 + .verify = cris_freq_verify,
18176 + .target = cris_freq_target,
18177 + .init = cris_freq_cpu_init,
18178 + .exit = cris_freq_cpu_exit,
18179 + .name = "cris_freq",
18180 + .owner = THIS_MODULE,
18181 + .attr = cris_freq_attr,
18182 +};
18183 +
18184 +static int __init cris_freq_init(void)
18185 +{
18186 + int ret;
18187 + ret = cpufreq_register_driver(&cris_freq_driver);
18188 + cpufreq_register_notifier(&cris_sdram_freq_notifier_block,
18189 + CPUFREQ_TRANSITION_NOTIFIER);
18190 + return ret;
18191 +}
18192 +
18193 +static int
18194 +cris_sdram_freq_notifier(struct notifier_block *nb, unsigned long val, void *data)
18195 +{
18196 + int i;
18197 + struct cpufreq_freqs *freqs = data;
18198 + if (val == CPUFREQ_PRECHANGE) {
18199 + reg_bif_core_rw_sdram_timing timing =
18200 + REG_RD(bif_core, regi_bif_core, rw_sdram_timing);
18201 + timing.cpd = (freqs->new == 200000 ? 0 : 1);
18202 +
18203 + if (freqs->new == 200000)
18204 + for (i = 0; i < 50000; i++);
18205 + REG_WR(bif_core, regi_bif_core, rw_sdram_timing, timing);
18206 + }
18207 + return 0;
18208 +}
18209 +
18210 +
18211 +module_init(cris_freq_init);
18212 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/kernel/crisksyms.c linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/crisksyms.c
18213 --- linux-2.6.19.2.old/arch/cris/arch-v32/kernel/crisksyms.c 2007-01-10 20:10:37.000000000 +0100
18214 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/crisksyms.c 2006-11-21 04:21:34.000000000 +0100
18215 @@ -3,6 +3,7 @@
18216 #include <asm/arch/dma.h>
18217 #include <asm/arch/intmem.h>
18218 #include <asm/arch/pinmux.h>
18219 +#include <asm/arch/io.h>
18220
18221 /* Functions for allocating DMA channels */
18222 EXPORT_SYMBOL(crisv32_request_dma);
18223 @@ -16,7 +17,11 @@
18224
18225 /* Functions for handling pinmux */
18226 EXPORT_SYMBOL(crisv32_pinmux_alloc);
18227 +EXPORT_SYMBOL(crisv32_pinmux_alloc_fixed);
18228 EXPORT_SYMBOL(crisv32_pinmux_dealloc);
18229 +EXPORT_SYMBOL(crisv32_pinmux_dealloc_fixed);
18230 +EXPORT_SYMBOL(crisv32_io_get_name);
18231 +EXPORT_SYMBOL(crisv32_io_get);
18232
18233 /* Functions masking/unmasking interrupts */
18234 EXPORT_SYMBOL(mask_irq);
18235 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/kernel/debugport.c linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/debugport.c
18236 --- linux-2.6.19.2.old/arch/cris/arch-v32/kernel/debugport.c 2007-01-10 20:10:37.000000000 +0100
18237 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/debugport.c 2006-10-13 14:43:13.000000000 +0200
18238 @@ -4,18 +4,13 @@
18239
18240 #include <linux/console.h>
18241 #include <linux/init.h>
18242 -#include <linux/major.h>
18243 -#include <linux/delay.h>
18244 -#include <linux/tty.h>
18245 #include <asm/system.h>
18246 -#include <asm/io.h>
18247 +#include <asm/arch/hwregs/reg_rdwr.h>
18248 +#include <asm/arch/hwregs/reg_map.h>
18249 #include <asm/arch/hwregs/ser_defs.h>
18250 #include <asm/arch/hwregs/dma_defs.h>
18251 #include <asm/arch/pinmux.h>
18252
18253 -#include <asm/irq.h>
18254 -#include <asm/arch/hwregs/intr_vect_defs.h>
18255 -
18256 struct dbg_port
18257 {
18258 unsigned char nbr;
18259 @@ -26,7 +21,7 @@
18260 unsigned int bits;
18261 };
18262
18263 -struct dbg_port ports[] =
18264 +struct dbg_port ports[] =
18265 {
18266 {
18267 0,
18268 @@ -89,15 +84,6 @@
18269 #endif
18270 #endif
18271
18272 -#ifdef CONFIG_ETRAXFS_SIM
18273 -extern void print_str( const char *str );
18274 -static char buffer[1024];
18275 -static char msg[] = "Debug: ";
18276 -static int buffer_pos = sizeof(msg) - 1;
18277 -#endif
18278 -
18279 -extern struct tty_driver *serial_driver;
18280 -
18281 static void
18282 start_port(struct dbg_port* p)
18283 {
18284 @@ -118,7 +104,7 @@
18285 /* Set up serial port registers */
18286 reg_ser_rw_tr_ctrl tr_ctrl = {0};
18287 reg_ser_rw_tr_dma_en tr_dma_en = {0};
18288 -
18289 +
18290 reg_ser_rw_rec_ctrl rec_ctrl = {0};
18291 reg_ser_rw_tr_baud_div tr_baud_div = {0};
18292 reg_ser_rw_rec_baud_div rec_baud_div = {0};
18293 @@ -148,6 +134,7 @@
18294 tr_ctrl.data_bits = regk_ser_bits7;
18295 rec_ctrl.data_bits = regk_ser_bits7;
18296 }
18297 +
18298
18299 REG_WR (ser, p->instance, rw_tr_baud_div, tr_baud_div);
18300 REG_WR (ser, p->instance, rw_rec_baud_div, rec_baud_div);
18301 @@ -156,124 +143,21 @@
18302 REG_WR (ser, p->instance, rw_rec_ctrl, rec_ctrl);
18303 }
18304
18305 -/* No debug */
18306 -#ifdef CONFIG_ETRAX_DEBUG_PORT_NULL
18307 -
18308 -static void
18309 -console_write(struct console *co, const char *buf, unsigned int len)
18310 -{
18311 - return;
18312 -}
18313 -
18314 -/* Target debug */
18315 -#elif !defined(CONFIG_ETRAXFS_SIM)
18316 -
18317 -static void
18318 -console_write_direct(struct console *co, const char *buf, unsigned int len)
18319 -{
18320 - int i;
18321 - reg_ser_r_stat_din stat;
18322 - reg_ser_rw_tr_dma_en tr_dma_en, old;
18323 -
18324 - /* Switch to manual mode */
18325 - tr_dma_en = old = REG_RD (ser, port->instance, rw_tr_dma_en);
18326 - if (tr_dma_en.en == regk_ser_yes) {
18327 - tr_dma_en.en = regk_ser_no;
18328 - REG_WR(ser, port->instance, rw_tr_dma_en, tr_dma_en);
18329 - }
18330 -
18331 - /* Send data */
18332 - for (i = 0; i < len; i++) {
18333 - /* LF -> CRLF */
18334 - if (buf[i] == '\n') {
18335 - do {
18336 - stat = REG_RD (ser, port->instance, r_stat_din);
18337 - } while (!stat.tr_rdy);
18338 - REG_WR_INT (ser, port->instance, rw_dout, '\r');
18339 - }
18340 - /* Wait until transmitter is ready and send.*/
18341 - do {
18342 - stat = REG_RD (ser, port->instance, r_stat_din);
18343 - } while (!stat.tr_rdy);
18344 - REG_WR_INT (ser, port->instance, rw_dout, buf[i]);
18345 - }
18346 -
18347 - /* Restore mode */
18348 - if (tr_dma_en.en != old.en)
18349 - REG_WR(ser, port->instance, rw_tr_dma_en, old);
18350 -}
18351 -
18352 -static void
18353 -console_write(struct console *co, const char *buf, unsigned int len)
18354 -{
18355 - if (!port)
18356 - return;
18357 - console_write_direct(co, buf, len);
18358 -}
18359 -
18360 -
18361 -
18362 -#else
18363 -
18364 -/* VCS debug */
18365 -
18366 -static void
18367 -console_write(struct console *co, const char *buf, unsigned int len)
18368 -{
18369 - char* pos;
18370 - pos = memchr(buf, '\n', len);
18371 - if (pos) {
18372 - int l = ++pos - buf;
18373 - memcpy(buffer + buffer_pos, buf, l);
18374 - memcpy(buffer, msg, sizeof(msg) - 1);
18375 - buffer[buffer_pos + l] = '\0';
18376 - print_str(buffer);
18377 - buffer_pos = sizeof(msg) - 1;
18378 - if (pos - buf != len) {
18379 - memcpy(buffer + buffer_pos, pos, len - l);
18380 - buffer_pos += len - l;
18381 - }
18382 - } else {
18383 - memcpy(buffer + buffer_pos, buf, len);
18384 - buffer_pos += len;
18385 - }
18386 -}
18387 -
18388 -#endif
18389 -
18390 -int raw_printk(const char *fmt, ...)
18391 -{
18392 - static char buf[1024];
18393 - int printed_len;
18394 - va_list args;
18395 - va_start(args, fmt);
18396 - printed_len = vsnprintf(buf, sizeof(buf), fmt, args);
18397 - va_end(args);
18398 - console_write(NULL, buf, strlen(buf));
18399 - return printed_len;
18400 -}
18401 -
18402 -void
18403 -stupid_debug(char* buf)
18404 -{
18405 - console_write(NULL, buf, strlen(buf));
18406 -}
18407 -
18408 #ifdef CONFIG_ETRAX_KGDB
18409 /* Use polling to get a single character from the kernel debug port */
18410 int
18411 getDebugChar(void)
18412 {
18413 - reg_ser_rs_status_data stat;
18414 + reg_ser_rs_stat_din stat;
18415 reg_ser_rw_ack_intr ack_intr = { 0 };
18416
18417 do {
18418 - stat = REG_RD(ser, kgdb_instance, rs_status_data);
18419 - } while (!stat.data_avail);
18420 + stat = REG_RD(ser, kgdb_port->instance, rs_stat_din);
18421 + } while (!stat.dav);
18422
18423 /* Ack the data_avail interrupt. */
18424 - ack_intr.data_avail = 1;
18425 - REG_WR(ser, kgdb_instance, rw_ack_intr, ack_intr);
18426 + ack_intr.dav = 1;
18427 + REG_WR(ser, kgdb_port->instance, rw_ack_intr, ack_intr);
18428
18429 return stat.data;
18430 }
18431 @@ -282,173 +166,18 @@
18432 void
18433 putDebugChar(int val)
18434 {
18435 - reg_ser_r_status_data stat;
18436 + reg_ser_r_stat_din stat;
18437 do {
18438 - stat = REG_RD (ser, kgdb_instance, r_status_data);
18439 - } while (!stat.tr_ready);
18440 - REG_WR (ser, kgdb_instance, rw_data_out, REG_TYPE_CONV(reg_ser_rw_data_out, int, val));
18441 + stat = REG_RD (ser, kgdb_port->instance, r_stat_din);
18442 + } while (!stat.tr_rdy);
18443 + REG_WR_INT (ser, kgdb_port->instance, rw_dout, val);
18444 }
18445 #endif /* CONFIG_ETRAX_KGDB */
18446
18447 -static int __init
18448 -console_setup(struct console *co, char *options)
18449 -{
18450 - char* s;
18451 -
18452 - if (options) {
18453 - port = &ports[co->index];
18454 - port->baudrate = 115200;
18455 - port->parity = 'N';
18456 - port->bits = 8;
18457 - port->baudrate = simple_strtoul(options, NULL, 10);
18458 - s = options;
18459 - while(*s >= '0' && *s <= '9')
18460 - s++;
18461 - if (*s) port->parity = *s++;
18462 - if (*s) port->bits = *s++ - '0';
18463 - port->started = 0;
18464 - start_port(port);
18465 - }
18466 - return 0;
18467 -}
18468 -
18469 -/* This is a dummy serial device that throws away anything written to it.
18470 - * This is used when no debug output is wanted.
18471 - */
18472 -static struct tty_driver dummy_driver;
18473 -
18474 -static int dummy_open(struct tty_struct *tty, struct file * filp)
18475 -{
18476 - return 0;
18477 -}
18478 -
18479 -static void dummy_close(struct tty_struct *tty, struct file * filp)
18480 -{
18481 -}
18482 -
18483 -static int dummy_write(struct tty_struct * tty,
18484 - const unsigned char *buf, int count)
18485 -{
18486 - return count;
18487 -}
18488 -
18489 -static int
18490 -dummy_write_room(struct tty_struct *tty)
18491 -{
18492 - return 8192;
18493 -}
18494 -
18495 -void __init
18496 -init_dummy_console(void)
18497 -{
18498 - memset(&dummy_driver, 0, sizeof(struct tty_driver));
18499 - dummy_driver.driver_name = "serial";
18500 - dummy_driver.name = "ttyS";
18501 - dummy_driver.major = TTY_MAJOR;
18502 - dummy_driver.minor_start = 68;
18503 - dummy_driver.num = 1; /* etrax100 has 4 serial ports */
18504 - dummy_driver.type = TTY_DRIVER_TYPE_SERIAL;
18505 - dummy_driver.subtype = SERIAL_TYPE_NORMAL;
18506 - dummy_driver.init_termios = tty_std_termios;
18507 - dummy_driver.init_termios.c_cflag =
18508 - B115200 | CS8 | CREAD | HUPCL | CLOCAL; /* is normally B9600 default... */
18509 - dummy_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
18510 -
18511 - dummy_driver.open = dummy_open;
18512 - dummy_driver.close = dummy_close;
18513 - dummy_driver.write = dummy_write;
18514 - dummy_driver.write_room = dummy_write_room;
18515 - if (tty_register_driver(&dummy_driver))
18516 - panic("Couldn't register dummy serial driver\n");
18517 -}
18518 -
18519 -static struct tty_driver*
18520 -crisv32_console_device(struct console* co, int *index)
18521 -{
18522 - if (port)
18523 - *index = port->nbr;
18524 - return port ? serial_driver : &dummy_driver;
18525 -}
18526 -
18527 -static struct console sercons = {
18528 - name : "ttyS",
18529 - write: console_write,
18530 - read : NULL,
18531 - device : crisv32_console_device,
18532 - unblank : NULL,
18533 - setup : console_setup,
18534 - flags : CON_PRINTBUFFER,
18535 - index : -1,
18536 - cflag : 0,
18537 - next : NULL
18538 -};
18539 -static struct console sercons0 = {
18540 - name : "ttyS",
18541 - write: console_write,
18542 - read : NULL,
18543 - device : crisv32_console_device,
18544 - unblank : NULL,
18545 - setup : console_setup,
18546 - flags : CON_PRINTBUFFER,
18547 - index : 0,
18548 - cflag : 0,
18549 - next : NULL
18550 -};
18551 -
18552 -static struct console sercons1 = {
18553 - name : "ttyS",
18554 - write: console_write,
18555 - read : NULL,
18556 - device : crisv32_console_device,
18557 - unblank : NULL,
18558 - setup : console_setup,
18559 - flags : CON_PRINTBUFFER,
18560 - index : 1,
18561 - cflag : 0,
18562 - next : NULL
18563 -};
18564 -static struct console sercons2 = {
18565 - name : "ttyS",
18566 - write: console_write,
18567 - read : NULL,
18568 - device : crisv32_console_device,
18569 - unblank : NULL,
18570 - setup : console_setup,
18571 - flags : CON_PRINTBUFFER,
18572 - index : 2,
18573 - cflag : 0,
18574 - next : NULL
18575 -};
18576 -static struct console sercons3 = {
18577 - name : "ttyS",
18578 - write: console_write,
18579 - read : NULL,
18580 - device : crisv32_console_device,
18581 - unblank : NULL,
18582 - setup : console_setup,
18583 - flags : CON_PRINTBUFFER,
18584 - index : 3,
18585 - cflag : 0,
18586 - next : NULL
18587 -};
18588 -
18589 /* Register console for printk's, etc. */
18590 int __init
18591 init_etrax_debug(void)
18592 {
18593 - static int first = 1;
18594 -
18595 - if (!first) {
18596 - unregister_console(&sercons);
18597 - register_console(&sercons0);
18598 - register_console(&sercons1);
18599 - register_console(&sercons2);
18600 - register_console(&sercons3);
18601 - init_dummy_console();
18602 - return 0;
18603 - }
18604 - first = 0;
18605 - register_console(&sercons);
18606 start_port(port);
18607
18608 #ifdef CONFIG_ETRAX_KGDB
18609 @@ -456,5 +185,3 @@
18610 #endif /* CONFIG_ETRAX_KGDB */
18611 return 0;
18612 }
18613 -
18614 -__initcall(init_etrax_debug);
18615 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/kernel/dma.c linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/dma.c
18616 --- linux-2.6.19.2.old/arch/cris/arch-v32/kernel/dma.c 2007-01-10 20:10:37.000000000 +0100
18617 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/dma.c 2007-02-02 08:45:22.000000000 +0100
18618 @@ -12,6 +12,16 @@
18619 #include <asm/system.h>
18620 #include <asm/arch/arbiter.h>
18621
18622 +/*
18623 + * The memory region we allocated bandwidth for is stored in
18624 + * used_dma_channels as an in-use flag.
18625 + */
18626 +enum dma_region_allocated_marker {
18627 + DMA_NO_REGION_ALLOCATED = 0,
18628 + DMA_INT_REGION_ALLOCATED = 1,
18629 + DMA_EXT_REGION_ALLOCATED = 2
18630 +};
18631 +
18632 static char used_dma_channels[MAX_DMA_CHANNELS];
18633 static const char * used_dma_channels_users[MAX_DMA_CHANNELS];
18634
18635 @@ -74,7 +84,7 @@
18636 if (options & DMA_VERBOSE_ON_ERROR) {
18637 printk("Failed to request DMA %i for %s, only 0-%i valid)\n", dmanr, device_id, MAX_DMA_CHANNELS-1);
18638 }
18639 -
18640 +
18641 if (options & DMA_PANIC_ON_ERROR)
18642 panic("request_dma error!");
18643 return -EINVAL;
18644 @@ -202,13 +212,14 @@
18645 if (dmanr == 3)
18646 strmux_cfg.dma3 = regk_strmux_ext3;
18647 else if (dmanr == 9)
18648 - strmux_cfg.dma9 = regk_strmux_ext2;
18649 + strmux_cfg.dma9 = regk_strmux_ext3;
18650 else
18651 - panic("Invalid DMA channel for ext2\n");
18652 + panic("Invalid DMA channel for ext3\n");
18653 break;
18654 }
18655
18656 - used_dma_channels[dmanr] = 1;
18657 + used_dma_channels[dmanr] = options & DMA_INT_MEM
18658 + ? DMA_INT_REGION_ALLOCATED : DMA_EXT_REGION_ALLOCATED;
18659 used_dma_channels_users[dmanr] = device_id;
18660 REG_WR(config, regi_config, rw_clk_ctrl, clk_ctrl);
18661 REG_WR(strmux, regi_strmux, rw_cfg, strmux_cfg);
18662 @@ -218,7 +229,12 @@
18663
18664 void crisv32_free_dma(unsigned int dmanr)
18665 {
18666 + int region;
18667 +
18668 spin_lock(&dma_lock);
18669 + region = used_dma_channels[dmanr] == DMA_INT_REGION_ALLOCATED
18670 + ? INT_REGION : EXT_REGION;
18671 used_dma_channels[dmanr] = 0;
18672 + crisv32_arbiter_deallocate_bandwidth(dmanr, region);
18673 spin_unlock(&dma_lock);
18674 }
18675 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/kernel/entry.S linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/entry.S
18676 --- linux-2.6.19.2.old/arch/cris/arch-v32/kernel/entry.S 2007-01-10 20:10:37.000000000 +0100
18677 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/entry.S 2007-01-09 10:29:19.000000000 +0100
18678 @@ -11,7 +11,7 @@
18679 *
18680 * Stack layout in 'ret_from_system_call':
18681 * ptrace needs to have all regs on the stack.
18682 - * if the order here is changed, it needs to be
18683 + * if the order here is changed, it needs to be
18684 * updated in fork.c:copy_process, signal.c:do_signal,
18685 * ptrace.c and ptrace.h
18686 *
18687 @@ -40,7 +40,7 @@
18688 .globl sys_call_table
18689
18690 ; Check if preemptive kernel scheduling should be done.
18691 -#ifdef CONFIG_PREEMPT
18692 +#ifdef CONFIG_PREEMPT
18693 _resume_kernel:
18694 di
18695 ; Load current task struct.
18696 @@ -81,7 +81,7 @@
18697 nop
18698 ba ret_from_sys_call
18699 nop
18700 -
18701 +
18702 ret_from_intr:
18703 ;; Check for resched if preemptive kernel, or if we're going back to
18704 ;; user-mode. This test matches the user_regs(regs) macro. Don't simply
18705 @@ -93,7 +93,7 @@
18706 bpl _resume_kernel
18707
18708 ; Note that di below is in delay slot.
18709 -
18710 +
18711 _resume_userspace:
18712 di ; So need_resched and sigpending don't change.
18713
18714 @@ -107,19 +107,19 @@
18715 nop
18716 ba _Rexit
18717 nop
18718 -
18719 +
18720 ;; The system_call is called by a BREAK instruction, which looks pretty
18721 ;; much like any other exception.
18722 ;;
18723 ;; System calls can't be made from interrupts but we still stack ERP
18724 ;; to have a complete stack frame.
18725 - ;;
18726 + ;;
18727 ;; In r9 we have the wanted syscall number. Arguments come in r10,r11,r12,
18728 ;; r13,mof,srp
18729 ;;
18730 ;; This function looks on the _surface_ like spaghetti programming, but it's
18731 - ;; really designed so that the fast-path does not force cache-loading of
18732 - ;; non-used instructions. Only the non-common cases cause the outlined code
18733 + ;; really designed so that the fast-path does not force cache-loading of
18734 + ;; non-used instructions. Only the non-common cases cause the outlined code
18735 ;; to run..
18736
18737 system_call:
18738 @@ -151,7 +151,7 @@
18739 or.d (1<<9), $r0
18740 move $r0, $ccs
18741 #endif
18742 -
18743 +
18744 movs.w -ENOSYS, $r0
18745 addoq +PT_r10, $sp, $acr
18746 move.d $r0, [$acr]
18747 @@ -166,9 +166,9 @@
18748 bmi _syscall_trace_entry
18749 nop
18750
18751 -_syscall_traced:
18752 +_syscall_traced:
18753 ;; Check for sanity in the requested syscall number.
18754 - cmpu.w NR_syscalls, $r9
18755 + cmpu.w NR_syscalls, $r9
18756 bhs ret_from_sys_call
18757 lslq 2, $r9 ; Multiply by 4, in the delay slot.
18758
18759 @@ -177,7 +177,7 @@
18760 move.d $sp, $r0
18761 subq 4, $sp
18762 move.d $r0, [$sp]
18763 -
18764 +
18765 ;; The registers carrying parameters (R10-R13) are intact. The optional
18766 ;; fifth and sixth parameters is in MOF and SRP respectivly. Put them
18767 ;; back on the stack.
18768 @@ -185,33 +185,33 @@
18769 move $srp, [$sp]
18770 subq 4, $sp
18771 move $mof, [$sp]
18772 -
18773 +
18774 ;; Actually to the system call.
18775 addo.d +sys_call_table, $r9, $acr
18776 move.d [$acr], $acr
18777 jsr $acr
18778 nop
18779 -
18780 +
18781 addq 3*4, $sp ; Pop the mof, srp and regs parameters.
18782 addoq +PT_r10, $sp, $acr
18783 move.d $r10, [$acr] ; Save the return value.
18784
18785 - moveq 1, $r9 ; "Parameter" to ret_from_sys_call to
18786 + moveq 1, $r9 ; "Parameter" to ret_from_sys_call to
18787 ; show it was a sys call.
18788 -
18789 +
18790 ;; Fall through into ret_from_sys_call to return.
18791 -
18792 +
18793 ret_from_sys_call:
18794 ;; R9 is a parameter:
18795 ;; >= 1 from syscall
18796 ;; 0 from irq
18797 -
18798 +
18799 ;; Get the current task-struct pointer.
18800 - movs.w -8192, $r0 ; THREAD_SIZE == 8192
18801 + movs.w -8192, $r0 ; THREAD_SIZE == 8192
18802 and.d $sp, $r0
18803
18804 di ; Make sure need_resched and sigpending don't change.
18805 -
18806 +
18807 addoq +TI_flags, $r0, $acr
18808 move.d [$acr], $r1
18809 and.d _TIF_ALLWORK_MASK, $r1
18810 @@ -253,14 +253,14 @@
18811 move.d $r1, $r9
18812 ba _resume_userspace
18813 nop
18814 -
18815 +
18816 _work_pending:
18817 addoq +TI_flags, $r0, $acr
18818 move.d [$acr], $r10
18819 btstq TIF_NEED_RESCHED, $r10 ; Need resched?
18820 bpl _work_notifysig ; No, must be signal/notify.
18821 nop
18822 -
18823 +
18824 _work_resched:
18825 move.d $r9, $r1 ; Preserve R9.
18826 jsr schedule
18827 @@ -281,28 +281,26 @@
18828 ;; Deal with pending signals and notify-resume requests.
18829
18830 addoq +TI_flags, $r0, $acr
18831 - move.d [$acr], $r13 ; The thread_info_flags parameter.
18832 - move.d $r9, $r10 ; do_notify_resume syscall/irq param.
18833 - moveq 0, $r11 ; oldset param - 0 in this case.
18834 - move.d $sp, $r12 ; The regs param.
18835 + move.d [$acr], $r12 ; The thread_info_flags parameter.
18836 + move.d $sp, $r11 ; The regs param.
18837 jsr do_notify_resume
18838 - nop
18839 -
18840 + move.d $r9, $r10 ; do_notify_resume syscall/irq param.
18841 +
18842 ba _Rexit
18843 nop
18844
18845 ;; We get here as a sidetrack when we've entered a syscall with the
18846 ;; trace-bit set. We need to call do_syscall_trace and then continue
18847 ;; with the call.
18848 -
18849 +
18850 _syscall_trace_entry:
18851 ;; PT_r10 in the frame contains -ENOSYS as required, at this point.
18852 -
18853 +
18854 jsr do_syscall_trace
18855 nop
18856
18857 ;; Now re-enter the syscall code to do the syscall itself. We need to
18858 - ;; restore R9 here to contain the wanted syscall, and the other
18859 + ;; restore R9 here to contain the wanted syscall, and the other
18860 ;; parameter-bearing registers.
18861 addoq +PT_r9, $sp, $acr
18862 move.d [$acr], $r9
18863 @@ -318,10 +316,10 @@
18864 move [$acr], $mof
18865 addoq +PT_srp, $sp, $acr
18866 move [$acr], $srp
18867 -
18868 +
18869 ba _syscall_traced
18870 nop
18871 -
18872 +
18873 ;; Resume performs the actual task-switching, by switching stack
18874 ;; pointers. Input arguments are:
18875 ;;
18876 @@ -331,7 +329,7 @@
18877 ;;
18878 ;; Returns old current in R10.
18879
18880 -resume:
18881 +resume:
18882 subq 4, $sp
18883 move $srp, [$sp] ; Keep old/new PC on the stack.
18884 add.d $r12, $r10 ; R10 = current tasks tss.
18885 @@ -341,14 +339,14 @@
18886
18887 addoq +THREAD_usp, $r10, $acr
18888 move $usp, [$acr] ; Save user-mode stackpointer.
18889 -
18890 +
18891 ;; See copy_thread for the reason why register R9 is saved.
18892 subq 10*4, $sp
18893 movem $r9, [$sp] ; Save non-scratch registers and R9.
18894 -
18895 +
18896 addoq +THREAD_ksp, $r10, $acr
18897 move.d $sp, [$acr] ; Save kernel SP for old task.
18898 -
18899 +
18900 move.d $sp, $r10 ; Return last running task in R10.
18901 and.d -8192, $r10 ; Get thread_info from stackpointer.
18902 addoq +TI_task, $r10, $acr
18903 @@ -360,7 +358,7 @@
18904
18905 addoq +THREAD_usp, $r11, $acr
18906 move [$acr], $usp ; Restore user-mode stackpointer.
18907 -
18908 +
18909 addoq +THREAD_ccs, $r11, $acr
18910 move [$acr], $ccs ; Restore IRQ enable status.
18911 move.d [$sp+], $acr
18912 @@ -407,7 +405,7 @@
18913 movem [$sp+], $r13
18914 move.d [$sp+], $acr
18915 move [$sp], $srs
18916 - addq 4, $sp
18917 + addq 4, $sp
18918 move [$sp+], $mof
18919 move [$sp+], $spc
18920 move [$sp+], $ccs
18921 @@ -419,7 +417,7 @@
18922
18923 .comm cause_of_death, 4 ;; Don't declare this anywhere.
18924
18925 -spurious_interrupt:
18926 +spurious_interrupt:
18927 di
18928 jump hard_reset_now
18929 nop
18930 @@ -494,31 +492,38 @@
18931 ;; thread_info as first parameter
18932 move.d $r9, $r10
18933 moveq 5, $r11 ; SIGTRAP as second argument.
18934 - jsr ugdb_trap_user
18935 + jsr ugdb_trap_user
18936 nop
18937 jump ret_from_intr ; Use the return routine for interrupts.
18938 nop
18939 -
18940 -gdb_handle_exception:
18941 +
18942 +gdb_handle_exception:
18943 subq 4, $sp
18944 move.d $r0, [$sp]
18945 #ifdef CONFIG_ETRAX_KGDB
18946 - move $ccs, $r0 ; U-flag not affected by previous insns.
18947 + move $ccs, $r0 ; U-flag not affected by previous insns.
18948 btstq 16, $r0 ; Test the U-flag.
18949 - bmi _ugdb_handle_exception ; Go to user mode debugging.
18950 - nop ; Empty delay-slot (cannot pop R0 here).
18951 + bmi _ugdb_handle_exception ; Go to user mode debugging.
18952 + nop ; Empty delay-slot (cannot pop R0 here).
18953 ba kgdb_handle_exception ; Go to kernel debugging.
18954 move.d [$sp+], $r0 ; Restore R0 in delay slot.
18955 #endif
18956 -
18957 +
18958 _ugdb_handle_exception:
18959 ba do_sigtrap ; SIGTRAP the offending process.
18960 move.d [$sp+], $r0 ; Restore R0 in delay slot.
18961
18962 + .global kernel_execve
18963 +kernel_execve:
18964 + move.d __NR_execve, $r9
18965 + break 13
18966 + ret
18967 + nop
18968 +
18969 .data
18970
18971 .section .rodata,"a"
18972 -sys_call_table:
18973 +sys_call_table:
18974 .long sys_restart_syscall ; 0 - old "setup()" system call, used
18975 ; for restarting.
18976 .long sys_exit
18977 @@ -647,7 +652,7 @@
18978 .long sys_adjtimex
18979 .long sys_mprotect /* 125 */
18980 .long sys_sigprocmask
18981 - .long sys_ni_syscall /* old "create_module" */
18982 + .long sys_ni_syscall /* old "create_module" */
18983 .long sys_init_module
18984 .long sys_delete_module
18985 .long sys_ni_syscall /* 130: old "get_kernel_syms" */
18986 @@ -789,7 +794,7 @@
18987 .long sys_clock_getres
18988 .long sys_clock_nanosleep
18989 .long sys_statfs64
18990 - .long sys_fstatfs64
18991 + .long sys_fstatfs64
18992 .long sys_tgkill /* 270 */
18993 .long sys_utimes
18994 .long sys_fadvise64_64
18995 @@ -805,7 +810,43 @@
18996 .long sys_mq_getsetattr
18997 .long sys_ni_syscall /* reserved for kexec */
18998 .long sys_waitid
18999 -
19000 + .long sys_ni_syscall /* 285 */ /* available */
19001 + .long sys_add_key
19002 + .long sys_request_key
19003 + .long sys_keyctl
19004 + .long sys_ioprio_set
19005 + .long sys_ioprio_get /* 290 */
19006 + .long sys_inotify_init
19007 + .long sys_inotify_add_watch
19008 + .long sys_inotify_rm_watch
19009 + .long sys_migrate_pages
19010 + .long sys_openat /* 295 */
19011 + .long sys_mkdirat
19012 + .long sys_mknodat
19013 + .long sys_fchownat
19014 + .long sys_futimesat
19015 + .long sys_fstatat64 /* 300 */
19016 + .long sys_unlinkat
19017 + .long sys_renameat
19018 + .long sys_linkat
19019 + .long sys_symlinkat
19020 + .long sys_readlinkat /* 305 */
19021 + .long sys_fchmodat
19022 + .long sys_faccessat
19023 + .long sys_pselect6
19024 + .long sys_ppoll
19025 + .long sys_unshare /* 310 */
19026 + .long sys_set_robust_list
19027 + .long sys_set_robust_list
19028 + .long sys_get_robust_list
19029 + .long sys_splice
19030 + .long sys_sync_file_range
19031 + .long sys_tee /* 315 */
19032 + .long sys_vmsplice
19033 + .long sys_move_pages
19034 + .long sys_getcpu
19035 + .long sys_epoll_pwait
19036 +
19037 /*
19038 * NOTE!! This doesn't have to be exact - we just have
19039 * to make sure we have _enough_ of the "sys_ni_syscall"
19040 @@ -816,4 +857,4 @@
19041 .rept NR_syscalls - (.-sys_call_table) / 4
19042 .long sys_ni_syscall
19043 .endr
19044 -
19045 +
19046 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/kernel/fasttimer.c linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/fasttimer.c
19047 --- linux-2.6.19.2.old/arch/cris/arch-v32/kernel/fasttimer.c 2007-01-10 20:10:37.000000000 +0100
19048 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/fasttimer.c 2007-01-09 10:29:19.000000000 +0100
19049 @@ -1,110 +1,10 @@
19050 -/* $Id: fasttimer.c,v 1.11 2005/01/04 11:15:46 starvik Exp $
19051 +/*
19052 * linux/arch/cris/kernel/fasttimer.c
19053 *
19054 * Fast timers for ETRAX FS
19055 * This may be useful in other OS than Linux so use 2 space indentation...
19056 *
19057 - * $Log: fasttimer.c,v $
19058 - * Revision 1.11 2005/01/04 11:15:46 starvik
19059 - * Don't share timer IRQ.
19060 - *
19061 - * Revision 1.10 2004/12/07 09:19:38 starvik
19062 - * Corrected includes.
19063 - * Use correct interrupt macros.
19064 - *
19065 - * Revision 1.9 2004/05/14 10:18:58 starvik
19066 - * Export fast_timer_list
19067 - *
19068 - * Revision 1.8 2004/05/14 07:58:03 starvik
19069 - * Merge of changes from 2.4
19070 - *
19071 - * Revision 1.7 2003/07/10 12:06:14 starvik
19072 - * Return IRQ_NONE if irq wasn't handled
19073 - *
19074 - * Revision 1.6 2003/07/04 08:27:49 starvik
19075 - * Merge of Linux 2.5.74
19076 - *
19077 - * Revision 1.5 2003/06/05 10:16:22 johana
19078 - * New INTR_VECT macros.
19079 - *
19080 - * Revision 1.4 2003/06/03 08:49:45 johana
19081 - * Fixed typo.
19082 - *
19083 - * Revision 1.3 2003/06/02 12:51:27 johana
19084 - * Now compiles.
19085 - * Commented some include files that probably can be removed.
19086 - *
19087 - * Revision 1.2 2003/06/02 12:09:41 johana
19088 - * Ported to ETRAX FS using the trig interrupt instead of timer1.
19089 - *
19090 - * Revision 1.3 2002/12/12 08:26:32 starvik
19091 - * Don't use C-comments inside CVS comments
19092 - *
19093 - * Revision 1.2 2002/12/11 15:42:02 starvik
19094 - * Extracted v10 (ETRAX 100LX) specific stuff from arch/cris/kernel/
19095 - *
19096 - * Revision 1.1 2002/11/18 07:58:06 starvik
19097 - * Fast timers (from Linux 2.4)
19098 - *
19099 - * Revision 1.5 2002/10/15 06:21:39 starvik
19100 - * Added call to init_waitqueue_head
19101 - *
19102 - * Revision 1.4 2002/05/28 17:47:59 johana
19103 - * Added del_fast_timer()
19104 - *
19105 - * Revision 1.3 2002/05/28 16:16:07 johana
19106 - * Handle empty fast_timer_list
19107 - *
19108 - * Revision 1.2 2002/05/27 15:38:42 johana
19109 - * Made it compile without warnings on Linux 2.4.
19110 - * (includes, wait_queue, PROC_FS and snprintf)
19111 - *
19112 - * Revision 1.1 2002/05/27 15:32:25 johana
19113 - * arch/etrax100/kernel/fasttimer.c v1.8 from the elinux tree.
19114 - *
19115 - * Revision 1.8 2001/11/27 13:50:40 pkj
19116 - * Disable interrupts while stopping the timer and while modifying the
19117 - * list of active timers in timer1_handler() as it may be interrupted
19118 - * by other interrupts (e.g., the serial interrupt) which may add fast
19119 - * timers.
19120 - *
19121 - * Revision 1.7 2001/11/22 11:50:32 pkj
19122 - * * Only store information about the last 16 timers.
19123 - * * proc_fasttimer_read() now uses an allocated buffer, since it
19124 - * requires more space than just a page even for only writing the
19125 - * last 16 timers. The buffer is only allocated on request, so
19126 - * unless /proc/fasttimer is read, it is never allocated.
19127 - * * Renamed fast_timer_started to fast_timers_started to match
19128 - * fast_timers_added and fast_timers_expired.
19129 - * * Some clean-up.
19130 - *
19131 - * Revision 1.6 2000/12/13 14:02:08 johana
19132 - * Removed volatile for fast_timer_list
19133 - *
19134 - * Revision 1.5 2000/12/13 13:55:35 johana
19135 - * Added DEBUG_LOG, added som cli() and cleanup
19136 - *
19137 - * Revision 1.4 2000/12/05 13:48:50 johana
19138 - * Added range check when writing proc file, modified timer int handling
19139 - *
19140 - * Revision 1.3 2000/11/23 10:10:20 johana
19141 - * More debug/logging possibilities.
19142 - * Moved GET_JIFFIES_USEC() to timex.h and time.c
19143 - *
19144 - * Revision 1.2 2000/11/01 13:41:04 johana
19145 - * Clean up and bugfixes.
19146 - * Created new do_gettimeofday_fast() that gets a timeval struct
19147 - * with time based on jiffies and *R_TIMER0_DATA, uses a table
19148 - * for fast conversion of timer value to microseconds.
19149 - * (Much faster the standard do_gettimeofday() and we don't really
19150 - * wan't to use the true time - we wan't the "uptime" so timers don't screw up
19151 - * when we change the time.
19152 - * TODO: Add efficient support for continuous timers as well.
19153 - *
19154 - * Revision 1.1 2000/10/26 15:49:16 johana
19155 - * Added fasttimer, highresolution timers.
19156 - *
19157 - * Copyright (C) 2000,2001 2002, 2003 Axis Communications AB, Lund, Sweden
19158 + * Copyright (C) 2000-2006 Axis Communications AB, Lund, Sweden
19159 */
19160
19161 #include <linux/errno.h>
19162 @@ -128,13 +28,13 @@
19163 #include <asm/fasttimer.h>
19164 #include <linux/proc_fs.h>
19165
19166 -/*
19167 - * timer0 is running at 100MHz and generating jiffies timer ticks
19168 +/*
19169 + * timer0 is running at 100MHz and generating jiffies timer ticks
19170 * at 100 or 1000 HZ.
19171 * fasttimer gives an API that gives timers that expire "between" the jiffies
19172 * giving microsecond resolution (10 ns).
19173 * fasttimer uses reg_timer_rw_trig register to get interrupt when
19174 - * r_time reaches a certain value.
19175 + * r_time reaches a certain value.
19176 */
19177
19178
19179 @@ -151,19 +51,19 @@
19180 #define SANITYCHECK(x)
19181 #endif
19182
19183 -#define D1(x)
19184 -#define D2(x)
19185 -#define DP(x)
19186 +#define D1(x)
19187 +#define D2(x)
19188 +#define DP(x)
19189
19190 #define __INLINE__ inline
19191
19192 -static int fast_timer_running = 0;
19193 -static int fast_timers_added = 0;
19194 -static int fast_timers_started = 0;
19195 -static int fast_timers_expired = 0;
19196 -static int fast_timers_deleted = 0;
19197 -static int fast_timer_is_init = 0;
19198 -static int fast_timer_ints = 0;
19199 +static unsigned int fast_timer_running = 0;
19200 +static unsigned int fast_timers_added = 0;
19201 +static unsigned int fast_timers_started = 0;
19202 +static unsigned int fast_timers_expired = 0;
19203 +static unsigned int fast_timers_deleted = 0;
19204 +static unsigned int fast_timer_is_init = 0;
19205 +static unsigned int fast_timer_ints = 0;
19206
19207 struct fast_timer *fast_timer_list = NULL;
19208
19209 @@ -171,8 +71,8 @@
19210 #define DEBUG_LOG_MAX 128
19211 static const char * debug_log_string[DEBUG_LOG_MAX];
19212 static unsigned long debug_log_value[DEBUG_LOG_MAX];
19213 -static int debug_log_cnt = 0;
19214 -static int debug_log_cnt_wrapped = 0;
19215 +static unsigned int debug_log_cnt = 0;
19216 +static unsigned int debug_log_cnt_wrapped = 0;
19217
19218 #define DEBUG_LOG(string, value) \
19219 { \
19220 @@ -202,48 +102,33 @@
19221 int timer_div_settings[NUM_TIMER_STATS];
19222 int timer_delay_settings[NUM_TIMER_STATS];
19223
19224 +struct work_struct fast_work;
19225
19226 static void
19227 -timer_trig_handler(void);
19228 +timer_trig_handler(void* dummy);
19229
19230
19231
19232 /* Not true gettimeofday, only checks the jiffies (uptime) + useconds */
19233 -void __INLINE__ do_gettimeofday_fast(struct timeval *tv)
19234 +void __INLINE__ do_gettimeofday_fast(struct fasttime_t *tv)
19235 {
19236 - unsigned long sec = jiffies;
19237 - unsigned long usec = GET_JIFFIES_USEC();
19238 -
19239 - usec += (sec % HZ) * (1000000 / HZ);
19240 - sec = sec / HZ;
19241 -
19242 - if (usec > 1000000)
19243 - {
19244 - usec -= 1000000;
19245 - sec++;
19246 - }
19247 - tv->tv_sec = sec;
19248 - tv->tv_usec = usec;
19249 + tv->tv_jiff = jiffies;
19250 + tv->tv_usec = GET_JIFFIES_USEC();
19251 }
19252
19253 -int __INLINE__ timeval_cmp(struct timeval *t0, struct timeval *t1)
19254 +int __INLINE__ timeval_cmp(struct fasttime_t *t0, struct fasttime_t *t1)
19255 {
19256 - if (t0->tv_sec < t1->tv_sec)
19257 - {
19258 + /* Compare jiffies. Takes care of wrapping */
19259 + if (time_before(t0->tv_jiff, t1->tv_jiff))
19260 return -1;
19261 - }
19262 - else if (t0->tv_sec > t1->tv_sec)
19263 - {
19264 + else if (time_after(t0->tv_jiff, t1->tv_jiff))
19265 return 1;
19266 - }
19267 +
19268 + /* Compare us */
19269 if (t0->tv_usec < t1->tv_usec)
19270 - {
19271 return -1;
19272 - }
19273 else if (t0->tv_usec > t1->tv_usec)
19274 - {
19275 return 1;
19276 - }
19277 return 0;
19278 }
19279
19280 @@ -254,20 +139,23 @@
19281 reg_timer_rw_intr_mask intr_mask;
19282 reg_timer_rw_trig trig;
19283 reg_timer_rw_trig_cfg trig_cfg = { 0 };
19284 - reg_timer_r_time r_time;
19285 -
19286 - r_time = REG_RD(timer, regi_timer, r_time);
19287 + reg_timer_r_time r_time0;
19288 + reg_timer_r_time r_time1;
19289 + unsigned char trig_wrap;
19290 + unsigned char time_wrap;
19291
19292 + r_time0 = REG_RD(timer, regi_timer, r_time);
19293 +
19294 D1(printk("start_timer_trig : %d us freq: %i div: %i\n",
19295 delay_us, freq_index, div));
19296 /* Clear trig irq */
19297 intr_mask = REG_RD(timer, regi_timer, rw_intr_mask);
19298 intr_mask.trig = 0;
19299 REG_WR(timer, regi_timer, rw_intr_mask, intr_mask);
19300 -
19301 - /* Set timer values */
19302 +
19303 + /* Set timer values and check if trigger wraps. */
19304 /* r_time is 100MHz (10 ns resolution) */
19305 - trig = r_time + delay_us*(1000/10);
19306 + trig_wrap = (trig = r_time0 + delay_us*(1000/10)) < r_time0;
19307
19308 timer_div_settings[fast_timers_started % NUM_TIMER_STATS] = trig;
19309 timer_delay_settings[fast_timers_started % NUM_TIMER_STATS] = delay_us;
19310 @@ -275,15 +163,17 @@
19311 /* Ack interrupt */
19312 ack_intr.trig = 1;
19313 REG_WR(timer, regi_timer, rw_ack_intr, ack_intr);
19314 -
19315 +
19316 /* Start timer */
19317 REG_WR(timer, regi_timer, rw_trig, trig);
19318 trig_cfg.tmr = regk_timer_time;
19319 REG_WR(timer, regi_timer, rw_trig_cfg, trig_cfg);
19320
19321 /* Check if we have already passed the trig time */
19322 - r_time = REG_RD(timer, regi_timer, r_time);
19323 - if (r_time < trig) {
19324 + r_time1 = REG_RD(timer, regi_timer, r_time);
19325 + time_wrap = r_time1 < r_time0;
19326 +
19327 + if ((trig_wrap && !time_wrap) || (r_time1 < trig)) {
19328 /* No, Enable trig irq */
19329 intr_mask = REG_RD(timer, regi_timer, rw_intr_mask);
19330 intr_mask.trig = 1;
19331 @@ -291,16 +181,17 @@
19332 fast_timers_started++;
19333 fast_timer_running = 1;
19334 }
19335 - else
19336 + else
19337 {
19338 /* We have passed the time, disable trig point, ack intr */
19339 trig_cfg.tmr = regk_timer_off;
19340 REG_WR(timer, regi_timer, rw_trig_cfg, trig_cfg);
19341 REG_WR(timer, regi_timer, rw_ack_intr, ack_intr);
19342 - /* call the int routine directly */
19343 - timer_trig_handler();
19344 + /* call the int routine */
19345 + INIT_WORK(&fast_work, timer_trig_handler, (void*)NULL);
19346 + schedule_work(&fast_work);
19347 }
19348 -
19349 +
19350 }
19351
19352 /* In version 1.4 this function takes 27 - 50 us */
19353 @@ -327,7 +218,7 @@
19354 {
19355 printk("timer name: %s data: 0x%08lX already in list!\n", name, data);
19356 sanity_failed++;
19357 - return;
19358 + goto done;
19359 }
19360 else
19361 {
19362 @@ -343,11 +234,11 @@
19363 t->name = name;
19364
19365 t->tv_expires.tv_usec = t->tv_set.tv_usec + delay_us % 1000000;
19366 - t->tv_expires.tv_sec = t->tv_set.tv_sec + delay_us / 1000000;
19367 + t->tv_expires.tv_jiff = t->tv_set.tv_jiff + delay_us / 1000000 / HZ;
19368 if (t->tv_expires.tv_usec > 1000000)
19369 {
19370 t->tv_expires.tv_usec -= 1000000;
19371 - t->tv_expires.tv_sec++;
19372 + t->tv_expires.tv_jiff += HZ;
19373 }
19374 #ifdef FAST_TIMER_LOG
19375 timer_added_log[fast_timers_added % NUM_TIMER_STATS] = *t;
19376 @@ -388,6 +279,7 @@
19377
19378 D2(printk("start_one_shot_timer: %d us done\n", delay_us));
19379
19380 +done:
19381 local_irq_restore(flags);
19382 } /* start_one_shot_timer */
19383
19384 @@ -431,26 +323,32 @@
19385 /* Timer interrupt handler for trig interrupts */
19386
19387 static irqreturn_t
19388 -timer_trig_interrupt(int irq, void *dev_id, struct pt_regs *regs)
19389 +timer_trig_interrupt(int irq, void *dev_id)
19390 {
19391 reg_timer_r_masked_intr masked_intr;
19392 -
19393 /* Check if the timer interrupt is for us (a trig int) */
19394 masked_intr = REG_RD(timer, regi_timer, r_masked_intr);
19395 if (!masked_intr.trig)
19396 return IRQ_NONE;
19397 - timer_trig_handler();
19398 + timer_trig_handler(NULL);
19399 return IRQ_HANDLED;
19400 }
19401
19402 -static void timer_trig_handler(void)
19403 +static void timer_trig_handler(void* dummy)
19404 {
19405 reg_timer_rw_ack_intr ack_intr = { 0 };
19406 reg_timer_rw_intr_mask intr_mask;
19407 reg_timer_rw_trig_cfg trig_cfg = { 0 };
19408 struct fast_timer *t;
19409 - unsigned long flags;
19410 + unsigned long flags;
19411
19412 + /* We keep interrupts disabled not only when we modify the
19413 + * fast timer list, but any time we hold a reference to a
19414 + * timer in the list, since del_fast_timer may be called
19415 + * from (another) interrupt context. Thus, the only time
19416 + * when interrupts are enabled is when calling the timer
19417 + * callback function.
19418 + */
19419 local_irq_save(flags);
19420
19421 /* Clear timer trig interrupt */
19422 @@ -470,16 +368,17 @@
19423 fast_timer_running = 0;
19424 fast_timer_ints++;
19425
19426 - local_irq_restore(flags);
19427 + fast_timer_function_type *f;
19428 + unsigned long d;
19429
19430 t = fast_timer_list;
19431 while (t)
19432 {
19433 - struct timeval tv;
19434 + struct fasttime_t tv;
19435
19436 /* Has it really expired? */
19437 do_gettimeofday_fast(&tv);
19438 - D1(printk("t: %is %06ius\n", tv.tv_sec, tv.tv_usec));
19439 + D1(printk("t: %is %06ius\n", tv.tv_jiff, tv.tv_usec));
19440
19441 if (timeval_cmp(&t->tv_expires, &tv) <= 0)
19442 {
19443 @@ -490,7 +389,6 @@
19444 fast_timers_expired++;
19445
19446 /* Remove this timer before call, since it may reuse the timer */
19447 - local_irq_save(flags);
19448 if (t->prev)
19449 {
19450 t->prev->next = t->next;
19451 @@ -505,11 +403,21 @@
19452 }
19453 t->prev = NULL;
19454 t->next = NULL;
19455 - local_irq_restore(flags);
19456
19457 - if (t->function != NULL)
19458 + /* Save function callback data before enabling interrupts,
19459 + * since the timer may be removed and we don't know how it
19460 + * was allocated (e.g. ->function and ->data may become
19461 + * overwritten after deletion if the timer was stack-allocated).
19462 + */
19463 + f = t->function;
19464 + d = t->data;
19465 +
19466 + if (f != NULL)
19467 {
19468 - t->function(t->data);
19469 + /* Run the callback function with interrupts enabled. */
19470 + local_irq_restore(flags);
19471 + f(d);
19472 + local_irq_save(flags);
19473 }
19474 else
19475 {
19476 @@ -522,16 +430,19 @@
19477 D1(printk(".\n"));
19478 }
19479
19480 - local_irq_save(flags);
19481 if ((t = fast_timer_list) != NULL)
19482 {
19483 /* Start next timer.. */
19484 - long us;
19485 - struct timeval tv;
19486 + long us = 0;
19487 + struct fasttime_t tv;
19488
19489 do_gettimeofday_fast(&tv);
19490 - us = ((t->tv_expires.tv_sec - tv.tv_sec) * 1000000 +
19491 - t->tv_expires.tv_usec - tv.tv_usec);
19492 +
19493 + /* time_after_eq takes care of wrapping */
19494 + if (time_after_eq(t->tv_expires.tv_jiff, tv.tv_jiff))
19495 + us = ((t->tv_expires.tv_jiff - tv.tv_jiff) * 1000000 / HZ +
19496 + t->tv_expires.tv_usec - tv.tv_usec);
19497 +
19498 if (us > 0)
19499 {
19500 if (!fast_timer_running)
19501 @@ -541,7 +452,6 @@
19502 #endif
19503 start_timer_trig(us);
19504 }
19505 - local_irq_restore(flags);
19506 break;
19507 }
19508 else
19509 @@ -552,9 +462,10 @@
19510 D1(printk("e! %d\n", us));
19511 }
19512 }
19513 - local_irq_restore(flags);
19514 }
19515
19516 + local_irq_restore(flags);
19517 +
19518 if (!t)
19519 {
19520 D1(printk("ttrig stop!\n"));
19521 @@ -577,28 +488,17 @@
19522 void schedule_usleep(unsigned long us)
19523 {
19524 struct fast_timer t;
19525 -#ifdef DECLARE_WAITQUEUE
19526 wait_queue_head_t sleep_wait;
19527 init_waitqueue_head(&sleep_wait);
19528 - {
19529 - DECLARE_WAITQUEUE(wait, current);
19530 -#else
19531 - struct wait_queue *sleep_wait = NULL;
19532 - struct wait_queue wait = { current, NULL };
19533 -#endif
19534
19535 D1(printk("schedule_usleep(%d)\n", us));
19536 - add_wait_queue(&sleep_wait, &wait);
19537 - set_current_state(TASK_INTERRUPTIBLE);
19538 start_one_shot_timer(&t, wake_up_func, (unsigned long)&sleep_wait, us,
19539 "usleep");
19540 - schedule();
19541 - set_current_state(TASK_RUNNING);
19542 - remove_wait_queue(&sleep_wait, &wait);
19543 + /* Uninterruptible sleep on the fast timer. (The condition is somewhat
19544 + redundant since the timer is what wakes us up.) */
19545 + wait_event(sleep_wait, !fast_timer_pending(&t));
19546 +
19547 D1(printk("done schedule_usleep(%d)\n", us));
19548 -#ifdef DECLARE_WAITQUEUE
19549 - }
19550 -#endif
19551 }
19552
19553 #ifdef CONFIG_PROC_FS
19554 @@ -638,7 +538,7 @@
19555 unsigned long flags;
19556 int i = 0;
19557 int num_to_show;
19558 - struct timeval tv;
19559 + struct fasttime_t tv;
19560 struct fast_timer *t, *nextt;
19561 static char *bigbuf = NULL;
19562 static unsigned long used;
19563 @@ -646,7 +546,8 @@
19564 if (!bigbuf && !(bigbuf = vmalloc(BIG_BUF_SIZE)))
19565 {
19566 used = 0;
19567 - bigbuf[0] = '\0';
19568 + if (buf)
19569 + buf[0] = '\0';
19570 return 0;
19571 }
19572
19573 @@ -668,7 +569,7 @@
19574 used += sprintf(bigbuf + used, "Fast timer running: %s\n",
19575 fast_timer_running ? "yes" : "no");
19576 used += sprintf(bigbuf + used, "Current time: %lu.%06lu\n",
19577 - (unsigned long)tv.tv_sec,
19578 + (unsigned long)tv.tv_jiff,
19579 (unsigned long)tv.tv_usec);
19580 #ifdef FAST_TIMER_SANITY_CHECKS
19581 used += sprintf(bigbuf + used, "Sanity failed: %i\n",
19582 @@ -717,9 +618,9 @@
19583 "d: %6li us data: 0x%08lX"
19584 "\n",
19585 t->name,
19586 - (unsigned long)t->tv_set.tv_sec,
19587 + (unsigned long)t->tv_set.tv_jiff,
19588 (unsigned long)t->tv_set.tv_usec,
19589 - (unsigned long)t->tv_expires.tv_sec,
19590 + (unsigned long)t->tv_expires.tv_jiff,
19591 (unsigned long)t->tv_expires.tv_usec,
19592 t->delay_us,
19593 t->data
19594 @@ -739,9 +640,9 @@
19595 "d: %6li us data: 0x%08lX"
19596 "\n",
19597 t->name,
19598 - (unsigned long)t->tv_set.tv_sec,
19599 + (unsigned long)t->tv_set.tv_jiff,
19600 (unsigned long)t->tv_set.tv_usec,
19601 - (unsigned long)t->tv_expires.tv_sec,
19602 + (unsigned long)t->tv_expires.tv_jiff,
19603 (unsigned long)t->tv_expires.tv_usec,
19604 t->delay_us,
19605 t->data
19606 @@ -759,9 +660,9 @@
19607 "d: %6li us data: 0x%08lX"
19608 "\n",
19609 t->name,
19610 - (unsigned long)t->tv_set.tv_sec,
19611 + (unsigned long)t->tv_set.tv_jiff,
19612 (unsigned long)t->tv_set.tv_usec,
19613 - (unsigned long)t->tv_expires.tv_sec,
19614 + (unsigned long)t->tv_expires.tv_jiff,
19615 (unsigned long)t->tv_expires.tv_usec,
19616 t->delay_us,
19617 t->data
19618 @@ -772,7 +673,6 @@
19619
19620 used += sprintf(bigbuf + used, "Active timers:\n");
19621 local_irq_save(flags);
19622 - local_irq_save(flags);
19623 t = fast_timer_list;
19624 while (t != NULL && (used+100 < BIG_BUF_SIZE))
19625 {
19626 @@ -783,15 +683,15 @@
19627 /* " func: 0x%08lX" */
19628 "\n",
19629 t->name,
19630 - (unsigned long)t->tv_set.tv_sec,
19631 + (unsigned long)t->tv_set.tv_jiff,
19632 (unsigned long)t->tv_set.tv_usec,
19633 - (unsigned long)t->tv_expires.tv_sec,
19634 + (unsigned long)t->tv_expires.tv_jiff,
19635 (unsigned long)t->tv_expires.tv_usec,
19636 t->delay_us,
19637 t->data
19638 /* , t->function */
19639 );
19640 - local_irq_disable();
19641 + local_irq_save(flags);
19642 if (t->next != nextt)
19643 {
19644 printk("timer removed!\n");
19645 @@ -822,7 +722,7 @@
19646 static struct fast_timer tr[10];
19647 static int exp_num[10];
19648
19649 -static struct timeval tv_exp[100];
19650 +static struct fasttime_t tv_exp[100];
19651
19652 static void test_timeout(unsigned long data)
19653 {
19654 @@ -860,7 +760,7 @@
19655 int prev_num;
19656 int j;
19657
19658 - struct timeval tv, tv0, tv1, tv2;
19659 + struct fasttime_t tv, tv0, tv1, tv2;
19660
19661 printk("fast_timer_test() start\n");
19662 do_gettimeofday_fast(&tv);
19663 @@ -873,7 +773,7 @@
19664 {
19665 do_gettimeofday_fast(&tv_exp[j]);
19666 }
19667 - printk("fast_timer_test() %is %06i\n", tv.tv_sec, tv.tv_usec);
19668 + printk("fast_timer_test() %is %06i\n", tv.tv_jiff, tv.tv_usec);
19669
19670 for (j = 0; j < 1000; j++)
19671 {
19672 @@ -883,11 +783,11 @@
19673 for (j = 0; j < 100; j++)
19674 {
19675 printk("%i.%i %i.%i %i.%i %i.%i %i.%i\n",
19676 - tv_exp[j].tv_sec,tv_exp[j].tv_usec,
19677 - tv_exp[j+1].tv_sec,tv_exp[j+1].tv_usec,
19678 - tv_exp[j+2].tv_sec,tv_exp[j+2].tv_usec,
19679 - tv_exp[j+3].tv_sec,tv_exp[j+3].tv_usec,
19680 - tv_exp[j+4].tv_sec,tv_exp[j+4].tv_usec);
19681 + tv_exp[j].tv_jiff,tv_exp[j].tv_usec,
19682 + tv_exp[j+1].tv_jiff,tv_exp[j+1].tv_usec,
19683 + tv_exp[j+2].tv_jiff,tv_exp[j+2].tv_usec,
19684 + tv_exp[j+3].tv_jiff,tv_exp[j+3].tv_usec,
19685 + tv_exp[j+4].tv_jiff,tv_exp[j+4].tv_usec);
19686 j += 4;
19687 }
19688 do_gettimeofday_fast(&tv0);
19689 @@ -919,9 +819,9 @@
19690 }
19691 }
19692 do_gettimeofday_fast(&tv2);
19693 - printk("Timers started %is %06i\n", tv0.tv_sec, tv0.tv_usec);
19694 - printk("Timers started at %is %06i\n", tv1.tv_sec, tv1.tv_usec);
19695 - printk("Timers done %is %06i\n", tv2.tv_sec, tv2.tv_usec);
19696 + printk("Timers started %is %06i\n", tv0.tv_jiff, tv0.tv_usec);
19697 + printk("Timers started at %is %06i\n", tv1.tv_jiff, tv1.tv_usec);
19698 + printk("Timers done %is %06i\n", tv2.tv_jiff, tv2.tv_usec);
19699 DP(printk("buf0:\n");
19700 printk(buf0);
19701 printk("buf1:\n");
19702 @@ -943,9 +843,9 @@
19703 printk("%-10s set: %6is %06ius exp: %6is %06ius "
19704 "data: 0x%08X func: 0x%08X\n",
19705 t->name,
19706 - t->tv_set.tv_sec,
19707 + t->tv_set.tv_jiff,
19708 t->tv_set.tv_usec,
19709 - t->tv_expires.tv_sec,
19710 + t->tv_expires.tv_jiff,
19711 t->tv_expires.tv_usec,
19712 t->data,
19713 t->function
19714 @@ -953,10 +853,10 @@
19715
19716 printk(" del: %6ius did exp: %6is %06ius as #%i error: %6li\n",
19717 t->delay_us,
19718 - tv_exp[j].tv_sec,
19719 + tv_exp[j].tv_jiff,
19720 tv_exp[j].tv_usec,
19721 exp_num[j],
19722 - (tv_exp[j].tv_sec - t->tv_expires.tv_sec)*1000000 + tv_exp[j].tv_usec - t->tv_expires.tv_usec);
19723 + (tv_exp[j].tv_jiff - t->tv_expires.tv_jiff)*1000000 + tv_exp[j].tv_usec - t->tv_expires.tv_usec);
19724 }
19725 proc_fasttimer_read(buf5, NULL, 0, 0, 0);
19726 printk("buf5 after all done:\n");
19727 @@ -966,7 +866,7 @@
19728 #endif
19729
19730
19731 -void fast_timer_init(void)
19732 +int fast_timer_init(void)
19733 {
19734 /* For some reason, request_irq() hangs when called froom time_init() */
19735 if (!fast_timer_is_init)
19736 @@ -981,10 +881,10 @@
19737 proc_register_dynamic(&proc_root, &fasttimer_proc_entry);
19738 #endif
19739 #endif /* PROC_FS */
19740 - if(request_irq(TIMER_INTR_VECT, timer_trig_interrupt, IRQF_DISABLED,
19741 - "fast timer int", NULL))
19742 + if(request_irq(TIMER_INTR_VECT, timer_trig_interrupt, SA_SHIRQ | SA_INTERRUPT,
19743 + "fast timer int", &fast_timer_list))
19744 {
19745 - printk("err: timer1 irq\n");
19746 + printk("err: fasttimer irq\n");
19747 }
19748 fast_timer_is_init = 1;
19749 #ifdef FAST_TIMER_TEST
19750 @@ -992,4 +892,6 @@
19751 fast_timer_test();
19752 #endif
19753 }
19754 + return 0;
19755 }
19756 +__initcall(fast_timer_init);
19757 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/kernel/head.S linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/head.S
19758 --- linux-2.6.19.2.old/arch/cris/arch-v32/kernel/head.S 2007-01-10 20:10:37.000000000 +0100
19759 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/head.S 2007-01-09 10:29:19.000000000 +0100
19760 @@ -4,7 +4,6 @@
19761 * Copyright (C) 2003, Axis Communications AB
19762 */
19763
19764 -
19765 #define ASSEMBLER_MACROS_ONLY
19766
19767 /*
19768 @@ -12,14 +11,21 @@
19769 * -traditional must not be used when assembling this file.
19770 */
19771 #include <asm/arch/hwregs/reg_rdwr.h>
19772 +#include <asm/arch/memmap.h>
19773 +#include <asm/arch/hwregs/intr_vect.h>
19774 #include <asm/arch/hwregs/asm/mmu_defs_asm.h>
19775 #include <asm/arch/hwregs/asm/reg_map_asm.h>
19776 #include <asm/arch/hwregs/asm/config_defs_asm.h>
19777 #include <asm/arch/hwregs/asm/bif_core_defs_asm.h>
19778 -
19779 +#include <asm/arch/hwregs/asm/pinmux_defs_asm.h>
19780 +#include <asm/arch/hwregs/asm/gio_defs_asm.h>
19781 +
19782 #define CRAMFS_MAGIC 0x28cd3d45
19783 +#define JHEAD_MAGIC 0x1FF528A6
19784 +#define JHEAD_SIZE 8
19785 #define RAM_INIT_MAGIC 0x56902387
19786 -#define COMMAND_LINE_MAGIC 0x87109563
19787 +#define COMMAND_LINE_MAGIC 0x87109563
19788 +#define NAND_BOOT_MAGIC 0x9a9db001
19789
19790 ;; NOTE: R8 and R9 carry information from the decompressor (if the
19791 ;; kernel was compressed). They must not be used in the code below
19792 @@ -30,11 +36,10 @@
19793 .global romfs_start
19794 .global romfs_length
19795 .global romfs_in_flash
19796 + .global nand_boot
19797 .global swapper_pg_dir
19798 - .global crisv32_nand_boot
19799 - .global crisv32_nand_cramfs_offset
19800
19801 - ;; Dummy section to make it bootable with current VCS simulator
19802 + ;; Dummy section to make it bootable with current VCS simulator
19803 #ifdef CONFIG_ETRAXFS_SIM
19804 .section ".boot", "ax"
19805 ba tstart
19806 @@ -42,13 +47,13 @@
19807 #endif
19808
19809 .text
19810 -tstart:
19811 +tstart:
19812 ;; This is the entry point of the kernel. The CPU is currently in
19813 ;; supervisor mode.
19814 - ;;
19815 + ;;
19816 ;; 0x00000000 if flash.
19817 ;; 0x40004000 if DRAM.
19818 - ;;
19819 + ;;
19820 di
19821
19822 ;; Start clocks for used blocks.
19823 @@ -72,20 +77,25 @@
19824 move.d REG_ADDR(bif_core, regi_bif_core, rw_grp4_cfg), $r0
19825 move.d CONFIG_ETRAX_MEM_GRP4_CONFIG, $r1
19826 move.d $r1, [$r0]
19827 -
19828 -#ifdef CONFIG_ETRAXFS_SIM
19829 +
19830 +#ifdef CONFIG_ETRAXFS_SIM
19831 ;; Set up minimal flash waitstates
19832 move.d 0, $r10
19833 move.d REG_ADDR(bif_core, regi_bif_core, rw_grp1_cfg), $r11
19834 move.d $r10, [$r11]
19835 -#endif
19836 +#endif
19837
19838 +#ifdef CONFIG_SMP
19839 +secondary_cpu_entry: /* Entry point for secondary CPUs */
19840 + di
19841 +#endif
19842 +
19843 ;; Setup and enable the MMU. Use same configuration for both the data
19844 ;; and the instruction MMU.
19845 ;;
19846 ;; Note; 3 cycles is needed for a bank-select to take effect. Further;
19847 ;; bank 1 is the instruction MMU, bank 2 is the data MMU.
19848 -#ifndef CONFIG_ETRAXFS_SIM
19849 +#ifndef CONFIG_ETRAXFS_SIM
19850 move.d REG_FIELD(mmu, rw_mm_kbase_hi, base_e, 8) \
19851 | REG_FIELD(mmu, rw_mm_kbase_hi, base_c, 4) \
19852 | REG_FIELD(mmu, rw_mm_kbase_hi, base_b, 0xb), $r0
19853 @@ -96,7 +106,7 @@
19854 | REG_FIELD(mmu, rw_mm_kbase_hi, base_c, 0) \
19855 | REG_FIELD(mmu, rw_mm_kbase_hi, base_b, 0xb) \
19856 | REG_FIELD(mmu, rw_mm_kbase_hi, base_a, 0xa), $r0
19857 -#endif
19858 +#endif
19859
19860 ;; Temporary map of 0x40 -> 0x40 and 0x00 -> 0x00.
19861 move.d REG_FIELD(mmu, rw_mm_kbase_lo, base_4, 4) \
19862 @@ -146,8 +156,8 @@
19863 | REG_STATE(mmu, rw_mm_cfg, seg_2, page) \
19864 | REG_STATE(mmu, rw_mm_cfg, seg_1, page) \
19865 | REG_STATE(mmu, rw_mm_cfg, seg_0, linear), $r2
19866 -#endif
19867 -
19868 +#endif
19869 +
19870 ;; Update instruction MMU.
19871 move 1, $srs
19872 nop
19873 @@ -165,7 +175,7 @@
19874 move $r0, $s2 ; kbase_hi.
19875 move $r1, $s1 ; kbase_lo
19876 move $r2, $s0 ; mm_cfg, virtual memory configuration.
19877 -
19878 +
19879 ;; Enable data and instruction MMU.
19880 move 0, $srs
19881 moveq 0xf, $r0 ; IMMU, DMMU, DCache, Icache on
19882 @@ -183,17 +193,11 @@
19883 nop
19884 nop
19885 nop
19886 - move $s10, $r0
19887 + move $s12, $r0
19888 cmpq 0, $r0
19889 beq master_cpu
19890 nop
19891 slave_cpu:
19892 - ; A slave waits for cpu_now_booting to be equal to CPU ID.
19893 - move.d cpu_now_booting, $r1
19894 -slave_wait:
19895 - cmp.d [$r1], $r0
19896 - bne slave_wait
19897 - nop
19898 ; Time to boot-up. Get stack location provided by master CPU.
19899 move.d smp_init_current_idle_thread, $r1
19900 move.d [$r1], $sp
19901 @@ -203,9 +207,16 @@
19902 jsr smp_callin
19903 nop
19904 master_cpu:
19905 -#endif
19906 + /* Set up entry point for secondary CPUs. The boot ROM has set up
19907 + * EBP at start of internal memory. The CPU will get there
19908 + * later when we issue an IPI to them... */
19909 + move.d MEM_INTMEM_START + IPI_INTR_VECT * 4, $r0
19910 + move.d secondary_cpu_entry, $r1
19911 + move.d $r1, [$r0]
19912 +#endif
19913 #ifndef CONFIG_ETRAXFS_SIM
19914 - ;; Check if starting from DRAM or flash.
19915 + ; Check if starting from DRAM (network->RAM boot or unpacked
19916 + ; compressed kernel), or directly from flash.
19917 lapcq ., $r0
19918 and.d 0x7fffffff, $r0 ; Mask off the non-cache bit.
19919 cmp.d 0x10000, $r0 ; Arbitrary, something above this code.
19920 @@ -238,6 +249,7 @@
19921 ;; Copy the text and data section to DRAM. This depends on that the
19922 ;; variables used below are correctly set up by the linker script.
19923 ;; The calculated value stored in R4 is used below.
19924 + ;; Leave the cramfs file system (piggybacked after the kernel) in flash.
19925 moveq 0, $r0 ; Source.
19926 move.d text_start, $r1 ; Destination.
19927 move.d __vmlinux_end, $r2
19928 @@ -249,7 +261,7 @@
19929 blo 1b
19930 nop
19931
19932 - ;; Keep CRAMFS in flash.
19933 + ;; Check for cramfs.
19934 moveq 0, $r0
19935 move.d romfs_length, $r1
19936 move.d $r0, [$r1]
19937 @@ -257,7 +269,8 @@
19938 cmp.d CRAMFS_MAGIC, $r0
19939 bne 1f
19940 nop
19941 -
19942 +
19943 + ;; Set length and start of cramfs, set romfs_in_flash flag
19944 addoq +4, $r4, $acr
19945 move.d [$acr], $r0
19946 move.d romfs_length, $r1
19947 @@ -273,35 +286,32 @@
19948 nop
19949
19950 _inram:
19951 - ;; Check if booting from NAND flash (in that case we just remember the offset
19952 - ;; into the flash where cramfs should be).
19953 - move.d REG_ADDR(config, regi_config, r_bootsel), $r0
19954 - move.d [$r0], $r0
19955 - and.d REG_MASK(config, r_bootsel, boot_mode), $r0
19956 - cmp.d REG_STATE(config, r_bootsel, boot_mode, nand), $r0
19957 - bne move_cramfs
19958 - moveq 1,$r0
19959 - move.d crisv32_nand_boot, $r1
19960 - move.d $r0, [$r1]
19961 - move.d crisv32_nand_cramfs_offset, $r1
19962 - move.d $r9, [$r1]
19963 + ;; Check if booting from NAND flash; if so, set appropriate flags
19964 + ;; and move on.
19965 + cmp.d NAND_BOOT_MAGIC, $r12
19966 + bne move_cramfs ; not nand, jump
19967 moveq 1, $r0
19968 - move.d romfs_in_flash, $r1
19969 + move.d nand_boot, $r1 ; tell axisflashmap we're booting from NAND
19970 + move.d $r0, [$r1]
19971 + moveq 0, $r0 ; tell axisflashmap romfs is not in
19972 + move.d romfs_in_flash, $r1 ; (directly accessed) flash
19973 move.d $r0, [$r1]
19974 - jump _start_it
19975 + jump _start_it ; continue with boot
19976 nop
19977
19978 -move_cramfs:
19979 - ;; Move the cramfs after BSS.
19980 +move_cramfs:
19981 + ;; kernel is in DRAM.
19982 + ;; Must figure out if there is a piggybacked rootfs image or not.
19983 + ;; Set romfs_length to 0 => no rootfs image available by default.
19984 moveq 0, $r0
19985 move.d romfs_length, $r1
19986 move.d $r0, [$r1]
19987
19988 -#ifndef CONFIG_ETRAXFS_SIM
19989 +#ifndef CONFIG_ETRAXFS_SIM
19990 ;; The kernel could have been unpacked to DRAM by the loader, but
19991 - ;; the cramfs image could still be inte the flash immediately
19992 - ;; following the compressed kernel image. The loaded passes the address
19993 - ;; of the bute succeeding the last compressed byte in the flash in
19994 + ;; the cramfs image could still be in the flash immediately
19995 + ;; following the compressed kernel image. The loader passes the address
19996 + ;; of the byte succeeding the last compressed byte in the flash in
19997 ;; register R9 when starting the kernel.
19998 cmp.d 0x0ffffff8, $r9
19999 bhs _no_romfs_in_flash ; R9 points outside the flash area.
20000 @@ -309,12 +319,14 @@
20001 #else
20002 ba _no_romfs_in_flash
20003 nop
20004 -#endif
20005 +#endif
20006 + ;; cramfs rootfs might to be in flash. Check for it.
20007 move.d [$r9], $r0 ; cramfs_super.magic
20008 cmp.d CRAMFS_MAGIC, $r0
20009 bne _no_romfs_in_flash
20010 nop
20011
20012 + ;; found cramfs in flash. set address and size, and romfs_in_flash flag.
20013 addoq +4, $r9, $acr
20014 move.d [$acr], $r0
20015 move.d romfs_length, $r1
20016 @@ -330,29 +342,45 @@
20017 nop
20018
20019 _no_romfs_in_flash:
20020 - ;; Look for cramfs.
20021 -#ifndef CONFIG_ETRAXFS_SIM
20022 + ;; No romfs in flash, so look for cramfs, or jffs2 with jhead,
20023 + ;; after kernel in RAM, as is the case with network->RAM boot.
20024 + ;; For cramfs, partition starts with magic and length.
20025 + ;; For jffs2, a jhead is prepended which contains with magic and length.
20026 + ;; The jhead is not part of the jffs2 partition however.
20027 +#ifndef CONFIG_ETRAXFS_SIM
20028 move.d __vmlinux_end, $r0
20029 #else
20030 - move.d __end, $r0
20031 -#endif
20032 + move.d __end, $r0
20033 +#endif
20034 move.d [$r0], $r1
20035 - cmp.d CRAMFS_MAGIC, $r1
20036 - bne 2f
20037 + cmp.d CRAMFS_MAGIC, $r1 ; cramfs magic?
20038 + beq 2f ; yes, jump
20039 + nop
20040 + cmp.d JHEAD_MAGIC, $r1 ; jffs2 (jhead) magic?
20041 + bne 4f ; no, skip copy
20042 + nop
20043 + addq 4, $r0 ; location of jffs2 size
20044 + move.d [$r0+], $r2 ; fetch jffs2 size -> r2
20045 + ; r0 now points to start of jffs2
20046 + ba 3f
20047 nop
20048 +2:
20049 + addoq +4, $r0, $acr ; location of cramfs size
20050 + move.d [$acr], $r2 ; fetch cramfs size -> r2
20051 + ; r0 still points to start of cramfs
20052 +3:
20053 + ;; Now, move the root fs to after kernel's BSS
20054
20055 - addoq +4, $r0, $acr
20056 - move.d [$acr], $r2
20057 - move.d _end, $r1
20058 + move.d _end, $r1 ; start of cramfs -> r1
20059 move.d romfs_start, $r3
20060 - move.d $r1, [$r3]
20061 + move.d $r1, [$r3] ; store at romfs_start (for axisflashmap)
20062 move.d romfs_length, $r3
20063 - move.d $r2, [$r3]
20064 + move.d $r2, [$r3] ; store size at romfs_length
20065
20066 -#ifndef CONFIG_ETRAXFS_SIM
20067 - add.d $r2, $r0
20068 +#ifndef CONFIG_ETRAXFS_SIM
20069 + add.d $r2, $r0 ; copy from end and downwards
20070 add.d $r2, $r1
20071 -
20072 +
20073 lsrq 1, $r2 ; Size is in bytes, we copy words.
20074 addq 1, $r2
20075 1:
20076 @@ -364,17 +392,24 @@
20077 bne 1b
20078 nop
20079 #endif
20080 -
20081 -2:
20082 +
20083 +4:
20084 + ;; BSS move done.
20085 + ;; Clear romfs_in_flash flag, as we now know romfs is in DRAM
20086 + ;; Also clear nand_boot flag; if we got here, we know we've not
20087 + ;; booted from NAND flash.
20088 moveq 0, $r0
20089 move.d romfs_in_flash, $r1
20090 move.d $r0, [$r1]
20091 + moveq 0, $r0
20092 + move.d nand_boot, $r1
20093 + move.d $r0, [$r1]
20094
20095 jump _start_it ; Jump to cached code.
20096 nop
20097 -
20098 +
20099 _start_it:
20100 -
20101 +
20102 ;; Check if kernel command line is supplied
20103 cmp.d COMMAND_LINE_MAGIC, $r10
20104 bne no_command_line
20105 @@ -383,9 +418,9 @@
20106 move.d 256, $r13
20107 move.d cris_command_line, $r10
20108 or.d 0x80000000, $r11 ; Make it virtual
20109 -1:
20110 - move.b [$r11+], $r12
20111 - move.b $r12, [$r10+]
20112 +1:
20113 + move.b [$r11+], $r1
20114 + move.b $r1, [$r10+]
20115 subq 1, $r13
20116 bne 1b
20117 nop
20118 @@ -401,7 +436,7 @@
20119 move.d etrax_irv, $r1 ; Set the exception base register and pointer.
20120 move.d $r0, [$r1]
20121
20122 -#ifndef CONFIG_ETRAXFS_SIM
20123 +#ifndef CONFIG_ETRAXFS_SIM
20124 ;; Clear the BSS region from _bss_start to _end.
20125 move.d __bss_start, $r0
20126 move.d _end, $r1
20127 @@ -429,17 +464,31 @@
20128 .data
20129 etrax_irv:
20130 .dword 0
20131 +
20132 +; Variables for communication with the Axis flash map driver (axisflashmap),
20133 +; and for setting up memory in arch/cris/kernel/setup.c .
20134 +
20135 +; romfs_start is set to the start of the root file system, if it exists
20136 +; in directly accessible memory (i.e. NOR Flash when booting from Flash,
20137 +; or RAM when booting directly from a network-downloaded RAM image)
20138 romfs_start:
20139 .dword 0
20140 +
20141 +; romfs_length is set to the size of the root file system image, if it exists
20142 +; in directly accessible memory (see romfs_start). Otherwise it is set to 0.
20143 romfs_length:
20144 .dword 0
20145 +
20146 +; romfs_in_flash is set to 1 if the root file system resides in directly
20147 +; accessible flash memory (i.e. NOR flash). It is set to 0 for RAM boot
20148 +; or NAND flash boot.
20149 romfs_in_flash:
20150 .dword 0
20151 -crisv32_nand_boot:
20152 - .dword 0
20153 -crisv32_nand_cramfs_offset:
20154 - .dword 0
20155
20156 +; nand_boot is set to 1 when the kernel has been booted from NAND flash
20157 +nand_boot:
20158 + .dword 0
20159 +
20160 swapper_pg_dir = 0xc0002000
20161
20162 .section ".init.data", "aw"
20163 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/kernel/io.c linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/io.c
20164 --- linux-2.6.19.2.old/arch/cris/arch-v32/kernel/io.c 2007-01-10 20:10:37.000000000 +0100
20165 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/io.c 2006-11-21 00:04:55.000000000 +0100
20166 @@ -1,7 +1,7 @@
20167 -/*
20168 +/*
20169 * Helper functions for I/O pins.
20170 *
20171 - * Copyright (c) 2004 Axis Communications AB.
20172 + * Copyright (c) 2004, 2006 Axis Communications AB.
20173 */
20174
20175 #include <linux/types.h>
20176 @@ -15,6 +15,10 @@
20177 #include <asm/arch/pinmux.h>
20178 #include <asm/arch/hwregs/gio_defs.h>
20179
20180 +#ifndef DEBUG
20181 +#define DEBUG(x)
20182 +#endif
20183 +
20184 struct crisv32_ioport crisv32_ioports[] =
20185 {
20186 {
20187 @@ -46,13 +50,15 @@
20188 (unsigned long*)REG_ADDR(gio, regi_gio, rw_pe_dout),
20189 (unsigned long*)REG_ADDR(gio, regi_gio, r_pe_din),
20190 18
20191 - }
20192 + }
20193 };
20194
20195 #define NBR_OF_PORTS sizeof(crisv32_ioports)/sizeof(struct crisv32_ioport)
20196
20197 -struct crisv32_iopin crisv32_led1_green;
20198 -struct crisv32_iopin crisv32_led1_red;
20199 +struct crisv32_iopin crisv32_led_net0_green;
20200 +struct crisv32_iopin crisv32_led_net0_red;
20201 +struct crisv32_iopin crisv32_led_net1_green;
20202 +struct crisv32_iopin crisv32_led_net1_red;
20203 struct crisv32_iopin crisv32_led2_green;
20204 struct crisv32_iopin crisv32_led2_red;
20205 struct crisv32_iopin crisv32_led3_green;
20206 @@ -76,34 +82,54 @@
20207 static int __init crisv32_io_init(void)
20208 {
20209 int ret = 0;
20210 +
20211 + u32 i;
20212 +
20213 + /* Locks *should* be dynamically initialized. */
20214 + for (i = 0; i < ARRAY_SIZE(crisv32_ioports); i++)
20215 + spin_lock_init (&crisv32_ioports[i].lock);
20216 + spin_lock_init (&dummy_port.lock);
20217 +
20218 /* Initialize LEDs */
20219 - ret += crisv32_io_get_name(&crisv32_led1_green, CONFIG_ETRAX_LED1G);
20220 - ret += crisv32_io_get_name(&crisv32_led1_red, CONFIG_ETRAX_LED1R);
20221 +#if (defined(CONFIG_ETRAX_NBR_LED_GRP_ONE) || defined(CONFIG_ETRAX_NBR_LED_GRP_TWO))
20222 + ret += crisv32_io_get_name(&crisv32_led_net0_green, CONFIG_ETRAX_LED_G_NET0);
20223 + crisv32_io_set_dir(&crisv32_led_net0_green, crisv32_io_dir_out);
20224 + if (strcmp(CONFIG_ETRAX_LED_G_NET0, CONFIG_ETRAX_LED_R_NET0)) {
20225 + ret += crisv32_io_get_name(&crisv32_led_net0_red, CONFIG_ETRAX_LED_R_NET0);
20226 + crisv32_io_set_dir(&crisv32_led_net0_red, crisv32_io_dir_out);
20227 + } else
20228 + crisv32_led_net0_red = dummy_led;
20229 +#endif
20230 +
20231 +#ifdef CONFIG_ETRAX_NBR_LED_GRP_TWO
20232 + ret += crisv32_io_get_name(&crisv32_led_net1_green, CONFIG_ETRAX_LED_G_NET1);
20233 + crisv32_io_set_dir(&crisv32_led_net1_green, crisv32_io_dir_out);
20234 + if (strcmp(CONFIG_ETRAX_LED_G_NET1, CONFIG_ETRAX_LED_R_NET1)) {
20235 + crisv32_io_get_name(&crisv32_led_net1_red, CONFIG_ETRAX_LED_R_NET1);
20236 + crisv32_io_set_dir(&crisv32_led_net1_red, crisv32_io_dir_out);
20237 + } else
20238 + crisv32_led_net1_red = dummy_led;
20239 +#endif
20240 +
20241 ret += crisv32_io_get_name(&crisv32_led2_green, CONFIG_ETRAX_LED2G);
20242 ret += crisv32_io_get_name(&crisv32_led2_red, CONFIG_ETRAX_LED2R);
20243 ret += crisv32_io_get_name(&crisv32_led3_green, CONFIG_ETRAX_LED3G);
20244 ret += crisv32_io_get_name(&crisv32_led3_red, CONFIG_ETRAX_LED3R);
20245 - crisv32_io_set_dir(&crisv32_led1_green, crisv32_io_dir_out);
20246 - crisv32_io_set_dir(&crisv32_led1_red, crisv32_io_dir_out);
20247 +
20248 crisv32_io_set_dir(&crisv32_led2_green, crisv32_io_dir_out);
20249 crisv32_io_set_dir(&crisv32_led2_red, crisv32_io_dir_out);
20250 crisv32_io_set_dir(&crisv32_led3_green, crisv32_io_dir_out);
20251 crisv32_io_set_dir(&crisv32_led3_red, crisv32_io_dir_out);
20252
20253 - if (!strcmp(CONFIG_ETRAX_LED1G, CONFIG_ETRAX_LED1R))
20254 - crisv32_led1_red = dummy_led;
20255 - if (!strcmp(CONFIG_ETRAX_LED2G, CONFIG_ETRAX_LED2R))
20256 - crisv32_led2_red = dummy_led;
20257 -
20258 return ret;
20259 }
20260
20261 __initcall(crisv32_io_init);
20262
20263 -int crisv32_io_get(struct crisv32_iopin* iopin,
20264 +int crisv32_io_get(struct crisv32_iopin* iopin,
20265 unsigned int port, unsigned int pin)
20266 {
20267 - if (port > NBR_OF_PORTS)
20268 + if (port > NBR_OF_PORTS)
20269 return -EINVAL;
20270 if (port > crisv32_ioports[port].pin_count)
20271 return -EINVAL;
20272 @@ -111,14 +137,17 @@
20273 iopin->bit = 1 << pin;
20274 iopin->port = &crisv32_ioports[port];
20275
20276 - if (crisv32_pinmux_alloc(port, pin, pin, pinmux_gpio))
20277 + /* Only allocate pinmux gpiopins if port != PORT_A (port 0) */
20278 + /* NOTE! crisv32_pinmux_alloc thinks PORT_B is port 0 */
20279 + if (port != 0 && crisv32_pinmux_alloc(port-1, pin, pin, pinmux_gpio))
20280 return -EIO;
20281 -
20282 + DEBUG(printk("crisv32_io_get: Allocated pin %d on port %d\n", pin, port ));
20283 +
20284 return 0;
20285 }
20286
20287 int crisv32_io_get_name(struct crisv32_iopin* iopin,
20288 - char* name)
20289 + const char* name)
20290 {
20291 int port;
20292 int pin;
20293 @@ -128,7 +157,7 @@
20294
20295 if (toupper(*name) < 'A' || toupper(*name) > 'E')
20296 return -EINVAL;
20297 -
20298 +
20299 port = toupper(*name) - 'A';
20300 name++;
20301 pin = simple_strtoul(name, NULL, 10);
20302 @@ -139,9 +168,12 @@
20303 iopin->bit = 1 << pin;
20304 iopin->port = &crisv32_ioports[port];
20305
20306 - if (crisv32_pinmux_alloc(port, pin, pin, pinmux_gpio))
20307 + /* Only allocate pinmux gpiopins if port != PORT_A (port 0) */
20308 + /* NOTE! crisv32_pinmux_alloc thinks PORT_B is port 0 */
20309 + if (port != 0 && crisv32_pinmux_alloc(port-1, pin, pin, pinmux_gpio))
20310 return -EIO;
20311
20312 + DEBUG(printk("crisv32_io_get_name: Allocated pin %d on port %d\n", pin, port));
20313 return 0;
20314 }
20315
20316 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/kernel/irq.c linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/irq.c
20317 --- linux-2.6.19.2.old/arch/cris/arch-v32/kernel/irq.c 2007-01-10 20:10:37.000000000 +0100
20318 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/irq.c 2006-10-13 14:43:13.000000000 +0200
20319 @@ -44,10 +44,10 @@
20320 cpumask_t mask; /* The CPUs to which the IRQ may be allocated. */
20321 };
20322
20323 -struct cris_irq_allocation irq_allocations[NR_IRQS] =
20324 +struct cris_irq_allocation irq_allocations[NR_IRQS] =
20325 {[0 ... NR_IRQS - 1] = {0, CPU_MASK_ALL}};
20326
20327 -static unsigned long irq_regs[NR_CPUS] =
20328 +static unsigned long irq_regs[NR_CPUS] =
20329 {
20330 regi_irq,
20331 #ifdef CONFIG_SMP
20332 @@ -79,9 +79,9 @@
20333 extern void kgdb_init(void);
20334 extern void breakpoint(void);
20335
20336 -/*
20337 - * Build the IRQ handler stubs using macros from irq.h. First argument is the
20338 - * IRQ number, the second argument is the corresponding bit in
20339 +/*
20340 + * Build the IRQ handler stubs using macros from irq.h. First argument is the
20341 + * IRQ number, the second argument is the corresponding bit in
20342 * intr_rw_vect_mask found in asm/arch/hwregs/intr_vect_defs.h.
20343 */
20344 BUILD_IRQ(0x31, (1 << 0)) /* memarb */
20345 @@ -139,7 +139,7 @@
20346
20347 spin_lock_irqsave(&irq_lock, flags);
20348 intr_mask = REG_RD_INT(intr_vect, irq_regs[cpu], rw_mask);
20349 -
20350 +
20351 /* Remember; 1 let thru, 0 block. */
20352 intr_mask &= ~(1 << (irq - FIRST_IRQ));
20353
20354 @@ -152,10 +152,10 @@
20355 {
20356 int intr_mask;
20357 unsigned long flags;
20358 -
20359 +
20360 spin_lock_irqsave(&irq_lock, flags);
20361 intr_mask = REG_RD_INT(intr_vect, irq_regs[cpu], rw_mask);
20362 -
20363 +
20364 /* Remember; 1 let thru, 0 block. */
20365 intr_mask |= (1 << (irq - FIRST_IRQ));
20366
20367 @@ -168,7 +168,7 @@
20368 {
20369 int cpu;
20370 unsigned long flags;
20371 -
20372 +
20373 spin_lock_irqsave(&irq_lock, flags);
20374 cpu = irq_allocations[irq - FIRST_IRQ].cpu;
20375
20376 @@ -178,12 +178,12 @@
20377 spin_unlock_irqrestore(&irq_lock, flags);
20378 return smp_processor_id();
20379 }
20380 -
20381 +
20382
20383 /* Let the interrupt stay if possible */
20384 if (cpu_isset(cpu, irq_allocations[irq - FIRST_IRQ].mask))
20385 goto out;
20386 -
20387 +
20388 /* IRQ must be moved to another CPU. */
20389 cpu = first_cpu(irq_allocations[irq - FIRST_IRQ].mask);
20390 irq_allocations[irq - FIRST_IRQ].cpu = cpu;
20391 @@ -287,7 +287,7 @@
20392 * interrupt from the CPU and software has to sort out which
20393 * interrupts that happened. There are two special cases here:
20394 *
20395 - * 1. Timer interrupts may never be blocked because of the
20396 + * 1. Timer interrupts may never be blocked because of the
20397 * watchdog (refer to comment in include/asr/arch/irq.h)
20398 * 2. GDB serial port IRQs are unhandled here and will be handled
20399 * as a single IRQ when it strikes again because the GDB
20400 @@ -304,33 +304,33 @@
20401 cpu = smp_processor_id();
20402
20403 /* An extra irq_enter here to prevent softIRQs to run after
20404 - * each do_IRQ. This will decrease the interrupt latency.
20405 + * each do_IRQ. This will decrease the interrupt latency.
20406 */
20407 irq_enter();
20408
20409 /* Get which IRQs that happend. */
20410 masked = REG_RD_INT(intr_vect, irq_regs[cpu], r_masked_vect);
20411 -
20412 +
20413 /* Calculate new IRQ mask with these IRQs disabled. */
20414 mask = REG_RD_INT(intr_vect, irq_regs[cpu], rw_mask);
20415 mask &= ~masked;
20416
20417 /* Timer IRQ is never masked */
20418 if (masked & TIMER_MASK)
20419 - mask |= TIMER_MASK;
20420 + mask |= TIMER_MASK;
20421
20422 /* Block all the IRQs */
20423 REG_WR_INT(intr_vect, irq_regs[cpu], rw_mask, mask);
20424 -
20425 +
20426 /* Check for timer IRQ and handle it special. */
20427 if (masked & TIMER_MASK) {
20428 masked &= ~TIMER_MASK;
20429 - do_IRQ(TIMER_INTR_VECT, regs);
20430 + do_IRQ(TIMER_INTR_VECT, regs);
20431 }
20432
20433 #ifdef IGNORE_MASK
20434 /* Remove IRQs that can't be handled as multiple. */
20435 - masked &= ~IGNORE_MASK;
20436 + masked &= ~IGNORE_MASK;
20437 #endif
20438
20439 /* Handle the rest of the IRQs. */
20440 @@ -377,7 +377,7 @@
20441 irq_desc[TIMER_INTR_VECT].status |= IRQ_PER_CPU;
20442 irq_allocations[IPI_INTR_VECT - FIRST_IRQ].cpu = CPU_FIXED;
20443 irq_desc[IPI_INTR_VECT].status |= IRQ_PER_CPU;
20444 -
20445 +
20446 set_exception_vector(0x00, nmi_interrupt);
20447 set_exception_vector(0x30, multiple_interrupt);
20448
20449 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/kernel/kgdb.c linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/kgdb.c
20450 --- linux-2.6.19.2.old/arch/cris/arch-v32/kernel/kgdb.c 2007-01-10 20:10:37.000000000 +0100
20451 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/kgdb.c 2005-07-06 11:40:49.000000000 +0200
20452 @@ -25,7 +25,7 @@
20453 * kgdb usage notes:
20454 * -----------------
20455 *
20456 - * If you select CONFIG_ETRAX_KGDB in the configuration, the kernel will be
20457 + * If you select CONFIG_ETRAX_KGDB in the configuration, the kernel will be
20458 * built with different gcc flags: "-g" is added to get debug infos, and
20459 * "-fomit-frame-pointer" is omitted to make debugging easier. Since the
20460 * resulting kernel will be quite big (approx. > 7 MB), it will be stripped
20461 @@ -118,7 +118,7 @@
20462 * call to kgdb_init() is necessary in order to allow any breakpoints
20463 * or error conditions to be properly intercepted and reported to gdb.
20464 * Two, a breakpoint needs to be generated to begin communication. This
20465 - * is most easily accomplished by a call to breakpoint().
20466 + * is most easily accomplished by a call to breakpoint().
20467 *
20468 * The following gdb commands are supported:
20469 *
20470 @@ -382,8 +382,8 @@
20471 int getDebugChar(void);
20472
20473 #ifdef CONFIG_ETRAXFS_SIM
20474 -int getDebugChar(void)
20475 -{
20476 +int getDebugChar(void)
20477 +{
20478 return socketread();
20479 }
20480 #endif
20481 @@ -490,7 +490,7 @@
20482
20483 /********************************** Breakpoint *******************************/
20484 /* Use an internal stack in the breakpoint and interrupt response routines.
20485 - FIXME: How do we know the size of this stack is enough?
20486 + FIXME: How do we know the size of this stack is enough?
20487 Global so it can be reached from assembler code. */
20488 #define INTERNAL_STACK_SIZE 1024
20489 char internal_stack[INTERNAL_STACK_SIZE];
20490 @@ -511,7 +511,7 @@
20491 gdb_cris_strcpy(char *s1, const char *s2)
20492 {
20493 char *s = s1;
20494 -
20495 +
20496 for (s = s1; (*s++ = *s2++) != '\0'; )
20497 ;
20498 return s1;
20499 @@ -522,7 +522,7 @@
20500 gdb_cris_strlen(const char *s)
20501 {
20502 const char *sc;
20503 -
20504 +
20505 for (sc = s; *sc != '\0'; sc++)
20506 ;
20507 return (sc - s);
20508 @@ -534,7 +534,7 @@
20509 {
20510 const unsigned char uc = c;
20511 const unsigned char *su;
20512 -
20513 +
20514 for (su = s; 0 < n; ++su, --n)
20515 if (*su == uc)
20516 return (void *)su;
20517 @@ -549,15 +549,15 @@
20518 char *s1;
20519 char *sd;
20520 int x = 0;
20521 -
20522 +
20523 for (s1 = (char*)s; (sd = gdb_cris_memchr(hexchars, *s1, base)) != NULL; ++s1)
20524 x = x * base + (sd - hexchars);
20525 -
20526 +
20527 if (endptr) {
20528 /* Unconverted suffix is stored in endptr unless endptr is NULL. */
20529 *endptr = s1;
20530 }
20531 -
20532 +
20533 return x;
20534 }
20535
20536 @@ -629,7 +629,7 @@
20537 } else if (regno == PID) {
20538 /* 32-bit register. */
20539 *valptr = *(unsigned int *)((char *)&reg.pid);
20540 -
20541 +
20542 } else if (regno == SRS) {
20543 /* 8-bit register. */
20544 *valptr = (unsigned int)(*(unsigned char *)((char *)&reg.srs));
20545 @@ -726,7 +726,7 @@
20546 *buf++ = highhex (ch);
20547 *buf++ = lowhex (ch);
20548 }
20549 -
20550 +
20551 /* Terminate properly. */
20552 *buf = '\0';
20553 return buf;
20554 @@ -804,7 +804,7 @@
20555 continue;
20556
20557 buffer[count] = 0;
20558 -
20559 +
20560 if (ch == '#') {
20561 xmitcsum = hex(getDebugChar()) << 4;
20562 xmitcsum += hex(getDebugChar());
20563 @@ -836,7 +836,7 @@
20564 int checksum;
20565 int runlen;
20566 int encode;
20567 -
20568 +
20569 do {
20570 char *src = buffer;
20571 putDebugChar('$');
20572 @@ -905,42 +905,42 @@
20573 {
20574 char *ptr = output_buffer;
20575 unsigned int reg_cont;
20576 -
20577 +
20578 /* Send trap type (converted to signal) */
20579
20580 - *ptr++ = 'T';
20581 + *ptr++ = 'T';
20582 *ptr++ = highhex(sigval);
20583 *ptr++ = lowhex(sigval);
20584
20585 if (((reg.exs & 0xff00) >> 8) == 0xc) {
20586 -
20587 +
20588 /* Some kind of hardware watchpoint triggered. Find which one
20589 and determine its type (read/write/access). */
20590 int S, bp, trig_bits = 0, rw_bits = 0;
20591 int trig_mask = 0;
20592 unsigned int *bp_d_regs = &sreg.s3_3;
20593 /* In a lot of cases, the stopped data address will simply be EDA.
20594 - In some cases, we adjust it to match the watched data range.
20595 + In some cases, we adjust it to match the watched data range.
20596 (We don't want to change the actual EDA though). */
20597 unsigned int stopped_data_address;
20598 /* The S field of EXS. */
20599 S = (reg.exs & 0xffff0000) >> 16;
20600 -
20601 +
20602 if (S & 1) {
20603 /* Instruction watchpoint. */
20604 /* FIXME: Check against, and possibly adjust reported EDA. */
20605 } else {
20606 /* Data watchpoint. Find the one that triggered. */
20607 for (bp = 0; bp < 6; bp++) {
20608 -
20609 +
20610 /* Dx_RD, Dx_WR in the S field of EXS for this BP. */
20611 int bitpos_trig = 1 + bp * 2;
20612 /* Dx_BPRD, Dx_BPWR in BP_CTRL for this BP. */
20613 int bitpos_config = 2 + bp * 4;
20614 -
20615 +
20616 /* Get read/write trig bits for this BP. */
20617 trig_bits = (S & (3 << bitpos_trig)) >> bitpos_trig;
20618 -
20619 +
20620 /* Read/write config bits for this BP. */
20621 rw_bits = (sreg.s0_3 & (3 << bitpos_config)) >> bitpos_config;
20622 if (trig_bits) {
20623 @@ -949,11 +949,11 @@
20624 if ((rw_bits == 0x1 && trig_bits != 0x1) ||
20625 (rw_bits == 0x2 && trig_bits != 0x2))
20626 panic("Invalid r/w trigging for this BP");
20627 -
20628 +
20629 /* Mark this BP as trigged for future reference. */
20630 trig_mask |= (1 << bp);
20631 -
20632 - if (reg.eda >= bp_d_regs[bp * 2] &&
20633 +
20634 + if (reg.eda >= bp_d_regs[bp * 2] &&
20635 reg.eda <= bp_d_regs[bp * 2 + 1]) {
20636 /* EDA withing range for this BP; it must be the one
20637 we're looking for. */
20638 @@ -972,7 +972,7 @@
20639
20640 /* Read/write config bits for this BP (needed later). */
20641 rw_bits = (sreg.s0_3 & (3 << bitpos_config)) >> bitpos_config;
20642 -
20643 +
20644 if (trig_mask & (1 << bp)) {
20645 /* EDA within 31 bytes of the configured start address? */
20646 if (reg.eda + 31 >= bp_d_regs[bp * 2]) {
20647 @@ -987,12 +987,12 @@
20648 }
20649 }
20650 }
20651 -
20652 +
20653 /* No match yet? */
20654 BUG_ON(bp >= 6);
20655 /* Note that we report the type according to what the BP is configured
20656 for (otherwise we'd never report an 'awatch'), not according to how
20657 - it trigged. We did check that the trigged bits match what the BP is
20658 + it trigged. We did check that the trigged bits match what the BP is
20659 configured for though. */
20660 if (rw_bits == 0x1) {
20661 /* read */
20662 @@ -1110,12 +1110,12 @@
20663
20664 if (sigval == SIGTRAP) {
20665 /* Break 8, single step or hardware breakpoint exception. */
20666 -
20667 +
20668 /* Check IDX field of EXS. */
20669 if (((reg.exs & 0xff00) >> 8) == 0x18) {
20670
20671 /* Break 8. */
20672 -
20673 +
20674 /* Static (compiled) breakpoints must return to the next instruction
20675 in order to avoid infinite loops (default value of ERP). Dynamic
20676 (gdb-invoked) must subtract the size of the break instruction from
20677 @@ -1132,7 +1132,7 @@
20678 reg.pc -= 2;
20679 }
20680 }
20681 -
20682 +
20683 } else if (((reg.exs & 0xff00) >> 8) == 0x3) {
20684 /* Single step. */
20685 /* Don't fiddle with S1. */
20686 @@ -1190,10 +1190,10 @@
20687 unsigned int *bp_d_regs = &sreg.s3_3;
20688
20689 /* The watchpoint allocation scheme is the simplest possible.
20690 - For example, if a region is watched for read and
20691 + For example, if a region is watched for read and
20692 a write watch is requested, a new watchpoint will
20693 be used. Also, if a watch for a region that is already
20694 - covered by one or more existing watchpoints, a new
20695 + covered by one or more existing watchpoints, a new
20696 watchpoint will be used. */
20697
20698 /* First, find a free data watchpoint. */
20699 @@ -1205,13 +1205,13 @@
20700 break;
20701 }
20702 }
20703 -
20704 +
20705 if (bp > 5) {
20706 /* We're out of watchpoints. */
20707 gdb_cris_strcpy(output_buffer, error_message[E04]);
20708 return;
20709 }
20710 -
20711 +
20712 /* Configure the control register first. */
20713 if (type == '3' || type == '4') {
20714 /* Trigger on read. */
20715 @@ -1221,11 +1221,11 @@
20716 /* Trigger on write. */
20717 sreg.s0_3 |= (2 << (2 + bp * 4));
20718 }
20719 -
20720 +
20721 /* Ugly pointer arithmetics to configure the watched range. */
20722 bp_d_regs[bp * 2] = addr;
20723 bp_d_regs[bp * 2 + 1] = (addr + len - 1);
20724 - }
20725 + }
20726
20727 /* Set the S1 flag to enable watchpoints. */
20728 reg.ccs |= (1 << (S_CCS_BITNR + CCS_SHIFT));
20729 @@ -1258,7 +1258,7 @@
20730 /* Not in use. */
20731 gdb_cris_strcpy(output_buffer, error_message[E04]);
20732 return;
20733 - }
20734 + }
20735 /* Deconfigure. */
20736 sreg.s1_3 = 0;
20737 sreg.s2_3 = 0;
20738 @@ -1268,8 +1268,8 @@
20739 unsigned int *bp_d_regs = &sreg.s3_3;
20740 /* Try to find a watchpoint that is configured for the
20741 specified range, then check that read/write also matches. */
20742 -
20743 - /* Ugly pointer arithmetic, since I cannot rely on a
20744 +
20745 + /* Ugly pointer arithmetic, since I cannot rely on a
20746 single switch (addr) as there may be several watchpoints with
20747 the same start address for example. */
20748
20749 @@ -1279,7 +1279,7 @@
20750 /* Matching range. */
20751 int bitpos = 2 + bp * 4;
20752 int rw_bits;
20753 -
20754 +
20755 /* Read/write bits for this BP. */
20756 rw_bits = (sreg.s0_3 & (0x3 << bitpos)) >> bitpos;
20757
20758 @@ -1347,7 +1347,7 @@
20759 (char *)&sreg + (reg.srs * 16 * sizeof(unsigned int)),
20760 16 * sizeof(unsigned int));
20761 break;
20762 - }
20763 + }
20764 case 'G':
20765 /* Write registers. GXX..XX
20766 Each byte of register data is described by two hex digits.
20767 @@ -1357,11 +1357,11 @@
20768 hex2mem((char *)&reg, &input_buffer[1], sizeof(registers));
20769 /* Support registers. */
20770 hex2mem((char *)&sreg + (reg.srs * 16 * sizeof(unsigned int)),
20771 - &input_buffer[1] + sizeof(registers),
20772 + &input_buffer[1] + sizeof(registers),
20773 16 * sizeof(unsigned int));
20774 gdb_cris_strcpy(output_buffer, "OK");
20775 break;
20776 -
20777 +
20778 case 'P':
20779 /* Write register. Pn...=r...
20780 Write register n..., hex value without 0x, with value r...,
20781 @@ -1393,7 +1393,7 @@
20782 }
20783 }
20784 break;
20785 -
20786 +
20787 case 'm':
20788 /* Read from memory. mAA..AA,LLLL
20789 AA..AA is the address and LLLL is the length.
20790 @@ -1416,7 +1416,7 @@
20791 mem2hex(output_buffer, addr, len);
20792 }
20793 break;
20794 -
20795 +
20796 case 'X':
20797 /* Write to memory. XAA..AA,LLLL:XX..XX
20798 AA..AA is the start address, LLLL is the number of bytes, and
20799 @@ -1448,7 +1448,7 @@
20800 }
20801 }
20802 break;
20803 -
20804 +
20805 case 'c':
20806 /* Continue execution. cAA..AA
20807 AA..AA is the address where execution is resumed. If AA..AA is
20808 @@ -1472,15 +1472,15 @@
20809 if ((sreg.s0_3 & 0x3fff) == 0) {
20810 reg.ccs &= ~(1 << (S_CCS_BITNR + CCS_SHIFT));
20811 }
20812 -
20813 +
20814 return;
20815 -
20816 +
20817 case 's':
20818 /* Step. sAA..AA
20819 AA..AA is the address where execution is resumed. If AA..AA is
20820 omitted, resume at the present address. Success: return to the
20821 executing thread. Failure: will never know. */
20822 -
20823 +
20824 if (input_buffer[1] != '\0') {
20825 /* FIXME: Doesn't handle address argument. */
20826 gdb_cris_strcpy(output_buffer, error_message[E04]);
20827 @@ -1497,7 +1497,7 @@
20828 return;
20829
20830 case 'Z':
20831 -
20832 +
20833 /* Insert breakpoint or watchpoint, Ztype,addr,length.
20834 Remote protocol says: A remote target shall return an empty string
20835 for an unrecognized breakpoint or watchpoint packet type. */
20836 @@ -1522,7 +1522,7 @@
20837 int addr = gdb_cris_strtol(&input_buffer[3], &lenptr, 16);
20838 int len = gdb_cris_strtol(lenptr + 1, &dataptr, 16);
20839 char type = input_buffer[1];
20840 -
20841 +
20842 remove_watchpoint(type, addr, len);
20843 break;
20844 }
20845 @@ -1537,14 +1537,14 @@
20846 output_buffer[2] = lowhex(sigval);
20847 output_buffer[3] = 0;
20848 break;
20849 -
20850 +
20851 case 'D':
20852 /* Detach from host. D
20853 Success: OK, and return to the executing thread.
20854 Failure: will never know */
20855 putpacket("OK");
20856 return;
20857 -
20858 +
20859 case 'k':
20860 case 'r':
20861 /* kill request or reset request.
20862 @@ -1552,7 +1552,7 @@
20863 Failure: will never know. */
20864 kill_restart();
20865 break;
20866 -
20867 +
20868 case 'C':
20869 case 'S':
20870 case '!':
20871 @@ -1570,7 +1570,7 @@
20872 and ignored (below)? */
20873 gdb_cris_strcpy(output_buffer, error_message[E04]);
20874 break;
20875 -
20876 +
20877 default:
20878 /* The stub should ignore other request and send an empty
20879 response ($#<checksum>). This way we can extend the protocol and GDB
20880 @@ -1587,7 +1587,7 @@
20881 {
20882 reg_intr_vect_rw_mask intr_mask;
20883 reg_ser_rw_intr_mask ser_intr_mask;
20884 -
20885 +
20886 /* Configure the kgdb serial port. */
20887 #if defined(CONFIG_ETRAX_KGDB_PORT0)
20888 /* Note: no shortcut registered (not handled by multiple_interrupt).
20889 @@ -1597,9 +1597,9 @@
20890 intr_mask = REG_RD(intr_vect, regi_irq, rw_mask);
20891 intr_mask.ser0 = 1;
20892 REG_WR(intr_vect, regi_irq, rw_mask, intr_mask);
20893 -
20894 +
20895 ser_intr_mask = REG_RD(ser, regi_ser0, rw_intr_mask);
20896 - ser_intr_mask.data_avail = regk_ser_yes;
20897 + ser_intr_mask.dav = regk_ser_yes;
20898 REG_WR(ser, regi_ser0, rw_intr_mask, ser_intr_mask);
20899 #elif defined(CONFIG_ETRAX_KGDB_PORT1)
20900 /* Note: no shortcut registered (not handled by multiple_interrupt).
20901 @@ -1609,9 +1609,9 @@
20902 intr_mask = REG_RD(intr_vect, regi_irq, rw_mask);
20903 intr_mask.ser1 = 1;
20904 REG_WR(intr_vect, regi_irq, rw_mask, intr_mask);
20905 -
20906 +
20907 ser_intr_mask = REG_RD(ser, regi_ser1, rw_intr_mask);
20908 - ser_intr_mask.data_avail = regk_ser_yes;
20909 + ser_intr_mask.dav = regk_ser_yes;
20910 REG_WR(ser, regi_ser1, rw_intr_mask, ser_intr_mask);
20911 #elif defined(CONFIG_ETRAX_KGDB_PORT2)
20912 /* Note: no shortcut registered (not handled by multiple_interrupt).
20913 @@ -1621,9 +1621,9 @@
20914 intr_mask = REG_RD(intr_vect, regi_irq, rw_mask);
20915 intr_mask.ser2 = 1;
20916 REG_WR(intr_vect, regi_irq, rw_mask, intr_mask);
20917 -
20918 +
20919 ser_intr_mask = REG_RD(ser, regi_ser2, rw_intr_mask);
20920 - ser_intr_mask.data_avail = regk_ser_yes;
20921 + ser_intr_mask.dav = regk_ser_yes;
20922 REG_WR(ser, regi_ser2, rw_intr_mask, ser_intr_mask);
20923 #elif defined(CONFIG_ETRAX_KGDB_PORT3)
20924 /* Note: no shortcut registered (not handled by multiple_interrupt).
20925 @@ -1635,7 +1635,7 @@
20926 REG_WR(intr_vect, regi_irq, rw_mask, intr_mask);
20927
20928 ser_intr_mask = REG_RD(ser, regi_ser3, rw_intr_mask);
20929 - ser_intr_mask.data_avail = regk_ser_yes;
20930 + ser_intr_mask.dav = regk_ser_yes;
20931 REG_WR(ser, regi_ser3, rw_intr_mask, ser_intr_mask);
20932 #endif
20933
20934 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/kernel/kgdb_asm.S linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/kgdb_asm.S
20935 --- linux-2.6.19.2.old/arch/cris/arch-v32/kernel/kgdb_asm.S 2007-01-10 20:10:37.000000000 +0100
20936 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/kgdb_asm.S 2006-10-13 14:43:13.000000000 +0200
20937 @@ -11,7 +11,7 @@
20938 .globl kgdb_handle_exception
20939
20940 kgdb_handle_exception:
20941 -
20942 +
20943 ;; Create a register image of the caller.
20944 ;;
20945 ;; First of all, save the ACR on the stack since we need it for address calculations.
20946 @@ -262,7 +262,7 @@
20947 ;; Nothing in S15, bank 3
20948 clear.d [$acr]
20949 addq 4, $acr
20950 -
20951 +
20952 ;; Check what got us here: get IDX field of EXS.
20953 move $exs, $r10
20954 and.d 0xff00, $r10
20955 @@ -307,7 +307,7 @@
20956 handle_comm:
20957 move.d internal_stack+1020, $sp ; Use the internal stack which grows upwards
20958 jsr handle_exception ; Interactive routine
20959 - nop
20960 + nop
20961
20962 ;;
20963 ;; Return to the caller
20964 @@ -345,7 +345,7 @@
20965 ;; Nothing in S6 - S7, bank 0.
20966 addq 4, $acr
20967 addq 4, $acr
20968 -
20969 +
20970 move.d [$acr], $r0
20971 move $r0, $s8
20972 addq 4, $acr
20973 @@ -507,7 +507,7 @@
20974 addq 8, $acr
20975
20976 ;; Skip BZ, VR.
20977 - addq 2, $acr
20978 + addq 2, $acr
20979
20980 move [$acr], $pid ; Restore PID
20981 addq 4, $acr
20982 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/kernel/pinmux.c linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/pinmux.c
20983 --- linux-2.6.19.2.old/arch/cris/arch-v32/kernel/pinmux.c 2007-01-10 20:10:37.000000000 +0100
20984 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/pinmux.c 2006-08-11 10:32:21.000000000 +0200
20985 @@ -1,7 +1,7 @@
20986 -/*
20987 +/*
20988 * Allocator for I/O pins. All pins are allocated to GPIO at bootup.
20989 * Unassigned pins and GPIO pins can be allocated to a fixed interface
20990 - * or the I/O processor instead.
20991 + * or the I/O processor instead.
20992 *
20993 * Copyright (c) 2004 Axis Communications AB.
20994 */
20995 @@ -33,9 +33,10 @@
20996
20997 if (!initialized) {
20998 reg_pinmux_rw_pa pa = REG_RD(pinmux, regi_pinmux, rw_pa);
20999 + REG_WR_INT(pinmux, regi_pinmux, rw_hwprot, 0);
21000 initialized = 1;
21001 - pa.pa0 = pa.pa1 = pa.pa2 = pa.pa3 =
21002 - pa.pa4 = pa.pa5 = pa.pa6 = pa.pa7 = regk_pinmux_yes;
21003 + pa.pa0 = pa.pa1 = pa.pa2 = pa.pa3 =
21004 + pa.pa4 = pa.pa5 = pa.pa6 = pa.pa7 = regk_pinmux_yes;
21005 REG_WR(pinmux, regi_pinmux, rw_pa, pa);
21006 crisv32_pinmux_alloc(PORT_B, 0, PORT_PINS - 1, pinmux_gpio);
21007 crisv32_pinmux_alloc(PORT_C, 0, PORT_PINS - 1, pinmux_gpio);
21008 @@ -46,124 +47,137 @@
21009 return 0;
21010 }
21011
21012 -int
21013 -crisv32_pinmux_alloc(int port, int first_pin, int last_pin, enum pin_mode mode)
21014 +/*
21015 + * must be called with the pinmux_lock held.
21016 + */
21017 +static int __crisv32_pinmux_alloc(int port, int first_pin, int last_pin,
21018 + enum pin_mode mode)
21019 {
21020 int i;
21021 - unsigned long flags;
21022
21023 - crisv32_pinmux_init();
21024 -
21025 - if (port > PORTS)
21026 + if (port >= PORTS ||
21027 + first_pin < 0 || last_pin >= PORT_PINS || last_pin < first_pin)
21028 return -EINVAL;
21029 -
21030 - spin_lock_irqsave(&pinmux_lock, flags);
21031 -
21032 - for (i = first_pin; i <= last_pin; i++)
21033 +
21034 + for (i = first_pin; i <= last_pin; i++)
21035 {
21036 - if ((pins[port][i] != pinmux_none) && (pins[port][i] != pinmux_gpio) &&
21037 - (pins[port][i] != mode))
21038 + if ((pins[port][i] != pinmux_none)
21039 + && (pins[port][i] != pinmux_gpio)
21040 + && (pins[port][i] != mode))
21041 {
21042 - spin_unlock_irqrestore(&pinmux_lock, flags);
21043 #ifdef DEBUG
21044 panic("Pinmux alloc failed!\n");
21045 #endif
21046 return -EPERM;
21047 }
21048 }
21049 -
21050 +
21051 for (i = first_pin; i <= last_pin; i++)
21052 pins[port][i] = mode;
21053
21054 crisv32_pinmux_set(port);
21055 -
21056 - spin_unlock_irqrestore(&pinmux_lock, flags);
21057 -
21058 return 0;
21059 }
21060
21061 int
21062 +crisv32_pinmux_alloc(int port, int first_pin, int last_pin, enum pin_mode mode)
21063 +{
21064 + int r;
21065 + unsigned long flags;
21066 +
21067 + crisv32_pinmux_init();
21068 +
21069 + spin_lock_irqsave(&pinmux_lock, flags);
21070 + r = __crisv32_pinmux_alloc(port, first_pin, last_pin, mode);
21071 + spin_unlock_irqrestore(&pinmux_lock, flags);
21072 + return r;
21073 +}
21074 +
21075 +int
21076 crisv32_pinmux_alloc_fixed(enum fixed_function function)
21077 {
21078 int ret = -EINVAL;
21079 char saved[sizeof pins];
21080 unsigned long flags;
21081 -
21082 + reg_pinmux_rw_hwprot hwprot;
21083 +
21084 + crisv32_pinmux_init();
21085 +
21086 spin_lock_irqsave(&pinmux_lock, flags);
21087
21088 /* Save internal data for recovery */
21089 memcpy(saved, pins, sizeof pins);
21090 -
21091 - reg_pinmux_rw_hwprot hwprot = REG_RD(pinmux, regi_pinmux, rw_hwprot);
21092 -
21093 +
21094 + hwprot = REG_RD(pinmux, regi_pinmux, rw_hwprot);
21095 +
21096 switch(function)
21097 {
21098 case pinmux_ser1:
21099 - ret = crisv32_pinmux_alloc(PORT_C, 4, 7, pinmux_fixed);
21100 + ret = __crisv32_pinmux_alloc(PORT_C, 4, 7, pinmux_fixed);
21101 hwprot.ser1 = regk_pinmux_yes;
21102 break;
21103 case pinmux_ser2:
21104 - ret = crisv32_pinmux_alloc(PORT_C, 8, 11, pinmux_fixed);
21105 + ret = __crisv32_pinmux_alloc(PORT_C, 8, 11, pinmux_fixed);
21106 hwprot.ser2 = regk_pinmux_yes;
21107 break;
21108 case pinmux_ser3:
21109 - ret = crisv32_pinmux_alloc(PORT_C, 12, 15, pinmux_fixed);
21110 + ret = __crisv32_pinmux_alloc(PORT_C, 12, 15, pinmux_fixed);
21111 hwprot.ser3 = regk_pinmux_yes;
21112 break;
21113 case pinmux_sser0:
21114 - ret = crisv32_pinmux_alloc(PORT_C, 0, 3, pinmux_fixed);
21115 - ret |= crisv32_pinmux_alloc(PORT_C, 16, 16, pinmux_fixed);
21116 + ret = __crisv32_pinmux_alloc(PORT_C, 0, 3, pinmux_fixed);
21117 + ret |= __crisv32_pinmux_alloc(PORT_C, 16, 16, pinmux_fixed);
21118 hwprot.sser0 = regk_pinmux_yes;
21119 break;
21120 case pinmux_sser1:
21121 - ret = crisv32_pinmux_alloc(PORT_D, 0, 4, pinmux_fixed);
21122 + ret = __crisv32_pinmux_alloc(PORT_D, 0, 4, pinmux_fixed);
21123 hwprot.sser1 = regk_pinmux_yes;
21124 break;
21125 case pinmux_ata0:
21126 - ret = crisv32_pinmux_alloc(PORT_D, 5, 7, pinmux_fixed);
21127 - ret |= crisv32_pinmux_alloc(PORT_D, 15, 17, pinmux_fixed);
21128 + ret = __crisv32_pinmux_alloc(PORT_D, 5, 7, pinmux_fixed);
21129 + ret |= __crisv32_pinmux_alloc(PORT_D, 15, 17, pinmux_fixed);
21130 hwprot.ata0 = regk_pinmux_yes;
21131 break;
21132 case pinmux_ata1:
21133 - ret = crisv32_pinmux_alloc(PORT_D, 0, 4, pinmux_fixed);
21134 - ret |= crisv32_pinmux_alloc(PORT_E, 17, 17, pinmux_fixed);
21135 + ret = __crisv32_pinmux_alloc(PORT_D, 0, 4, pinmux_fixed);
21136 + ret |= __crisv32_pinmux_alloc(PORT_E, 17, 17, pinmux_fixed);
21137 hwprot.ata1 = regk_pinmux_yes;
21138 break;
21139 case pinmux_ata2:
21140 - ret = crisv32_pinmux_alloc(PORT_C, 11, 15, pinmux_fixed);
21141 - ret |= crisv32_pinmux_alloc(PORT_E, 3, 3, pinmux_fixed);
21142 + ret = __crisv32_pinmux_alloc(PORT_C, 11, 15, pinmux_fixed);
21143 + ret |= __crisv32_pinmux_alloc(PORT_E, 3, 3, pinmux_fixed);
21144 hwprot.ata2 = regk_pinmux_yes;
21145 break;
21146 case pinmux_ata3:
21147 - ret = crisv32_pinmux_alloc(PORT_C, 8, 10, pinmux_fixed);
21148 - ret |= crisv32_pinmux_alloc(PORT_C, 0, 2, pinmux_fixed);
21149 + ret = __crisv32_pinmux_alloc(PORT_C, 8, 10, pinmux_fixed);
21150 + ret |= __crisv32_pinmux_alloc(PORT_C, 0, 2, pinmux_fixed);
21151 hwprot.ata2 = regk_pinmux_yes;
21152 break;
21153 case pinmux_ata:
21154 - ret = crisv32_pinmux_alloc(PORT_B, 0, 15, pinmux_fixed);
21155 - ret |= crisv32_pinmux_alloc(PORT_D, 8, 15, pinmux_fixed);
21156 + ret = __crisv32_pinmux_alloc(PORT_B, 0, 15, pinmux_fixed);
21157 + ret |= __crisv32_pinmux_alloc(PORT_D, 8, 15, pinmux_fixed);
21158 hwprot.ata = regk_pinmux_yes;
21159 break;
21160 case pinmux_eth1:
21161 - ret = crisv32_pinmux_alloc(PORT_E, 0, 17, pinmux_fixed);
21162 + ret = __crisv32_pinmux_alloc(PORT_E, 0, 17, pinmux_fixed);
21163 hwprot.eth1 = regk_pinmux_yes;
21164 hwprot.eth1_mgm = regk_pinmux_yes;
21165 break;
21166 case pinmux_timer:
21167 - ret = crisv32_pinmux_alloc(PORT_C, 16, 16, pinmux_fixed);
21168 + ret = __crisv32_pinmux_alloc(PORT_C, 16, 16, pinmux_fixed);
21169 hwprot.timer = regk_pinmux_yes;
21170 spin_unlock_irqrestore(&pinmux_lock, flags);
21171 return ret;
21172 }
21173 -
21174 +
21175 if (!ret)
21176 REG_WR(pinmux, regi_pinmux, rw_hwprot, hwprot);
21177 else
21178 memcpy(pins, saved, sizeof pins);
21179 -
21180 - spin_unlock_irqrestore(&pinmux_lock, flags);
21181 -
21182 - return ret;
21183 +
21184 + spin_unlock_irqrestore(&pinmux_lock, flags);
21185 +
21186 + return ret;
21187 }
21188
21189 void
21190 @@ -189,33 +203,126 @@
21191 #endif
21192 }
21193
21194 -int
21195 -crisv32_pinmux_dealloc(int port, int first_pin, int last_pin)
21196 +/*
21197 + * must be called with the pinmux_lock held.
21198 + */
21199 +static int __crisv32_pinmux_dealloc(int port, int first_pin, int last_pin)
21200 {
21201 int i;
21202 +
21203 + if (port > PORTS)
21204 + return -EINVAL;
21205 +
21206 + for (i = first_pin; i <= last_pin; i++)
21207 + pins[port][i] = pinmux_none;
21208 +
21209 + crisv32_pinmux_set(port);
21210 +
21211 + return 0;
21212 +}
21213 +
21214 +int crisv32_pinmux_dealloc(int port, int first_pin, int last_pin)
21215 +{
21216 + int r;
21217 unsigned long flags;
21218
21219 crisv32_pinmux_init();
21220 +
21221 + spin_lock_irqsave(&pinmux_lock, flags);
21222 + r = __crisv32_pinmux_dealloc(port, first_pin, last_pin);
21223 + spin_unlock_irqrestore(&pinmux_lock, flags);
21224 + return r;
21225 +}
21226
21227 - if (port > PORTS)
21228 - return -EINVAL;
21229 +int
21230 +crisv32_pinmux_dealloc_fixed(enum fixed_function function)
21231 +{
21232 + int ret = -EINVAL;
21233 + char saved[sizeof pins];
21234 + unsigned long flags;
21235
21236 spin_lock_irqsave(&pinmux_lock, flags);
21237
21238 - for (i = first_pin; i <= last_pin; i++)
21239 - pins[port][i] = pinmux_none;
21240 + /* Save internal data for recovery */
21241 + memcpy(saved, pins, sizeof pins);
21242 +
21243 + reg_pinmux_rw_hwprot hwprot = REG_RD(pinmux, regi_pinmux, rw_hwprot);
21244 +
21245 + switch(function)
21246 + {
21247 + case pinmux_ser1:
21248 + ret = __crisv32_pinmux_dealloc(PORT_C, 4, 7);
21249 + hwprot.ser1 = regk_pinmux_no;
21250 + break;
21251 + case pinmux_ser2:
21252 + ret = __crisv32_pinmux_dealloc(PORT_C, 8, 11);
21253 + hwprot.ser2 = regk_pinmux_no;
21254 + break;
21255 + case pinmux_ser3:
21256 + ret = __crisv32_pinmux_dealloc(PORT_C, 12, 15);
21257 + hwprot.ser3 = regk_pinmux_no;
21258 + break;
21259 + case pinmux_sser0:
21260 + ret = __crisv32_pinmux_dealloc(PORT_C, 0, 3);
21261 + ret |= __crisv32_pinmux_dealloc(PORT_C, 16, 16);
21262 + hwprot.sser0 = regk_pinmux_no;
21263 + break;
21264 + case pinmux_sser1:
21265 + ret = __crisv32_pinmux_dealloc(PORT_D, 0, 4);
21266 + hwprot.sser1 = regk_pinmux_no;
21267 + break;
21268 + case pinmux_ata0:
21269 + ret = __crisv32_pinmux_dealloc(PORT_D, 5, 7);
21270 + ret |= __crisv32_pinmux_dealloc(PORT_D, 15, 17);
21271 + hwprot.ata0 = regk_pinmux_no;
21272 + break;
21273 + case pinmux_ata1:
21274 + ret = __crisv32_pinmux_dealloc(PORT_D, 0, 4);
21275 + ret |= __crisv32_pinmux_dealloc(PORT_E, 17, 17);
21276 + hwprot.ata1 = regk_pinmux_no;
21277 + break;
21278 + case pinmux_ata2:
21279 + ret = __crisv32_pinmux_dealloc(PORT_C, 11, 15);
21280 + ret |= __crisv32_pinmux_dealloc(PORT_E, 3, 3);
21281 + hwprot.ata2 = regk_pinmux_no;
21282 + break;
21283 + case pinmux_ata3:
21284 + ret = __crisv32_pinmux_dealloc(PORT_C, 8, 10);
21285 + ret |= __crisv32_pinmux_dealloc(PORT_C, 0, 2);
21286 + hwprot.ata2 = regk_pinmux_no;
21287 + break;
21288 + case pinmux_ata:
21289 + ret = __crisv32_pinmux_dealloc(PORT_B, 0, 15);
21290 + ret |= __crisv32_pinmux_dealloc(PORT_D, 8, 15);
21291 + hwprot.ata = regk_pinmux_no;
21292 + break;
21293 + case pinmux_eth1:
21294 + ret = __crisv32_pinmux_dealloc(PORT_E, 0, 17);
21295 + hwprot.eth1 = regk_pinmux_no;
21296 + hwprot.eth1_mgm = regk_pinmux_no;
21297 + break;
21298 + case pinmux_timer:
21299 + ret = __crisv32_pinmux_dealloc(PORT_C, 16, 16);
21300 + hwprot.timer = regk_pinmux_no;
21301 + spin_unlock_irqrestore(&pinmux_lock, flags);
21302 + return ret;
21303 + }
21304 +
21305 + if (!ret)
21306 + REG_WR(pinmux, regi_pinmux, rw_hwprot, hwprot);
21307 + else
21308 + memcpy(pins, saved, sizeof pins);
21309
21310 - crisv32_pinmux_set(port);
21311 spin_unlock_irqrestore(&pinmux_lock, flags);
21312 -
21313 - return 0;
21314 +
21315 + return ret;
21316 }
21317
21318 void
21319 crisv32_pinmux_dump(void)
21320 {
21321 int i, j;
21322 -
21323 +
21324 crisv32_pinmux_init();
21325
21326 for (i = 0; i < PORTS; i++)
21327 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/kernel/process.c linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/process.c
21328 --- linux-2.6.19.2.old/arch/cris/arch-v32/kernel/process.c 2007-01-10 20:10:37.000000000 +0100
21329 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/process.c 2006-10-13 14:43:13.000000000 +0200
21330 @@ -74,9 +74,9 @@
21331 #else
21332 {
21333 reg_timer_rw_wd_ctrl wd_ctrl = {0};
21334 -
21335 +
21336 stop_watchdog();
21337 -
21338 +
21339 wd_ctrl.key = 16; /* Arbitrary key. */
21340 wd_ctrl.cnt = 1; /* Minimum time. */
21341 wd_ctrl.cmd = regk_timer_start;
21342 @@ -141,7 +141,7 @@
21343 {
21344 struct pt_regs *childregs;
21345 struct switch_stack *swstack;
21346 -
21347 +
21348 /*
21349 * Put the pt_regs structure at the end of the new kernel stack page and
21350 * fix it up. Note: the task_struct doubles as the kernel stack for the
21351 @@ -152,7 +152,7 @@
21352 p->set_child_tid = p->clear_child_tid = NULL;
21353 childregs->r10 = 0; /* Child returns 0 after a fork/clone. */
21354
21355 - /* Set a new TLS ?
21356 + /* Set a new TLS ?
21357 * The TLS is in $mof beacuse it is the 5th argument to sys_clone.
21358 */
21359 if (p->mm && (clone_flags & CLONE_SETTLS)) {
21360 @@ -165,20 +165,20 @@
21361 /* Paramater to ret_from_sys_call. 0 is don't restart the syscall. */
21362 swstack->r9 = 0;
21363
21364 - /*
21365 + /*
21366 * We want to return into ret_from_sys_call after the _resume.
21367 * ret_from_fork will call ret_from_sys_call.
21368 */
21369 swstack->return_ip = (unsigned long) ret_from_fork;
21370 -
21371 +
21372 /* Fix the user-mode and kernel-mode stackpointer. */
21373 - p->thread.usp = usp;
21374 + p->thread.usp = usp;
21375 p->thread.ksp = (unsigned long) swstack;
21376
21377 return 0;
21378 }
21379
21380 -/*
21381 +/*
21382 * Be aware of the "magic" 7th argument in the four system-calls below.
21383 * They need the latest stackframe, which is put as the 7th argument by
21384 * entry.S. The previous arguments are dummies or actually used, but need
21385 @@ -200,7 +200,7 @@
21386
21387 /* FIXME: Is parent_tid/child_tid really third/fourth argument? Update lib? */
21388 asmlinkage int
21389 -sys_clone(unsigned long newusp, unsigned long flags, int *parent_tid, int *child_tid,
21390 +sys_clone(unsigned long newusp, unsigned long flags, int *parent_tid, int *child_tid,
21391 unsigned long tls, long srp, struct pt_regs *regs)
21392 {
21393 if (!newusp)
21394 @@ -209,11 +209,11 @@
21395 return do_fork(flags, newusp, regs, 0, parent_tid, child_tid);
21396 }
21397
21398 -/*
21399 +/*
21400 * vfork is a system call in i386 because of register-pressure - maybe
21401 * we can remove it and handle it in libc but we put it here until then.
21402 */
21403 -asmlinkage int
21404 +asmlinkage int
21405 sys_vfork(long r10, long r11, long r12, long r13, long mof, long srp,
21406 struct pt_regs *regs)
21407 {
21408 @@ -222,7 +222,7 @@
21409
21410 /* sys_execve() executes a new program. */
21411 asmlinkage int
21412 -sys_execve(const char *fname, char **argv, char **envp, long r13, long mof, long srp,
21413 +sys_execve(const char *fname, char **argv, char **envp, long r13, long mof, long srp,
21414 struct pt_regs *regs)
21415 {
21416 int error;
21417 @@ -254,13 +254,13 @@
21418 unsigned long usp = rdusp();
21419 printk("ERP: %08lx SRP: %08lx CCS: %08lx USP: %08lx MOF: %08lx\n",
21420 regs->erp, regs->srp, regs->ccs, usp, regs->mof);
21421 -
21422 +
21423 printk(" r0: %08lx r1: %08lx r2: %08lx r3: %08lx\n",
21424 regs->r0, regs->r1, regs->r2, regs->r3);
21425 -
21426 +
21427 printk(" r4: %08lx r5: %08lx r6: %08lx r7: %08lx\n",
21428 regs->r4, regs->r5, regs->r6, regs->r7);
21429 -
21430 +
21431 printk(" r8: %08lx r9: %08lx r10: %08lx r11: %08lx\n",
21432 regs->r8, regs->r9, regs->r10, regs->r11);
21433
21434 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/kernel/ptrace.c linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/ptrace.c
21435 --- linux-2.6.19.2.old/arch/cris/arch-v32/kernel/ptrace.c 2007-01-10 20:10:37.000000000 +0100
21436 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/ptrace.c 2006-03-22 10:56:56.000000000 +0100
21437 @@ -20,7 +20,7 @@
21438 #include <asm/processor.h>
21439 #include <asm/arch/hwregs/supp_reg.h>
21440
21441 -/*
21442 +/*
21443 * Determines which bits in CCS the user has access to.
21444 * 1 = access, 0 = no access.
21445 */
21446 @@ -84,7 +84,7 @@
21447 *
21448 * Make sure the single step bit is not set.
21449 */
21450 -void
21451 +void
21452 ptrace_disable(struct task_struct *child)
21453 {
21454 unsigned long tmp;
21455 @@ -105,7 +105,7 @@
21456 unsigned long __user *datap = (unsigned long __user *)data;
21457
21458 switch (request) {
21459 - /* Read word at location address. */
21460 + /* Read word at location address. */
21461 case PTRACE_PEEKTEXT:
21462 case PTRACE_PEEKDATA: {
21463 unsigned long tmp;
21464 @@ -122,11 +122,11 @@
21465 tmp = *(unsigned long*)addr;
21466 } else {
21467 copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
21468 -
21469 +
21470 if (copied != sizeof(tmp))
21471 break;
21472 }
21473 -
21474 +
21475 ret = put_user(tmp,datap);
21476 break;
21477 }
21478 @@ -143,18 +143,18 @@
21479 ret = put_user(tmp, datap);
21480 break;
21481 }
21482 -
21483 +
21484 /* Write the word at location address. */
21485 case PTRACE_POKETEXT:
21486 case PTRACE_POKEDATA:
21487 ret = 0;
21488 -
21489 +
21490 if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
21491 break;
21492 -
21493 +
21494 ret = -EIO;
21495 break;
21496 -
21497 +
21498 /* Write the word at location address in the USER area. */
21499 case PTRACE_POKEUSR:
21500 ret = -EIO;
21501 @@ -178,10 +178,10 @@
21502 case PTRACE_SYSCALL:
21503 case PTRACE_CONT:
21504 ret = -EIO;
21505 -
21506 +
21507 if (!valid_signal(data))
21508 break;
21509 -
21510 +
21511 /* Continue means no single-step. */
21512 put_reg(child, PT_SPC, 0);
21513
21514 @@ -198,27 +198,27 @@
21515 else {
21516 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
21517 }
21518 -
21519 +
21520 child->exit_code = data;
21521 -
21522 +
21523 /* TODO: make sure any pending breakpoint is killed */
21524 wake_up_process(child);
21525 ret = 0;
21526 -
21527 +
21528 break;
21529 -
21530 +
21531 /* Make the child exit by sending it a sigkill. */
21532 case PTRACE_KILL:
21533 ret = 0;
21534 -
21535 +
21536 if (child->exit_state == EXIT_ZOMBIE)
21537 break;
21538 -
21539 +
21540 child->exit_code = SIGKILL;
21541 -
21542 +
21543 /* Deconfigure single-step and h/w bp. */
21544 ptrace_disable(child);
21545 -
21546 +
21547 /* TODO: make sure any pending breakpoint is killed */
21548 wake_up_process(child);
21549 break;
21550 @@ -227,7 +227,7 @@
21551 case PTRACE_SINGLESTEP: {
21552 unsigned long tmp;
21553 ret = -EIO;
21554 -
21555 +
21556 /* Set up SPC if not set already (in which case we have
21557 no other choice but to trust it). */
21558 if (!get_reg(child, PT_SPC)) {
21559 @@ -240,7 +240,7 @@
21560
21561 if (!valid_signal(data))
21562 break;
21563 -
21564 +
21565 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
21566
21567 /* TODO: set some clever breakpoint mechanism... */
21568 @@ -259,15 +259,15 @@
21569 case PTRACE_GETREGS: {
21570 int i;
21571 unsigned long tmp;
21572 -
21573 +
21574 for (i = 0; i <= PT_MAX; i++) {
21575 tmp = get_reg(child, i);
21576 -
21577 +
21578 if (put_user(tmp, datap)) {
21579 ret = -EFAULT;
21580 goto out_tsk;
21581 }
21582 -
21583 +
21584 datap++;
21585 }
21586
21587 @@ -279,22 +279,22 @@
21588 case PTRACE_SETREGS: {
21589 int i;
21590 unsigned long tmp;
21591 -
21592 +
21593 for (i = 0; i <= PT_MAX; i++) {
21594 if (get_user(tmp, datap)) {
21595 ret = -EFAULT;
21596 goto out_tsk;
21597 }
21598 -
21599 +
21600 if (i == PT_CCS) {
21601 tmp &= CCS_MASK;
21602 tmp |= get_reg(child, PT_CCS) & ~CCS_MASK;
21603 }
21604 -
21605 +
21606 put_reg(child, i, tmp);
21607 datap++;
21608 }
21609 -
21610 +
21611 ret = 0;
21612 break;
21613 }
21614 @@ -304,6 +304,7 @@
21615 break;
21616 }
21617
21618 +out_tsk:
21619 return ret;
21620 }
21621
21622 @@ -311,15 +312,15 @@
21623 {
21624 if (!test_thread_flag(TIF_SYSCALL_TRACE))
21625 return;
21626 -
21627 +
21628 if (!(current->ptrace & PT_PTRACED))
21629 return;
21630 -
21631 +
21632 /* the 0x80 provides a way for the tracing parent to distinguish
21633 between a syscall stop and SIGTRAP delivery */
21634 ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
21635 ? 0x80 : 0));
21636 -
21637 +
21638 /*
21639 * This isn't the same as continuing with a signal, but it will do for
21640 * normal use.
21641 @@ -338,7 +339,7 @@
21642 int copied;
21643 int opsize = 0;
21644
21645 - /* Read the opcode at pc (do what PTRACE_PEEKTEXT would do). */
21646 + /* Read the opcode at pc (do what PTRACE_PEEKTEXT would do). */
21647 copied = access_process_vm(child, pc, &opcode, sizeof(opcode), 0);
21648 if (copied != sizeof(opcode))
21649 return 0;
21650 @@ -361,7 +362,7 @@
21651 opsize = 6;
21652 break;
21653 default:
21654 - panic("ERROR: Couldn't find size of opcode 0x%lx at 0x%lx\n",
21655 + panic("ERROR: Couldn't find size of opcode 0x%lx at 0x%lx\n",
21656 opcode, pc);
21657 }
21658
21659 @@ -378,7 +379,7 @@
21660 /* Delay slot bit set. Report as stopped on proper
21661 instruction. */
21662 if (spc) {
21663 - /* Rely on SPC if set. FIXME: We might want to check
21664 + /* Rely on SPC if set. FIXME: We might want to check
21665 that EXS indicates we stopped due to a single-step
21666 exception. */
21667 pc = spc;
21668 @@ -422,7 +423,7 @@
21669 register int old_srs;
21670
21671 #ifdef CONFIG_ETRAX_KGDB
21672 - /* Ignore write, but pretend it was ok if value is 0
21673 + /* Ignore write, but pretend it was ok if value is 0
21674 (we don't want POKEUSR/SETREGS failing unnessecarily). */
21675 return (data == 0) ? ret : -1;
21676 #endif
21677 @@ -431,7 +432,7 @@
21678 if (!bp_owner)
21679 bp_owner = pid;
21680 else if (bp_owner != pid) {
21681 - /* Ignore write, but pretend it was ok if value is 0
21682 + /* Ignore write, but pretend it was ok if value is 0
21683 (we don't want POKEUSR/SETREGS failing unnessecarily). */
21684 return (data == 0) ? ret : -1;
21685 }
21686 @@ -440,7 +441,7 @@
21687 SPEC_REG_RD(SPEC_REG_SRS, old_srs);
21688 /* Switch to BP bank. */
21689 SUPP_BANK_SEL(BANK_BP);
21690 -
21691 +
21692 switch (regno - PT_BP) {
21693 case 0:
21694 SUPP_REG_WR(0, data); break;
21695 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/kernel/setup.c linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/setup.c
21696 --- linux-2.6.19.2.old/arch/cris/arch-v32/kernel/setup.c 2007-01-10 20:10:37.000000000 +0100
21697 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/setup.c 2006-10-13 14:43:13.000000000 +0200
21698 @@ -40,12 +40,12 @@
21699
21700 {"ETRAX 100LX", 10, 8, HAS_ETHERNET100 | HAS_SCSI | HAS_ATA | HAS_USB
21701 | HAS_MMU | HAS_MMU_BUG},
21702 -
21703 +
21704 {"ETRAX 100LX v2", 11, 8, HAS_ETHERNET100 | HAS_SCSI | HAS_ATA | HAS_USB
21705 | HAS_MMU},
21706 -
21707 +
21708 {"ETRAX FS", 32, 32, HAS_ETHERNET100 | HAS_ATA | HAS_MMU},
21709 -
21710 +
21711 {"Unknown", 0, 0, 0}
21712 };
21713
21714 @@ -67,7 +67,7 @@
21715 #endif
21716
21717 revision = rdvr();
21718 -
21719 +
21720 for (i = 0; i < entries; i++) {
21721 if (cpinfo[i].rev == revision) {
21722 info = &cpinfo[i];
21723 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/kernel/signal.c linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/signal.c
21724 --- linux-2.6.19.2.old/arch/cris/arch-v32/kernel/signal.c 2007-01-10 20:10:37.000000000 +0100
21725 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/signal.c 2006-03-22 10:56:56.000000000 +0100
21726 @@ -50,7 +50,7 @@
21727 unsigned char retcode[8]; /* Trampoline code. */
21728 };
21729
21730 -int do_signal(int restart, sigset_t *oldset, struct pt_regs *regs);
21731 +void do_signal(int restart, struct pt_regs *regs);
21732 void keep_debug_flags(unsigned long oldccs, unsigned long oldspc,
21733 struct pt_regs *regs);
21734 /*
21735 @@ -61,74 +61,16 @@
21736 sys_sigsuspend(old_sigset_t mask, long r11, long r12, long r13, long mof,
21737 long srp, struct pt_regs *regs)
21738 {
21739 - sigset_t saveset;
21740 -
21741 mask &= _BLOCKABLE;
21742 -
21743 spin_lock_irq(&current->sighand->siglock);
21744 -
21745 - saveset = current->blocked;
21746 -
21747 + current->saved_sigmask = current->blocked;
21748 siginitset(&current->blocked, mask);
21749 -
21750 recalc_sigpending();
21751 spin_unlock_irq(&current->sighand->siglock);
21752 -
21753 - regs->r10 = -EINTR;
21754 -
21755 - while (1) {
21756 - current->state = TASK_INTERRUPTIBLE;
21757 - schedule();
21758 -
21759 - if (do_signal(0, &saveset, regs)) {
21760 - /*
21761 - * This point is reached twice: once to call
21762 - * the signal handler, then again to return
21763 - * from the sigsuspend system call. When
21764 - * calling the signal handler, R10 hold the
21765 - * signal number as set by do_signal(). The
21766 - * sigsuspend call will always return with
21767 - * the restored value above; -EINTR.
21768 - */
21769 - return regs->r10;
21770 - }
21771 - }
21772 -}
21773 -
21774 -/* Define some dummy arguments to be able to reach the regs argument. */
21775 -int
21776 -sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, long r12, long r13,
21777 - long mof, long srp, struct pt_regs *regs)
21778 -{
21779 - sigset_t saveset;
21780 - sigset_t newset;
21781 -
21782 - if (sigsetsize != sizeof(sigset_t))
21783 - return -EINVAL;
21784 -
21785 - if (copy_from_user(&newset, unewset, sizeof(newset)))
21786 - return -EFAULT;
21787 -
21788 - sigdelsetmask(&newset, ~_BLOCKABLE);
21789 - spin_lock_irq(&current->sighand->siglock);
21790 -
21791 - saveset = current->blocked;
21792 - current->blocked = newset;
21793 -
21794 - recalc_sigpending();
21795 - spin_unlock_irq(&current->sighand->siglock);
21796 -
21797 - regs->r10 = -EINTR;
21798 -
21799 - while (1) {
21800 - current->state = TASK_INTERRUPTIBLE;
21801 - schedule();
21802 -
21803 - if (do_signal(0, &saveset, regs)) {
21804 - /* See comment in function above. */
21805 - return regs->r10;
21806 - }
21807 - }
21808 + current->state = TASK_INTERRUPTIBLE;
21809 + schedule();
21810 + set_thread_flag(TIF_RESTORE_SIGMASK);
21811 + return -ERESTARTNOHAND;
21812 }
21813
21814 int
21815 @@ -263,7 +205,7 @@
21816 unsigned long oldccs = regs->ccs;
21817
21818 frame = (struct rt_signal_frame *) rdusp();
21819 -
21820 +
21821 /*
21822 * Since the signal is stacked on a dword boundary, the frame
21823 * should be dword aligned here as well. It it's not, then the
21824 @@ -285,7 +227,7 @@
21825
21826 recalc_sigpending();
21827 spin_unlock_irq(&current->sighand->siglock);
21828 -
21829 +
21830 if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
21831 goto badframe;
21832
21833 @@ -311,7 +253,7 @@
21834
21835 err = 0;
21836 usp = rdusp();
21837 -
21838 +
21839 /*
21840 * Copy the registers. They are located first in sc, so it's
21841 * possible to use sc directly.
21842 @@ -351,7 +293,7 @@
21843 * which performs the syscall sigreturn(), or a provided user-mode
21844 * trampoline.
21845 */
21846 -static void
21847 +static int
21848 setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
21849 struct pt_regs * regs)
21850 {
21851 @@ -388,7 +330,7 @@
21852 /* Trampoline - the desired return ip is in the signal return page. */
21853 return_ip = cris_signal_return_page;
21854
21855 - /*
21856 + /*
21857 * This is movu.w __NR_sigreturn, r9; break 13;
21858 *
21859 * WE DO NOT USE IT ANY MORE! It's only left here for historical
21860 @@ -402,7 +344,7 @@
21861
21862 if (err)
21863 goto give_sigsegv;
21864 -
21865 +
21866 /*
21867 * Set up registers for signal handler.
21868 *
21869 @@ -417,16 +359,17 @@
21870 /* Actually move the USP to reflect the stacked frame. */
21871 wrusp((unsigned long)frame);
21872
21873 - return;
21874 + return 0;
21875
21876 give_sigsegv:
21877 if (sig == SIGSEGV)
21878 ka->sa.sa_handler = SIG_DFL;
21879 -
21880 +
21881 force_sig(SIGSEGV, current);
21882 + return -EFAULT;
21883 }
21884
21885 -static void
21886 +static int
21887 setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
21888 sigset_t *set, struct pt_regs * regs)
21889 {
21890 @@ -441,11 +384,11 @@
21891 goto give_sigsegv;
21892
21893 /* TODO: what is the current->exec_domain stuff and invmap ? */
21894 -
21895 +
21896 err |= __put_user(&frame->info, &frame->pinfo);
21897 err |= __put_user(&frame->uc, &frame->puc);
21898 err |= copy_siginfo_to_user(&frame->info, info);
21899 -
21900 +
21901 if (err)
21902 goto give_sigsegv;
21903
21904 @@ -467,7 +410,7 @@
21905 /* Trampoline - the desired return ip is in the signal return page. */
21906 return_ip = cris_signal_return_page + 6;
21907
21908 - /*
21909 + /*
21910 * This is movu.w __NR_rt_sigreturn, r9; break 13;
21911 *
21912 * WE DO NOT USE IT ANY MORE! It's only left here for historical
21913 @@ -478,7 +421,7 @@
21914
21915 err |= __put_user(__NR_rt_sigreturn,
21916 (short __user*)(frame->retcode+2));
21917 -
21918 +
21919 err |= __put_user(0xe93d, (short __user*)(frame->retcode+4));
21920 }
21921
21922 @@ -503,21 +446,24 @@
21923 /* Actually move the usp to reflect the stacked frame. */
21924 wrusp((unsigned long)frame);
21925
21926 - return;
21927 + return 0;
21928
21929 give_sigsegv:
21930 if (sig == SIGSEGV)
21931 ka->sa.sa_handler = SIG_DFL;
21932 -
21933 +
21934 force_sig(SIGSEGV, current);
21935 + return -EFAULT;
21936 }
21937
21938 /* Invoke a singal handler to, well, handle the signal. */
21939 -static inline void
21940 +static inline int
21941 handle_signal(int canrestart, unsigned long sig,
21942 siginfo_t *info, struct k_sigaction *ka,
21943 sigset_t *oldset, struct pt_regs * regs)
21944 {
21945 + int ret;
21946 +
21947 /* Check if this got called from a system call. */
21948 if (canrestart) {
21949 /* If so, check system call restarting. */
21950 @@ -561,19 +507,23 @@
21951
21952 /* Set up the stack frame. */
21953 if (ka->sa.sa_flags & SA_SIGINFO)
21954 - setup_rt_frame(sig, ka, info, oldset, regs);
21955 + ret = setup_rt_frame(sig, ka, info, oldset, regs);
21956 else
21957 - setup_frame(sig, ka, oldset, regs);
21958 + ret = setup_frame(sig, ka, oldset, regs);
21959
21960 if (ka->sa.sa_flags & SA_ONESHOT)
21961 ka->sa.sa_handler = SIG_DFL;
21962
21963 - spin_lock_irq(&current->sighand->siglock);
21964 - sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
21965 - if (!(ka->sa.sa_flags & SA_NODEFER))
21966 - sigaddset(&current->blocked,sig);
21967 - recalc_sigpending();
21968 - spin_unlock_irq(&current->sighand->siglock);
21969 + if (ret == 0) {
21970 + spin_lock_irq(&current->sighand->siglock);
21971 + sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
21972 + if (!(ka->sa.sa_flags & SA_NODEFER))
21973 + sigaddset(&current->blocked,sig);
21974 + recalc_sigpending();
21975 + spin_unlock_irq(&current->sighand->siglock);
21976 + }
21977 +
21978 + return ret;
21979 }
21980
21981 /*
21982 @@ -587,12 +537,13 @@
21983 * we can use user_mode(regs) to see if we came directly from kernel or user
21984 * mode below.
21985 */
21986 -int
21987 -do_signal(int canrestart, sigset_t *oldset, struct pt_regs *regs)
21988 +void
21989 +do_signal(int canrestart, struct pt_regs *regs)
21990 {
21991 int signr;
21992 siginfo_t info;
21993 struct k_sigaction ka;
21994 + sigset_t *oldset;
21995
21996 /*
21997 * The common case should go fast, which is why this point is
21998 @@ -600,17 +551,27 @@
21999 * without doing anything.
22000 */
22001 if (!user_mode(regs))
22002 - return 1;
22003 + return;
22004
22005 - if (!oldset)
22006 + if (test_thread_flag(TIF_RESTORE_SIGMASK))
22007 + oldset = &current->saved_sigmask;
22008 + else
22009 oldset = &current->blocked;
22010
22011 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
22012 -
22013 +
22014 if (signr > 0) {
22015 - /* Deliver the signal. */
22016 - handle_signal(canrestart, signr, &info, &ka, oldset, regs);
22017 - return 1;
22018 + /* Whee! Actually deliver the signal. */
22019 + if (handle_signal(canrestart, signr, &info, &ka, oldset, regs)) {
22020 + /* a signal was successfully delivered; the saved
22021 + * sigmask will have been stored in the signal frame,
22022 + * and will be restored by sigreturn, so we can simply
22023 + * clear the TIF_RESTORE_SIGMASK flag */
22024 + if (test_thread_flag(TIF_RESTORE_SIGMASK))
22025 + clear_thread_flag(TIF_RESTORE_SIGMASK);
22026 + }
22027 +
22028 + return;
22029 }
22030
22031 /* Got here from a system call? */
22032 @@ -621,14 +582,19 @@
22033 regs->r10 == -ERESTARTNOINTR) {
22034 RESTART_CRIS_SYS(regs);
22035 }
22036 -
22037 +
22038 if (regs->r10 == -ERESTART_RESTARTBLOCK){
22039 regs->r10 = __NR_restart_syscall;
22040 regs->erp -= 2;
22041 }
22042 }
22043 -
22044 - return 0;
22045 +
22046 + /* if there's no signal to deliver, we just put the saved sigmask
22047 + * back */
22048 + if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
22049 + clear_thread_flag(TIF_RESTORE_SIGMASK);
22050 + sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
22051 + }
22052 }
22053
22054 asmlinkage void
22055 @@ -651,7 +617,7 @@
22056 sys_kill(ti->task->pid, sig);
22057 }
22058
22059 -void
22060 +void
22061 keep_debug_flags(unsigned long oldccs, unsigned long oldspc,
22062 struct pt_regs *regs)
22063 {
22064 @@ -666,7 +632,7 @@
22065 regs->ccs |= (1 << (S_CCS_BITNR + CCS_SHIFT));
22066 /* Assume the SPC is valid and interesting. */
22067 regs->spc = oldspc;
22068 -
22069 +
22070 } else if (oldccs & (1 << (S_CCS_BITNR + CCS_SHIFT))) {
22071 /* If a h/w bp was set in the signal handler we need
22072 to keep the S flag. */
22073 @@ -679,7 +645,7 @@
22074 have forgotten all about it. */
22075 regs->spc = 0;
22076 regs->ccs &= ~(1 << (S_CCS_BITNR + CCS_SHIFT));
22077 - }
22078 + }
22079 }
22080
22081 /* Set up the trampolines on the signal return page. */
22082 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/kernel/smp.c linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/smp.c
22083 --- linux-2.6.19.2.old/arch/cris/arch-v32/kernel/smp.c 2007-01-10 20:10:37.000000000 +0100
22084 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/smp.c 2007-01-09 10:29:19.000000000 +0100
22085 @@ -20,6 +20,7 @@
22086 #define IPI_SCHEDULE 1
22087 #define IPI_CALL 2
22088 #define IPI_FLUSH_TLB 4
22089 +#define IPI_BOOT 8
22090
22091 #define FLUSH_ALL (void*)0xffffffff
22092
22093 @@ -30,6 +31,8 @@
22094 cpumask_t cpu_online_map = CPU_MASK_NONE;
22095 EXPORT_SYMBOL(cpu_online_map);
22096 cpumask_t phys_cpu_present_map = CPU_MASK_NONE;
22097 +cpumask_t cpu_possible_map;
22098 +EXPORT_SYMBOL(cpu_possible_map);
22099 EXPORT_SYMBOL(phys_cpu_present_map);
22100
22101 /* Variables used during SMP boot */
22102 @@ -55,7 +58,7 @@
22103 extern int setup_irq(int, struct irqaction *);
22104
22105 /* Mode registers */
22106 -static unsigned long irq_regs[NR_CPUS] =
22107 +static unsigned long irq_regs[NR_CPUS] =
22108 {
22109 regi_irq,
22110 regi_irq2
22111 @@ -97,6 +100,7 @@
22112
22113 cpu_set(0, cpu_online_map);
22114 cpu_set(0, phys_cpu_present_map);
22115 + cpu_set(0, cpu_possible_map);
22116 }
22117
22118 void __init smp_cpus_done(unsigned int max_cpus)
22119 @@ -109,6 +113,7 @@
22120 {
22121 unsigned timeout;
22122 struct task_struct *idle;
22123 + cpumask_t cpu_mask = CPU_MASK_NONE;
22124
22125 idle = fork_idle(cpuid);
22126 if (IS_ERR(idle))
22127 @@ -120,6 +125,12 @@
22128 smp_init_current_idle_thread = task_thread_info(idle);
22129 cpu_now_booting = cpuid;
22130
22131 + /* Kick it */
22132 + cpu_set(cpuid, cpu_online_map);
22133 + cpu_set(cpuid, cpu_mask);
22134 + send_ipi(IPI_BOOT, 0, cpu_mask);
22135 + cpu_clear(cpuid, cpu_online_map);
22136 +
22137 /* Wait for CPU to come online */
22138 for (timeout = 0; timeout < 10000; timeout++) {
22139 if(cpu_online(cpuid)) {
22140 @@ -142,7 +153,7 @@
22141 * specific stuff such as the local timer and the MMU. */
22142 void __init smp_callin(void)
22143 {
22144 - extern void cpu_idle(void);
22145 + extern void cpu_idle(void);
22146
22147 int cpu = cpu_now_booting;
22148 reg_intr_vect_rw_mask vect_mask = {0};
22149 @@ -190,8 +201,8 @@
22150
22151 /* cache_decay_ticks is used by the scheduler to decide if a process
22152 * is "hot" on one CPU. A higher value means a higher penalty to move
22153 - * a process to another CPU. Our cache is rather small so we report
22154 - * 1 tick.
22155 + * a process to another CPU. Our cache is rather small so we report
22156 + * 1 tick.
22157 */
22158 unsigned long cache_decay_ticks = 1;
22159
22160 @@ -205,14 +216,14 @@
22161 {
22162 cpumask_t cpu_mask = CPU_MASK_NONE;
22163 cpu_set(cpu, cpu_mask);
22164 - send_ipi(IPI_SCHEDULE, 0, cpu_mask);
22165 + send_ipi(IPI_SCHEDULE, 0, cpu_mask);
22166 }
22167
22168 /* TLB flushing
22169 *
22170 * Flush needs to be done on the local CPU and on any other CPU that
22171 * may have the same mapping. The mm->cpu_vm_mask is used to keep track
22172 - * of which CPUs that a specific process has been executed on.
22173 + * of which CPUs that a specific process has been executed on.
22174 */
22175 void flush_tlb_common(struct mm_struct* mm, struct vm_area_struct* vma, unsigned long addr)
22176 {
22177 @@ -244,7 +255,7 @@
22178 cpu_set(smp_processor_id(), mm->cpu_vm_mask);
22179 }
22180
22181 -void flush_tlb_page(struct vm_area_struct *vma,
22182 +void flush_tlb_page(struct vm_area_struct *vma,
22183 unsigned long addr)
22184 {
22185 __flush_tlb_page(vma, addr);
22186 @@ -252,8 +263,8 @@
22187 }
22188
22189 /* Inter processor interrupts
22190 - *
22191 - * The IPIs are used for:
22192 + *
22193 + * The IPIs are used for:
22194 * * Force a schedule on a CPU
22195 * * FLush TLB on other CPUs
22196 * * Call a function on other CPUs
22197 @@ -341,7 +352,7 @@
22198 else if (flush_vma == FLUSH_ALL)
22199 __flush_tlb_mm(flush_mm);
22200 else
22201 - __flush_tlb_page(flush_vma, flush_addr);
22202 + __flush_tlb_page(flush_vma, flush_addr);
22203 }
22204
22205 ipi.vector = 0;
22206 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/kernel/time.c linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/time.c
22207 --- linux-2.6.19.2.old/arch/cris/arch-v32/kernel/time.c 2007-01-10 20:10:37.000000000 +0100
22208 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/time.c 2007-01-09 10:29:19.000000000 +0100
22209 @@ -1,4 +1,4 @@
22210 -/* $Id: time.c,v 1.19 2005/04/29 05:40:09 starvik Exp $
22211 +/* $Id: time.c,v 1.25 2007/01/09 09:29:19 starvik Exp $
22212 *
22213 * linux/arch/cris/arch-v32/kernel/time.c
22214 *
22215 @@ -14,12 +14,14 @@
22216 #include <linux/sched.h>
22217 #include <linux/init.h>
22218 #include <linux/threads.h>
22219 +#include <linux/cpufreq.h>
22220 #include <asm/types.h>
22221 #include <asm/signal.h>
22222 #include <asm/io.h>
22223 #include <asm/delay.h>
22224 #include <asm/rtc.h>
22225 #include <asm/irq.h>
22226 +#include <asm/irq_regs.h>
22227
22228 #include <asm/arch/hwregs/reg_map.h>
22229 #include <asm/arch/hwregs/reg_rdwr.h>
22230 @@ -31,7 +33,7 @@
22231 #define ETRAX_WD_HZ 763 /* watchdog counts at 763 Hz */
22232 #define ETRAX_WD_CNT ((2*ETRAX_WD_HZ)/HZ + 1) /* Number of 763 counts before watchdog bites */
22233
22234 -unsigned long timer_regs[NR_CPUS] =
22235 +unsigned long timer_regs[NR_CPUS] =
22236 {
22237 regi_timer,
22238 #ifdef CONFIG_SMP
22239 @@ -44,6 +46,15 @@
22240 extern int setup_irq(int, struct irqaction *);
22241 extern int have_rtc;
22242
22243 +#ifdef CONFIG_CPU_FREQ
22244 +static int
22245 +cris_time_freq_notifier(struct notifier_block *nb, unsigned long val, void *data);
22246 +
22247 +static struct notifier_block cris_time_freq_notifier_block = {
22248 + .notifier_call = cris_time_freq_notifier
22249 +};
22250 +#endif
22251 +
22252 unsigned long get_ns_in_jiffie(void)
22253 {
22254 reg_timer_r_tmr0_data data;
22255 @@ -63,7 +74,7 @@
22256 static unsigned long jiffies_p = 0;
22257
22258 /*
22259 - * cache volatile jiffies temporarily; we have IRQs turned off.
22260 + * cache volatile jiffies temporarily; we have IRQs turned off.
22261 */
22262 unsigned long jiffies_t;
22263
22264 @@ -82,7 +93,7 @@
22265 */
22266 if( jiffies_t == jiffies_p ) {
22267 if( count > count_p ) {
22268 - /* Timer wrapped, use new count and prescale
22269 + /* Timer wrapped, use new count and prescale
22270 * increase the time corresponding to one jiffie
22271 */
22272 usec_count = 1000000/HZ;
22273 @@ -101,7 +112,7 @@
22274 * The watchdog timer is an 8-bit timer with a configurable start value.
22275 * Once started the whatchdog counts downwards with a frequency of 763 Hz
22276 * (100/131072 MHz). When the watchdog counts down to 1, it generates an
22277 - * NMI (Non Maskable Interrupt), and when it counts down to 0, it resets the
22278 + * NMI (Non Maskable Interrupt), and when it counts down to 0, it resets the
22279 * chip.
22280 */
22281 /* This gives us 1.3 ms to do something useful when the NMI comes */
22282 @@ -124,7 +135,7 @@
22283 {
22284 #if defined(CONFIG_ETRAX_WATCHDOG)
22285 reg_timer_rw_wd_ctrl wd_ctrl = { 0 };
22286 -
22287 +
22288 /* only keep watchdog happy as long as we have memory left! */
22289 if(nr_free_pages() > WATCHDOG_MIN_FREE_PAGES) {
22290 /* reset the watchdog with the inverse of the old key */
22291 @@ -139,7 +150,7 @@
22292
22293 /* stop the watchdog - we still need the correct key */
22294
22295 -void
22296 +void
22297 stop_watchdog(void)
22298 {
22299 #if defined(CONFIG_ETRAX_WATCHDOG)
22300 @@ -149,7 +160,7 @@
22301 wd_ctrl.cmd = regk_timer_stop;
22302 wd_ctrl.key = watchdog_key;
22303 REG_WR(timer, regi_timer, rw_wd_ctrl, wd_ctrl);
22304 -#endif
22305 +#endif
22306 }
22307
22308 extern void show_registers(struct pt_regs *regs);
22309 @@ -160,7 +171,8 @@
22310 #if defined(CONFIG_ETRAX_WATCHDOG)
22311 extern int cause_of_death;
22312
22313 - raw_printk("Watchdog bite\n");
22314 + oops_in_progress = 1;
22315 + printk("Watchdog bite\n");
22316
22317 /* Check if forced restart or unexpected watchdog */
22318 if (cause_of_death == 0xbedead) {
22319 @@ -169,8 +181,9 @@
22320
22321 /* Unexpected watchdog, stop the watchdog and dump registers*/
22322 stop_watchdog();
22323 - raw_printk("Oops: bitten by watchdog\n");
22324 - show_registers(regs);
22325 + printk("Oops: bitten by watchdog\n");
22326 + show_registers(regs);
22327 + oops_in_progress = 0;
22328 #ifndef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY
22329 reset_watchdog();
22330 #endif
22331 @@ -191,8 +204,9 @@
22332 extern void cris_do_profile(struct pt_regs *regs);
22333
22334 static inline irqreturn_t
22335 -timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
22336 +timer_interrupt(int irq, void *dev_id)
22337 {
22338 + struct pt_regs* regs = get_irq_regs();
22339 int cpu = smp_processor_id();
22340 reg_timer_r_masked_intr masked_intr;
22341 reg_timer_rw_ack_intr ack_intr = { 0 };
22342 @@ -226,7 +240,7 @@
22343 * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
22344 * called as close as possible to 500 ms before the new second starts.
22345 *
22346 - * The division here is not time critical since it will run once in
22347 + * The division here is not time critical since it will run once in
22348 * 11 minutes
22349 */
22350 if ((time_status & STA_UNSYNC) == 0 &&
22351 @@ -246,7 +260,7 @@
22352 */
22353
22354 static struct irqaction irq_timer = {
22355 - .mask = timer_interrupt,
22356 + .handler = timer_interrupt,
22357 .flags = IRQF_SHARED | IRQF_DISABLED,
22358 .mask = CPU_MASK_NONE,
22359 .name = "timer"
22360 @@ -262,7 +276,7 @@
22361
22362 /* Setup the etrax timers
22363 * Base frequency is 100MHz, divider 1000000 -> 100 HZ
22364 - * We use timer0, so timer1 is free.
22365 + * We use timer0, so timer1 is free.
22366 * The trig timer is used by the fasttimer API if enabled.
22367 */
22368
22369 @@ -284,11 +298,11 @@
22370 {
22371 reg_intr_vect_rw_mask intr_mask;
22372
22373 - /* probe for the RTC and read it if it exists
22374 - * Before the RTC can be probed the loops_per_usec variable needs
22375 - * to be initialized to make usleep work. A better value for
22376 - * loops_per_usec is calculated by the kernel later once the
22377 - * clock has started.
22378 + /* probe for the RTC and read it if it exists
22379 + * Before the RTC can be probed the loops_per_usec variable needs
22380 + * to be initialized to make usleep work. A better value for
22381 + * loops_per_usec is calculated by the kernel later once the
22382 + * clock has started.
22383 */
22384 loops_per_usec = 50;
22385
22386 @@ -297,7 +311,7 @@
22387 xtime.tv_sec = 0;
22388 xtime.tv_nsec = 0;
22389 have_rtc = 0;
22390 - } else {
22391 + } else {
22392 /* get the current time */
22393 have_rtc = 1;
22394 update_xtime_from_cmos();
22395 @@ -316,9 +330,9 @@
22396 intr_mask = REG_RD(intr_vect, regi_irq, rw_mask);
22397 intr_mask.timer = 1;
22398 REG_WR(intr_vect, regi_irq, rw_mask, intr_mask);
22399 -
22400 +
22401 /* now actually register the timer irq handler that calls timer_interrupt() */
22402 -
22403 +
22404 setup_irq(TIMER_INTR_VECT, &irq_timer);
22405
22406 /* enable watchdog if we should use one */
22407 @@ -330,10 +344,7 @@
22408 /* If we use the hardware watchdog, we want to trap it as an NMI
22409 and dump registers before it resets us. For this to happen, we
22410 must set the "m" NMI enable flag (which once set, is unset only
22411 - when an NMI is taken).
22412 -
22413 - The same goes for the external NMI, but that doesn't have any
22414 - driver or infrastructure support yet. */
22415 + when an NMI is taken). */
22416 {
22417 unsigned long flags;
22418 local_save_flags(flags);
22419 @@ -341,4 +352,27 @@
22420 local_irq_restore(flags);
22421 }
22422 #endif
22423 +
22424 +#ifdef CONFIG_CPU_FREQ
22425 + cpufreq_register_notifier(&cris_time_freq_notifier_block,
22426 + CPUFREQ_TRANSITION_NOTIFIER);
22427 +#endif
22428 +}
22429 +
22430 +#ifdef CONFIG_CPU_FREQ
22431 +static int
22432 +cris_time_freq_notifier(struct notifier_block *nb, unsigned long val, void *data)
22433 +{
22434 + struct cpufreq_freqs *freqs = data;
22435 + if (val == CPUFREQ_POSTCHANGE) {
22436 + reg_timer_r_tmr0_data data;
22437 + reg_timer_rw_tmr0_div div = (freqs->new * 500) / HZ;
22438 + do
22439 + {
22440 + data = REG_RD(timer, timer_regs[freqs->cpu], r_tmr0_data);
22441 + } while (data > 20);
22442 + REG_WR(timer, timer_regs[freqs->cpu], rw_tmr0_div, div);
22443 + }
22444 + return 0;
22445 }
22446 +#endif
22447 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/kernel/traps.c linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/traps.c
22448 --- linux-2.6.19.2.old/arch/cris/arch-v32/kernel/traps.c 2007-01-10 20:10:37.000000000 +0100
22449 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/traps.c 2006-12-11 14:04:24.000000000 +0100
22450 @@ -1,50 +1,43 @@
22451 /*
22452 - * Copyright (C) 2003, Axis Communications AB.
22453 + * Copyright (C) 2003-2006, Axis Communications AB.
22454 */
22455
22456 #include <linux/ptrace.h>
22457 #include <asm/uaccess.h>
22458 -
22459 #include <asm/arch/hwregs/supp_reg.h>
22460 -
22461 -extern void reset_watchdog(void);
22462 -extern void stop_watchdog(void);
22463 -
22464 -extern int raw_printk(const char *fmt, ...);
22465 +#include <asm/arch/hwregs/intr_vect_defs.h>
22466
22467 void
22468 show_registers(struct pt_regs *regs)
22469 {
22470 /*
22471 * It's possible to use either the USP register or current->thread.usp.
22472 - * USP might not correspond to the current proccess for all cases this
22473 + * USP might not correspond to the current process for all cases this
22474 * function is called, and current->thread.usp isn't up to date for the
22475 - * current proccess. Experience shows that using USP is the way to go.
22476 + * current process. Experience shows that using USP is the way to go.
22477 */
22478 - unsigned long usp;
22479 + unsigned long usp = rdusp();
22480 unsigned long d_mmu_cause;
22481 unsigned long i_mmu_cause;
22482
22483 - usp = rdusp();
22484 + printk("CPU: %d\n", smp_processor_id());
22485
22486 - raw_printk("CPU: %d\n", smp_processor_id());
22487 + printk("ERP: %08lx SRP: %08lx CCS: %08lx USP: %08lx MOF: %08lx\n",
22488 + regs->erp, regs->srp, regs->ccs, usp, regs->mof);
22489
22490 - raw_printk("ERP: %08lx SRP: %08lx CCS: %08lx USP: %08lx MOF: %08lx\n",
22491 - regs->erp, regs->srp, regs->ccs, usp, regs->mof);
22492 + printk(" r0: %08lx r1: %08lx r2: %08lx r3: %08lx\n",
22493 + regs->r0, regs->r1, regs->r2, regs->r3);
22494
22495 - raw_printk(" r0: %08lx r1: %08lx r2: %08lx r3: %08lx\n",
22496 - regs->r0, regs->r1, regs->r2, regs->r3);
22497 + printk(" r4: %08lx r5: %08lx r6: %08lx r7: %08lx\n",
22498 + regs->r4, regs->r5, regs->r6, regs->r7);
22499
22500 - raw_printk(" r4: %08lx r5: %08lx r6: %08lx r7: %08lx\n",
22501 - regs->r4, regs->r5, regs->r6, regs->r7);
22502 + printk(" r8: %08lx r9: %08lx r10: %08lx r11: %08lx\n",
22503 + regs->r8, regs->r9, regs->r10, regs->r11);
22504
22505 - raw_printk(" r8: %08lx r9: %08lx r10: %08lx r11: %08lx\n",
22506 - regs->r8, regs->r9, regs->r10, regs->r11);
22507 + printk("r12: %08lx r13: %08lx oR10: %08lx acr: %08lx\n",
22508 + regs->r12, regs->r13, regs->orig_r10, regs->acr);
22509
22510 - raw_printk("r12: %08lx r13: %08lx oR10: %08lx acr: %08lx\n",
22511 - regs->r12, regs->r13, regs->orig_r10, regs->acr);
22512 -
22513 - raw_printk("sp: %08lx\n", regs);
22514 + printk(" sp: %08lx\n", (unsigned long)regs);
22515
22516 SUPP_BANK_SEL(BANK_IM);
22517 SUPP_REG_RD(RW_MM_CAUSE, i_mmu_cause);
22518 @@ -52,18 +45,20 @@
22519 SUPP_BANK_SEL(BANK_DM);
22520 SUPP_REG_RD(RW_MM_CAUSE, d_mmu_cause);
22521
22522 - raw_printk(" Data MMU Cause: %08lx\n", d_mmu_cause);
22523 - raw_printk("Instruction MMU Cause: %08lx\n", i_mmu_cause);
22524 + printk(" Data MMU Cause: %08lx\n", d_mmu_cause);
22525 + printk("Instruction MMU Cause: %08lx\n", i_mmu_cause);
22526
22527 - raw_printk("Process %s (pid: %d, stackpage: %08lx)\n",
22528 - current->comm, current->pid, (unsigned long) current);
22529 + printk("Process %s (pid: %d, stackpage=%08lx)\n",
22530 + current->comm, current->pid, (unsigned long)current);
22531
22532 - /* Show additional info if in kernel-mode. */
22533 + /*
22534 + * When in-kernel, we also print out the stack and code at the
22535 + * time of the fault..
22536 + */
22537 if (!user_mode(regs)) {
22538 int i;
22539 - unsigned char c;
22540
22541 - show_stack(NULL, (unsigned long *) usp);
22542 + show_stack(NULL, (unsigned long *)usp);
22543
22544 /*
22545 * If the previous stack-dump wasn't a kernel one, dump the
22546 @@ -72,7 +67,7 @@
22547 if (usp != 0)
22548 show_stack(NULL, NULL);
22549
22550 - raw_printk("\nCode: ");
22551 + printk("\nCode: ");
22552
22553 if (regs->erp < PAGE_OFFSET)
22554 goto bad_value;
22555 @@ -84,76 +79,65 @@
22556 * instruction decoding should be in sync at the interesting
22557 * point, but small enough to fit on a row. The regs->erp
22558 * location is pointed out in a ksymoops-friendly way by
22559 - * wrapping the byte for that address in parenthesis.
22560 + * wrapping the byte for that address in parenthesises.
22561 */
22562 for (i = -12; i < 12; i++) {
22563 - if (__get_user(c, &((unsigned char *) regs->erp)[i])) {
22564 + unsigned char c;
22565 +
22566 + if (__get_user(c, &((unsigned char *)regs->erp)[i])) {
22567 bad_value:
22568 - raw_printk(" Bad IP value.");
22569 + printk(" Bad IP value.");
22570 break;
22571 }
22572
22573 if (i == 0)
22574 - raw_printk("(%02x) ", c);
22575 + printk("(%02x) ", c);
22576 else
22577 - raw_printk("%02x ", c);
22578 + printk("%02x ", c);
22579 }
22580 -
22581 - raw_printk("\n");
22582 + printk("\n");
22583 }
22584 }
22585
22586 -/*
22587 - * This gets called from entry.S when the watchdog has bitten. Show something
22588 - * similiar to an Oops dump, and if the kernel if configured to be a nice doggy;
22589 - * halt instead of reboot.
22590 - */
22591 void
22592 -watchdog_bite_hook(struct pt_regs *regs)
22593 +arch_enable_nmi(void)
22594 {
22595 -#ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY
22596 - local_irq_disable();
22597 - stop_watchdog();
22598 - show_registers(regs);
22599 -
22600 - while (1)
22601 - ; /* Do nothing. */
22602 -#else
22603 - show_registers(regs);
22604 -#endif
22605 + unsigned long flags;
22606 +
22607 + local_save_flags(flags);
22608 + flags |= (1 << 30); /* NMI M flag is at bit 30 */
22609 + local_irq_restore(flags);
22610 }
22611
22612 -/* This is normally the Oops function. */
22613 -void
22614 -die_if_kernel(const char *str, struct pt_regs *regs, long err)
22615 +extern void (*nmi_handler)(struct pt_regs*);
22616 +void handle_nmi(struct pt_regs* regs)
22617 {
22618 - if (user_mode(regs))
22619 - return;
22620 + reg_intr_vect_r_nmi r;
22621
22622 -#ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY
22623 - /*
22624 - * This printout might take too long and could trigger
22625 - * the watchdog normally. If NICE_DOGGY is set, simply
22626 - * stop the watchdog during the printout.
22627 - */
22628 - stop_watchdog();
22629 -#endif
22630 -
22631 - raw_printk("%s: %04lx\n", str, err & 0xffff);
22632 + if (nmi_handler)
22633 + nmi_handler(regs);
22634
22635 - show_registers(regs);
22636 -
22637 -#ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY
22638 - reset_watchdog();
22639 -#endif
22640 -
22641 - do_exit(SIGSEGV);
22642 + /* Wait until nmi is no longer active. */
22643 + do {
22644 + r = REG_RD(intr_vect, regi_irq, r_nmi);
22645 + } while (r.ext == regk_intr_vect_on);
22646 }
22647
22648 -void arch_enable_nmi(void)
22649 +#ifdef CONFIG_DEBUG_BUGVERBOSE
22650 +void
22651 +handle_BUG(struct pt_regs *regs)
22652 {
22653 - unsigned long flags;
22654 - local_save_flags(flags);
22655 - flags |= (1<<30); /* NMI M flag is at bit 30 */
22656 - local_irq_restore(flags);
22657 + struct bug_frame f;
22658 + unsigned char c;
22659 + unsigned long erp = regs->erp;
22660 +
22661 + if (__copy_from_user(&f, (const void __user *)(erp - 8), sizeof f))
22662 + return;
22663 + if (f.prefix != BUG_PREFIX || f.magic != BUG_MAGIC)
22664 + return;
22665 + if (__get_user(c, f.filename))
22666 + f.filename = "<bad filename>";
22667 +
22668 + printk("kernel BUG at %s:%d!\n", f.filename, f.line);
22669 }
22670 +#endif
22671 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/kernel/vcs_hook.c linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/vcs_hook.c
22672 --- linux-2.6.19.2.old/arch/cris/arch-v32/kernel/vcs_hook.c 2007-01-10 20:10:37.000000000 +0100
22673 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/vcs_hook.c 1970-01-01 01:00:00.000000000 +0100
22674 @@ -1,96 +0,0 @@
22675 -// $Id: vcs_hook.c,v 1.2 2003/08/12 12:01:06 starvik Exp $
22676 -//
22677 -// Call simulator hook. This is the part running in the
22678 -// simulated program.
22679 -//
22680 -
22681 -#include "vcs_hook.h"
22682 -#include <stdarg.h>
22683 -#include <asm/arch-v32/hwregs/reg_map.h>
22684 -#include <asm/arch-v32/hwregs/intr_vect_defs.h>
22685 -
22686 -#define HOOK_TRIG_ADDR 0xb7000000 /* hook cvlog model reg address */
22687 -#define HOOK_MEM_BASE_ADDR 0xa0000000 /* csp4 (shared mem) base addr */
22688 -
22689 -#define HOOK_DATA(offset) ((unsigned*) HOOK_MEM_BASE_ADDR)[offset]
22690 -#define VHOOK_DATA(offset) ((volatile unsigned*) HOOK_MEM_BASE_ADDR)[offset]
22691 -#define HOOK_TRIG(funcid) do { *((unsigned *) HOOK_TRIG_ADDR) = funcid; } while(0)
22692 -#define HOOK_DATA_BYTE(offset) ((unsigned char*) HOOK_MEM_BASE_ADDR)[offset]
22693 -
22694 -
22695 -// ------------------------------------------------------------------ hook_call
22696 -int hook_call( unsigned id, unsigned pcnt, ...) {
22697 - va_list ap;
22698 - unsigned i;
22699 - unsigned ret;
22700 -#ifdef USING_SOS
22701 - PREEMPT_OFF_SAVE();
22702 -#endif
22703 -
22704 - // pass parameters
22705 - HOOK_DATA(0) = id;
22706 -
22707 - /* Have to make hook_print_str a special case since we call with a
22708 - parameter of byte type. Should perhaps be a separate
22709 - hook_call. */
22710 -
22711 - if (id == hook_print_str) {
22712 - int i;
22713 - char *str;
22714 -
22715 - HOOK_DATA(1) = pcnt;
22716 -
22717 - va_start(ap, pcnt);
22718 - str = (char*)va_arg(ap,unsigned);
22719 -
22720 - for (i=0; i!=pcnt; i++) {
22721 - HOOK_DATA_BYTE(8+i) = str[i];
22722 - }
22723 - HOOK_DATA_BYTE(8+i) = 0; /* null byte */
22724 - }
22725 - else {
22726 - va_start(ap, pcnt);
22727 - for( i = 1; i <= pcnt; i++ ) HOOK_DATA(i) = va_arg(ap,unsigned);
22728 - va_end(ap);
22729 - }
22730 -
22731 - // read from mem to make sure data has propagated to memory before trigging
22732 - *((volatile unsigned*) HOOK_MEM_BASE_ADDR);
22733 -
22734 - // trigger hook
22735 - HOOK_TRIG(id);
22736 -
22737 - // wait for call to finish
22738 - while( VHOOK_DATA(0) > 0 ) {}
22739 -
22740 - // extract return value
22741 -
22742 - ret = VHOOK_DATA(1);
22743 -
22744 -#ifdef USING_SOS
22745 - PREEMPT_RESTORE();
22746 -#endif
22747 - return ret;
22748 -}
22749 -
22750 -unsigned
22751 -hook_buf(unsigned i)
22752 -{
22753 - return (HOOK_DATA(i));
22754 -}
22755 -
22756 -void print_str( const char *str ) {
22757 - int i;
22758 - for (i=1; str[i]; i++); /* find null at end of string */
22759 - hook_call(hook_print_str, i, str);
22760 -}
22761 -
22762 -// --------------------------------------------------------------- CPU_KICK_DOG
22763 -void CPU_KICK_DOG(void) {
22764 - (void) hook_call( hook_kick_dog, 0 );
22765 -}
22766 -
22767 -// ------------------------------------------------------- CPU_WATCHDOG_TIMEOUT
22768 -void CPU_WATCHDOG_TIMEOUT( unsigned t ) {
22769 - (void) hook_call( hook_dog_timeout, 1, t );
22770 -}
22771 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/kernel/vcs_hook.h linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/vcs_hook.h
22772 --- linux-2.6.19.2.old/arch/cris/arch-v32/kernel/vcs_hook.h 2007-01-10 20:10:37.000000000 +0100
22773 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/kernel/vcs_hook.h 1970-01-01 01:00:00.000000000 +0100
22774 @@ -1,42 +0,0 @@
22775 -// $Id: vcs_hook.h,v 1.1 2003/08/12 12:01:06 starvik Exp $
22776 -//
22777 -// Call simulator hook functions
22778 -
22779 -#ifndef HOOK_H
22780 -#define HOOK_H
22781 -
22782 -int hook_call( unsigned id, unsigned pcnt, ...);
22783 -
22784 -enum hook_ids {
22785 - hook_debug_on = 1,
22786 - hook_debug_off,
22787 - hook_stop_sim_ok,
22788 - hook_stop_sim_fail,
22789 - hook_alloc_shared,
22790 - hook_ptr_shared,
22791 - hook_free_shared,
22792 - hook_file2shared,
22793 - hook_cmp_shared,
22794 - hook_print_params,
22795 - hook_sim_time,
22796 - hook_stop_sim,
22797 - hook_kick_dog,
22798 - hook_dog_timeout,
22799 - hook_rand,
22800 - hook_srand,
22801 - hook_rand_range,
22802 - hook_print_str,
22803 - hook_print_hex,
22804 - hook_cmp_offset_shared,
22805 - hook_fill_random_shared,
22806 - hook_alloc_random_data,
22807 - hook_calloc_random_data,
22808 - hook_print_int,
22809 - hook_print_uint,
22810 - hook_fputc,
22811 - hook_init_fd,
22812 - hook_sbrk
22813 -
22814 -};
22815 -
22816 -#endif
22817 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/lib/Makefile linux-2.6.19.2.dev/arch/cris/arch-v32/lib/Makefile
22818 --- linux-2.6.19.2.old/arch/cris/arch-v32/lib/Makefile 2007-01-10 20:10:37.000000000 +0100
22819 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/lib/Makefile 2006-10-11 19:29:20.000000000 +0200
22820 @@ -2,5 +2,5 @@
22821 # Makefile for Etrax-specific library files..
22822 #
22823
22824 -lib-y = checksum.o checksumcopy.o string.o usercopy.o memset.o csumcpfruser.o spinlock.o
22825 +lib-y = checksum.o checksumcopy.o string.o usercopy.o memset.o csumcpfruser.o spinlock.o delay.o
22826
22827 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/lib/checksum.S linux-2.6.19.2.dev/arch/cris/arch-v32/lib/checksum.S
22828 --- linux-2.6.19.2.old/arch/cris/arch-v32/lib/checksum.S 2007-01-10 20:10:37.000000000 +0100
22829 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/lib/checksum.S 2005-08-15 15:53:12.000000000 +0200
22830 @@ -7,15 +7,15 @@
22831
22832 .globl csum_partial
22833 csum_partial:
22834 -
22835 +
22836 ;; r10 - src
22837 ;; r11 - length
22838 ;; r12 - checksum
22839
22840 ;; check for breakeven length between movem and normal word looping versions
22841 - ;; we also do _NOT_ want to compute a checksum over more than the
22842 + ;; we also do _NOT_ want to compute a checksum over more than the
22843 ;; actual length when length < 40
22844 -
22845 +
22846 cmpu.w 80,$r11
22847 blo _word_loop
22848 nop
22849 @@ -24,17 +24,17 @@
22850 ;; this overhead is why we have a check above for breakeven length
22851 ;; only r0 - r8 have to be saved, the other ones are clobber-able
22852 ;; according to the ABI
22853 -
22854 +
22855 subq 9*4,$sp
22856 subq 10*4,$r11 ; update length for the first loop
22857 movem $r8,[$sp]
22858 -
22859 +
22860 ;; do a movem checksum
22861
22862 _mloop: movem [$r10+],$r9 ; read 10 longwords
22863
22864 ;; perform dword checksumming on the 10 longwords
22865 -
22866 +
22867 add.d $r0,$r12
22868 addc $r1,$r12
22869 addc $r2,$r12
22870 @@ -48,9 +48,8 @@
22871
22872 ;; fold the carry into the checksum, to avoid having to loop the carry
22873 ;; back into the top
22874 -
22875 +
22876 addc 0,$r12
22877 - addc 0,$r12 ; do it again, since we might have generated a carry
22878
22879 subq 10*4,$r11
22880 bge _mloop
22881 @@ -68,34 +67,30 @@
22882
22883 ;; fold 32-bit checksum into a 16-bit checksum, to avoid carries below.
22884 ;; r9 and r13 can be used as temporaries.
22885 -
22886 +
22887 moveq -1,$r9 ; put 0xffff in r9, faster than move.d 0xffff,r9
22888 lsrq 16,$r9
22889 -
22890 +
22891 move.d $r12,$r13
22892 lsrq 16,$r13 ; r13 = checksum >> 16
22893 and.d $r9,$r12 ; checksum = checksum & 0xffff
22894 add.d $r13,$r12 ; checksum += r13
22895 - move.d $r12,$r13 ; do the same again, maybe we got a carry last add
22896 - lsrq 16,$r13
22897 - and.d $r9,$r12
22898 - add.d $r13,$r12
22899
22900 _no_fold:
22901 cmpq 2,$r11
22902 blt _no_words
22903 nop
22904 -
22905 +
22906 ;; checksum the rest of the words
22907 -
22908 +
22909 subq 2,$r11
22910 -
22911 +
22912 _wloop: subq 2,$r11
22913 bge _wloop
22914 addu.w [$r10+],$r12
22915 -
22916 +
22917 addq 2,$r11
22918 -
22919 +
22920 _no_words:
22921 ;; see if we have one odd byte more
22922 cmpq 1,$r11
22923 @@ -104,7 +99,7 @@
22924 ret
22925 move.d $r12,$r10
22926
22927 -_do_byte:
22928 +_do_byte:
22929 ;; copy and checksum the last byte
22930 addu.b [$r10],$r12
22931 ret
22932 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/lib/checksumcopy.S linux-2.6.19.2.dev/arch/cris/arch-v32/lib/checksumcopy.S
22933 --- linux-2.6.19.2.old/arch/cris/arch-v32/lib/checksumcopy.S 2007-01-10 20:10:37.000000000 +0100
22934 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/lib/checksumcopy.S 2005-08-15 15:53:12.000000000 +0200
22935 @@ -3,23 +3,23 @@
22936 * Copyright (c) 1998, 2001, 2003 Axis Communications AB
22937 *
22938 * Authors: Bjorn Wesen
22939 - *
22940 + *
22941 * csum_partial_copy_nocheck(const char *src, char *dst,
22942 * int len, unsigned int sum)
22943 */
22944
22945 .globl csum_partial_copy_nocheck
22946 -csum_partial_copy_nocheck:
22947 -
22948 +csum_partial_copy_nocheck:
22949 +
22950 ;; r10 - src
22951 ;; r11 - dst
22952 ;; r12 - length
22953 ;; r13 - checksum
22954
22955 ;; check for breakeven length between movem and normal word looping versions
22956 - ;; we also do _NOT_ want to compute a checksum over more than the
22957 + ;; we also do _NOT_ want to compute a checksum over more than the
22958 ;; actual length when length < 40
22959 -
22960 +
22961 cmpu.w 80,$r12
22962 blo _word_loop
22963 nop
22964 @@ -28,19 +28,19 @@
22965 ;; this overhead is why we have a check above for breakeven length
22966 ;; only r0 - r8 have to be saved, the other ones are clobber-able
22967 ;; according to the ABI
22968 -
22969 +
22970 subq 9*4,$sp
22971 subq 10*4,$r12 ; update length for the first loop
22972 movem $r8,[$sp]
22973 -
22974 +
22975 ;; do a movem copy and checksum
22976 -
22977 +
22978 1: ;; A failing userspace access (the read) will have this as PC.
22979 _mloop: movem [$r10+],$r9 ; read 10 longwords
22980 movem $r9,[$r11+] ; write 10 longwords
22981
22982 ;; perform dword checksumming on the 10 longwords
22983 -
22984 +
22985 add.d $r0,$r13
22986 addc $r1,$r13
22987 addc $r2,$r13
22988 @@ -54,9 +54,8 @@
22989
22990 ;; fold the carry into the checksum, to avoid having to loop the carry
22991 ;; back into the top
22992 -
22993 +
22994 addc 0,$r13
22995 - addc 0,$r13 ; do it again, since we might have generated a carry
22996
22997 subq 10*4,$r12
22998 bge _mloop
22999 @@ -74,34 +73,30 @@
23000
23001 ;; fold 32-bit checksum into a 16-bit checksum, to avoid carries below
23002 ;; r9 can be used as temporary.
23003 -
23004 +
23005 move.d $r13,$r9
23006 lsrq 16,$r9 ; r0 = checksum >> 16
23007 and.d 0xffff,$r13 ; checksum = checksum & 0xffff
23008 add.d $r9,$r13 ; checksum += r0
23009 - move.d $r13,$r9 ; do the same again, maybe we got a carry last add
23010 - lsrq 16,$r9
23011 - and.d 0xffff,$r13
23012 - add.d $r9,$r13
23013 -
23014 +
23015 _no_fold:
23016 cmpq 2,$r12
23017 blt _no_words
23018 nop
23019 -
23020 +
23021 ;; copy and checksum the rest of the words
23022 -
23023 +
23024 subq 2,$r12
23025 -
23026 +
23027 2: ;; A failing userspace access for the read below will have this as PC.
23028 _wloop: move.w [$r10+],$r9
23029 addu.w $r9,$r13
23030 subq 2,$r12
23031 bge _wloop
23032 move.w $r9,[$r11+]
23033 -
23034 +
23035 addq 2,$r12
23036 -
23037 +
23038 _no_words:
23039 ;; see if we have one odd byte more
23040 cmpq 1,$r12
23041 @@ -110,7 +105,7 @@
23042 ret
23043 move.d $r13,$r10
23044
23045 -_do_byte:
23046 +_do_byte:
23047 ;; copy and checksum the last byte
23048 3: ;; A failing userspace access for the read below will have this as PC.
23049 move.b [$r10],$r9
23050 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/lib/delay.c linux-2.6.19.2.dev/arch/cris/arch-v32/lib/delay.c
23051 --- linux-2.6.19.2.old/arch/cris/arch-v32/lib/delay.c 1970-01-01 01:00:00.000000000 +0100
23052 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/lib/delay.c 2006-10-16 01:08:41.000000000 +0200
23053 @@ -0,0 +1,28 @@
23054 +/*
23055 + * Precise Delay Loops for ETRAX FS
23056 + *
23057 + * Copyright (C) 2006 Axis Communications AB.
23058 + *
23059 + */
23060 +
23061 +#include <asm/arch/hwregs/reg_map.h>
23062 +#include <asm/arch/hwregs/reg_rdwr.h>
23063 +#include <asm/arch/hwregs/timer_defs.h>
23064 +#include <linux/types.h>
23065 +#include <linux/delay.h>
23066 +#include <linux/module.h>
23067 +
23068 +/*
23069 + * On ETRAX FS, we can check the free-running read-only 100MHz timer
23070 + * getting 32-bit 10ns precision, theoretically good for 42.94967295
23071 + * seconds. Unsigned arithmetic and careful expression handles
23072 + * wrapping.
23073 + */
23074 +
23075 +void cris_delay10ns(u32 n10ns)
23076 +{
23077 + u32 t0 = REG_RD(timer, regi_timer, r_time);
23078 + while (REG_RD(timer, regi_timer, r_time) - t0 < n10ns)
23079 + ;
23080 +}
23081 +EXPORT_SYMBOL(cris_delay10ns);
23082 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/lib/dram_init.S linux-2.6.19.2.dev/arch/cris/arch-v32/lib/dram_init.S
23083 --- linux-2.6.19.2.old/arch/cris/arch-v32/lib/dram_init.S 2007-01-10 20:10:37.000000000 +0100
23084 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/lib/dram_init.S 2006-11-28 11:06:19.000000000 +0100
23085 @@ -1,14 +1,14 @@
23086 -/* $Id: dram_init.S,v 1.4 2005/04/24 18:48:32 starvik Exp $
23087 - *
23088 +/* $Id: dram_init.S,v 1.9 2006/11/28 10:06:19 ricardw Exp $
23089 + *
23090 * DRAM/SDRAM initialization - alter with care
23091 * This file is intended to be included from other assembler files
23092 *
23093 - * Note: This file may not modify r8 or r9 because they are used to
23094 - * carry information from the decompresser to the kernel
23095 + * Note: This file may not modify r8 .. r12 because they are used to
23096 + * carry information from the decompressor to the kernel
23097 *
23098 * Copyright (C) 2000-2003 Axis Communications AB
23099 *
23100 - * Authors: Mikael Starvik (starvik@axis.com)
23101 + * Authors: Mikael Starvik (starvik@axis.com)
23102 */
23103
23104 /* Just to be certain the config file is included, we include it here
23105 @@ -18,13 +18,13 @@
23106
23107 #include <asm/arch/hwregs/asm/reg_map_asm.h>
23108 #include <asm/arch/hwregs/asm/bif_core_defs_asm.h>
23109 -
23110 - ;; WARNING! The registers r8 and r9 are used as parameters carrying
23111 - ;; information from the decompressor (if the kernel was compressed).
23112 +
23113 + ;; WARNING! The registers r8 .. r12 are used as parameters carrying
23114 + ;; information from the decompressor (if the kernel was compressed).
23115 ;; They should not be used in the code below.
23116
23117 ; Refer to BIF MDS for a description of SDRAM initialization
23118 -
23119 +
23120 ; Bank configuration
23121 move.d REG_ADDR(bif_core, regi_bif_core, rw_sdram_cfg_grp0), $r0
23122 move.d CONFIG_ETRAX_SDRAM_GRP0_CONFIG, $r1
23123 @@ -33,7 +33,7 @@
23124 move.d CONFIG_ETRAX_SDRAM_GRP1_CONFIG, $r1
23125 move.d $r1, [$r0]
23126
23127 - ; Calculate value of mrs_data
23128 + ; Calculate value of mrs_data
23129 ; CAS latency = 2 && bus_width = 32 => 0x40
23130 ; CAS latency = 3 && bus_width = 32 => 0x60
23131 ; CAS latency = 2 && bus_width = 16 => 0x20
23132 @@ -43,7 +43,7 @@
23133 move.d CONFIG_ETRAX_SDRAM_COMMAND, $r2
23134 bne _set_timing
23135 nop
23136 -
23137 +
23138 move.d 0x40, $r4 ; Assume 32 bits and CAS latency = 2
23139 move.d CONFIG_ETRAX_SDRAM_TIMING, $r1
23140 and.d 0x07, $r1 ; Get CAS latency
23141 @@ -51,7 +51,7 @@
23142 beq _bw_check
23143 nop
23144 move.d 0x60, $r4
23145 -
23146 +
23147 _bw_check:
23148 ; Assume that group 0 width is equal to group 1. This assumption
23149 ; is wrong for a group 1 only hardware (such as the grand old
23150 @@ -67,23 +67,27 @@
23151 move.d CONFIG_ETRAX_SDRAM_TIMING, $r1
23152 and.d ~(3 << reg_bif_core_rw_sdram_timing___ref___lsb), $r1
23153 move.d REG_ADDR(bif_core, regi_bif_core, rw_sdram_timing), $r0
23154 - move.d $r1, [$r0]
23155 + move.d $r1, [$r0]
23156 +
23157 + ; Wait 200us
23158 + move.d 10000, $r2
23159 +1: bne 1b
23160 + subq 1, $r2
23161
23162 ; Issue NOP command
23163 move.d REG_ADDR(bif_core, regi_bif_core, rw_sdram_cmd), $r5
23164 moveq regk_bif_core_nop, $r1
23165 move.d $r1, [$r5]
23166 -
23167 +
23168 ; Wait 200us
23169 move.d 10000, $r2
23170 1: bne 1b
23171 subq 1, $r2
23172 -
23173 +
23174 ; Issue initialization command sequence
23175 - move.d _sdram_commands_start, $r2
23176 - and.d 0x000fffff, $r2 ; Make sure commands are read from flash
23177 - move.d _sdram_commands_end, $r3
23178 - and.d 0x000fffff, $r3
23179 + lapc.d _sdram_commands_start, $r2 ; position-independent
23180 + lapc.d _sdram_commands_end, $r3 ; position-independent
23181 +
23182 1: clear.d $r6
23183 move.b [$r2+], $r6 ; Load command
23184 or.d $r4, $r6 ; Add calculated mrs
23185 @@ -100,7 +104,7 @@
23186 move.d CONFIG_ETRAX_SDRAM_TIMING, $r1
23187 move.d REG_ADDR(bif_core, regi_bif_core, rw_sdram_timing), $r0
23188 move.d $r1, [$r0]
23189 -
23190 +
23191 ; Initialization finished
23192 ba _sdram_commands_end
23193 nop
23194 @@ -116,4 +120,4 @@
23195 .byte regk_bif_core_ref ; refresh
23196 .byte regk_bif_core_ref ; refresh
23197 .byte regk_bif_core_mrs ; mrs
23198 -_sdram_commands_end:
23199 +_sdram_commands_end:
23200 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/lib/hw_settings.S linux-2.6.19.2.dev/arch/cris/arch-v32/lib/hw_settings.S
23201 --- linux-2.6.19.2.old/arch/cris/arch-v32/lib/hw_settings.S 2007-01-10 20:10:37.000000000 +0100
23202 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/lib/hw_settings.S 2006-10-13 14:43:15.000000000 +0200
23203 @@ -1,25 +1,25 @@
23204 /*
23205 - * $Id: hw_settings.S,v 1.3 2005/04/24 18:36:57 starvik Exp $
23206 - *
23207 + * $Id: hw_settings.S,v 1.5 2006/10/13 12:43:15 starvik Exp $
23208 + *
23209 * This table is used by some tools to extract hardware parameters.
23210 * The table should be included in the kernel and the decompressor.
23211 * Don't forget to update the tools if you change this table.
23212 *
23213 * Copyright (C) 2001 Axis Communications AB
23214 *
23215 - * Authors: Mikael Starvik (starvik@axis.com)
23216 + * Authors: Mikael Starvik (starvik@axis.com)
23217 */
23218
23219 #include <asm/arch/hwregs/asm/reg_map_asm.h>
23220 #include <asm/arch/hwregs/asm/bif_core_defs_asm.h>
23221 #include <asm/arch/hwregs/asm/gio_defs_asm.h>
23222 -
23223 +
23224 .ascii "HW_PARAM_MAGIC" ; Magic number
23225 .dword 0xc0004000 ; Kernel start address
23226
23227 ; Debug port
23228 #ifdef CONFIG_ETRAX_DEBUG_PORT0
23229 - .dword 0
23230 + .dword 0
23231 #elif defined(CONFIG_ETRAX_DEBUG_PORT1)
23232 .dword 1
23233 #elif defined(CONFIG_ETRAX_DEBUG_PORT2)
23234 @@ -28,9 +28,9 @@
23235 .dword 3
23236 #else
23237 .dword 4 ; No debug
23238 -#endif
23239 +#endif
23240
23241 - ; Register values
23242 + ; Register values
23243 .dword REG_ADDR(bif_core, regi_bif_core, rw_grp1_cfg)
23244 .dword CONFIG_ETRAX_MEM_GRP1_CONFIG
23245 .dword REG_ADDR(bif_core, regi_bif_core, rw_grp2_cfg)
23246 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/lib/memset.c linux-2.6.19.2.dev/arch/cris/arch-v32/lib/memset.c
23247 --- linux-2.6.19.2.old/arch/cris/arch-v32/lib/memset.c 2007-01-10 20:10:37.000000000 +0100
23248 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/lib/memset.c 2003-07-02 05:00:14.000000000 +0200
23249 @@ -66,7 +66,7 @@
23250
23251 {
23252 register char *dst __asm__ ("r13") = pdst;
23253 -
23254 +
23255 /* This is NONPORTABLE, but since this whole routine is */
23256 /* grossly nonportable that doesn't matter. */
23257
23258 @@ -156,7 +156,7 @@
23259 }
23260
23261 /* Either we directly starts copying, using dword copying
23262 - in a loop, or we copy as much as possible with 'movem'
23263 + in a loop, or we copy as much as possible with 'movem'
23264 and then the last block (<44 bytes) is copied here.
23265 This will work since 'movem' will have updated src,dst,n. */
23266
23267 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/lib/nand_init.S linux-2.6.19.2.dev/arch/cris/arch-v32/lib/nand_init.S
23268 --- linux-2.6.19.2.old/arch/cris/arch-v32/lib/nand_init.S 2007-01-10 20:10:37.000000000 +0100
23269 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/lib/nand_init.S 2007-01-31 16:52:19.000000000 +0100
23270 @@ -9,14 +9,16 @@
23271 ##
23272 ## Some notes about the bug/feature for future reference:
23273 ## The bootrom copies the first 127 KB from NAND flash to internal
23274 -## memory. The problem is that it does a bytewise copy. NAND flashes
23275 -## does autoincrement on the address so for a 16-bite device each
23276 -## read/write increases the address by two. So the copy loop in the
23277 +## memory. The problem is that it does a bytewise copy, copying
23278 +## a single byte from the lowest byte of the bus for each address.
23279 +## NAND flashes autoincrement on the address so for a 16 bit device
23280 +## each read/write increases the address by two. So the copy loop in the
23281 ## bootrom will discard every second byte. This is solved by inserting
23282 -## zeroes in every second byte in the first erase block.
23283 +## zeroes in every second byte in the first erase block, in order
23284 +## to get contiguous code.
23285 ##
23286 ## The bootrom also incorrectly assumes that it can read the flash
23287 -## linear with only one read command but the flash will actually
23288 +## linearly with only one read command but the flash will actually
23289 ## switch between normal area and spare area if you do that so we
23290 ## can't trust more than the first 256 bytes.
23291 ##
23292 @@ -29,14 +31,16 @@
23293 #include <asm/arch/hwregs/asm/config_defs_asm.h>
23294
23295 ;; There are 8-bit NAND flashes and 16-bit NAND flashes.
23296 -;; We need to treat them slightly different.
23297 -#if CONFIG_ETRAX_FLASH_BUSWIDTH==2
23298 -#define PAGE_SIZE 256
23299 +;; We need to treat them slightly differently.
23300 +#if CONFIG_ETRAX_NANDFLASH_BUSWIDTH==2
23301 +#define PAGE_SIZE_ADDRESSES 256
23302 #else
23303 -#error 2
23304 -#define PAGE_SIZE 512
23305 +#define PAGE_SIZE_ADDRESSES 512
23306 #endif
23307 +
23308 +;; Block size for erase
23309 #define ERASE_BLOCK 16384
23310 +#define PAGE_SIZE_BYTES 512
23311
23312 ;; GPIO pins connected to NAND flash
23313 #define CE 4
23314 @@ -49,6 +53,7 @@
23315 #define NAND_WR_ADDR 0x94000000
23316
23317 #define READ_CMD 0x00
23318 +#define RESET_CMD 0xFF
23319
23320 ;; Readability macros
23321 #define CSP_MASK \
23322 @@ -58,6 +63,10 @@
23323 REG_STATE(bif_core, rw_grp3_cfg, gated_csp0, rd) | \
23324 REG_STATE(bif_core, rw_grp3_cfg, gated_csp1, wr)
23325
23326 +;; Normally we initialize GPIO and bus interfaces.
23327 +;; This is strictly not necessary; boot ROM does this for us.
23328 +#define INTERFACE_SETUP (1)
23329 +
23330 ;;----------------------------------------------------------------------------
23331 ;; Macros to set/clear GPIO bits
23332
23333 @@ -71,16 +80,41 @@
23334 move.d $r9, [$r2]
23335 .endm
23336
23337 +.macro GPIO_SYNC
23338 +;; Originally, we read back data written to nand flash in order
23339 +;; to flush the pipeline. It turned out however, that the real
23340 +;; culprit was a lack of wait states.
23341 +;; This macro remains in the code however in case this conclusion
23342 +;; is wrong too.
23343 +;;
23344 +;; move.d [$r2], $r9 ; read back to flush pipeline
23345 +.endm
23346 +
23347 ;;----------------------------------------------------------------------------
23348 +;; Read value from bus to temporary register to sync with previous write
23349 +;; This generates no signal to the NAND flash, since only chip select lines are
23350 +;; pulled out to the chip, and read is not gated with chip select for the write
23351 +;; area.
23352
23353 -nand_boot:
23354 - ;; Check if nand boot was selected
23355 - move.d REG_ADDR(config, regi_config, r_bootsel), $r0
23356 - move.d [$r0], $r0
23357 - and.d REG_MASK(config, r_bootsel, boot_mode), $r0
23358 - cmp.d REG_STATE(config, r_bootsel, boot_mode, nand), $r0
23359 - bne normal_boot ; No NAND boot
23360 - nop
23361 +.macro BUS_SYNC r
23362 + move.b [$r1], \r
23363 +.endm
23364 +
23365 +;;----------------------------------------------------------------------------
23366 +;; Delay macro
23367 +;; x = delay = 10*x + 20 ns, e.g. DELAY 25 => 270ns delay, max 63 (650 ns)
23368 +;;(@200Mc)
23369 +;; r is temp reg used
23370 +;; Macro currently not used, save for a rainy day.
23371 +
23372 +.macro DELAY x, r
23373 + clear.d \r
23374 + addq (\x),\r ; addq zero-extends its argument
23375 +7: bne 7b
23376 + subq 1, \r
23377 +.endm
23378 +
23379 +;;----------------------------------------------------------------------------
23380
23381 copy_nand_to_ram:
23382 ;; copy_nand_to_ram
23383 @@ -88,7 +122,6 @@
23384 ;; r10 - destination
23385 ;; r11 - source offset
23386 ;; r12 - size
23387 - ;; r13 - Address to jump to after completion
23388 ;; Note : r10-r12 are clobbered on return
23389 ;; Registers used:
23390 ;; r0 - NAND_RD_ADDR
23391 @@ -96,83 +129,99 @@
23392 ;; r2 - reg_gio_rw_pa_dout
23393 ;; r3 - reg_gio_r_pa_din
23394 ;; r4 - tmp
23395 - ;; r5 - byte counter within a page
23396 - ;; r6 - reg_pinmux_rw_pa
23397 - ;; r7 - reg_gio_rw_pa_oe
23398 - ;; r8 - reg_bif_core_rw_grp3_cfg
23399 + ;; r5 - byte counter within a page / tmp2
23400 + ;; r6 - r_bootsel masked w/ 0x18
23401 + ;; r7 - n/u
23402 + ;; r8 - n/u
23403 ;; r9 - reg_gio_rw_pa_dout shadow
23404 - move.d 0x90000000, $r0
23405 - move.d 0x94000000, $r1
23406 + move.d NAND_RD_ADDR, $r0
23407 + move.d NAND_WR_ADDR, $r1
23408 move.d REG_ADDR(gio, regi_gio, rw_pa_dout), $r2
23409 move.d REG_ADDR(gio, regi_gio, r_pa_din), $r3
23410 - move.d REG_ADDR(pinmux, regi_pinmux, rw_pa), $r6
23411 - move.d REG_ADDR(gio, regi_gio, rw_pa_oe), $r7
23412 - move.d REG_ADDR(bif_core, regi_bif_core, rw_grp3_cfg), $r8
23413
23414 -#if CONFIG_ETRAX_FLASH_BUSWIDTH==2
23415 +#if CONFIG_ETRAX_NANDFLASH_BUSWIDTH==2
23416 lsrq 1, $r11
23417 #endif
23418 +
23419 +#if INTERFACE_SETUP
23420 + ;; Set up pinmux
23421 + move.d REG_ADDR(pinmux, regi_pinmux, rw_pa), $r5
23422 + move.d [$r5], $r4
23423 + or.b 0xf0, $r4 ; bits 4,5,6,7
23424 + move.d $r4, [$r5]
23425 +
23426 ;; Set up GPIO
23427 - move.d [$r2], $r9
23428 - move.d [$r7], $r4
23429 + move.d REG_ADDR(gio, regi_gio, rw_pa_oe), $r5
23430 + move.d [$r5], $r4
23431 or.b (1<<ALE) | (1 << CLE) | (1<<CE), $r4
23432 - move.d $r4, [$r7]
23433 + move.d $r4, [$r5]
23434
23435 +#endif
23436 ;; Set up bif
23437 - move.d [$r8], $r4
23438 - and.d CSP_MASK, $r4
23439 + move.d REG_ADDR(bif_core, regi_bif_core, rw_grp3_cfg), $r5
23440 + move.d CONFIG_ETRAX_MEM_GRP3_CONFIG, $r4 ; wait states
23441 + and.d ~CSP_MASK, $r4
23442 or.d CSP_VAL, $r4
23443 - move.d $r4, [$r8]
23444 + move.d $r4, [$r5]
23445 +
23446 + move.d [$r2], $r9 ; fetch PA DOUT to shadow register
23447 +
23448 + ;; figure out how many address cycles the flash needs
23449 + move.d REG_ADDR(config, regi_config, r_bootsel), $r5
23450 + move.d [$r5], $r6
23451 + andq 0x18, $r6 ; mask out bs3,4 (00=>3, 08=>4, 18=>5 cycles)
23452
23453 1: ;; Copy one page
23454 CLR CE
23455 SET CLE
23456 + GPIO_SYNC
23457 moveq READ_CMD, $r4
23458 move.b $r4, [$r1]
23459 - moveq 20, $r4
23460 -2: bne 2b
23461 - subq 1, $r4
23462 + BUS_SYNC $r4
23463 CLR CLE
23464 SET ALE
23465 - clear.w [$r1] ; Column address = 0
23466 - move.d $r11, $r4
23467 + GPIO_SYNC
23468 + clear.b [$r1] ; Column address = 0
23469 + move.d $r11, $r4 ; Address
23470 + lsrq 9, $r4 ; Row address is A9 and up
23471 + move.b $r4, [$r1] ; Row address byte #0
23472 lsrq 8, $r4
23473 - move.b $r4, [$r1] ; Row address
23474 + cmpq 0x08, $r6 ; 8 => Z, 0 => C, 18h => NZ,NC
23475 + bcs 4f ; C (3 cycles) => jump
23476 + move.b $r4, [$r1] ; Row address byte #1 (DELAY SLOT) (no flagset)
23477 + beq 3f ; Z (4 cycles) => jump
23478 + lsrq 8, $r4 ; (DELAY SLOT)
23479 + move.b $r4, [$r1] ; Row address byte #2 (5 cyc only)
23480 lsrq 8, $r4
23481 - move.b $r4, [$r1] ; Row adddress
23482 - moveq 20, $r4
23483 -2: bne 2b
23484 - subq 1, $r4
23485 +3:
23486 + move.b $r4, [$r1] ; Row address byte #3 (5 cyc) or #2 (4 cyc)
23487 +4:
23488 + BUS_SYNC $r4
23489 CLR ALE
23490 + GPIO_SYNC
23491 +
23492 2: move.d [$r3], $r4
23493 and.d 1 << BY, $r4
23494 beq 2b
23495 - movu.w PAGE_SIZE, $r5
23496 + nop
23497 + movu.w PAGE_SIZE_ADDRESSES, $r5
23498 2: ; Copy one byte/word
23499 -#if CONFIG_ETRAX_FLASH_BUSWIDTH==2
23500 +#if CONFIG_ETRAX_NANDFLASH_BUSWIDTH==2
23501 move.w [$r0], $r4
23502 #else
23503 move.b [$r0], $r4
23504 #endif
23505 subq 1, $r5
23506 bne 2b
23507 -#if CONFIG_ETRAX_FLASH_BUSWIDTH==2
23508 +#if CONFIG_ETRAX_NANDFLASH_BUSWIDTH==2
23509 move.w $r4, [$r10+]
23510 - subu.w PAGE_SIZE*2, $r12
23511 #else
23512 move.b $r4, [$r10+]
23513 - subu.w PAGE_SIZE, $r12
23514 #endif
23515 - bpl 1b
23516 - addu.w PAGE_SIZE, $r11
23517 + subu.w PAGE_SIZE_BYTES, $r12
23518 + bhi 1b
23519 + addu.w PAGE_SIZE_ADDRESSES, $r11
23520
23521 - ;; End of copy
23522 - jump $r13
23523 - nop
23524 + SET CE
23525
23526 - ;; This will warn if the code above is too large. If you consider
23527 - ;; to remove this you don't understand the bug/feature.
23528 - .org 256
23529 - .org ERASE_BLOCK
23530 -
23531 -normal_boot:
23532 + ;; End of copy
23533 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/lib/spinlock.S linux-2.6.19.2.dev/arch/cris/arch-v32/lib/spinlock.S
23534 --- linux-2.6.19.2.old/arch/cris/arch-v32/lib/spinlock.S 2007-01-10 20:10:37.000000000 +0100
23535 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/lib/spinlock.S 2006-05-24 11:38:43.000000000 +0200
23536 @@ -1,22 +1,22 @@
23537 ;; Core of the spinlock implementation
23538 ;;
23539 -;; Copyright (C) 2004 Axis Communications AB.
23540 +;; Copyright (C) 2004 Axis Communications AB.
23541 ;;
23542 -;; Author: Mikael Starvik
23543 -
23544 +;; Author: Mikael Starvik
23545
23546 +
23547 .global cris_spin_lock
23548 .global cris_spin_trylock
23549
23550 .text
23551 -
23552 +
23553 cris_spin_lock:
23554 clearf p
23555 -1: test.d [$r10]
23556 +1: test.b [$r10]
23557 beq 1b
23558 clearf p
23559 ax
23560 - clear.d [$r10]
23561 + clear.b [$r10]
23562 bcs 1b
23563 clearf p
23564 ret
23565 @@ -24,10 +24,10 @@
23566
23567 cris_spin_trylock:
23568 clearf p
23569 -1: move.d [$r10], $r11
23570 +1: move.b [$r10], $r11
23571 ax
23572 - clear.d [$r10]
23573 + clear.b [$r10]
23574 bcs 1b
23575 clearf p
23576 ret
23577 - move.d $r11,$r10
23578 + movu.b $r11,$r10
23579 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/lib/string.c linux-2.6.19.2.dev/arch/cris/arch-v32/lib/string.c
23580 --- linux-2.6.19.2.old/arch/cris/arch-v32/lib/string.c 2007-01-10 20:10:37.000000000 +0100
23581 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/lib/string.c 2003-07-02 05:00:14.000000000 +0200
23582 @@ -48,8 +48,8 @@
23583 register char *dst __asm__ ("r13") = pdst;
23584 register const char *src __asm__ ("r11") = psrc;
23585 register int n __asm__ ("r12") = pn;
23586 -
23587 -
23588 +
23589 +
23590 /* When src is aligned but not dst, this makes a few extra needless
23591 cycles. I believe it would take as many to check that the
23592 re-alignment was unnecessary. */
23593 @@ -117,13 +117,13 @@
23594 ;; Restore registers from stack \n\
23595 movem [$sp+],$r10"
23596
23597 - /* Outputs */ : "=r" (dst), "=r" (src), "=r" (n)
23598 + /* Outputs */ : "=r" (dst), "=r" (src), "=r" (n)
23599 /* Inputs */ : "0" (dst), "1" (src), "2" (n));
23600 -
23601 +
23602 }
23603
23604 /* Either we directly starts copying, using dword copying
23605 - in a loop, or we copy as much as possible with 'movem'
23606 + in a loop, or we copy as much as possible with 'movem'
23607 and then the last block (<44 bytes) is copied here.
23608 This will work since 'movem' will have updated src,dst,n. */
23609
23610 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/mm/init.c linux-2.6.19.2.dev/arch/cris/arch-v32/mm/init.c
23611 --- linux-2.6.19.2.old/arch/cris/arch-v32/mm/init.c 2007-01-10 20:10:37.000000000 +0100
23612 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/mm/init.c 2006-10-13 14:43:14.000000000 +0200
23613 @@ -34,12 +34,12 @@
23614 unsigned long mmu_kbase_hi;
23615 unsigned long mmu_kbase_lo;
23616 unsigned short mmu_page_id;
23617 -
23618 - /*
23619 +
23620 + /*
23621 * Make sure the current pgd table points to something sane, even if it
23622 * is most probably not used until the next switch_mm.
23623 */
23624 - per_cpu(current_pgd, smp_processor_id()) = init_mm.pgd;
23625 + per_cpu(current_pgd, smp_processor_id()) = init_mm.pgd;
23626
23627 #ifdef CONFIG_SMP
23628 {
23629 @@ -65,7 +65,7 @@
23630 REG_STATE(mmu, rw_mm_cfg, seg_d, page) |
23631 REG_STATE(mmu, rw_mm_cfg, seg_c, linear) |
23632 REG_STATE(mmu, rw_mm_cfg, seg_b, linear) |
23633 -#ifndef CONFIG_ETRAXFS_SIM
23634 +#ifndef CONFIG_ETRAXFS_SIM
23635 REG_STATE(mmu, rw_mm_cfg, seg_a, page) |
23636 #else
23637 REG_STATE(mmu, rw_mm_cfg, seg_a, linear) |
23638 @@ -115,7 +115,7 @@
23639 SUPP_REG_WR(RW_MM_KBASE_HI, mmu_kbase_hi);
23640 SUPP_REG_WR(RW_MM_KBASE_LO, mmu_kbase_lo);
23641 SUPP_REG_WR(RW_MM_TLB_HI, mmu_page_id);
23642 -
23643 +
23644 /* Update the data MMU. */
23645 SUPP_BANK_SEL(BANK_DM);
23646 SUPP_REG_WR(RW_MM_CFG, mmu_config);
23647 @@ -125,7 +125,7 @@
23648
23649 SPEC_REG_WR(SPEC_REG_PID, 0);
23650
23651 - /*
23652 + /*
23653 * The MMU has been enabled ever since head.S but just to make it
23654 * totally obvious enable it here as well.
23655 */
23656 @@ -133,7 +133,7 @@
23657 SUPP_REG_WR(RW_GC_CFG, 0xf); /* IMMU, DMMU, ICache, DCache on */
23658 }
23659
23660 -void __init
23661 +void __init
23662 paging_init(void)
23663 {
23664 int i;
23665 @@ -160,13 +160,13 @@
23666 for (i = 1; i < MAX_NR_ZONES; i++)
23667 zones_size[i] = 0;
23668
23669 - /*
23670 + /*
23671 * Use free_area_init_node instead of free_area_init, because it is
23672 - * designed for systems where the DRAM starts at an address
23673 + * designed for systems where the DRAM starts at an address
23674 * substantially higher than 0, like us (we start at PAGE_OFFSET). This
23675 * saves space in the mem_map page array.
23676 */
23677 free_area_init_node(0, &contig_page_data, zones_size, PAGE_OFFSET >> PAGE_SHIFT, 0);
23678 -
23679 +
23680 mem_map = contig_page_data.node_mem_map;
23681 }
23682 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/mm/intmem.c linux-2.6.19.2.dev/arch/cris/arch-v32/mm/intmem.c
23683 --- linux-2.6.19.2.old/arch/cris/arch-v32/mm/intmem.c 2007-01-10 20:10:37.000000000 +0100
23684 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/mm/intmem.c 2006-01-02 12:27:04.000000000 +0100
23685 @@ -27,7 +27,7 @@
23686 {
23687 static int initiated = 0;
23688 if (!initiated) {
23689 - struct intmem_allocation* alloc =
23690 + struct intmem_allocation* alloc =
23691 (struct intmem_allocation*)kmalloc(sizeof *alloc, GFP_KERNEL);
23692 INIT_LIST_HEAD(&intmem_allocations);
23693 intmem_virtual = ioremap(MEM_INTMEM_START, MEM_INTMEM_SIZE);
23694 @@ -44,7 +44,7 @@
23695 struct intmem_allocation* allocation;
23696 struct intmem_allocation* tmp;
23697 void* ret = NULL;
23698 -
23699 +
23700 preempt_disable();
23701 crisv32_intmem_init();
23702
23703 @@ -55,7 +55,7 @@
23704 if (allocation->status == STATUS_FREE &&
23705 allocation->size >= size + alignment) {
23706 if (allocation->size > size + alignment) {
23707 - struct intmem_allocation* alloc =
23708 + struct intmem_allocation* alloc =
23709 (struct intmem_allocation*)
23710 kmalloc(sizeof *alloc, GFP_ATOMIC);
23711 alloc->status = STATUS_FREE;
23712 @@ -73,13 +73,13 @@
23713 allocation->offset += alignment;
23714 list_add_tail(&tmp->entry, &allocation->entry);
23715 }
23716 - }
23717 + }
23718 allocation->status = STATUS_ALLOCATED;
23719 allocation->size = size;
23720 ret = (void*)((int)intmem_virtual + allocation->offset);
23721 }
23722 }
23723 - preempt_enable();
23724 + preempt_enable();
23725 return ret;
23726 }
23727
23728 @@ -96,22 +96,22 @@
23729
23730 list_for_each_entry_safe(allocation, tmp, &intmem_allocations, entry) {
23731 if (allocation->offset == (int)(addr - intmem_virtual)) {
23732 - struct intmem_allocation* prev =
23733 - list_entry(allocation->entry.prev,
23734 + struct intmem_allocation* prev =
23735 + list_entry(allocation->entry.prev,
23736 struct intmem_allocation, entry);
23737 - struct intmem_allocation* next =
23738 - list_entry(allocation->entry.next,
23739 + struct intmem_allocation* next =
23740 + list_entry(allocation->entry.next,
23741 struct intmem_allocation, entry);
23742
23743 allocation->status = STATUS_FREE;
23744 /* Join with prev and/or next if also free */
23745 - if (prev->status == STATUS_FREE) {
23746 + if ((prev != &intmem_allocations) && (prev->status == STATUS_FREE)) {
23747 prev->size += allocation->size;
23748 list_del(&allocation->entry);
23749 kfree(allocation);
23750 allocation = prev;
23751 }
23752 - if (next->status == STATUS_FREE) {
23753 + if ((next != &intmem_allocations) && (next->status == STATUS_FREE)) {
23754 allocation->size += next->size;
23755 list_del(&next->entry);
23756 kfree(next);
23757 @@ -125,13 +125,13 @@
23758
23759 void* crisv32_intmem_phys_to_virt(unsigned long addr)
23760 {
23761 - return (void*)(addr - MEM_INTMEM_START+
23762 + return (void*)(addr - MEM_INTMEM_START+
23763 (unsigned long)intmem_virtual);
23764 }
23765
23766 unsigned long crisv32_intmem_virt_to_phys(void* addr)
23767 {
23768 - return (unsigned long)((unsigned long )addr -
23769 + return (unsigned long)((unsigned long )addr -
23770 (unsigned long)intmem_virtual + MEM_INTMEM_START);
23771 }
23772
23773 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/mm/mmu.S linux-2.6.19.2.dev/arch/cris/arch-v32/mm/mmu.S
23774 --- linux-2.6.19.2.old/arch/cris/arch-v32/mm/mmu.S 2007-01-10 20:10:37.000000000 +0100
23775 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/mm/mmu.S 2006-08-04 10:10:20.000000000 +0200
23776 @@ -1,3 +1,5 @@
23777 +; WARNING : The refill handler has been modified, see below !!!
23778 +
23779 /*
23780 * Copyright (C) 2003 Axis Communications AB
23781 *
23782 @@ -9,7 +11,7 @@
23783
23784 #include <asm/page.h>
23785 #include <asm/pgtable.h>
23786 -
23787 +
23788 ; Save all register. Must save in same order as struct pt_regs.
23789 .macro SAVE_ALL
23790 subq 12, $sp
23791 @@ -29,11 +31,11 @@
23792 subq 14*4, $sp
23793 movem $r13, [$sp]
23794 subq 4, $sp
23795 - move.d $r10, [$sp]
23796 + move.d $r10, [$sp]
23797 .endm
23798
23799 ; Bus fault handler. Extracts relevant information and calls mm subsystem
23800 -; to handle the fault.
23801 +; to handle the fault.
23802 .macro MMU_BUS_FAULT_HANDLER handler, mmu, we, ex
23803 .globl \handler
23804 \handler:
23805 @@ -45,7 +47,7 @@
23806 orq \ex << 1, $r13 ; execute?
23807 move $s3, $r10 ; rw_mm_cause
23808 and.d ~8191, $r10 ; Get faulting page start address
23809 -
23810 +
23811 jsr do_page_fault
23812 nop
23813 ba ret_from_intr
23814 @@ -59,15 +61,28 @@
23815 ; The code below handles case 1 and calls the mm subsystem for case 2 and 3.
23816 ; Do not touch this code without very good reasons and extensive testing.
23817 ; Note that the code is optimized to minimize stalls (makes the code harder
23818 -; to read).
23819 +; to read).
23820 +;
23821 +; WARNING !!!
23822 +; Modified by Mikael Asker 060725: added a workaround for strange TLB
23823 +; behavior. If the same PTE is present in more than one set, the TLB
23824 +; doesn't recognize it and we get stuck in a loop of refill exceptions.
23825 +; The workaround detects such loops and exits them by flushing
23826 +; the TLB contents. The problem and workaround were verified
23827 +; in VCS by Mikael Starvik.
23828 ;
23829 ; Each page is 8 KB. Each PMD holds 8192/4 PTEs (each PTE is 4 bytes) so each
23830 -; PMD holds 16 MB of virtual memory.
23831 +; PMD holds 16 MB of virtual memory.
23832 ; Bits 0-12 : Offset within a page
23833 ; Bits 13-23 : PTE offset within a PMD
23834 ; Bits 24-31 : PMD offset within the PGD
23835 -
23836 +
23837 .macro MMU_REFILL_HANDLER handler, mmu
23838 + .data
23839 +1: .dword 0 ; refill_count
23840 + ; == 0 <=> last_refill_cause is invalid
23841 +2: .dword 0 ; last_refill_cause
23842 + .text
23843 .globl \handler
23844 \handler:
23845 subq 4, $sp
23846 @@ -76,40 +91,88 @@
23847 subq 4, $sp
23848 move \mmu, $srs ; Select MMU support register bank
23849 move.d $acr, [$sp]
23850 - subq 4, $sp
23851 - move.d $r0, [$sp]
23852 -#ifdef CONFIG_SMP
23853 + subq 12, $sp
23854 + move.d 1b, $acr ; Point to refill_count
23855 + movem $r2, [$sp]
23856 +
23857 + test.d [$acr] ; refill_count == 0 ?
23858 + beq 5f ; yes, last_refill_cause is invalid
23859 + move.d $acr, $r1
23860 +
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
23867 + moveq 1, $r2
23868 +
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
23872 +
23873 +3: ; Probably not in a loop, continue normal processing
23874 +#ifdef CONFIG_SMP
23875 move $s7, $acr ; PGD
23876 #else
23877 move.d per_cpu__current_pgd, $acr ; PGD
23878 #endif
23879 ; Look up PMD in PGD
23880 - move $s3, $r0 ; rw_mm_cause
23881 lsrq 24, $r0 ; Get PMD index into PGD (bit 24-31)
23882 move.d [$acr], $acr ; PGD for the current process
23883 addi $r0.d, $acr, $acr
23884 move $s3, $r0 ; rw_mm_cause
23885 move.d [$acr], $acr ; Get PMD
23886 - beq 1f
23887 + beq 8f
23888 ; Look up PTE in PMD
23889 lsrq PAGE_SHIFT, $r0
23890 and.w PAGE_MASK, $acr ; Remove PMD flags
23891 and.d 0x7ff, $r0 ; Get PTE index into PMD (bit 13-23)
23892 addi $r0.d, $acr, $acr
23893 move.d [$acr], $acr ; Get PTE
23894 - beq 2f
23895 - move.d [$sp+], $r0 ; Pop r0 in delayslot
23896 + beq 9f
23897 + movem [$sp], $r2 ; Restore r0-r2 in delay slot
23898 + addq 12, $sp
23899 ; Store in TLB
23900 move $acr, $s5
23901 - ; Return
23902 +4: ; Return
23903 move.d [$sp+], $acr
23904 move [$sp], $srs
23905 addq 4, $sp
23906 rete
23907 rfe
23908 -1: ; PMD missing, let the mm subsystem fix it up.
23909 - move.d [$sp+], $r0 ; Pop r0
23910 -2: ; PTE missing, let the mm subsystem fix it up.
23911 +
23912 +5: ; last_refill_cause is invalid
23913 + moveq 1, $r2
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
23919 +
23920 +6: ; rw_mm_cause == last_refill_cause
23921 + move.d [$acr], $r2 ; Get refill_count
23922 + cmpq 4, $r2 ; refill_count > 4 ?
23923 + bhi 7f ; yes
23924 + addq 1, $r2 ; refill_count++
23925 + ba 3b ; Continue normal processing
23926 + move.d $r2, [$acr]
23927 +
23928 +7: ; refill_count > 4, error
23929 + subq 4, $sp
23930 + move $srp, [$sp]
23931 + jsr __flush_tlb_all
23932 + move.d $acr, $r0 ; Save pointer to refill_count
23933 + move [$sp+], $srp
23934 + clear.d [$r0] ; refill_count = 0
23935 + movem [$sp], $r2
23936 + ba 4b ; Return
23937 + addq 12, $sp
23938 +
23939 +8: ; PMD missing, let the mm subsystem fix it up.
23940 + movem [$sp], $r2 ; Restore r0-r2
23941 +9: ; PTE missing, let the mm subsystem fix it up.
23942 + addq 12, $sp
23943 move.d [$sp+], $acr
23944 move [$sp], $srs
23945 addq 4, $sp
23946 @@ -128,7 +191,7 @@
23947 ba ret_from_intr
23948 nop
23949 .endm
23950 -
23951 +
23952 ; This is the MMU bus fault handlers.
23953
23954 MMU_REFILL_HANDLER i_mmu_refill, 1
23955 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/mm/tlb.c linux-2.6.19.2.dev/arch/cris/arch-v32/mm/tlb.c
23956 --- linux-2.6.19.2.old/arch/cris/arch-v32/mm/tlb.c 2007-01-10 20:10:37.000000000 +0100
23957 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/mm/tlb.c 2006-08-07 12:06:44.000000000 +0200
23958 @@ -2,7 +2,7 @@
23959 * Low level TLB handling.
23960 *
23961 * Copyright (C) 2000-2003, Axis Communications AB.
23962 - *
23963 + *
23964 * Authors: Bjorn Wesen <bjornw@axis.com>
23965 * Tobias Anderberg <tobiasa@axis.com>, CRISv32 port.
23966 */
23967 @@ -79,7 +79,7 @@
23968 void
23969 __flush_tlb_mm(struct mm_struct *mm)
23970 {
23971 - int i;
23972 + int i;
23973 int mmu;
23974 unsigned long flags;
23975 unsigned long page_id;
23976 @@ -90,7 +90,7 @@
23977
23978 if (page_id == NO_CONTEXT)
23979 return;
23980 -
23981 +
23982 /* Mark the TLB entries that match the page_id as invalid. */
23983 local_save_flags(flags);
23984 local_irq_disable();
23985 @@ -99,15 +99,15 @@
23986 SUPP_BANK_SEL(mmu);
23987 for (i = 0; i < NUM_TLB_ENTRIES; i++) {
23988 UPDATE_TLB_SEL_IDX(i);
23989 -
23990 +
23991 /* Get the page_id */
23992 SUPP_REG_RD(RW_MM_TLB_HI, tlb_hi);
23993
23994 /* Check if the page_id match. */
23995 if ((tlb_hi & 0xff) == page_id) {
23996 mmu_tlb_hi = (REG_FIELD(mmu, rw_mm_tlb_hi, pid,
23997 - INVALID_PAGEID)
23998 - | REG_FIELD(mmu, rw_mm_tlb_hi, vpn,
23999 + INVALID_PAGEID)
24000 + | REG_FIELD(mmu, rw_mm_tlb_hi, vpn,
24001 i & 0xf));
24002
24003 UPDATE_TLB_HILO(mmu_tlb_hi, 0);
24004 @@ -135,7 +135,7 @@
24005 return;
24006
24007 addr &= PAGE_MASK;
24008 -
24009 +
24010 /*
24011 * Invalidate those TLB entries that match both the mm context and the
24012 * requested virtual address.
24013 @@ -150,11 +150,11 @@
24014 SUPP_REG_RD(RW_MM_TLB_HI, tlb_hi);
24015
24016 /* Check if page_id and address matches */
24017 - if (((tlb_hi & 0xff) == page_id) &&
24018 + if (((tlb_hi & 0xff) == page_id) &&
24019 ((tlb_hi & PAGE_MASK) == addr)) {
24020 mmu_tlb_hi = REG_FIELD(mmu, rw_mm_tlb_hi, pid,
24021 INVALID_PAGEID) | addr;
24022 -
24023 +
24024 UPDATE_TLB_HILO(mmu_tlb_hi, 0);
24025 }
24026 }
24027 @@ -178,33 +178,35 @@
24028 static DEFINE_SPINLOCK(mmu_context_lock);
24029
24030 /* Called in schedule() just before actually doing the switch_to. */
24031 -void
24032 +void
24033 switch_mm(struct mm_struct *prev, struct mm_struct *next,
24034 struct task_struct *tsk)
24035 -{
24036 - int cpu = smp_processor_id();
24037 -
24038 - /* Make sure there is a MMU context. */
24039 - spin_lock(&mmu_context_lock);
24040 - get_mmu_context(next);
24041 - cpu_set(cpu, next->cpu_vm_mask);
24042 - spin_unlock(&mmu_context_lock);
24043 -
24044 - /*
24045 - * Remember the pgd for the fault handlers. Keep a seperate copy of it
24046 - * because current and active_mm might be invalid at points where
24047 - * there's still a need to derefer the pgd.
24048 - */
24049 - per_cpu(current_pgd, cpu) = next->pgd;
24050 -
24051 - /* Switch context in the MMU. */
24052 - if (tsk && task_thread_info(tsk))
24053 - {
24054 - SPEC_REG_WR(SPEC_REG_PID, next->context.page_id | task_thread_info(tsk)->tls);
24055 - }
24056 - else
24057 - {
24058 - SPEC_REG_WR(SPEC_REG_PID, next->context.page_id);
24059 - }
24060 +{
24061 + if (prev != next) {
24062 + int cpu = smp_processor_id();
24063 +
24064 + /* Make sure there is a MMU context. */
24065 + spin_lock(&mmu_context_lock);
24066 + get_mmu_context(next);
24067 + cpu_set(cpu, next->cpu_vm_mask);
24068 + spin_unlock(&mmu_context_lock);
24069 +
24070 + /*
24071 + * Remember the pgd for the fault handlers. Keep a seperate copy of it
24072 + * because current and active_mm might be invalid at points where
24073 + * there's still a need to derefer the pgd.
24074 + */
24075 + per_cpu(current_pgd, cpu) = next->pgd;
24076 +
24077 + /* Switch context in the MMU. */
24078 + if (tsk && task_thread_info(tsk))
24079 + {
24080 + SPEC_REG_WR(SPEC_REG_PID, next->context.page_id | task_thread_info(tsk)->tls);
24081 + }
24082 + else
24083 + {
24084 + SPEC_REG_WR(SPEC_REG_PID, next->context.page_id);
24085 + }
24086 + }
24087 }
24088
24089 diff -urN linux-2.6.19.2.old/arch/cris/arch-v32/vmlinux.lds.S linux-2.6.19.2.dev/arch/cris/arch-v32/vmlinux.lds.S
24090 --- linux-2.6.19.2.old/arch/cris/arch-v32/vmlinux.lds.S 2007-01-10 20:10:37.000000000 +0100
24091 +++ linux-2.6.19.2.dev/arch/cris/arch-v32/vmlinux.lds.S 2006-10-13 14:43:11.000000000 +0200
24092 @@ -5,11 +5,11 @@
24093 * script. It is for example quite vital that all generated sections
24094 * that are used are actually named here, otherwise the linker will
24095 * put them at the end, where the init stuff is which is FREED after
24096 - * the kernel has booted.
24097 - */
24098 + * the kernel has booted.
24099 + */
24100
24101 #include <asm-generic/vmlinux.lds.h>
24102 -
24103 +
24104 jiffies = jiffies_64;
24105 SECTIONS
24106 {
24107 @@ -20,7 +20,7 @@
24108 /* The boot section is only necessary until the VCS top level testbench */
24109 /* includes both flash and DRAM. */
24110 .boot : { *(.boot) }
24111 -
24112 +
24113 . = DRAM_VIRTUAL_BASE + 0x4000; /* See head.S and pages reserved at the start. */
24114
24115 _text = .; /* Text and read-only data. */
24116 @@ -35,7 +35,7 @@
24117 *(.text.__*)
24118 }
24119
24120 - _etext = . ; /* End of text section. */
24121 + _etext = . ; /* End of text section. */
24122 __etext = .;
24123
24124 . = ALIGN(4); /* Exception table. */
24125 @@ -59,7 +59,7 @@
24126
24127 . = ALIGN(8192); /* Init code and data. */
24128 __init_begin = .;
24129 - .init.text : {
24130 + .init.text : {
24131 _sinittext = .;
24132 *(.init.text)
24133 _einittext = .;
24134 @@ -81,7 +81,7 @@
24135 *(.initcall5.init);
24136 *(.initcall6.init);
24137 *(.initcall7.init);
24138 - __initcall_end = .;
24139 + __initcall_end = .;
24140 }
24141
24142 .con_initcall.init : {
24143 @@ -94,20 +94,20 @@
24144 __per_cpu_start = .;
24145 .data.percpu : { *(.data.percpu) }
24146 __per_cpu_end = .;
24147 -
24148 +
24149 .init.ramfs : {
24150 __initramfs_start = .;
24151 *(.init.ramfs)
24152 __initramfs_end = .;
24153 - /*
24154 + /*
24155 * We fill to the next page, so we can discard all init
24156 * pages without needing to consider what payload might be
24157 * appended to the kernel image.
24158 */
24159 - FILL (0);
24160 + FILL (0);
24161 . = ALIGN (8192);
24162 }
24163 -
24164 +
24165 __vmlinux_end = .; /* Last address of the physical file. */
24166 __init_end = .;
24167
24168 diff -urN linux-2.6.19.2.old/arch/cris/kernel/crisksyms.c linux-2.6.19.2.dev/arch/cris/kernel/crisksyms.c
24169 --- linux-2.6.19.2.old/arch/cris/kernel/crisksyms.c 2007-01-10 20:10:37.000000000 +0100
24170 +++ linux-2.6.19.2.dev/arch/cris/kernel/crisksyms.c 2006-11-03 13:49:17.000000000 +0100
24171 @@ -9,7 +9,7 @@
24172 #include <linux/kernel.h>
24173 #include <linux/string.h>
24174 #include <linux/tty.h>
24175 -
24176 +
24177 #include <asm/semaphore.h>
24178 #include <asm/processor.h>
24179 #include <asm/uaccess.h>
24180 @@ -28,6 +28,7 @@
24181 extern void __ashldi3(void);
24182 extern void __ashrdi3(void);
24183 extern void __lshrdi3(void);
24184 +extern void __negdi2(void);
24185 extern void iounmap(volatile void * __iomem);
24186
24187 /* Platform dependent support */
24188 @@ -35,18 +36,7 @@
24189 EXPORT_SYMBOL(get_cmos_time);
24190 EXPORT_SYMBOL(loops_per_usec);
24191
24192 -/* String functions */
24193 -EXPORT_SYMBOL(memcmp);
24194 -EXPORT_SYMBOL(memmove);
24195 -EXPORT_SYMBOL(strstr);
24196 -EXPORT_SYMBOL(strcpy);
24197 -EXPORT_SYMBOL(strchr);
24198 -EXPORT_SYMBOL(strcmp);
24199 -EXPORT_SYMBOL(strlen);
24200 -EXPORT_SYMBOL(strcat);
24201 -EXPORT_SYMBOL(strncat);
24202 -EXPORT_SYMBOL(strncmp);
24203 -EXPORT_SYMBOL(strncpy);
24204 +EXPORT_SYMBOL(ktime_get_ts);
24205
24206 /* Math functions */
24207 EXPORT_SYMBOL(__Udiv);
24208 @@ -56,6 +46,7 @@
24209 EXPORT_SYMBOL(__ashldi3);
24210 EXPORT_SYMBOL(__ashrdi3);
24211 EXPORT_SYMBOL(__lshrdi3);
24212 +EXPORT_SYMBOL(__negdi2);
24213
24214 /* Memory functions */
24215 EXPORT_SYMBOL(__ioremap);
24216 @@ -85,4 +76,4 @@
24217 EXPORT_SYMBOL(del_fast_timer);
24218 EXPORT_SYMBOL(schedule_usleep);
24219 #endif
24220 -
24221 +EXPORT_SYMBOL(csum_partial);
24222 diff -urN linux-2.6.19.2.old/arch/cris/kernel/irq.c linux-2.6.19.2.dev/arch/cris/kernel/irq.c
24223 --- linux-2.6.19.2.old/arch/cris/kernel/irq.c 2007-01-10 20:10:37.000000000 +0100
24224 +++ linux-2.6.19.2.dev/arch/cris/kernel/irq.c 2007-01-09 10:29:20.000000000 +0100
24225 @@ -92,14 +92,16 @@
24226 asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
24227 {
24228 unsigned long sp;
24229 + struct pt_regs *old_regs = set_irq_regs(regs);
24230 irq_enter();
24231 sp = rdsp();
24232 if (unlikely((sp & (PAGE_SIZE - 1)) < (PAGE_SIZE/8))) {
24233 printk("do_IRQ: stack overflow: %lX\n", sp);
24234 show_stack(NULL, (unsigned long *)sp);
24235 }
24236 - __do_IRQ(irq, regs);
24237 + __do_IRQ(irq);
24238 irq_exit();
24239 + set_irq_regs(old_regs);
24240 }
24241
24242 void weird_irq(void)
24243 diff -urN linux-2.6.19.2.old/arch/cris/kernel/process.c linux-2.6.19.2.dev/arch/cris/kernel/process.c
24244 --- linux-2.6.19.2.old/arch/cris/kernel/process.c 2007-01-10 20:10:37.000000000 +0100
24245 +++ linux-2.6.19.2.dev/arch/cris/kernel/process.c 2006-06-25 17:00:10.000000000 +0200
24246 @@ -1,4 +1,4 @@
24247 -/* $Id: process.c,v 1.21 2005/03/04 08:16:17 starvik Exp $
24248 +/* $Id: process.c,v 1.26 2006/06/25 15:00:10 starvik Exp $
24249 *
24250 * linux/arch/cris/kernel/process.c
24251 *
24252 @@ -8,6 +8,21 @@
24253 * Authors: Bjorn Wesen (bjornw@axis.com)
24254 *
24255 * $Log: process.c,v $
24256 + * Revision 1.26 2006/06/25 15:00:10 starvik
24257 + * Merge of Linux 2.6.17
24258 + *
24259 + * Revision 1.25 2006/03/22 09:56:56 starvik
24260 + * Merge of Linux 2.6.16
24261 + *
24262 + * Revision 1.24 2006/01/04 06:09:48 starvik
24263 + * Merge of Linux 2.6.15
24264 + *
24265 + * Revision 1.23 2005/08/29 07:32:19 starvik
24266 + * Merge of 2.6.13
24267 + *
24268 + * Revision 1.22 2005/08/18 08:33:18 starvik
24269 + * Corrected signature of machine_restart
24270 + *
24271 * Revision 1.21 2005/03/04 08:16:17 starvik
24272 * Merge of Linux 2.6.11.
24273 *
24274 @@ -195,12 +210,18 @@
24275 */
24276 void (*pm_idle)(void);
24277
24278 +extern void default_idle(void);
24279 +
24280 +void (*pm_power_off)(void);
24281 +EXPORT_SYMBOL(pm_power_off);
24282 +
24283 /*
24284 * The idle thread. There's no useful work to be
24285 * done, so just try to conserve power and have a
24286 * low exit latency (ie sit in a loop waiting for
24287 * somebody to say that they'd like to reschedule)
24288 */
24289 +
24290 void cpu_idle (void)
24291 {
24292 /* endless idle loop with no priority at all */
24293 diff -urN linux-2.6.19.2.old/arch/cris/kernel/profile.c linux-2.6.19.2.dev/arch/cris/kernel/profile.c
24294 --- linux-2.6.19.2.old/arch/cris/kernel/profile.c 2007-01-10 20:10:37.000000000 +0100
24295 +++ linux-2.6.19.2.dev/arch/cris/kernel/profile.c 2004-10-05 08:22:44.000000000 +0200
24296 @@ -42,7 +42,7 @@
24297 return count;
24298 }
24299
24300 -static ssize_t
24301 +static ssize_t
24302 write_cris_profile(struct file *file, const char __user *buf,
24303 size_t count, loff_t *ppos)
24304 {
24305 diff -urN linux-2.6.19.2.old/arch/cris/kernel/ptrace.c linux-2.6.19.2.dev/arch/cris/kernel/ptrace.c
24306 --- linux-2.6.19.2.old/arch/cris/kernel/ptrace.c 2007-01-10 20:10:37.000000000 +0100
24307 +++ linux-2.6.19.2.dev/arch/cris/kernel/ptrace.c 2006-03-23 15:54:02.000000000 +0100
24308 @@ -8,6 +8,9 @@
24309 * Authors: Bjorn Wesen
24310 *
24311 * $Log: ptrace.c,v $
24312 + * Revision 1.11 2006/03/23 14:54:02 starvik
24313 + * Corrected signal handling.
24314 + *
24315 * Revision 1.10 2004/09/22 11:50:01 orjanf
24316 * * Moved get_reg/put_reg to arch-specific files.
24317 * * Added functions to access debug registers (CRISv32).
24318 @@ -82,13 +85,13 @@
24319 /* notification of userspace execution resumption
24320 * - triggered by current->work.notify_resume
24321 */
24322 -extern int do_signal(int canrestart, sigset_t *oldset, struct pt_regs *regs);
24323 +extern int do_signal(int canrestart, struct pt_regs *regs);
24324
24325
24326 -void do_notify_resume(int canrestart, sigset_t *oldset, struct pt_regs *regs,
24327 +void do_notify_resume(int canrestart, struct pt_regs *regs,
24328 __u32 thread_info_flags )
24329 {
24330 /* deal with pending signal delivery */
24331 if (thread_info_flags & _TIF_SIGPENDING)
24332 - do_signal(canrestart,oldset,regs);
24333 + do_signal(canrestart,regs);
24334 }
24335 diff -urN linux-2.6.19.2.old/arch/cris/kernel/semaphore.c linux-2.6.19.2.dev/arch/cris/kernel/semaphore.c
24336 --- linux-2.6.19.2.old/arch/cris/kernel/semaphore.c 2007-01-10 20:10:37.000000000 +0100
24337 +++ linux-2.6.19.2.dev/arch/cris/kernel/semaphore.c 2005-10-31 09:48:05.000000000 +0100
24338 @@ -4,7 +4,7 @@
24339 */
24340
24341 #include <linux/sched.h>
24342 -#include <linux/init.h>
24343 +#include <asm/semaphore.h>
24344 #include <asm/semaphore-helper.h>
24345
24346 /*
24347 @@ -95,6 +95,7 @@
24348 tsk->state = TASK_RUNNING; \
24349 remove_wait_queue(&sem->wait, &wait);
24350
24351 +
24352 void __sched __down(struct semaphore * sem)
24353 {
24354 DOWN_VAR
24355 diff -urN linux-2.6.19.2.old/arch/cris/kernel/setup.c linux-2.6.19.2.dev/arch/cris/kernel/setup.c
24356 --- linux-2.6.19.2.old/arch/cris/kernel/setup.c 2007-01-10 20:10:37.000000000 +0100
24357 +++ linux-2.6.19.2.dev/arch/cris/kernel/setup.c 2007-01-09 10:29:20.000000000 +0100
24358 @@ -18,7 +18,7 @@
24359 #include <linux/screen_info.h>
24360 #include <linux/utsname.h>
24361 #include <linux/pfn.h>
24362 -
24363 +#include <linux/cpu.h>
24364 #include <asm/setup.h>
24365
24366 /*
24367 @@ -36,6 +36,8 @@
24368
24369 extern unsigned long romfs_start, romfs_length, romfs_in_flash; /* from head.S */
24370
24371 +static struct cpu cpu_devices[NR_CPUS];
24372 +
24373 extern void show_etrax_copyright(void); /* arch-vX/kernel/setup.c */
24374
24375 /* This mainly sets up the memory area, and can be really confusing.
24376 @@ -187,4 +189,14 @@
24377 .show = show_cpuinfo,
24378 };
24379
24380 +static int __init topology_init(void)
24381 +{
24382 + int i;
24383 +
24384 + for_each_possible_cpu(i) {
24385 + return register_cpu(&cpu_devices[i], i);
24386 + }
24387 +}
24388 +
24389 +subsys_initcall(topology_init);
24390
24391 diff -urN linux-2.6.19.2.old/arch/cris/kernel/sys_cris.c linux-2.6.19.2.dev/arch/cris/kernel/sys_cris.c
24392 --- linux-2.6.19.2.old/arch/cris/kernel/sys_cris.c 2007-01-10 20:10:37.000000000 +0100
24393 +++ linux-2.6.19.2.dev/arch/cris/kernel/sys_cris.c 2007-01-09 10:29:20.000000000 +0100
24394 @@ -1,4 +1,4 @@
24395 -/* $Id: sys_cris.c,v 1.6 2004/03/11 11:38:40 starvik Exp $
24396 +/* $Id: sys_cris.c,v 1.7 2007/01/09 09:29:20 starvik Exp $
24397 *
24398 * linux/arch/cris/kernel/sys_cris.c
24399 *
24400 @@ -172,3 +172,4 @@
24401 return -ENOSYS;
24402 }
24403 }
24404 +
24405 diff -urN linux-2.6.19.2.old/arch/cris/kernel/time.c linux-2.6.19.2.dev/arch/cris/kernel/time.c
24406 --- linux-2.6.19.2.old/arch/cris/kernel/time.c 2007-01-10 20:10:37.000000000 +0100
24407 +++ linux-2.6.19.2.dev/arch/cris/kernel/time.c 2007-01-09 10:29:20.000000000 +0100
24408 @@ -1,4 +1,4 @@
24409 -/* $Id: time.c,v 1.18 2005/03/04 08:16:17 starvik Exp $
24410 +/* $Id: time.c,v 1.23 2007/01/09 09:29:20 starvik Exp $
24411 *
24412 * linux/arch/cris/kernel/time.c
24413 *
24414 @@ -172,10 +172,6 @@
24415 mon = CMOS_READ(RTC_MONTH);
24416 year = CMOS_READ(RTC_YEAR);
24417
24418 - printk(KERN_DEBUG
24419 - "rtc: sec 0x%x min 0x%x hour 0x%x day 0x%x mon 0x%x year 0x%x\n",
24420 - sec, min, hour, day, mon, year);
24421 -
24422 BCD_TO_BIN(sec);
24423 BCD_TO_BIN(min);
24424 BCD_TO_BIN(hour);
24425 @@ -208,11 +204,11 @@
24426 cris_do_profile(struct pt_regs* regs)
24427 {
24428
24429 -#if CONFIG_SYSTEM_PROFILER
24430 +#ifdef CONFIG_SYSTEM_PROFILER
24431 cris_profile_sample(regs);
24432 #endif
24433
24434 -#if CONFIG_PROFILING
24435 +#ifdef CONFIG_PROFILING
24436 profile_tick(CPU_PROFILING, regs);
24437 #endif
24438 }
24439 @@ -222,10 +218,15 @@
24440 */
24441 unsigned long long sched_clock(void)
24442 {
24443 - return (unsigned long long)jiffies * (1000000000 / HZ);
24444 + unsigned long long ns;
24445 +
24446 + ns = jiffies;
24447 + ns *= 1000000000 / HZ;
24448 + ns += get_ns_in_jiffie();
24449 + return ns;
24450 }
24451
24452 -static int
24453 +static int
24454 __init init_udelay(void)
24455 {
24456 loops_per_usec = (loops_per_jiffy * HZ) / 1000000;
24457 diff -urN linux-2.6.19.2.old/arch/cris/kernel/traps.c linux-2.6.19.2.dev/arch/cris/kernel/traps.c
24458 --- linux-2.6.19.2.old/arch/cris/kernel/traps.c 2007-01-10 20:10:37.000000000 +0100
24459 +++ linux-2.6.19.2.dev/arch/cris/kernel/traps.c 2006-12-11 14:04:23.000000000 +0100
24460 @@ -1,66 +1,78 @@
24461 -/* $Id: traps.c,v 1.11 2005/01/24 16:03:19 orjanf Exp $
24462 - *
24463 +/*
24464 * linux/arch/cris/traps.c
24465 *
24466 - * Here we handle the break vectors not used by the system call
24467 - * mechanism, as well as some general stack/register dumping
24468 + * Here we handle the break vectors not used by the system call
24469 + * mechanism, as well as some general stack/register dumping
24470 * things.
24471 - *
24472 - * Copyright (C) 2000-2002 Axis Communications AB
24473 + *
24474 + * Copyright (C) 2000-2006 Axis Communications AB
24475 *
24476 * Authors: Bjorn Wesen
24477 - * Hans-Peter Nilsson
24478 + * Hans-Peter Nilsson
24479 *
24480 */
24481
24482 #include <linux/init.h>
24483 #include <linux/module.h>
24484 +
24485 #include <asm/pgtable.h>
24486 #include <asm/uaccess.h>
24487
24488 +extern void arch_enable_nmi(void);
24489 +extern void stop_watchdog(void);
24490 +extern void reset_watchdog(void);
24491 +extern void show_registers(struct pt_regs *regs);
24492 +
24493 +#ifdef CONFIG_DEBUG_BUGVERBOSE
24494 +extern void handle_BUG(struct pt_regs *regs);
24495 +#else
24496 +#define handle_BUG(regs)
24497 +#endif
24498 +
24499 static int kstack_depth_to_print = 24;
24500
24501 -extern int raw_printk(const char *fmt, ...);
24502 +void (*nmi_handler)(struct pt_regs*);
24503
24504 -void show_trace(unsigned long * stack)
24505 +void
24506 +show_trace(unsigned long *stack)
24507 {
24508 unsigned long addr, module_start, module_end;
24509 extern char _stext, _etext;
24510 int i;
24511
24512 - raw_printk("\nCall Trace: ");
24513 + printk("\nCall Trace: ");
24514
24515 - i = 1;
24516 - module_start = VMALLOC_START;
24517 - module_end = VMALLOC_END;
24518 + i = 1;
24519 + module_start = VMALLOC_START;
24520 + module_end = VMALLOC_END;
24521
24522 - while (((long) stack & (THREAD_SIZE-1)) != 0) {
24523 - if (__get_user (addr, stack)) {
24524 + while (((long)stack & (THREAD_SIZE-1)) != 0) {
24525 + if (__get_user(addr, stack)) {
24526 /* This message matches "failing address" marked
24527 s390 in ksymoops, so lines containing it will
24528 not be filtered out by ksymoops. */
24529 - raw_printk ("Failing address 0x%lx\n", (unsigned long)stack);
24530 + printk("Failing address 0x%lx\n", (unsigned long)stack);
24531 break;
24532 }
24533 stack++;
24534
24535 - /*
24536 - * If the address is either in the text segment of the
24537 - * kernel, or in the region which contains vmalloc'ed
24538 - * memory, it *may* be the address of a calling
24539 - * routine; if so, print it so that someone tracing
24540 - * down the cause of the crash will be able to figure
24541 - * out the call path that was taken.
24542 - */
24543 - if (((addr >= (unsigned long) &_stext) &&
24544 - (addr <= (unsigned long) &_etext)) ||
24545 - ((addr >= module_start) && (addr <= module_end))) {
24546 - if (i && ((i % 8) == 0))
24547 - raw_printk("\n ");
24548 - raw_printk("[<%08lx>] ", addr);
24549 - i++;
24550 - }
24551 - }
24552 + /*
24553 + * If the address is either in the text segment of the
24554 + * kernel, or in the region which contains vmalloc'ed
24555 + * memory, it *may* be the address of a calling
24556 + * routine; if so, print it so that someone tracing
24557 + * down the cause of the crash will be able to figure
24558 + * out the call path that was taken.
24559 + */
24560 + if (((addr >= (unsigned long)&_stext) &&
24561 + (addr <= (unsigned long)&_etext)) ||
24562 + ((addr >= module_start) && (addr <= module_end))) {
24563 + if (i && ((i % 8) == 0))
24564 + printk("\n ");
24565 + printk("[<%08lx>] ", addr);
24566 + i++;
24567 + }
24568 + }
24569 }
24570
24571 /*
24572 @@ -78,109 +90,150 @@
24573 * with the ksymoops maintainer.
24574 */
24575
24576 -void
24577 +void
24578 show_stack(struct task_struct *task, unsigned long *sp)
24579 {
24580 - unsigned long *stack, addr;
24581 - int i;
24582 + unsigned long *stack, addr;
24583 + int i;
24584
24585 /*
24586 * debugging aid: "show_stack(NULL);" prints a
24587 * back trace.
24588 */
24589
24590 - if(sp == NULL) {
24591 + if (sp == NULL) {
24592 if (task)
24593 sp = (unsigned long*)task->thread.ksp;
24594 else
24595 sp = (unsigned long*)rdsp();
24596 }
24597
24598 - stack = sp;
24599 + stack = sp;
24600
24601 - raw_printk("\nStack from %08lx:\n ", (unsigned long)stack);
24602 - for(i = 0; i < kstack_depth_to_print; i++) {
24603 - if (((long) stack & (THREAD_SIZE-1)) == 0)
24604 - break;
24605 - if (i && ((i % 8) == 0))
24606 - raw_printk("\n ");
24607 - if (__get_user (addr, stack)) {
24608 + printk("\nStack from %08lx:\n ", (unsigned long)stack);
24609 + for (i = 0; i < kstack_depth_to_print; i++) {
24610 + if (((long)stack & (THREAD_SIZE-1)) == 0)
24611 + break;
24612 + if (i && ((i % 8) == 0))
24613 + printk("\n ");
24614 + if (__get_user(addr, stack)) {
24615 /* This message matches "failing address" marked
24616 s390 in ksymoops, so lines containing it will
24617 not be filtered out by ksymoops. */
24618 - raw_printk ("Failing address 0x%lx\n", (unsigned long)stack);
24619 + printk("Failing address 0x%lx\n", (unsigned long)stack);
24620 break;
24621 }
24622 stack++;
24623 - raw_printk("%08lx ", addr);
24624 - }
24625 + printk("%08lx ", addr);
24626 + }
24627 show_trace(sp);
24628 }
24629
24630 -static void (*nmi_handler)(struct pt_regs*);
24631 -extern void arch_enable_nmi(void);
24632 +#if 0
24633 +/* displays a short stack trace */
24634
24635 -void set_nmi_handler(void (*handler)(struct pt_regs*))
24636 +int
24637 +show_stack(void)
24638 {
24639 - nmi_handler = handler;
24640 - arch_enable_nmi();
24641 + unsigned long *sp = (unsigned long *)rdusp();
24642 + int i;
24643 +
24644 + printk("Stack dump [0x%08lx]:\n", (unsigned long)sp);
24645 + for (i = 0; i < 16; i++)
24646 + printk("sp + %d: 0x%08lx\n", i*4, sp[i]);
24647 + return 0;
24648 }
24649 +#endif
24650
24651 -void handle_nmi(struct pt_regs* regs)
24652 +void
24653 +dump_stack(void)
24654 {
24655 - if (nmi_handler)
24656 - nmi_handler(regs);
24657 + show_stack(NULL, NULL);
24658 +}
24659 +
24660 +EXPORT_SYMBOL(dump_stack);
24661 +
24662 +void
24663 +set_nmi_handler(void (*handler)(struct pt_regs*))
24664 +{
24665 + nmi_handler = handler;
24666 + arch_enable_nmi();
24667 }
24668
24669 #ifdef CONFIG_DEBUG_NMI_OOPS
24670 -void oops_nmi_handler(struct pt_regs* regs)
24671 +void
24672 +oops_nmi_handler(struct pt_regs* regs)
24673 {
24674 - stop_watchdog();
24675 - raw_printk("NMI!\n");
24676 - show_registers(regs);
24677 + stop_watchdog();
24678 + oops_in_progress = 1;
24679 + printk("NMI!\n");
24680 + show_registers(regs);
24681 + oops_in_progress = 0;
24682 }
24683
24684 -static int
24685 -__init oops_nmi_register(void)
24686 +static int __init
24687 +oops_nmi_register(void)
24688 {
24689 - set_nmi_handler(oops_nmi_handler);
24690 - return 0;
24691 + set_nmi_handler(oops_nmi_handler);
24692 + return 0;
24693 }
24694
24695 __initcall(oops_nmi_register);
24696
24697 #endif
24698
24699 -#if 0
24700 -/* displays a short stack trace */
24701 -
24702 -int
24703 -show_stack()
24704 +/*
24705 + * This gets called from entry.S when the watchdog has bitten. Show something
24706 + * similiar to an Oops dump, and if the kernel is configured to be a nice
24707 + * doggy, then halt instead of reboot.
24708 + */
24709 +void
24710 +watchdog_bite_hook(struct pt_regs *regs)
24711 {
24712 - unsigned long *sp = (unsigned long *)rdusp();
24713 - int i;
24714 - raw_printk("Stack dump [0x%08lx]:\n", (unsigned long)sp);
24715 - for(i = 0; i < 16; i++)
24716 - raw_printk("sp + %d: 0x%08lx\n", i*4, sp[i]);
24717 - return 0;
24718 -}
24719 +#ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY
24720 + local_irq_disable();
24721 + stop_watchdog();
24722 + show_registers(regs);
24723 +
24724 + while (1)
24725 + ; /* Do nothing. */
24726 +#else
24727 + show_registers(regs);
24728 #endif
24729 +}
24730
24731 -void dump_stack(void)
24732 +/* This is normally the Oops function. */
24733 +void
24734 +die_if_kernel(const char *str, struct pt_regs *regs, long err)
24735 {
24736 - show_stack(NULL, NULL);
24737 -}
24738 + if (user_mode(regs))
24739 + return;
24740
24741 -EXPORT_SYMBOL(dump_stack);
24742 +#ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY
24743 + /*
24744 + * This printout might take too long and could trigger
24745 + * the watchdog normally. If NICE_DOGGY is set, simply
24746 + * stop the watchdog during the printout.
24747 + */
24748 + stop_watchdog();
24749 +#endif
24750
24751 -void __init
24752 -trap_init(void)
24753 -{
24754 - /* Nothing needs to be done */
24755 + handle_BUG(regs);
24756 +
24757 + printk("%s: %04lx\n", str, err & 0xffff);
24758 +
24759 + show_registers(regs);
24760 +
24761 + oops_in_progress = 0;
24762 +
24763 +#ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY
24764 + reset_watchdog();
24765 +#endif
24766 + do_exit(SIGSEGV);
24767 }
24768
24769 -void spinning_cpu(void* addr)
24770 +void __init
24771 +trap_init(void)
24772 {
24773 - raw_printk("CPU %d spinning on %X\n", smp_processor_id(), addr);
24774 - dump_stack();
24775 + /* Nothing needs to be done */
24776 }
24777 diff -urN linux-2.6.19.2.old/arch/cris/mm/fault.c linux-2.6.19.2.dev/arch/cris/mm/fault.c
24778 --- linux-2.6.19.2.old/arch/cris/mm/fault.c 2007-01-10 20:10:37.000000000 +0100
24779 +++ linux-2.6.19.2.dev/arch/cris/mm/fault.c 2006-09-29 13:14:06.000000000 +0200
24780 @@ -1,11 +1,27 @@
24781 /*
24782 * linux/arch/cris/mm/fault.c
24783 *
24784 - * Copyright (C) 2000, 2001 Axis Communications AB
24785 + * Copyright (C) 2000-2006 Axis Communications AB
24786 + *
24787 + * Authors: Bjorn Wesen
24788 *
24789 - * Authors: Bjorn Wesen
24790 - *
24791 * $Log: fault.c,v $
24792 + * Revision 1.25 2006/09/29 11:14:06 orjanf
24793 + * * Use arch-independent macro to get irp/erp for v10/v32.
24794 + *
24795 + * Revision 1.24 2006/09/29 10:58:09 orjanf
24796 + * * Added user mode SIGSEGV printk.
24797 + *
24798 + * Revision 1.23 2006/06/20 07:42:56 pkj
24799 + * Removed an unnecessary reference to raw_printk().
24800 + *
24801 + * Revision 1.22 2005/08/29 07:32:20 starvik
24802 + * Merge of 2.6.13
24803 + *
24804 + * Revision 1.21 2005/07/02 12:29:37 starvik
24805 + * Use the generic oops_in_progress instead of the raw_printk hack.
24806 + * Moved some functions to achr-independent code.
24807 + *
24808 * Revision 1.20 2005/03/04 08:16:18 starvik
24809 * Merge of Linux 2.6.11.
24810 *
24811 @@ -135,7 +151,6 @@
24812
24813 extern int find_fixup_code(struct pt_regs *);
24814 extern void die_if_kernel(const char *, struct pt_regs *, long);
24815 -extern int raw_printk(const char *fmt, ...);
24816
24817 /* debug of low-level TLB reload */
24818 #undef DEBUG
24819 @@ -164,8 +179,8 @@
24820 * address.
24821 *
24822 * error_code:
24823 - * bit 0 == 0 means no page found, 1 means protection fault
24824 - * bit 1 == 0 means read, 1 means write
24825 + * bit 0 == 0 means no page found, 1 means protection fault
24826 + * bit 1 == 0 means read, 1 means write
24827 *
24828 * If this routine detects a bad access, it returns 1, otherwise it
24829 * returns 0.
24830 @@ -180,9 +195,9 @@
24831 struct vm_area_struct * vma;
24832 siginfo_t info;
24833
24834 - D(printk("Page fault for %lX on %X at %lX, prot %d write %d\n",
24835 - address, smp_processor_id(), instruction_pointer(regs),
24836 - protection, writeaccess));
24837 + D(printk("Page fault for %lX on %X at %lX, prot %d write %d\n",
24838 + address, smp_processor_id(), instruction_pointer(regs),
24839 + protection, writeaccess));
24840
24841 tsk = current;
24842
24843 @@ -318,6 +333,8 @@
24844 /* info.si_code has been set above */
24845 info.si_addr = (void *)address;
24846 force_sig_info(SIGSEGV, &info, tsk);
24847 + printk(KERN_NOTICE "%s (pid %d) segfaults for page address %08lx at pc %08lx\n",
24848 + tsk->comm, tsk->pid, address, instruction_pointer(regs));
24849 return;
24850 }
24851
24852 @@ -325,7 +342,7 @@
24853
24854 /* Are we prepared to handle this kernel fault?
24855 *
24856 - * (The kernel has valid exception-points in the source
24857 + * (The kernel has valid exception-points in the source
24858 * when it acesses user-memory. When it fails in one
24859 * of those points, we find it in a table and do a jump
24860 * to some fixup code that loads an appropriate error
24861 @@ -340,13 +357,17 @@
24862 * terminate things with extreme prejudice.
24863 */
24864
24865 - if ((unsigned long) (address) < PAGE_SIZE)
24866 - raw_printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
24867 - else
24868 - raw_printk(KERN_ALERT "Unable to handle kernel access");
24869 - raw_printk(" at virtual address %08lx\n",address);
24870 + if (!oops_in_progress) {
24871 + oops_in_progress = 1;
24872 + if ((unsigned long) (address) < PAGE_SIZE)
24873 + printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
24874 + else
24875 + printk(KERN_ALERT "Unable to handle kernel access");
24876 + printk(" at virtual address %08lx\n",address);
24877
24878 - die_if_kernel("Oops", regs, (writeaccess << 1) | protection);
24879 + die_if_kernel("Oops", regs, (writeaccess << 1) | protection);
24880 + oops_in_progress = 0;
24881 + }
24882
24883 do_exit(SIGKILL);
24884
24885 @@ -405,8 +426,8 @@
24886 /* Since we're two-level, we don't need to do both
24887 * set_pgd and set_pmd (they do the same thing). If
24888 * we go three-level at some point, do the right thing
24889 - * with pgd_present and set_pgd here.
24890 - *
24891 + * with pgd_present and set_pgd here.
24892 + *
24893 * Also, since the vmalloc area is global, we don't
24894 * need to copy individual PTE's, it is enough to
24895 * copy the pgd pointer into the pte page of the
24896 diff -urN linux-2.6.19.2.old/arch/cris/mm/init.c linux-2.6.19.2.dev/arch/cris/mm/init.c
24897 --- linux-2.6.19.2.old/arch/cris/mm/init.c 2007-01-10 20:10:37.000000000 +0100
24898 +++ linux-2.6.19.2.dev/arch/cris/mm/init.c 2006-06-25 17:00:10.000000000 +0200
24899 @@ -7,6 +7,15 @@
24900 * Authors: Bjorn Wesen (bjornw@axis.com)
24901 *
24902 * $Log: init.c,v $
24903 + * Revision 1.14 2006/06/25 15:00:10 starvik
24904 + * Merge of Linux 2.6.17
24905 + *
24906 + * Revision 1.13 2005/06/20 05:30:00 starvik
24907 + * Remove unnecessary diff to kernel.org tree
24908 + *
24909 + * Revision 1.12 2004/08/16 12:37:24 starvik
24910 + * Merge of Linux 2.6.8
24911 + *
24912 * Revision 1.11 2004/05/28 09:28:56 starvik
24913 * Calculation of loops_per_usec moved because initalization order has changed
24914 * in Linux 2.6.
This page took 1.156338 seconds and 5 git commands to generate.