Merge branch 'cris' of git://www.jni.nu/cris
authorLinus Torvalds <torvalds@woody.linux-foundation.org>
Fri, 8 Feb 2008 18:01:28 +0000 (10:01 -0800)
committerLinus Torvalds <torvalds@woody.linux-foundation.org>
Fri, 8 Feb 2008 18:01:28 +0000 (10:01 -0800)
* 'cris' of git://www.jni.nu/cris: (158 commits)
  CRIS v32: Remove hwregs/timer_defs.h, it is now architecture specific.
  CRIS v32: Change drivers/i2c.c locking.
  CRIS v32: Rewrite ARTPEC-3 gpio driver to avoid volatiles and general cleanup.
  CRIS: Add new timerfd syscall entries.
  MAINTAINERS: Add my information for the CRIS port.
  CRIS v32: Correct spelling of bandwidth in function name.
  CRIS v32: Clean up nandflash.c for ARTPEC-3 and ETRAX FS.
  CRIS v10: Cleanup of drivers/gpio.c
  CRIS v10: drivers/net/cris/eth_v10.c rename LED defines to CRIS_LED to avoid name clash.
  CRIS: Make io_pwm_set_period members unsigned in etraxgpio.h
  CRIS: Move ETRAX_AXISFLASHMAP to common Kconfig file.
  CRIS: Drop regs parameter from call to profile_tick in kernel/time.c
  CRIS v32: Fix minor formatting issue in mach-a3/io.c
  CRIS v32: Initialize GIO even if we're rambooting in kernel/head.S
  CRIS v32: Remove kernel/arbiter.c, it now exists in machine dependent directory.
  CRIS v32: Minor changes to avoid errors in asm-cris/arch-v32/hwregs/reg_rdwr.h
  CRIS v32: arch-v32/hwregs/intr_vect_defs.h moved to machine dependent directory.
  CRIS v32: Correct offset for TASK_pid in asm-cris/arch-v32/offset.h
  CRIS v32: Move register map header to machine dependent directory.
  CRIS v32: Let compiler know that memory is clobbered after a break op.
  ...

226 files changed:
MAINTAINERS
arch/cris/Kconfig
arch/cris/Makefile
arch/cris/arch-v10/Kconfig
arch/cris/arch-v10/boot/Makefile
arch/cris/arch-v10/boot/compressed/Makefile
arch/cris/arch-v10/boot/compressed/misc.c
arch/cris/arch-v10/boot/rescue/Makefile
arch/cris/arch-v10/boot/rescue/head.S
arch/cris/arch-v10/boot/rescue/kimagerescue.S
arch/cris/arch-v10/boot/rescue/testrescue.S
arch/cris/arch-v10/drivers/Kconfig
arch/cris/arch-v10/drivers/Makefile
arch/cris/arch-v10/drivers/axisflashmap.c
arch/cris/arch-v10/drivers/ds1302.c
arch/cris/arch-v10/drivers/eeprom.c
arch/cris/arch-v10/drivers/gpio.c
arch/cris/arch-v10/drivers/i2c.c
arch/cris/arch-v10/drivers/pcf8563.c
arch/cris/arch-v10/drivers/sync_serial.c [new file with mode: 0644]
arch/cris/arch-v10/kernel/debugport.c
arch/cris/arch-v10/kernel/dma.c
arch/cris/arch-v10/kernel/entry.S
arch/cris/arch-v10/kernel/fasttimer.c
arch/cris/arch-v10/kernel/head.S
arch/cris/arch-v10/kernel/io_interface_mux.c
arch/cris/arch-v10/kernel/irq.c
arch/cris/arch-v10/kernel/kgdb.c
arch/cris/arch-v10/kernel/process.c
arch/cris/arch-v10/kernel/ptrace.c
arch/cris/arch-v10/kernel/shadows.c
arch/cris/arch-v10/kernel/traps.c
arch/cris/arch-v10/lib/checksum.S
arch/cris/arch-v10/lib/checksumcopy.S
arch/cris/arch-v10/lib/dram_init.S
arch/cris/arch-v10/lib/old_checksum.c
arch/cris/arch-v10/mm/fault.c
arch/cris/arch-v10/mm/tlb.c
arch/cris/arch-v32/Kconfig
arch/cris/arch-v32/boot/Makefile
arch/cris/arch-v32/boot/compressed/Makefile
arch/cris/arch-v32/boot/compressed/README
arch/cris/arch-v32/boot/compressed/head.S
arch/cris/arch-v32/boot/compressed/misc.c
arch/cris/arch-v32/boot/rescue/Makefile
arch/cris/arch-v32/boot/rescue/head.S
arch/cris/arch-v32/boot/rescue/rescue.ld
arch/cris/arch-v32/drivers/Kconfig
arch/cris/arch-v32/drivers/Makefile
arch/cris/arch-v32/drivers/axisflashmap.c
arch/cris/arch-v32/drivers/cryptocop.c
arch/cris/arch-v32/drivers/i2c.c
arch/cris/arch-v32/drivers/i2c.h
arch/cris/arch-v32/drivers/iop_fw_load.c
arch/cris/arch-v32/drivers/mach-a3/Makefile [new file with mode: 0644]
arch/cris/arch-v32/drivers/mach-a3/gpio.c [new file with mode: 0644]
arch/cris/arch-v32/drivers/mach-a3/nandflash.c [new file with mode: 0644]
arch/cris/arch-v32/drivers/mach-fs/Makefile [new file with mode: 0644]
arch/cris/arch-v32/drivers/mach-fs/gpio.c [moved from arch/cris/arch-v32/drivers/gpio.c with 52% similarity]
arch/cris/arch-v32/drivers/mach-fs/nandflash.c [moved from arch/cris/arch-v32/drivers/nandflash.c with 51% similarity]
arch/cris/arch-v32/drivers/pcf8563.c
arch/cris/arch-v32/drivers/sync_serial.c
arch/cris/arch-v32/kernel/Makefile
arch/cris/arch-v32/kernel/arbiter.c [deleted file]
arch/cris/arch-v32/kernel/crisksyms.c
arch/cris/arch-v32/kernel/debugport.c
arch/cris/arch-v32/kernel/entry.S
arch/cris/arch-v32/kernel/fasttimer.c
arch/cris/arch-v32/kernel/head.S
arch/cris/arch-v32/kernel/io.c [deleted file]
arch/cris/arch-v32/kernel/irq.c
arch/cris/arch-v32/kernel/kgdb.c
arch/cris/arch-v32/kernel/process.c
arch/cris/arch-v32/kernel/ptrace.c
arch/cris/arch-v32/kernel/signal.c
arch/cris/arch-v32/kernel/smp.c
arch/cris/arch-v32/kernel/time.c
arch/cris/arch-v32/kernel/traps.c
arch/cris/arch-v32/kernel/vcs_hook.c [deleted file]
arch/cris/arch-v32/lib/Makefile
arch/cris/arch-v32/lib/checksum.S
arch/cris/arch-v32/lib/checksumcopy.S
arch/cris/arch-v32/lib/delay.c [new file with mode: 0644]
arch/cris/arch-v32/lib/spinlock.S
arch/cris/arch-v32/mach-a3/Kconfig [new file with mode: 0644]
arch/cris/arch-v32/mach-a3/Makefile [new file with mode: 0644]
arch/cris/arch-v32/mach-a3/arbiter.c [new file with mode: 0644]
arch/cris/arch-v32/mach-a3/cpufreq.c [new file with mode: 0644]
arch/cris/arch-v32/mach-a3/dma.c [new file with mode: 0644]
arch/cris/arch-v32/mach-a3/dram_init.S [new file with mode: 0644]
arch/cris/arch-v32/mach-a3/hw_settings.S [new file with mode: 0644]
arch/cris/arch-v32/mach-a3/io.c [new file with mode: 0644]
arch/cris/arch-v32/mach-a3/pinmux.c [new file with mode: 0644]
arch/cris/arch-v32/mach-a3/vcs_hook.c [new file with mode: 0644]
arch/cris/arch-v32/mach-a3/vcs_hook.h [new file with mode: 0644]
arch/cris/arch-v32/mach-fs/Kconfig [new file with mode: 0644]
arch/cris/arch-v32/mach-fs/Makefile [new file with mode: 0644]
arch/cris/arch-v32/mach-fs/arbiter.c [new file with mode: 0644]
arch/cris/arch-v32/mach-fs/cpufreq.c [new file with mode: 0644]
arch/cris/arch-v32/mach-fs/dma.c [moved from arch/cris/arch-v32/kernel/dma.c with 83% similarity]
arch/cris/arch-v32/mach-fs/dram_init.S [moved from arch/cris/arch-v32/lib/dram_init.S with 84% similarity]
arch/cris/arch-v32/mach-fs/hw_settings.S [moved from arch/cris/arch-v32/lib/hw_settings.S with 87% similarity]
arch/cris/arch-v32/mach-fs/io.c [new file with mode: 0644]
arch/cris/arch-v32/mach-fs/pinmux.c [new file with mode: 0644]
arch/cris/arch-v32/mach-fs/vcs_hook.c [new file with mode: 0644]
arch/cris/arch-v32/mach-fs/vcs_hook.h [moved from arch/cris/arch-v32/kernel/vcs_hook.h with 80% similarity]
arch/cris/arch-v32/mm/Makefile
arch/cris/arch-v32/mm/init.c
arch/cris/arch-v32/mm/intmem.c
arch/cris/arch-v32/mm/l2cache.c [new file with mode: 0644]
arch/cris/arch-v32/mm/mmu.S
arch/cris/arch-v32/mm/tlb.c
arch/cris/arch-v32/vmlinux.lds.S
arch/cris/artpec_3_defconfig [new file with mode: 0644]
arch/cris/defconfig
arch/cris/etraxfs_defconfig [new file with mode: 0644]
arch/cris/kernel/module.c
arch/cris/kernel/process.c
arch/cris/kernel/ptrace.c
arch/cris/kernel/semaphore.c
arch/cris/kernel/setup.c
arch/cris/kernel/time.c
arch/cris/kernel/traps.c
arch/cris/mm/fault.c
arch/cris/mm/init.c
drivers/net/cris/eth_v10.c
include/asm-cris/Kbuild
include/asm-cris/arch-v10/Kbuild
include/asm-cris/arch-v10/bug.h [new file with mode: 0644]
include/asm-cris/arch-v10/io.h
include/asm-cris/arch-v10/page.h
include/asm-cris/arch-v32/Kbuild
include/asm-cris/arch-v32/atomic.h
include/asm-cris/arch-v32/bug.h [new file with mode: 0644]
include/asm-cris/arch-v32/cache.h
include/asm-cris/arch-v32/delay.h
include/asm-cris/arch-v32/hwregs/Makefile
include/asm-cris/arch-v32/hwregs/dma.h
include/asm-cris/arch-v32/hwregs/eth_defs.h
include/asm-cris/arch-v32/hwregs/reg_rdwr.h
include/asm-cris/arch-v32/io.h
include/asm-cris/arch-v32/irq.h
include/asm-cris/arch-v32/juliette.h [deleted file]
include/asm-cris/arch-v32/mach-a3/arbiter.h [new file with mode: 0644]
include/asm-cris/arch-v32/mach-a3/dma.h [new file with mode: 0644]
include/asm-cris/arch-v32/mach-a3/hwregs/asm/clkgen_defs_asm.h [new file with mode: 0644]
include/asm-cris/arch-v32/mach-a3/hwregs/asm/ddr2_defs_asm.h [new file with mode: 0644]
include/asm-cris/arch-v32/mach-a3/hwregs/asm/gio_defs_asm.h [new file with mode: 0644]
include/asm-cris/arch-v32/mach-a3/hwregs/asm/pinmux_defs_asm.h [new file with mode: 0644]
include/asm-cris/arch-v32/mach-a3/hwregs/asm/pio_defs_asm.h [new file with mode: 0644]
include/asm-cris/arch-v32/mach-a3/hwregs/asm/reg_map_asm.h [new file with mode: 0644]
include/asm-cris/arch-v32/mach-a3/hwregs/asm/timer_defs_asm.h [new file with mode: 0644]
include/asm-cris/arch-v32/mach-a3/hwregs/clkgen_defs.h [new file with mode: 0644]
include/asm-cris/arch-v32/mach-a3/hwregs/ddr2_defs.h [new file with mode: 0644]
include/asm-cris/arch-v32/mach-a3/hwregs/gio_defs.h [new file with mode: 0644]
include/asm-cris/arch-v32/mach-a3/hwregs/intr_vect.h [new file with mode: 0644]
include/asm-cris/arch-v32/mach-a3/hwregs/intr_vect_defs.h [new file with mode: 0644]
include/asm-cris/arch-v32/mach-a3/hwregs/iop/asm/iop_reg_space_asm.h [new file with mode: 0644]
include/asm-cris/arch-v32/mach-a3/hwregs/iop/asm/iop_sap_in_defs_asm.h [new file with mode: 0644]
include/asm-cris/arch-v32/mach-a3/hwregs/iop/asm/iop_sap_out_defs_asm.h [new file with mode: 0644]
include/asm-cris/arch-v32/mach-a3/hwregs/iop/asm/iop_sw_cfg_defs_asm.h [new file with mode: 0644]
include/asm-cris/arch-v32/mach-a3/hwregs/iop/asm/iop_sw_cpu_defs_asm.h [new file with mode: 0644]
include/asm-cris/arch-v32/mach-a3/hwregs/iop/asm/iop_sw_mpu_defs_asm.h [new file with mode: 0644]
include/asm-cris/arch-v32/mach-a3/hwregs/iop/asm/iop_sw_spu_defs_asm.h [new file with mode: 0644]
include/asm-cris/arch-v32/mach-a3/hwregs/iop/asm/iop_version_defs_asm.h [new file with mode: 0644]
include/asm-cris/arch-v32/mach-a3/hwregs/iop/iop_reg_space.h [new file with mode: 0644]
include/asm-cris/arch-v32/mach-a3/hwregs/iop/iop_sap_in_defs.h [new file with mode: 0644]
include/asm-cris/arch-v32/mach-a3/hwregs/iop/iop_sap_out_defs.h [new file with mode: 0644]
include/asm-cris/arch-v32/mach-a3/hwregs/iop/iop_sw_cfg_defs.h [new file with mode: 0644]
include/asm-cris/arch-v32/mach-a3/hwregs/iop/iop_sw_cpu_defs.h [new file with mode: 0644]
include/asm-cris/arch-v32/mach-a3/hwregs/iop/iop_sw_mpu_defs.h [new file with mode: 0644]
include/asm-cris/arch-v32/mach-a3/hwregs/iop/iop_sw_spu_defs.h [new file with mode: 0644]
include/asm-cris/arch-v32/mach-a3/hwregs/iop/iop_version_defs.h [new file with mode: 0644]
include/asm-cris/arch-v32/mach-a3/hwregs/l2cache_defs.h [new file with mode: 0644]
include/asm-cris/arch-v32/mach-a3/hwregs/marb_bar_defs.h [new file with mode: 0644]
include/asm-cris/arch-v32/mach-a3/hwregs/marb_foo_defs.h [new file with mode: 0644]
include/asm-cris/arch-v32/mach-a3/hwregs/pinmux_defs.h [new file with mode: 0644]
include/asm-cris/arch-v32/mach-a3/hwregs/pio_defs.h [new file with mode: 0644]
include/asm-cris/arch-v32/mach-a3/hwregs/reg_map.h [new file with mode: 0644]
include/asm-cris/arch-v32/mach-a3/hwregs/strmux_defs.h [new file with mode: 0644]
include/asm-cris/arch-v32/mach-a3/hwregs/timer_defs.h [new file with mode: 0644]
include/asm-cris/arch-v32/mach-a3/memmap.h [new file with mode: 0644]
include/asm-cris/arch-v32/mach-a3/pinmux.h [new file with mode: 0644]
include/asm-cris/arch-v32/mach-a3/startup.inc [new file with mode: 0644]
include/asm-cris/arch-v32/mach-fs/arbiter.h [new file with mode: 0644]
include/asm-cris/arch-v32/mach-fs/hwregs/asm/bif_core_defs_asm.h [new file with mode: 0644]
include/asm-cris/arch-v32/mach-fs/hwregs/asm/config_defs_asm.h [new file with mode: 0644]
include/asm-cris/arch-v32/mach-fs/hwregs/asm/gio_defs_asm.h [new file with mode: 0644]
include/asm-cris/arch-v32/mach-fs/hwregs/asm/pinmux_defs_asm.h [new file with mode: 0644]
include/asm-cris/arch-v32/mach-fs/hwregs/asm/reg_map_asm.h [new file with mode: 0644]
include/asm-cris/arch-v32/mach-fs/hwregs/asm/timer_defs_asm.h [new file with mode: 0644]
include/asm-cris/arch-v32/mach-fs/hwregs/bif_core_defs.h [new file with mode: 0644]
include/asm-cris/arch-v32/mach-fs/hwregs/bif_dma_defs.h [new file with mode: 0644]
include/asm-cris/arch-v32/mach-fs/hwregs/bif_slave_defs.h [new file with mode: 0644]
include/asm-cris/arch-v32/mach-fs/hwregs/config_defs.h [new file with mode: 0644]
include/asm-cris/arch-v32/mach-fs/hwregs/gio_defs.h [new file with mode: 0644]
include/asm-cris/arch-v32/mach-fs/hwregs/intr_vect.h [new file with mode: 0644]
include/asm-cris/arch-v32/mach-fs/hwregs/intr_vect_defs.h [moved from include/asm-cris/arch-v32/hwregs/intr_vect_defs.h with 96% similarity]
include/asm-cris/arch-v32/mach-fs/hwregs/marb_bp_defs.h [new file with mode: 0644]
include/asm-cris/arch-v32/mach-fs/hwregs/marb_defs.h [new file with mode: 0644]
include/asm-cris/arch-v32/mach-fs/hwregs/pinmux_defs.h [new file with mode: 0644]
include/asm-cris/arch-v32/mach-fs/hwregs/reg_map.h [moved from include/asm-cris/arch-v32/hwregs/reg_map.h with 97% similarity]
include/asm-cris/arch-v32/mach-fs/hwregs/strmux_defs.h [new file with mode: 0644]
include/asm-cris/arch-v32/mach-fs/hwregs/timer_defs.h [moved from include/asm-cris/arch-v32/hwregs/timer_defs.h with 99% similarity]
include/asm-cris/arch-v32/mach-fs/pinmux.h [new file with mode: 0644]
include/asm-cris/arch-v32/mach-fs/startup.inc [new file with mode: 0644]
include/asm-cris/arch-v32/offset.h
include/asm-cris/arch-v32/page.h
include/asm-cris/arch-v32/pinmux.h
include/asm-cris/arch-v32/processor.h
include/asm-cris/arch-v32/spinlock.h
include/asm-cris/arch-v32/system.h
include/asm-cris/arch-v32/timex.h
include/asm-cris/arch-v32/unistd.h
include/asm-cris/atomic.h
include/asm-cris/axisflashmap.h
include/asm-cris/bug.h
include/asm-cris/delay.h
include/asm-cris/dma-mapping.h
include/asm-cris/etraxgpio.h
include/asm-cris/io.h
include/asm-cris/pgtable.h
include/asm-cris/rtc.h
include/asm-cris/smp.h
include/asm-cris/sync_serial.h
include/asm-cris/unistd.h

index a24631f4eab186236001b7b4b3b90798236206e2..0d6f5119a6da08e49ab50e316a606c4acaf9a9a6 100644 (file)
@@ -1173,6 +1173,8 @@ S:        Orphan
 CRIS PORT
 P:     Mikael Starvik
 M:     starvik@axis.com
+P:     Jesper Nilsson
+M:     jesper.nilsson@axis.com
 L:     dev-etrax@axis.com
 W:     http://developer.axis.com
 S:     Maintained
index ff078e60e76da8f2b9ef0753287b8407d44d277f..8456bc8efb7c6b2ce3fa1107189b8e4ff92923fd 100644 (file)
@@ -13,10 +13,6 @@ config ZONE_DMA
        bool
        default y
 
-config NO_DMA
-       bool
-       default y
-
 config RWSEM_GENERIC_SPINLOCK
        bool
        default y
@@ -24,6 +20,10 @@ config RWSEM_GENERIC_SPINLOCK
 config RWSEM_XCHGADD_ALGORITHM
        bool
 
+config GENERIC_IOMAP
+       bool
+       default y
+
 config ARCH_HAS_ILOG2_U32
        bool
        default n
@@ -44,13 +44,13 @@ config GENERIC_CALIBRATE_DELAY
        bool
        default y
 
-config IRQ_PER_CPU
-       bool
-       default y
-
 config NO_IOPORT
        def_bool y
 
+config FORCE_MAX_ZONEORDER
+       int
+       default 6
+
 config CRIS
        bool
        default y
@@ -97,17 +97,15 @@ config ETRAX_FAST_TIMER
         timers).
         This is needed if CONFIG_ETRAX_SERIAL_FAST_TIMER is enabled.
 
-config PREEMPT
-       bool "Preemptible Kernel"
+config ETRAX_KMALLOCED_MODULES
+       bool "Enable module allocation with kmalloc"
        help
-         This option reduces the latency of the kernel when reacting to
-         real-time or interactive events by allowing a low priority process to
-         be preempted even if it is in kernel mode executing a system call.
-         This allows applications to run more reliably even when the system is
-         under load.
+         Enable module allocation with kmalloc instead of vmalloc.
+
+config OOM_REBOOT
+       bool "Enable reboot at out of memory"
 
-         Say Y here if you are building a kernel for a desktop, embedded
-         or real-time system.  Say N if you are unsure.
+source "kernel/Kconfig.preempt"
 
 source mm/Kconfig
 
@@ -134,24 +132,124 @@ config SVINTO_SIM
        help
          Support the xsim ETRAX Simulator.
 
+config ETRAXFS
+       bool "ETRAX-FS-V32"
+       help
+         Support CRIS V32.
+
+config CRIS_MACH_ARTPEC3
+        bool "ARTPEC-3"
+        help
+          Support Axis ARTPEC-3.
+
 endchoice
 
+config ETRAX_VCS_SIM
+       bool "VCS Simulator"
+       help
+         Setup hardware to be run in the VCS simulator.
+
 config ETRAX_ARCH_V10
        bool
        default y if ETRAX100LX || ETRAX100LX_V2
        default n if !(ETRAX100LX || ETRAX100LX_V2)
 
+config ETRAX_ARCH_V32
+       bool
+       default y if (ETRAXFS || CRIS_MACH_ARTPEC3)
+       default n if !(ETRAXFS || CRIS_MACH_ARTPEC3)
+
 config ETRAX_DRAM_SIZE
        int "DRAM size (dec, in MB)"
        default "8"
        help
          Size of DRAM (decimal in MB) typically 2, 8 or 16.
 
+config ETRAX_VMEM_SIZE
+       int "Video memory size (dec, in MB)"
+       depends on ETRAX_ARCH_V32 && !ETRAXFS
+       default 8 if !ETRAXFS
+       help
+       Size of Video accessible memory (decimal, in MB).
+
 config ETRAX_FLASH_BUSWIDTH
-       int "Buswidth of flash in bytes"
+       int "Buswidth of NOR flash in bytes"
        default "2"
        help
-         Width in bytes of the Flash bus (1, 2 or 4). Is usually 2.
+         Width in bytes of the NOR Flash bus (1, 2 or 4). Is usually 2.
+
+config ETRAX_NANDFLASH_BUSWIDTH
+       int "Buswidth of NAND flash in bytes"
+       default "1"
+       help
+         Width in bytes of the NAND flash (1 or 2).
+
+config ETRAX_FLASH1_SIZE
+       int "FLASH1 size (dec, in MB. 0 = Unknown)"
+       default "0"
+
+choice
+       prompt "Product debug-port"
+       default ETRAX_DEBUG_PORT0
+
+config ETRAX_DEBUG_PORT0
+       bool "Serial-0"
+       help
+         Choose a serial port for the ETRAX debug console.  Default to
+         port 0.
+
+config ETRAX_DEBUG_PORT1
+       bool "Serial-1"
+       help
+         Use serial port 1 for the console.
+
+config ETRAX_DEBUG_PORT2
+       bool "Serial-2"
+       help
+         Use serial port 2 for the console.
+
+config ETRAX_DEBUG_PORT3
+       bool "Serial-3"
+       help
+         Use serial port 3 for the console.
+
+config ETRAX_DEBUG_PORT_NULL
+       bool "disabled"
+       help
+         Disable serial-port debugging.
+
+endchoice
+
+choice
+       prompt "Kernel GDB port"
+       depends on ETRAX_KGDB
+       default ETRAX_KGDB_PORT0
+       help
+         Choose a serial port for kernel debugging.  NOTE: This port should
+         not be enabled under Drivers for built-in interfaces (as it has its
+         own initialization code) and should not be the same as the debug port.
+
+config ETRAX_KGDB_PORT0
+       bool "Serial-0"
+       help
+         Use serial port 0 for kernel debugging.
+
+config ETRAX_KGDB_PORT1
+       bool "Serial-1"
+       help
+         Use serial port 1 for kernel debugging.
+
+config ETRAX_KGDB_PORT2
+       bool "Serial-2"
+       help
+         Use serial port 2 for kernel debugging.
+
+config ETRAX_KGDB_PORT3
+       bool "Serial-3"
+       help
+         Use serial port 3 for kernel debugging.
+
+endchoice
 
 source arch/cris/arch-v10/Kconfig
 source arch/cris/arch-v32/Kconfig
@@ -165,6 +263,387 @@ menu "Drivers for built-in interfaces"
 source arch/cris/arch-v10/drivers/Kconfig
 source arch/cris/arch-v32/drivers/Kconfig
 
+config ETRAX_AXISFLASHMAP
+       bool "Axis flash-map support"
+       select MTD
+       select MTD_CFI
+       select MTD_CFI_AMDSTD
+       select MTD_JEDECPROBE if ETRAX_ARCH_V32
+       select MTD_CHAR
+       select MTD_BLOCK
+       select MTD_PARTITIONS
+       select MTD_CONCAT
+       select MTD_COMPLEX_MAPPINGS
+       help
+         This option enables MTD mapping of flash devices.  Needed to use
+         flash memories.  If unsure, say Y.
+
+config ETRAX_RTC
+       bool "Real Time Clock support"
+       depends on ETRAX_I2C
+       help
+         Enables drivers for the Real-Time Clock battery-backed chips on
+         some products. The kernel reads the time when booting, and
+         the date can be set using ioctl(fd, RTC_SET_TIME, &rt) with rt a
+         rtc_time struct (see <file:include/asm-cris/rtc.h>) on the /dev/rtc
+         device.  You can check the time with cat /proc/rtc, but
+         normal time reading should be done using libc function time and
+         friends.
+
+choice
+       prompt "RTC chip"
+       depends on ETRAX_RTC
+       default ETRAX_PCF8563 if ETRAX_ARCH_V32
+       default ETRAX_DS1302 if ETRAX_ARCH_V10
+
+config ETRAX_DS1302
+       depends on ETRAX_ARCH_V10
+       bool "DS1302"
+       help
+         Enables the driver for the DS1302 Real-Time Clock battery-backed
+         chip on some products.
+
+config ETRAX_PCF8563
+       bool "PCF8563"
+       help
+         Enables the driver for the PCF8563 Real-Time Clock battery-backed
+         chip on some products.
+
+endchoice
+
+config ETRAX_SYNCHRONOUS_SERIAL
+       bool "Synchronous serial-port support"
+       help
+         Select this to enable the synchronous serial port driver.
+
+config ETRAX_SYNCHRONOUS_SERIAL_PORT0
+       bool "Synchronous serial port 0 enabled"
+       depends on ETRAX_SYNCHRONOUS_SERIAL
+       help
+         Enabled synchronous serial port 0.
+
+config ETRAX_SYNCHRONOUS_SERIAL0_DMA
+       bool "Enable DMA on synchronous serial port 0."
+       depends on ETRAX_SYNCHRONOUS_SERIAL_PORT0
+       help
+         A synchronous serial port can run in manual or DMA mode.
+         Selecting this option will make it run in DMA mode.
+
+config ETRAX_SYNCHRONOUS_SERIAL_PORT1
+       bool "Synchronous serial port 1 enabled"
+       depends on ETRAX_SYNCHRONOUS_SERIAL && (ETRAXFS || ETRAX_ARCH_V10)
+       help
+         Enabled synchronous serial port 1.
+
+config ETRAX_SYNCHRONOUS_SERIAL1_DMA
+       bool "Enable DMA on synchronous serial port 1."
+       depends on ETRAX_SYNCHRONOUS_SERIAL_PORT1
+       help
+         A synchronous serial port can run in manual or DMA mode.
+         Selecting this option will make it run in DMA mode.
+
+choice
+       prompt "Network LED behavior"
+       depends on ETRAX_ETHERNET
+       default ETRAX_NETWORK_LED_ON_WHEN_ACTIVITY
+
+config ETRAX_NETWORK_LED_ON_WHEN_LINK
+       bool "LED_on_when_link"
+       help
+         Selecting LED_on_when_link will light the LED when there is a
+         connection and will flash off when there is activity.
+
+         Selecting LED_on_when_activity will light the LED only when
+         there is activity.
+
+         This setting will also affect the behaviour of other activity LEDs
+         e.g. Bluetooth.
+
+config ETRAX_NETWORK_LED_ON_WHEN_ACTIVITY
+       bool "LED_on_when_activity"
+       help
+         Selecting LED_on_when_link will light the LED when there is a
+         connection and will flash off when there is activity.
+
+         Selecting LED_on_when_activity will light the LED only when
+         there is activity.
+
+         This setting will also affect the behaviour of other activity LEDs
+         e.g. Bluetooth.
+
+endchoice
+
+choice
+       prompt "Ser0 DMA out channel"
+       depends on ETRAX_SERIAL_PORT0
+       default ETRAX_SERIAL_PORT0_DMA6_OUT if ETRAX_ARCH_V32
+       default ETRAX_SERIAL_PORT0_NO_DMA_OUT if ETRAX_ARCH_V10
+
+config ETRAX_SERIAL_PORT0_NO_DMA_OUT
+       bool "Ser0 uses no DMA for output"
+       help
+         Do not use DMA for ser0 output.
+
+config ETRAX_SERIAL_PORT0_DMA6_OUT
+       bool "Ser0 uses DMA6 for output"
+       depends on ETRAXFS
+       help
+         Enables the DMA6 output channel for ser0 (ttyS0).
+         If you do not enable DMA, an interrupt for each character will be
+         used when transmitting data.
+         Normally you want to use DMA, unless you use the DMA channel for
+         something else.
+
+config ETRAX_SERIAL_PORT0_DMA0_OUT
+       bool "Ser0 uses DMA0 for output"
+       depends on CRIS_MACH_ARTPEC3
+       help
+         Enables the DMA0 output channel for ser0 (ttyS0).
+         If you do not enable DMA, an interrupt for each character will be
+         used when transmitting data.
+         Normally you want to use DMA, unless you use the DMA channel for
+         something else.
+
+endchoice
+
+choice
+       prompt "Ser0 DMA in channel "
+       depends on ETRAX_SERIAL_PORT0
+       default ETRAX_SERIAL_PORT0_NO_DMA_IN if ETRAX_ARCH_V32
+       default ETRAX_SERIAL_PORT0_DMA7_IN if ETRAX_ARCH_V10
+       help
+         What DMA channel to use for ser0.
+
+config ETRAX_SERIAL_PORT0_NO_DMA_IN
+       bool "Ser0 uses no DMA for input"
+       help
+         Do not use DMA for ser0 input.
+
+config ETRAX_SERIAL_PORT0_DMA7_IN
+       bool "Ser0 uses DMA7 for input"
+       depends on ETRAXFS
+       help
+         Enables the DMA7 input channel for ser0 (ttyS0).
+         If you do not enable DMA, an interrupt for each character will be
+         used when receiving data.
+         Normally you want to use DMA, unless you use the DMA channel for
+         something else.
+
+config ETRAX_SERIAL_PORT0_DMA1_IN
+       bool "Ser0 uses DMA1 for input"
+       depends on CRIS_MACH_ARTPEC3
+       help
+         Enables the DMA1 input channel for ser0 (ttyS0).
+         If you do not enable DMA, an interrupt for each character will be
+         used when receiveing data.
+         Normally you want to use DMA, unless you use the DMA channel for
+         something else.
+
+endchoice
+
+choice
+       prompt "Ser1 DMA in channel "
+       depends on ETRAX_SERIAL_PORT1
+       default ETRAX_SERIAL_PORT1_NO_DMA_IN if ETRAX_ARCH_V32
+       default ETRAX_SERIAL_PORT1_DMA9_IN if ETRAX_ARCH_V10
+       help
+         What DMA channel to use for ser1.
+
+config ETRAX_SERIAL_PORT1_NO_DMA_IN
+       bool "Ser1 uses no DMA for input"
+       help
+         Do not use DMA for ser1 input.
+
+config ETRAX_SERIAL_PORT1_DMA5_IN
+       bool "Ser1 uses DMA5 for input"
+       depends on ETRAX_ARCH_V32
+       help
+         Enables the DMA5 input channel for ser1 (ttyS1).
+         If you do not enable DMA, an interrupt for each character will be
+         used when receiving data.
+         Normally you want this on, unless you use the DMA channel for
+         something else.
+
+config ETRAX_SERIAL_PORT1_DMA9_IN
+       depends on ETRAX_ARCH_V10
+       bool "Ser1 uses DMA9 for input"
+
+endchoice
+
+
+choice
+       prompt "Ser1 DMA out channel"
+       depends on ETRAX_SERIAL_PORT1
+       default ETRAX_SERIAL_PORT1_NO_DMA_OUT if ETRAX_ARCH_V32
+       default ETRAX_SERIAL_PORT1_DMA8_OUT if ETRAX_ARCH_V10
+       help
+         What DMA channel to use for ser1.
+
+config ETRAX_SERIAL_PORT1_NO_DMA_OUT
+       bool "Ser1 uses no DMA for output"
+       help
+         Do not use DMA for ser1 output.
+
+config ETRAX_SERIAL_PORT1_DMA8_OUT
+       depends on ETRAX_ARCH_V10
+       bool "Ser1 uses DMA8 for output"
+
+config ETRAX_SERIAL_PORT1_DMA4_OUT
+       depends on ETRAX_ARCH_V32
+       bool "Ser1 uses DMA4 for output"
+       help
+         Enables the DMA4 output channel for ser1 (ttyS1).
+         If you do not enable DMA, an interrupt for each character will be
+         used when transmitting data.
+         Normally you want this on, unless you use the DMA channel for
+         something else.
+
+endchoice
+
+choice
+       prompt "Ser2 DMA out channel"
+       depends on ETRAX_SERIAL_PORT2
+       default ETRAX_SERIAL_PORT2_NO_DMA_OUT if ETRAX_ARCH_V32
+       default ETRAX_SERIAL_PORT2_DMA2_OUT if ETRAX_ARCH_V10
+
+config ETRAX_SERIAL_PORT2_NO_DMA_OUT
+       bool "Ser2 uses no DMA for output"
+       help
+         Do not use DMA for ser2 output.
+
+config ETRAX_SERIAL_PORT2_DMA2_OUT
+       bool "Ser2 uses DMA2 for output"
+       depends on ETRAXFS || ETRAX_ARCH_V10
+       help
+         Enables the DMA2 output channel for ser2 (ttyS2).
+         If you do not enable DMA, an interrupt for each character will be
+         used when transmitting data.
+         Normally you want to use DMA, unless you use the DMA channel for
+         something else.
+
+config ETRAX_SERIAL_PORT2_DMA6_OUT
+       bool "Ser2 uses DMA6 for output"
+       depends on CRIS_MACH_ARTPEC3
+       help
+         Enables the DMA6 output channel for ser2 (ttyS2).
+         If you do not enable DMA, an interrupt for each character will be
+         used when transmitting data.
+         Normally you want to use DMA, unless you use the DMA channel for
+         something else.
+
+endchoice
+
+choice
+       prompt "Ser2 DMA in channel"
+       depends on ETRAX_SERIAL_PORT2
+       default ETRAX_SERIAL_PORT2_NO_DMA_IN if ETRAX_ARCH_V32
+       default ETRAX_SERIAL_PORT2_DMA3_IN if ETRAX_ARCH_V10
+       help
+         What DMA channel to use for ser2.
+
+config ETRAX_SERIAL_PORT2_NO_DMA_IN
+       bool "Ser2 uses no DMA for input"
+       help
+         Do not use DMA for ser2 input.
+
+config ETRAX_SERIAL_PORT2_DMA3_IN
+       bool "Ser2 uses DMA3 for input"
+       depends on ETRAXFS || ETRAX_ARCH_V10
+       help
+         Enables the DMA3 input channel for ser2 (ttyS2).
+         If you do not enable DMA, an interrupt for each character will be
+         used when receiving data.
+         Normally you want to use DMA, unless you use the DMA channel for
+         something else.
+
+config ETRAX_SERIAL_PORT2_DMA7_IN
+       bool "Ser2 uses DMA7 for input"
+       depends on CRIS_MACH_ARTPEC3
+       help
+         Enables the DMA7 input channel for ser2 (ttyS2).
+         If you do not enable DMA, an interrupt for each character will be
+         used when receiveing data.
+         Normally you want to use DMA, unless you use the DMA channel for
+         something else.
+
+endchoice
+
+choice
+       prompt "Ser3 DMA in channel"
+       depends on ETRAX_SERIAL_PORT3
+       default ETRAX_SERIAL_PORT3_NO_DMA_IN if ETRAX_ARCH_V32
+       default ETRAX_SERIAL_PORT3_DMA5_IN if ETRAX_ARCH_V10
+       help
+         What DMA channel to use for ser3.
+
+config ETRAX_SERIAL_PORT3_NO_DMA_IN
+       bool "Ser3 uses no DMA for input"
+       help
+         Do not use DMA for ser3 input.
+
+config ETRAX_SERIAL_PORT3_DMA5_IN
+       depends on ETRAX_ARCH_V10
+       bool "DMA 5"
+
+config ETRAX_SERIAL_PORT3_DMA9_IN
+       bool "Ser3 uses DMA9 for input"
+       depends on ETRAXFS
+       help
+         Enables the DMA9 input channel for ser3 (ttyS3).
+         If you do not enable DMA, an interrupt for each character will be
+         used when receiving data.
+         Normally you want to use DMA, unless you use the DMA channel for
+         something else.
+
+config ETRAX_SERIAL_PORT3_DMA3_IN
+       bool "Ser3 uses DMA3 for input"
+       depends on CRIS_MACH_ARTPEC3
+       help
+         Enables the DMA3 input channel for ser3 (ttyS3).
+         If you do not enable DMA, an interrupt for each character will be
+         used when receiveing data.
+         Normally you want to use DMA, unless you use the DMA channel for
+         something else.
+
+endchoice
+
+choice
+       prompt "Ser3 DMA out channel"
+       depends on ETRAX_SERIAL_PORT3
+       default ETRAX_SERIAL_PORT3_NO_DMA_OUT if ETRAX_ARCH_V32
+       default ETRAX_SERIAL_PORT3_DMA4_OUT if ETRAX_ARCH_V10
+
+config ETRAX_SERIAL_PORT3_NO_DMA_OUT
+       bool "Ser3 uses no DMA for output"
+       help
+         Do not use DMA for ser3 output.
+
+config ETRAX_SERIAL_PORT3_DMA4_OUT
+       depends on ETRAX_ARCH_V10
+       bool "DMA 4"
+
+config ETRAX_SERIAL_PORT3_DMA8_OUT
+       bool "Ser3 uses DMA8 for output"
+       depends on ETRAXFS
+       help
+         Enables the DMA8 output channel for ser3 (ttyS3).
+         If you do not enable DMA, an interrupt for each character will be
+         used when transmitting data.
+         Normally you want to use DMA, unless you use the DMA channel for
+         something else.
+
+config ETRAX_SERIAL_PORT3_DMA2_OUT
+       bool "Ser3 uses DMA2 for output"
+       depends on CRIS_MACH_ARTPEC3
+       help
+         Enables the DMA2 output channel for ser3 (ttyS3).
+         If you do not enable DMA, an interrupt for each character will be
+         used when transmitting data.
+         Normally you want to use DMA, unless you use the DMA channel for
+         something else.
+
+endchoice
+
 endmenu
 
 source "drivers/base/Kconfig"
@@ -178,22 +657,10 @@ source "drivers/pnp/Kconfig"
 
 source "drivers/block/Kconfig"
 
-source "drivers/md/Kconfig"
-
 source "drivers/ide/Kconfig"
 
-source "drivers/scsi/Kconfig"
-
-source "drivers/ieee1394/Kconfig"
-
-source "drivers/message/i2o/Kconfig"
-
 source "drivers/net/Kconfig"
 
-source "drivers/isdn/Kconfig"
-
-source "drivers/telephony/Kconfig"
-
 source "drivers/i2c/Kconfig"
 
 source "drivers/rtc/Kconfig"
@@ -205,17 +672,8 @@ source "drivers/input/Kconfig"
 
 source "drivers/char/Kconfig"
 
-#source drivers/misc/Config.in
-source "drivers/media/Kconfig"
-
 source "fs/Kconfig"
 
-source "sound/Kconfig"
-
-source "drivers/pcmcia/Kconfig"
-
-source "drivers/pci/Kconfig"
-
 source "drivers/usb/Kconfig"
 
 source "arch/cris/Kconfig.debug"
index e6bf00c262e06fa5f1ec94d2420c38df8a76d7d6..838cd2ae03ae53ffdb130bedec3f90e225d676b8 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.28 2005/03/17 10:44:37 larsv Exp $
+#
 # cris/Makefile
 #
 # This file is included by the global makefile so that you can add your own
 # License.  See the file "COPYING" in the main directory of this archive
 # for more details.
 
-# A bug in ld prevents us from having a (constant-value) symbol in a
-# "ORIGIN =" or "LENGTH =" expression.
-
 arch-y := v10
 arch-$(CONFIG_ETRAX_ARCH_V10) := v10
 arch-$(CONFIG_ETRAX_ARCH_V32) := v32
 
-# No config avaiable for make clean etc
+# No config available for make clean etc
+mach-y := fs
+mach-$(CONFIG_CRIS_MACH_ARTPEC3) := a3
+mach-$(CONFIG_ETRAXFS) := fs
+
 ifneq ($(arch-y),)
 SARCH := arch-$(arch-y)
 else
 SARCH :=
 endif
 
+ifneq ($(mach-y),)
+MACH := mach-$(mach-y)
+else
+MACH :=
+endif
+
 LD = $(CROSS_COMPILE)ld -mcrislinux
 
 OBJCOPYFLAGS := -O binary -R .note -R .comment -S
 
 CPPFLAGS_vmlinux.lds = -DDRAM_VIRTUAL_BASE=0x$(CONFIG_ETRAX_DRAM_VIRTUAL_BASE)
-KBUILD_AFLAGS += -mlinux
 
-KBUILD_CFLAGS += -mlinux -march=$(arch-y) -pipe
+KBUILD_AFLAGS += -mlinux -march=$(arch-y) -Iinclude/asm/arch/mach -Iinclude/asm/arch
+
+KBUILD_CFLAGS += -mlinux -march=$(arch-y) -pipe -Iinclude/asm/arch/mach -Iinclude/asm/arch
 
 ifdef CONFIG_FRAME_POINTER
 KBUILD_CFLAGS := $(subst -fomit-frame-pointer,,$(KBUILD_CFLAGS)) -g
@@ -44,6 +52,9 @@ LIBGCC = $(shell $(CC) $(KBUILD_CFLAGS) -print-file-name=libgcc.a)
 
 core-y         += arch/$(ARCH)/kernel/ arch/$(ARCH)/mm/
 core-y         += arch/$(ARCH)/$(SARCH)/kernel/ arch/$(ARCH)/$(SARCH)/mm/
+ifdef CONFIG_ETRAX_ARCH_V32
+core-y         += arch/$(ARCH)/$(SARCH)/$(MACH)/
+endif
 drivers-y      += arch/$(ARCH)/$(SARCH)/drivers/
 libs-y         += arch/$(ARCH)/$(SARCH)/lib/ $(LIBGCC)
 
@@ -52,79 +63,69 @@ SRC_ARCH              = $(srctree)/arch/$(ARCH)
 # cris object files path
 OBJ_ARCH              = $(objtree)/arch/$(ARCH)
 
-target_boot_arch_dir  = $(OBJ_ARCH)/$(SARCH)/boot
-target_boot_dir       = $(OBJ_ARCH)/boot
-src_boot_dir          = $(SRC_ARCH)/boot
-target_compressed_dir = $(OBJ_ARCH)/boot/compressed
-src_compressed_dir    = $(SRC_ARCH)/boot/compressed
-target_rescue_dir     = $(OBJ_ARCH)/boot/rescue
-src_rescue_dir        = $(SRC_ARCH)/boot/rescue
-
-export target_boot_arch_dir target_boot_dir src_boot_dir target_compressed_dir src_compressed_dir target_rescue_dir src_rescue_dir
-
-vmlinux.bin: vmlinux
-       $(OBJCOPY) $(OBJCOPYFLAGS) vmlinux vmlinux.bin
-
-timage: vmlinux.bin
-       cat vmlinux.bin cramfs.img >timage
-
-simimage: timage
-       cp vmlinux.bin simvmlinux.bin
-
-# the following will remake timage without compiling the kernel
-# it does of course require that all object files exist...
-
-cramfs:
-## cramfs      - Creates a cramfs image
-       mkcramfs -b 8192 -m romfs_meta.txt root cramfs.img
-       cat vmlinux.bin cramfs.img >timage
+boot := arch/$(ARCH)/boot
+MACHINE := arch/$(ARCH)/$(SARCH)
 
-clinux: vmlinux.bin decompress.bin rescue.bin
+all: zImage
 
-decompress.bin: $(target_boot_dir)
-       @$(MAKE) -f $(src_compressed_dir)/Makefile $(target_compressed_dir)/decompress.bin
+zImage Image: vmlinux
+       $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@
 
-$(target_rescue_dir)/rescue.bin: $(target_boot_dir)
-       @$(MAKE) -f $(src_rescue_dir)/Makefile $(target_rescue_dir)/rescue.bin
-
-zImage: $(target_boot_dir) vmlinux.bin $(target_rescue_dir)/rescue.bin
-## zImage     - Compressed kernel (gzip)
-       @$(MAKE) -f $(src_boot_dir)/Makefile zImage
-
-$(target_boot_dir): $(target_boot_arch_dir)
-       ln -sfn $< $@
-
-$(target_boot_arch_dir):
-       mkdir -p $@
-
-compressed: zImage
-
-archmrproper:
-archclean:
-       @if [ -d arch/$(ARCH)/boot ]; then \
-               $(MAKE) $(clean)=arch/$(ARCH)/boot ; \
-       fi
-       rm -f timage vmlinux.bin decompress.bin rescue.bin cramfs.img
-       rm -rf $(LD_SCRIPT).tmp
-
-archprepare: $(SRC_ARCH)/.links $(srctree)/include/asm-$(ARCH)/.arch
+archprepare: $(SRC_ARCH)/.links $(srctree)/include/asm-$(ARCH)/.arch FORCE
 
 # Create some links to make all tools happy
 $(SRC_ARCH)/.links:
        @rm -rf $(SRC_ARCH)/drivers
-       @ln -sfn $(SRC_ARCH)/$(SARCH)/drivers $(SRC_ARCH)/drivers
+       @ln -sfn $(SARCH)/drivers $(SRC_ARCH)/drivers
        @rm -rf $(SRC_ARCH)/boot
-       @ln -sfn $(SRC_ARCH)/$(SARCH)/boot $(SRC_ARCH)/boot
+       @ln -sfn $(SARCH)/boot $(SRC_ARCH)/boot
        @rm -rf $(SRC_ARCH)/lib
-       @ln -sfn $(SRC_ARCH)/$(SARCH)/lib $(SRC_ARCH)/lib
-       @ln -sfn $(SRC_ARCH)/$(SARCH) $(SRC_ARCH)/arch
-       @ln -sfn $(SRC_ARCH)/$(SARCH)/vmlinux.lds.S $(SRC_ARCH)/kernel/vmlinux.lds.S
-       @ln -sfn $(SRC_ARCH)/$(SARCH)/kernel/asm-offsets.c $(SRC_ARCH)/kernel/asm-offsets.c
+       @ln -sfn $(SARCH)/lib $(SRC_ARCH)/lib
+       @rm -f $(SRC_ARCH)/arch/mach
+       @rm -rf $(SRC_ARCH)/arch
+       @ln -sfn $(SARCH) $(SRC_ARCH)/arch
+ifdef CONFIG_ETRAX_ARCH_V32
+       @ln -sfn ../$(SARCH)/$(MACH) $(SRC_ARCH)/arch/mach
+endif
+       @rm -rf $(SRC_ARCH)/kernel/vmlinux.lds.S
+       @ln -sfn ../$(SARCH)/vmlinux.lds.S $(SRC_ARCH)/kernel/vmlinux.lds.S
+       @rm -rf $(SRC_ARCH)/kernel/asm-offsets.c
+       @ln -sfn ../$(SARCH)/kernel/asm-offsets.c $(SRC_ARCH)/kernel/asm-offsets.c
        @touch $@
 
 # Create link to sub arch includes
 $(srctree)/include/asm-$(ARCH)/.arch: $(wildcard include/config/arch/*.h)
-       @echo '  Making $(srctree)/include/asm-$(ARCH)/arch -> $(srctree)/include/asm-$(ARCH)/$(SARCH) symlink'
-       @rm -f include/asm-$(ARCH)/arch
-       @ln -sf $(srctree)/include/asm-$(ARCH)/$(SARCH) $(srctree)/include/asm-$(ARCH)/arch
+       @echo '  SYMLINK include/asm-$(ARCH)/arch -> include/asm-$(ARCH)/$(SARCH)'
+       @rm -f $(srctree)/include/asm-$(ARCH)/arch/mach
+       @rm -f $(srctree)/include/asm-$(ARCH)/arch
+       @ln -sf $(SARCH) $(srctree)/include/asm-$(ARCH)/arch
+ifdef CONFIG_ETRAX_ARCH_V32
+       @ln -sf $(MACH) $(srctree)/include/asm-$(ARCH)/arch/mach
+endif
        @touch $@
+
+archclean:
+       $(Q)if [ -e arch/$(ARCH)/boot ]; then \
+               $(MAKE) $(clean)=arch/$(ARCH)/boot; \
+       fi
+
+CLEAN_FILES += \
+       $(MACHINE)/boot/zImage \
+       $(MACHINE)/boot/compressed/decompress.bin \
+       $(MACHINE)/boot/compressed/piggy.gz \
+       $(MACHINE)/boot/rescue/rescue.bin \
+       $(SRC_ARCH)/.links \
+       $(srctree)/include/asm-$(ARCH)/.arch
+
+MRPROPER_FILES += \
+       $(SRC_ARCH)/drivers \
+       $(SRC_ARCH)/boot \
+       $(SRC_ARCH)/lib \
+       $(SRC_ARCH)/arch \
+       $(SRC_ARCH)/kernel/vmlinux.lds.S \
+       $(SRC_ARCH)/kernel/asm-offsets.c
+
+define archhelp
+  echo  '* zImage        - Compressed kernel image (arch/$(ARCH)/boot/zImage)'
+  echo  '* Image         - Uncompressed kernel image (arch/$(ARCH)/boot/Image)'
+endef
index 1d61faec77cd0b01241462104bf1747e3b6a508d..adc164e99339b44e49321a269a61de21c8232ee2 100644 (file)
@@ -1,5 +1,7 @@
 if ETRAX_ARCH_V10
 
+menu "CRIS v10 options"
+
 # ETRAX 100LX v1 has a MMU "feature" requiring a low mapping
 config CRIS_LOW_MAP
        bool
@@ -228,69 +230,6 @@ config ETRAX_LED12R
          For products with only one or two controllable LEDs,
          set this to same as CONFIG_ETRAX_LED1G (normally 2).
 
-choice
-       prompt "Product debug-port"
-       depends on ETRAX_ARCH_V10
-       default ETRAX_DEBUG_PORT0
-
-config ETRAX_DEBUG_PORT0
-       bool "Serial-0"
-       help
-         Choose a serial port for the ETRAX debug console.  Default to
-         port 0.
-
-config ETRAX_DEBUG_PORT1
-       bool "Serial-1"
-       help
-         Use serial port 1 for the console.
-
-config ETRAX_DEBUG_PORT2
-       bool "Serial-2"
-       help
-         Use serial port 2 for the console.
-
-config ETRAX_DEBUG_PORT3
-       bool "Serial-3"
-       help
-         Use serial port 3 for the console.
-
-config ETRAX_DEBUG_PORT_NULL
-       bool "disabled"
-       help
-         Disable serial-port debugging.
-
-endchoice
-
-choice
-       prompt "Kernel GDB port"
-       depends on ETRAX_KGDB
-       default ETRAX_KGDB_PORT0
-       help
-         Choose a serial port for kernel debugging.  NOTE: This port should
-         not be enabled under Drivers for built-in interfaces (as it has its
-         own initialization code) and should not be the same as the debug port.
-
-config ETRAX_KGDB_PORT0
-       bool "Serial-0"
-       help
-         Use serial port 0 for kernel debugging.
-
-config ETRAX_KGDB_PORT1
-       bool "Serial-1"
-       help
-         Use serial port 1 for kernel debugging.
-
-config ETRAX_KGDB_PORT2
-       bool "Serial-2"
-       help
-         Use serial port 2 for kernel debugging.
-
-config ETRAX_KGDB_PORT3
-       bool "Serial-3"
-       help
-         Use serial port 3 for kernel debugging.
-
-endchoice
 
 choice
        prompt "Product rescue-port"
@@ -454,4 +393,6 @@ config ETRAX_POWERBUTTON_BIT
        help
          Configure where power button is connected.
 
+endmenu
+
 endif
index e5b105851108999126ba802426869dbc54dd2714..20c83a53caf35d494066ba1c01ff9771a86d0c74 100644 (file)
@@ -1,13 +1,21 @@
 #
-# arch/cris/boot/Makefile
+# arch/cris/arch-v10/boot/Makefile
 #
-target = $(target_boot_dir)
-src    = $(src_boot_dir)
 
-zImage: compressed/vmlinuz
+OBJCOPY = objcopy-cris
+OBJCOPYFLAGS = -O binary --remove-section=.bss
 
-compressed/vmlinuz:
-       @$(MAKE) -f $(src)/compressed/Makefile $(target_compressed_dir)/vmlinuz
+subdir- := compressed rescue
+targets := Image
 
-clean:
-       @$(MAKE) -f $(src)/compressed/Makefile clean
+$(obj)/Image: vmlinux FORCE
+       $(call if_changed,objcopy)
+       @echo '  Kernel: $@ is ready'
+
+$(obj)/compressed/vmlinux: $(obj)/Image FORCE
+       $(Q)$(MAKE) $(build)=$(obj)/compressed $@
+       $(Q)$(MAKE) $(build)=$(obj)/rescue $(obj)/rescue/rescue.bin
+
+$(obj)/zImage:  $(obj)/compressed/vmlinux
+       @cp $< $@
+       @echo '  Kernel: $@ is ready'
index 6584a44820f416996f4352073a9620e2e4a1b883..4a031cb27eb905f3ec264fb230486fee0c71d662 100644 (file)
@@ -1,45 +1,35 @@
 #
-# create a compressed vmlinuz image from the binary vmlinux.bin file
+# arch/cris/arch-v10/boot/compressed/Makefile
 #
-target = $(target_compressed_dir)
-src    = $(src_compressed_dir)
 
 CC = gcc-cris -melf $(LINUXINCLUDE)
-CFLAGS = -O2
+ccflags-y += -O2
 LD = ld-cris
+ldflags-y += -T $(obj)/decompress.ld
+OBJECTS = $(obj)/head.o $(obj)/misc.o
 OBJCOPY = objcopy-cris
 OBJCOPYFLAGS = -O binary --remove-section=.bss
-OBJECTS = $(target)/head.o $(target)/misc.o
 
-# files to compress
-SYSTEM = $(objtree)/vmlinux.bin
+quiet_cmd_image = BUILD   $@
+cmd_image = cat $(obj)/decompress.bin $(obj)/piggy.gz > $@
 
-all: $(target_compressed_dir)/vmlinuz
+targets := vmlinux piggy.gz decompress.o decompress.bin
 
-$(target)/decompress.bin: $(OBJECTS)
-       $(LD) -T $(src)/decompress.ld -o $(target)/decompress.o $(OBJECTS)
-       $(OBJCOPY) $(OBJCOPYFLAGS) $(target)/decompress.o $(target)/decompress.bin
+$(obj)/decompress.o: $(OBJECTS) FORCE
+       $(call if_changed,ld)
 
-# Create vmlinuz image in top-level build directory
-$(target_compressed_dir)/vmlinuz: $(target) piggy.img $(target)/decompress.bin
-       @echo "  COMPR   vmlinux.bin --> vmlinuz"
-       @cat $(target)/decompress.bin piggy.img > $(target_compressed_dir)/vmlinuz
-       @rm -f piggy.img
+$(obj)/decompress.bin: $(obj)/decompress.o FORCE
+       $(call if_changed,objcopy)
 
-$(target)/head.o: $(src)/head.S
-       $(CC) -D__ASSEMBLY__ -traditional -c $< -o $@
+$(obj)/head.o: $(obj)/head.S .config
+       @$(CC) -D__ASSEMBLY__ -traditional -c $< -o $@
 
-$(target)/misc.o: $(src)/misc.c
-       $(CC) -D__KERNEL__ -c $< -o $@
+$(obj)/misc.o: $(obj)/misc.c .config
+       @$(CC) -D__KERNEL__ -c $< -o $@
 
-# gzip the kernel image
+$(obj)/vmlinux: $(obj)/piggy.gz $(obj)/decompress.bin FORCE
+       $(call if_changed,image)
 
-piggy.img: $(SYSTEM)
-       @cat $(SYSTEM) | gzip -f -9 > piggy.img
-
-$(target):
-       mkdir -p $(target)
-
-clean:
-       rm -f piggy.img $(objtree)/vmlinuz
+$(obj)/piggy.gz: $(obj)/../Image FORCE
+       $(call if_changed,gzip)
 
index e205d2e7e0897202aed04742d0ff3cd67b399960..9a43ab19391e6a1680068d3f7dabd5b9a9703459 100644 (file)
@@ -1,15 +1,13 @@
 /*
  * misc.c
  *
- * $Id: misc.c,v 1.6 2003/10/27 08:04:31 starvik Exp $
- * 
- * This is a collection of several routines from gzip-1.0.3 
+ * This is a collection of several routines from gzip-1.0.3
  * adapted for Linux.
  *
  * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
  * puts by Nick Holloway 1993, better puts by Martin Mares 1995
  * adaptation for Linux/CRIS Axis Communications AB, 1999
- * 
+ *
  */
 
 /* where the piggybacked kernel image expects itself to live.
index 8be9b31303129456ee43c916b63643069b1aff9d..2e5045b9e19c01ece12a4f97f88c9012c6b431fe 100644 (file)
@@ -1,56 +1,38 @@
 #
-# Makefile for rescue code
+# Makefile for rescue (bootstrap) code
 #
-target = $(target_rescue_dir)
-src    = $(src_rescue_dir)
 
 CC = gcc-cris -mlinux $(LINUXINCLUDE)
-CFLAGS = -O2
+ccflags-y += -O2
+asflags-y += -traditional
 LD = gcc-cris -mlinux -nostdlib
+ldflags-y += -T $(obj)/rescue.ld
 OBJCOPY = objcopy-cris
 OBJCOPYFLAGS = -O binary --remove-section=.bss
+obj-$(CONFIG_ETRAX_AXISFLASHMAP) = head.o
+OBJECT := $(obj)/head.o
 
-all: $(target)/rescue.bin $(target)/testrescue.bin $(target)/kimagerescue.bin
+targets := rescue.o rescue.bin
 
-$(target)/rescue.bin: $(target) $(target)/head.o
-       $(LD) -T $(src)/rescue.ld -o $(target)/rescue.o $(target)/head.o
-       $(OBJCOPY) $(OBJCOPYFLAGS) $(target)/rescue.o $(target)/rescue.bin
-# Place a copy in top-level build directory
-       cp -p $(target)/rescue.bin $(objtree)
+$(obj)/rescue.o: $(OBJECT) FORCE
+       $(call if_changed,ld)
 
-$(target)/testrescue.bin: $(target) $(target)/testrescue.o
-       $(OBJCOPY) $(OBJCOPYFLAGS) $(target)/testrescue.o tr.bin
+$(obj)/rescue.bin: $(obj)/rescue.o FORCE
+       $(call if_changed,objcopy)
+       cp -p $(obj)/rescue.bin $(objtree)
+
+$(obj)/testrescue.bin: $(obj)/testrescue.o
+       $(OBJCOPY) $(OBJCOPYFLAGS) $(obj)/testrescue.o tr.bin
 # Pad it to 784 bytes
        dd if=/dev/zero of=tmp2423 bs=1 count=784
        cat tr.bin tmp2423 >testrescue_tmp.bin
-       dd if=testrescue_tmp.bin of=$(target)/testrescue.bin bs=1 count=784
+       dd if=testrescue_tmp.bin of=$(obj)/testrescue.bin bs=1 count=784
        rm tr.bin tmp2423 testrescue_tmp.bin
 
-$(target)/kimagerescue.bin: $(target) $(target)/kimagerescue.o
-       $(OBJCOPY) $(OBJCOPYFLAGS) $(target)/kimagerescue.o ktr.bin
+$(obj)/kimagerescue.bin: $(obj)/kimagerescue.o
+       $(OBJCOPY) $(OBJCOPYFLAGS) $(obj)/kimagerescue.o ktr.bin
 # Pad it to 784 bytes, that's what the rescue loader expects
        dd if=/dev/zero of=tmp2423 bs=1 count=784
        cat ktr.bin tmp2423 >kimagerescue_tmp.bin
-       dd if=kimagerescue_tmp.bin of=$(target)/kimagerescue.bin bs=1 count=784
+       dd if=kimagerescue_tmp.bin of=$(obj)/kimagerescue.bin bs=1 count=784
        rm ktr.bin tmp2423 kimagerescue_tmp.bin
-
-$(target):
-       mkdir -p $(target)
-
-$(target)/head.o: $(src)/head.S
-       $(CC) -D__ASSEMBLY__ -traditional -c $< -o $*.o
-
-$(target)/testrescue.o: $(src)/testrescue.S
-       $(CC) -D__ASSEMBLY__ -traditional -c $< -o $*.o
-
-$(target)/kimagerescue.o: $(src)/kimagerescue.S
-       $(CC) -D__ASSEMBLY__ -traditional -c $< -o $*.o
-
-clean:
-       rm -f $(target)/*.o $(target)/*.bin
-
-fastdep:
-
-modules:
-
-modules-install:
index f223cc0c00bb0c8a277ce359d78a5ebf7c92db1e..6ba7be8ac4a035a3de225dd276cd9ab31243e8cb 100644 (file)
@@ -1,5 +1,4 @@
-/* $Id: head.S,v 1.7 2005/03/07 12:11:06 starvik Exp $
- * 
+/*
  * Rescue code, made to reside at the beginning of the
  * flash-memory. when it starts, it checks a partition
  * table at the first sector after the rescue sector.
  * Partition table format:
  *
  *     Code transparency:
- * 
+ *
  *     2 bytes    [opcode 'nop']
  *     2 bytes    [opcode 'di']
  *     4 bytes    [opcode 'ba <offset>', 8-bit or 16-bit version]
  *     2 bytes    [opcode 'nop', delay slot]
  *
- *     Table validation (at +10):      
- * 
+ *     Table validation (at +10):
+ *
  *     2 bytes    [magic/version word for partitiontable - 0xef, 0xbe]
  *     2 bytes    [length of all entries plus the end marker]
  *     4 bytes    [checksum for the partitiontable itself]
  *
- *     Entries, each with the following format, last has offset -1:    
- *    
+ *     Entries, each with the following format, last has offset -1:
+ *
  *        4 bytes    [offset in bytes, from start of flash]
  *        4 bytes    [length in bytes of partition]
  *        4 bytes    [checksum, simple longword sum]
@@ -47,9 +46,9 @@
  *     End marker
  *
  *        4 bytes    [-1]
- * 
+ *
  *      10 bytes    [0, padding]
- * 
+ *
  * Bit 0 in flags signifies RW or RO. The rescue code only bothers
  * to check the checksum for RO partitions, since the others will
  * change their data without updating the checksums. A 1 in bit 0
  *
  * During the wait for serial input, the status LED will flash so the
  * user knows something went wrong.
- * 
- * Copyright (C) 1999, 2000, 2001, 2002, 2003 Axis Communications AB
+ *
+ * Copyright (C) 1999-2007 Axis Communications AB
  */
 
+#ifdef CONFIG_ETRAX_AXISFLASHMAP
+
 #define ASSEMBLER_MACROS_ONLY
 #include <asm/arch/sv_addr_ag.h>
 
        ;; The partitiontable is looked for at the first sector after the boot
        ;; sector. Sector size is 65536 bytes in all flashes we use.
-               
+
 #define PTABLE_START CONFIG_ETRAX_PTABLE_SECTOR
 #define PTABLE_MAGIC 0xbeef
 
        ;; The normal Etrax100 on-chip boot ROM does serial boot at 0x380000f0.
-       ;; That is not where we put our downloaded serial boot-code. The length is
-       ;; enough for downloading code that loads the rest of itself (after
-       ;; having setup the DRAM etc). It is the same length as the on-chip
-       ;; ROM loads, so the same host loader can be used to load a rescued
-       ;; product as well as one booted through the Etrax serial boot code.
-               
+       ;; That is not where we put our downloaded serial boot-code.
+       ;; The length is enough for downloading code that loads the rest
+       ;; of itself (after having setup the DRAM etc).
+       ;; It is the same length as the on-chip ROM loads, so the same
+       ;; host loader can be used to load a rescued product as well as
+       ;; one booted through the Etrax serial boot code.
+
 #define CODE_START 0x40000000
 #define CODE_LENGTH 784
 
 #define SERRECC R_SERIAL2_REC_CTRL
 #define SERRDAT R_SERIAL2_REC_DATA
 #define SERSTAT R_SERIAL2_STATUS
-#endif 
+#endif
 #ifdef CONFIG_ETRAX_RESCUE_SER3
 #define SERXOFF R_SERIAL3_XOFF
 #define SERBAUD R_SERIAL3_BAUD
 #define RAM_INIT_MAGIC 0x56902387
 
        .text
-       
+
        ;; This is the entry point of the rescue code
        ;; 0x80000000 if loaded in flash (as it should be)
-       ;; since etrax actually starts at address 2 when booting from flash, we
+       ;; Since etrax actually starts at address 2 when booting from flash, we
        ;; put a nop (2 bytes) here first so we dont accidentally skip the di
 
-       nop     
+       nop
        di
 
        jump    in_cache        ; enter cached area instead
 in_cache:
 
 
-       ;; first put a jump test to give a possibility of upgrading the rescue code
-       ;; without erasing/reflashing the sector. we put a longword of -1 here and if
-       ;; it is not -1, we jump using the value as jump target. since we can always
-       ;; change 1's to 0's without erasing the sector, it is possible to add new
+       ;; First put a jump test to give a possibility of upgrading the
+       ;; rescue code without erasing/reflashing the sector.
+       ;; We put a longword of -1 here and if it is not -1, we jump using
+       ;; the value as jump target. Since we can always change 1's to 0's
+       ;; without erasing the sector, it is possible to add new
        ;; code after this and altering the jumptarget in an upgrade.
 
 jtcd:  move.d  [jumptarget], $r0
        cmp.d   0xffffffff, $r0
        beq     no_newjump
        nop
-       
+
        jump    [$r0]
 
-jumptarget:    
+jumptarget:
        .dword  0xffffffff      ; can be overwritten later to insert new code
-       
+
 no_newjump:
-#ifdef CONFIG_ETRAX_ETHERNET           
+#ifdef CONFIG_ETRAX_ETHERNET
        ;; Start MII clock to make sure it is running when tranceiver is reset
        move.d 0x3, $r0    ; enable = on, phy = mii_clk
        move.d $r0, [R_NETWORK_GEN_CONFIG]
 #endif
-       
+
        ;; We need to setup the bus registers before we start using the DRAM
 #include "../../lib/dram_init.S"
 
        ;; we now should go through the checksum-table and check the listed
        ;; partitions for errors.
-       
+
        move.d  PTABLE_START, $r3
        move.d  [$r3], $r0
        cmp.d   NOP_DI, $r0     ; make sure the nop/di is there...
        bne     do_rescue
        nop
-       
+
        ;; skip the code transparency block (10 bytes).
 
        addq    10, $r3
-       
+
        ;; check for correct magic
-       
+
        move.w  [$r3+], $r0
        cmp.w   PTABLE_MAGIC, $r0
        bne     do_rescue       ; didn't recognize - trig rescue
@@ -186,11 +189,11 @@ no_newjump:
        cmp.d   $r0, $r4
        bne     do_rescue       ; didn't match - trig rescue
        nop
-       
+
        ;; ptable is ok. validate each entry.
 
        moveq   -1, $r7
-       
+
 ploop: move.d  [$r3+], $r1     ; partition offset (from ptable start)
        bne     notfirst        ; check if it is the partition containing ptable
        nop                     ; yes..
@@ -199,7 +202,7 @@ ploop:      move.d  [$r3+], $r1     ; partition offset (from ptable start)
        sub.d   $r8, $r2        ; minus the ptable length
        ba      bosse
        nop
-notfirst:      
+notfirst:
        cmp.d   -1, $r1         ; the end of the ptable ?
        beq     flash_ok        ;   if so, the flash is validated
        move.d  [$r3+], $r2     ; partition length
@@ -213,47 +216,46 @@ bosse:    move.d  [$r3+], $r5     ; checksum
        bpl     1f
        nop
        move.d  $r1, $r7        ; remember boot partition offset
-1:     
-
+1:
        add.d   PTABLE_START, $r1
-       
+
        jsr     checksum        ; checksum the partition
-       
+
        cmp.d   $r0, $r5
        beq     ploop           ; checksums matched, go to next entry
        nop
 
        ;; otherwise fall through to the rescue code.
-       
+
 do_rescue:
        ;; setup port PA and PB default initial directions and data
        ;; (so we can flash LEDs, and so that DTR and others are set)
-       
+
        move.b  CONFIG_ETRAX_DEF_R_PORT_PA_DIR, $r0
        move.b  $r0, [R_PORT_PA_DIR]
        move.b  CONFIG_ETRAX_DEF_R_PORT_PA_DATA, $r0
        move.b  $r0, [R_PORT_PA_DATA]
-       
+
        move.b  CONFIG_ETRAX_DEF_R_PORT_PB_DIR, $r0
        move.b  $r0, [R_PORT_PB_DIR]
        move.b  CONFIG_ETRAX_DEF_R_PORT_PB_DATA, $r0
        move.b  $r0, [R_PORT_PB_DATA]
 
        ;; setup the serial port at 115200 baud
-       
+
        moveq   0, $r0
-       move.d  $r0, [SERXOFF] 
+       move.d  $r0, [SERXOFF]
 
        move.b  0x99, $r0
-       move.b  $r0, [SERBAUD]          ; 115.2kbaud for both transmit and receive
+       move.b  $r0, [SERBAUD]  ; 115.2kbaud for both transmit and receive
 
-       move.b  0x40, $r0               ; rec enable
-       move.b  $r0, [SERRECC] 
+       move.b  0x40, $r0       ; rec enable
+       move.b  $r0, [SERRECC]
 
        moveq   0, $r1          ; "timer" to clock out a LED red flash
        move.d  CODE_START, $r3 ; destination counter
        movu.w  CODE_LENGTH, $r4; length
-       
+
 wait_ser:
        addq    1, $r1
 #ifndef CONFIG_ETRAX_NO_LEDS
@@ -272,20 +274,20 @@ wait_ser:
        nop
 1:     not     $r0             ; clear bit
        and.d   $r0, $r2
-2:     
+2:
 #ifdef CONFIG_ETRAX_PA_LEDS
-       move.b  $r2, [R_PORT_PA_DATA]   
-#endif 
+       move.b  $r2, [R_PORT_PA_DATA]
+#endif
 #ifdef CONFIG_ETRAX_PB_LEDS
-       move.b  $r2, [R_PORT_PB_DATA]   
+       move.b  $r2, [R_PORT_PB_DATA]
 #endif
 #ifdef CONFIG_ETRAX_90000000_LEDS
        move.b  $r2, [0x90000000]
 #endif
 #endif
-       
+
        ;; check if we got something on the serial port
-       
+
        move.b  [SERSTAT], $r0
        btstq   0, $r0          ; data_avail
        bpl     wait_ser
@@ -295,14 +297,15 @@ wait_ser:
 
        move.b  [SERRDAT], $r0
        move.b  $r0, [$r3+]
-       
+
        subq    1, $r4          ; decrease length
        bne     wait_ser
        nop
 
        ;; jump into downloaded code
 
-       move.d  RAM_INIT_MAGIC, $r8     ; Tell next product that DRAM is initialized
+       move.d  RAM_INIT_MAGIC, $r8     ; Tell next product that DRAM is
+                                       ; initialized
        jump    CODE_START
 
 flash_ok:
@@ -313,7 +316,8 @@ flash_ok:
        nop
        move.d  PTABLE_START, $r7; otherwise use the ptable start
 1:
-       move.d  RAM_INIT_MAGIC, $r8     ; Tell next product that DRAM is initialized
+       move.d  RAM_INIT_MAGIC, $r8     ; Tell next product that DRAM is
+                                       ; initialized
        jump    $r7             ; boot!
 
 
@@ -327,7 +331,8 @@ checksum:
        moveq   0, $r0
        moveq   CONFIG_ETRAX_FLASH1_SIZE, $r6
 
-       ;; If the first physical flash memory is exceeded wrap to the second one.
+       ;; If the first physical flash memory is exceeded wrap to the
+       ;; second one
        btstq   26, $r1         ; Are we addressing first flash?
        bpl     1f
        nop
@@ -351,3 +356,5 @@ checksum:
 3:     move.d  MEM_CSE1_START, $r1 ; wrap to second flash
        ba      2b
        nop
+
+#endif
index cbccd6316d3908ab12179b52be0bdf6fbd0cc74c..55eeff8bb08ea6ca5d6c36278cadf34688597b43 100644 (file)
@@ -1,5 +1,4 @@
-/* $Id: kimagerescue.S,v 1.1 2001/12/17 13:59:27 bjornw Exp $
- * 
+/*
  * Rescue code to be prepended on a kimage and copied to the
  * rescue serial port.
  * This is called from the rescue code, it will copy received data to
@@ -7,13 +6,13 @@
  */
 
 #define ASSEMBLER_MACROS_ONLY
-#include <asm/sv_addr_ag.h>
+#include <asm/arch/sv_addr_ag.h>
 
 #define CODE_START 0x40004000
 #define CODE_LENGTH 784
 #define TIMEOUT_VALUE 1000
-       
-               
+
+
 #ifdef CONFIG_ETRAX_RESCUE_SER0
 #define SERXOFF R_SERIAL0_XOFF
 #define SERBAUD R_SERIAL0_BAUD
@@ -34,7 +33,7 @@
 #define SERRECC R_SERIAL2_REC_CTRL
 #define SERRDAT R_SERIAL2_REC_DATA
 #define SERSTAT R_SERIAL2_STATUS
-#endif 
+#endif
 #ifdef CONFIG_ETRAX_RESCUE_SER3
 #define SERXOFF R_SERIAL3_XOFF
 #define SERBAUD R_SERIAL3_BAUD
        ;; 0x80000000 if loaded in flash (as it should be)
        ;; since etrax actually starts at address 2 when booting from flash, we
        ;; put a nop (2 bytes) here first so we dont accidentally skip the di
-       
-       nop     
+
+       nop
        di
-#ifndef CONFIG_SVINTO_SIM      
+#ifndef CONFIG_SVINTO_SIM
        ;; setup port PA and PB default initial directions and data
        ;; (so we can flash LEDs, and so that DTR and others are set)
-       
+
        move.b  CONFIG_ETRAX_DEF_R_PORT_PA_DIR, $r0
        move.b  $r0, [R_PORT_PA_DIR]
        move.b  CONFIG_ETRAX_DEF_R_PORT_PA_DATA, $r0
        move.b  $r0, [R_PORT_PA_DATA]
-       
+
        move.b  CONFIG_ETRAX_DEF_R_PORT_PB_DIR, $r0
        move.b  $r0, [R_PORT_PB_DIR]
        move.b  CONFIG_ETRAX_DEF_R_PORT_PB_DATA, $r0
        move.b  $r0, [R_PORT_PB_DATA]
-       
+
        ;; We need to setup the bus registers before we start using the DRAM
 #include "../../lib/dram_init.S"
-       
+
 #endif
        ;; Setup the stack to a suitably high address.
        ;; We assume 8 MB is the minimum DRAM in an eLinux
        ;; product and put the sp at the top for now.
 
        move.d  0x40800000, $sp
-       
+
        ;; setup the serial port at 115200 baud
-       
+
        moveq   0, $r0
-       move.d  $r0, [SERXOFF] 
+       move.d  $r0, [SERXOFF]
 
        move.b  0x99, $r0
-       move.b  $r0, [SERBAUD]          ; 115.2kbaud for both transmit and receive
+       move.b  $r0, [SERBAUD]          ; 115.2kbaud for both transmit
+                                       ; and receive
 
        move.b  0x40, $r0               ; rec enable
-       move.b  $r0, [SERRECC] 
+       move.b  $r0, [SERRECC]
 
 
-       moveq   0, $r1          ; "timer" to clock out a LED red flash
-       move.d  CODE_START, $r3 ; destination counter
+       moveq   0, $r1                  ; "timer" to clock out a LED red flash
+       move.d  CODE_START, $r3         ; destination counter
        move.d  CODE_LENGTH, $r4        ; length
        move.d  TIMEOUT_VALUE, $r5      ; "timeout" until jump
 
 wait_ser:
        addq    1, $r1
-       subq    1, $r5          ; decrease timeout
-       beq     jump_start      ; timed out
+       subq    1, $r5                  ; decrease timeout
+       beq     jump_start              ; timed out
        nop
 #ifndef CONFIG_ETRAX_NO_LEDS
 #ifdef CONFIG_ETRAX_PA_LEDS
@@ -111,21 +111,21 @@ wait_ser:
        or.d    $r0, $r2                ; set bit
        ba      2f
        nop
-1:     not     $r0             ; clear bit
+1:     not     $r0                     ; clear bit
        and.d   $r0, $r2
-2:     
+2:
 #ifdef CONFIG_ETRAX_PA_LEDS
        move.b  $r2, [R_PORT_PA_DATA]
-#endif 
+#endif
 #ifdef CONFIG_ETRAX_PB_LEDS
        move.b  $r2, [R_PORT_PB_DATA]
 #endif
 #endif
-               
+
        ;; check if we got something on the serial port
-       
+
        move.b  [SERSTAT], $r0
-       btstq   0, $r0          ; data_avail
+       btstq   0, $r0                  ; data_avail
        bpl     wait_ser
        nop
 
@@ -134,7 +134,7 @@ wait_ser:
        move.b  [SERRDAT], $r0
        move.b  $r0, [$r3+]
        move.d  TIMEOUT_VALUE, $r5      ; reset "timeout"
-       subq    1, $r4          ; decrease length
+       subq    1, $r4                  ; decrease length
        bne     wait_ser
        nop
 jump_start:
index 566a9f341254478a5aa9596a0ba6dab09b5e77e6..2d937f9afe23c4fe092332757ef351d2a2397ebd 100644 (file)
@@ -1,13 +1,12 @@
-/* $Id: testrescue.S,v 1.1 2001/12/17 13:59:27 bjornw Exp $
- *
+/*
  * Simple testcode to download by the rescue block.
- * Just lits some LEDs to show it was downloaded correctly.
- * 
+ * Just lights some LEDs to show it was downloaded correctly.
+ *
  * Copyright (C) 1999 Axis Communications AB
  */
 
 #define ASSEMBLER_MACROS_ONLY
-#include <asm/sv_addr_ag.h>
+#include <asm/arch/sv_addr_ag.h>
 
        .text
 
        moveq   -1, $r2
        move.b  $r2, [R_PORT_PA_DIR]
        moveq   0, $r2
-       move.b  $r2, [R_PORT_PA_DATA]   
+       move.b  $r2, [R_PORT_PA_DATA]
 
 endless:
        nop
        ba      endless
        nop
 
-       
index 96740ef497d4237ebffc65ffb79afe8a1bdc5f4c..58f5864a668057ff57e5c62c29a64e7d4103ab18 100644 (file)
@@ -9,37 +9,6 @@ config ETRAX_ETHERNET
          This option enables the ETRAX 100LX built-in 10/100Mbit Ethernet
          controller.
 
-choice
-       prompt "Network LED behavior"
-       depends on ETRAX_ETHERNET
-       default ETRAX_NETWORK_LED_ON_WHEN_ACTIVITY
-
-config ETRAX_NETWORK_LED_ON_WHEN_LINK
-       bool "LED_on_when_link"
-       help
-         Selecting LED_on_when_link will light the LED when there is a
-         connection and will flash off when there is activity.
-
-         Selecting LED_on_when_activity will light the LED only when
-         there is activity.
-
-         This setting will also affect the behaviour of other activity LEDs
-         e.g. Bluetooth.
-
-config ETRAX_NETWORK_LED_ON_WHEN_ACTIVITY
-       bool "LED_on_when_activity"
-       help
-         Selecting LED_on_when_link will light the LED when there is a
-         connection and will flash off when there is activity.
-
-         Selecting LED_on_when_activity will light the LED only when
-         there is activity.
-
-         This setting will also affect the behaviour of other activity LEDs
-         e.g. Bluetooth.
-
-endchoice
-
 config ETRAX_SERIAL
        bool "Serial-port support"
        depends on ETRAX_ARCH_V10
@@ -83,32 +52,6 @@ config ETRAX_SERIAL_PORT0
          Normally you want this on, unless you use external DMA 1 that uses
          the same DMA channels.
 
-choice
-       prompt "Ser0 DMA out assignment"
-       depends on ETRAX_SERIAL_PORT0
-       default ETRAX_SERIAL_PORT0_DMA6_OUT
-
-config ETRAX_SERIAL_PORT0_NO_DMA_OUT
-       bool "No DMA out"
-
-config ETRAX_SERIAL_PORT0_DMA6_OUT
-       bool "DMA 6"
-
-endchoice
-
-choice
-       prompt "Ser0 DMA in assignment"
-       depends on ETRAX_SERIAL_PORT0
-       default ETRAX_SERIAL_PORT0_DMA7_IN
-
-config ETRAX_SERIAL_PORT0_NO_DMA_IN
-       bool "No DMA in"
-
-config ETRAX_SERIAL_PORT0_DMA7_IN
-       bool "DMA 7"
-
-endchoice
-
 choice
        prompt "Ser0 DTR, RI, DSR and CD assignment"
        depends on ETRAX_SERIAL_PORT0
@@ -197,32 +140,6 @@ config ETRAX_SERIAL_PORT1
        help
          Enables the ETRAX 100 serial driver for ser1 (ttyS1).
 
-choice
-       prompt "Ser1 DMA out assignment"
-       depends on ETRAX_SERIAL_PORT1
-       default ETRAX_SERIAL_PORT1_DMA8_OUT
-
-config ETRAX_SERIAL_PORT1_NO_DMA_OUT
-       bool "No DMA out"
-
-config ETRAX_SERIAL_PORT1_DMA8_OUT
-       bool "DMA 8"
-
-endchoice
-
-choice
-       prompt "Ser1 DMA in assignment"
-       depends on ETRAX_SERIAL_PORT1
-       default ETRAX_SERIAL_PORT1_DMA9_IN
-
-config ETRAX_SERIAL_PORT1_NO_DMA_IN
-       bool "No DMA in"
-
-config ETRAX_SERIAL_PORT1_DMA9_IN
-       bool "DMA 9"
-
-endchoice
-
 choice
        prompt "Ser1 DTR, RI, DSR and CD assignment"
        depends on ETRAX_SERIAL_PORT1
@@ -314,32 +231,6 @@ config ETRAX_SERIAL_PORT2
        help
          Enables the ETRAX 100 serial driver for ser2 (ttyS2).
 
-choice
-       prompt "Ser2 DMA out assignment"
-       depends on ETRAX_SERIAL_PORT2
-       default ETRAX_SERIAL_PORT2_DMA2_OUT
-
-config ETRAX_SERIAL_PORT2_NO_DMA_OUT
-       bool "No DMA out"
-
-config ETRAX_SERIAL_PORT2_DMA2_OUT
-       bool "DMA 2"
-
-endchoice
-
-choice
-       prompt "Ser2 DMA in assignment"
-       depends on ETRAX_SERIAL_PORT2
-       default ETRAX_SERIAL_PORT2_DMA3_IN
-
-config ETRAX_SERIAL_PORT2_NO_DMA_IN
-       bool "No DMA in"
-
-config ETRAX_SERIAL_PORT2_DMA3_IN
-       bool "DMA 3"
-
-endchoice
-
 choice
        prompt "Ser2 DTR, RI, DSR and CD assignment"
        depends on ETRAX_SERIAL_PORT2
@@ -428,32 +319,6 @@ config ETRAX_SERIAL_PORT3
        help
          Enables the ETRAX 100 serial driver for ser3 (ttyS3).
 
-choice
-       prompt "Ser3 DMA out assignment"
-       depends on ETRAX_SERIAL_PORT3
-       default ETRAX_SERIAL_PORT3_DMA4_OUT
-
-config ETRAX_SERIAL_PORT3_NO_DMA_OUT
-       bool "No DMA out"
-
-config ETRAX_SERIAL_PORT3_DMA4_OUT
-       bool "DMA 4"
-
-endchoice
-
-choice
-       prompt "Ser3 DMA in assignment"
-       depends on ETRAX_SERIAL_PORT3
-       default ETRAX_SERIAL_PORT3_DMA5_IN
-
-config ETRAX_SERIAL_PORT3_NO_DMA_IN
-       bool "No DMA in"
-
-config ETRAX_SERIAL_PORT3_DMA5_IN
-       bool "DMA 5"
-
-endchoice
-
 choice
        prompt "Ser3 DTR, RI, DSR and CD assignment"
        depends on ETRAX_SERIAL_PORT3
@@ -563,21 +428,6 @@ config ETRAX_USB_HOST_PORT2
        depends on ETRAX_USB_HOST
        default n
 
-config ETRAX_AXISFLASHMAP
-       bool "Axis flash-map support"
-       depends on ETRAX_ARCH_V10
-       select MTD
-       select MTD_CFI
-       select MTD_CFI_AMDSTD
-       select MTD_CHAR
-       select MTD_BLOCK
-       select MTD_PARTITIONS
-       select MTD_CONCAT
-       select MTD_COMPLEX_MAPPINGS
-       help
-         This option enables MTD mapping of flash devices.  Needed to use
-         flash memories.  If unsure, say Y.
-
 config ETRAX_PTABLE_SECTOR
        int "Byte-offset of partition table sector"
        depends on ETRAX_AXISFLASHMAP
@@ -731,37 +581,6 @@ config ETRAX_PB_CHANGEABLE_BITS
          Bit set = changeable.
          You probably want 00 here.
 
-config ETRAX_RTC
-       bool "Real Time Clock support"
-       depends on ETRAX_ARCH_V10
-       help
-         Enables drivers for the Real-Time Clock battery-backed chips on
-         some products. The kernel reads the time when booting, and
-         the date can be set using ioctl(fd, RTC_SET_TIME, &rt) with rt a
-         rtc_time struct (see <file:include/asm-cris/rtc.h>) on the /dev/rtc
-         device, major 121.  You can check the time with cat /proc/rtc, but
-         normal time reading should be done using libc function time and
-         friends.
-
-choice
-       prompt "RTC chip"
-       depends on ETRAX_RTC
-       default ETRAX_DS1302
-
-config ETRAX_DS1302
-       bool "DS1302"
-       help
-         Enables the driver for the DS1302 Real-Time Clock battery-backed
-         chip on some products.
-
-config ETRAX_PCF8563
-       bool "PCF8563"
-       help
-         Enables the driver for the PCF8563 Real-Time Clock battery-backed
-         chip on some products.
-
-endchoice
-
 config ETRAX_DS1302_RST_ON_GENERIC_PORT
        bool "DS1302 RST on Generic Port"
        depends on ETRAX_DS1302
index 20258e36f3848b35d0f0b08a0bcc107f2328bb5c..44bf2e88c26e49a7308bcec4df4da97297bfa6c7 100644 (file)
@@ -2,11 +2,11 @@
 # Makefile for Etrax-specific drivers
 #
 
-obj-$(CONFIG_ETRAX_AXISFLASHMAP)        += axisflashmap.o
-obj-$(CONFIG_ETRAX_I2C)                += i2c.o
-obj-$(CONFIG_ETRAX_I2C_EEPROM)          += eeprom.o
-obj-$(CONFIG_ETRAX_GPIO)               += gpio.o
-obj-$(CONFIG_ETRAX_DS1302)              += ds1302.o
+obj-$(CONFIG_ETRAX_AXISFLASHMAP)       += axisflashmap.o
+obj-$(CONFIG_ETRAX_I2C)                        += i2c.o
+obj-$(CONFIG_ETRAX_I2C_EEPROM)         += eeprom.o
+obj-$(CONFIG_ETRAX_GPIO)               += gpio.o
+obj-$(CONFIG_ETRAX_DS1302)             += ds1302.o
 obj-$(CONFIG_ETRAX_PCF8563)            += pcf8563.o
-
+obj-$(CONFIG_ETRAX_SYNCHRONOUS_SERIAL) += sync_serial.o
 
index ea3cf2e39a14d943ab5532f53aeaf1560cd7be32..b3bdda93ffef6280aa2e1d0ee90961d02762d8c9 100644 (file)
  * tells us what other partitions to define. If there isn't, we use a default
  * partition split defined below.
  *
- * $Log: axisflashmap.c,v $
- * Revision 1.11  2004/11/15 10:27:14  starvik
- * Corrected typo (Thanks to Milton Miller <miltonm@bga.com>).
- *
- * Revision 1.10  2004/08/16 12:37:22  starvik
- * Merge of Linux 2.6.8
- *
- * Revision 1.8  2004/05/14 07:58:03  starvik
- * Merge of changes from 2.4
- *
- * Revision 1.6  2003/07/04 08:27:37  starvik
- * Merge of Linux 2.5.74
- *
- * Revision 1.5  2002/12/11 13:13:57  starvik
- * Added arch/ to v10 specific includes
- * Added fix from Linux 2.4 in serial.c (flush_to_flip_buffer)
- *
- * Revision 1.4  2002/11/20 11:56:10  starvik
- * Merge of Linux 2.5.48
- *
- * Revision 1.3  2002/11/13 14:54:13  starvik
- * Copied from linux 2.4
- *
- * Revision 1.28  2002/10/01 08:08:43  jonashg
- * The first partition ends at the start of the partition table.
- *
- * Revision 1.27  2002/08/21 09:23:13  jonashg
- * Speling.
- *
- * Revision 1.26  2002/08/21 08:35:20  jonashg
- * Cosmetic change to printouts.
- *
- * Revision 1.25  2002/08/21 08:15:42  jonashg
- * Made it compile even without CONFIG_MTD_CONCAT defined.
- *
- * Revision 1.24  2002/08/20 13:12:35  jonashg
- * * New approach to probing. Probe cse0 and cse1 separately and (mtd)concat
- *   the results.
- * * Removed compile time tests concerning how the mtdram driver has been
- *   configured. The user will know about the misconfiguration at runtime
- *   instead. (The old approach made it impossible to use mtdram for anything
- *   else than RAM boot).
- *
- * Revision 1.23  2002/05/13 12:12:28  johana
- * Allow compile without CONFIG_MTD_MTDRAM but warn at compiletime and
- * be informative at runtime.
- *
- * Revision 1.22  2002/05/13 10:24:44  johana
- * Added #if checks on MTDRAM CONFIG
- *
- * Revision 1.21  2002/05/06 16:05:20  johana
- * Removed debug printout.
- *
- * Revision 1.20  2002/05/06 16:03:00  johana
- * No more cramfs as root hack in generic code.
- * It's handled by axisflashmap using mtdram.
- *
- * Revision 1.19  2002/03/15 17:10:28  bjornw
- * Changed comment about cached access since we changed this before
- *
- * Revision 1.18  2002/03/05 17:06:15  jonashg
- * Try amd_flash probe before cfi_probe since amd_flash driver can handle two
- * (or more) flash chips of different model and the cfi driver cannot.
- *
- * Revision 1.17  2001/11/12 19:42:38  pkj
- * Fixed compiler warnings.
- *
- * Revision 1.16  2001/11/08 11:18:58  jonashg
- * Always read from uncached address to avoid problems with flushing
- * cachelines after write and MTD-erase. No performance loss have been
- * seen yet.
- *
- * Revision 1.15  2001/10/19 12:41:04  jonashg
- * Name of probe has changed in MTD.
- *
- * Revision 1.14  2001/09/21 07:14:10  jonashg
- * Made root filesystem (cramfs) use mtdblock driver when booting from flash.
- *
- * Revision 1.13  2001/08/15 13:57:35  jonashg
- * Entire MTD updated to the linux 2.4.7 version.
- *
- * Revision 1.12  2001/06/11 09:50:30  jonashg
- * Oops, 2MB is 0x200000 bytes.
- *
- * Revision 1.11  2001/06/08 11:39:44  jonashg
- * Changed sizes and offsets in axis_default_partitions to use
- * CONFIG_ETRAX_PTABLE_SECTOR.
- *
- * Revision 1.10  2001/05/29 09:42:03  jonashg
- * Use macro for end marker length instead of sizeof.
- *
- * Revision 1.9  2001/05/29 08:52:52  jonashg
- * Gave names to the magic fours (size of the ptable end marker).
- *
- * Revision 1.8  2001/05/28 15:36:20  jonashg
- * * Removed old comment about ptable location in flash (it's a CONFIG_ option).
- * * Variable ptable was initialized twice to the same value.
- *
- * Revision 1.7  2001/04/05 13:41:46  markusl
- * Updated according to review remarks
- *
- * Revision 1.6  2001/03/07 09:21:21  bjornw
- * No need to waste .data
- *
- * Revision 1.5  2001/03/06 16:27:01  jonashg
- * Probe the entire flash area for flash devices.
- *
- * Revision 1.4  2001/02/23 12:47:15  bjornw
- * Uncached flash in LOW_MAP moved from 0xe to 0x8
- *
- * Revision 1.3  2001/02/16 12:11:45  jonashg
- * MTD driver amd_flash is now included in MTD CVS repository.
- * (It's now in drivers/mtd).
- *
- * Revision 1.2  2001/02/09 11:12:22  jonashg
- * Support for AMD compatible non-CFI flash chips.
- * Only tested with Toshiba TC58FVT160 so far.
- *
- * Revision 1.1  2001/01/12 17:01:18  bjornw
- * * Added axisflashmap.c, a physical mapping for MTD that reads and understands
- *   Axis partition-table format.
- *
- *
  */
 
 #include <linux/module.h>
@@ -235,7 +112,7 @@ static struct map_info map_cse1 = {
 };
 
 /* If no partition-table was found, we use this default-set. */
-#define MAX_PARTITIONS         7  
+#define MAX_PARTITIONS         7
 #define NUM_DEFAULT_PARTITIONS 3
 
 /*
@@ -300,6 +177,15 @@ static struct mtd_partition axis_partitions[MAX_PARTITIONS] = {
        },
 };
 
+#ifdef CONFIG_ETRAX_AXISFLASHMAP_MTD0WHOLE
+/* Main flash device */
+static struct mtd_partition main_partition = {
+       .name = "main",
+       .size = 0,
+       .offset = 0
+};
+#endif
+
 /*
  * Probe a chip select for AMD-compatible (JEDEC) or CFI-compatible flash
  * chips in that order (because the amd_flash-driver is faster).
@@ -316,15 +202,14 @@ static struct mtd_info *probe_cs(struct map_info *map_cs)
        mtd_cs = do_map_probe("cfi_probe", map_cs);
 #endif
 #ifdef CONFIG_MTD_JEDECPROBE
-       if (!mtd_cs) {
+       if (!mtd_cs)
                mtd_cs = do_map_probe("jedec_probe", map_cs);
-       }
 #endif
 
        return mtd_cs;
 }
 
-/* 
+/*
  * Probe each chip select individually for flash chips. If there are chips on
  * both cse0 and cse1, the mtd_info structs will be concatenated to one struct
  * so that MTD partitions can cross chip boundries.
@@ -351,7 +236,7 @@ static struct mtd_info *flash_probe(void)
        if (mtd_cse0 && mtd_cse1) {
 #ifdef CONFIG_MTD_CONCAT
                struct mtd_info *mtds[] = { mtd_cse0, mtd_cse1 };
-               
+
                /* Since the concatenation layer adds a small overhead we
                 * could try to figure out if the chips in cse0 and cse1 are
                 * identical and reprobe the whole cse0+cse1 window. But since
@@ -372,7 +257,7 @@ static struct mtd_info *flash_probe(void)
 
                        /* The best we can do now is to only use what we found
                         * at cse0.
-                        */ 
+                        */
                        mtd_cse = mtd_cse0;
                        map_destroy(mtd_cse1);
                }
@@ -395,7 +280,7 @@ static int __init init_axis_flash(void)
        struct partitiontable_head *ptable_head = NULL;
        struct partitiontable_entry *ptable;
        int use_default_ptable = 1; /* Until proven otherwise. */
-       const char *pmsg = "  /dev/flash%d at 0x%08x, size 0x%08x\n";
+       const char pmsg[] = "  /dev/flash%d at 0x%08x, size 0x%08x\n";
 
        if (!(mymtd = flash_probe())) {
                /* There's no reason to use this module if no flash chip can
@@ -435,7 +320,7 @@ static int __init init_axis_flash(void)
                unsigned long offset = CONFIG_ETRAX_PTABLE_SECTOR;
                unsigned char *p;
                unsigned long csum = 0;
-               
+
                ptable = (struct partitiontable_entry *)
                        ((unsigned long)ptable_head + sizeof(*ptable_head));
 
@@ -490,6 +375,16 @@ static int __init init_axis_flash(void)
                pidx++;
        }
 
+#ifdef CONFIG_ETRAX_AXISFLASHMAP_MTD0WHOLE
+       if (mymtd) {
+               main_partition.size = mymtd->size;
+               err = add_mtd_partitions(mymtd, &main_partition, 1);
+               if (err)
+                       panic("axisflashmap: Could not initialize "
+                             "partition for whole main mtd device!\n");
+       }
+#endif
+
         if (mymtd) {
                if (use_default_ptable) {
                        printk(KERN_INFO " Using default partition table.\n");
@@ -499,9 +394,8 @@ static int __init init_axis_flash(void)
                        err = add_mtd_partitions(mymtd, axis_partitions, pidx);
                }
 
-               if (err) {
+               if (err)
                        panic("axisflashmap could not add MTD partitions!\n");
-               }
        }
 
        if (!romfs_in_flash) {
@@ -515,25 +409,24 @@ static int __init init_axis_flash(void)
 #else
                struct mtd_info *mtd_ram;
 
-               mtd_ram = kmalloc(sizeof(struct mtd_info),
-                                                    GFP_KERNEL);
-               if (!mtd_ram) {
+               mtd_ram = kmalloc(sizeof(struct mtd_info), GFP_KERNEL);
+               if (!mtd_ram)
                        panic("axisflashmap couldn't allocate memory for "
                              "mtd_info!\n");
-               }
 
                printk(KERN_INFO " Adding RAM partition for romfs image:\n");
-               printk(pmsg, pidx, romfs_start, romfs_length);
-
-               err = mtdram_init_device(mtd_ram, (void*)romfs_start, 
-                                        romfs_length, "romfs");
-               if (err) {
+               printk(pmsg, pidx, (unsigned)romfs_start,
+                       (unsigned)romfs_length);
+
+               err = mtdram_init_device(mtd_ram,
+                       (void *)romfs_start,
+                       romfs_length,
+                       "romfs");
+               if (err)
                        panic("axisflashmap could not initialize MTD RAM "
                              "device!\n");
-               }
 #endif
        }
-
        return err;
 }
 
index 1d1936a18133d36376186baea9a1d76434f408dc..c9aa3904be05610f35425ced24c0a88a93383350 100644 (file)
@@ -333,7 +333,7 @@ rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                        ds1302_writereg(RTC_TRICKLECHARGER, tcs_val);
                        return 0;
                }
-               case RTC_VLOW_RD:
+               case RTC_VL_READ:
                {
                        /* TODO:
                         * Implement voltage low detection support
@@ -342,7 +342,7 @@ rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                               " is not supported\n");
                        return 0;
                }
-               case RTC_VLOW_SET:
+               case RTC_VL_CLR:
                {
                        /* TODO:
                         * Nothing to do since Voltage Low detection is not supported
index be35a70798aa5cc008807e6cc7488ba45f0d24dc..f1cac9dc75b8150bfdad17e904450f7738428438 100644 (file)
 *!  Sep  03 1999  Edgar Iglesias    Added bail-out stuff if we get interrupted
 *!                                  in the spin-lock.
 *!
-*!  $Log: eeprom.c,v $
-*!  Revision 1.12  2005/06/19 17:06:46  starvik
-*!  Merge of Linux 2.6.12.
-*!
-*!  Revision 1.11  2005/01/26 07:14:46  starvik
-*!  Applied diff from kernel janitors (Nish Aravamudan).
-*!
-*!  Revision 1.10  2003/09/11 07:29:48  starvik
-*!  Merge of Linux 2.6.0-test5
-*!
-*!  Revision 1.9  2003/07/04 08:27:37  starvik
-*!  Merge of Linux 2.5.74
-*!
-*!  Revision 1.8  2003/04/09 05:20:47  starvik
-*!  Merge of Linux 2.5.67
-*!
-*!  Revision 1.6  2003/02/10 07:19:28  starvik
-*!  Removed misplaced ;
-*!
-*!  Revision 1.5  2002/12/11 13:13:57  starvik
-*!  Added arch/ to v10 specific includes
-*!  Added fix from Linux 2.4 in serial.c (flush_to_flip_buffer)
-*!
-*!  Revision 1.4  2002/11/20 11:56:10  starvik
-*!  Merge of Linux 2.5.48
-*!
-*!  Revision 1.3  2002/11/18 13:16:06  starvik
-*!  Linux 2.5 port of latest 2.4 drivers
-*!
-*!  Revision 1.8  2001/06/15 13:24:29  jonashg
-*!  * Added verification of pointers from userspace in read and write.
-*!  * Made busy counter volatile.
-*!  * Added define for initial write delay.
-*!  * Removed warnings by using loff_t instead of unsigned long.
-*!
-*!  Revision 1.7  2001/06/14 15:26:54  jonashg
-*!  Removed test because condition is always true.
-*!
-*!  Revision 1.6  2001/06/14 15:18:20  jonashg
-*!  Kb -> kB (makes quite a difference if you don't know if you have 2k or 16k).
-*!
-*!  Revision 1.5  2001/06/14 14:39:51  jonashg
-*!  Forgot to use name when registering the driver.
-*!
-*!  Revision 1.4  2001/06/14 14:35:47  jonashg
-*!  * Gave driver a name and used it in printk's.
-*!  * Cleanup.
-*!
-*!  Revision 1.3  2001/03/19 16:04:46  markusl
-*!  Fixed init of fops struct
-*!
-*!  Revision 1.2  2001/03/19 10:35:07  markusl
-*!  2.4 port of eeprom driver
-*!
-*!  Revision 1.8  2000/05/18 10:42:25  edgar
-*!  Make sure to end write cycle on _every_ write
-*!
-*!  Revision 1.7  2000/01/17 17:41:01  johana
-*!  Adjusted probing and return -ENOSPC when writing outside EEPROM
-*!
-*!  Revision 1.6  2000/01/17 15:50:36  johana
-*!  Added adaptive timing adjustments and fixed autoprobing for 2k and 16k(?)
-*!  EEPROMs
-*!
-*!  Revision 1.5  1999/09/03 15:07:37  edgar
-*!  Added bail-out check to the spinlock
-*!
-*!  Revision 1.4  1999/09/03 12:11:17  bjornw
-*!  Proper atomicity (need to use spinlocks, not if's). users -> busy.
-*!
-*!
 *!        (c) 1999 Axis Communications AB, Lund, Sweden
 *!*****************************************************************************/
 
 #include <asm/uaccess.h>
 #include "i2c.h"
 
-#define D(x) 
+#define D(x)
 
 /* If we should use adaptive timing or not: */
-//#define EEPROM_ADAPTIVE_TIMING      
+/* #define EEPROM_ADAPTIVE_TIMING */
 
 #define EEPROM_MAJOR_NR 122  /* use a LOCAL/EXPERIMENTAL major for now */
 #define EEPROM_MINOR_NR 0
index 0d347a7058355c0d9ff7e90cbd0e73a0b535b6af..68a998bd10697cade8c194ed01bd96003f712995 100644 (file)
-/* $Id: gpio.c,v 1.17 2005/06/19 17:06:46 starvik Exp $
- *
+/*
  * Etrax general port I/O device
  *
- * Copyright (c) 1999, 2000, 2001, 2002 Axis Communications AB
+ * Copyright (c) 1999-2007 Axis Communications AB
  *
  * Authors:    Bjorn Wesen      (initial version)
  *             Ola Knutsson     (LED handling)
  *             Johan Adolfsson  (read/set directions, write, port G)
- *
- * $Log: gpio.c,v $
- * Revision 1.17  2005/06/19 17:06:46  starvik
- * Merge of Linux 2.6.12.
- *
- * Revision 1.16  2005/03/07 13:02:29  starvik
- * Protect driver global states with spinlock
- *
- * Revision 1.15  2005/01/05 06:08:55  starvik
- * No need to do local_irq_disable after local_irq_save.
- *
- * Revision 1.14  2004/12/13 12:21:52  starvik
- * Added I/O and DMA allocators from Linux 2.4
- *
- * Revision 1.12  2004/08/24 07:19:59  starvik
- * Whitespace cleanup
- *
- * Revision 1.11  2004/05/14 07:58:03  starvik
- * Merge of changes from 2.4
- *
- * Revision 1.9  2003/09/11 07:29:48  starvik
- * Merge of Linux 2.6.0-test5
- *
- * Revision 1.8  2003/07/04 08:27:37  starvik
- * Merge of Linux 2.5.74
- *
- * Revision 1.7  2003/01/10 07:44:07  starvik
- * init_ioremap is now called by kernel before drivers are initialized
- *
- * Revision 1.6  2002/12/11 13:13:57  starvik
- * Added arch/ to v10 specific includes
- * Added fix from Linux 2.4 in serial.c (flush_to_flip_buffer)
- *
- * Revision 1.5  2002/11/20 11:56:11  starvik
- * Merge of Linux 2.5.48
- *
- * Revision 1.4  2002/11/18 10:10:05  starvik
- * Linux 2.5 port of latest gpio.c from Linux 2.4
- *
- * Revision 1.20  2002/10/16 21:16:24  johana
- * Added support for PA high level interrupt.
- * That gives 2ms response time with iodtest for high levels and 2-12 ms
- * response time on low levels if the check is not made in
- * process.c:cpu_idle() as well.
- *
- * Revision 1.19  2002/10/14 18:27:33  johana
- * Implemented alarm handling so select() now works.
- * Latency is around 6-9 ms with a etrax_gpio_wake_up_check() in
- * cpu_idle().
- * Otherwise I get 15-18 ms (same as doing the poll in userspace -
- * but less overhead).
- * TODO? Perhaps we should add the check in IMMEDIATE_BH (or whatever it
- * is in 2.4) as well?
- * TODO? Perhaps call request_irq()/free_irq() only when needed?
- * Increased version to 2.5
- *
- * Revision 1.18  2002/10/11 15:02:00  johana
- * Mask inverted 8 bit value in setget_input().
- *
- * Revision 1.17  2002/06/17 15:53:01  johana
- * Added IO_READ_INBITS, IO_READ_OUTBITS, IO_SETGET_INPUT and IO_SETGET_OUTPUT
- * that take a pointer as argument and thus can handle 32 bit ports (G)
- * correctly.
- * These should be used instead of IO_READBITS, IO_SETINPUT and IO_SETOUTPUT.
- * (especially if Port G bit 31 is used)
- *
- * Revision 1.16  2002/06/17 09:59:51  johana
- * Returning 32 bit values in the ioctl return value doesn't work if bit
- * 31 is set (could happen for port G), so mask it of with 0x7FFFFFFF.
- * A new set of ioctl's will be added.
- *
- * Revision 1.15  2002/05/06 13:19:13  johana
- * IO_SETINPUT returns mask with bit set = inputs for PA and PB as well.
- *
- * Revision 1.14  2002/04/12 12:01:53  johana
- * Use global r_port_g_data_shadow.
- * Moved gpio_init_port_g() closer to gpio_init() and marked it __init.
- *
- * Revision 1.13  2002/04/10 12:03:55  johana
- * Added support for port G /dev/gpiog (minor 3).
- * Changed indentation on switch cases.
- * Fixed other spaces to tabs.
- *
- * Revision 1.12  2001/11/12 19:42:15  pkj
- * * Corrected return values from gpio_leds_ioctl().
- * * Fixed compiler warnings.
- *
- * Revision 1.11  2001/10/30 14:39:12  johana
- * Added D() around gpio_write printk.
- *
- * Revision 1.10  2001/10/25 10:24:42  johana
- * Added IO_CFG_WRITE_MODE ioctl and write method that can do fast
- * bittoggling in the kernel. (This speeds up programming an FPGA with 450kB
- * from ~60 seconds to 4 seconds).
- * Added save_flags/cli/restore_flags in ioctl.
- *
- * Revision 1.9  2001/05/04 14:16:07  matsfg
- * Corrected spelling error
- *
- * Revision 1.8  2001/04/27 13:55:26  matsfg
- * Moved initioremap.
- * Turns off all LEDS on init.
- * Added support for shutdown and powerbutton.
- *
- * Revision 1.7  2001/04/04 13:30:08  matsfg
- * Added bitset and bitclear for leds. Calls init_ioremap to set up memmapping
- *
- * Revision 1.6  2001/03/26 16:03:06  bjornw
- * Needs linux/config.h
- *
- * Revision 1.5  2001/03/26 14:22:03  bjornw
- * Namechange of some config options
- *
- * Revision 1.4  2001/02/27 13:52:48  bjornw
- * malloc.h -> slab.h
- *
- * Revision 1.3  2001/01/24 15:06:48  bjornw
- * gpio_wq correct type
- *
- * Revision 1.2  2001/01/18 16:07:30  bjornw
- * 2.4 port
- *
- * Revision 1.1  2001/01/18 15:55:16  bjornw
- * Verbatim copy of etraxgpio.c from elinux 2.0 added
- *
- *
  */
 
 
@@ -165,7 +38,7 @@ static int dp_cnt;
 #else
 #define DP(x)
 #endif
-       
+
 static char gpio_name[] = "etrax gpio";
 
 #if 0
@@ -173,9 +46,9 @@ static wait_queue_head_t *gpio_wq;
 #endif
 
 static int gpio_ioctl(struct inode *inode, struct file *file,
-                     unsigned int cmd, unsigned long arg);
-static ssize_t gpio_write(struct file * file, const char * buf, size_t count,
-                          loff_t *off);
+       unsigned int cmd, unsigned long arg);
+static ssize_t gpio_write(struct file *file, const char __user *buf,
+       size_t count, loff_t *off);
 static int gpio_open(struct inode *inode, struct file *filp);
 static int gpio_release(struct inode *inode, struct file *filp);
 static unsigned int gpio_poll(struct file *filp, struct poll_table_struct *wait);
@@ -201,22 +74,22 @@ struct gpio_private {
 
 /* linked list of alarms to check for */
 
-static struct gpio_private *alarmlist = 0;
+static struct gpio_private *alarmlist;
 
-static int gpio_some_alarms = 0; /* Set if someone uses alarm */
-static unsigned long gpio_pa_irq_enabled_mask = 0;
+static int gpio_some_alarms; /* Set if someone uses alarm */
+static unsigned long gpio_pa_irq_enabled_mask;
 
 static DEFINE_SPINLOCK(gpio_lock); /* Protect directions etc */
 
 /* Port A and B use 8 bit access, but Port G is 32 bit */
 #define NUM_PORTS (GPIO_MINOR_B+1)
 
-static volatile unsigned char *ports[NUM_PORTS] = { 
-       R_PORT_PA_DATA, 
+static volatile unsigned char *ports[NUM_PORTS] = {
+       R_PORT_PA_DATA,
        R_PORT_PB_DATA,
 };
 static volatile unsigned char *shads[NUM_PORTS] = {
-       &port_pa_data_shadow, 
+       &port_pa_data_shadow,
        &port_pb_data_shadow
 };
 
@@ -236,29 +109,29 @@ static volatile unsigned char *shads[NUM_PORTS] = {
 #endif
 
 
-static unsigned char changeable_dir[NUM_PORTS] = { 
+static unsigned char changeable_dir[NUM_PORTS] = {
        CONFIG_ETRAX_PA_CHANGEABLE_DIR,
-       CONFIG_ETRAX_PB_CHANGEABLE_DIR 
+       CONFIG_ETRAX_PB_CHANGEABLE_DIR
 };
-static unsigned char changeable_bits[NUM_PORTS] = { 
+static unsigned char changeable_bits[NUM_PORTS] = {
        CONFIG_ETRAX_PA_CHANGEABLE_BITS,
-       CONFIG_ETRAX_PB_CHANGEABLE_BITS 
+       CONFIG_ETRAX_PB_CHANGEABLE_BITS
 };
 
-static volatile unsigned char *dir[NUM_PORTS] = { 
-       R_PORT_PA_DIR, 
-       R_PORT_PB_DIR 
+static volatile unsigned char *dir[NUM_PORTS] = {
+       R_PORT_PA_DIR,
+       R_PORT_PB_DIR
 };
 
 static volatile unsigned char *dir_shadow[NUM_PORTS] = {
-       &port_pa_dir_shadow, 
-       &port_pb_dir_shadow 
+       &port_pa_dir_shadow,
+       &port_pb_dir_shadow
 };
 
 /* All bits in port g that can change dir. */
 static const unsigned long int changeable_dir_g_mask = 0x01FFFF01;
 
-/* Port G is 32 bit, handle it special, some bits are both inputs 
+/* Port G is 32 bit, handle it special, some bits are both inputs
    and outputs at the same time, only some of the bits can change direction
    and some of them in groups of 8 bit. */
 static unsigned long changeable_dir_g;
@@ -269,18 +142,17 @@ static unsigned long dir_g_shadow; /* 1=output */
 #define USE_PORTS(priv) ((priv)->minor <= GPIO_MINOR_B)
 
 
-
-static unsigned int 
-gpio_poll(struct file *file,
-         poll_table *wait)
+static unsigned int gpio_poll(struct file *file, poll_table *wait)
 {
        unsigned int mask = 0;
-       struct gpio_private *priv = (struct gpio_private *)file->private_data;
+       struct gpio_private *priv = file->private_data;
        unsigned long data;
-       spin_lock(&gpio_lock);
+       unsigned long flags;
+
+       spin_lock_irqsave(&gpio_lock, flags);
+
        poll_wait(file, &priv->alarm_wq, wait);
        if (priv->minor == GPIO_MINOR_A) {
-               unsigned long flags;
                unsigned long tmp;
                data = *R_PORT_PA_DATA;
                /* PA has support for high level interrupt -
@@ -288,27 +160,25 @@ gpio_poll(struct file *file,
                 */
                tmp = ~data & priv->highalarm & 0xFF;
                tmp = (tmp << R_IRQ_MASK1_SET__pa0__BITNR);
-               local_irq_save(flags);
+
                gpio_pa_irq_enabled_mask |= tmp;
                *R_IRQ_MASK1_SET = tmp;
-               local_irq_restore(flags);
-
        } else if (priv->minor == GPIO_MINOR_B)
                data = *R_PORT_PB_DATA;
        else if (priv->minor == GPIO_MINOR_G)
                data = *R_PORT_G_DATA;
        else {
-               spin_unlock(&gpio_lock);
-               return 0;
+               mask = 0;
+               goto out;
        }
-       
+
        if ((data & priv->highalarm) ||
            (~data & priv->lowalarm)) {
                mask = POLLIN|POLLRDNORM;
        }
 
-       spin_unlock(&gpio_lock);
-       
+out:
+       spin_unlock_irqrestore(&gpio_lock, flags);
        DP(printk("gpio_poll ready: mask 0x%08X\n", mask));
 
        return mask;
@@ -316,16 +186,19 @@ gpio_poll(struct file *file,
 
 int etrax_gpio_wake_up_check(void)
 {
-       struct gpio_private *priv = alarmlist;
+       struct gpio_private *priv;
        unsigned long data = 0;
         int ret = 0;
-       spin_lock(&gpio_lock);
+       unsigned long flags;
+
+       spin_lock_irqsave(&gpio_lock, flags);
+       priv = alarmlist;
        while (priv) {
-               if (USE_PORTS(priv)) {
+               if (USE_PORTS(priv))
                        data = *priv->port;
-               } else if (priv->minor == GPIO_MINOR_G) {
+               else if (priv->minor == GPIO_MINOR_G)
                        data = *R_PORT_G_DATA;
-               }
+
                if ((data & priv->highalarm) ||
                    (~data & priv->lowalarm)) {
                        DP(printk("etrax_gpio_wake_up_check %i\n",priv->minor));
@@ -334,12 +207,12 @@ int etrax_gpio_wake_up_check(void)
                }
                priv = priv->next;
        }
-       spin_unlock(&gpio_lock);
+       spin_unlock_irqrestore(&gpio_lock, flags);
         return ret;
 }
 
 static irqreturn_t
-gpio_poll_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+gpio_poll_timer_interrupt(int irq, void *dev_id)
 {
        if (gpio_some_alarms) {
                etrax_gpio_wake_up_check();
@@ -349,10 +222,13 @@ gpio_poll_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 }
 
 static irqreturn_t
-gpio_pa_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+gpio_interrupt(int irq, void *dev_id)
 {
        unsigned long tmp;
-       spin_lock(&gpio_lock);
+       unsigned long flags;
+
+       spin_lock_irqsave(&gpio_lock, flags);
+
        /* Find what PA interrupts are active */
        tmp = (*R_IRQ_READ1);
 
@@ -363,75 +239,70 @@ gpio_pa_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        *R_IRQ_MASK1_CLR = tmp;
        gpio_pa_irq_enabled_mask &= ~tmp;
 
-       spin_unlock(&gpio_lock);
+       spin_unlock_irqrestore(&gpio_lock, flags);
 
-       if (gpio_some_alarms) {
+       if (gpio_some_alarms)
                return IRQ_RETVAL(etrax_gpio_wake_up_check());
-       }
+
         return IRQ_NONE;
 }
 
+static void gpio_write_bit(struct gpio_private *priv,
+       unsigned char data, int bit)
+{
+       *priv->port = *priv->shadow &= ~(priv->clk_mask);
+       if (data & 1 << bit)
+               *priv->port = *priv->shadow |= priv->data_mask;
+       else
+               *priv->port = *priv->shadow &= ~(priv->data_mask);
+
+       /* For FPGA: min 5.0ns (DCC) before CCLK high */
+       *priv->port = *priv->shadow |= priv->clk_mask;
+}
 
-static ssize_t gpio_write(struct file * file, const char * buf, size_t count,
-                          loff_t *off)
+static void gpio_write_byte(struct gpio_private *priv, unsigned char data)
 {
-       struct gpio_private *priv = (struct gpio_private *)file->private_data;
-       unsigned char data, clk_mask, data_mask, write_msb;
-       unsigned long flags;
+       int i;
 
-       spin_lock(&gpio_lock);
+       if (priv->write_msb)
+               for (i = 7; i >= 0; i--)
+                       gpio_write_bit(priv, data, i);
+       else
+               for (i = 0; i <= 7; i++)
+                       gpio_write_bit(priv, data, i);
+}
 
+static ssize_t gpio_write(struct file *file, const char __user *buf,
+       size_t count, loff_t *off)
+{
+       struct gpio_private *priv = file->private_data;
+       unsigned long flags;
        ssize_t retval = count;
-       if (priv->minor !=GPIO_MINOR_A && priv->minor != GPIO_MINOR_B) {
-               retval = -EFAULT;
-               goto out;
-       }
-    
-       if (!access_ok(VERIFY_READ, buf, count)) {
-               retval = -EFAULT;
-               goto out;
-       }
-       clk_mask = priv->clk_mask;
-       data_mask = priv->data_mask;
+
+       if (priv->minor != GPIO_MINOR_A && priv->minor != GPIO_MINOR_B)
+               return -EFAULT;
+
+       if (!access_ok(VERIFY_READ, buf, count))
+               return -EFAULT;
+
+       spin_lock_irqsave(&gpio_lock, flags);
+
        /* It must have been configured using the IO_CFG_WRITE_MODE */
        /* Perhaps a better error code? */
-       if (clk_mask == 0 || data_mask == 0) {
+       if (priv->clk_mask == 0 || priv->data_mask == 0) {
                retval = -EPERM;
                goto out;
        }
-       write_msb = priv->write_msb;
-       D(printk("gpio_write: %lu to data 0x%02X clk 0x%02X msb: %i\n",count, data_mask, clk_mask, write_msb));
-       while (count--) {
-               int i;
-               data = *buf++;
-               if (priv->write_msb) {
-                       for (i = 7; i >= 0;i--) {
-                               local_irq_save(flags);
-                               *priv->port = *priv->shadow &= ~clk_mask;
-                               if (data & 1<<i)
-                                       *priv->port = *priv->shadow |= data_mask;
-                               else
-                                       *priv->port = *priv->shadow &= ~data_mask;
-                       /* For FPGA: min 5.0ns (DCC) before CCLK high */
-                               *priv->port = *priv->shadow |= clk_mask;
-                               local_irq_restore(flags);
-                       }
-               } else {
-                       for (i = 0; i <= 7;i++) {
-                               local_irq_save(flags);
-                               *priv->port = *priv->shadow &= ~clk_mask;
-                               if (data & 1<<i)
-                                       *priv->port = *priv->shadow |= data_mask;
-                               else
-                                       *priv->port = *priv->shadow &= ~data_mask;
-                       /* For FPGA: min 5.0ns (DCC) before CCLK high */
-                               *priv->port = *priv->shadow |= clk_mask;
-                               local_irq_restore(flags);
-                       }
-               }
-       }
+
+       D(printk(KERN_DEBUG "gpio_write: %02X to data 0x%02X "
+               "clk 0x%02X msb: %i\n",
+               count, priv->data_mask, priv->clk_mask, priv->write_msb));
+
+       while (count--)
+               gpio_write_byte(priv, *buf++);
+
 out:
-       spin_unlock(&gpio_lock);
+       spin_unlock_irqrestore(&gpio_lock, flags);
        return retval;
 }
 
@@ -442,22 +313,20 @@ gpio_open(struct inode *inode, struct file *filp)
 {
        struct gpio_private *priv;
        int p = iminor(inode);
+       unsigned long flags;
 
        if (p > GPIO_MINOR_LAST)
                return -EINVAL;
 
-       priv = kmalloc(sizeof(struct gpio_private),
-                                             GFP_KERNEL);
+       priv = kzalloc(sizeof(struct gpio_private), GFP_KERNEL);
 
        if (!priv)
                return -ENOMEM;
 
        priv->minor = p;
 
-       /* initialize the io/alarm struct and link it into our alarmlist */
+       /* initialize the io/alarm struct */
 
-       priv->next = alarmlist;
-       alarmlist = priv;
        if (USE_PORTS(priv)) { /* A and B */
                priv->port = ports[p];
                priv->shadow = shads[p];
@@ -480,7 +349,13 @@ gpio_open(struct inode *inode, struct file *filp)
        priv->data_mask = 0;
        init_waitqueue_head(&priv->alarm_wq);
 
-       filp->private_data = (void *)priv;
+       filp->private_data = priv;
+
+       /* link it into our alarmlist */
+       spin_lock_irqsave(&gpio_lock, flags);
+       priv->next = alarmlist;
+       alarmlist = priv;
+       spin_unlock_irqrestore(&gpio_lock, flags);
 
        return 0;
 }
@@ -490,11 +365,12 @@ gpio_release(struct inode *inode, struct file *filp)
 {
        struct gpio_private *p;
        struct gpio_private *todel;
+       unsigned long flags;
 
-       spin_lock(&gpio_lock);
+       spin_lock_irqsave(&gpio_lock, flags);
 
-        p = alarmlist;
-        todel = (struct gpio_private *)filp->private_data;
+       p = alarmlist;
+       todel = filp->private_data;
 
        /* unlink from alarmlist and free the private structure */
 
@@ -512,123 +388,114 @@ gpio_release(struct inode *inode, struct file *filp)
        while (p) {
                if (p->highalarm | p->lowalarm) {
                        gpio_some_alarms = 1;
-                       spin_unlock(&gpio_lock);
-                       return 0;
+                       goto out;
                }
                p = p->next;
        }
        gpio_some_alarms = 0;
-       spin_unlock(&gpio_lock);
+out:
+       spin_unlock_irqrestore(&gpio_lock, flags);
        return 0;
 }
 
-/* Main device API. ioctl's to read/set/clear bits, as well as to 
+/* Main device API. ioctl's to read/set/clear bits, as well as to
  * set alarms to wait for using a subsequent select().
  */
-
 unsigned long inline setget_input(struct gpio_private *priv, unsigned long arg)
 {
-       /* Set direction 0=unchanged 1=input, 
-        * return mask with 1=input 
-        */
-       unsigned long flags;
+       /* Set direction 0=unchanged 1=input,
+        * return mask with 1=input */
        if (USE_PORTS(priv)) {
-               local_irq_save(flags);
-               *priv->dir = *priv->dir_shadow &= 
+               *priv->dir = *priv->dir_shadow &=
                ~((unsigned char)arg & priv->changeable_dir);
-               local_irq_restore(flags);
                return ~(*priv->dir_shadow) & 0xFF; /* Only 8 bits */
-       } else if (priv->minor == GPIO_MINOR_G) {
-               /* We must fiddle with R_GEN_CONFIG to change dir */
-               local_irq_save(flags);
-               if (((arg & dir_g_in_bits) != arg) && 
-                   (arg & changeable_dir_g)) {
-                       arg &= changeable_dir_g;
-                       /* Clear bits in genconfig to set to input */
-                       if (arg & (1<<0)) {
-                               genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g0dir);
-                               dir_g_in_bits |= (1<<0);
-                               dir_g_out_bits &= ~(1<<0);
-                       }
-                       if ((arg & 0x0000FF00) == 0x0000FF00) {
-                               genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g8_15dir);
-                               dir_g_in_bits |= 0x0000FF00;
-                               dir_g_out_bits &= ~0x0000FF00;
-                       }
-                       if ((arg & 0x00FF0000) == 0x00FF0000) {
-                               genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g16_23dir);
-                               dir_g_in_bits |= 0x00FF0000;
-                               dir_g_out_bits &= ~0x00FF0000;
-                       }
-                       if (arg & (1<<24)) {
-                               genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g24dir);
-                               dir_g_in_bits |= (1<<24);
-                               dir_g_out_bits &= ~(1<<24);
-                       }
-                       D(printk(KERN_INFO "gpio: SETINPUT on port G set "
-                                "genconfig to 0x%08lX "
-                                "in_bits: 0x%08lX "
-                                "out_bits: 0x%08lX\n",
-                                (unsigned long)genconfig_shadow,
-                                dir_g_in_bits, dir_g_out_bits));
-                       *R_GEN_CONFIG = genconfig_shadow;
-                       /* Must be a >120 ns delay before writing this again */
-                               
+       }
+
+       if (priv->minor != GPIO_MINOR_G)
+               return 0;
+
+       /* We must fiddle with R_GEN_CONFIG to change dir */
+       if (((arg & dir_g_in_bits) != arg) &&
+           (arg & changeable_dir_g)) {
+               arg &= changeable_dir_g;
+               /* Clear bits in genconfig to set to input */
+               if (arg & (1<<0)) {
+                       genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, g0dir);
+                       dir_g_in_bits |= (1<<0);
+                       dir_g_out_bits &= ~(1<<0);
                }
-               local_irq_restore(flags);
-               return dir_g_in_bits;
+               if ((arg & 0x0000FF00) == 0x0000FF00) {
+                       genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, g8_15dir);
+                       dir_g_in_bits |= 0x0000FF00;
+                       dir_g_out_bits &= ~0x0000FF00;
+               }
+               if ((arg & 0x00FF0000) == 0x00FF0000) {
+                       genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, g16_23dir);
+                       dir_g_in_bits |= 0x00FF0000;
+                       dir_g_out_bits &= ~0x00FF0000;
+               }
+               if (arg & (1<<24)) {
+                       genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, g24dir);
+                       dir_g_in_bits |= (1<<24);
+                       dir_g_out_bits &= ~(1<<24);
+               }
+               D(printk(KERN_DEBUG "gpio: SETINPUT on port G set "
+                        "genconfig to 0x%08lX "
+                        "in_bits: 0x%08lX "
+                        "out_bits: 0x%08lX\n",
+                        (unsigned long)genconfig_shadow,
+                        dir_g_in_bits, dir_g_out_bits));
+               *R_GEN_CONFIG = genconfig_shadow;
+               /* Must be a >120 ns delay before writing this again */
+
        }
-       return 0;
+       return dir_g_in_bits;
 } /* setget_input */
 
 unsigned long inline setget_output(struct gpio_private *priv, unsigned long arg)
 {
-       unsigned long flags;
        if (USE_PORTS(priv)) {
-               local_irq_save(flags);
-               *priv->dir = *priv->dir_shadow |= 
-                 ((unsigned char)arg & priv->changeable_dir);
-               local_irq_restore(flags);
+               *priv->dir = *priv->dir_shadow |=
+                       ((unsigned char)arg & priv->changeable_dir);
                return *priv->dir_shadow;
-       } else if (priv->minor == GPIO_MINOR_G) {
-               /* We must fiddle with R_GEN_CONFIG to change dir */                    
-               local_irq_save(flags);
-               if (((arg & dir_g_out_bits) != arg) &&
-                   (arg & changeable_dir_g)) {
-                       /* Set bits in genconfig to set to output */
-                       if (arg & (1<<0)) {
-                               genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g0dir);
-                               dir_g_out_bits |= (1<<0);
-                               dir_g_in_bits &= ~(1<<0);
-                       }
-                       if ((arg & 0x0000FF00) == 0x0000FF00) {
-                               genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g8_15dir);
-                               dir_g_out_bits |= 0x0000FF00;
-                               dir_g_in_bits &= ~0x0000FF00;
-                       }
-                       if ((arg & 0x00FF0000) == 0x00FF0000) {
-                               genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g16_23dir);
-                               dir_g_out_bits |= 0x00FF0000;
-                               dir_g_in_bits &= ~0x00FF0000;
-                       }
-                       if (arg & (1<<24)) {
-                               genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g24dir);
-                               dir_g_out_bits |= (1<<24);
-                               dir_g_in_bits &= ~(1<<24);
-                       }
-                       D(printk(KERN_INFO "gpio: SETOUTPUT on port G set "
-                                "genconfig to 0x%08lX "
-                                "in_bits: 0x%08lX "
-                                "out_bits: 0x%08lX\n",
-                                (unsigned long)genconfig_shadow,
-                                dir_g_in_bits, dir_g_out_bits));
-                       *R_GEN_CONFIG = genconfig_shadow;
-                       /* Must be a >120 ns delay before writing this again */
+       }
+       if (priv->minor != GPIO_MINOR_G)
+               return 0;
+
+       /* We must fiddle with R_GEN_CONFIG to change dir */
+       if (((arg & dir_g_out_bits) != arg) &&
+           (arg & changeable_dir_g)) {
+               /* Set bits in genconfig to set to output */
+               if (arg & (1<<0)) {
+                       genconfig_shadow |= IO_MASK(R_GEN_CONFIG, g0dir);
+                       dir_g_out_bits |= (1<<0);
+                       dir_g_in_bits &= ~(1<<0);
                }
-               local_irq_restore(flags);
-               return dir_g_out_bits & 0x7FFFFFFF;
+               if ((arg & 0x0000FF00) == 0x0000FF00) {
+                       genconfig_shadow |= IO_MASK(R_GEN_CONFIG, g8_15dir);
+                       dir_g_out_bits |= 0x0000FF00;
+                       dir_g_in_bits &= ~0x0000FF00;
+               }
+               if ((arg & 0x00FF0000) == 0x00FF0000) {
+                       genconfig_shadow |= IO_MASK(R_GEN_CONFIG, g16_23dir);
+                       dir_g_out_bits |= 0x00FF0000;
+                       dir_g_in_bits &= ~0x00FF0000;
+               }
+               if (arg & (1<<24)) {
+                       genconfig_shadow |= IO_MASK(R_GEN_CONFIG, g24dir);
+                       dir_g_out_bits |= (1<<24);
+                       dir_g_in_bits &= ~(1<<24);
+               }
+               D(printk(KERN_INFO "gpio: SETOUTPUT on port G set "
+                        "genconfig to 0x%08lX "
+                        "in_bits: 0x%08lX "
+                        "out_bits: 0x%08lX\n",
+                        (unsigned long)genconfig_shadow,
+                        dir_g_in_bits, dir_g_out_bits));
+               *R_GEN_CONFIG = genconfig_shadow;
+               /* Must be a >120 ns delay before writing this again */
        }
-       return 0;
+       return dir_g_out_bits & 0x7FFFFFFF;
 } /* setget_output */
 
 static int
@@ -642,12 +509,11 @@ gpio_ioctl(struct inode *inode, struct file *file,
        unsigned long val;
         int ret = 0;
 
-       struct gpio_private *priv = (struct gpio_private *)file->private_data;
-       if (_IOC_TYPE(cmd) != ETRAXGPIO_IOCTYPE) {
+       struct gpio_private *priv = file->private_data;
+       if (_IOC_TYPE(cmd) != ETRAXGPIO_IOCTYPE)
                return -EINVAL;
-       }
 
-       spin_lock(&gpio_lock);
+       spin_lock_irqsave(&gpio_lock, flags);
 
        switch (_IOC_NR(cmd)) {
        case IO_READBITS: /* Use IO_READ_INBITS and IO_READ_OUTBITS instead */
@@ -659,7 +525,6 @@ gpio_ioctl(struct inode *inode, struct file *file,
                }
                break;
        case IO_SETBITS:
-               local_irq_save(flags);
                // set changeable bits with a 1 in arg
                if (USE_PORTS(priv)) {
                        *priv->port = *priv->shadow |= 
@@ -667,10 +532,8 @@ gpio_ioctl(struct inode *inode, struct file *file,
                } else if (priv->minor == GPIO_MINOR_G) {
                        *R_PORT_G_DATA = port_g_data_shadow |= (arg & dir_g_out_bits);
                }
-               local_irq_restore(flags);
                break;
        case IO_CLRBITS:
-               local_irq_save(flags);
                // clear changeable bits with a 1 in arg
                if (USE_PORTS(priv)) {
                        *priv->port = *priv->shadow &= 
@@ -678,7 +541,6 @@ gpio_ioctl(struct inode *inode, struct file *file,
                } else if (priv->minor == GPIO_MINOR_G) {
                        *R_PORT_G_DATA = port_g_data_shadow &= ~((unsigned long)arg & dir_g_out_bits);
                }
-               local_irq_restore(flags);
                break;
        case IO_HIGHALARM:
                // set alarm when bits with 1 in arg go high
@@ -698,6 +560,8 @@ gpio_ioctl(struct inode *inode, struct file *file,
                        /* Must update gpio_some_alarms */
                        struct gpio_private *p = alarmlist;
                        int some_alarms;
+                       spin_lock_irq(&gpio_lock);
+                       p = alarmlist;
                        some_alarms = 0;
                        while (p) {
                                if (p->highalarm | p->lowalarm) {
@@ -707,6 +571,7 @@ gpio_ioctl(struct inode *inode, struct file *file,
                                p = p->next;
                        }
                        gpio_some_alarms = some_alarms;
+                       spin_unlock_irq(&gpio_lock);
                }
                break;
        case IO_READDIR: /* Use IO_SETGET_INPUT/OUTPUT instead! */
@@ -766,7 +631,7 @@ gpio_ioctl(struct inode *inode, struct file *file,
                } else if (priv->minor == GPIO_MINOR_G) {
                        val = *R_PORT_G_DATA;
                }
-               if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
+               if (copy_to_user((void __user *)arg, &val, sizeof(val)))
                        ret = -EFAULT;
                break;
        case IO_READ_OUTBITS:
@@ -776,33 +641,32 @@ gpio_ioctl(struct inode *inode, struct file *file,
                } else if (priv->minor == GPIO_MINOR_G) {
                        val = port_g_data_shadow;
                }
-               if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
+               if (copy_to_user((void __user *)arg, &val, sizeof(val)))
                        ret = -EFAULT;
                break;
        case IO_SETGET_INPUT: 
                /* bits set in *arg is set to input,
                 * *arg updated with current input pins.
                 */
-               if (copy_from_user(&val, (unsigned long*)arg, sizeof(val)))
+               if (copy_from_user(&val, (void __user *)arg, sizeof(val)))
                {
                        ret = -EFAULT;
                        break;
                }
                val = setget_input(priv, val);
-               if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
+               if (copy_to_user((void __user *)arg, &val, sizeof(val)))
                        ret = -EFAULT;
                break;
        case IO_SETGET_OUTPUT:
                /* bits set in *arg is set to output,
                 * *arg updated with current output pins.
                 */
-               if (copy_from_user(&val, (unsigned long*)arg, sizeof(val)))
-               {
+               if (copy_from_user(&val, (void __user *)arg, sizeof(val))) {
                        ret = -EFAULT;
                        break;
                }
                val = setget_output(priv, val);
-               if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
+               if (copy_to_user((void __user *)arg, &val, sizeof(val)))
                        ret = -EFAULT;
                break;
        default:
@@ -812,7 +676,7 @@ gpio_ioctl(struct inode *inode, struct file *file,
                        ret = -EINVAL;
        } /* switch */
 
-       spin_unlock(&gpio_lock);
+       spin_unlock_irqrestore(&gpio_lock, flags);
        return ret;
 }
 
@@ -824,18 +688,18 @@ gpio_leds_ioctl(unsigned int cmd, unsigned long arg)
 
        switch (_IOC_NR(cmd)) {
        case IO_LEDACTIVE_SET:
-               green = ((unsigned char) arg) & 1;
-               red   = (((unsigned char) arg) >> 1) & 1;
-               LED_ACTIVE_SET_G(green);
-               LED_ACTIVE_SET_R(red);
+               green = ((unsigned char)arg) & 1;
+               red   = (((unsigned char)arg) >> 1) & 1;
+               CRIS_LED_ACTIVE_SET_G(green);
+               CRIS_LED_ACTIVE_SET_R(red);
                break;
 
        case IO_LED_SETBIT:
-               LED_BIT_SET(arg);
+               CRIS_LED_BIT_SET(arg);
                break;
 
        case IO_LED_CLRBIT:
-               LED_BIT_CLR(arg);
+               CRIS_LED_BIT_CLR(arg);
                break;
 
        default:
@@ -845,7 +709,7 @@ gpio_leds_ioctl(unsigned int cmd, unsigned long arg)
        return 0;
 }
 
-const struct file_operations gpio_fops = {
+static const struct file_operations gpio_fops = {
        .owner       = THIS_MODULE,
        .poll        = gpio_poll,
        .ioctl       = gpio_ioctl,
@@ -854,16 +718,18 @@ const struct file_operations gpio_fops = {
        .release     = gpio_release,
 };
 
-
-void ioif_watcher(const unsigned int gpio_in_available,
-                 const unsigned int gpio_out_available,
-                 const unsigned char pa_available,
-                 const unsigned char pb_available)
+static void ioif_watcher(const unsigned int gpio_in_available,
+       const unsigned int gpio_out_available,
+       const unsigned char pa_available,
+       const unsigned char pb_available)
 {
        unsigned long int flags;
-       D(printk("gpio.c: ioif_watcher called\n"));
-       D(printk("gpio.c: G in: 0x%08x G out: 0x%08x PA: 0x%02x PB: 0x%02x\n",
-                gpio_in_available, gpio_out_available, pa_available, pb_available));
+
+       D(printk(KERN_DEBUG "gpio.c: ioif_watcher called\n"));
+       D(printk(KERN_DEBUG "gpio.c: G in: 0x%08x G out: 0x%08x "
+               "PA: 0x%02x PB: 0x%02x\n",
+               gpio_in_available, gpio_out_available,
+               pa_available, pb_available));
 
        spin_lock_irqsave(&gpio_lock, flags);
 
@@ -872,7 +738,7 @@ void ioif_watcher(const unsigned int gpio_in_available,
 
        /* Initialise the dir_g_shadow etc. depending on genconfig */
        /* 0=input 1=output */
-       if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, g0dir, out)) 
+       if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, g0dir, out))
                dir_g_shadow |= (1 << 0);
        if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, g8_15dir, out))
                dir_g_shadow |= 0x0000FF00;
@@ -884,7 +750,8 @@ void ioif_watcher(const unsigned int gpio_in_available,
        changeable_dir_g = changeable_dir_g_mask;
        changeable_dir_g &= dir_g_out_bits;
        changeable_dir_g &= dir_g_in_bits;
-       /* Correct the bits that can change direction */ 
+
+       /* Correct the bits that can change direction */
        dir_g_out_bits &= ~changeable_dir_g;
        dir_g_out_bits |= dir_g_shadow;
        dir_g_in_bits &= ~changeable_dir_g;
@@ -892,7 +759,8 @@ void ioif_watcher(const unsigned int gpio_in_available,
 
        spin_unlock_irqrestore(&gpio_lock, flags);
 
-       printk(KERN_INFO "GPIO port G: in_bits: 0x%08lX out_bits: 0x%08lX val: %08lX\n",
+       printk(KERN_INFO "GPIO port G: in_bits: 0x%08lX out_bits: 0x%08lX "
+               "val: %08lX\n",
               dir_g_in_bits, dir_g_out_bits, (unsigned long)*R_PORT_G_DATA);
        printk(KERN_INFO "GPIO port G: dir: %08lX changeable: %08lX\n",
               dir_g_shadow, changeable_dir_g);
@@ -900,16 +768,12 @@ void ioif_watcher(const unsigned int gpio_in_available,
 
 /* main driver initialization routine, called from mem.c */
 
-static __init int
-gpio_init(void)
+static int __init gpio_init(void)
 {
        int res;
 #if defined (CONFIG_ETRAX_CSP0_LEDS)
        int i;
 #endif
-        printk("gpio init\n");
-
-       /* do the formalities */
 
        res = register_chrdev(GPIO_MAJOR, gpio_name, &gpio_fops);
        if (res < 0) {
@@ -919,43 +783,45 @@ gpio_init(void)
 
        /* Clear all leds */
 #if defined (CONFIG_ETRAX_CSP0_LEDS) ||  defined (CONFIG_ETRAX_PA_LEDS) || defined (CONFIG_ETRAX_PB_LEDS)
-       LED_NETWORK_SET(0);
-       LED_ACTIVE_SET(0);
-       LED_DISK_READ(0);
-       LED_DISK_WRITE(0);
+       CRIS_LED_NETWORK_SET(0);
+       CRIS_LED_ACTIVE_SET(0);
+       CRIS_LED_DISK_READ(0);
+       CRIS_LED_DISK_WRITE(0);
 
 #if defined (CONFIG_ETRAX_CSP0_LEDS)
-       for (i = 0; i < 32; i++) {
-               LED_BIT_SET(i);
-       }
+       for (i = 0; i < 32; i++)
+               CRIS_LED_BIT_SET(i);
 #endif
 
 #endif
        /* The I/O interface allocation watcher will be called when
         * registering it. */
        if (cris_io_interface_register_watcher(ioif_watcher)){
-               printk(KERN_WARNING "gpio_init: Failed to install IO if allocator watcher\n");
+               printk(KERN_WARNING "gpio_init: Failed to install IO "
+                       "if allocator watcher\n");
        }
 
-       printk(KERN_INFO "ETRAX 100LX GPIO driver v2.5, (c) 2001, 2002, 2003, 2004 Axis Communications AB\n");
+       printk(KERN_INFO "ETRAX 100LX GPIO driver v2.5, (c) 2001-2008 "
+               "Axis Communications AB\n");
        /* We call etrax_gpio_wake_up_check() from timer interrupt and
         * from cpu_idle() in kernel/process.c
         * The check in cpu_idle() reduces latency from ~15 ms to ~6 ms
         * in some tests.
-        */  
-       if (request_irq(TIMER0_IRQ_NBR, gpio_poll_timer_interrupt,
-                       IRQF_SHARED | IRQF_DISABLED,"gpio poll", NULL)) {
+        */
+       res = request_irq(TIMER0_IRQ_NBR, gpio_poll_timer_interrupt,
+               IRQF_SHARED | IRQF_DISABLED, "gpio poll", gpio_name);
+       if (res) {
                printk(KERN_CRIT "err: timer0 irq for gpio\n");
+               return res;
        }
-       if (request_irq(PA_IRQ_NBR, gpio_pa_interrupt,
-                       IRQF_SHARED | IRQF_DISABLED,"gpio PA", NULL)) {
+       res = request_irq(PA_IRQ_NBR, gpio_interrupt,
+               IRQF_SHARED | IRQF_DISABLED, "gpio PA", gpio_name);
+       if (res)
                printk(KERN_CRIT "err: PA irq for gpio\n");
-       }
-       
 
        return res;
 }
 
 /* this makes sure that gpio_init is called during kernel boot */
-
 module_init(gpio_init);
+
index aca81ddaf60f787eb42256819d72ab137c3f4d23..d6d22067d0c80529733a4d8818a04ad120e62e59 100644 (file)
@@ -6,85 +6,9 @@
 *!              kernel modules (i2c_writereg/readreg) and from userspace using
 *!              ioctl()'s
 *!
-*! Nov 30 1998  Torbjorn Eliasson  Initial version.
-*!              Bjorn Wesen        Elinux kernel version.
-*! Jan 14 2000  Johan Adolfsson    Fixed PB shadow register stuff - 
-*!                                 don't use PB_I2C if DS1302 uses same bits,
-*!                                 use PB.
-*! $Log: i2c.c,v $
-*! Revision 1.13  2005/03/07 13:13:07  starvik
-*! Added spinlocks to protect states etc
-*!
-*! Revision 1.12  2005/01/05 06:11:22  starvik
-*! No need to do local_irq_disable after local_irq_save.
-*!
-*! Revision 1.11  2004/12/13 12:21:52  starvik
-*! Added I/O and DMA allocators from Linux 2.4
-*!
-*! Revision 1.9  2004/08/24 06:49:14  starvik
-*! Whitespace cleanup
-*!
-*! Revision 1.8  2004/06/08 08:48:26  starvik
-*! Removed unused code
-*!
-*! Revision 1.7  2004/05/28 09:26:59  starvik
-*! Modified I2C initialization to work in 2.6.
-*!
-*! Revision 1.6  2004/05/14 07:58:03  starvik
-*! Merge of changes from 2.4
-*!
-*! Revision 1.4  2002/12/11 13:13:57  starvik
-*! Added arch/ to v10 specific includes
-*! Added fix from Linux 2.4 in serial.c (flush_to_flip_buffer)
-*!
-*! Revision 1.3  2002/11/20 11:56:11  starvik
-*! Merge of Linux 2.5.48
-*!
-*! Revision 1.2  2002/11/18 13:16:06  starvik
-*! Linux 2.5 port of latest 2.4 drivers
-*!
-*! Revision 1.9  2002/10/31 15:32:26  starvik
-*! Update Port B register and shadow even when running with hardware support
-*!   to avoid glitches when reading bits
-*! Never set direction to out in i2c_inbyte
-*! Removed incorrect clock toggling at end of i2c_inbyte
-*!
-*! Revision 1.8  2002/08/13 06:31:53  starvik
-*! Made SDA and SCL line configurable
-*! Modified i2c_inbyte to work with PCF8563
-*!
-*! Revision 1.7  2001/04/04 13:11:36  markusl
-*! Updated according to review remarks
-*!
-*! Revision 1.6  2001/03/19 12:43:00  markusl
-*! Made some symbols unstatic (used by the eeprom driver)
-*!
-*! Revision 1.5  2001/02/27 13:52:48  bjornw
-*! malloc.h -> slab.h
-*!
-*! Revision 1.4  2001/02/15 07:17:40  starvik
-*! Corrected usage if port_pb_i2c_shadow
-*!
-*! Revision 1.3  2001/01/26 17:55:13  bjornw
-*! * Made I2C_USES_PB_NOT_PB_I2C a CONFIG option instead of assigning it
-*!   magically. Config.in needs to set it for the options that need it, like
-*!   Dallas 1302 support. Actually, it should be default since it screws up
-*!   the PB bits even if you don't use I2C..
-*! * Include linux/config.h to get the above
-*!
-*! Revision 1.2  2001/01/18 15:49:30  bjornw
-*! 2.4 port of I2C including some cleanups (untested of course)
-*!
-*! Revision 1.1  2001/01/18 15:35:25  bjornw
-*! Verbatim copy of the Etrax i2c driver, 2.0 elinux version
-*!
-*!
-*! ---------------------------------------------------------------------------
-*!
-*! (C) Copyright 1999-2002 Axis Communications AB, LUND, SWEDEN
+*! (C) Copyright 1999-2007 Axis Communications AB, LUND, SWEDEN
 *!
 *!***************************************************************************/
-/* $Id: i2c.c,v 1.13 2005/03/07 13:13:07 starvik Exp $ */
 
 /****************** INCLUDE FILES SECTION ***********************************/
 
@@ -622,7 +546,7 @@ i2c_readreg(unsigned char theSlave, unsigned char theReg)
                 * last received byte needs to be nacked
                 * instead of acked
                 */
-               i2c_sendack();
+               i2c_sendnack();
                /*
                 * end sequence
                 */
@@ -708,6 +632,7 @@ i2c_init(void)
        if (!first) {
                return res;
        }
+       first = 0;
 
        /* Setup and enable the Port B I2C interface */
 
index c263b8232dbcdfa6148d026db5253a4effc3c6a2..52103d16dc6c0e2b185a8700f8d4263a7683d122 100644 (file)
@@ -8,14 +8,13 @@
  * low detector are also provided. All address and data are transferred
  * serially via two-line bidirectional I2C-bus. Maximum bus speed is
  * 400 kbits/s. The built-in word address register is incremented
- * automatically after each written or read bute.
+ * automatically after each written or read byte.
  *
- * Copyright (c) 2002, Axis Communications AB
+ * Copyright (c) 2002-2007, Axis Communications AB
  * All rights reserved.
  *
  * Author: Tobias Anderberg <tobiasa@axis.com>.
  *
- * $Id: pcf8563.c,v 1.11 2005/03/07 13:13:07 starvik Exp $
  */
 
 #include <linux/module.h>
 #include <linux/ioctl.h>
 #include <linux/delay.h>
 #include <linux/bcd.h>
-#include <linux/capability.h>
+#include <linux/mutex.h>
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
 #include <asm/io.h>
-#include <asm/arch/svinto.h>
 #include <asm/rtc.h>
+
 #include "i2c.h"
 
-#define PCF8563_MAJOR 121              /* Local major number. */
-#define DEVICE_NAME "rtc"              /* Name which is registered in /proc/devices. */
+#define PCF8563_MAJOR 121      /* Local major number. */
+#define DEVICE_NAME "rtc"      /* Name which is registered in /proc/devices. */
 #define PCF8563_NAME "PCF8563"
-#define DRIVER_VERSION "$Revision: 1.11 $"
+#define DRIVER_VERSION "$Revision: 1.24 $"
 
 /* I2C bus slave registers. */
 #define RTC_I2C_READ           0xa3
 #define rtc_read(x) i2c_readreg(RTC_I2C_READ, x)
 #define rtc_write(x,y) i2c_writereg(RTC_I2C_WRITE, x, y)
 
-static DEFINE_SPINLOCK(rtc_lock); /* Protect state etc */
-       
+static DEFINE_MUTEX(rtc_lock); /* Protect state etc */
+
 static const unsigned char days_in_month[] =
        { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
 
 int pcf8563_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
 
+/* Cache VL bit value read at driver init since writing the RTC_SECOND
+ * register clears the VL status.
+ */
+static int voltage_low;
+
 static const struct file_operations pcf8563_fops = {
        .owner = THIS_MODULE,
        .ioctl = pcf8563_ioctl,
 };
 
 unsigned char
-pcf8563_readreg(int reg) 
+pcf8563_readreg(int reg)
 {
-       unsigned char res = i2c_readreg(RTC_I2C_READ, reg);
-
-       /* The PCF8563 does not return 0 for unimplemented bits */
-       switch(reg)
-       {
-               case RTC_SECONDS:
-               case RTC_MINUTES:
-                    res &= 0x7f;
-                    break;
-               case RTC_HOURS:
-               case RTC_DAY_OF_MONTH:
-                    res &= 0x3f;
-                    break;
-               case RTC_MONTH:
-                    res = (res & 0x1f) - 1;  /* PCF8563 returns month in range 1-12 */
-                    break;
+       unsigned char res = rtc_read(reg);
+
+       /* The PCF8563 does not return 0 for unimplemented bits. */
+       switch (reg) {
+       case RTC_SECONDS:
+       case RTC_MINUTES:
+               res &= 0x7F;
+               break;
+       case RTC_HOURS:
+       case RTC_DAY_OF_MONTH:
+               res &= 0x3F;
+               break;
+       case RTC_WEEKDAY:
+               res &= 0x07;
+               break;
+       case RTC_MONTH:
+               res &= 0x1F;
+               break;
+       case RTC_CONTROL1:
+               res &= 0xA8;
+               break;
+       case RTC_CONTROL2:
+               res &= 0x1F;
+               break;
+       case RTC_CLOCKOUT_FREQ:
+       case RTC_TIMER_CONTROL:
+               res &= 0x83;
+               break;
        }
        return res;
 }
 
 void
-pcf8563_writereg(int reg, unsigned char val) 
+pcf8563_writereg(int reg, unsigned char val)
 {
-#ifdef CONFIG_ETRAX_RTC_READONLY
-       if (reg == RTC_CONTROL1 || (reg >= RTC_SECONDS && reg <= RTC_YEAR))
-               return;
-#endif
-
        rtc_write(reg, val);
 }
 
 void
 get_rtc_time(struct rtc_time *tm)
 {
-       tm->tm_sec = rtc_read(RTC_SECONDS);
-       tm->tm_min = rtc_read(RTC_MINUTES);
+       tm->tm_sec  = rtc_read(RTC_SECONDS);
+       tm->tm_min  = rtc_read(RTC_MINUTES);
        tm->tm_hour = rtc_read(RTC_HOURS);
        tm->tm_mday = rtc_read(RTC_DAY_OF_MONTH);
-       tm->tm_mon = rtc_read(RTC_MONTH);
+       tm->tm_wday = rtc_read(RTC_WEEKDAY);
+       tm->tm_mon  = rtc_read(RTC_MONTH);
        tm->tm_year = rtc_read(RTC_YEAR);
 
-       if (tm->tm_sec & 0x80)
-               printk(KERN_WARNING "%s: RTC Low Voltage - date/time is not reliable!\n", PCF8563_NAME);
+       if (tm->tm_sec & 0x80) {
+               printk(KERN_ERR "%s: RTC Voltage Low - reliable date/time "
+                      "information is no longer guaranteed!\n", PCF8563_NAME);
+       }
 
-       tm->tm_year = BCD_TO_BIN(tm->tm_year) + ((tm->tm_mon & 0x80) ? 100 : 0);
-       tm->tm_sec &= 0x7f;
-       tm->tm_min &= 0x7f;
-       tm->tm_hour &= 0x3f;
-       tm->tm_mday &= 0x3f;
-       tm->tm_mon &= 0x1f;
+       tm->tm_year  = BCD_TO_BIN(tm->tm_year) +
+                      ((tm->tm_mon & 0x80) ? 100 : 0);
+       tm->tm_sec  &= 0x7F;
+       tm->tm_min  &= 0x7F;
+       tm->tm_hour &= 0x3F;
+       tm->tm_mday &= 0x3F;
+       tm->tm_wday &= 0x07; /* Not coded in BCD. */
+       tm->tm_mon  &= 0x1F;
 
        BCD_TO_BIN(tm->tm_sec);
        BCD_TO_BIN(tm->tm_min);
@@ -126,17 +142,24 @@ get_rtc_time(struct rtc_time *tm)
 int __init
 pcf8563_init(void)
 {
-       int ret;
-
-       if ((ret = i2c_init())) {
-               printk(KERN_CRIT "pcf8563_init: failed to init i2c\n");
-               return ret;
+       static int res;
+       static int first = 1;
+
+       if (!first)
+               return res;
+       first = 0;
+
+       /* Initiate the i2c protocol. */
+       res = i2c_init();
+       if (res < 0) {
+               printk(KERN_CRIT "pcf8563_init: Failed to init i2c.\n");
+               return res;
        }
 
        /*
         * First of all we need to reset the chip. This is done by
-        * clearing control1, control2 and clk freq, clear the 
-        * Voltage Low bit, and resetting all alarms.
+        * clearing control1, control2 and clk freq and resetting
+        * all alarms.
         */
        if (rtc_write(RTC_CONTROL1, 0x00) < 0)
                goto err;
@@ -147,34 +170,36 @@ pcf8563_init(void)
        if (rtc_write(RTC_CLOCKOUT_FREQ, 0x00) < 0)
                goto err;
 
-       /* Clear the VL bit in the seconds register. */
-       ret = rtc_read(RTC_SECONDS);
-       
-       if (rtc_write(RTC_SECONDS, (ret & 0x7f)) < 0)
+       if (rtc_write(RTC_TIMER_CONTROL, 0x03) < 0)
                goto err;
-               
+
        /* Reset the alarms. */
-       if (rtc_write(RTC_MINUTE_ALARM, 0x00) < 0)
+       if (rtc_write(RTC_MINUTE_ALARM, 0x80) < 0)
                goto err;
-       
-       if (rtc_write(RTC_HOUR_ALARM, 0x00) < 0)
+
+       if (rtc_write(RTC_HOUR_ALARM, 0x80) < 0)
                goto err;
-       
-       if (rtc_write(RTC_DAY_ALARM, 0x00) < 0)
+
+       if (rtc_write(RTC_DAY_ALARM, 0x80) < 0)
                goto err;
-       
-       if (rtc_write(RTC_WEEKDAY_ALARM, 0x00) < 0)
+
+       if (rtc_write(RTC_WEEKDAY_ALARM, 0x80) < 0)
                goto err;
-        
-       /* Check for low voltage, and warn about it.. */
-       if (rtc_read(RTC_SECONDS) & 0x80)
-               printk(KERN_WARNING "%s: RTC Low Voltage - date/time is not reliable!\n", PCF8563_NAME);
-       
-       return 0;
+
+       /* Check for low voltage, and warn about it. */
+       if (rtc_read(RTC_SECONDS) & 0x80) {
+               voltage_low = 1;
+               printk(KERN_WARNING "%s: RTC Voltage Low - reliable "
+                      "date/time information is no longer guaranteed!\n",
+                      PCF8563_NAME);
+       }
+
+       return res;
 
 err:
        printk(KERN_INFO "%s: Error initializing chip.\n", PCF8563_NAME);
-       return -1;
+       res = -1;
+       return res;
 }
 
 void __exit
@@ -187,8 +212,8 @@ pcf8563_exit(void)
  * ioctl calls for this driver. Why return -ENOTTY upon error? Because
  * POSIX says so!
  */
-int
-pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
+int pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
+       unsigned long arg)
 {
        /* Some sanity checks. */
        if (_IOC_TYPE(cmd) != RTC_MAGIC)
@@ -198,124 +223,146 @@ pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned
                return -ENOTTY;
 
        switch (cmd) {
-               case RTC_RD_TIME:
-                       {
-                               struct rtc_time tm;
-
-                               spin_lock(&rtc_lock);
-                               get_rtc_time(&tm);
-
-                               if (copy_to_user((struct rtc_time *) arg, &tm, sizeof(struct rtc_time))) {
-                                       spin_unlock(&rtc_lock);
-                                       return -EFAULT;
-                               }
-
-                               spin_unlock(&rtc_lock);
-                               return 0;
-                       }
-                       break;
-               case RTC_SET_TIME:
-                       {
-#ifdef CONFIG_ETRAX_RTC_READONLY
-                               return -EPERM;
-#else
-                               int leap;
-                               int century;
-                               struct rtc_time tm;
-
-                               memset(&tm, 0, sizeof (struct rtc_time));
-                               if (!capable(CAP_SYS_TIME))
-                                       return -EPERM;
-
-                               if (copy_from_user(&tm, (struct rtc_time *) arg, sizeof(struct rtc_time)))
-                                       return -EFAULT;
-
-                               /* Convert from struct tm to struct rtc_time. */
-                               tm.tm_year += 1900;
-                               tm.tm_mon += 1;
-                               
-                               leap = ((tm.tm_mon == 2) && ((tm.tm_year % 4) == 0)) ? 1 : 0;
-
-                               /* Perform some sanity checks. */
-                               if ((tm.tm_year < 1970) ||
-                                   (tm.tm_mon > 12) ||
-                                   (tm.tm_mday == 0) ||
-                                   (tm.tm_mday > days_in_month[tm.tm_mon] + leap) ||
-                                   (tm.tm_hour >= 24) ||
-                                   (tm.tm_min >= 60) ||
-                                   (tm.tm_sec >= 60))
-                                       return -EINVAL;
-
-                               century = (tm.tm_year >= 2000) ? 0x80 : 0;
-                               tm.tm_year = tm.tm_year % 100;
-
-                               BIN_TO_BCD(tm.tm_year);
-                               BIN_TO_BCD(tm.tm_mday);
-                               BIN_TO_BCD(tm.tm_hour);
-                               BIN_TO_BCD(tm.tm_min);
-                               BIN_TO_BCD(tm.tm_sec);
-                               tm.tm_mon |= century;
-
-                               spin_lock(&rtc_lock);
-                               
-                               rtc_write(RTC_YEAR, tm.tm_year);
-                               rtc_write(RTC_MONTH, tm.tm_mon);
-                               rtc_write(RTC_DAY_OF_MONTH, tm.tm_mday);
-                               rtc_write(RTC_HOURS, tm.tm_hour);
-                               rtc_write(RTC_MINUTES, tm.tm_min);
-                               rtc_write(RTC_SECONDS, tm.tm_sec);
-
-                               spin_unlock(&rtc_lock);
-
-                               return 0;
-#endif /* !CONFIG_ETRAX_RTC_READONLY */
-                       }
-
-               case RTC_VLOW_RD:
-               {
-                       int vl_bit = 0;
-
-                       if (rtc_read(RTC_SECONDS) & 0x80) {
-                               vl_bit = 1;
-                               printk(KERN_WARNING "%s: RTC Voltage Low - reliable "
-                                      "date/time information is no longer guaranteed!\n",
-                                      PCF8563_NAME);
-                       }
-                       if (copy_to_user((int *) arg, &vl_bit, sizeof(int)))
-                               return -EFAULT;
-
-                       return 0;
-               }
+       case RTC_RD_TIME:
+       {
+               struct rtc_time tm;
 
-               case RTC_VLOW_SET:
-               {
-                       /* Clear the VL bit in the seconds register */
-                       int ret = rtc_read(RTC_SECONDS);
+               mutex_lock(&rtc_lock);
+               memset(&tm, 0, sizeof tm);
+               get_rtc_time(&tm);
 
-                       rtc_write(RTC_SECONDS, (ret & 0x7F));
+               if (copy_to_user((struct rtc_time *) arg, &tm,
+                                sizeof tm)) {
+                       spin_unlock(&rtc_lock);
+                       return -EFAULT;
+               }
+
+               mutex_unlock(&rtc_lock);
 
-                       return 0;
+               return 0;
+       }
+       case RTC_SET_TIME:
+       {
+               int leap;
+               int year;
+               int century;
+               struct rtc_time tm;
+
+               memset(&tm, 0, sizeof tm);
+               if (!capable(CAP_SYS_TIME))
+                       return -EPERM;
+
+               if (copy_from_user(&tm, (struct rtc_time *) arg, sizeof tm))
+                       return -EFAULT;
+
+               /* Convert from struct tm to struct rtc_time. */
+               tm.tm_year += 1900;
+               tm.tm_mon += 1;
+
+               /*
+                * Check if tm.tm_year is a leap year. A year is a leap
+                * year if it is divisible by 4 but not 100, except
+                * that years divisible by 400 _are_ leap years.
+                */
+               year = tm.tm_year;
+               leap = (tm.tm_mon == 2) &&
+                       ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0);
+
+               /* Perform some sanity checks. */
+               if ((tm.tm_year < 1970) ||
+                   (tm.tm_mon > 12) ||
+                   (tm.tm_mday == 0) ||
+                   (tm.tm_mday > days_in_month[tm.tm_mon] + leap) ||
+                   (tm.tm_wday >= 7) ||
+                   (tm.tm_hour >= 24) ||
+                   (tm.tm_min >= 60) ||
+                   (tm.tm_sec >= 60))
+                       return -EINVAL;
+
+               century = (tm.tm_year >= 2000) ? 0x80 : 0;
+               tm.tm_year = tm.tm_year % 100;
+
+               BIN_TO_BCD(tm.tm_year);
+               BIN_TO_BCD(tm.tm_mon);
+               BIN_TO_BCD(tm.tm_mday);
+               BIN_TO_BCD(tm.tm_hour);
+               BIN_TO_BCD(tm.tm_min);
+               BIN_TO_BCD(tm.tm_sec);
+               tm.tm_mon |= century;
+
+               mutex_lock(&rtc_lock);
+
+               rtc_write(RTC_YEAR, tm.tm_year);
+               rtc_write(RTC_MONTH, tm.tm_mon);
+               rtc_write(RTC_WEEKDAY, tm.tm_wday); /* Not coded in BCD. */
+               rtc_write(RTC_DAY_OF_MONTH, tm.tm_mday);
+               rtc_write(RTC_HOURS, tm.tm_hour);
+               rtc_write(RTC_MINUTES, tm.tm_min);
+               rtc_write(RTC_SECONDS, tm.tm_sec);
+
+               mutex_unlock(&rtc_lock);
+
+               return 0;
+       }
+       case RTC_VL_READ:
+               if (voltage_low) {
+                       printk(KERN_ERR "%s: RTC Voltage Low - "
+                              "reliable date/time information is no "
+                              "longer guaranteed!\n", PCF8563_NAME);
                }
 
-               default:
-                               return -ENOTTY;
+               if (copy_to_user((int *) arg, &voltage_low, sizeof(int)))
+                       return -EFAULT;
+               return 0;
+
+       case RTC_VL_CLR:
+       {
+               /* Clear the VL bit in the seconds register in case
+                * the time has not been set already (which would
+                * have cleared it). This does not really matter
+                * because of the cached voltage_low value but do it
+                * anyway for consistency. */
+
+               int ret = rtc_read(RTC_SECONDS);
+
+               rtc_write(RTC_SECONDS, (ret & 0x7F));
+
+               /* Clear the cached value. */
+               voltage_low = 0;
+
+               return 0;
+       }
+       default:
+               return -ENOTTY;
        }
 
        return 0;
 }
 
-static int __init
-pcf8563_register(void)
+static int __init pcf8563_register(void)
 {
-       pcf8563_init();
+       if (pcf8563_init() < 0) {
+               printk(KERN_INFO "%s: Unable to initialize Real-Time Clock "
+                      "Driver, %s\n", PCF8563_NAME, DRIVER_VERSION);
+               return -1;
+       }
+
        if (register_chrdev(PCF8563_MAJOR, DEVICE_NAME, &pcf8563_fops) < 0) {
                printk(KERN_INFO "%s: Unable to get major number %d for RTC device.\n",
                       PCF8563_NAME, PCF8563_MAJOR);
                return -1;
        }
 
-       printk(KERN_INFO "%s Real-Time Clock Driver, %s\n", PCF8563_NAME, DRIVER_VERSION);
-        return 0;
+       printk(KERN_INFO "%s Real-Time Clock Driver, %s\n", PCF8563_NAME,
+              DRIVER_VERSION);
+
+       /* Check for low voltage, and warn about it. */
+       if (voltage_low) {
+               printk(KERN_WARNING "%s: RTC Voltage Low - reliable date/time "
+                      "information is no longer guaranteed!\n", PCF8563_NAME);
+       }
+
+       return 0;
 }
 
 module_init(pcf8563_register);
diff --git a/arch/cris/arch-v10/drivers/sync_serial.c b/arch/cris/arch-v10/drivers/sync_serial.c
new file mode 100644 (file)
index 0000000..069546e
--- /dev/null
@@ -0,0 +1,1441 @@
+/*
+ * Simple synchronous serial port driver for ETRAX 100LX.
+ *
+ * Synchronous serial ports are used for continuous streamed data like audio.
+ * The default setting for this driver is compatible with the STA 013 MP3
+ * decoder. The driver can easily be tuned to fit other audio encoder/decoders
+ * and SPI
+ *
+ * Copyright (c) 2001-2008 Axis Communications AB
+ *
+ * Author: Mikael Starvik, Johan Adolfsson
+ *
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/major.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/poll.h>
+#include <linux/init.h>
+#include <linux/timer.h>
+#include <asm/irq.h>
+#include <asm/dma.h>
+#include <asm/io.h>
+#include <asm/arch/svinto.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/sync_serial.h>
+#include <asm/arch/io_interface_mux.h>
+
+/* The receiver is a bit tricky beacuse of the continuous stream of data.*/
+/*                                                                       */
+/* Three DMA descriptors are linked together. Each DMA descriptor is     */
+/* responsible for port->bufchunk of a common buffer.                    */
+/*                                                                       */
+/* +---------------------------------------------+                       */
+/* |   +----------+   +----------+   +----------+ |                      */
+/* +-> | Descr[0] |-->| Descr[1] |-->| Descr[2] |-+                      */
+/*     +----------+   +----------+   +----------+                        */
+/*         |            |              |                                 */
+/*         v            v              v                                 */
+/*   +-------------------------------------+                             */
+/*   |        BUFFER                       |                             */
+/*   +-------------------------------------+                             */
+/*      |<- data_avail ->|                                               */
+/*    readp          writep                                              */
+/*                                                                       */
+/* If the application keeps up the pace readp will be right after writep.*/
+/* If the application can't keep the pace we have to throw away data.    */
+/* The idea is that readp should be ready with the data pointed out by  */
+/* Descr[i] when the DMA has filled in Descr[i+1].                       */
+/* Otherwise we will discard                                            */
+/* the rest of the data pointed out by Descr1 and set readp to the start */
+/* of Descr2                                                             */
+
+#define SYNC_SERIAL_MAJOR 125
+
+/* IN_BUFFER_SIZE should be a multiple of 6 to make sure that 24 bit */
+/* words can be handled */
+#define IN_BUFFER_SIZE 12288
+#define IN_DESCR_SIZE 256
+#define NUM_IN_DESCR (IN_BUFFER_SIZE/IN_DESCR_SIZE)
+#define OUT_BUFFER_SIZE 4096
+
+#define DEFAULT_FRAME_RATE 0
+#define DEFAULT_WORD_RATE 7
+
+/* NOTE: Enabling some debug will likely cause overrun or underrun,
+ * especially if manual mode is use.
+ */
+#define DEBUG(x)
+#define DEBUGREAD(x)
+#define DEBUGWRITE(x)
+#define DEBUGPOLL(x)
+#define DEBUGRXINT(x)
+#define DEBUGTXINT(x)
+
+/* Define some macros to access ETRAX 100 registers */
+#define SETF(var, reg, field, val) \
+       do { \
+               var = (var & ~IO_MASK_(reg##_, field##_)) | \
+                       IO_FIELD_(reg##_, field##_, val); \
+       } while (0)
+
+#define SETS(var, reg, field, val) \
+       do { \
+               var = (var & ~IO_MASK_(reg##_, field##_)) | \
+                       IO_STATE_(reg##_, field##_, _##val); \
+       } while (0)
+
+struct sync_port {
+       /* Etrax registers and bits*/
+       const volatile unsigned *const status;
+       volatile unsigned *const ctrl_data;
+       volatile unsigned *const output_dma_first;
+       volatile unsigned char *const output_dma_cmd;
+       volatile unsigned char *const output_dma_clr_irq;
+       volatile unsigned *const input_dma_first;
+       volatile unsigned char *const input_dma_cmd;
+       volatile unsigned *const input_dma_descr;
+       /* 8*4 */
+       volatile unsigned char *const input_dma_clr_irq;
+       volatile unsigned *const data_out;
+       const volatile unsigned *const data_in;
+       char data_avail_bit; /* In R_IRQ_MASK1_RD/SET/CLR */
+       char transmitter_ready_bit; /* In R_IRQ_MASK1_RD/SET/CLR */
+       char input_dma_descr_bit; /* In R_IRQ_MASK2_RD */
+
+       char output_dma_bit; /* In R_IRQ_MASK2_RD */
+       /* End of fields initialised in array */
+       char started; /* 1 if port has been started */
+       char port_nbr; /* Port 0 or 1 */
+       char busy; /* 1 if port is busy */
+
+       char enabled;  /* 1 if port is enabled */
+       char use_dma;  /* 1 if port uses dma */
+       char tr_running;
+
+       char init_irqs;
+
+       /* Register shadow */
+       unsigned int ctrl_data_shadow;
+       /* Remaining bytes for current transfer */
+       volatile unsigned int out_count;
+       /* Current position in out_buffer */
+       unsigned char *outp;
+       /* 16*4 */
+       /* Next byte to be read by application */
+       volatile unsigned char *volatile readp;
+       /* Next byte to be written by etrax */
+       volatile unsigned char *volatile writep;
+
+       unsigned int in_buffer_size;
+       unsigned int inbufchunk;
+       struct etrax_dma_descr out_descr __attribute__ ((aligned(32)));
+       struct etrax_dma_descr in_descr[NUM_IN_DESCR] __attribute__ ((aligned(32)));
+       unsigned char out_buffer[OUT_BUFFER_SIZE] __attribute__ ((aligned(32)));
+       unsigned char in_buffer[IN_BUFFER_SIZE]__attribute__ ((aligned(32)));
+       unsigned char flip[IN_BUFFER_SIZE] __attribute__ ((aligned(32)));
+       struct etrax_dma_descr *next_rx_desc;
+       struct etrax_dma_descr *prev_rx_desc;
+       int full;
+
+       wait_queue_head_t out_wait_q;
+       wait_queue_head_t in_wait_q;
+};
+
+
+static int etrax_sync_serial_init(void);
+static void initialize_port(int portnbr);
+static inline int sync_data_avail(struct sync_port *port);
+
+static int sync_serial_open(struct inode *inode, struct file *file);
+static int sync_serial_release(struct inode *inode, struct file *file);
+static unsigned int sync_serial_poll(struct file *filp, poll_table *wait);
+
+static int sync_serial_ioctl(struct inode *inode, struct file *file,
+       unsigned int cmd, unsigned long arg);
+static ssize_t sync_serial_write(struct file *file, const char *buf,
+       size_t count, loff_t *ppos);
+static ssize_t sync_serial_read(struct file *file, char *buf,
+       size_t count, loff_t *ppos);
+
+#if ((defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0) && \
+     defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL0_DMA)) || \
+    (defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1) && \
+     defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL1_DMA)))
+#define SYNC_SER_DMA
+#endif
+
+static void send_word(struct sync_port *port);
+static void start_dma(struct sync_port *port, const char *data, int count);
+static void start_dma_in(struct sync_port *port);
+#ifdef SYNC_SER_DMA
+static irqreturn_t tr_interrupt(int irq, void *dev_id);
+static irqreturn_t rx_interrupt(int irq, void *dev_id);
+#endif
+#if ((defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0) && \
+     !defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL0_DMA)) || \
+    (defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1) && \
+     !defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL1_DMA)))
+#define SYNC_SER_MANUAL
+#endif
+#ifdef SYNC_SER_MANUAL
+static irqreturn_t manual_interrupt(int irq, void *dev_id);
+#endif
+
+/* The ports */
+static struct sync_port ports[] = {
+       {
+               .status                = R_SYNC_SERIAL1_STATUS,
+               .ctrl_data             = R_SYNC_SERIAL1_CTRL,
+               .output_dma_first      = R_DMA_CH8_FIRST,
+               .output_dma_cmd        = R_DMA_CH8_CMD,
+               .output_dma_clr_irq    = R_DMA_CH8_CLR_INTR,
+               .input_dma_first       = R_DMA_CH9_FIRST,
+               .input_dma_cmd         = R_DMA_CH9_CMD,
+               .input_dma_descr       = R_DMA_CH9_DESCR,
+               .input_dma_clr_irq     = R_DMA_CH9_CLR_INTR,
+               .data_out              = R_SYNC_SERIAL1_TR_DATA,
+               .data_in               = R_SYNC_SERIAL1_REC_DATA,
+               .data_avail_bit        = IO_BITNR(R_IRQ_MASK1_RD, ser1_data),
+               .transmitter_ready_bit = IO_BITNR(R_IRQ_MASK1_RD, ser1_ready),
+               .input_dma_descr_bit   = IO_BITNR(R_IRQ_MASK2_RD, dma9_descr),
+               .output_dma_bit        = IO_BITNR(R_IRQ_MASK2_RD, dma8_eop),
+               .init_irqs             = 1,
+#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL0_DMA)
+               .use_dma               = 1,
+#else
+               .use_dma               = 0,
+#endif
+       },
+       {
+               .status                = R_SYNC_SERIAL3_STATUS,
+               .ctrl_data             = R_SYNC_SERIAL3_CTRL,
+               .output_dma_first      = R_DMA_CH4_FIRST,
+               .output_dma_cmd        = R_DMA_CH4_CMD,
+               .output_dma_clr_irq    = R_DMA_CH4_CLR_INTR,
+               .input_dma_first       = R_DMA_CH5_FIRST,
+               .input_dma_cmd         = R_DMA_CH5_CMD,
+               .input_dma_descr       = R_DMA_CH5_DESCR,
+               .input_dma_clr_irq     = R_DMA_CH5_CLR_INTR,
+               .data_out              = R_SYNC_SERIAL3_TR_DATA,
+               .data_in               = R_SYNC_SERIAL3_REC_DATA,
+               .data_avail_bit        = IO_BITNR(R_IRQ_MASK1_RD, ser3_data),
+               .transmitter_ready_bit = IO_BITNR(R_IRQ_MASK1_RD, ser3_ready),
+               .input_dma_descr_bit   = IO_BITNR(R_IRQ_MASK2_RD, dma5_descr),
+               .output_dma_bit        = IO_BITNR(R_IRQ_MASK2_RD, dma4_eop),
+               .init_irqs             = 1,
+#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL1_DMA)
+               .use_dma               = 1,
+#else
+               .use_dma               = 0,
+#endif
+       }
+};
+
+/* Register shadows */
+static unsigned sync_serial_prescale_shadow;
+
+#define NUMBER_OF_PORTS 2
+
+static struct file_operations sync_serial_fops = {
+       .owner   = THIS_MODULE,
+       .write   = sync_serial_write,
+       .read    = sync_serial_read,
+       .poll    = sync_serial_poll,
+       .ioctl   = sync_serial_ioctl,
+       .open    = sync_serial_open,
+       .release = sync_serial_release
+};
+
+static int __init etrax_sync_serial_init(void)
+{
+       ports[0].enabled = 0;
+       ports[1].enabled = 0;
+
+#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0)
+       if (cris_request_io_interface(if_sync_serial_1, "sync_ser1")) {
+               printk(KERN_CRIT "ETRAX100LX sync_serial: "
+                       "Could not allocate IO group for port %d\n", 0);
+               return -EBUSY;
+       }
+#endif
+#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1)
+       if (cris_request_io_interface(if_sync_serial_3, "sync_ser3")) {
+#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0)
+               cris_free_io_interface(if_sync_serial_1);
+#endif
+               printk(KERN_CRIT "ETRAX100LX sync_serial: "
+                       "Could not allocate IO group for port %d\n", 1);
+               return -EBUSY;
+       }
+#endif
+
+       if (register_chrdev(SYNC_SERIAL_MAJOR, "sync serial",
+                       &sync_serial_fops) < 0) {
+#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1)
+               cris_free_io_interface(if_sync_serial_3);
+#endif
+#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0)
+               cris_free_io_interface(if_sync_serial_1);
+#endif
+               printk("unable to get major for synchronous serial port\n");
+               return -EBUSY;
+       }
+
+       /* Deselect synchronous serial ports while configuring. */
+       SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode1, async);
+       SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode3, async);
+       *R_GEN_CONFIG_II = gen_config_ii_shadow;
+
+       /* Initialize Ports */
+#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0)
+       ports[0].enabled = 1;
+       SETS(port_pb_i2c_shadow, R_PORT_PB_I2C, syncser1, ss1extra);
+       SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode1, sync);
+#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL0_DMA)
+       ports[0].use_dma = 1;
+#else
+       ports[0].use_dma = 0;
+#endif
+       initialize_port(0);
+#endif
+
+#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1)
+       ports[1].enabled = 1;
+       SETS(port_pb_i2c_shadow, R_PORT_PB_I2C, syncser3, ss3extra);
+       SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode3, sync);
+#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL1_DMA)
+       ports[1].use_dma = 1;
+#else
+       ports[1].use_dma = 0;
+#endif
+       initialize_port(1);
+#endif
+
+       *R_PORT_PB_I2C = port_pb_i2c_shadow; /* Use PB4/PB7 */
+
+       /* Set up timing */
+       *R_SYNC_SERIAL_PRESCALE = sync_serial_prescale_shadow = (
+               IO_STATE(R_SYNC_SERIAL_PRESCALE, clk_sel_u1, codec) |
+               IO_STATE(R_SYNC_SERIAL_PRESCALE, word_stb_sel_u1, external) |
+               IO_STATE(R_SYNC_SERIAL_PRESCALE, clk_sel_u3, codec) |
+               IO_STATE(R_SYNC_SERIAL_PRESCALE, word_stb_sel_u3, external) |
+               IO_STATE(R_SYNC_SERIAL_PRESCALE, prescaler, div4) |
+               IO_FIELD(R_SYNC_SERIAL_PRESCALE, frame_rate,
+                       DEFAULT_FRAME_RATE) |
+               IO_FIELD(R_SYNC_SERIAL_PRESCALE, word_rate, DEFAULT_WORD_RATE) |
+               IO_STATE(R_SYNC_SERIAL_PRESCALE, warp_mode, normal));
+
+       /* Select synchronous ports */
+       *R_GEN_CONFIG_II = gen_config_ii_shadow;
+
+       printk(KERN_INFO "ETRAX 100LX synchronous serial port driver\n");
+       return 0;
+}
+
+static void __init initialize_port(int portnbr)
+{
+       struct sync_port *port = &ports[portnbr];
+
+       DEBUG(printk(KERN_DEBUG "Init sync serial port %d\n", portnbr));
+
+       port->started = 0;
+       port->port_nbr = portnbr;
+       port->busy = 0;
+       port->tr_running = 0;
+
+       port->out_count = 0;
+       port->outp = port->out_buffer;
+
+       port->readp = port->flip;
+       port->writep = port->flip;
+       port->in_buffer_size = IN_BUFFER_SIZE;
+       port->inbufchunk = IN_DESCR_SIZE;
+       port->next_rx_desc = &port->in_descr[0];
+       port->prev_rx_desc = &port->in_descr[NUM_IN_DESCR-1];
+       port->prev_rx_desc->ctrl = d_eol;
+
+       init_waitqueue_head(&port->out_wait_q);
+       init_waitqueue_head(&port->in_wait_q);
+
+       port->ctrl_data_shadow =
+               IO_STATE(R_SYNC_SERIAL1_CTRL, tr_baud, c115k2Hz)   |
+               IO_STATE(R_SYNC_SERIAL1_CTRL, mode, master_output) |
+               IO_STATE(R_SYNC_SERIAL1_CTRL, error, ignore)       |
+               IO_STATE(R_SYNC_SERIAL1_CTRL, rec_enable, disable) |
+               IO_STATE(R_SYNC_SERIAL1_CTRL, f_synctype, normal)  |
+               IO_STATE(R_SYNC_SERIAL1_CTRL, f_syncsize, word)    |
+               IO_STATE(R_SYNC_SERIAL1_CTRL, f_sync, on)            |
+               IO_STATE(R_SYNC_SERIAL1_CTRL, clk_mode, normal)    |
+               IO_STATE(R_SYNC_SERIAL1_CTRL, clk_halt, stopped)   |
+               IO_STATE(R_SYNC_SERIAL1_CTRL, bitorder, msb)         |
+               IO_STATE(R_SYNC_SERIAL1_CTRL, tr_enable, disable)  |
+               IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size8bit)  |
+               IO_STATE(R_SYNC_SERIAL1_CTRL, buf_empty, lmt_8)    |
+               IO_STATE(R_SYNC_SERIAL1_CTRL, buf_full, lmt_8)     |
+               IO_STATE(R_SYNC_SERIAL1_CTRL, flow_ctrl, enabled)  |
+               IO_STATE(R_SYNC_SERIAL1_CTRL, clk_polarity, neg)   |
+               IO_STATE(R_SYNC_SERIAL1_CTRL, frame_polarity, normal)|
+               IO_STATE(R_SYNC_SERIAL1_CTRL, status_polarity, inverted)|
+               IO_STATE(R_SYNC_SERIAL1_CTRL, clk_driver, normal)   |
+               IO_STATE(R_SYNC_SERIAL1_CTRL, frame_driver, normal) |
+               IO_STATE(R_SYNC_SERIAL1_CTRL, status_driver, normal)|
+               IO_STATE(R_SYNC_SERIAL1_CTRL, def_out0, high);
+
+       if (port->use_dma)
+               port->ctrl_data_shadow |= IO_STATE(R_SYNC_SERIAL1_CTRL,
+                       dma_enable, on);
+       else
+               port->ctrl_data_shadow |= IO_STATE(R_SYNC_SERIAL1_CTRL,
+                       dma_enable, off);
+
+       *port->ctrl_data = port->ctrl_data_shadow;
+}
+
+static inline int sync_data_avail(struct sync_port *port)
+{
+       int avail;
+       unsigned char *start;
+       unsigned char *end;
+
+       start = (unsigned char *)port->readp; /* cast away volatile */
+       end = (unsigned char *)port->writep;  /* cast away volatile */
+       /* 0123456789  0123456789
+        *  -----      -    -----
+        *  ^rp  ^wp    ^wp ^rp
+        */
+       if (end >= start)
+               avail = end - start;
+       else
+               avail = port->in_buffer_size - (start - end);
+       return avail;
+}
+
+static inline int sync_data_avail_to_end(struct sync_port *port)
+{
+       int avail;
+       unsigned char *start;
+       unsigned char *end;
+
+       start = (unsigned char *)port->readp; /* cast away volatile */
+       end = (unsigned char *)port->writep;  /* cast away volatile */
+       /* 0123456789  0123456789
+        *  -----           -----
+        *  ^rp  ^wp    ^wp ^rp
+        */
+
+       if (end >= start)
+               avail = end - start;
+       else
+               avail = port->flip + port->in_buffer_size - start;
+       return avail;
+}
+
+
+static int sync_serial_open(struct inode *inode, struct file *file)
+{
+       int dev = MINOR(inode->i_rdev);
+       struct sync_port *port;
+       int mode;
+
+       DEBUG(printk(KERN_DEBUG "Open sync serial port %d\n", dev));
+
+       if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled) {
+               DEBUG(printk(KERN_DEBUG "Invalid minor %d\n", dev));
+               return -ENODEV;
+       }
+       port = &ports[dev];
+       /* Allow open this device twice (assuming one reader and one writer) */
+       if (port->busy == 2) {
+               DEBUG(printk(KERN_DEBUG "Device is busy.. \n"));
+               return -EBUSY;
+       }
+       if (port->init_irqs) {
+               if (port->use_dma) {
+                       if (port == &ports[0]) {
+#ifdef SYNC_SER_DMA
+                               if (request_irq(24, tr_interrupt, 0,
+                                               "synchronous serial 1 dma tr",
+                                               &ports[0])) {
+                                       printk(KERN_CRIT "Can't alloc "
+                                               "sync serial port 1 IRQ");
+                                       return -EBUSY;
+                               } else if (request_irq(25, rx_interrupt, 0,
+                                               "synchronous serial 1 dma rx",
+                                               &ports[0])) {
+                                       free_irq(24, &port[0]);
+                                       printk(KERN_CRIT "Can't alloc "
+                                               "sync serial port 1 IRQ");
+                                       return -EBUSY;
+                               } else if (cris_request_dma(8,
+                                               "synchronous serial 1 dma tr",
+                                               DMA_VERBOSE_ON_ERROR,
+                                               dma_ser1)) {
+                                       free_irq(24, &port[0]);
+                                       free_irq(25, &port[0]);
+                                       printk(KERN_CRIT "Can't alloc "
+                                               "sync serial port 1 "
+                                               "TX DMA channel");
+                                       return -EBUSY;
+                               } else if (cris_request_dma(9,
+                                               "synchronous serial 1 dma rec",
+                                               DMA_VERBOSE_ON_ERROR,
+                                               dma_ser1)) {
+                                       cris_free_dma(8, NULL);
+                                       free_irq(24, &port[0]);
+                                       free_irq(25, &port[0]);
+                                       printk(KERN_CRIT "Can't alloc "
+                                               "sync serial port 1 "
+                                               "RX DMA channel");
+                                       return -EBUSY;
+                               }
+#endif
+                               RESET_DMA(8); WAIT_DMA(8);
+                               RESET_DMA(9); WAIT_DMA(9);
+                               *R_DMA_CH8_CLR_INTR =
+                                       IO_STATE(R_DMA_CH8_CLR_INTR, clr_eop,
+                                               do) |
+                                       IO_STATE(R_DMA_CH8_CLR_INTR, clr_descr,
+                                               do);
+                               *R_DMA_CH9_CLR_INTR =
+                                       IO_STATE(R_DMA_CH9_CLR_INTR, clr_eop,
+                                               do) |
+                                       IO_STATE(R_DMA_CH9_CLR_INTR, clr_descr,
+                                               do);
+                               *R_IRQ_MASK2_SET =
+                                       IO_STATE(R_IRQ_MASK2_SET, dma8_eop,
+                                               set) |
+                                       IO_STATE(R_IRQ_MASK2_SET, dma9_descr,
+                                               set);
+                       } else if (port == &ports[1]) {
+#ifdef SYNC_SER_DMA
+                               if (request_irq(20, tr_interrupt, 0,
+                                               "synchronous serial 3 dma tr",
+                                               &ports[1])) {
+                                       printk(KERN_CRIT "Can't alloc "
+                                               "sync serial port 3 IRQ");
+                                       return -EBUSY;
+                               } else if (request_irq(21, rx_interrupt, 0,
+                                               "synchronous serial 3 dma rx",
+                                               &ports[1])) {
+                                       free_irq(20, &ports[1]);
+                                       printk(KERN_CRIT "Can't alloc "
+                                               "sync serial port 3 IRQ");
+                                       return -EBUSY;
+                               } else if (cris_request_dma(4,
+                                               "synchronous serial 3 dma tr",
+                                               DMA_VERBOSE_ON_ERROR,
+                                               dma_ser3)) {
+                                       free_irq(21, &ports[1]);
+                                       free_irq(20, &ports[1]);
+                                       printk(KERN_CRIT "Can't alloc "
+                                               "sync serial port 3 "
+                                               "TX DMA channel");
+                                       return -EBUSY;
+                               } else if (cris_request_dma(5,
+                                               "synchronous serial 3 dma rec",
+                                               DMA_VERBOSE_ON_ERROR,
+                                               dma_ser3)) {
+                                       cris_free_dma(4, NULL);
+                                       free_irq(21, &ports[1]);
+                                       free_irq(20, &ports[1]);
+                                       printk(KERN_CRIT "Can't alloc "
+                                               "sync serial port 3 "
+                                               "RX DMA channel");
+                                       return -EBUSY;
+                               }
+#endif
+                               RESET_DMA(4); WAIT_DMA(4);
+                               RESET_DMA(5); WAIT_DMA(5);
+                               *R_DMA_CH4_CLR_INTR =
+                                       IO_STATE(R_DMA_CH4_CLR_INTR, clr_eop,
+                                               do) |
+                                       IO_STATE(R_DMA_CH4_CLR_INTR, clr_descr,
+                                               do);
+                               *R_DMA_CH5_CLR_INTR =
+                                       IO_STATE(R_DMA_CH5_CLR_INTR, clr_eop,
+                                               do) |
+                                       IO_STATE(R_DMA_CH5_CLR_INTR, clr_descr,
+                                               do);
+                               *R_IRQ_MASK2_SET =
+                                       IO_STATE(R_IRQ_MASK2_SET, dma4_eop,
+                                               set) |
+                                       IO_STATE(R_IRQ_MASK2_SET, dma5_descr,
+                                               set);
+                       }
+                       start_dma_in(port);
+                       port->init_irqs = 0;
+               } else { /* !port->use_dma */
+#ifdef SYNC_SER_MANUAL
+                       if (port == &ports[0]) {
+                               if (request_irq(8,
+                                               manual_interrupt,
+                                               IRQF_SHARED | IRQF_DISABLED,
+                                               "synchronous serial manual irq",
+                                               &ports[0])) {
+                                       printk(KERN_CRIT "Can't alloc "
+                                               "sync serial manual irq");
+                                       return -EBUSY;
+                               }
+                       } else if (port == &ports[1]) {
+                               if (request_irq(8,
+                                               manual_interrupt,
+                                               IRQF_SHARED | IRQF_DISABLED,
+                                               "synchronous serial manual irq",
+                                               &ports[1])) {
+                                       printk(KERN_CRIT "Can't alloc "
+                                               "sync serial manual irq");
+                                       return -EBUSY;
+                               }
+                       }
+                       port->init_irqs = 0;
+#else
+                       panic("sync_serial: Manual mode not supported.\n");
+#endif /* SYNC_SER_MANUAL */
+               }
+       } /* port->init_irqs */
+
+       port->busy++;
+       /* Start port if we use it as input */
+       mode = IO_EXTRACT(R_SYNC_SERIAL1_CTRL, mode, port->ctrl_data_shadow);
+       if (mode == IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, mode, master_input) ||
+           mode == IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, mode, slave_input) ||
+           mode == IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, mode, master_bidir) ||
+           mode == IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, mode, slave_bidir)) {
+               SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_halt,
+                       running);
+               SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, tr_enable,
+                       enable);
+               SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, rec_enable,
+                       enable);
+               port->started = 1;
+               *port->ctrl_data = port->ctrl_data_shadow;
+               if (!port->use_dma)
+                       *R_IRQ_MASK1_SET = 1 << port->data_avail_bit;
+               DEBUG(printk(KERN_DEBUG "sser%d rec started\n", dev));
+       }
+       return 0;
+}
+
+static int sync_serial_release(struct inode *inode, struct file *file)
+{
+       int dev = MINOR(inode->i_rdev);
+       struct sync_port *port;
+
+       if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled) {
+               DEBUG(printk(KERN_DEBUG "Invalid minor %d\n", dev));
+               return -ENODEV;
+       }
+       port = &ports[dev];
+       if (port->busy)
+               port->busy--;
+       if (!port->busy)
+               *R_IRQ_MASK1_CLR = ((1 << port->data_avail_bit) |
+                                   (1 << port->transmitter_ready_bit));
+
+       return 0;
+}
+
+
+
+static unsigned int sync_serial_poll(struct file *file, poll_table *wait)
+{
+       int dev = MINOR(file->f_dentry->d_inode->i_rdev);
+       unsigned int mask = 0;
+       struct sync_port *port;
+       DEBUGPOLL(static unsigned int prev_mask = 0);
+
+       port = &ports[dev];
+       poll_wait(file, &port->out_wait_q, wait);
+       poll_wait(file, &port->in_wait_q, wait);
+       /* Some room to write */
+       if (port->out_count < OUT_BUFFER_SIZE)
+               mask |=  POLLOUT | POLLWRNORM;
+       /* At least an inbufchunk of data */
+       if (sync_data_avail(port) >= port->inbufchunk)
+               mask |= POLLIN | POLLRDNORM;
+
+       DEBUGPOLL(if (mask != prev_mask)
+               printk(KERN_DEBUG "sync_serial_poll: mask 0x%08X %s %s\n",
+                       mask,
+                       mask & POLLOUT ? "POLLOUT" : "",
+                       mask & POLLIN ? "POLLIN" : "");
+               prev_mask = mask;
+       );
+       return mask;
+}
+
+static int sync_serial_ioctl(struct inode *inode, struct file *file,
+                 unsigned int cmd, unsigned long arg)
+{
+       int return_val = 0;
+       unsigned long flags;
+
+       int dev = MINOR(file->f_dentry->d_inode->i_rdev);
+       struct sync_port *port;
+
+       if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled) {
+               DEBUG(printk(KERN_DEBUG "Invalid minor %d\n", dev));
+               return -1;
+       }
+       port = &ports[dev];
+
+       local_irq_save(flags);
+       /* Disable port while changing config */
+       if (dev) {
+               if (port->use_dma) {
+                       RESET_DMA(4); WAIT_DMA(4);
+                       port->tr_running = 0;
+                       port->out_count = 0;
+                       port->outp = port->out_buffer;
+                       *R_DMA_CH4_CLR_INTR =
+                               IO_STATE(R_DMA_CH4_CLR_INTR, clr_eop, do) |
+                               IO_STATE(R_DMA_CH4_CLR_INTR, clr_descr, do);
+               }
+               SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode3, async);
+       } else {
+               if (port->use_dma) {
+                       RESET_DMA(8); WAIT_DMA(8);
+                       port->tr_running = 0;
+                       port->out_count = 0;
+                       port->outp = port->out_buffer;
+                       *R_DMA_CH8_CLR_INTR =
+                               IO_STATE(R_DMA_CH8_CLR_INTR, clr_eop, do) |
+                               IO_STATE(R_DMA_CH8_CLR_INTR, clr_descr, do);
+               }
+               SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode1, async);
+       }
+       *R_GEN_CONFIG_II = gen_config_ii_shadow;
+       local_irq_restore(flags);
+
+       switch (cmd) {
+       case SSP_SPEED:
+               if (GET_SPEED(arg) == CODEC) {
+                       if (dev)
+                               SETS(sync_serial_prescale_shadow,
+                                       R_SYNC_SERIAL_PRESCALE, clk_sel_u3,
+                                       codec);
+                       else
+                               SETS(sync_serial_prescale_shadow,
+                                       R_SYNC_SERIAL_PRESCALE, clk_sel_u1,
+                                       codec);
+
+                       SETF(sync_serial_prescale_shadow,
+                               R_SYNC_SERIAL_PRESCALE, prescaler,
+                               GET_FREQ(arg));
+                       SETF(sync_serial_prescale_shadow,
+                               R_SYNC_SERIAL_PRESCALE, frame_rate,
+                               GET_FRAME_RATE(arg));
+                       SETF(sync_serial_prescale_shadow,
+                               R_SYNC_SERIAL_PRESCALE, word_rate,
+                               GET_WORD_RATE(arg));
+               } else {
+                       SETF(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
+                               tr_baud, GET_SPEED(arg));
+                       if (dev)
+                               SETS(sync_serial_prescale_shadow,
+                                       R_SYNC_SERIAL_PRESCALE, clk_sel_u3,
+                                       baudrate);
+                       else
+                               SETS(sync_serial_prescale_shadow,
+                                       R_SYNC_SERIAL_PRESCALE, clk_sel_u1,
+                                       baudrate);
+               }
+               break;
+       case SSP_MODE:
+               if (arg > 5)
+                       return -EINVAL;
+               if (arg == MASTER_OUTPUT || arg == SLAVE_OUTPUT)
+                       *R_IRQ_MASK1_CLR = 1 << port->data_avail_bit;
+               else if (!port->use_dma)
+                       *R_IRQ_MASK1_SET = 1 << port->data_avail_bit;
+               SETF(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, mode, arg);
+               break;
+       case SSP_FRAME_SYNC:
+               if (arg & NORMAL_SYNC)
+                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
+                               f_synctype, normal);
+               else if (arg & EARLY_SYNC)
+                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
+                               f_synctype, early);
+
+               if (arg & BIT_SYNC)
+                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
+                               f_syncsize, bit);
+               else if (arg & WORD_SYNC)
+                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
+                               f_syncsize, word);
+               else if (arg & EXTENDED_SYNC)
+                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
+                               f_syncsize, extended);
+
+               if (arg & SYNC_ON)
+                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
+                               f_sync, on);
+               else if (arg & SYNC_OFF)
+                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
+                               f_sync, off);
+
+               if (arg & WORD_SIZE_8)
+                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
+                               wordsize, size8bit);
+               else if (arg & WORD_SIZE_12)
+                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
+                               wordsize, size12bit);
+               else if (arg & WORD_SIZE_16)
+                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
+                               wordsize, size16bit);
+               else if (arg & WORD_SIZE_24)
+                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
+                               wordsize, size24bit);
+               else if (arg & WORD_SIZE_32)
+                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
+                               wordsize, size32bit);
+
+               if (arg & BIT_ORDER_MSB)
+                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
+                               bitorder, msb);
+               else if (arg & BIT_ORDER_LSB)
+                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
+                               bitorder, lsb);
+
+               if (arg & FLOW_CONTROL_ENABLE)
+                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
+                               flow_ctrl, enabled);
+               else if (arg & FLOW_CONTROL_DISABLE)
+                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
+                               flow_ctrl, disabled);
+
+               if (arg & CLOCK_NOT_GATED)
+                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
+                               clk_mode, normal);
+               else if (arg & CLOCK_GATED)
+                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
+                               clk_mode, gated);
+
+               break;
+       case SSP_IPOLARITY:
+               /* NOTE!! negedge is considered NORMAL */
+               if (arg & CLOCK_NORMAL)
+                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
+                               clk_polarity, neg);
+               else if (arg & CLOCK_INVERT)
+                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
+                               clk_polarity, pos);
+
+               if (arg & FRAME_NORMAL)
+                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
+                               frame_polarity, normal);
+               else if (arg & FRAME_INVERT)
+                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
+                               frame_polarity, inverted);
+
+               if (arg & STATUS_NORMAL)
+                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
+                               status_polarity, normal);
+               else if (arg & STATUS_INVERT)
+                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
+                               status_polarity, inverted);
+               break;
+       case SSP_OPOLARITY:
+               if (arg & CLOCK_NORMAL)
+                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
+                               clk_driver, normal);
+               else if (arg & CLOCK_INVERT)
+                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
+                               clk_driver, inverted);
+
+               if (arg & FRAME_NORMAL)
+                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
+                               frame_driver, normal);
+               else if (arg & FRAME_INVERT)
+                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
+                               frame_driver, inverted);
+
+               if (arg & STATUS_NORMAL)
+                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
+                               status_driver, normal);
+               else if (arg & STATUS_INVERT)
+                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
+                               status_driver, inverted);
+               break;
+       case SSP_SPI:
+               SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, flow_ctrl,
+                       disabled);
+               SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, bitorder,
+                       msb);
+               SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize,
+                       size8bit);
+               SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_sync, on);
+               SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_syncsize,
+                       word);
+               SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_synctype,
+                       normal);
+               if (arg & SPI_SLAVE) {
+                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
+                               frame_polarity, inverted);
+                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
+                               clk_polarity, neg);
+                       SETF(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
+                               mode, SLAVE_INPUT);
+               } else {
+                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
+                               frame_driver, inverted);
+                       SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
+                               clk_driver, inverted);
+                       SETF(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
+                               mode, MASTER_OUTPUT);
+               }
+               break;
+       case SSP_INBUFCHUNK:
+#if 0
+               if (arg > port->in_buffer_size/NUM_IN_DESCR)
+                       return -EINVAL;
+               port->inbufchunk = arg;
+               /* Make sure in_buffer_size is a multiple of inbufchunk */
+               port->in_buffer_size =
+                       (port->in_buffer_size/port->inbufchunk) *
+                       port->inbufchunk;
+               DEBUG(printk(KERN_DEBUG "inbufchunk %i in_buffer_size: %i\n",
+                       port->inbufchunk, port->in_buffer_size));
+               if (port->use_dma) {
+                       if (port->port_nbr == 0) {
+                               RESET_DMA(9);
+                               WAIT_DMA(9);
+                       } else {
+                               RESET_DMA(5);
+                               WAIT_DMA(5);
+                       }
+                       start_dma_in(port);
+               }
+#endif
+               break;
+       default:
+               return_val = -1;
+       }
+       /* Make sure we write the config without interruption */
+       local_irq_save(flags);
+       /* Set config and enable port */
+       *port->ctrl_data = port->ctrl_data_shadow;
+       nop(); nop(); nop(); nop();
+       *R_SYNC_SERIAL_PRESCALE = sync_serial_prescale_shadow;
+       nop(); nop(); nop(); nop();
+       if (dev)
+               SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode3, sync);
+       else
+               SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode1, sync);
+
+       *R_GEN_CONFIG_II = gen_config_ii_shadow;
+       /* Reset DMA. At readout from serial port the data could be shifted
+        * one byte if not resetting DMA.
+        */
+       if (port->use_dma) {
+               if (port->port_nbr == 0) {
+                       RESET_DMA(9);
+                       WAIT_DMA(9);
+               } else {
+                       RESET_DMA(5);
+                       WAIT_DMA(5);
+               }
+               start_dma_in(port);
+       }
+       local_irq_restore(flags);
+       return return_val;
+}
+
+
+static ssize_t sync_serial_write(struct file *file, const char *buf,
+       size_t count, loff_t *ppos)
+{
+       int dev = MINOR(file->f_dentry->d_inode->i_rdev);
+       DECLARE_WAITQUEUE(wait, current);
+       struct sync_port *port;
+       unsigned long flags;
+       unsigned long c, c1;
+       unsigned long free_outp;
+       unsigned long outp;
+       unsigned long out_buffer;
+
+       if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled) {
+               DEBUG(printk(KERN_DEBUG "Invalid minor %d\n", dev));
+               return -ENODEV;
+       }
+       port = &ports[dev];
+
+       DEBUGWRITE(printk(KERN_DEBUG "W d%d c %lu (%d/%d)\n",
+               port->port_nbr, count, port->out_count, OUT_BUFFER_SIZE));
+       /* Space to end of buffer */
+       /*
+        * out_buffer <c1>012345<-   c    ->OUT_BUFFER_SIZE
+        *            outp^    +out_count
+        *                      ^free_outp
+        * out_buffer 45<-     c      ->0123OUT_BUFFER_SIZE
+        *             +out_count   outp^
+        *              free_outp
+        *
+        */
+
+       /* Read variables that may be updated by interrupts */
+       local_irq_save(flags);
+       if (count > OUT_BUFFER_SIZE - port->out_count)
+               count = OUT_BUFFER_SIZE - port->out_count;
+
+       outp = (unsigned long)port->outp;
+       free_outp = outp + port->out_count;
+       local_irq_restore(flags);
+       out_buffer = (unsigned long)port->out_buffer;
+
+       /* Find out where and how much to write */
+       if (free_outp >= out_buffer + OUT_BUFFER_SIZE)
+               free_outp -= OUT_BUFFER_SIZE;
+       if (free_outp >= outp)
+               c = out_buffer + OUT_BUFFER_SIZE - free_outp;
+       else
+               c = outp - free_outp;
+       if (c > count)
+               c = count;
+
+       DEBUGWRITE(printk(KERN_DEBUG "w op %08lX fop %08lX c %lu\n",
+               outp, free_outp, c));
+       if (copy_from_user((void *)free_outp, buf, c))
+               return -EFAULT;
+
+       if (c != count) {
+               buf += c;
+               c1 = count - c;
+               DEBUGWRITE(printk(KERN_DEBUG "w2 fi %lu c %lu c1 %lu\n",
+                       free_outp-out_buffer, c, c1));
+               if (copy_from_user((void *)out_buffer, buf, c1))
+                       return -EFAULT;
+       }
+       local_irq_save(flags);
+       port->out_count += count;
+       local_irq_restore(flags);
+
+       /* Make sure transmitter/receiver is running */
+       if (!port->started) {
+               SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_halt,
+                       running);
+               SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, tr_enable,
+                       enable);
+               SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, rec_enable,
+                       enable);
+               port->started = 1;
+       }
+
+       *port->ctrl_data = port->ctrl_data_shadow;
+
+       if (file->f_flags & O_NONBLOCK) {
+               local_irq_save(flags);
+               if (!port->tr_running) {
+                       if (!port->use_dma) {
+                               /* Start sender by writing data */
+                               send_word(port);
+                               /* and enable transmitter ready IRQ */
+                               *R_IRQ_MASK1_SET = 1 <<
+                                       port->transmitter_ready_bit;
+                       } else
+                               start_dma(port,
+                                       (unsigned char *volatile)port->outp, c);
+               }
+               local_irq_restore(flags);
+               DEBUGWRITE(printk(KERN_DEBUG "w d%d c %lu NB\n",
+                       port->port_nbr, count));
+               return count;
+       }
+
+       /* Sleep until all sent */
+       add_wait_queue(&port->out_wait_q, &wait);
+       set_current_state(TASK_INTERRUPTIBLE);
+       local_irq_save(flags);
+       if (!port->tr_running) {
+               if (!port->use_dma) {
+                       /* Start sender by writing data */
+                       send_word(port);
+                       /* and enable transmitter ready IRQ */
+                       *R_IRQ_MASK1_SET = 1 << port->transmitter_ready_bit;
+               } else
+                       start_dma(port, port->outp, c);
+       }
+       local_irq_restore(flags);
+       schedule();
+       set_current_state(TASK_RUNNING);
+       remove_wait_queue(&port->out_wait_q, &wait);
+       if (signal_pending(current))
+               return -EINTR;
+
+       DEBUGWRITE(printk(KERN_DEBUG "w d%d c %lu\n", port->port_nbr, count));
+       return count;
+}
+
+static ssize_t sync_serial_read(struct file *file, char *buf,
+                               size_t count, loff_t *ppos)
+{
+       int dev = MINOR(file->f_dentry->d_inode->i_rdev);
+       int avail;
+       struct sync_port *port;
+       unsigned char *start;
+       unsigned char *end;
+       unsigned long flags;
+
+       if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled) {
+               DEBUG(printk(KERN_DEBUG "Invalid minor %d\n", dev));
+               return -ENODEV;
+       }
+       port = &ports[dev];
+
+       DEBUGREAD(printk(KERN_DEBUG "R%d c %d ri %lu wi %lu /%lu\n",
+               dev, count, port->readp - port->flip,
+               port->writep - port->flip, port->in_buffer_size));
+
+       if (!port->started) {
+               SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_halt,
+                       running);
+               SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, tr_enable,
+                       enable);
+               SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, rec_enable,
+                       enable);
+               port->started = 1;
+       }
+       *port->ctrl_data = port->ctrl_data_shadow;
+
+       /* Calculate number of available bytes */
+       /* Save pointers to avoid that they are modified by interrupt */
+       local_irq_save(flags);
+       start = (unsigned char *)port->readp; /* cast away volatile */
+       end = (unsigned char *)port->writep;  /* cast away volatile */
+       local_irq_restore(flags);
+       while (start == end && !port->full) {
+               /* No data */
+               if (file->f_flags & O_NONBLOCK)
+                       return -EAGAIN;
+
+               interruptible_sleep_on(&port->in_wait_q);
+               if (signal_pending(current))
+                       return -EINTR;
+
+               local_irq_save(flags);
+               start = (unsigned char *)port->readp; /* cast away volatile */
+               end = (unsigned char *)port->writep;  /* cast away volatile */
+               local_irq_restore(flags);
+       }
+
+       /* Lazy read, never return wrapped data. */
+       if (port->full)
+               avail = port->in_buffer_size;
+       else if (end > start)
+               avail = end - start;
+       else
+               avail = port->flip + port->in_buffer_size - start;
+
+       count = count > avail ? avail : count;
+       if (copy_to_user(buf, start, count))
+               return -EFAULT;
+       /* Disable interrupts while updating readp */
+       local_irq_save(flags);
+       port->readp += count;
+       if (port->readp >= port->flip + port->in_buffer_size) /* Wrap? */
+               port->readp = port->flip;
+       port->full = 0;
+       local_irq_restore(flags);
+       DEBUGREAD(printk(KERN_DEBUG "r %d\n", count));
+       return count;
+}
+
+static void send_word(struct sync_port *port)
+{
+       switch (IO_EXTRACT(R_SYNC_SERIAL1_CTRL, wordsize,
+                       port->ctrl_data_shadow)) {
+       case IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, wordsize, size8bit):
+                port->out_count--;
+                *port->data_out = *port->outp++;
+                if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE)
+                        port->outp = port->out_buffer;
+                break;
+       case IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, wordsize, size12bit):
+       {
+               int data = (*port->outp++) << 8;
+               data |= *port->outp++;
+               port->out_count -= 2;
+               *port->data_out = data;
+               if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE)
+                       port->outp = port->out_buffer;
+               break;
+       }
+       case IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, wordsize, size16bit):
+               port->out_count -= 2;
+               *port->data_out = *(unsigned short *)port->outp;
+               port->outp += 2;
+               if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE)
+                       port->outp = port->out_buffer;
+               break;
+       case IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, wordsize, size24bit):
+               port->out_count -= 3;
+               *port->data_out = *(unsigned int *)port->outp;
+               port->outp += 3;
+               if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE)
+                       port->outp = port->out_buffer;
+               break;
+       case IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, wordsize, size32bit):
+               port->out_count -= 4;
+               *port->data_out = *(unsigned int *)port->outp;
+               port->outp += 4;
+               if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE)
+                       port->outp = port->out_buffer;
+               break;
+       }
+}
+
+
+static void start_dma(struct sync_port *port, const char *data, int count)
+{
+       port->tr_running = 1;
+       port->out_descr.hw_len = 0;
+       port->out_descr.next = 0;
+       port->out_descr.ctrl = d_eol | d_eop; /* No d_wait to avoid glitches */
+       port->out_descr.sw_len = count;
+       port->out_descr.buf = virt_to_phys(data);
+       port->out_descr.status = 0;
+
+       *port->output_dma_first = virt_to_phys(&port->out_descr);
+       *port->output_dma_cmd = IO_STATE(R_DMA_CH0_CMD, cmd, start);
+       DEBUGTXINT(printk(KERN_DEBUG "dma %08lX c %d\n",
+               (unsigned long)data, count));
+}
+
+static void start_dma_in(struct sync_port *port)
+{
+       int i;
+       unsigned long buf;
+       port->writep = port->flip;
+
+       if (port->writep > port->flip + port->in_buffer_size) {
+               panic("Offset too large in sync serial driver\n");
+               return;
+       }
+       buf = virt_to_phys(port->in_buffer);
+       for (i = 0; i < NUM_IN_DESCR; i++) {
+               port->in_descr[i].sw_len = port->inbufchunk;
+               port->in_descr[i].ctrl = d_int;
+               port->in_descr[i].next = virt_to_phys(&port->in_descr[i+1]);
+               port->in_descr[i].buf = buf;
+               port->in_descr[i].hw_len = 0;
+               port->in_descr[i].status = 0;
+               port->in_descr[i].fifo_len = 0;
+               buf += port->inbufchunk;
+               prepare_rx_descriptor(&port->in_descr[i]);
+       }
+       /* Link the last descriptor to the first */
+       port->in_descr[i-1].next = virt_to_phys(&port->in_descr[0]);
+       port->in_descr[i-1].ctrl |= d_eol;
+       port->next_rx_desc = &port->in_descr[0];
+       port->prev_rx_desc = &port->in_descr[NUM_IN_DESCR - 1];
+       *port->input_dma_first = virt_to_phys(port->next_rx_desc);
+       *port->input_dma_cmd = IO_STATE(R_DMA_CH0_CMD, cmd, start);
+}
+
+#ifdef SYNC_SER_DMA
+static irqreturn_t tr_interrupt(int irq, void *dev_id)
+{
+       unsigned long ireg = *R_IRQ_MASK2_RD;
+       struct etrax_dma_descr *descr;
+       unsigned int sentl;
+       int handled = 0;
+       int i;
+
+       for (i = 0; i < NUMBER_OF_PORTS; i++) {
+               struct sync_port *port = &ports[i];
+               if (!port->enabled  || !port->use_dma)
+                       continue;
+
+               /* IRQ active for the port? */
+               if (!(ireg & (1 << port->output_dma_bit)))
+                       continue;
+
+               handled = 1;
+
+               /* Clear IRQ */
+               *port->output_dma_clr_irq =
+                       IO_STATE(R_DMA_CH0_CLR_INTR, clr_eop, do) |
+                       IO_STATE(R_DMA_CH0_CLR_INTR, clr_descr, do);
+
+               descr = &port->out_descr;
+               if (!(descr->status & d_stop))
+                       sentl = descr->sw_len;
+               else
+                       /* Otherwise find amount of data sent here */
+                       sentl = descr->hw_len;
+
+               port->out_count -= sentl;
+               port->outp += sentl;
+               if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE)
+                       port->outp = port->out_buffer;
+               if (port->out_count) {
+                       int c = port->out_buffer + OUT_BUFFER_SIZE - port->outp;
+                       if (c > port->out_count)
+                               c = port->out_count;
+                       DEBUGTXINT(printk(KERN_DEBUG
+                               "tx_int DMAWRITE %i %i\n", sentl, c));
+                       start_dma(port, port->outp, c);
+               } else  {
+                       DEBUGTXINT(printk(KERN_DEBUG
+                               "tx_int DMA stop %i\n", sentl));
+                       port->tr_running = 0;
+               }
+               /* wake up the waiting process */
+               wake_up_interruptible(&port->out_wait_q);
+       }
+       return IRQ_RETVAL(handled);
+} /* tr_interrupt */
+
+static irqreturn_t rx_interrupt(int irq, void *dev_id)
+{
+       unsigned long ireg = *R_IRQ_MASK2_RD;
+       int i;
+       int handled = 0;
+
+       for (i = 0; i < NUMBER_OF_PORTS; i++) {
+               struct sync_port *port = &ports[i];
+
+               if (!port->enabled || !port->use_dma)
+                       continue;
+
+               if (!(ireg & (1 << port->input_dma_descr_bit)))
+                       continue;
+
+               /* Descriptor interrupt */
+               handled = 1;
+               while (*port->input_dma_descr !=
+                               virt_to_phys(port->next_rx_desc)) {
+                       if (port->writep + port->inbufchunk > port->flip +
+                                       port->in_buffer_size) {
+                               int first_size = port->flip +
+                                       port->in_buffer_size - port->writep;
+                               memcpy(port->writep,
+                                       phys_to_virt(port->next_rx_desc->buf),
+                                       first_size);
+                               memcpy(port->flip,
+                                       phys_to_virt(port->next_rx_desc->buf +
+                                       first_size),
+                                       port->inbufchunk - first_size);
+                               port->writep = port->flip +
+                                       port->inbufchunk - first_size;
+                       } else {
+                               memcpy(port->writep,
+                                       phys_to_virt(port->next_rx_desc->buf),
+                                       port->inbufchunk);
+                               port->writep += port->inbufchunk;
+                               if (port->writep >= port->flip
+                                               + port->in_buffer_size)
+                                       port->writep = port->flip;
+                       }
+                       if (port->writep == port->readp)
+                               port->full = 1;
+                       prepare_rx_descriptor(port->next_rx_desc);
+                       port->next_rx_desc->ctrl |= d_eol;
+                       port->prev_rx_desc->ctrl &= ~d_eol;
+                       port->prev_rx_desc = phys_to_virt((unsigned)
+                               port->next_rx_desc);
+                       port->next_rx_desc = phys_to_virt((unsigned)
+                               port->next_rx_desc->next);
+                       /* Wake up the waiting process */
+                       wake_up_interruptible(&port->in_wait_q);
+                       *port->input_dma_cmd = IO_STATE(R_DMA_CH1_CMD,
+                               cmd, restart);
+                       /* DMA has reached end of descriptor */
+                       *port->input_dma_clr_irq = IO_STATE(R_DMA_CH0_CLR_INTR,
+                               clr_descr, do);
+               }
+       }
+       return IRQ_RETVAL(handled);
+} /* rx_interrupt */
+#endif /* SYNC_SER_DMA */
+
+#ifdef SYNC_SER_MANUAL
+static irqreturn_t manual_interrupt(int irq, void *dev_id)
+{
+       int i;
+       int handled = 0;
+
+       for (i = 0; i < NUMBER_OF_PORTS; i++) {
+               struct sync_port *port = &ports[i];
+
+               if (!port->enabled || port->use_dma)
+                       continue;
+
+               /* Data received? */
+               if (*R_IRQ_MASK1_RD & (1 << port->data_avail_bit)) {
+                       handled = 1;
+                       /* Read data */
+                       switch (port->ctrl_data_shadow &
+                               IO_MASK(R_SYNC_SERIAL1_CTRL, wordsize)) {
+                       case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size8bit):
+                               *port->writep++ =
+                                       *(volatile char *)port->data_in;
+                               break;
+                       case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size12bit):
+                       {
+                               int data = *(unsigned short *)port->data_in;
+                               *port->writep = (data & 0x0ff0) >> 4;
+                               *(port->writep + 1) = data & 0x0f;
+                               port->writep += 2;
+                               break;
+                       }
+                       case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size16bit):
+                               *(unsigned short *)port->writep =
+                                       *(volatile unsigned short *)port->data_in;
+                               port->writep += 2;
+                               break;
+                       case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size24bit):
+                               *(unsigned int *)port->writep = *port->data_in;
+                               port->writep += 3;
+                               break;
+                       case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size32bit):
+                               *(unsigned int *)port->writep = *port->data_in;
+                               port->writep += 4;
+                               break;
+                       }
+
+                       /* Wrap? */
+                       if (port->writep >= port->flip + port->in_buffer_size)
+                               port->writep = port->flip;
+                       if (port->writep == port->readp) {
+                               /* Receive buffer overrun, discard oldest */
+                               port->readp++;
+                               /* Wrap? */
+                               if (port->readp >= port->flip +
+                                               port->in_buffer_size)
+                                       port->readp = port->flip;
+                       }
+                       if (sync_data_avail(port) >= port->inbufchunk) {
+                               /* Wake up application */
+                               wake_up_interruptible(&port->in_wait_q);
+                       }
+               }
+
+               /* Transmitter ready? */
+               if (*R_IRQ_MASK1_RD & (1 << port->transmitter_ready_bit)) {
+                       if (port->out_count > 0) {
+                               /* More data to send */
+                               send_word(port);
+                       } else {
+                               /* Transmission finished */
+                               /* Turn off IRQ */
+                               *R_IRQ_MASK1_CLR = 1 <<
+                                       port->transmitter_ready_bit;
+                               /* Wake up application */
+                               wake_up_interruptible(&port->out_wait_q);
+                       }
+               }
+       }
+       return IRQ_RETVAL(handled);
+}
+#endif
+
+module_init(etrax_sync_serial_init);
index 93679a48c791528625cd4e3949ef2e13ad4504e4..04d5eee2c90cbf26dcc1945ce2ecc3ff5da93545 100644 (file)
@@ -1,6 +1,6 @@
 /* Serialport functions for debugging
  *
- * Copyright (c) 2000 Axis Communications AB
+ * Copyright (c) 2000-2007 Axis Communications AB
  *
  * Authors:  Bjorn Wesen
  *
  *    enableDebugIRQ()
  *    init_etrax_debug()
  *
- * $Log: debugport.c,v $
- * Revision 1.27  2005/06/10 10:34:14  starvik
- * Real console support
- *
- * Revision 1.26  2005/06/07 07:06:07  starvik
- * Added LF->CR translation to make ETRAX customers happy.
- *
- * Revision 1.25  2005/03/08 08:56:47  mikaelam
- * Do only set index as port->index if port is defined, otherwise use the index from the command line
- *
- * Revision 1.24  2005/01/19 10:26:33  mikaelam
- * Return the cris serial driver in console device driver callback function
- *
- * Revision 1.23  2005/01/14 10:12:17  starvik
- * KGDB on separate port.
- * Console fixes from 2.4.
- *
- * Revision 1.22  2005/01/11 16:06:13  starvik
- * typo
- *
- * Revision 1.21  2005/01/11 13:49:14  starvik
- * Added raw_printk to be used where we don't trust the console.
- *
- * Revision 1.20  2004/12/27 11:18:32  starvik
- * Merge of Linux 2.6.10 (not functional yet).
- *
- * Revision 1.19  2004/10/21 07:26:16  starvik
- * Made it possible to specify console settings on kernel command line.
- *
- * Revision 1.18  2004/10/19 13:07:37  starvik
- * Merge of Linux 2.6.9
- *
- * Revision 1.17  2004/09/29 10:33:46  starvik
- * Resolved a dealock when printing debug from kernel.
- *
- * Revision 1.16  2004/08/24 06:12:19  starvik
- * Whitespace cleanup
- *
- * Revision 1.15  2004/08/16 12:37:19  starvik
- * Merge of Linux 2.6.8
- *
- * Revision 1.14  2004/05/17 13:11:29  starvik
- * Disable DMA until real serial driver is up
- *
- * Revision 1.13  2004/05/14 07:58:01  starvik
- * Merge of changes from 2.4
- *
- * Revision 1.12  2003/09/11 07:29:49  starvik
- * Merge of Linux 2.6.0-test5
- *
- * Revision 1.11  2003/07/07 09:53:36  starvik
- * Revert all the 2.5.74 merge changes to make the console work again
- *
- * Revision 1.9  2003/02/17 17:07:23  starvik
- * Solved the problem with corrupted debug output (from Linux 2.4)
- *   * Wait until DMA, FIFO and pipe is empty before and after transmissions
- *   * Buffer data until a FIFO flush can be triggered.
- *
- * Revision 1.8  2003/01/22 06:48:36  starvik
- * Fixed warnings issued by GCC 3.2.1
- *
- * Revision 1.7  2002/12/12 08:26:32  starvik
- * Don't use C-comments inside CVS comments
- *
- * Revision 1.6  2002/12/11 15:42:02  starvik
- * Extracted v10 (ETRAX 100LX) specific stuff from arch/cris/kernel/
- *
- * Revision 1.5  2002/11/20 06:58:03  starvik
- * Compiles with kgdb
- *
- * Revision 1.4  2002/11/19 14:35:24  starvik
- * Changes from linux 2.4
- * Changed struct initializer syntax to the currently preferred notation
- *
- * Revision 1.3  2002/11/06 09:47:03  starvik
- * Modified for new interrupt macros
- *
- * Revision 1.2  2002/01/21 15:21:50  bjornw
- * Update for kdev_t changes
- *
- * Revision 1.6  2001/04/17 13:58:39  orjanf
- * * Renamed CONFIG_KGDB to CONFIG_ETRAX_KGDB.
- *
- * Revision 1.5  2001/03/26 14:22:05  bjornw
- * Namechange of some config options
- *
- * Revision 1.4  2000/10/06 12:37:26  bjornw
- * Use physical addresses when talking to DMA
- *
- *
  */
 
 #include <linux/console.h>
 #include <asm/arch/svinto.h>
 #include <asm/io.h>             /* Get SIMCOUT. */
 
+extern void reset_watchdog(void);
+
 struct dbg_port
 {
   unsigned int index;
@@ -188,7 +100,9 @@ struct dbg_port ports[]=
   }
 };
 
+#ifdef CONFIG_ETRAX_SERIAL
 extern struct tty_driver *serial_driver;
+#endif
 
 struct dbg_port* port =
 #if defined(CONFIG_ETRAX_DEBUG_PORT0)
@@ -368,11 +282,12 @@ console_write_direct(struct console *co, const char *buf, unsigned int len)
 {
        int i;
        unsigned long flags;
-       local_irq_save(flags);
 
         if (!port)
                return;
 
+       local_irq_save(flags);
+
        /* Send data */
        for (i = 0; i < len; i++) {
                /* LF -> CRLF */
@@ -386,26 +301,16 @@ console_write_direct(struct console *co, const char *buf, unsigned int len)
                        ;
                *port->write = buf[i];
        }
-       local_irq_restore(flags);
-}
 
-int raw_printk(const char *fmt, ...)
-{
-       static char buf[1024];
-       int printed_len;
-       static int first = 1;
-       if (first) {
-               /* Force reinitialization of the port to get manual mode. */
-               port->started = 0;
-               start_port(port);
-               first = 0;
-       }
-       va_list args;
-       va_start(args, fmt);
-       printed_len = vsnprintf(buf, sizeof(buf), fmt, args);
-       va_end(args);
-       console_write_direct(NULL, buf, strlen(buf));
-       return printed_len;
+       /*
+        * Feed the watchdog, otherwise it will reset the chip during boot.
+        * The time to send an ordinary boot message line (10-90 chars)
+        * varies between 1-8ms at 115200. What makes up for the additional
+        * 90ms that allows the watchdog to bite?
+       */
+       reset_watchdog();
+
+       local_irq_restore(flags);
 }
 
 static void
@@ -500,6 +405,7 @@ console_setup(struct console *co, char *options)
        return 0;
 }
 
+
 /* This is a dummy serial device that throws away anything written to it.
  * This is used when no debug output is wanted.
  */
@@ -555,7 +461,13 @@ etrax_console_device(struct console* co, int *index)
 {
        if (port)
                *index = port->index;
+       else
+               *index = 0;
+#ifdef CONFIG_ETRAX_SERIAL
         return port ? serial_driver : &dummy_driver;
+#else
+       return &dummy_driver;
+#endif
 }
 
 static struct console sercons = {
index e9a0311b141da4997ec77a3301eb23b6d302d1b4..eb1fa0d2b49f92f89c80030c6d81552eb02d3a27 100644 (file)
@@ -1,6 +1,5 @@
 /* Wrapper for DMA channel allocator that updates DMA client muxing.
- * Copyright 2004, Axis Communications AB
- * $Id: dma.c,v 1.1 2004/12/13 12:21:51 starvik Exp $
+ * Copyright 2004-2007, Axis Communications AB
  */
 
 #include <linux/kernel.h>
index d1361dc119e24d76b3042bd7b70fcb91bdde205a..3a65f322ae078061d5f63488dab7bd19e4eec4d4 100644 (file)
@@ -1,252 +1,9 @@
-/* $Id: entry.S,v 1.28 2005/06/20 05:06:30 starvik Exp $
- *
+/*
  *  linux/arch/cris/entry.S
  *
  *  Copyright (C) 2000, 2001, 2002 Axis Communications AB
  *
  *  Authors:   Bjorn Wesen (bjornw@axis.com)
- *
- *  $Log: entry.S,v $
- *  Revision 1.28  2005/06/20 05:06:30  starvik
- *  Remove unnecessary diff to kernel.org tree
- *
- *  Revision 1.27  2005/03/04 08:16:16  starvik
- *  Merge of Linux 2.6.11.
- *
- *  Revision 1.26  2005/01/11 13:49:47  starvik
- *  Added NMI handler.
- *
- *  Revision 1.25  2004/12/27 11:18:32  starvik
- *  Merge of Linux 2.6.10 (not functional yet).
- *
- *  Revision 1.24  2004/12/22 10:41:23  starvik
- *  Updates to make v10 compile with the latest SMP aware generic code (even
- *  though v10 will never have SMP).
- *
- *  Revision 1.23  2004/10/19 13:07:37  starvik
- *  Merge of Linux 2.6.9
- *
- *  Revision 1.22  2004/06/21 10:29:55  starvik
- *  Merge of Linux 2.6.7
- *
- *  Revision 1.21  2004/06/09 05:30:27  starvik
- *  Clean up multiple interrupt handling.
- *    Prevent interrupts from interrupting each other.
- *    Handle all active interrupts.
- *
- *  Revision 1.20  2004/06/08 08:55:32  starvik
- *  Removed unused code
- *
- *  Revision 1.19  2004/06/04 11:56:15  starvik
- *  Implemented page table lookup for refills in assembler for improved performance.
- *
- *  Revision 1.18  2004/05/11 12:28:25  starvik
- *  Merge of Linux 2.6.6
- *
- *  Revision 1.17  2003/09/11 07:29:49  starvik
- *  Merge of Linux 2.6.0-test5
- *
- *  Revision 1.16  2003/07/04 08:27:41  starvik
- *  Merge of Linux 2.5.74
- *
- *  Revision 1.15  2003/04/09 07:32:55  starvik
- *  resume should return task_struct, not thread_info
- *
- *  Revision 1.14  2003/04/09 05:20:44  starvik
- *  Merge of Linux 2.5.67
- *
- *  Revision 1.13  2002/12/11 15:42:02  starvik
- *  Extracted v10 (ETRAX 100LX) specific stuff from arch/cris/kernel/*.c
- *
- *  Revision 1.12  2002/12/10 09:00:10  starvik
- *  Merge of Linux 2.5.51
- *
- *  Revision 1.11  2002/12/05 07:53:10  starvik
- *  Corrected constants used with btstq
- *
- *  Revision 1.10  2002/11/27 08:45:10  starvik
- *  pid is in task_struct, not thread_info
- *
- *  Revision 1.9  2002/11/26 09:52:05  starvik
- *  Added preemptive kernel scheduling (if CONFIG_PREEMPT)
- *
- *  Revision 1.8  2002/11/20 11:56:11  starvik
- *  Merge of Linux 2.5.48
- *
- *  Revision 1.7  2002/11/18 13:02:42  starvik
- *  Added fourth parameter to do_notify_resume
- *  Minor cleanup
- *
- *  Revision 1.6  2002/11/11 10:37:50  starvik
- *  Use new asm-offset defines
- *  Modified for new location of current->work etc
- *  Removed SYMBOL_NAME from syscalls
- *  Added some new syscalls
- *
- *  Revision 1.5  2002/11/05 06:45:11  starvik
- *  Merge of Linux 2.5.45
- *
- *  Revision 1.4  2002/02/05 15:41:31  bjornw
- *  Rewritten to conform better to current 2.5 code (similar to arch/i386)
- *
- *  Revision 1.3  2002/01/21 15:22:20  bjornw
- *  NICE_DOGGY fix from 2.4 arch/cris
- *
- *  Revision 1.37  2001/12/07 17:03:55  bjornw
- *  Call a c-hook called watchdog_bite_hook instead of show_registers directly
- *
- *  Revision 1.36  2001/11/22 13:36:36  bjornw
- *  * In ret_from_intr, check regs->dccr for usermode reentrance instead of
- *    DCCR explicitly (because the latter might not reflect current reality)
- *  * In mmu_bus_fault, set $r9 _after_ calling the C-code instead of before
- *    since $r9 is call-clobbered and is potentially needed afterwards
- *
- *  Revision 1.35  2001/10/30 17:10:15  bjornw
- *  Add some syscalls
- *
- *  Revision 1.34  2001/10/01 14:45:03  bjornw
- *  Removed underscores and added register prefixes
- *
- *  Revision 1.33  2001/08/21 13:48:01  jonashg
- *  Added fix by HP to avoid oops when doing a hard_reset_now.
- *
- *  Revision 1.32  2001/08/14 04:32:02  hp
- *  In _resume, add comment why R9 is saved; don't sound like it's call-saved.
- *
- *  Revision 1.31  2001/07/25 16:07:42  bjornw
- *  softirq_active/mask -> softirq_pending only
- *
- *  Revision 1.30  2001/07/05 01:03:32  hp
- *  - include asm/errno.h to get ENOSYS.
- *  - Use ENOSYS, not local constant LENOSYS; tweak comments.
- *  - Explain why .include, not #include is used.
- *  - Make oops-register-dump if watchdog bits and it's not expected.
- *  - Don't jsr, use jump _hard_reset_now, and skip spurious nop.
- *  - Use correct section attribute for section .rodata.
- *  - Adjust sys_ni_syscall fill number.
- *
- *  Revision 1.29  2001/06/25 14:07:00  hp
- *     Fix review comment.
- *     * head.S: Use IO_STATE, IO_FIELD and IO_MASK constructs instead of
- *     magic numbers.  Add comment that -traditional must not be used.
- *     * entry.S (SYMBOL_NAME): Change redefinition to use ## concatenation.
- *     Correct and update comment.
- *     * Makefile (.S.o): Don't use -traditional.  Add comment why the
- *     toplevel rule can't be used (now that there's a reason).
- *
- *  Revision 1.28  2001/06/21 02:00:40  hp
- *     * entry.S: Include asm/unistd.h.
- *     (_sys_call_table): Use section .rodata, not .data.
- *     (_kernel_thread): Move from...
- *     * process.c: ... here.
- *     * entryoffsets.c (VAL): Break out from...
- *     (OF): Use VAL.
- *     (LCLONE_VM): New asmified value from CLONE_VM.
- *
- *  Revision 1.27  2001/05/29 11:25:27  markusl
- *  In case of "spurious_interrupt", do hard_reset instead of hanging system in a loop...
- *
- *  Revision 1.26  2001/05/15 15:46:03  bjornw
- *  Include config.h now that we use some CONFIG_ options
- *
- *  Revision 1.25  2001/05/15 05:38:47  hp
- *  Tweaked code in _ret_from_sys_call
- *
- *  Revision 1.24  2001/05/15 05:27:49  hp
- *  Save r9 in r1 over function call rather than on stack.
- *
- *  Revision 1.23  2001/05/15 05:10:00  hp
- *  Generate entry.S structure offsets from C
- *
- *  Revision 1.22  2001/04/17 13:58:39  orjanf
- *  * Renamed CONFIG_KGDB to CONFIG_ETRAX_KGDB.
- *
- *  Revision 1.21  2001/04/17 11:33:29  orjanf
- *  Updated according to review:
- *  * Included asm/sv_addr_ag.h to get macro for internal register.
- *  * Corrected comment regarding system call argument passing.
- *  * Removed comment about instruction being in a delay slot.
- *  * Added comment about SYMBOL_NAME macro.
- *
- *  Revision 1.20  2001/04/12 08:51:07  hp
- *  - Add entry for sys_fcntl64.  In fact copy last piece from i386 including ...
- *  - .rept to fill table to safe state with sys_ni_syscall.
- *
- *  Revision 1.19  2001/04/04 09:43:32  orjanf
- *  * Moved do_sigtrap from traps.c to entry.S.
- *  * LTASK_PID need not be global anymore.
- *
- *  Revision 1.18  2001/03/26 09:25:02  markusl
- *  Updated after review, should now handle USB interrupts correctly.
- *
- *  Revision 1.17  2001/03/21 16:12:55  bjornw
- *  * Always make room for the cpu status record in the frame, in order to
- *    use the same framelength and layout for both mmu busfaults and normal
- *    irqs. No need to check for the explicit CRIS_FRAME_FIXUP type anymore.
- *  * Fixed bug with using addq for popping the stack in the epilogue - it
- *    destroyed the flag register. Use instructions that don't affect the
- *    flag register instead.
- *  * Removed write to R_PORT_PA_DATA during spurious_interrupt
- *
- *  Revision 1.16  2001/03/20 19:43:02  bjornw
- *  * Get rid of esp0 setting
- *  * Give a 7th argument to a systemcall - the stackframe
- *
- *  Revision 1.15  2001/03/05 13:14:30  bjornw
- *  Spelling fix
- *
- *  Revision 1.14  2001/02/23 08:36:36  perf
- *  New ABI; syscallnr=r9, arg5=mof, arg6=srp.
- *  Corrected tracesys call check.
- *
- *  Revision 1.13  2001/02/15 08:40:55  perf
- *  H-P by way of perf;
- *  - (_system_call): Don't read system call function address into r1.
- *  - (RBFExit): There is no such thing as a null pop.  Adjust sp by addq.
- *  - (_system_call): Don't use r10 and don't save and restore it.
- *  - (THREAD_ESP0): New constant.
- *  - (_system_call): Inline set_esp0.
- *
- *  Revision 1.12  2001/01/31 17:56:25  orjanf
- *  Added definition of LTASK_PID and made it global.
- *
- *  Revision 1.11  2001/01/10 21:13:29  bjornw
- *  SYMBOL_NAME is defined incorrectly for the compiler options we currently use
- *
- *  Revision 1.10  2000/12/18 23:47:56  bjornw
- *  * Added syscall trace support (ptrace), completely untested of course
- *  * Removed redundant check for NULL entries in syscall_table
- *
- *  Revision 1.9  2000/11/21 16:40:51  bjornw
- *  * New frame type used when an SBFS frame needs to be popped without
- *    actually restarting the instruction
- *  * Enable interrupts in signal_return (they did so in x86, I hope it's a good
- *    idea)
- *
- *  Revision 1.8  2000/11/17 16:53:35  bjornw
- *  Added detection of frame-type in Rexit, so that mmu_bus_fault can
- *  use ret_from_intr in the return-path to check for signals (like SEGV)
- *  and other foul things that might have occurred during the fault.
- *
- *  Revision 1.7  2000/10/06 15:04:28  bjornw
- *  Include mof in register savings
- *
- *  Revision 1.6  2000/09/12 16:02:44  bjornw
- *  Linux-2.4.0-test7 derived updates
- *
- *  Revision 1.5  2000/08/17 15:35:15  bjornw
- *  2.4.0-test6 changed local_irq_count and friends API
- *
- *  Revision 1.4  2000/08/02 13:59:30  bjornw
- *  Removed olduname and uname from the syscall list
- *
- *  Revision 1.3  2000/07/31 13:32:58  bjornw
- *  * Export ret_from_intr
- *  * _resume updated (prev/last tjohejsan)
- *  * timer_interrupt obsolete
- *  * SIGSEGV detection in mmu_bus_fault temporarily disabled
- *
- *
  */
 
 /*
@@ -1167,9 +924,11 @@ sys_call_table:
        .long sys_epoll_pwait
        .long sys_utimensat             /* 320 */
        .long sys_signalfd
-       .long sys_ni_syscall
+       .long sys_timerfd_create
        .long sys_eventfd
        .long sys_fallocate
+       .long sys_timerfd_settime       /* 325 */
+       .long sys_timerfd_gettime
 
         /*
          * NOTE!! This doesn't have to be exact - we just have
index c1a3a2100ee71e1094a8df045bec8f5948ef5023..31ff35cff02c8940322d33bca6c0757b66d0a6b6 100644 (file)
 
 #define DEBUG_LOG_INCLUDED
 #define FAST_TIMER_LOG
-//#define FAST_TIMER_TEST
+/* #define FAST_TIMER_TEST */
 
 #define FAST_TIMER_SANITY_CHECKS
 
 #ifdef FAST_TIMER_SANITY_CHECKS
-#define SANITYCHECK(x) x
 static int sanity_failed;
-#else
-#define SANITYCHECK(x)
 #endif
 
 #define D1(x)
@@ -226,23 +223,19 @@ void start_one_shot_timer(struct fast_timer *t,
   do_gettimeofday_fast(&t->tv_set);
   tmp = fast_timer_list;
 
-  SANITYCHECK({ /* Check so this is not in the list already... */
-    while (tmp != NULL)
-    {
-      if (tmp == t)
-      {
-        printk(KERN_WARNING
-               "timer name: %s data: 0x%08lX already in list!\n", name, data);
-        sanity_failed++;
-                               goto done;
-      }
-      else
-      {
-        tmp = tmp->next;
-      }
-    }
-    tmp = fast_timer_list;
-  });
+#ifdef FAST_TIMER_SANITY_CHECKS
+       /* Check so this is not in the list already... */
+       while (tmp != NULL) {
+               if (tmp == t) {
+                       printk(KERN_WARNING "timer name: %s data: "
+                               "0x%08lX already in list!\n", name, data);
+                       sanity_failed++;
+                       goto done;
+               } else
+                       tmp = tmp->next;
+       }
+       tmp = fast_timer_list;
+#endif
 
   t->delay_us = delay_us;
   t->function = function;
index d946d8b8d2773eb44c8b7f530f0d74a63482863e..96344afc4ebcb9a084037afccc89c824fdda00d4 100644 (file)
-/* $Id: head.S,v 1.10 2005/06/20 05:12:54 starvik Exp $
- * 
+/*
  * Head of the kernel - alter with care
  *
  * Copyright (C) 2000, 2001 Axis Communications AB
  *
  * Authors:    Bjorn Wesen (bjornw@axis.com)
  * 
- * $Log: head.S,v $
- * Revision 1.10  2005/06/20 05:12:54  starvik
- * Remove unnecessary diff to kernel.org tree
- *
- * Revision 1.9  2004/12/13 12:21:51  starvik
- * Added I/O and DMA allocators from Linux 2.4
- *
- * Revision 1.8  2004/11/22 11:41:14  starvik
- * Kernel command line may be supplied to kernel. Not used by Axis but may
- * be used by customers.
- *
- * Revision 1.7  2004/05/14 07:58:01  starvik
- * Merge of changes from 2.4
- *
- * Revision 1.6  2003/04/28 05:31:46  starvik
- * Added section attributes
- *
- * Revision 1.5  2002/12/11 15:42:02  starvik
- * Extracted v10 (ETRAX 100LX) specific stuff from arch/cris/kernel/*.c
- *
- * Revision 1.4  2002/11/07 09:00:44  starvik
- * Names changed for init sections
- * init_task_union -> init_thread_union
- *
- * Revision 1.3  2002/02/05 15:38:23  bjornw
- * Oops.. non-CRAMFS_MAGIC should jump over the copying, not into it...
- *
- * Revision 1.2  2001/12/18 13:35:19  bjornw
- * Applied the 2.4.13->2.4.16 CRIS patch to 2.5.1 (is a copy of 2.4.15).
- *
- * Revision 1.43  2001/11/08 15:09:43  starvik
- * Only start MII clock if Ethernet is configured
- *
- * Revision 1.42  2001/11/08 14:37:34  starvik
- * Start MII clock early to make sure that it is running at tranceiver reset
- *
- * Revision 1.41  2001/10/29 14:55:58  pkj
- * Corrected pa$r0 to par0.
- *
- * Revision 1.40  2001/10/03 14:59:57  pkj
- * Added support for resetting the Bluetooth hardware.
- *
- * Revision 1.39  2001/10/01 14:45:03  bjornw
- * Removed underscores and added register prefixes
- *
- * Revision 1.38  2001/09/21 07:14:11  jonashg
- * Made root filesystem (cramfs) use mtdblock driver when booting from flash.
- *
- * Revision 1.37  2001/09/11 13:44:29  orjanf
- * Decouple usage of serial ports for debug and kgdb.
- *
- * Revision 1.36  2001/06/29 12:39:31  pkj
- * Added support for mirroring the first flash to just below the
- * second one, to make them look consecutive to cramfs.
- *
- * Revision 1.35  2001/06/25 14:07:00  hp
- *     Fix review comment.
- *     * head.S: Use IO_STATE, IO_FIELD and IO_MASK constructs instead of
- *     magic numbers.  Add comment that -traditional must not be used.
- *     * entry.S (SYMBOL_NAME): Change redefinition to use ## concatenation.
- *     Correct and update comment.
- *     * Makefile (.S.o): Don't use -traditional.  Add comment why the
- *     toplevel rule can't be used (now that there's a reason).
- *
- * Revision 1.34  2001/05/15 07:08:14  hp
- * Tweak "notice" to reflect that both r8 r9 are used
- *
- * Revision 1.33  2001/05/15 06:40:05  hp
- * Put bulk of code in .text.init, data in .data.init
- *
- * Revision 1.32  2001/05/15 06:18:56  hp
- * Execute review comment: s/bcc/bhs/g; s/bcs/blo/g
- *
- * Revision 1.31  2001/05/15 06:08:40  hp
- * Add sentence about autodetecting the bit31-MMU-bug
- *
- * Revision 1.30  2001/05/15 06:00:05  hp
- * Update comment: LOW_MAP is not forced on xsim anymore.
- *
- * Revision 1.29  2001/04/18 12:51:59  orjanf
- * * Reverted review change regarding the use of bcs/bcc.
- * * Removed non-working LED-clearing code.
- *
- * Revision 1.28  2001/04/17 13:58:39  orjanf
- * * Renamed CONFIG_KGDB to CONFIG_ETRAX_KGDB.
- *
- * Revision 1.27  2001/04/17 11:42:35  orjanf
- * Changed according to review:
- * * Added comment explaining memory map bug.
- * * Changed bcs and bcc to blo and bhs, respectively.
- * * Removed mentioning of Stallone and Olga boards.
- *
- * Revision 1.26  2001/04/06 12:31:07  jonashg
- * Check for cramfs in flash before RAM instead of RAM before flash.
- *
- * Revision 1.25  2001/04/04 06:23:53  starvik
- * Initialize DRAM if not already initialized
- *
- * Revision 1.24  2001/04/03 11:12:00  starvik
- * Removed dram init (done by rescue or etrax100boot
- * Corrected include
- *
- * Revision 1.23  2001/04/03 09:53:03  starvik
- * Include hw_settings.S
- *
- * Revision 1.22  2001/03/26 14:23:26  bjornw
- * Namechange of some config options
- *
- * Revision 1.21  2001/03/08 12:14:41  bjornw
- * * Config name for ETRAX IDE was renamed
- * * Removed G27 auto-setting when JULIETTE is chosen (need to make this
- *   a new config option later)
- *
- * Revision 1.20  2001/02/23 12:47:56  bjornw
- * MMU regs during LOW_MAP updated to reflect a newer reality
- *
- * Revision 1.19  2001/02/19 11:12:07  bjornw
- * Changed comment header format
- *
- * Revision 1.18  2001/02/15 07:25:38  starvik
- * Added support for synchronous serial ports
- *
- * Revision 1.17  2001/02/08 15:53:13  starvik
- * Last commit removed some important ifdefs
- *
- * Revision 1.16  2001/02/08 15:20:38  starvik
- * Include dram_init.S as inline
- *
- * Revision 1.15  2001/01/29 18:12:01  bjornw
- * Corrected some comments
- *
- * Revision 1.14  2001/01/29 13:11:29  starvik
- * Include dram_init.S (with DRAM/SDRAM initialization)
- *
- * Revision 1.13  2001/01/23 14:54:57  markusl
- * Updated for USB
- * i.e. added r_gen_config settings
- *
- * Revision 1.12  2001/01/19 16:16:29  perf
- * Added temporary mapping of 0x0c->0x0c to avoid flash loading confusion.
- * Renamed serial options from ETRAX100 to ETRAX.
- *
- * Revision 1.11  2001/01/16 16:31:38  bjornw
- * * Changed name and semantics of running_from_flash to romfs_in_flash,
- *   set by head.S to indicate to setup.c whether there is a cramfs image
- *   after the kernels BSS or not. Should work for all three boot-cases
- *   (DRAM with cramfs in DRAM, DRAM with cramfs in flash (compressed boot),
- *    and flash with cramfs in flash)
- *
- * Revision 1.10  2001/01/16 14:12:21  bjornw
- * * Check for cramfs start passed in r9 from the decompressor, if all other
- *   cramfs options fail (if we boot from DRAM but don't find a cramfs image
- *   after the kernel in DRAM, it is probably still in the flash)
- * * Check magic in cramfs detection when booting from flash directly
- *
- * Revision 1.9  2001/01/15 17:17:02  bjornw
- * * Corrected the code that detects the cramfs lengths
- * * Added a comment saying that the above does not work due to other
- *   reasons..
- *
- * Revision 1.8  2001/01/15 16:27:51  jonashg
- * Made boot after flashing work.
- * * end destination is __vmlinux_end in RAM.
- * * _romfs_start moved because of virtual memory.
- *
- * Revision 1.7  2000/11/21 13:55:29  bjornw
- * Use CONFIG_CRIS_LOW_MAP for the low VM map instead of explicit CPU type
- *
- * Revision 1.6  2000/10/06 12:36:55  bjornw
- * Forgot swapper_pg_dir when changing memory map..
- *
- * Revision 1.5  2000/10/04 16:49:30  bjornw
- * * Fixed memory mapping in LX
- * * Check for cramfs instead of romfs
- *
  */
        
 #define ASSEMBLER_MACROS_ONLY
@@ -595,11 +419,17 @@ no_command_line:
 
        moveq   0,$r0
 
+       ;; Select or disable serial port 2
+#ifdef CONFIG_ETRAX_SERIAL_PORT2
+       or.d      IO_STATE (R_GEN_CONFIG, ser2, select),$r0
+#else
+       or.d      IO_STATE (R_GEN_CONFIG, ser2, disable),$r0
+#endif
+
        ;; Init interfaces (disable them).
        or.d      IO_STATE (R_GEN_CONFIG, scsi0, disable) \
                | IO_STATE (R_GEN_CONFIG, ata, disable) \
                | IO_STATE (R_GEN_CONFIG, par0, disable) \
-               | IO_STATE (R_GEN_CONFIG, ser2, disable) \
                | IO_STATE (R_GEN_CONFIG, mio, disable) \
                | IO_STATE (R_GEN_CONFIG, scsi1, disable) \
                | IO_STATE (R_GEN_CONFIG, scsi0w, disable) \
@@ -801,6 +631,41 @@ no_command_line:
                | IO_STATE (R_SERIAL1_TR_CTRL, tr_bitnr, tr_8bit),$r0
        move.b  $r0,[R_SERIAL1_TR_CTRL]
 
+#ifdef CONFIG_ETRAX_SERIAL_PORT2
+       ;; setup the serial port 2 at 115200 baud for debug purposes
+
+       moveq     IO_STATE (R_SERIAL2_XOFF, tx_stop, enable)            \
+               | IO_STATE (R_SERIAL2_XOFF, auto_xoff, disable)         \
+               | IO_FIELD (R_SERIAL2_XOFF, xoff_char, 0),$r0
+       move.d  $r0,[R_SERIAL2_XOFF]
+
+       ; 115.2kbaud for both transmit and receive
+       move.b    IO_STATE (R_SERIAL2_BAUD, tr_baud, c115k2Hz)          \
+               | IO_STATE (R_SERIAL2_BAUD, rec_baud, c115k2Hz),$r0
+       move.b  $r0,[R_SERIAL2_BAUD]
+
+       ; Set up and enable the serial2 receiver.
+       move.b    IO_STATE (R_SERIAL2_REC_CTRL, dma_err, stop)          \
+               | IO_STATE (R_SERIAL2_REC_CTRL, rec_enable, enable)     \
+               | IO_STATE (R_SERIAL2_REC_CTRL, rts_, active)           \
+               | IO_STATE (R_SERIAL2_REC_CTRL, sampling, middle)       \
+               | IO_STATE (R_SERIAL2_REC_CTRL, rec_stick_par, normal)  \
+               | IO_STATE (R_SERIAL2_REC_CTRL, rec_par, even)          \
+               | IO_STATE (R_SERIAL2_REC_CTRL, rec_par_en, disable)    \
+               | IO_STATE (R_SERIAL2_REC_CTRL, rec_bitnr, rec_8bit),$r0
+       move.b  $r0,[R_SERIAL2_REC_CTRL]
+
+       ; Set up and enable the serial2 transmitter.
+       move.b    IO_FIELD (R_SERIAL2_TR_CTRL, txd, 0)                  \
+               | IO_STATE (R_SERIAL2_TR_CTRL, tr_enable, enable)       \
+               | IO_STATE (R_SERIAL2_TR_CTRL, auto_cts, disabled)      \
+               | IO_STATE (R_SERIAL2_TR_CTRL, stop_bits, one_bit)      \
+               | IO_STATE (R_SERIAL2_TR_CTRL, tr_stick_par, normal)    \
+               | IO_STATE (R_SERIAL2_TR_CTRL, tr_par, even)            \
+               | IO_STATE (R_SERIAL2_TR_CTRL, tr_par_en, disable)      \
+               | IO_STATE (R_SERIAL2_TR_CTRL, tr_bitnr, tr_8bit),$r0
+       move.b  $r0,[R_SERIAL2_TR_CTRL]
+#endif
        
 #ifdef CONFIG_ETRAX_SERIAL_PORT3       
        ;; setup the serial port 3 at 115200 baud for debug purposes
index f3b327d4ed9cf912040a56310b69cad7063f7fd8..add98e0941b541970e3f1d4cb01cb00902a74aed 100644 (file)
@@ -1,10 +1,9 @@
 /* IO interface mux allocator for ETRAX100LX.
- * Copyright 2004, Axis Communications AB
- * $Id: io_interface_mux.c,v 1.2 2004/12/21 12:08:38 starvik Exp $
+ * Copyright 2004-2007, Axis Communications AB
  */
 
 
-/* C.f. ETRAX100LX Designer's Reference 20.9 */
+/* C.f. ETRAX100LX Designer's Reference chapter 19.9 */
 
 #include <linux/kernel.h>
 #include <linux/slab.h>
@@ -45,17 +44,39 @@ struct watcher
 struct if_group
 {
        enum io_if_group        group;
-       unsigned char           used;
-       enum cris_io_interface  owner;
+       /* name - the name of the group 'A' to 'F' */
+       char                   *name;
+       /* used - a bit mask of all pins in the group in the order listed
+        * in the tables in 19.9.1 to 19.9.6.  Note that no
+        * distinction is made between in, out and in/out pins. */
+       unsigned int            used;
 };
 
 
 struct interface
 {
        enum cris_io_interface   ioif;
+       /* name - the name of the interface */
+       char                    *name;
+       /* groups - OR'ed together io_if_group flags describing what pin groups
+        * the interface uses pins in. */
        unsigned char            groups;
+       /* used - set when the interface is allocated. */
        unsigned char            used;
        char                    *owner;
+       /* group_a through group_f - bit masks describing what pins in the
+        * pin groups the interface uses. */
+       unsigned int             group_a;
+       unsigned int             group_b;
+       unsigned int             group_c;
+       unsigned int             group_d;
+       unsigned int             group_e;
+       unsigned int             group_f;
+
+       /* gpio_g_in, gpio_g_out, gpio_b - bit masks telling what pins in the
+        * GPIO ports the interface uses.  This could be reconstucted using
+        * the group_X masks and a table of what pins the GPIO ports use,
+        * but that would be messy. */
        unsigned int             gpio_g_in;
        unsigned int             gpio_g_out;
        unsigned char            gpio_b;
@@ -64,26 +85,32 @@ struct interface
 static struct if_group if_groups[6] = {
        {
                .group = group_a,
+               .name = "A",
                .used = 0,
        },
        {
                .group = group_b,
+               .name = "B",
                .used = 0,
        },
        {
                .group = group_c,
+               .name = "C",
                .used = 0,
        },
        {
                .group = group_d,
+               .name = "D",
                .used = 0,
        },
        {
                .group = group_e,
+               .name = "E",
                .used = 0,
        },
        {
                .group = group_f,
+               .name = "F",
                .used = 0,
        }
 };
@@ -94,14 +121,32 @@ static struct interface interfaces[] = {
        /* Begin Non-multiplexed interfaces */
        {
                .ioif = if_eth,
+               .name = "ethernet",
                .groups = 0,
+
+               .group_a = 0,
+               .group_b = 0,
+               .group_c = 0,
+               .group_d = 0,
+               .group_e = 0,
+               .group_f = 0,
+
                .gpio_g_in = 0,
                .gpio_g_out = 0,
                .gpio_b = 0
        },
        {
                .ioif = if_serial_0,
+               .name = "serial_0",
                .groups = 0,
+
+               .group_a = 0,
+               .group_b = 0,
+               .group_c = 0,
+               .group_d = 0,
+               .group_e = 0,
+               .group_f = 0,
+
                .gpio_g_in = 0,
                .gpio_g_out = 0,
                .gpio_b = 0
@@ -109,172 +154,385 @@ static struct interface interfaces[] = {
        /* End Non-multiplexed interfaces */
        {
                .ioif = if_serial_1,
+               .name = "serial_1",
                .groups = group_e,
+
+               .group_a = 0,
+               .group_b = 0,
+               .group_c = 0,
+               .group_d = 0,
+               .group_e = 0x0f,
+               .group_f = 0,
+
                .gpio_g_in =  0x00000000,
                .gpio_g_out = 0x00000000,
                .gpio_b = 0x00
        },
        {
                .ioif = if_serial_2,
+               .name = "serial_2",
                .groups = group_b,
+
+               .group_a = 0,
+               .group_b = 0x0f,
+               .group_c = 0,
+               .group_d = 0,
+               .group_e = 0,
+               .group_f = 0,
+
                .gpio_g_in =  0x000000c0,
                .gpio_g_out = 0x000000c0,
                .gpio_b = 0x00
        },
        {
                .ioif = if_serial_3,
+               .name = "serial_3",
                .groups = group_c,
+
+               .group_a = 0,
+               .group_b = 0,
+               .group_c = 0x0f,
+               .group_d = 0,
+               .group_e = 0,
+               .group_f = 0,
+
                .gpio_g_in =  0xc0000000,
                .gpio_g_out = 0xc0000000,
                .gpio_b = 0x00
        },
        {
                .ioif = if_sync_serial_1,
-               .groups = group_e | group_f, /* if_sync_serial_1 and if_sync_serial_3
-                                              can be used simultaneously */
+               .name = "sync_serial_1",
+               .groups = group_e | group_f,
+
+               .group_a = 0,
+               .group_b = 0,
+               .group_c = 0,
+               .group_d = 0,
+               .group_e = 0x0f,
+               .group_f = 0x10,
+
                .gpio_g_in =  0x00000000,
                .gpio_g_out = 0x00000000,
                .gpio_b = 0x10
        },
        {
                .ioif = if_sync_serial_3,
+               .name = "sync_serial_3",
                .groups = group_c | group_f,
+
+               .group_a = 0,
+               .group_b = 0,
+               .group_c = 0x0f,
+               .group_d = 0,
+               .group_e = 0,
+               .group_f = 0x80,
+
                .gpio_g_in =  0xc0000000,
                .gpio_g_out = 0xc0000000,
                .gpio_b = 0x80
        },
        {
                .ioif = if_shared_ram,
+               .name = "shared_ram",
                .groups = group_a,
+
+               .group_a = 0x7f8ff,
+               .group_b = 0,
+               .group_c = 0,
+               .group_d = 0,
+               .group_e = 0,
+               .group_f = 0,
+
                .gpio_g_in =  0x0000ff3e,
                .gpio_g_out = 0x0000ff38,
                .gpio_b = 0x00
        },
        {
                .ioif = if_shared_ram_w,
+               .name = "shared_ram_w",
                .groups = group_a | group_d,
+
+               .group_a = 0x7f8ff,
+               .group_b = 0,
+               .group_c = 0,
+               .group_d = 0xff,
+               .group_e = 0,
+               .group_f = 0,
+
                .gpio_g_in =  0x00ffff3e,
                .gpio_g_out = 0x00ffff38,
                .gpio_b = 0x00
        },
        {
                .ioif = if_par_0,
+               .name = "par_0",
                .groups = group_a,
+
+               .group_a = 0x7fbff,
+               .group_b = 0,
+               .group_c = 0,
+               .group_d = 0,
+               .group_e = 0,
+               .group_f = 0,
+
                .gpio_g_in =  0x0000ff3e,
                .gpio_g_out = 0x0000ff3e,
                .gpio_b = 0x00
        },
        {
                .ioif = if_par_1,
+               .name = "par_1",
                .groups = group_d,
+
+               .group_a = 0,
+               .group_b = 0,
+               .group_c = 0,
+               .group_d = 0x7feff,
+               .group_e = 0,
+               .group_f = 0,
+
                .gpio_g_in =  0x3eff0000,
                .gpio_g_out = 0x3eff0000,
                .gpio_b = 0x00
        },
        {
                .ioif = if_par_w,
+               .name = "par_w",
                .groups = group_a | group_d,
+
+               .group_a = 0x7fbff,
+               .group_b = 0,
+               .group_c = 0,
+               .group_d = 0xff,
+               .group_e = 0,
+               .group_f = 0,
+
                .gpio_g_in =  0x00ffff3e,
                .gpio_g_out = 0x00ffff3e,
                .gpio_b = 0x00
        },
        {
                .ioif = if_scsi8_0,
-               .groups = group_a | group_b | group_f, /* if_scsi8_0 and if_scsi8_1
-                                                         can be used simultaneously */
+               .name = "scsi8_0",
+               .groups = group_a | group_b | group_f,
+
+               .group_a = 0x7ffff,
+               .group_b = 0x0f,
+               .group_c = 0,
+               .group_d = 0,
+               .group_e = 0,
+               .group_f = 0x10,
+
                .gpio_g_in =  0x0000ffff,
                .gpio_g_out = 0x0000ffff,
                .gpio_b = 0x10
        },
        {
                .ioif = if_scsi8_1,
-               .groups = group_c | group_d | group_f, /* if_scsi8_0 and if_scsi8_1
-