[lantiq]
authorblogic <blogic@3c298f89-4303-0410-b956-a3cf2f4a3e73>
Mon, 10 Oct 2011 15:13:46 +0000 (15:13 +0000)
committerblogic <blogic@3c298f89-4303-0410-b956-a3cf2f4a3e73>
Mon, 10 Oct 2011 15:13:46 +0000 (15:13 +0000)
* update patches to 3.0
* add basic vr9 support
* backport 3.1 fixes
* backport 3.2 queue (falcon)

git-svn-id: svn://svn.openwrt.org/openwrt/trunk@28405 3c298f89-4303-0410-b956-a3cf2f4a3e73

116 files changed:
target/linux/lantiq/Makefile
target/linux/lantiq/ar9/config-3.0 [deleted file]
target/linux/lantiq/ar9/config-default
target/linux/lantiq/ar9/profiles/003-buffalo.mk
target/linux/lantiq/ar9/target.mk
target/linux/lantiq/ase/config-3.0 [deleted file]
target/linux/lantiq/ase/config-default
target/linux/lantiq/ase/target.mk
target/linux/lantiq/config-3.0 [deleted file]
target/linux/lantiq/config-default
target/linux/lantiq/danube/config-3.0 [deleted file]
target/linux/lantiq/danube/config-default
target/linux/lantiq/danube/profiles/002-arcadyan.mk
target/linux/lantiq/danube/profiles/003-gigaset.mk
target/linux/lantiq/danube/target.mk
target/linux/lantiq/falcon/config-3.0 [deleted file]
target/linux/lantiq/falcon/config-default
target/linux/lantiq/files-3.0/arch/mips/include/asm/mach-lantiq/dev-leds-gpio.h [new file with mode: 0644]
target/linux/lantiq/files-3.0/arch/mips/lantiq/dev-gpio-buttons.c [new file with mode: 0644]
target/linux/lantiq/files-3.0/arch/mips/lantiq/dev-gpio-buttons.h [new file with mode: 0644]
target/linux/lantiq/files-3.0/arch/mips/lantiq/dev-leds-gpio.c [new file with mode: 0644]
target/linux/lantiq/files-3.0/arch/mips/lantiq/falcon/addon-easy98000.c [new file with mode: 0644]
target/linux/lantiq/files-3.0/arch/mips/lantiq/falcon/dev-leds-easy98000-cpld.c [new file with mode: 0644]
target/linux/lantiq/files-3.0/arch/mips/lantiq/falcon/dev-leds-easy98000-cpld.h [new file with mode: 0644]
target/linux/lantiq/files-3.0/arch/mips/lantiq/falcon/mach-95C3AM1.c [new file with mode: 0644]
target/linux/lantiq/files-3.0/arch/mips/lantiq/falcon/mach-easy98020.c [new file with mode: 0644]
target/linux/lantiq/files-3.0/arch/mips/lantiq/xway/dev-dwc_otg.c [new file with mode: 0644]
target/linux/lantiq/files-3.0/arch/mips/lantiq/xway/dev-dwc_otg.h [new file with mode: 0644]
target/linux/lantiq/files-3.0/arch/mips/lantiq/xway/mach-arv45xx.c [new file with mode: 0644]
target/linux/lantiq/files-3.0/arch/mips/lantiq/xway/mach-easy50601.c [new file with mode: 0644]
target/linux/lantiq/files-3.0/arch/mips/lantiq/xway/mach-easy50712.c [new file with mode: 0644]
target/linux/lantiq/files-3.0/arch/mips/lantiq/xway/mach-fritz.c [new file with mode: 0644]
target/linux/lantiq/files-3.0/arch/mips/lantiq/xway/mach-gigasx76x.c [new file with mode: 0644]
target/linux/lantiq/files-3.0/arch/mips/lantiq/xway/mach-netgear.c [new file with mode: 0644]
target/linux/lantiq/files-3.0/arch/mips/lantiq/xway/mach-wbmr.c [new file with mode: 0644]
target/linux/lantiq/modules.mk
target/linux/lantiq/patches-3.0/000-gpio_fix.patch [deleted file]
target/linux/lantiq/patches-3.0/0001-MIPS-lantiq-fix-early-printk.patch [new file with mode: 0644]
target/linux/lantiq/patches-3.0/0002-MIPS-lantiq-fix-cmdline-parsing.patch [new file with mode: 0644]
target/linux/lantiq/patches-3.0/0003-MIPS-lantiq-fix-watchdogs-timeout-handling.patch [new file with mode: 0644]
target/linux/lantiq/patches-3.0/0004-MIPS-lantiq-reorganize-xway-code.patch [new file with mode: 0644]
target/linux/lantiq/patches-3.0/0005-MIPS-lantiq-make-irq.c-support-the-FALC-ON.patch [new file with mode: 0644]
target/linux/lantiq/patches-3.0/0006-MIPS-lantiq-add-basic-support-for-FALC-ON.patch [new file with mode: 0644]
target/linux/lantiq/patches-3.0/0007-MIPS-lantiq-add-support-for-FALC-ON-GPIOs.patch [new file with mode: 0644]
target/linux/lantiq/patches-3.0/0008-MIPS-lantiq-add-support-for-the-EASY98000-evaluation.patch [new file with mode: 0644]
target/linux/lantiq/patches-3.0/0009-MIPS-make-oprofile-use-cp0_perfcount_irq-if-it-is-se.patch [new file with mode: 0644]
target/linux/lantiq/patches-3.0/0010-MIPS-enable-oprofile-support-on-lantiq-targets.patch [new file with mode: 0644]
target/linux/lantiq/patches-3.0/0011-MIPS-lantiq-adds-falcon-I2C.patch [new file with mode: 0644]
target/linux/lantiq/patches-3.0/0012-MIPS-lantiq-adds-GPIO3-support-on-AR9.patch [new file with mode: 0644]
target/linux/lantiq/patches-3.0/0013-MIPS-lantiq-adds-FALC-ON-spi-driver.patch [new file with mode: 0644]
target/linux/lantiq/patches-3.0/0014-MIPS-lantiq-adds-xway-spi.patch [new file with mode: 0644]
target/linux/lantiq/patches-3.0/0015-MIPS-lantiq-adds-etop-support-for-ase-ar9.patch [new file with mode: 0644]
target/linux/lantiq/patches-3.0/0016-MIPS-lantiq-adds-xway-nand-driver.patch [new file with mode: 0644]
target/linux/lantiq/patches-3.0/0017-MIPS-lantiq-adds-GPTU-driver.patch [new file with mode: 0644]
target/linux/lantiq/patches-3.0/0018-MIPS-lantiq-adds-dwc_otg.patch [new file with mode: 0644]
target/linux/lantiq/patches-3.0/0019-MIPS-lantiq-adds-VPE-extensions.patch [new file with mode: 0644]
target/linux/lantiq/patches-3.0/0020-MIPS-lantiq-adds-falcon-VPE-softdog.patch [new file with mode: 0644]
target/linux/lantiq/patches-3.0/0021-MIPS-lantiq-adds-cache-split.patch [new file with mode: 0644]
target/linux/lantiq/patches-3.0/0022-MIPS-lantiq-adds-udp-in-kernel-redirect.patch [new file with mode: 0644]
target/linux/lantiq/patches-3.0/0023-MIPS-lantiq-adds-basic-vr9-support.patch [new file with mode: 0644]
target/linux/lantiq/patches-3.0/020-xway-fix-mtd.patch [deleted file]
target/linux/lantiq/patches-3.0/030-lmo-queue.patch [deleted file]
target/linux/lantiq/patches-3.0/100-falcon_bsp_header.patch [new file with mode: 0644]
target/linux/lantiq/patches-3.0/100-falcon_header.patch [deleted file]
target/linux/lantiq/patches-3.0/110-falcon_board.patch [deleted file]
target/linux/lantiq/patches-3.0/120-falcon-i2c.patch [deleted file]
target/linux/lantiq/patches-3.0/130-falcon-spi-flash.patch [deleted file]
target/linux/lantiq/patches-3.0/140-falcon-easy98000-cpld-led.patch [deleted file]
target/linux/lantiq/patches-3.0/150-falcon-easy98020.patch [deleted file]
target/linux/lantiq/patches-3.0/160-falcon-95C3AM1.patch [deleted file]
target/linux/lantiq/patches-3.0/170-falcon-dm9000-polling.patch [deleted file]
target/linux/lantiq/patches-3.0/180-falcon-linux3.0.patch [deleted file]
target/linux/lantiq/patches-3.0/190-falcon-fix_include.patch [deleted file]
target/linux/lantiq/patches-3.0/200-netif_receive_skb.patch [deleted file]
target/linux/lantiq/patches-3.0/200-owrt-netif_receive_skb.patch [new file with mode: 0644]
target/linux/lantiq/patches-3.0/201-owrt-mtd_uimage_split.patch [new file with mode: 0644]
target/linux/lantiq/patches-3.0/202-owrt-atm.patch [new file with mode: 0644]
target/linux/lantiq/patches-3.0/203-owrt-cmdline.patch [new file with mode: 0644]
target/linux/lantiq/patches-3.0/204-owrt-dm9000-polling.patch [new file with mode: 0644]
target/linux/lantiq/patches-3.0/205-owrt-gpio-export.patch [new file with mode: 0644]
target/linux/lantiq/patches-3.0/210-machtypes.patch [new file with mode: 0644]
target/linux/lantiq/patches-3.0/210-mtd_uimage_split.patch [deleted file]
target/linux/lantiq/patches-3.0/211-devices.patch [new file with mode: 0644]
target/linux/lantiq/patches-3.0/220-atm_hack.patch [deleted file]
target/linux/lantiq/patches-3.0/230-cmdline_hack.patch [deleted file]
target/linux/lantiq/patches-3.0/240-udp_redirect.patch [deleted file]
target/linux/lantiq/patches-3.0/250-mt-vpe.patch [deleted file]
target/linux/lantiq/patches-3.0/260-ar9-cache-split.patch [deleted file]
target/linux/lantiq/patches-3.0/400-spi1.patch [deleted file]
target/linux/lantiq/patches-3.0/410-spi2.patch [deleted file]
target/linux/lantiq/patches-3.0/420-spi3.patch [deleted file]
target/linux/lantiq/patches-3.0/430-gptu.patch [deleted file]
target/linux/lantiq/patches-3.0/440-dwc_otg.patch [deleted file]
target/linux/lantiq/patches-3.0/450-mach-arv45xx.patch [deleted file]
target/linux/lantiq/patches-3.0/460-mach-dgn3500.patch [deleted file]
target/linux/lantiq/patches-3.0/470-mach-gigasx76x.patch [deleted file]
target/linux/lantiq/patches-3.0/480-mach-easy98020.patch [deleted file]
target/linux/lantiq/patches-3.0/510-register_madwifi.patch [deleted file]
target/linux/lantiq/patches-3.0/520-register_buttons.patch [deleted file]
target/linux/lantiq/patches-3.0/530-register_tapi.patch [deleted file]
target/linux/lantiq/patches-3.0/540-dev-leds-gpio.patch [deleted file]
target/linux/lantiq/patches-3.0/550-register_ebu.patch [deleted file]
target/linux/lantiq/patches-3.0/800-fix-etop.patch [new file with mode: 0644]
target/linux/lantiq/patches-3.0/990-backport-3.1-fix-asc-drv-timeout.patch [new file with mode: 0644]
target/linux/lantiq/patches-3.0/990-fix-asc-drv-timeout.patch [deleted file]
target/linux/lantiq/patches-3.0/990-fix-early_printk.patch [deleted file]
target/linux/lantiq/patches-3.0/991-backport-3.1-fix-eiu.patch [new file with mode: 0644]
target/linux/lantiq/patches-3.0/991-fix-wdt-timeout.patch [deleted file]
target/linux/lantiq/patches-3.0/992-backport-3.1-fix-pci.patch [new file with mode: 0644]
target/linux/lantiq/patches-3.0/993-backport-3.1-fix-mtd.patch [new file with mode: 0644]
target/linux/lantiq/patches-3.0/994-backport-3.1-fix-clk.patch [new file with mode: 0644]
target/linux/lantiq/patches-3.0/995-backport-3.1-lookup_resource.patch [new file with mode: 0644]
target/linux/lantiq/patches-3.0/998-easy98000-asc1.patch [deleted file]
target/linux/lantiq/vr9/config-default [new file with mode: 0644]
target/linux/lantiq/vr9/profiles/000-generic.mk [new file with mode: 0644]
target/linux/lantiq/vr9/target.mk [new file with mode: 0644]

index e355c15..8d845b9 100644 (file)
@@ -12,7 +12,7 @@ BOARDNAME:=Lantiq GPON/XWAY
 FEATURES:=squashfs jffs2
 DEFAULT_SUBTARGET:=danube
 
-LINUX_VERSION:=2.6.39.4
+LINUX_VERSION:=3.0.3
 
 CFLAGS=-Os -pipe -mips32r2 -mtune=mips32r2 -fno-caller-saves
 
diff --git a/target/linux/lantiq/ar9/config-3.0 b/target/linux/lantiq/ar9/config-3.0
deleted file mode 100644 (file)
index f596114..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-CONFIG_ADM6996_PHY=y
-CONFIG_AR8216_PHY=y
-# CONFIG_ARCH_DMA_ADDR_T_64BIT is not set
-# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
-# CONFIG_ATH79 is not set
-CONFIG_GENERIC_ATOMIC64=y
-CONFIG_GENERIC_IRQ_SHOW=y
-CONFIG_HAVE_ARCH_JUMP_LABEL=y
-CONFIG_HAVE_C_RECORDMCOUNT=y
-CONFIG_HAVE_DMA_API_DEBUG=y
-CONFIG_HAVE_DMA_ATTRS=y
-CONFIG_HAVE_DYNAMIC_FTRACE=y
-CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
-CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
-CONFIG_HAVE_FUNCTION_TRACER=y
-CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
-CONFIG_HAVE_GENERIC_HARDIRQS=y
-CONFIG_HAVE_IRQ_WORK=y
-CONFIG_HAVE_PERF_EVENTS=y
-CONFIG_HW_HAS_PCI=y
-CONFIG_INPUT=y
-CONFIG_INPUT_EVDEV=y
-# CONFIG_INPUT_GPIO_BUTTONS is not set
-CONFIG_INPUT_POLLDEV=y
-# CONFIG_ISDN is not set
-CONFIG_LANTIQ_ETOP=y
-# CONFIG_LANTIQ_MACH_ARV45XX is not set
-# CONFIG_LANTIQ_MACH_EASY50712 is not set
-CONFIG_LANTIQ_MACH_NETGEAR=y
-# CONFIG_LANTIQ_MACH_GIGASX76X is not set
-CONFIG_MACH_NO_WESTBRIDGE=y
-# CONFIG_MINIX_FS_NATIVE_ENDIAN is not set
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NEED_PER_CPU_KM=y
-CONFIG_PCI=y
-CONFIG_PCI_DOMAINS=y
-CONFIG_PERF_USE_VMALLOC=y
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_QUOTACTL is not set
-CONFIG_RTL8306_PHY=y
-# CONFIG_SOC_AMAZON_SE is not set
-# CONFIG_SOC_FALCON is not set
-CONFIG_SOC_TYPE_XWAY=y
-CONFIG_SOC_XWAY=y
-CONFIG_SPI=y
-CONFIG_SPI_BITBANG=y
-# CONFIG_SPI_GPIO is not set
-CONFIG_SPI_LANTIQ=y
-CONFIG_SPI_MASTER=y
-CONFIG_USB_SUPPORT=y
-CONFIG_XZ_DEC=y
index fb69899..34192d0 100644 (file)
@@ -27,8 +27,8 @@ CONFIG_LANTIQ_ETOP=y
 # CONFIG_LANTIQ_MACH_ARV45XX is not set
 # CONFIG_LANTIQ_MACH_EASY50712 is not set
 CONFIG_LANTIQ_MACH_NETGEAR=y
-# CONFIG_LANTIQ_MACH_GIGASX76X is not set
 CONFIG_LANTIQ_MACH_WBMR=y
+# CONFIG_LANTIQ_MACH_GIGASX76X is not set
 CONFIG_MACH_NO_WESTBRIDGE=y
 # CONFIG_MINIX_FS_NATIVE_ENDIAN is not set
 CONFIG_NEED_DMA_MAP_STATE=y
@@ -40,6 +40,7 @@ CONFIG_PERF_USE_VMALLOC=y
 # CONFIG_QUOTACTL is not set
 CONFIG_RTL8306_PHY=y
 # CONFIG_SOC_AMAZON_SE is not set
+# CONFIG_SOC_VR9 is not set
 # CONFIG_SOC_FALCON is not set
 CONFIG_SOC_TYPE_XWAY=y
 CONFIG_SOC_XWAY=y
@@ -50,3 +51,4 @@ CONFIG_SPI_LANTIQ=y
 CONFIG_SPI_MASTER=y
 CONFIG_USB_SUPPORT=y
 CONFIG_XZ_DEC=y
+CONFIG_SPI_XWAY=y
index bdf838d..df2829e 100644 (file)
@@ -1,7 +1,7 @@
 define Profile/WBMR
   NAME:=WBMR - Buffalo WBMR-HP-G300H
   PACKAGES:= kmod-usb-core kmod-usb-dwc-otg kmod-leds-gpio \
-        kmod-ltq-dsl-firmware-b kmod-ledtrig-usbdev 
+        kmod-ltq-dsl-firmware-b-ar9 kmod-ledtrig-usbdev
 endef
 
 define Profile/WBMR/Description
index a04384e..89a1586 100644 (file)
@@ -3,7 +3,7 @@ SUBTARGET:=ar9
 BOARDNAME:=AR9
 FEATURES:=squashfs jffs2 atm
 
-DEFAULT_PACKAGES+=kmod-pppoa ppp-mod-pppoa linux-atm atm-tools br2684ctl kmod-ltq-dsl ltq-dsl-app swconfig
+DEFAULT_PACKAGES+=kmod-pppoa ppp-mod-pppoa linux-atm atm-tools br2684ctl kmod-ltq-dsl-ar9 ltq-dsl-app swconfig
 
 define Target/Description
        Lantiq XWAY (danube/twinpass/ar9)
diff --git a/target/linux/lantiq/ase/config-3.0 b/target/linux/lantiq/ase/config-3.0
deleted file mode 100644 (file)
index b39ed5e..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-# CONFIG_ARCH_DMA_ADDR_T_64BIT is not set
-# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
-# CONFIG_ATH79 is not set
-CONFIG_GENERIC_ATOMIC64=y
-CONFIG_GENERIC_IRQ_SHOW=y
-CONFIG_HAVE_ARCH_JUMP_LABEL=y
-CONFIG_HAVE_C_RECORDMCOUNT=y
-CONFIG_HAVE_DMA_API_DEBUG=y
-CONFIG_HAVE_DMA_ATTRS=y
-CONFIG_HAVE_DYNAMIC_FTRACE=y
-CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
-CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
-CONFIG_HAVE_FUNCTION_TRACER=y
-CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
-CONFIG_HAVE_GENERIC_HARDIRQS=y
-CONFIG_HAVE_IRQ_WORK=y
-CONFIG_HAVE_PERF_EVENTS=y
-CONFIG_INPUT=y
-CONFIG_INPUT_EVDEV=y
-# CONFIG_INPUT_GPIO_BUTTONS is not set
-CONFIG_INPUT_POLLDEV=y
-# CONFIG_ISDN is not set
-CONFIG_LANTIQ_ETOP=y
-CONFIG_LANTIQ_MACH_EASY50601=y
-CONFIG_MACH_NO_WESTBRIDGE=y
-# CONFIG_MINIX_FS_NATIVE_ENDIAN is not set
-# CONFIG_MTD_LATCH_ADDR is not set
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NEED_PER_CPU_KM=y
-CONFIG_PERF_USE_VMALLOC=y
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_QUOTACTL is not set
-CONFIG_SOC_AMAZON_SE=y
-# CONFIG_SOC_FALCON is not set
-CONFIG_SOC_TYPE_XWAY=y
-# CONFIG_SOC_XWAY is not set
-CONFIG_XZ_DEC=y
index b39ed5e..a6c8a3d 100644 (file)
@@ -31,7 +31,9 @@ CONFIG_PERF_USE_VMALLOC=y
 # CONFIG_PREEMPT_RCU is not set
 # CONFIG_QUOTACTL is not set
 CONFIG_SOC_AMAZON_SE=y
+# CONFIG_SOC_VR9 is not set
 # CONFIG_SOC_FALCON is not set
 CONFIG_SOC_TYPE_XWAY=y
 # CONFIG_SOC_XWAY is not set
 CONFIG_XZ_DEC=y
+CONFIG_SPI_XWAY=y
index 343edf9..9837463 100644 (file)
@@ -3,7 +3,7 @@ SUBTARGET:=ase
 BOARDNAME:=Amazon-SE
 FEATURES:=squashfs jffs2 atm
 
-DEFAULT_PACKAGES+=kmod-pppoa ppp-mod-pppoa linux-atm atm-tools br2684ctl kmod-ltq-dsl ltq-dsl-app
+DEFAULT_PACKAGES+=kmod-pppoa ppp-mod-pppoa linux-atm atm-tools br2684ctl kmod-ltq-dsl-ase ltq-dsl-app
 
 define Target/Description
        Lantiq ASE
diff --git a/target/linux/lantiq/config-3.0 b/target/linux/lantiq/config-3.0
deleted file mode 100644 (file)
index d57cf35..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-# CONFIG_ARCH_DMA_ADDR_T_64BIT is not set
-# CONFIG_ARCH_HAS_ILOG2_U32 is not set
-# CONFIG_ARCH_HAS_ILOG2_U64 is not set
-CONFIG_ARCH_HIBERNATION_POSSIBLE=y
-# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
-CONFIG_ARCH_POPULATES_NODE_MAP=y
-CONFIG_ARCH_REQUIRE_GPIOLIB=y
-# CONFIG_ARCH_SUPPORTS_MSI is not set
-CONFIG_ARCH_SUPPORTS_OPROFILE=y
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
-# CONFIG_ATH79 is not set
-CONFIG_BCMA_POSSIBLE=y
-# CONFIG_BRCMUTIL is not set
-CONFIG_CEVT_R4K=y
-CONFIG_CEVT_R4K_LIB=y
-CONFIG_CPU_BIG_ENDIAN=y
-CONFIG_CPU_HAS_PREFETCH=y
-CONFIG_CPU_HAS_SYNC=y
-CONFIG_CPU_MIPS32=y
-# CONFIG_CPU_MIPS32_R1 is not set
-CONFIG_CPU_MIPS32_R2=y
-CONFIG_CPU_MIPSR2=y
-CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_HIGHMEM=y
-CONFIG_CSRC_R4K=y
-CONFIG_CSRC_R4K_LIB=y
-CONFIG_DECOMPRESS_LZMA=y
-CONFIG_DMA_NONCOHERENT=y
-CONFIG_EARLY_PRINTK=y
-# CONFIG_FSNOTIFY is not set
-CONFIG_GENERIC_ATOMIC64=y
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
-CONFIG_GENERIC_CMOS_UPDATE=y
-CONFIG_GENERIC_GPIO=y
-CONFIG_GENERIC_IRQ_SHOW=y
-CONFIG_GPIOLIB=y
-CONFIG_GPIO_SYSFS=y
-CONFIG_HARDWARE_WATCHPOINTS=y
-CONFIG_HAS_DMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT=y
-CONFIG_HAVE_ARCH_JUMP_LABEL=y
-CONFIG_HAVE_ARCH_KGDB=y
-CONFIG_HAVE_CLK=y
-CONFIG_HAVE_C_RECORDMCOUNT=y
-CONFIG_HAVE_DMA_API_DEBUG=y
-CONFIG_HAVE_DMA_ATTRS=y
-CONFIG_HAVE_DYNAMIC_FTRACE=y
-CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
-CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
-CONFIG_HAVE_FUNCTION_TRACER=y
-CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
-CONFIG_HAVE_GENERIC_DMA_COHERENT=y
-CONFIG_HAVE_GENERIC_HARDIRQS=y
-CONFIG_HAVE_IDE=y
-CONFIG_HAVE_IRQ_WORK=y
-CONFIG_HAVE_OPROFILE=y
-CONFIG_HAVE_PERF_EVENTS=y
-CONFIG_HW_RANDOM=y
-CONFIG_HZ=250
-# CONFIG_HZ_100 is not set
-CONFIG_HZ_250=y
-CONFIG_IFX_UDP_REDIRECT=y
-CONFIG_IMAGE_CMDLINE_HACK=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_IRQ_CPU=y
-CONFIG_LANTIQ=y
-CONFIG_LANTIQ_MACH_95C3AM1=y
-CONFIG_LANTIQ_MACH_EASY98000=y
-CONFIG_LANTIQ_MACH_EASY98020=y
-CONFIG_LANTIQ_WDT=y
-CONFIG_LEDS_GPIO=y
-CONFIG_MACH_NO_WESTBRIDGE=y
-# CONFIG_MINIX_FS_NATIVE_ENDIAN is not set
-CONFIG_MIPS=y
-CONFIG_MIPS_L1_CACHE_SHIFT=5
-CONFIG_MIPS_MACHINE=y
-CONFIG_MIPS_MT_DISABLED=y
-# CONFIG_MIPS_MT_SMP is not set
-# CONFIG_MIPS_MT_SMTC is not set
-# CONFIG_MIPS_VPE_LOADER is not set
-CONFIG_MTD_CFI_ADV_OPTIONS=y
-CONFIG_MTD_CFI_GEOMETRY=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_LANTIQ=y
-CONFIG_MTD_UIMAGE_SPLIT=y
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NEED_PER_CPU_KM=y
-CONFIG_NLS=y
-CONFIG_PAGEFLAGS_EXTENDED=y
-CONFIG_PERF_USE_VMALLOC=y
-CONFIG_PHYLIB=y
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_QUOTACTL is not set
-# CONFIG_RTC_CLASS is not set
-CONFIG_RTL8366RB_PHY=y
-CONFIG_RTL8366_SMI=y
-# CONFIG_SCSI_DMA is not set
-# CONFIG_SERIAL_8250 is not set
-CONFIG_SERIAL_LANTIQ=y
-CONFIG_SWAP_IO_SPACE=y
-CONFIG_SWCONFIG=y
-CONFIG_SYS_HAS_CPU_MIPS32_R1=y
-CONFIG_SYS_HAS_CPU_MIPS32_R2=y
-CONFIG_SYS_HAS_EARLY_PRINTK=y
-CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
-CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
-CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
-CONFIG_SYS_SUPPORTS_MULTITHREADING=y
-CONFIG_XZ_DEC=y
-CONFIG_ZONE_DMA_FLAG=0
index d799d24..d4e90c9 100644 (file)
@@ -1,70 +1,62 @@
-# CONFIG_64BIT is not set
+# CONFIG_ARCH_DMA_ADDR_T_64BIT is not set
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_REQUIRE_GPIOLIB=y
 # CONFIG_ARCH_SUPPORTS_MSI is not set
 CONFIG_ARCH_SUPPORTS_OPROFILE=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
+# CONFIG_ATH79 is not set
+CONFIG_BCMA_POSSIBLE=y
+# CONFIG_BRCMUTIL is not set
 CONFIG_CEVT_R4K=y
 CONFIG_CEVT_R4K_LIB=y
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
 CONFIG_CPU_BIG_ENDIAN=y
-# CONFIG_CPU_CAVIUM_OCTEON is not set
 CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_CPU_HAS_SYNC=y
-# CONFIG_CPU_LITTLE_ENDIAN is not set
-# CONFIG_CPU_LOONGSON2E is not set
 CONFIG_CPU_MIPS32=y
 # CONFIG_CPU_MIPS32_R1 is not set
 CONFIG_CPU_MIPS32_R2=y
-# CONFIG_CPU_MIPS64_R1 is not set
-# CONFIG_CPU_MIPS64_R2 is not set
 CONFIG_CPU_MIPSR2=y
-# CONFIG_CPU_NEVADA is not set
-# CONFIG_CPU_R10000 is not set
-# CONFIG_CPU_R3000 is not set
-# CONFIG_CPU_R4300 is not set
-# CONFIG_CPU_R4X00 is not set
-# CONFIG_CPU_R5000 is not set
-# CONFIG_CPU_R5432 is not set
-# CONFIG_CPU_R5500 is not set
-# CONFIG_CPU_R6000 is not set
-# CONFIG_CPU_R8000 is not set
-# CONFIG_CPU_RM7000 is not set
-# CONFIG_CPU_RM9000 is not set
-# CONFIG_CPU_SB1 is not set
 CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
 CONFIG_CPU_SUPPORTS_HIGHMEM=y
-# CONFIG_CPU_TX39XX is not set
-# CONFIG_CPU_TX49XX is not set
-# CONFIG_CPU_VR41XX is not set
 CONFIG_CSRC_R4K=y
 CONFIG_CSRC_R4K_LIB=y
 CONFIG_DECOMPRESS_LZMA=y
-CONFIG_DMA_NEED_PCI_MAP_STATE=y
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_EARLY_PRINTK=y
 # CONFIG_FSNOTIFY is not set
+CONFIG_GENERIC_ATOMIC64=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
 CONFIG_GENERIC_CMOS_UPDATE=y
-CONFIG_GENERIC_FIND_LAST_BIT=y
-CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_GPIO=y
-CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_GENERIC_IRQ_SHOW=y
 CONFIG_GPIOLIB=y
 CONFIG_GPIO_SYSFS=y
 CONFIG_HARDWARE_WATCHPOINTS=y
 CONFIG_HAS_DMA=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
+CONFIG_HAVE_ARCH_JUMP_LABEL=y
 CONFIG_HAVE_ARCH_KGDB=y
 CONFIG_HAVE_CLK=y
+CONFIG_HAVE_C_RECORDMCOUNT=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
 CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_HAVE_GENERIC_HARDIRQS=y
 CONFIG_HAVE_IDE=y
+CONFIG_HAVE_IRQ_WORK=y
 CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_PERF_EVENTS=y
 CONFIG_HW_RANDOM=y
 CONFIG_HZ=250
 # CONFIG_HZ_100 is not set
@@ -74,9 +66,13 @@ CONFIG_IMAGE_CMDLINE_HACK=y
 CONFIG_INITRAMFS_SOURCE=""
 CONFIG_IRQ_CPU=y
 CONFIG_LANTIQ=y
+CONFIG_LANTIQ_MACH_95C3AM1=y
+CONFIG_LANTIQ_MACH_EASY98000=y
+CONFIG_LANTIQ_MACH_EASY98020=y
 CONFIG_LANTIQ_WDT=y
 CONFIG_LEDS_GPIO=y
-# CONFIG_MACH_ALCHEMY is not set
+CONFIG_MACH_NO_WESTBRIDGE=y
+# CONFIG_MINIX_FS_NATIVE_ENDIAN is not set
 CONFIG_MIPS=y
 CONFIG_MIPS_L1_CACHE_SHIFT=5
 CONFIG_MIPS_MACHINE=y
@@ -89,9 +85,15 @@ CONFIG_MTD_CFI_GEOMETRY=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_LANTIQ=y
 CONFIG_MTD_UIMAGE_SPLIT=y
-CONFIG_NLS=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_NEED_PER_CPU_KM=y
 CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_PERF_USE_VMALLOC=y
 CONFIG_PHYLIB=y
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_QUOTACTL is not set
+CONFIG_RTL8366RB_PHY=y
+CONFIG_RTL8366_SMI=y
 # CONFIG_SCSI_DMA is not set
 # CONFIG_SERIAL_8250 is not set
 CONFIG_SERIAL_LANTIQ=y
@@ -104,5 +106,5 @@ CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
 CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
 CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
 CONFIG_SYS_SUPPORTS_MULTITHREADING=y
-CONFIG_TREE_RCU=y
+CONFIG_XZ_DEC=y
 CONFIG_ZONE_DMA_FLAG=0
diff --git a/target/linux/lantiq/danube/config-3.0 b/target/linux/lantiq/danube/config-3.0
deleted file mode 100644 (file)
index 4ea6189..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-CONFIG_ADM6996_PHY=y
-CONFIG_AR8216_PHY=y
-# CONFIG_ARCH_DMA_ADDR_T_64BIT is not set
-# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
-# CONFIG_ATH79 is not set
-CONFIG_GENERIC_ATOMIC64=y
-CONFIG_GENERIC_IRQ_SHOW=y
-CONFIG_HAVE_ARCH_JUMP_LABEL=y
-CONFIG_HAVE_C_RECORDMCOUNT=y
-CONFIG_HAVE_DMA_API_DEBUG=y
-CONFIG_HAVE_DMA_ATTRS=y
-CONFIG_HAVE_DYNAMIC_FTRACE=y
-CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
-CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
-CONFIG_HAVE_FUNCTION_TRACER=y
-CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
-CONFIG_HAVE_GENERIC_HARDIRQS=y
-CONFIG_HAVE_IRQ_WORK=y
-CONFIG_HAVE_PERF_EVENTS=y
-CONFIG_HW_HAS_PCI=y
-CONFIG_INPUT=y
-CONFIG_INPUT_EVDEV=y
-# CONFIG_INPUT_GPIO_BUTTONS is not set
-CONFIG_INPUT_POLLDEV=y
-# CONFIG_ISDN is not set
-CONFIG_LANTIQ_ETOP=y
-CONFIG_LANTIQ_MACH_ARV45XX=y
-CONFIG_LANTIQ_MACH_EASY50712=y
-# CONFIG_LANTIQ_MACH_NETGEAR is not set
-CONFIG_LANTIQ_MACH_GIGASX76X=y
-CONFIG_MACH_NO_WESTBRIDGE=y
-# CONFIG_MINIX_FS_NATIVE_ENDIAN is not set
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NEED_PER_CPU_KM=y
-CONFIG_PCI=y
-CONFIG_PCI_DOMAINS=y
-CONFIG_PERF_USE_VMALLOC=y
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_QUOTACTL is not set
-CONFIG_RTL8306_PHY=y
-# CONFIG_SOC_AMAZON_SE is not set
-# CONFIG_SOC_FALCON is not set
-CONFIG_SOC_TYPE_XWAY=y
-CONFIG_SOC_XWAY=y
-CONFIG_SPI=y
-CONFIG_SPI_BITBANG=y
-# CONFIG_SPI_GPIO is not set
-CONFIG_SPI_LANTIQ=y
-CONFIG_SPI_MASTER=y
-CONFIG_USB_SUPPORT=y
-CONFIG_XZ_DEC=y
index 00ae07f..508706d 100644 (file)
@@ -27,8 +27,8 @@ CONFIG_LANTIQ_ETOP=y
 CONFIG_LANTIQ_MACH_ARV45XX=y
 CONFIG_LANTIQ_MACH_EASY50712=y
 # CONFIG_LANTIQ_MACH_NETGEAR is not set
-CONFIG_LANTIQ_MACH_GIGASX76X=y
 # CONFIG_LANTIQ_MACH_WBMR is not set
+CONFIG_LANTIQ_MACH_GIGASX76X=y
 CONFIG_MACH_NO_WESTBRIDGE=y
 # CONFIG_MINIX_FS_NATIVE_ENDIAN is not set
 CONFIG_NEED_DMA_MAP_STATE=y
@@ -41,6 +41,7 @@ CONFIG_PERF_USE_VMALLOC=y
 CONFIG_RTL8306_PHY=y
 # CONFIG_SOC_AMAZON_SE is not set
 # CONFIG_SOC_FALCON is not set
+# CONFIG_SOC_VR9 is not set
 CONFIG_SOC_TYPE_XWAY=y
 CONFIG_SOC_XWAY=y
 CONFIG_SPI=y
@@ -50,3 +51,4 @@ CONFIG_SPI_LANTIQ=y
 CONFIG_SPI_MASTER=y
 CONFIG_USB_SUPPORT=y
 CONFIG_XZ_DEC=y
+CONFIG_SPI_XWAY=y
index 509fe07..00cd00b 100644 (file)
@@ -1,6 +1,6 @@
 define Profile/ARV3527P
   NAME:=ARV3527P - Arcor Easybox 401
-  PACKAGES:=kmod-ledtrig-netdev kmod-leds-gpio kmod-button-hotplug kmod-ltq-dsl-firmware-b
+  PACKAGES:=kmod-ledtrig-netdev kmod-leds-gpio kmod-button-hotplug kmod-ltq-dsl-firmware-b-danube
 endef
 
 define Profile/ARV3527P/Description
@@ -13,7 +13,7 @@ define Profile/ARV4510PW
   NAME:=ARV4510PW - Wippies Homebox
   PACKAGES:= kmod-usb-core \
        kmod-ledtrig-netdev kmod-ledtrig-usbdev kmod-leds-gpio kmod-button-hotplug \
-       kmod-rt61-pci wpad-mini kmod-ltq-dsl-firmware-a
+       kmod-rt61-pci wpad-mini kmod-ltq-dsl-firmware-a-danube
 endef
 
 define Profile/ARV4510PW/Description
@@ -26,7 +26,7 @@ define Profile/ARV4518PW
   NAME:=ARV4518PW - SMC7908A
   PACKAGES:= kmod-usb-core kmod-usb-dwc-otg \
        kmod-ledtrig-netdev kmod-ledtrig-usbdev kmod-leds-gpio kmod-button-hotplug \
-       kmod-madwifi wpad-mini kmod-ltq-dsl-firmware-a
+       kmod-madwifi wpad-mini kmod-ltq-dsl-firmware-a-danube
 endef
 
 define Profile/ARV4518PW/Description
@@ -39,7 +39,7 @@ define Profile/ARV4520PW
   NAME:=ARV4520PW - Arcor Easybox 800
   PACKAGES:= kmod-usb-core kmod-usb-dwc-otg \
        kmod-ledtrig-netdev kmod-ledtrig-usbdev kmod-leds-gpio kmod-button-hotplug \
-       kmod-rt61-pci wpad-mini kmod-ltq-dsl-firmware-b 
+       kmod-rt61-pci wpad-mini kmod-ltq-dsl-firmware-b-danube 
 endef
 
 define Profile/ARV4520PW/Description
@@ -52,7 +52,7 @@ define Profile/ARV4525PW
   NAME:=ARV4525PW - Speedport W502V
   PACKAGES:= kmod-usb-core kmod-usb-dwc-otg \
        kmod-ledtrig-netdev kmod-ledtrig-usbdev kmod-leds-gpio kmod-button-hotplug \
-       kmod-madwifi wpad-mini kmod-ltq-dsl-firmware-b
+       kmod-madwifi wpad-mini kmod-ltq-dsl-firmware-b-danube
 endef
 
 define Profile/ARV4525PW/Description
@@ -65,7 +65,7 @@ define Profile/ARV7525PW
   NAME:=ARV7525PW - Speedport W303V Typ A
   PACKAGES:= kmod-usb-core kmod-usb-dwc-otg \
        kmod-ledtrig-netdev kmod-ledtrig-usbdev kmod-leds-gpio kmod-button-hotplug \
-       kmod-rt2800-pci wpad-mini kmod-ltq-dsl-firmware-b
+       kmod-rt2800-pci wpad-mini kmod-ltq-dsl-firmware-b-danube
 endef
 
 define Profile/ARV4525PW/Description
@@ -78,7 +78,7 @@ define Profile/ARV452CPW
   NAME:=ARV452CPW - Arcor Easybox 801
   PACKAGES:= kmod-usb-core kmod-usb-dwc-otg \
        kmod-ledtrig-netdev kmod-ledtrig-usbdev kmod-leds-gpio kmod-button-hotplug \
-       kmod-madwifi wpad-mini kmod-ltq-dsl-firmware-b
+       kmod-madwifi wpad-mini kmod-ltq-dsl-firmware-b-danube
 endef
 
 define Profile/ARV452CPW/Description
@@ -91,7 +91,7 @@ define Profile/ARV752DPW
   NAME:=ARV752DPW - Arcor Easybox 802
   PACKAGES:= kmod-usb-core kmod-usb-dwc-otg \
        kmod-ledtrig-netdev kmod-ledtrig-usbdev kmod-leds-gpio kmod-button-hotplug \
-       kmod-rt2800-pci kmod-ltq-dsl-firmware-b
+       kmod-rt2800-pci kmod-ltq-dsl-firmware-b-danube
 endef
 
 define Profile/ARV752DPW/Description
@@ -104,7 +104,7 @@ define Profile/ARV752DPW22
   NAME:=ARV752DPW22 - Arcor Easybox 803
   PACKAGES:= kmod-usb-core kmod-usb2 kmod-usb-uhci kmod-usb-dwc-otg \
        kmod-ledtrig-netdev kmod-ledtrig-usbdev kmod-leds-gpio kmod-button-hotplug \
-       kmod-ltq-dsl-firmware-b
+       kmod-ltq-dsl-firmware-b-danube
 endef
 
 define Profile/ARV752DPW22/Description
index 844b411..ee4605a 100644 (file)
@@ -1,7 +1,7 @@
 define Profile/GIGASX76X
   NAME:=GIGASX76X - Gigaset SX761,SX762,SX763
   PACKAGES:= kmod-usb-core kmod-usb-dwc-otg kmod-leds-gpio \
-        kmod-ltq-dsl-firmware-b kmod-ledtrig-usbdev 
+        kmod-ltq-dsl-firmware-b-danube kmod-ledtrig-usbdev 
 endef
 
 define Profile/GIGASX76X/Description
index 2fa1261..03fc186 100644 (file)
@@ -3,7 +3,7 @@ SUBTARGET:=danube
 BOARDNAME:=Danube
 FEATURES:=squashfs jffs2 atm
 
-DEFAULT_PACKAGES+=kmod-pppoa ppp-mod-pppoa linux-atm atm-tools br2684ctl kmod-ltq-dsl ltq-dsl-app swconfig
+DEFAULT_PACKAGES+=kmod-pppoa ppp-mod-pppoa linux-atm atm-tools br2684ctl kmod-ltq-dsl-danube ltq-dsl-app swconfig
 
 define Target/Description
        Lantiq Danube/Twinpass
diff --git a/target/linux/lantiq/falcon/config-3.0 b/target/linux/lantiq/falcon/config-3.0
deleted file mode 100644 (file)
index 0504928..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-CONFIG_CPU_MIPSR2_IRQ_EI=y
-CONFIG_CPU_MIPSR2_IRQ_VI=y
-CONFIG_IFX_VPE_CACHE_SPLIT=y
-CONFIG_IFX_VPE_EXT=y
-CONFIG_M25PXX_USE_FAST_READ=y
-CONFIG_MIPS_MT=y
-# CONFIG_MIPS_VPE_APSP_API is not set
-CONFIG_MIPS_VPE_LOADER=y
-CONFIG_MIPS_VPE_LOADER_TOM=y
-CONFIG_MTD_M25P80=y
-CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_ECC=y
-CONFIG_MTD_NAND_PLATFORM=y
-# CONFIG_MTD_SM_COMMON is not set
-CONFIG_MTSCHED=y
-# CONFIG_PERFCTRS is not set
-# CONFIG_SOC_AMAZON_SE is not set
-CONFIG_SOC_FALCON=y
-# CONFIG_SOC_TYPE_XWAY is not set
-# CONFIG_SOC_XWAY is not set
-CONFIG_SPI=y
-# CONFIG_SPI_BITBANG is not set
-CONFIG_SPI_FALCON=y
-# CONFIG_SPI_GPIO is not set
-CONFIG_SPI_MASTER=y
-# CONFIG_I2C_DESIGNWARE is not set
-
index 5f864f4..f1d6e48 100644 (file)
@@ -1,31 +1,8 @@
-# CONFIG_ARCH_DMA_ADDR_T_64BIT is not set
-# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
-# CONFIG_ATH79 is not set
 CONFIG_CPU_MIPSR2_IRQ_EI=y
 CONFIG_CPU_MIPSR2_IRQ_VI=y
-CONFIG_GENERIC_ATOMIC64=y
-CONFIG_GENERIC_IRQ_SHOW=y
-CONFIG_HAVE_ARCH_JUMP_LABEL=y
-CONFIG_HAVE_C_RECORDMCOUNT=y
-CONFIG_HAVE_DMA_API_DEBUG=y
-CONFIG_HAVE_DMA_ATTRS=y
-CONFIG_HAVE_DYNAMIC_FTRACE=y
-CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
-CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
-CONFIG_HAVE_FUNCTION_TRACER=y
-CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
-CONFIG_HAVE_GENERIC_HARDIRQS=y
-CONFIG_HAVE_IRQ_WORK=y
-CONFIG_HAVE_PERF_EVENTS=y
 CONFIG_IFX_VPE_CACHE_SPLIT=y
 CONFIG_IFX_VPE_EXT=y
-CONFIG_LANTIQ_MACH_95C3AM1=y
-CONFIG_LANTIQ_MACH_EASY98000=y
-CONFIG_LANTIQ_MACH_EASY98020=y
 CONFIG_M25PXX_USE_FAST_READ=y
-CONFIG_MACH_NO_WESTBRIDGE=y
-# CONFIG_MFD_MAX8997 is not set
-# CONFIG_MINIX_FS_NATIVE_ENDIAN is not set
 CONFIG_MIPS_MT=y
 # CONFIG_MIPS_VPE_APSP_API is not set
 CONFIG_MIPS_VPE_LOADER=y
@@ -33,24 +10,19 @@ CONFIG_MIPS_VPE_LOADER_TOM=y
 CONFIG_MTD_M25P80=y
 CONFIG_MTD_NAND=y
 CONFIG_MTD_NAND_ECC=y
-# CONFIG_MTD_NAND_ECC_BCH is not set
 CONFIG_MTD_NAND_PLATFORM=y
 # CONFIG_MTD_SM_COMMON is not set
 CONFIG_MTSCHED=y
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NEED_PER_CPU_KM=y
 # CONFIG_PERFCTRS is not set
-CONFIG_PERF_USE_VMALLOC=y
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_QUOTACTL is not set
 # CONFIG_SOC_AMAZON_SE is not set
 CONFIG_SOC_FALCON=y
 # CONFIG_SOC_TYPE_XWAY is not set
 # CONFIG_SOC_XWAY is not set
+# CONFIG_SOC_VR9 is not set
 CONFIG_SPI=y
 # CONFIG_SPI_BITBANG is not set
 CONFIG_SPI_FALCON=y
 # CONFIG_SPI_GPIO is not set
 CONFIG_SPI_MASTER=y
-CONFIG_XZ_DEC=y
 # CONFIG_I2C_DESIGNWARE is not set
+
diff --git a/target/linux/lantiq/files-3.0/arch/mips/include/asm/mach-lantiq/dev-leds-gpio.h b/target/linux/lantiq/files-3.0/arch/mips/include/asm/mach-lantiq/dev-leds-gpio.h
new file mode 100644 (file)
index 0000000..0991199
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ *  Lantiq GPIO LED device support
+ *
+ *  Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#ifndef _LANTIQ_DEV_LEDS_GPIO_H
+#define _LANTIQ_DEV_LEDS_GPIO_H
+
+#include <linux/leds.h>
+
+void ltq_add_device_leds_gpio(int id,
+                                unsigned num_leds,
+                                struct gpio_led *leds) __init;
+
+#endif /* _LANTIQ_DEV_LEDS_GPIO_H */
diff --git a/target/linux/lantiq/files-3.0/arch/mips/lantiq/dev-gpio-buttons.c b/target/linux/lantiq/files-3.0/arch/mips/lantiq/dev-gpio-buttons.c
new file mode 100644 (file)
index 0000000..bcc4f58
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ *  Lantiq GPIO button support
+ *
+ *  Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#include "linux/init.h"
+#include "linux/slab.h"
+#include <linux/platform_device.h>
+
+#include "dev-gpio-buttons.h"
+
+void __init ltq_register_gpio_keys_polled(int id,
+                                            unsigned poll_interval,
+                                            unsigned nbuttons,
+                                            struct gpio_keys_button *buttons)
+{
+       struct platform_device *pdev;
+       struct gpio_keys_platform_data pdata;
+       struct gpio_keys_button *p;
+       int err;
+
+       p = kmalloc(nbuttons * sizeof(*p), GFP_KERNEL);
+       if (!p)
+               return;
+
+       memcpy(p, buttons, nbuttons * sizeof(*p));
+
+       pdev = platform_device_alloc("gpio-keys-polled", id);
+       if (!pdev)
+               goto err_free_buttons;
+
+       memset(&pdata, 0, sizeof(pdata));
+       pdata.poll_interval = poll_interval;
+       pdata.nbuttons = nbuttons;
+       pdata.buttons = p;
+
+       err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
+       if (err)
+               goto err_put_pdev;
+
+       err = platform_device_add(pdev);
+       if (err)
+               goto err_put_pdev;
+
+       return;
+
+err_put_pdev:
+       platform_device_put(pdev);
+
+err_free_buttons:
+       kfree(p);
+}
diff --git a/target/linux/lantiq/files-3.0/arch/mips/lantiq/dev-gpio-buttons.h b/target/linux/lantiq/files-3.0/arch/mips/lantiq/dev-gpio-buttons.h
new file mode 100644 (file)
index 0000000..adb531c
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ *  Lantiq GPIO button support
+ *
+ *  Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#ifndef _LANTIQ_DEV_GPIO_BUTTONS_H
+#define _LANTIQ_DEV_GPIO_BUTTONS_H
+
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
+
+#define LTQ_KEYS_POLL_INTERVAL         20 /* msecs */
+#define LTQ_KEYS_DEBOUNCE_INTERVAL     (3 * LTQ_KEYS_POLL_INTERVAL)
+
+void ltq_register_gpio_keys_polled(int id,
+                                     unsigned poll_interval,
+                                     unsigned nbuttons,
+                                     struct gpio_keys_button *buttons);
+
+#endif /* _LANTIQ_DEV_GPIO_BUTTONS_H */
diff --git a/target/linux/lantiq/files-3.0/arch/mips/lantiq/dev-leds-gpio.c b/target/linux/lantiq/files-3.0/arch/mips/lantiq/dev-leds-gpio.c
new file mode 100644 (file)
index 0000000..8ebd054
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ *  Lantiq GPIO LED device support
+ *
+ *  Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  Parts of this file are based on Atheros' 2.6.15 BSP
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+
+#include "dev-leds-gpio.h"
+
+void __init ltq_add_device_leds_gpio(int id, unsigned num_leds,
+                                       struct gpio_led *leds)
+{
+       struct platform_device *pdev;
+       struct gpio_led_platform_data pdata;
+       struct gpio_led *p;
+       int err;
+
+       p = kmalloc(num_leds * sizeof(*p), GFP_KERNEL);
+       if (!p)
+               return;
+
+       memcpy(p, leds, num_leds * sizeof(*p));
+
+       pdev = platform_device_alloc("leds-gpio", id);
+       if (!pdev)
+               goto err_free_leds;
+
+       memset(&pdata, 0, sizeof(pdata));
+       pdata.num_leds = num_leds;
+       pdata.leds = p;
+
+       err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
+       if (err)
+               goto err_put_pdev;
+
+       err = platform_device_add(pdev);
+       if (err)
+               goto err_put_pdev;
+
+       return;
+
+err_put_pdev:
+       platform_device_put(pdev);
+
+err_free_leds:
+       kfree(p);
+}
diff --git a/target/linux/lantiq/files-3.0/arch/mips/lantiq/falcon/addon-easy98000.c b/target/linux/lantiq/files-3.0/arch/mips/lantiq/falcon/addon-easy98000.c
new file mode 100644 (file)
index 0000000..2085a1c
--- /dev/null
@@ -0,0 +1,212 @@
+/*
+ *  EASY98000 CPLD Addon driver
+ *
+ *  Copyright (C) 2011 Thomas Langer <thomas.langer@lantiq.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2  as published
+ *  by the Free Software Foundation.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/version.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+
+struct easy98000_reg_cpld {
+       u16 cmdreg1;            /* 0x1 */
+       u16 cmdreg0;            /* 0x0 */
+       u16 idreg0;             /* 0x3 */
+       u16 resreg;             /* 0x2 */
+       u16 intreg;             /* 0x5 */
+       u16 idreg1;             /* 0x4 */
+       u16 ledreg;             /* 0x7 */
+       u16 pcmconconfig;       /* 0x6 */
+       u16 res0;               /* 0x9 */
+       u16 ethledreg;          /* 0x8 */
+       u16 res1[4];            /* 0xa-0xd */
+       u16 cpld1v;             /* 0xf */
+       u16 cpld2v;             /* 0xe */
+};
+static struct easy98000_reg_cpld * const cpld =
+       (struct easy98000_reg_cpld *)(KSEG1 | 0x17c00000);
+#define cpld_r8(reg) (__raw_readw(&cpld->reg) & 0xFF)
+#define cpld_w8(val, reg) __raw_writew((val) & 0xFF, &cpld->reg)
+
+int easy98000_addon_has_dm9000(void)
+{
+       if ((cpld_r8(idreg0) & 0xF) == 1)
+               return 1;
+       return 0;
+}
+
+#if defined(CONFIG_PROC_FS)
+typedef void (*cpld_dump) (struct seq_file *s);
+struct proc_entry {
+       char *name;
+       void *callback;
+};
+
+static int cpld_proc_show ( struct seq_file *s, void *p )
+{
+       cpld_dump dump = s->private;
+
+       if ( dump != NULL )
+               dump(s);
+
+       return 0;
+}
+
+static int cpld_proc_open ( struct inode *inode, struct file *file )
+{
+       return single_open ( file, cpld_proc_show, PDE(inode)->data );
+}
+
+static void cpld_versions_get ( struct seq_file *s )
+{
+       seq_printf(s, "CPLD1: V%d\n", cpld_r8(cpld1v));
+       seq_printf(s, "CPLD2: V%d\n", cpld_r8(cpld2v));
+}
+
+static void cpld_ebu_module_get ( struct seq_file *s )
+{
+       u8 addon_id;
+
+       addon_id = cpld_r8(idreg0) & 0xF;
+       switch (addon_id) {
+       case 0xF: /* nothing connected */
+               break;
+       case 1:
+               seq_printf(s, "Ethernet Controller module (dm9000)\n");
+               break;
+       default:
+               seq_printf(s, "Unknown EBU module (EBU_ID=0x%02X)\n", addon_id);
+               break;
+       }
+}
+
+static void cpld_xmii_module_get ( struct seq_file *s )
+{
+       u8 addon_id;
+       char *mod = NULL;
+
+       addon_id = cpld_r8(idreg1) & 0xF;
+       switch (addon_id) {
+       case 0xF:
+               mod = "no module";
+               break;
+       case 0x1:
+               mod = "RGMII module";
+               break;
+       case 0x4:
+               mod = "GMII MAC Mode (XWAY TANTOS-3G)";
+               break;
+       case 0x6:
+               mod = "TMII MAC Mode (XWAY TANTOS-3G)";
+               break;
+       case 0x8:
+               mod = "GMII PHY module";
+               break;
+       case 0x9:
+               mod = "MII PHY module";
+               break;
+       case 0xA:
+               mod = "RMII PHY module";
+               break;
+       default:
+               break;
+       }
+       if (mod)
+               seq_printf(s, "%s\n", mod);
+       else
+               seq_printf(s, "unknown xMII module (xMII_ID=0x%02X)\n", addon_id);
+}
+
+static struct proc_entry proc_entries[] = {
+       {"versions",    cpld_versions_get},
+       {"ebu",         cpld_ebu_module_get},
+       {"xmii",        cpld_xmii_module_get},
+};
+
+static struct file_operations ops = {
+       .owner   = THIS_MODULE,
+       .open    = cpld_proc_open,
+       .read    = seq_read,
+       .llseek  = seq_lseek,
+       .release = single_release,
+};
+
+static void cpld_proc_entry_create(struct proc_dir_entry *parent_node,
+                                  struct proc_entry *proc_entry)
+{
+       proc_create_data ( proc_entry->name, (S_IFREG | S_IRUGO), parent_node,
+                          &ops, proc_entry->callback);
+}
+
+static int cpld_proc_install(void)
+{
+       struct proc_dir_entry *driver_proc_node;
+
+       driver_proc_node = proc_mkdir("cpld", NULL);
+       if (driver_proc_node != NULL) {
+               int i;
+               for (i = 0; i < ARRAY_SIZE(proc_entries); i++)
+                       cpld_proc_entry_create(driver_proc_node,
+                                             &proc_entries[i]);
+       } else {
+               printk("cannot create proc entry");
+               return -1;
+       }
+       return 0;
+}
+#else
+static inline int cpld_proc_install(void) {}
+#endif
+
+static int easy98000_addon_probe(struct platform_device *pdev)
+{
+       return cpld_proc_install();
+}
+
+static int easy98000_addon_remove(struct platform_device *pdev)
+{
+#if defined(CONFIG_PROC_FS)
+       char buf[64];
+       int i;
+
+       for (i = 0; i < sizeof(proc_entries) / sizeof(proc_entries[0]); i++) {
+               sprintf(buf, "cpld/%s", proc_entries[i].name);
+               remove_proc_entry(buf, 0);
+       }
+       remove_proc_entry("cpld", 0);
+#endif
+       return 0;
+}
+
+static struct platform_driver easy98000_addon_driver = {
+       .probe = easy98000_addon_probe,
+       .remove = __devexit_p(easy98000_addon_remove),
+       .driver = {
+               .name = "easy98000_addon",
+               .owner = THIS_MODULE,
+       },
+};
+
+int __init easy98000_addon_init(void)
+{
+       return platform_driver_register(&easy98000_addon_driver);
+}
+
+void __exit easy98000_addon_exit(void)
+{
+       platform_driver_unregister(&easy98000_addon_driver);
+}
+
+module_init(easy98000_addon_init);
+module_exit(easy98000_addon_exit);
diff --git a/target/linux/lantiq/files-3.0/arch/mips/lantiq/falcon/dev-leds-easy98000-cpld.c b/target/linux/lantiq/files-3.0/arch/mips/lantiq/falcon/dev-leds-easy98000-cpld.c
new file mode 100644 (file)
index 0000000..d02d261
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ *  EASY98000 CPLD LED driver
+ *
+ *  Copyright (C) 2010 Ralph Hempel <ralph.hempel@lantiq.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2  as published
+ *  by the Free Software Foundation.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/version.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/errno.h>
+#include <linux/leds.h>
+#include <linux/slab.h>
+
+#include "dev-leds-easy98000-cpld.h"
+
+const char *led_name[8] = {
+       "ge0_act",
+       "ge0_link",
+       "ge1_act",
+       "ge1_link",
+       "fe2_act",
+       "fe2_link",
+       "fe3_act",
+       "fe3_link"
+};
+
+#define cpld_base7                     ((u16 *)(KSEG1 | 0x17c0000c))
+#define cpld_base8                     ((u16 *)(KSEG1 | 0x17c00012))
+
+#define ltq_r16(reg)                   __raw_readw(reg)
+#define ltq_w16(val, reg)              __raw_writew(val, reg)
+
+struct cpld_led_dev {
+       struct led_classdev     cdev;
+       u8                      mask;
+       u16                     *base;
+};
+
+struct cpld_led_drvdata {
+       struct cpld_led_dev     *led_devs;
+       int                     num_leds;
+};
+
+void led_set(u8 mask, u16 *base)
+{
+       ltq_w16(ltq_r16(base) | mask, base);
+}
+
+void led_clear(u8 mask, u16 *base)
+{
+       ltq_w16(ltq_r16(base) & (~mask), base);
+}
+
+void led_blink_clear(u8 mask, u16 *base)
+{
+       led_clear(mask, base);
+}
+
+static void led_brightness(struct led_classdev *led_cdev,
+                              enum led_brightness value)
+{
+       struct cpld_led_dev *led_dev =
+           container_of(led_cdev, struct cpld_led_dev, cdev);
+
+       if (value)
+               led_set(led_dev->mask, led_dev->base);
+       else
+               led_clear(led_dev->mask, led_dev->base);
+}
+
+static int led_probe(struct platform_device *pdev)
+{
+       int i;
+       char name[32];
+       struct cpld_led_drvdata *drvdata;
+       int ret = 0;
+
+       drvdata = kzalloc(sizeof(struct cpld_led_drvdata) +
+                         sizeof(struct cpld_led_dev) * MAX_LED,
+                         GFP_KERNEL);
+       if (!drvdata)
+               return -ENOMEM;
+
+       drvdata->led_devs = (struct cpld_led_dev *) &drvdata[1];
+
+       for (i = 0; i < MAX_LED; i++) {
+               struct cpld_led_dev *led_dev = &drvdata->led_devs[i];
+               led_dev->cdev.brightness_set = led_brightness;
+               led_dev->cdev.default_trigger = NULL;
+               led_dev->mask = 1 << (i % 8);
+               if(i < 8) {
+                       sprintf(name, "easy98000-cpld:%s", led_name[i]);
+                       led_dev->base = cpld_base8;
+               } else {
+                       sprintf(name, "easy98000-cpld:red:%d", i-8);
+                       led_dev->base = cpld_base7;
+               }
+               led_dev->cdev.name = name;
+               ret = led_classdev_register(&pdev->dev, &led_dev->cdev);
+               if (ret)
+                       goto err;
+       }
+       platform_set_drvdata(pdev, drvdata);
+       return 0;
+
+err:
+       printk("led_probe: 3\n");
+       for (i = i - 1; i >= 0; i--)
+               led_classdev_unregister(&drvdata->led_devs[i].cdev);
+
+       kfree(drvdata);
+       return ret;
+}
+
+static int led_remove(struct platform_device *pdev)
+{
+       int i;
+       struct cpld_led_drvdata *drvdata = platform_get_drvdata(pdev);
+       for (i = 0; i < MAX_LED; i++)
+               led_classdev_unregister(&drvdata->led_devs[i].cdev);
+       kfree(drvdata);
+       return 0;
+}
+
+static struct platform_driver led_driver = {
+       .probe = led_probe,
+       .remove = __devexit_p(led_remove),
+       .driver = {
+                  .name = LED_NAME,
+                  .owner = THIS_MODULE,
+                  },
+};
+
+int __init easy98000_cpld_led_init(void)
+{
+       pr_info(LED_DESC ", Version " LED_VERSION
+               " (c) Copyright 2011, Lantiq Deutschland GmbH\n");
+       return platform_driver_register(&led_driver);
+}
+
+void __exit easy98000_cpld_led_exit(void)
+{
+       platform_driver_unregister(&led_driver);
+}
+
+module_init(easy98000_cpld_led_init);
+module_exit(easy98000_cpld_led_exit);
+
+MODULE_DESCRIPTION(LED_NAME);
+MODULE_DESCRIPTION(LED_DESC);
+MODULE_AUTHOR("Ralph Hempel <ralph.hempel@lantiq.com>");
+MODULE_LICENSE("GPL v2");
+
diff --git a/target/linux/lantiq/files-3.0/arch/mips/lantiq/falcon/dev-leds-easy98000-cpld.h b/target/linux/lantiq/files-3.0/arch/mips/lantiq/falcon/dev-leds-easy98000-cpld.h
new file mode 100644 (file)
index 0000000..3160189
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ *  EASY98000 CPLD LED driver
+ *
+ *  Copyright (C) 2010 Ralph Hempel <ralph.hempel@lantiq.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2  as published
+ *  by the Free Software Foundation.
+ *
+ */
+#ifndef _INCLUDE_EASY98000_CPLD_LED_H_
+#define _INCLUDE_EASY98000_CPLD_LED_H_
+
+#define LED_NAME       "easy98000_cpld_led"
+#define LED_DESC       "EASY98000 LED driver"
+#define LED_VERSION    "1.0.0"
+
+#define MAX_LED                16
+
+#endif /* _INCLUDE_EASY98000_CPLD_LED_H_ */
diff --git a/target/linux/lantiq/files-3.0/arch/mips/lantiq/falcon/mach-95C3AM1.c b/target/linux/lantiq/files-3.0/arch/mips/lantiq/falcon/mach-95C3AM1.c
new file mode 100644 (file)
index 0000000..f2e91c1
--- /dev/null
@@ -0,0 +1,95 @@
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/i2c-gpio.h>
+#include "../machtypes.h"
+
+#include "devices.h"
+#include "dev-leds-gpio.h"
+
+#define BOARD_95C3AM1_GPIO_LED_0 10
+#define BOARD_95C3AM1_GPIO_LED_1 11
+#define BOARD_95C3AM1_GPIO_LED_2 12
+#define BOARD_95C3AM1_GPIO_LED_3 13
+
+extern unsigned char ltq_ethaddr[6];
+
+static struct mtd_partition board_95C3AM1_partitions[] =
+{
+       {
+               .name   = "uboot",
+               .offset = 0x0,
+               .size   = 0x40000,
+       },
+       {
+               .name   = "uboot_env",
+               .offset = 0x40000,
+               .size   = 0x40000,      /* 2 sectors for redundant env. */
+       },
+       {
+               .name   = "linux",
+               .offset = 0x80000,
+               .size   = 0xF80000,     /* map only 16 MiB */
+       },
+};
+
+static struct flash_platform_data board_95C3AM1_flash_platform_data = {
+       .name = "sflash",
+       .parts = board_95C3AM1_partitions,
+       .nr_parts = ARRAY_SIZE(board_95C3AM1_partitions)
+};
+
+static struct spi_board_info board_95C3AM1_flash_data __initdata = {
+       .modalias               = "m25p80",
+       .bus_num                = 0,
+       .chip_select            = 0,
+       .max_speed_hz           = 10 * 1000 * 1000,
+       .mode                   = SPI_MODE_3,
+       .platform_data          = &board_95C3AM1_flash_platform_data
+};
+
+static struct gpio_led board_95C3AM1_leds_gpio[] __initdata = {
+       {
+               .name           = "power",
+               .gpio           = BOARD_95C3AM1_GPIO_LED_0,
+               .active_low     = 0,
+       }, {
+               .name           = "optical",
+               .gpio           = BOARD_95C3AM1_GPIO_LED_1,
+               .active_low     = 0,
+       }, {
+               .name           = "lan",
+               .gpio           = BOARD_95C3AM1_GPIO_LED_2,
+               .active_low     = 0,
+       }, {
+               .name           = "update",
+               .gpio           = BOARD_95C3AM1_GPIO_LED_3,
+               .active_low     = 0,
+       }
+};
+
+static struct i2c_gpio_platform_data board_95C3AM1_i2c_gpio_data = {
+       .sda_pin        = 107,
+       .scl_pin        = 108,
+};
+
+static struct platform_device board_95C3AM1_i2c_gpio_device = {
+       .name           = "i2c-gpio",
+       .id             = 0,
+       .dev = {
+               .platform_data  = &board_95C3AM1_i2c_gpio_data,
+       }
+};
+
+static void __init board_95C3AM1_init(void)
+{
+       falcon_register_i2c();
+       falcon_register_spi_flash(&board_95C3AM1_flash_data);
+       platform_device_register(&board_95C3AM1_i2c_gpio_device);
+       ltq_add_device_leds_gpio(-1, ARRAY_SIZE(board_95C3AM1_leds_gpio),
+                                               board_95C3AM1_leds_gpio);
+}
+
+MIPS_MACHINE(LANTIQ_MACH_95C3AM1,
+                       "95C3AM1",
+                       "95C3AM1 Board",
+                       board_95C3AM1_init);
diff --git a/target/linux/lantiq/files-3.0/arch/mips/lantiq/falcon/mach-easy98020.c b/target/linux/lantiq/files-3.0/arch/mips/lantiq/falcon/mach-easy98020.c
new file mode 100644 (file)
index 0000000..30e24de
--- /dev/null
@@ -0,0 +1,119 @@
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/leds.h>
+#include <linux/gpio.h>
+#include <linux/gpio_buttons.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+
+#include "../machtypes.h"
+#include "devices.h"
+#include "dev-leds-gpio.h"
+
+#define EASY98020_GPIO_LED_0 9
+#define EASY98020_GPIO_LED_1 10
+#define EASY98020_GPIO_LED_2 11
+#define EASY98020_GPIO_LED_3 12
+#define EASY98020_GPIO_LED_GE0_ACT 110
+#define EASY98020_GPIO_LED_GE0_LINK 109
+#define EASY98020_GPIO_LED_GE1_ACT 106
+#define EASY98020_GPIO_LED_GE1_LINK 105
+
+extern unsigned char ltq_ethaddr[6];
+
+static struct mtd_partition easy98020_spi_partitions[] =
+{
+       {
+               .name   = "uboot",
+               .offset = 0x0,
+               .size   = 0x40000,
+       },
+       {
+               .name   = "uboot_env",
+               .offset = 0x40000,
+               .size   = 0x40000,      /* 2 sectors for redundant env. */
+       },
+       {
+               .name   = "linux",
+               .offset = 0x80000,
+               .size   = 0xF80000,     /* map only 16 MiB */
+       },
+};
+
+static struct flash_platform_data easy98020_spi_flash_platform_data = {
+       .name = "sflash",
+       .parts = easy98020_spi_partitions,
+       .nr_parts = ARRAY_SIZE(easy98020_spi_partitions)
+};
+
+static struct spi_board_info easy98020_spi_flash_data __initdata = {
+       .modalias               = "m25p80",
+       .bus_num                = 0,
+       .chip_select            = 0,
+       .max_speed_hz           = 10 * 1000 * 1000,
+       .mode                   = SPI_MODE_3,
+       .platform_data          = &easy98020_spi_flash_platform_data
+};
+
+static struct gpio_led easy98020_leds_gpio[] __initdata = {
+       {
+               .name           = "easy98020:green:0",
+               .gpio           = EASY98020_GPIO_LED_0,
+               .active_low     = 0,
+       }, {
+               .name           = "easy98020:green:1",
+               .gpio           = EASY98020_GPIO_LED_1,
+               .active_low     = 0,
+       }, {
+               .name           = "easy98020:green:2",
+               .gpio           = EASY98020_GPIO_LED_2,
+               .active_low     = 0,
+       }, {
+               .name           = "easy98020:green:3",
+               .gpio           = EASY98020_GPIO_LED_3,
+               .active_low     = 0,
+       }, {
+               .name           = "easy98020:ge0_act",
+               .gpio           = EASY98020_GPIO_LED_GE0_ACT,
+               .active_low     = 0,
+       }, {
+               .name           = "easy98020:ge0_link",
+               .gpio           = EASY98020_GPIO_LED_GE0_LINK,
+               .active_low     = 0,
+       }, {
+               .name           = "easy98020:ge1_act",
+               .gpio           = EASY98020_GPIO_LED_GE1_ACT,
+               .active_low     = 0,
+       }, {
+               .name           = "easy98020:ge1_link",
+               .gpio           = EASY98020_GPIO_LED_GE1_LINK,
+               .active_low     = 0,
+       }
+};
+
+static void __init easy98020_init(void)
+{
+       falcon_register_i2c();
+       falcon_register_spi_flash(&easy98020_spi_flash_data);
+       ltq_add_device_leds_gpio(-1, ARRAY_SIZE(easy98020_leds_gpio),
+                                       easy98020_leds_gpio);
+}
+
+MIPS_MACHINE(LANTIQ_MACH_EASY98020,
+                       "EASY98020",
+                       "EASY98020 Eval Board",
+                       easy98020_init);
+
+MIPS_MACHINE(LANTIQ_MACH_EASY98020_1LAN,
+                       "EASY98020_1LAN",
+                       "EASY98020 Eval Board (1 LAN port)",
+                       easy98020_init);
+
+MIPS_MACHINE(LANTIQ_MACH_EASY98020_2LAN,
+                       "EASY98020_2LAN",
+                       "EASY98020 Eval Board (2 LAN ports)",
+                       easy98020_init);
diff --git a/target/linux/lantiq/files-3.0/arch/mips/lantiq/xway/dev-dwc_otg.c b/target/linux/lantiq/files-3.0/arch/mips/lantiq/xway/dev-dwc_otg.c
new file mode 100644 (file)
index 0000000..90b63fc
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/mtd/physmap.h>
+#include <linux/kernel.h>
+#include <linux/reboot.h>
+#include <linux/platform_device.h>
+#include <linux/leds.h>
+#include <linux/etherdevice.h>
+#include <linux/reboot.h>
+#include <linux/time.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/leds.h>
+
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+
+#include <lantiq_soc.h>
+#include <lantiq_irq.h>
+#include <lantiq_platform.h>
+
+#define LTQ_USB_IOMEM_BASE 0x1e101000
+#define LTQ_USB_IOMEM_SIZE 0x00001000
+
+static struct resource resources[] =
+{
+       [0] = {
+               .name    = "dwc_otg_membase",
+               .start   = LTQ_USB_IOMEM_BASE,
+               .end     = LTQ_USB_IOMEM_BASE + LTQ_USB_IOMEM_SIZE - 1,
+               .flags   = IORESOURCE_MEM,
+       },
+       [1] = {
+               .name    = "dwc_otg_irq",
+               .start   = LTQ_USB_INT,
+               .flags   = IORESOURCE_IRQ,
+       },
+};
+
+static u64 dwc_dmamask = (u32)0x1fffffff;
+
+static struct platform_device platform_dev = {
+       .name = "dwc_otg",
+       .dev = {
+               .dma_mask      = &dwc_dmamask,
+       },
+       .resource               = resources,
+       .num_resources          = ARRAY_SIZE(resources),
+};
+
+int __init
+xway_register_dwc(int pin)
+{
+       struct irq_data d;
+       d.irq = resources[1].start;
+       ltq_enable_irq(&d);
+       platform_dev.dev.platform_data = (void*) pin;
+       return platform_device_register(&platform_dev);
+}
diff --git a/target/linux/lantiq/files-3.0/arch/mips/lantiq/xway/dev-dwc_otg.h b/target/linux/lantiq/files-3.0/arch/mips/lantiq/xway/dev-dwc_otg.h
new file mode 100644 (file)
index 0000000..521fad0
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#ifndef _LTQ_DEV_DWC_H__
+#define _LTQ_DEV_DWC_H__
+
+#include <lantiq_platform.h>
+
+extern void __init xway_register_dwc(int pin);
+
+#endif
diff --git a/target/linux/lantiq/files-3.0/arch/mips/lantiq/xway/mach-arv45xx.c b/target/linux/lantiq/files-3.0/arch/mips/lantiq/xway/mach-arv45xx.c
new file mode 100644 (file)
index 0000000..7cd2bd8
--- /dev/null
@@ -0,0 +1,495 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/leds.h>
+#include <linux/gpio.h>
+#include <linux/gpio_buttons.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/input.h>
+#include <linux/etherdevice.h>
+#include <linux/ath5k_platform.h>
+#include <linux/pci.h>
+
+#include <lantiq_soc.h>
+#include <lantiq_platform.h>
+
+#include "../machtypes.h"
+#include "../dev-leds-gpio.h"
+#include "devices.h"
+#include "dev-dwc_otg.h"
+
+static struct mtd_partition arv4510_partitions[] =
+{
+       {
+               .name   = "uboot",
+               .offset = 0x0,
+               .size   = 0x20000,
+       },
+       {
+               .name   = "uboot_env",
+               .offset = 0x20000,
+               .size   = 0x120000,
+       },
+       {
+               .name   = "linux",
+               .offset = 0x40000,
+               .size   = 0xfa0000,
+       },
+       {
+               .name   = "board_config",
+               .offset = 0xfe0000,
+               .size   = 0x20000,
+       },
+};
+
+static struct mtd_partition arv45xx_partitions[] =
+{
+       {
+               .name   = "uboot",
+               .offset = 0x0,
+               .size   = 0x20000,
+       },
+       {
+               .name   = "uboot_env",
+               .offset = 0x20000,
+               .size   = 0x10000,
+       },
+       {
+               .name   = "linux",
+               .offset = 0x30000,
+               .size   = 0x3c0000,
+       },
+       {
+               .name   = "board_config",
+               .offset = 0x3f0000,
+               .size   = 0x10000,
+       },
+};
+
+static struct mtd_partition arv75xx_partitions[] =
+{
+       {
+               .name   = "uboot",
+               .offset = 0x0,
+               .size   = 0x10000,
+       },
+       {
+               .name   = "uboot_env",
+               .offset = 0x10000,
+               .size   = 0x10000,
+       },
+       {
+               .name   = "linux",
+               .offset = 0x20000,
+               .size   = 0x7d0000,
+       },
+       {
+               .name   = "board_config",
+               .offset = 0x7f0000,
+               .size   = 0x10000,
+       },
+};
+
+static struct physmap_flash_data arv4510_flash_data = {
+       .nr_parts       = ARRAY_SIZE(arv4510_partitions),
+       .parts          = arv4510_partitions,
+};
+
+static struct physmap_flash_data arv45xx_flash_data = {
+       .nr_parts       = ARRAY_SIZE(arv45xx_partitions),
+       .parts          = arv45xx_partitions,
+};
+
+static struct physmap_flash_data arv75xx_flash_data = {
+       .nr_parts       = ARRAY_SIZE(arv75xx_partitions),
+       .parts          = arv75xx_partitions,
+};
+
+static struct ltq_pci_data ltq_pci_data = {
+       .clock  = PCI_CLOCK_EXT,
+       .gpio   = PCI_GNT1 | PCI_REQ1,
+       .irq    = {
+               [14] = INT_NUM_IM0_IRL0 + 22,
+       },
+};
+
+static struct ltq_eth_data ltq_eth_data = {
+       .mii_mode       = PHY_INTERFACE_MODE_RMII,
+};
+
+static struct gpio_led
+arv4510pw_leds_gpio[] __initdata = {
+       { .name = "soc:green:foo", .gpio = 4, .active_low = 1, },
+};
+
+static struct gpio_led
+arv4518pw_leds_gpio[] __initdata = {
+       { .name = "soc:green:power", .gpio = 3, .active_low = 1, .default_trigger = "default-on" },
+       { .name = "soc:green:adsl", .gpio = 4, .active_low = 1, .default_trigger = "default-on" },
+       { .name = "soc:green:internet", .gpio = 5, .active_low = 1, .default_trigger = "default-on" },
+       { .name = "soc:green:wlan", .gpio = 6, .active_low = 1, .default_trigger = "default-on" },
+       { .name = "soc:yellow:wps", .gpio = 7, .active_low = 1, .default_trigger = "default-on" },
+       { .name = "soc:red:fail", .gpio = 8, .active_low = 1, .default_trigger = "default-on" },
+       { .name = "soc:green:usb", .gpio = 19, .active_low = 1, .default_trigger = "default-on" },
+       { .name = "soc:green:voip", .gpio = 100, .active_low = 1, .default_trigger = "default-on" },
+       { .name = "soc:green:fxs1", .gpio = 101, .active_low = 1, .default_trigger = "default-on" },
+       { .name = "soc:green:fxs2", .gpio = 102, .active_low = 1, .default_trigger = "default-on" },
+       { .name = "soc:green:fxo", .gpio = 103, .active_low = 1, .default_trigger = "default-on" },
+};
+
+static struct gpio_button
+arv4518pw_gpio_buttons[] __initdata = {
+       { .desc = "wlan", .type = EV_KEY, .code = BTN_0, .threshold = 3, .gpio = 28, .active_low = 1, },
+       { .desc = "wps", .type = EV_KEY, .code = BTN_1, .threshold = 3, .gpio = 29, .active_low = 1, },
+       { .desc = "reset", .type = EV_KEY, .code = BTN_2, .threshold = 3, .gpio = 30, .active_low = 1, },
+};
+
+static struct gpio_led
+arv4520pw_leds_gpio[] __initdata = {
+       { .name = "soc:blue:power", .gpio = 3, .active_low = 1, },
+       { .name = "soc:blue:adsl", .gpio = 4, .active_low = 1, },
+       { .name = "soc:blue:internet", .gpio = 5, .active_low = 1, },
+       { .name = "soc:red:power", .gpio = 6, .active_low = 1, },
+       { .name = "soc:yellow:wps", .gpio = 7, .active_low = 1, },
+       { .name = "soc:red:wps", .gpio = 9, .active_low = 1, },
+       { .name = "soc:blue:voip", .gpio = 100, .active_low = 1, },
+       { .name = "soc:blue:fxs1", .gpio = 101, .active_low = 1, },
+       { .name = "soc:blue:fxs2", .gpio = 102, .active_low = 1, },
+       { .name = "soc:blue:fxo", .gpio = 103, .active_low = 1, },
+       { .name = "soc:blue:voice", .gpio = 104, .active_low = 1, },
+       { .name = "soc:blue:usb", .gpio = 105, .active_low = 1, },
+       { .name = "soc:blue:wlan", .gpio = 106, .active_low = 1, },
+};
+
+static struct gpio_led
+arv452cpw_leds_gpio[] __initdata = {
+       { .name = "soc:blue:power", .gpio = 3, .active_low = 1, .default_trigger = "default-on" },
+       { .name = "soc:blue:adsl", .gpio = 4, .active_low = 1, .default_trigger = "default-on" },
+       { .name = "soc:blue:isdn", .gpio = 5, .active_low = 1, .default_trigger = "default-on" },
+       { .name = "soc:red:power", .gpio = 6, .active_low = 1, .default_trigger = "default-on" },
+       { .name = "soc:yellow:wps", .gpio = 7, .active_low = 1, .default_trigger = "default-on" },
+       { .name = "soc:red:wps", .gpio = 9, .active_low = 1, .default_trigger = "default-on" },
+       { .name = "soc:blue:fxs1", .gpio = 100, .active_low = 1, .default_trigger = "default-on" },
+       { .name = "soc:blue:fxs2", .gpio = 101, .active_low = 1, .default_trigger = "default-on" },
+       { .name = "soc:blue:wps", .gpio = 102, .active_low = 1, .default_trigger = "default-on" },
+       { .name = "soc:blue:fxo", .gpio = 103, .active_low = 1, .default_trigger = "default-on" },
+       { .name = "soc:blue:voice", .gpio = 104, .active_low = 1, .default_trigger = "default-on" },
+       { .name = "soc:blue:usb", .gpio = 105, .active_low = 1, .default_trigger = "default-on" },
+       { .name = "soc:blue:wlan", .gpio = 106, .active_low = 1, .default_trigger = "default-on" },
+       { .name = "soc:blue:internet", .gpio = 108, .active_low = 1, .default_trigger = "default-on" },
+       { .name = "soc:red:internet", .gpio = 109, .active_low = 1, .default_trigger = "default-on" },
+};
+
+static struct gpio_led
+arv4525pw_leds_gpio[] __initdata = {
+       { .name = "soc:green:festnetz", .gpio = 4, .active_low = 1, .default_trigger = "default-on" },
+       { .name = "soc:green:internet", .gpio = 5, .active_low = 1, .default_trigger = "default-on" },
+       { .name = "soc:green:dsl", .gpio = 6, .active_low = 1, .default_trigger = "default-on" },
+       { .name = "soc:green:wlan", .gpio = 8, .active_low = 1, .default_trigger = "default-on" },
+       { .name = "soc:green:online", .gpio = 9, .active_low = 1, .default_trigger = "default-on" },
+};
+
+static struct gpio_led
+arv752dpw22_leds_gpio[] __initdata = {
+       { .name = "soc:blue:power", .gpio = 3, .active_low = 1, .default_trigger = "default-on" },
+       { .name = "soc:red:internet", .gpio = 5, .active_low = 1, .default_trigger = "default-on" },
+       { .name = "soc:red:power", .gpio = 6, .active_low = 1, .default_trigger = "default-on" },
+       { .name = "soc:red:wps", .gpio = 8, .active_low = 1, .default_trigger = "default-on" },
+       { .name = "soc:red:fxo", .gpio = 103, .active_low = 1, .default_trigger = "default-on" },
+       { .name = "soc:red:voice", .gpio = 104, .active_low = 1, .default_trigger = "default-on" },
+       { .name = "soc:green:usb", .gpio = 105, .active_low = 1, .default_trigger = "default-on" },
+       { .name = "soc:green:wlan", .gpio = 106, .active_low = 1, .default_trigger = "default-on" },
+       { .name = "soc:green:wlan1", .gpio = 107, .active_low = 1, .default_trigger = "default-on" },
+       { .name = "soc:blue:wlan", .gpio = 108, .active_low = 1, .default_trigger = "default-on" },
+       { .name = "soc:blue:wlan1", .gpio = 109, .active_low = 1, .default_trigger = "default-on" },
+       { .name = "soc:green:eth1", .gpio = 111, .active_low = 1, .default_trigger = "default-on" },
+       { .name = "soc:green:eth2", .gpio = 112, .active_low = 1, .default_trigger = "default-on" },
+       { .name = "soc:green:eth3", .gpio = 113, .active_low = 1, .default_trigger = "default-on" },
+       { .name = "soc:green:eth4", .gpio = 114, .active_low = 1, .default_trigger = "default-on", },
+};
+
+static struct gpio_button
+arv752dpw22_gpio_buttons[] __initdata = {
+       { .desc = "btn0", .type = EV_KEY, .code = BTN_0, .threshold = 3, .gpio = 12, .active_low = 1, },
+       { .desc = "btn1", .type = EV_KEY, .code = BTN_1, .threshold = 3, .gpio = 13, .active_low = 1, },
+       { .desc = "btn2", .type = EV_KEY, .code = BTN_2, .threshold = 3, .gpio = 28, .active_low = 1, },
+};
+
+static struct gpio_led
+arv7518pw_leds_gpio[] __initdata = {
+       { .name = "soc:green:power", .gpio = 2, .active_low = 1, },
+       { .name = "soc:green:adsl", .gpio = 4, .active_low = 1, },
+       { .name = "soc:green:internet", .gpio = 5, .active_low = 1, },
+       { .name = "soc:green:wlan", .gpio = 6, .active_low = 1, },
+       { .name = "soc:red:internet", .gpio = 8, .active_low = 1, },
+       { .name = "soc:green:usb", .gpio = 19, .active_low = 1, },
+};
+
+static struct gpio_button
+arv7518pw_gpio_buttons[] __initdata = {
+       { .desc = "reset", .type = EV_KEY, .code = BTN_0, .threshold = 3, .gpio = 23, .active_low = 1, },
+       { .desc = "wlan", .type = EV_KEY, .code = BTN_1, .threshold = 3, .gpio = 25, .active_low = 1, },
+};
+
+static void
+arv45xx_register_ethernet(void)
+{
+#define ARV45XX_BRN_MAC                        0x3f0016
+       memcpy_fromio(&ltq_eth_data.mac.sa_data,
+               (void *)KSEG1ADDR(LTQ_FLASH_START + ARV45XX_BRN_MAC), 6);
+       ltq_register_etop(&ltq_eth_data);
+}
+
+static void
+arv75xx_register_ethernet(void)
+{
+#define ARV75XX_BRN_MAC                        0x7f0016
+       memcpy_fromio(&ltq_eth_data.mac.sa_data,
+               (void *)KSEG1ADDR(LTQ_FLASH_START + ARV75XX_BRN_MAC), 6);
+       ltq_register_etop(&ltq_eth_data);
+}
+
+static void
+bewan_register_ethernet(void)
+{
+#define BEWAN_BRN_MAC                  0x3f0014
+       memcpy_fromio(&ltq_eth_data.mac.sa_data,
+               (void *)KSEG1ADDR(LTQ_FLASH_START + BEWAN_BRN_MAC), 6);
+       ltq_register_etop(&ltq_eth_data);
+}
+
+static u16 arv45xx_ath5k_eeprom_data[ATH5K_PLAT_EEP_MAX_WORDS];
+static struct ath5k_platform_data arv45xx_ath5k_platform_data;
+
+/*static int arv45xx_pci_plat_dev_init(struct pci_dev *dev)
+{
+       dev->dev.platform_data = &arv45xx_ath5k_platform_data;
+       return 0;
+}
+*/
+void __init
+arv45xx_register_ath5k(void)
+{
+#define ARV45XX_BRN_ATH                0x3f0478
+       int i;
+       unsigned char eeprom_mac[6];
+       static u16 eeprom_data[ATH5K_PLAT_EEP_MAX_WORDS];
+       u32 *p = (u32*)arv45xx_ath5k_eeprom_data;
+
+       memcpy_fromio(eeprom_mac,
+               (void *)KSEG1ADDR(LTQ_FLASH_START + ARV45XX_BRN_MAC), 6);
+       eeprom_mac[5]++;
+       memcpy_fromio(arv45xx_ath5k_eeprom_data,
+               (void *)KSEG1ADDR(LTQ_FLASH_START + ARV45XX_BRN_ATH), ATH5K_PLAT_EEP_MAX_WORDS);
+       // swap eeprom bytes
+       for (i = 0; i < ATH5K_PLAT_EEP_MAX_WORDS>>1; i++){
+               //arv4518_ath5k_eeprom_data[i] = ((eeprom_data[i]&0xff)<<8)|((eeprom_data[i]&0xff00)>>8);
+               p[i] = ((eeprom_data[(i<<1)+1]&0xff)<<24)|((eeprom_data[(i<<1)+1]&0xff00)<<8)|((eeprom_data[i<<1]&0xff)<<8)|((eeprom_data[i<<1]&0xff00)>>8);
+               if (i == 0xbf>>1){
+                       // printk ("regdomain: 0x%x --> 0x%x\n", p[i], (p[i] & 0xffff0000)|0x67);
+                       /* regdomain is invalid?? how did original fw convert 
+                       * value to 0x82d4 ??
+                       * for now, force to 0x67 */
+                       p[i] &= 0xffff0000;
+                       p[i] |= 0x67;
+               }
+       }
+       arv45xx_ath5k_platform_data.eeprom_data = arv45xx_ath5k_eeprom_data;
+       arv45xx_ath5k_platform_data.macaddr = eeprom_mac;
+       //lqpci_plat_dev_init = arv45xx_pci_plat_dev_init;
+}
+
+static void __init
+arv3527p_init(void)
+{
+       ltq_register_gpio_stp();
+       //ltq_add_device_leds_gpio(arv3527p_leds_gpio, ARRAY_SIZE(arv3527p_leds_gpio));
+       ltq_register_nor(&arv45xx_flash_data);
+       arv45xx_register_ethernet();
+}
+
+MIPS_MACHINE(LANTIQ_MACH_ARV3527P,
+                       "ARV3527P",
+                       "ARV3527P - Arcor Easybox 401",
+                       arv3527p_init);
+
+static void __init
+arv4510pw_init(void)
+{
+       ltq_register_gpio_stp();
+       ltq_add_device_leds_gpio(-1, ARRAY_SIZE(arv4510pw_leds_gpio), arv4510pw_leds_gpio);
+       ltq_register_nor(&arv4510_flash_data);
+       ltq_pci_data.irq[12] = (INT_NUM_IM2_IRL0 + 31);
+       ltq_pci_data.irq[15] = (INT_NUM_IM0_IRL0 + 26);
+       ltq_pci_data.gpio |= PCI_EXIN2 | PCI_REQ2;
+       ltq_register_pci(&ltq_pci_data);
+       bewan_register_ethernet();
+}
+
+MIPS_MACHINE(LANTIQ_MACH_ARV4510PW,
+                       "ARV4510PW",
+                       "ARV4510PW - Wippies Homebox",
+                       arv4510pw_init);
+
+static void __init
+arv4518pw_init(void)
+{
+#define ARV4518PW_EBU                  0
+#define ARV4518PW_USB                  14
+#define ARV4518PW_SWITCH_RESET         13
+
+       ltq_register_gpio_ebu(ARV4518PW_EBU);
+       ltq_add_device_leds_gpio(-1, ARRAY_SIZE(arv4518pw_leds_gpio), arv4518pw_leds_gpio);
+       ltq_register_gpio_buttons(arv4518pw_gpio_buttons, ARRAY_SIZE(arv4518pw_gpio_buttons));
+       ltq_register_nor(&arv45xx_flash_data);
+       ltq_pci_data.gpio = PCI_GNT2 | PCI_REQ2;
+       ltq_register_pci(&ltq_pci_data);
+       ltq_register_madwifi_eep();
+       xway_register_dwc(ARV4518PW_USB);
+       arv45xx_register_ethernet();
+       arv45xx_register_ath5k();
+
+       gpio_request(ARV4518PW_SWITCH_RESET, "switch");
+       gpio_direction_output(ARV4518PW_SWITCH_RESET, 1);
+       gpio_export(ARV4518PW_SWITCH_RESET, 0);
+}
+
+MIPS_MACHINE(LANTIQ_MACH_ARV4518PW,
+                       "ARV4518PW",
+                       "ARV4518PW - SMC7908A-ISP, Airties WAV-221",
+                       arv4518pw_init);
+
+static void __init
+arv4520pw_init(void)
+{
+#define ARV4520PW_EBU                  0x400
+#define ARV4520PW_USB                  28
+#define ARV4520PW_SWITCH_RESET         110
+
+       ltq_register_gpio_ebu(ARV4520PW_EBU);
+       ltq_add_device_leds_gpio(-1, ARRAY_SIZE(arv4520pw_leds_gpio), arv4520pw_leds_gpio);
+       ltq_register_nor(&arv45xx_flash_data);
+       ltq_register_pci(&ltq_pci_data);
+       ltq_register_tapi();
+       arv45xx_register_ethernet();
+       xway_register_dwc(ARV4520PW_USB);
+
+       gpio_request(ARV4520PW_SWITCH_RESET, "switch");
+       gpio_set_value(ARV4520PW_SWITCH_RESET, 1);
+}
+
+MIPS_MACHINE(LANTIQ_MACH_ARV4520PW,
+                       "ARV4520PW",
+                       "ARV4520PW - Airties WAV-281, Arcor A800",
+                       arv4520pw_init);
+
+static void __init
+arv452Cpw_init(void)
+{
+#define ARV452CPW_EBU                  0x77f
+#define ARV452CPW_USB                  28
+#define ARV452CPW_RELAY1               31
+#define ARV452CPW_RELAY2               107
+#define ARV452CPW_SWITCH_RESET         110
+
+       ltq_register_gpio_ebu(ARV452CPW_EBU);
+       ltq_add_device_leds_gpio(-1, ARRAY_SIZE(arv452cpw_leds_gpio), arv452cpw_leds_gpio);
+       ltq_register_nor(&arv45xx_flash_data);
+       ltq_register_pci(&ltq_pci_data);
+       ltq_register_madwifi_eep();
+       xway_register_dwc(ARV452CPW_USB);
+       arv45xx_register_ethernet();
+       arv45xx_register_ath5k();
+
+       gpio_request(ARV452CPW_SWITCH_RESET, "switch");
+       gpio_set_value(ARV452CPW_SWITCH_RESET, 1);
+       gpio_export(ARV452CPW_SWITCH_RESET, 0);
+
+       gpio_request(ARV452CPW_RELAY1, "relay1");
+       gpio_direction_output(ARV452CPW_RELAY1, 1);
+       gpio_export(ARV452CPW_RELAY1, 0);
+
+       gpio_request(ARV452CPW_RELAY2, "relay2");
+       gpio_set_value(ARV452CPW_RELAY2, 1);
+       gpio_export(ARV452CPW_RELAY2, 0);
+}
+
+MIPS_MACHINE(LANTIQ_MACH_ARV452CPW,
+                       "ARV452CPW",
+                       "ARV452CPW - Arcor A801",
+                       arv452Cpw_init);
+
+static void __init
+arv4525pw_init(void)
+{
+       ltq_add_device_leds_gpio(-1, ARRAY_SIZE(arv4525pw_leds_gpio), arv4525pw_leds_gpio);
+       ltq_register_nor(&arv45xx_flash_data);
+       ltq_pci_data.clock = PCI_CLOCK_INT;
+       ltq_register_pci(&ltq_pci_data);
+       ltq_register_madwifi_eep();
+       ltq_eth_data.mii_mode = PHY_INTERFACE_MODE_MII;
+       arv45xx_register_ethernet();
+}
+
+MIPS_MACHINE(LANTIQ_MACH_ARV4525PW,
+                       "ARV4525PW",
+                       "ARV4525PW - Speedport W502V",
+                       arv4525pw_init);
+
+static void __init
+arv7518pw_init(void)
+{
+#define ARV7518PW_EBU                  0x2
+#define ARV7518PW_USB                  14
+
+       ltq_register_gpio_ebu(ARV7518PW_EBU);
+       ltq_add_device_leds_gpio(-1, ARRAY_SIZE(arv7518pw_leds_gpio), arv7518pw_leds_gpio);
+       ltq_register_gpio_buttons(arv7518pw_gpio_buttons, ARRAY_SIZE(arv7518pw_gpio_buttons));
+       ltq_register_nor(&arv75xx_flash_data);
+       ltq_register_pci(&ltq_pci_data);
+       ltq_register_tapi();
+       xway_register_dwc(ARV7518PW_USB);
+       arv75xx_register_ethernet();
+       //arv7518_register_ath9k(mac);
+}
+
+MIPS_MACHINE(LANTIQ_MACH_ARV7518PW,
+                       "ARV7518PW",
+                       "ARV7518PW - ASTORIA",
+                       arv7518pw_init);
+
+static void __init
+arv752dpw22_init(void)
+{
+#define ARV752DPW22_EBU                        0x2
+#define ARV752DPW22_USB                        100
+#define ARV752DPW22_RELAY              101
+
+       ltq_register_gpio_ebu(ARV752DPW22_EBU);
+       ltq_add_device_leds_gpio(-1, ARRAY_SIZE(arv752dpw22_leds_gpio), arv752dpw22_leds_gpio);
+       ltq_register_gpio_buttons(arv752dpw22_gpio_buttons, ARRAY_SIZE(arv752dpw22_gpio_buttons));
+       ltq_register_nor(&arv75xx_flash_data);
+       ltq_pci_data.irq[15] = (INT_NUM_IM3_IRL0 + 31);
+       ltq_pci_data.gpio |= PCI_EXIN1 | PCI_REQ2;
+       ltq_register_pci(&ltq_pci_data);
+       xway_register_dwc(ARV752DPW22_USB);
+       arv75xx_register_ethernet();
+
+       gpio_request(ARV752DPW22_RELAY, "relay");
+       gpio_set_value(ARV752DPW22_RELAY, 1);
+       gpio_export(ARV752DPW22_RELAY, 0);
+}
+
+MIPS_MACHINE(LANTIQ_MACH_ARV752DPW22,
+                       "ARV752DPW22",
+                       "ARV752DPW22 - Arcor A803",
+                       arv752dpw22_init);
diff --git a/target/linux/lantiq/files-3.0/arch/mips/lantiq/xway/mach-easy50601.c b/target/linux/lantiq/files-3.0/arch/mips/lantiq/xway/mach-easy50601.c
new file mode 100644 (file)
index 0000000..a5a0105
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/input.h>
+
+#include <lantiq.h>
+
+#include "../machtypes.h"
+#include "devices.h"
+
+static struct mtd_partition easy50601_partitions[] = {
+       {
+               .name   = "uboot",
+               .offset = 0x0,
+               .size   = 0x10000,
+       },
+       {
+               .name   = "uboot_env",
+               .offset = 0x10000,
+               .size   = 0x10000,
+       },
+       {
+               .name   = "linux",
+               .offset = 0x20000,
+               .size   = 0x3d0000,
+       },
+};
+
+static struct physmap_flash_data easy50601_flash_data = {
+       .nr_parts       = ARRAY_SIZE(easy50601_partitions),
+       .parts          = easy50601_partitions,
+};
+
+static struct ltq_eth_data ltq_eth_data = {
+       .mii_mode = -1, /* use EPHY */
+};
+
+static void __init easy50601_init(void)
+{
+       ltq_register_nor(&easy50601_flash_data);
+       ltq_register_etop(&ltq_eth_data);
+}
+
+MIPS_MACHINE(LTQ_MACH_EASY50601,
+                       "EASY50601",
+                       "EASY50601 Eval Board",
+                       easy50601_init);
diff --git a/target/linux/lantiq/files-3.0/arch/mips/lantiq/xway/mach-easy50712.c b/target/linux/lantiq/files-3.0/arch/mips/lantiq/xway/mach-easy50712.c
new file mode 100644 (file)
index 0000000..2fddfca
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/input.h>
+#include <linux/phy.h>
+
+#include <lantiq_soc.h>
+#include <irq.h>
+
+#include "../machtypes.h"
+#include "devices.h"
+
+static struct mtd_partition easy50712_partitions[] = {
+       {
+               .name   = "uboot",
+               .offset = 0x0,
+               .size   = 0x10000,
+       },
+       {
+               .name   = "uboot_env",
+               .offset = 0x10000,
+               .size   = 0x10000,
+       },
+       {
+               .name   = "linux",
+               .offset = 0x20000,
+               .size   = 0x3d0000,
+       },
+};
+
+static struct physmap_flash_data easy50712_flash_data = {
+       .nr_parts       = ARRAY_SIZE(easy50712_partitions),
+       .parts          = easy50712_partitions,
+};
+
+static struct ltq_pci_data ltq_pci_data = {
+       .clock  = PCI_CLOCK_INT,
+       .gpio   = PCI_GNT1 | PCI_REQ1,
+       .irq    = {
+               [14] = INT_NUM_IM0_IRL0 + 22,
+       },
+};
+
+static struct ltq_eth_data ltq_eth_data = {
+       .mii_mode = PHY_INTERFACE_MODE_MII,
+};
+
+static void __init easy50712_init(void)
+{
+       ltq_register_gpio_stp();
+       ltq_register_nor(&easy50712_flash_data);
+       ltq_register_pci(&ltq_pci_data);
+       ltq_register_etop(&ltq_eth_data);
+       ltq_register_tapi();
+}
+
+MIPS_MACHINE(LTQ_MACH_EASY50712,
+            "EASY50712",
+            "EASY50712 Eval Board",
+             easy50712_init);
diff --git a/target/linux/lantiq/files-3.0/arch/mips/lantiq/xway/mach-fritz.c b/target/linux/lantiq/files-3.0/arch/mips/lantiq/xway/mach-fritz.c
new file mode 100644 (file)
index 0000000..9b54242
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/input.h>
+#include <linux/phy.h>
+
+#include <lantiq_soc.h>
+#include <irq.h>
+
+#include "../machtypes.h"
+#include "devices.h"
+
+/*static struct mtd_partition fritz3370_partitions[] = {
+       {
+               .name   = "uboot",
+               .offset = 0x0,
+               .size   = 0x10000,
+       },
+       {
+               .name   = "uboot_env",
+               .offset = 0x10000,
+               .size   = 0x10000,
+       },
+       {
+               .name   = "linux",
+               .offset = 0x20000,
+               .size   = 0xe0000,
+       },
+       {
+               .name   = "rootfs",
+               .offset = 0x100000,
+               .size   = 0x300000,
+       },
+};
+
+static struct physmap_flash_data fritz3370_flash_data = {
+       .nr_parts       = ARRAY_SIZE(fritz3370_partitions),
+       .parts          = fritz3370_partitions,
+};
+
+static struct ltq_pci_data ltq_pci_data = {
+       .clock  = PCI_CLOCK_INT,
+       .gpio   = PCI_GNT1 | PCI_REQ1,
+       .irq    = {
+               [14] = INT_NUM_IM0_IRL0 + 22,
+       },
+};
+*/
+static struct ltq_eth_data ltq_eth_data = {
+       .mii_mode = PHY_INTERFACE_MODE_MII,
+};
+
+extern void xway_register_nand(void);
+
+static void __init fritz3370_init(void)
+{
+//     ltq_register_gpio_stp();
+//     ltq_register_nor(&fritz3370_flash_data);
+//     ltq_register_pci(&ltq_pci_data);
+       ltq_register_etop(&ltq_eth_data);
+       xway_register_nand();
+}
+
+MIPS_MACHINE(LANTIQ_MACH_FRITZ3370,
+            "FRITZ3370",
+            "FRITZ!BOX 3370",
+             fritz3370_init);
diff --git a/target/linux/lantiq/files-3.0/arch/mips/lantiq/xway/mach-gigasx76x.c b/target/linux/lantiq/files-3.0/arch/mips/lantiq/xway/mach-gigasx76x.c
new file mode 100644 (file)
index 0000000..ab2b08c
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2011 Andrej VlaÅ¡ić
+ *  Copyright (C) 2011 Luka Perkov
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/leds.h>
+#include <linux/gpio.h>
+#include <linux/gpio_buttons.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/input.h>
+#include <linux/ath5k_platform.h>
+#include <linux/pci.h>
+#include <linux/phy.h>
+
+#include <irq.h>
+
+#include <lantiq_soc.h>
+#include <lantiq_platform.h>
+
+#include "../machtypes.h"
+#include "../dev-leds-gpio.h"
+#include "devices.h"
+#include "dev-dwc_otg.h"
+
+static struct mtd_partition gigasx76x_partitions[] =
+{
+       {
+               .name   = "secondary_env",
+               .offset = 0xe000,
+               .size   = 0x2000,
+       },
+       {
+               .name   = "secondary_boot",
+               .offset = 0x10000,
+               .size   = 0x10000,
+       },
+       {
+               .name   = "uboot",
+               .offset = 0x20000,
+               .size   = 0x30000,
+       },
+       {
+               .name   = "linux",
+               .offset = 0x50000,
+               .size   = 0x7a0000,
+       },
+       {
+               .name   = "board_config",
+               .offset = 0x7f0000,
+               .size   = 0x10000,
+       },
+};
+
+static struct gpio_led
+gigasx76x_leds_gpio[] __initdata = {
+       { .name = "soc:green:usb", .gpio = 202, },
+       { .name = "soc:green:wlan", .gpio = 203, },
+       { .name = "soc:green:phone2", .gpio = 204, },
+       { .name = "soc:green:phone1", .gpio = 205, },
+       { .name = "soc:green:line", .gpio = 206, },
+       { .name = "soc:green:online", .gpio = 207, },
+};
+
+
+static struct physmap_flash_data gigasx76x_flash_data = {
+       .nr_parts       = ARRAY_SIZE(gigasx76x_partitions),
+       .parts          = gigasx76x_partitions,
+};
+
+static struct ltq_pci_data ltq_pci_data = {
+       .clock      = PCI_CLOCK_INT,
+       .gpio   = PCI_GNT1 | PCI_REQ1,
+       .irq    = {
+               [14] = INT_NUM_IM0_IRL0 + 22,
+       },
+};
+
+static struct ltq_eth_data ltq_eth_data = {
+  .mii_mode = PHY_INTERFACE_MODE_MII,
+};
+
+static void __init
+gigasx76x_init(void)
+{
+#define GIGASX76X_USB                  29
+
+       ltq_register_gpio_stp();
+       ltq_register_nor(&gigasx76x_flash_data);
+       ltq_register_pci(&ltq_pci_data);
+       ltq_register_etop(&ltq_eth_data);
+       xway_register_dwc(GIGASX76X_USB);
+       ltq_register_tapi();
+       ltq_register_madwifi_eep();
+       ltq_add_device_leds_gpio(-1, ARRAY_SIZE(gigasx76x_leds_gpio), gigasx76x_leds_gpio);
+}
+
+MIPS_MACHINE(LANTIQ_MACH_GIGASX76X,
+                       "GIGASX76X",
+                       "GIGASX76X - Gigaset SX761,SX762,SX763",
+                       gigasx76x_init);
diff --git a/target/linux/lantiq/files-3.0/arch/mips/lantiq/xway/mach-netgear.c b/target/linux/lantiq/files-3.0/arch/mips/lantiq/xway/mach-netgear.c
new file mode 100644 (file)
index 0000000..826bfe2
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/input.h>
+#include <linux/phy.h>
+#include <linux/spi/spi.h>
+
+#include <lantiq_soc.h>
+#include <irq.h>
+
+#include "../machtypes.h"
+#include "devices.h"
+
+static struct ltq_pci_data ltq_pci_data = {
+       .clock  = PCI_CLOCK_INT,
+       .gpio   = PCI_GNT1 | PCI_REQ1,
+       .irq    = {
+               [14] = INT_NUM_IM0_IRL0 + 22,
+       },
+};
+
+static struct ltq_eth_data ltq_eth_data = {
+       .mii_mode = PHY_INTERFACE_MODE_MII,
+};
+
+struct spi_board_info spi_info = {
+       .bus_num        = 0,
+       .chip_select    = 3,
+       .max_speed_hz   = 25000000,
+       .modalias       = "mx25l12805d",
+};
+
+struct ltq_spi_platform_data ltq_spi_data = {
+       .num_chipselect = 4,
+};
+
+static void __init dgn3500_init(void)
+{
+       ltq_register_pci(&ltq_pci_data);
+       ltq_register_etop(&ltq_eth_data);
+       ltq_register_spi(&ltq_spi_data, &spi_info, 1);
+}
+
+MIPS_MACHINE(LANTIQ_MACH_DGN3500B,
+            "DGN3500B",
+            "Netgear DGN3500B",
+             dgn3500_init);
diff --git a/target/linux/lantiq/files-3.0/arch/mips/lantiq/xway/mach-wbmr.c b/target/linux/lantiq/files-3.0/arch/mips/lantiq/xway/mach-wbmr.c
new file mode 100644 (file)
index 0000000..141a5b7
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/leds.h>
+#include <linux/gpio.h>
+#include <linux/gpio_buttons.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/input.h>
+
+#include <lantiq_soc.h>
+#include <irq.h>
+
+#include "../machtypes.h"
+#include "../dev-leds-gpio.h"
+#include "../dev-gpio-buttons.h"
+#include "devices.h"
+#include "dev-dwc_otg.h"
+
+static struct mtd_partition wbmr_partitions[] =
+{
+       {
+               .name   = "uboot",
+               .offset = 0x0,
+               .size   = 0x40000,
+       },
+       {
+               .name   = "uboot-env",
+               .offset = 0x40000,
+               .size   = 0x20000,
+       },
+       {
+               .name   = "linux",
+               .offset = 0x60000,
+               .size   = 0x1f20000,
+       },
+       {
+               .name   = "calibration",
+               .offset = 0x1fe0000,
+               .size   = 0x20000,
+       },
+};
+
+static struct physmap_flash_data wbmr_flash_data = {
+       .nr_parts       = ARRAY_SIZE(wbmr_partitions),
+       .parts          = wbmr_partitions,
+};
+
+static struct gpio_led
+wbmr_leds_gpio[] __initdata = {
+       { .name = "soc:blue:movie", .gpio = 20, .active_low = 1, },
+       { .name = "soc:red:internet", .gpio = 18, .active_low = 1, },
+       { .name = "soc:green:internet", .gpio = 17, .active_low = 1, },
+       { .name = "soc:green:adsl", .gpio = 16, .active_low = 1, },
+       { .name = "soc:green:wlan", .gpio = 15, .active_low = 1, },
+       { .name = "soc:red:security", .gpio = 14, .active_low = 1, },
+       { .name = "soc:green:power", .gpio = 1, .active_low = 1, },
+       { .name = "soc:red:power", .gpio = 5, .active_low = 1, },
+       { .name = "soc:green:usb", .gpio = 28, .active_low = 1, },
+};
+
+static struct gpio_keys_button
+wbmr_gpio_keys[] __initdata = {
+       {
+               .desc = "aoss",
+               .type = EV_KEY,
+               .code = BTN_0,
+               .debounce_interval = LTQ_KEYS_DEBOUNCE_INTERVAL,
+               .gpio = 0,
+               .active_low = 1,
+       },
+       {
+               .desc = "reset",
+               .type = EV_KEY,
+               .code = BTN_1,
+               .debounce_interval = LTQ_KEYS_DEBOUNCE_INTERVAL,
+               .gpio = 37,
+               .active_low = 1,
+       },
+};
+
+static struct ltq_pci_data ltq_pci_data = {
+       .clock      = PCI_CLOCK_INT,
+       .gpio   = PCI_GNT1 | PCI_REQ1,
+       .irq    = {
+               [14] = INT_NUM_IM0_IRL0 + 22,
+       },
+};
+
+static struct ltq_eth_data ltq_eth_data = {
+       .mii_mode = PHY_INTERFACE_MODE_RGMII,
+};
+
+static void __init
+wbmr_init(void)
+{
+#define WMBR_BRN_MAC                   0x1fd0024
+
+       ltq_add_device_leds_gpio(-1, ARRAY_SIZE(wbmr_leds_gpio), wbmr_leds_gpio);
+       ltq_register_gpio_keys_polled(-1, LTQ_KEYS_POLL_INTERVAL, ARRAY_SIZE(wbmr_gpio_keys), wbmr_gpio_keys);
+       ltq_register_nor(&wbmr_flash_data);
+       ltq_register_pci(&ltq_pci_data);
+       memcpy_fromio(&ltq_eth_data.mac.sa_data,
+               (void *)KSEG1ADDR(LTQ_FLASH_START + WMBR_BRN_MAC), 6);
+       ltq_register_etop(&ltq_eth_data);
+       xway_register_dwc(36);
+}
+
+MIPS_MACHINE(LANTIQ_MACH_WBMR,
+                       "WBMR",
+                       "WBMR",
+                       wbmr_init);
index 0d4ad2d..b0db10e 100644 (file)
@@ -29,7 +29,7 @@ USB_MENU:=USB Support
 define KernelPackage/usb-dwc-otg
   TITLE:=Synopsis DWC_OTG support
   SUBMENU:=$(USB_MENU)
-  DEPENDS+=@TARGET_lantiq_danube +kmod-usb-core
+  DEPENDS+=@(TARGET_lantiq_danube||TARGET_lantiq_ar9||TARGET_lantiq_vr9) +kmod-usb-core
   KCONFIG:=CONFIG_DWC_OTG \
        CONFIG_DWC_OTG_DEBUG=n \
        CONFIG_DWC_OTG_LANTIQ=y \
@@ -51,7 +51,7 @@ I2C_FALCON_MODULES:= \
 define KernelPackage/i2c-falcon-lantiq
   TITLE:=Falcon I2C controller
   $(call i2c_defaults,$(I2C_FALCON_MODULES),52)
-  DEPENDS:=kmod-i2c-core @TARGET_lantiq
+  DEPENDS:=kmod-i2c-core @(TARGET_lantiq_falcon||TARGET_lantiq_falcon_stable)
 endef
 
 define KernelPackage/i2c-falcon-lantiq/description
diff --git a/target/linux/lantiq/patches-3.0/000-gpio_fix.patch b/target/linux/lantiq/patches-3.0/000-gpio_fix.patch
deleted file mode 100644 (file)
index 6295f78..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
---- a/arch/mips/lantiq/xway/gpio_ebu.c
-+++ b/arch/mips/lantiq/xway/gpio_ebu.c
-@@ -63,7 +63,6 @@ static struct gpio_chip ltq_ebu_chip = {
-       .set = ltq_ebu_set,
-       .base = 72,
-       .ngpio = 16,
--      .can_sleep = 1,
-       .owner = THIS_MODULE,
- };
---- a/arch/mips/lantiq/xway/gpio_stp.c
-+++ b/arch/mips/lantiq/xway/gpio_stp.c
-@@ -72,7 +72,6 @@ static struct gpio_chip ltq_stp_chip = {
-       .set = ltq_stp_set,
-       .base = 48,
-       .ngpio = 24,
--      .can_sleep = 1,
-       .owner = THIS_MODULE,
- };
diff --git a/target/linux/lantiq/patches-3.0/0001-MIPS-lantiq-fix-early-printk.patch b/target/linux/lantiq/patches-3.0/0001-MIPS-lantiq-fix-early-printk.patch
new file mode 100644 (file)
index 0000000..2671360
--- /dev/null
@@ -0,0 +1,67 @@
+From 91f8d0c8fbb9ea70bf78a291e312157177be8ee3 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Sat, 20 Aug 2011 18:55:13 +0200
+Subject: [PATCH 01/24] MIPS: lantiq: fix early printk
+
+The code was using a 32bit write operation in the early_printk code. This
+resulted in 3 zero bytes also being written to the serial port. Change the
+memory access to 8bit.
+
+Signed-off-by: Thomas Langer <thomas.langer@lantiq.com>
+Signed-off-by: John Crispin <blogic@openwrt.org>
+Cc: linux-mips@linux-mips.org
+---
+ .../mips/include/asm/mach-lantiq/xway/lantiq_soc.h |    4 ++++
+ arch/mips/lantiq/early_printk.c                    |   14 ++++++++------
+ 2 files changed, 12 insertions(+), 6 deletions(-)
+
+diff --git a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
+index 8a3c6be..e6d1ca0 100644
+--- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
++++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
+@@ -34,6 +34,10 @@
+ #define LTQ_ASC1_BASE_ADDR    0x1E100C00
+ #define LTQ_ASC_SIZE          0x400
++/* during early_printk no ioremap is possible
++   lets use KSEG1 instead  */
++#define LTQ_EARLY_ASC         KSEG1ADDR(LTQ_ASC1_BASE_ADDR)
++
+ /* RCU - reset control unit */
+ #define LTQ_RCU_BASE_ADDR     0x1F203000
+ #define LTQ_RCU_SIZE          0x1000
+diff --git a/arch/mips/lantiq/early_printk.c b/arch/mips/lantiq/early_printk.c
+index 972e05f..5089075 100644
+--- a/arch/mips/lantiq/early_printk.c
++++ b/arch/mips/lantiq/early_printk.c
+@@ -12,11 +12,13 @@
+ #include <lantiq.h>
+ #include <lantiq_soc.h>
+-/* no ioremap possible at this early stage, lets use KSEG1 instead  */
+-#define LTQ_ASC_BASE  KSEG1ADDR(LTQ_ASC1_BASE_ADDR)
+ #define ASC_BUF               1024
+-#define LTQ_ASC_FSTAT ((u32 *)(LTQ_ASC_BASE + 0x0048))
+-#define LTQ_ASC_TBUF  ((u32 *)(LTQ_ASC_BASE + 0x0020))
++#define LTQ_ASC_FSTAT ((u32 *)(LTQ_EARLY_ASC + 0x0048))
++#ifdef __BIG_ENDIAN
++#define LTQ_ASC_TBUF  ((u32 *)(LTQ_EARLY_ASC + 0x0020 + 3))
++#else
++#define LTQ_ASC_TBUF  ((u32 *)(LTQ_EARLY_ASC + 0x0020))
++#endif
+ #define TXMASK                0x3F00
+ #define TXOFFSET      8
+@@ -27,7 +29,7 @@ void prom_putchar(char c)
+       local_irq_save(flags);
+       do { } while ((ltq_r32(LTQ_ASC_FSTAT) & TXMASK) >> TXOFFSET);
+       if (c == '\n')
+-              ltq_w32('\r', LTQ_ASC_TBUF);
+-      ltq_w32(c, LTQ_ASC_TBUF);
++              ltq_w8('\r', LTQ_ASC_TBUF);
++      ltq_w8(c, LTQ_ASC_TBUF);
+       local_irq_restore(flags);
+ }
+-- 
+1.7.5.4
+
diff --git a/target/linux/lantiq/patches-3.0/0002-MIPS-lantiq-fix-cmdline-parsing.patch b/target/linux/lantiq/patches-3.0/0002-MIPS-lantiq-fix-cmdline-parsing.patch
new file mode 100644 (file)
index 0000000..680a8dc
--- /dev/null
@@ -0,0 +1,37 @@
+From b85d5204f2fe8c3b5e6172f7cc1741ad6e849334 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Fri, 12 Aug 2011 16:27:38 +0200
+Subject: [PATCH 02/24] MIPS: lantiq: fix cmdline parsing
+
+The code tested if the KSEG1 mapped address of argv was != 0. We need to use
+CPHYSADDR instead to make the conditional actually work.
+
+Signed-off-by: Thomas Langer <thomas.langer@lantiq.com>
+Signed-off-by: John Crispin <blogic@openwrt.org>
+Cc: linux-mips@linux-mips.org
+---
+ arch/mips/lantiq/prom.c |    6 ++++--
+ 1 files changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/arch/mips/lantiq/prom.c b/arch/mips/lantiq/prom.c
+index 56ba007..5035c10 100644
+--- a/arch/mips/lantiq/prom.c
++++ b/arch/mips/lantiq/prom.c
+@@ -45,10 +45,12 @@ static void __init prom_init_cmdline(void)
+       char **argv = (char **) KSEG1ADDR(fw_arg1);
+       int i;
++      arcs_cmdline[0] = '\0';
++
+       for (i = 0; i < argc; i++) {
+-              char *p = (char *)  KSEG1ADDR(argv[i]);
++              char *p = (char *) KSEG1ADDR(argv[i]);
+-              if (p && *p) {
++              if (CPHYSADDR(p) && *p) {
+                       strlcat(arcs_cmdline, p, sizeof(arcs_cmdline));
+                       strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline));
+               }
+-- 
+1.7.5.4
+
diff --git a/target/linux/lantiq/patches-3.0/0003-MIPS-lantiq-fix-watchdogs-timeout-handling.patch b/target/linux/lantiq/patches-3.0/0003-MIPS-lantiq-fix-watchdogs-timeout-handling.patch
new file mode 100644 (file)
index 0000000..5d0061a
--- /dev/null
@@ -0,0 +1,45 @@
+From 14ea48a5f5702ddc97425cbe520600e187e14e4a Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Thu, 11 Aug 2011 13:58:39 +0200
+Subject: [PATCH 03/24] MIPS: lantiq: fix watchdogs timeout handling
+
+The enable function was using the global timeout variable for local operations.
+This resulted in the value of the global variable being corrupted, thus
+breaking the code.
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+Signed-off-by: Thomas Langer <thomas.langer@lantiq.com>
+Cc: linux-watchdog@vger.kernel.org
+Cc: linux-mips@linux-mips.org
+---
+ drivers/watchdog/lantiq_wdt.c |    8 ++++----
+ 1 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/watchdog/lantiq_wdt.c b/drivers/watchdog/lantiq_wdt.c
+index 7d82ada..102aed0 100644
+--- a/drivers/watchdog/lantiq_wdt.c
++++ b/drivers/watchdog/lantiq_wdt.c
+@@ -51,16 +51,16 @@ static int ltq_wdt_ok_to_close;
+ static void
+ ltq_wdt_enable(void)
+ {
+-      ltq_wdt_timeout = ltq_wdt_timeout *
++      unsigned long int timeout = ltq_wdt_timeout *
+                       (ltq_io_region_clk_rate / LTQ_WDT_DIVIDER) + 0x1000;
+-      if (ltq_wdt_timeout > LTQ_MAX_TIMEOUT)
+-              ltq_wdt_timeout = LTQ_MAX_TIMEOUT;
++      if (timeout > LTQ_MAX_TIMEOUT)
++              timeout = LTQ_MAX_TIMEOUT;
+       /* write the first password magic */
+       ltq_w32(LTQ_WDT_PW1, ltq_wdt_membase + LTQ_WDT_CR);
+       /* write the second magic plus the configuration and new timeout */
+       ltq_w32(LTQ_WDT_SR_EN | LTQ_WDT_SR_PWD | LTQ_WDT_SR_CLKDIV |
+-              LTQ_WDT_PW2 | ltq_wdt_timeout, ltq_wdt_membase + LTQ_WDT_CR);
++              LTQ_WDT_PW2 | timeout, ltq_wdt_membase + LTQ_WDT_CR);
+ }
+ static void
+-- 
+1.7.5.4
+
diff --git a/target/linux/lantiq/patches-3.0/0004-MIPS-lantiq-reorganize-xway-code.patch b/target/linux/lantiq/patches-3.0/0004-MIPS-lantiq-reorganize-xway-code.patch
new file mode 100644 (file)
index 0000000..a847bee
--- /dev/null
@@ -0,0 +1,883 @@
+From d90739a8962b541969b4c5f7ef1df8fec9c7f153 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Wed, 10 Aug 2011 14:57:04 +0200
+Subject: [PATCH 04/24] MIPS: lantiq: reorganize xway code
+
+Inside the folder arch/mips/lantiq/xway, there were alot of small files with
+lots of duplicated code. This patch adds a wrapper function for inserting and
+requesting resources and unifies the small files into one bigger file.
+
+This patch makes the xway code consistent with the falcon support added later
+in this series.
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+Signed-off-by: Thomas Langer <thomas.langer@lantiq.com>
+Cc: linux-mips@linux-mips.org
+---
+ arch/mips/include/asm/mach-lantiq/lantiq.h         |   14 +---
+ .../mips/include/asm/mach-lantiq/xway/lantiq_soc.h |   14 ++++
+ arch/mips/lantiq/clk.c                             |   25 +------
+ arch/mips/lantiq/devices.c                         |   30 ++------
+ arch/mips/lantiq/devices.h                         |    4 +
+ arch/mips/lantiq/prom.c                            |   50 +++++++++++--
+ arch/mips/lantiq/prom.h                            |    4 +
+ arch/mips/lantiq/xway/Makefile                     |    6 +-
+ arch/mips/lantiq/xway/devices.c                    |   42 ++---------
+ arch/mips/lantiq/xway/dma.c                        |   21 ++----
+ arch/mips/lantiq/xway/ebu.c                        |   53 --------------
+ arch/mips/lantiq/xway/pmu.c                        |   70 ------------------
+ arch/mips/lantiq/xway/prom-ase.c                   |    9 +++
+ arch/mips/lantiq/xway/prom-xway.c                  |   10 +++
+ arch/mips/lantiq/xway/reset.c                      |   21 ++----
+ arch/mips/lantiq/xway/setup-ase.c                  |   19 -----
+ arch/mips/lantiq/xway/setup-xway.c                 |   20 -----
+ arch/mips/lantiq/xway/sysctrl.c                    |   77 ++++++++++++++++++++
+ drivers/watchdog/lantiq_wdt.c                      |    2 +-
+ 19 files changed, 197 insertions(+), 294 deletions(-)
+ delete mode 100644 arch/mips/lantiq/xway/ebu.c
+ delete mode 100644 arch/mips/lantiq/xway/pmu.c
+ delete mode 100644 arch/mips/lantiq/xway/setup-ase.c
+ delete mode 100644 arch/mips/lantiq/xway/setup-xway.c
+ create mode 100644 arch/mips/lantiq/xway/sysctrl.c
+
+diff --git a/arch/mips/include/asm/mach-lantiq/lantiq.h b/arch/mips/include/asm/mach-lantiq/lantiq.h
+index ce2f029..66d7300 100644
+--- a/arch/mips/include/asm/mach-lantiq/lantiq.h
++++ b/arch/mips/include/asm/mach-lantiq/lantiq.h
+@@ -9,6 +9,7 @@
+ #define _LANTIQ_H__
+ #include <linux/irq.h>
++#include <linux/ioport.h>
+ /* generic reg access functions */
+ #define ltq_r32(reg)          __raw_readl(reg)
+@@ -18,15 +19,6 @@
+ #define ltq_r8(reg)           __raw_readb(reg)
+ #define ltq_w8(val, reg)      __raw_writeb(val, reg)
+-/* register access macros for EBU and CGU */
+-#define ltq_ebu_w32(x, y)     ltq_w32((x), ltq_ebu_membase + (y))
+-#define ltq_ebu_r32(x)                ltq_r32(ltq_ebu_membase + (x))
+-#define ltq_cgu_w32(x, y)     ltq_w32((x), ltq_cgu_membase + (y))
+-#define ltq_cgu_r32(x)                ltq_r32(ltq_cgu_membase + (x))
+-
+-extern __iomem void *ltq_ebu_membase;
+-extern __iomem void *ltq_cgu_membase;
+-
+ extern unsigned int ltq_get_cpu_ver(void);
+ extern unsigned int ltq_get_soc_type(void);
+@@ -51,7 +43,9 @@ extern void ltq_enable_irq(struct irq_data *data);
+ /* find out what caused the last cpu reset */
+ extern int ltq_reset_cause(void);
+-#define LTQ_RST_CAUSE_WDTRST  0x20
++
++/* helper for requesting and remapping resources */
++extern void __iomem *ltq_remap_resource(struct resource *res);
+ #define IOPORT_RESOURCE_START 0x10000000
+ #define IOPORT_RESOURCE_END   0xffffffff
+diff --git a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
+index e6d1ca0..da8ff95 100644
+--- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
++++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
+@@ -65,6 +65,8 @@
+ #define LTQ_CGU_BASE_ADDR     0x1F103000
+ #define LTQ_CGU_SIZE          0x1000
++#define CGU_EPHY              0x10
++
+ /* ICU - interrupt control unit */
+ #define LTQ_ICU_BASE_ADDR     0x1F880200
+ #define LTQ_ICU_SIZE          0x100
+@@ -101,6 +103,8 @@
+ #define LTQ_WDT_BASE_ADDR     0x1F8803F0
+ #define LTQ_WDT_SIZE          0x10
++#define LTQ_RST_CAUSE_WDTRST  0x20
++
+ /* STP - serial to parallel conversion unit */
+ #define LTQ_STP_BASE_ADDR     0x1E100BB0
+ #define LTQ_STP_SIZE          0x40
+@@ -125,11 +129,21 @@
+ #define LTQ_MPS_BASE_ADDR     (KSEG1 + 0x1F107000)
+ #define LTQ_MPS_CHIPID                ((u32 *)(LTQ_MPS_BASE_ADDR + 0x0344))
++/* register access macros for EBU and CGU */
++#define ltq_ebu_w32(x, y)     ltq_w32((x), ltq_ebu_membase + (y))
++#define ltq_ebu_r32(x)                ltq_r32(ltq_ebu_membase + (x))
++#define ltq_cgu_w32(x, y)     ltq_w32((x), ltq_cgu_membase + (y))
++#define ltq_cgu_r32(x)                ltq_r32(ltq_cgu_membase + (x))
++
++extern __iomem void *ltq_ebu_membase;
++extern __iomem void *ltq_cgu_membase;
++
+ /* request a non-gpio and set the PIO config */
+ extern int  ltq_gpio_request(unsigned int pin, unsigned int alt0,
+       unsigned int alt1, unsigned int dir, const char *name);
+ extern void ltq_pmu_enable(unsigned int module);
+ extern void ltq_pmu_disable(unsigned int module);
++extern void ltq_cgu_enable(unsigned int clk);
+ static inline int ltq_is_ar9(void)
+ {
+diff --git a/arch/mips/lantiq/clk.c b/arch/mips/lantiq/clk.c
+index 7e9c0ff..4254f08 100644
+--- a/arch/mips/lantiq/clk.c
++++ b/arch/mips/lantiq/clk.c
+@@ -22,6 +22,7 @@
+ #include <lantiq_soc.h>
+ #include "clk.h"
++#include "prom.h"
+ struct clk {
+       const char *name;
+@@ -46,16 +47,6 @@ static struct clk cpu_clk_generic[] = {
+       },
+ };
+-static struct resource ltq_cgu_resource = {
+-      .name   = "cgu",
+-      .start  = LTQ_CGU_BASE_ADDR,
+-      .end    = LTQ_CGU_BASE_ADDR + LTQ_CGU_SIZE - 1,
+-      .flags  = IORESOURCE_MEM,
+-};
+-
+-/* remapped clock register range */
+-void __iomem *ltq_cgu_membase;
+-
+ void clk_init(void)
+ {
+       cpu_clk = cpu_clk_generic;
+@@ -133,21 +124,11 @@ void __init plat_time_init(void)
+ {
+       struct clk *clk;
+-      if (insert_resource(&iomem_resource, &ltq_cgu_resource) < 0)
+-              panic("Failed to insert cgu memory\n");
+-
+-      if (request_mem_region(ltq_cgu_resource.start,
+-                      resource_size(&ltq_cgu_resource), "cgu") < 0)
+-              panic("Failed to request cgu memory\n");
++      ltq_soc_init();
+-      ltq_cgu_membase = ioremap_nocache(ltq_cgu_resource.start,
+-                              resource_size(&ltq_cgu_resource));
+-      if (!ltq_cgu_membase) {
+-              pr_err("Failed to remap cgu memory\n");
+-              unreachable();
+-      }
+       clk = clk_get(0, "cpu");
+       mips_hpt_frequency = clk_get_rate(clk) / ltq_get_counter_resolution();
+       write_c0_compare(read_c0_count());
++      pr_info("CPU Clock: %ldMHz\n", clk_get_rate(clk) / 1000000);
+       clk_put(clk);
+ }
+diff --git a/arch/mips/lantiq/devices.c b/arch/mips/lantiq/devices.c
+index 44a3677..81c7aab 100644
+--- a/arch/mips/lantiq/devices.c
++++ b/arch/mips/lantiq/devices.c
+@@ -27,12 +27,8 @@
+ #include "devices.h"
+ /* nor flash */
+-static struct resource ltq_nor_resource = {
+-      .name   = "nor",
+-      .start  = LTQ_FLASH_START,
+-      .end    = LTQ_FLASH_START + LTQ_FLASH_MAX - 1,
+-      .flags  = IORESOURCE_MEM,
+-};
++static struct resource ltq_nor_resource =
++      MEM_RES("nor", LTQ_FLASH_START, LTQ_FLASH_MAX);
+ static struct platform_device ltq_nor = {
+       .name           = "ltq_nor",
+@@ -47,12 +43,8 @@ void __init ltq_register_nor(struct physmap_flash_data *data)
+ }
+ /* watchdog */
+-static struct resource ltq_wdt_resource = {
+-      .name   = "watchdog",
+-      .start  = LTQ_WDT_BASE_ADDR,
+-      .end    = LTQ_WDT_BASE_ADDR + LTQ_WDT_SIZE - 1,
+-      .flags  = IORESOURCE_MEM,
+-};
++static struct resource ltq_wdt_resource =
++      MEM_RES("watchdog", LTQ_WDT_BASE_ADDR, LTQ_WDT_SIZE);
+ void __init ltq_register_wdt(void)
+ {
+@@ -61,24 +53,14 @@ void __init ltq_register_wdt(void)
+ /* asc ports */
+ static struct resource ltq_asc0_resources[] = {
+-      {
+-              .name   = "asc0",
+-              .start  = LTQ_ASC0_BASE_ADDR,
+-              .end    = LTQ_ASC0_BASE_ADDR + LTQ_ASC_SIZE - 1,
+-              .flags  = IORESOURCE_MEM,
+-      },
++      MEM_RES("asc0", LTQ_ASC0_BASE_ADDR, LTQ_ASC_SIZE),
+       IRQ_RES(tx, LTQ_ASC_TIR(0)),
+       IRQ_RES(rx, LTQ_ASC_RIR(0)),
+       IRQ_RES(err, LTQ_ASC_EIR(0)),
+ };
+ static struct resource ltq_asc1_resources[] = {
+-      {
+-              .name   = "asc1",
+-              .start  = LTQ_ASC1_BASE_ADDR,
+-              .end    = LTQ_ASC1_BASE_ADDR + LTQ_ASC_SIZE - 1,
+-              .flags  = IORESOURCE_MEM,
+-      },
++      MEM_RES("asc1", LTQ_ASC1_BASE_ADDR, LTQ_ASC_SIZE),
+       IRQ_RES(tx, LTQ_ASC_TIR(1)),
+       IRQ_RES(rx, LTQ_ASC_RIR(1)),
+       IRQ_RES(err, LTQ_ASC_EIR(1)),
+diff --git a/arch/mips/lantiq/devices.h b/arch/mips/lantiq/devices.h
+index 2947bb1..a03c23f 100644
+--- a/arch/mips/lantiq/devices.h
++++ b/arch/mips/lantiq/devices.h
+@@ -14,6 +14,10 @@
+ #define IRQ_RES(resname, irq) \
+       {.name = #resname, .start = (irq), .flags = IORESOURCE_IRQ}
++#define MEM_RES(resname, adr_start, adr_size) \
++      { .name = resname, .flags = IORESOURCE_MEM, \
++        .start = ((adr_start) & ~KSEG1), \
++        .end = ((adr_start + adr_size - 1) & ~KSEG1) }
+ extern void ltq_register_nor(struct physmap_flash_data *data);
+ extern void ltq_register_wdt(void);
+diff --git a/arch/mips/lantiq/prom.c b/arch/mips/lantiq/prom.c
+index 5035c10..fead2cc 100644
+--- a/arch/mips/lantiq/prom.c
++++ b/arch/mips/lantiq/prom.c
+@@ -16,6 +16,10 @@
+ #include "prom.h"
+ #include "clk.h"
++/* access to the ebu needs to be locked between different drivers */
++DEFINE_SPINLOCK(ebu_lock);
++EXPORT_SYMBOL_GPL(ebu_lock);
++
+ static struct ltq_soc_info soc_info;
+ unsigned int ltq_get_cpu_ver(void)
+@@ -57,16 +61,50 @@ static void __init prom_init_cmdline(void)
+       }
+ }
+-void __init prom_init(void)
++void __iomem *ltq_remap_resource(struct resource *res)
+ {
+-      struct clk *clk;
++      __iomem void *ret = NULL;
++      struct resource *lookup = lookup_resource(&iomem_resource, res->start);
++
++      if (lookup && strcmp(lookup->name, res->name)) {
++              panic("conflicting memory range %s\n", res->name);
++              return NULL;
++      }
++      if (!lookup) {
++              if (insert_resource(&iomem_resource, res) < 0) {
++                      panic("Failed to insert %s memory\n", res->name);
++                      return NULL;
++              }
++      }
++      if (request_mem_region(res->start,
++                      resource_size(res), res->name) < 0) {
++              panic("Failed to request %s memory\n", res->name);
++              goto err_res;
++      }
++      ret = ioremap_nocache(res->start, resource_size(res));
++      if (!ret)
++              goto err_mem;
++
++      pr_debug("remap: 0x%08X-0x%08X : \"%s\"\n",
++              res->start, res->end, res->name);
++      return ret;
++
++err_mem:
++      panic("Failed to remap %s memory\n", res->name);
++      release_mem_region(res->start, resource_size(res));
++
++err_res:
++      release_resource(res);
++      return NULL;
++}
++
++void __init prom_init(void)
++{
+       ltq_soc_detect(&soc_info);
+       clk_init();
+-      clk = clk_get(0, "cpu");
+-      snprintf(soc_info.sys_type, LTQ_SYS_TYPE_LEN - 1, "%s rev1.%d",
+-              soc_info.name, soc_info.rev);
+-      clk_put(clk);
++      snprintf(soc_info.sys_type, LTQ_SYS_TYPE_LEN - 1, "%s rev %s",
++              soc_info.name, soc_info.rev_type);
+       soc_info.sys_type[LTQ_SYS_TYPE_LEN - 1] = '\0';
+       pr_info("SoC: %s\n", soc_info.sys_type);
+       prom_init_cmdline();
+diff --git a/arch/mips/lantiq/prom.h b/arch/mips/lantiq/prom.h
+index b4229d9..51dba1b 100644
+--- a/arch/mips/lantiq/prom.h
++++ b/arch/mips/lantiq/prom.h
+@@ -9,17 +9,21 @@
+ #ifndef _LTQ_PROM_H__
+ #define _LTQ_PROM_H__
++#define LTQ_SYS_REV_LEN               0x10
+ #define LTQ_SYS_TYPE_LEN      0x100
+ struct ltq_soc_info {
+       unsigned char *name;
+       unsigned int rev;
++      unsigned char rev_type[LTQ_SYS_REV_LEN];
++      unsigned int srev;
+       unsigned int partnum;
+       unsigned int type;
+       unsigned char sys_type[LTQ_SYS_TYPE_LEN];
+ };
+ extern void ltq_soc_detect(struct ltq_soc_info *i);
++extern void ltq_soc_init(void);
+ extern void ltq_soc_setup(void);
+ #endif
+diff --git a/arch/mips/lantiq/xway/Makefile b/arch/mips/lantiq/xway/Makefile
+index c517f2e..6678402 100644
+--- a/arch/mips/lantiq/xway/Makefile
++++ b/arch/mips/lantiq/xway/Makefile
+@@ -1,7 +1,7 @@
+-obj-y := pmu.o ebu.o reset.o gpio.o gpio_stp.o gpio_ebu.o devices.o dma.o
++obj-y := sysctrl.o reset.o gpio.o gpio_stp.o gpio_ebu.o devices.o dma.o
+-obj-$(CONFIG_SOC_XWAY) += clk-xway.o prom-xway.o setup-xway.o
+-obj-$(CONFIG_SOC_AMAZON_SE) += clk-ase.o prom-ase.o setup-ase.o
++obj-$(CONFIG_SOC_XWAY) += clk-xway.o prom-xway.o
++obj-$(CONFIG_SOC_AMAZON_SE) += clk-ase.o prom-ase.o
+ obj-$(CONFIG_LANTIQ_MACH_EASY50712) += mach-easy50712.o
+ obj-$(CONFIG_LANTIQ_MACH_EASY50601) += mach-easy50601.o
+diff --git a/arch/mips/lantiq/xway/devices.c b/arch/mips/lantiq/xway/devices.c
+index d0e32ab..9bacaa8 100644
+--- a/arch/mips/lantiq/xway/devices.c
++++ b/arch/mips/lantiq/xway/devices.c
+@@ -31,22 +31,9 @@
+ /* gpio */
+ static struct resource ltq_gpio_resource[] = {
+-      {
+-              .name   = "gpio0",
+-              .start  = LTQ_GPIO0_BASE_ADDR,
+-              .end    = LTQ_GPIO0_BASE_ADDR + LTQ_GPIO_SIZE - 1,
+-              .flags  = IORESOURCE_MEM,
+-      }, {
+-              .name   = "gpio1",
+-              .start  = LTQ_GPIO1_BASE_ADDR,
+-              .end    = LTQ_GPIO1_BASE_ADDR + LTQ_GPIO_SIZE - 1,
+-              .flags  = IORESOURCE_MEM,
+-      }, {
+-              .name   = "gpio2",
+-              .start  = LTQ_GPIO2_BASE_ADDR,
+-              .end    = LTQ_GPIO2_BASE_ADDR + LTQ_GPIO_SIZE - 1,
+-              .flags  = IORESOURCE_MEM,
+-      }
++      MEM_RES("gpio0", LTQ_GPIO0_BASE_ADDR, LTQ_GPIO_SIZE),
++      MEM_RES("gpio1", LTQ_GPIO1_BASE_ADDR, LTQ_GPIO_SIZE),
++      MEM_RES("gpio2", LTQ_GPIO2_BASE_ADDR, LTQ_GPIO_SIZE),
+ };
+ void __init ltq_register_gpio(void)
+@@ -64,12 +51,8 @@ void __init ltq_register_gpio(void)
+ }
+ /* serial to parallel conversion */
+-static struct resource ltq_stp_resource = {
+-      .name   = "stp",
+-      .start  = LTQ_STP_BASE_ADDR,
+-      .end    = LTQ_STP_BASE_ADDR + LTQ_STP_SIZE - 1,
+-      .flags  = IORESOURCE_MEM,
+-};
++static struct resource ltq_stp_resource =
++      MEM_RES("stp", LTQ_STP_BASE_ADDR, LTQ_STP_SIZE);
+ void __init ltq_register_gpio_stp(void)
+ {
+@@ -78,12 +61,7 @@ void __init ltq_register_gpio_stp(void)
+ /* asc ports - amazon se has its own serial mapping */
+ static struct resource ltq_ase_asc_resources[] = {
+-      {
+-              .name   = "asc0",
+-              .start  = LTQ_ASC1_BASE_ADDR,
+-              .end    = LTQ_ASC1_BASE_ADDR + LTQ_ASC_SIZE - 1,
+-              .flags  = IORESOURCE_MEM,
+-      },
++      MEM_RES("asc0", LTQ_ASC1_BASE_ADDR, LTQ_ASC_SIZE),
+       IRQ_RES(tx, LTQ_ASC_ASE_TIR),
+       IRQ_RES(rx, LTQ_ASC_ASE_RIR),
+       IRQ_RES(err, LTQ_ASC_ASE_EIR),
+@@ -96,12 +74,8 @@ void __init ltq_register_ase_asc(void)
+ }
+ /* ethernet */
+-static struct resource ltq_etop_resources = {
+-      .name   = "etop",
+-      .start  = LTQ_ETOP_BASE_ADDR,
+-      .end    = LTQ_ETOP_BASE_ADDR + LTQ_ETOP_SIZE - 1,
+-      .flags  = IORESOURCE_MEM,
+-};
++static struct resource ltq_etop_resources =
++      MEM_RES("etop", LTQ_ETOP_BASE_ADDR, LTQ_ETOP_SIZE);
+ static struct platform_device ltq_etop = {
+       .name           = "ltq_etop",
+diff --git a/arch/mips/lantiq/xway/dma.c b/arch/mips/lantiq/xway/dma.c
+index 4278a45..af35e62 100644
+--- a/arch/mips/lantiq/xway/dma.c
++++ b/arch/mips/lantiq/xway/dma.c
+@@ -23,6 +23,8 @@
+ #include <lantiq_soc.h>
+ #include <xway_dma.h>
++#include "../devices.h"
++
+ #define LTQ_DMA_CTRL          0x10
+ #define LTQ_DMA_CPOLL         0x14
+ #define LTQ_DMA_CS            0x18
+@@ -54,12 +56,8 @@
+ #define ltq_dma_w32_mask(x, y, z)     ltq_w32_mask(x, y, \
+                                               ltq_dma_membase + (z))
+-static struct resource ltq_dma_resource = {
+-      .name   = "dma",
+-      .start  = LTQ_DMA_BASE_ADDR,
+-      .end    = LTQ_DMA_BASE_ADDR + LTQ_DMA_SIZE - 1,
+-      .flags  = IORESOURCE_MEM,
+-};
++static struct resource ltq_dma_resource =
++      MEM_RES("dma", LTQ_DMA_BASE_ADDR, LTQ_DMA_SIZE);
+ static void __iomem *ltq_dma_membase;
+@@ -219,17 +217,8 @@ ltq_dma_init(void)
+ {
+       int i;
+-      /* insert and request the memory region */
+-      if (insert_resource(&iomem_resource, &ltq_dma_resource) < 0)
+-              panic("Failed to insert dma memory\n");
+-
+-      if (request_mem_region(ltq_dma_resource.start,
+-                      resource_size(&ltq_dma_resource), "dma") < 0)
+-              panic("Failed to request dma memory\n");
+-
+       /* remap dma register range */
+-      ltq_dma_membase = ioremap_nocache(ltq_dma_resource.start,
+-                              resource_size(&ltq_dma_resource));
++      ltq_dma_membase = ltq_remap_resource(&ltq_dma_resource);
+       if (!ltq_dma_membase)
+               panic("Failed to remap dma memory\n");
+diff --git a/arch/mips/lantiq/xway/ebu.c b/arch/mips/lantiq/xway/ebu.c
+deleted file mode 100644
+index 66eb52f..0000000
+--- a/arch/mips/lantiq/xway/ebu.c
++++ /dev/null
+@@ -1,53 +0,0 @@
+-/*
+- *  This program is free software; you can redistribute it and/or modify it
+- *  under the terms of the GNU General Public License version 2 as published
+- *  by the Free Software Foundation.
+- *
+- *  EBU - the external bus unit attaches PCI, NOR and NAND
+- *
+- *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+- */
+-
+-#include <linux/kernel.h>
+-#include <linux/module.h>
+-#include <linux/version.h>
+-#include <linux/ioport.h>
+-
+-#include <lantiq_soc.h>
+-
+-/* all access to the ebu must be locked */
+-DEFINE_SPINLOCK(ebu_lock);
+-EXPORT_SYMBOL_GPL(ebu_lock);
+-
+-static struct resource ltq_ebu_resource = {
+-      .name   = "ebu",
+-      .start  = LTQ_EBU_BASE_ADDR,
+-      .end    = LTQ_EBU_BASE_ADDR + LTQ_EBU_SIZE - 1,
+-      .flags  = IORESOURCE_MEM,
+-};
+-
+-/* remapped base addr of the clock unit and external bus unit */
+-void __iomem *ltq_ebu_membase;
+-
+-static int __init lantiq_ebu_init(void)
+-{
+-      /* insert and request the memory region */
+-      if (insert_resource(&iomem_resource, &ltq_ebu_resource) < 0)
+-              panic("Failed to insert ebu memory\n");
+-
+-      if (request_mem_region(ltq_ebu_resource.start,
+-                      resource_size(&ltq_ebu_resource), "ebu") < 0)
+-              panic("Failed to request ebu memory\n");
+-
+-      /* remap ebu register range */
+-      ltq_ebu_membase = ioremap_nocache(ltq_ebu_resource.start,
+-                              resource_size(&ltq_ebu_resource));
+-      if (!ltq_ebu_membase)
+-              panic("Failed to remap ebu memory\n");
+-
+-      /* make sure to unprotect the memory region where flash is located */
+-      ltq_ebu_w32(ltq_ebu_r32(LTQ_EBU_BUSCON0) & ~EBU_WRDIS, LTQ_EBU_BUSCON0);
+-      return 0;
+-}
+-
+-postcore_initcall(lantiq_ebu_init);
+diff --git a/arch/mips/lantiq/xway/pmu.c b/arch/mips/lantiq/xway/pmu.c
+deleted file mode 100644
+index 9d69f01e..0000000
+--- a/arch/mips/lantiq/xway/pmu.c
++++ /dev/null
+@@ -1,70 +0,0 @@
+-/*
+- *  This program is free software; you can redistribute it and/or modify it
+- *  under the terms of the GNU General Public License version 2 as published
+- *  by the Free Software Foundation.
+- *
+- *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+- */
+-
+-#include <linux/kernel.h>
+-#include <linux/module.h>
+-#include <linux/version.h>
+-#include <linux/ioport.h>
+-
+-#include <lantiq_soc.h>
+-
+-/* PMU - the power management unit allows us to turn part of the core
+- * on and off
+- */
+-
+-/* the enable / disable registers */
+-#define LTQ_PMU_PWDCR 0x1C
+-#define LTQ_PMU_PWDSR 0x20
+-
+-#define ltq_pmu_w32(x, y)     ltq_w32((x), ltq_pmu_membase + (y))
+-#define ltq_pmu_r32(x)                ltq_r32(ltq_pmu_membase + (x))
+-
+-static struct resource ltq_pmu_resource = {
+-      .name   = "pmu",
+-      .start  = LTQ_PMU_BASE_ADDR,
+-      .end    = LTQ_PMU_BASE_ADDR + LTQ_PMU_SIZE - 1,
+-      .flags  = IORESOURCE_MEM,
+-};
+-
+-static void __iomem *ltq_pmu_membase;
+-
+-void ltq_pmu_enable(unsigned int module)
+-{
+-      int err = 1000000;
+-
+-      ltq_pmu_w32(ltq_pmu_r32(LTQ_PMU_PWDCR) & ~module, LTQ_PMU_PWDCR);
+-      do {} while (--err && (ltq_pmu_r32(LTQ_PMU_PWDSR) & module));
+-
+-      if (!err)
+-              panic("activating PMU module failed!\n");
+-}
+-EXPORT_SYMBOL(ltq_pmu_enable);
+-
+-void ltq_pmu_disable(unsigned int module)
+-{
+-      ltq_pmu_w32(ltq_pmu_r32(LTQ_PMU_PWDCR) | module, LTQ_PMU_PWDCR);
+-}
+-EXPORT_SYMBOL(ltq_pmu_disable);
+-
+-int __init ltq_pmu_init(void)
+-{
+-      if (insert_resource(&iomem_resource, &ltq_pmu_resource) < 0)
+-              panic("Failed to insert pmu memory\n");
+-
+-      if (request_mem_region(ltq_pmu_resource.start,
+-                      resource_size(&ltq_pmu_resource), "pmu") < 0)
+-              panic("Failed to request pmu memory\n");
+-
+-      ltq_pmu_membase = ioremap_nocache(ltq_pmu_resource.start,
+-                              resource_size(&ltq_pmu_resource));
+-      if (!ltq_pmu_membase)
+-              panic("Failed to remap pmu memory\n");
+-      return 0;
+-}
+-
+-core_initcall(ltq_pmu_init);
+diff --git a/arch/mips/lantiq/xway/prom-ase.c b/arch/mips/lantiq/xway/prom-ase.c
+index abe49f4..aaccdcb 100644
+--- a/arch/mips/lantiq/xway/prom-ase.c
++++ b/arch/mips/lantiq/xway/prom-ase.c
+@@ -13,6 +13,7 @@
+ #include <lantiq_soc.h>
++#include "devices.h"
+ #include "../prom.h"
+ #define SOC_AMAZON_SE "Amazon_SE"
+@@ -26,6 +27,7 @@ void __init ltq_soc_detect(struct ltq_soc_info *i)
+ {
+       i->partnum = (ltq_r32(LTQ_MPS_CHIPID) & PART_MASK) >> PART_SHIFT;
+       i->rev = (ltq_r32(LTQ_MPS_CHIPID) & REV_MASK) >> REV_SHIFT;
++      sprintf(i->rev_type, "1.%d", i->rev);
+       switch (i->partnum) {
+       case SOC_ID_AMAZON_SE:
+               i->name = SOC_AMAZON_SE;
+@@ -37,3 +39,10 @@ void __init ltq_soc_detect(struct ltq_soc_info *i)
+               break;
+       }
+ }
++
++void __init ltq_soc_setup(void)
++{
++      ltq_register_ase_asc();
++      ltq_register_gpio();
++      ltq_register_wdt();
++}
+diff --git a/arch/mips/lantiq/xway/prom-xway.c b/arch/mips/lantiq/xway/prom-xway.c
+index 1686692a..f3d1228 100644
+--- a/arch/mips/lantiq/xway/prom-xway.c
++++ b/arch/mips/lantiq/xway/prom-xway.c
+@@ -13,6 +13,7 @@
+ #include <lantiq_soc.h>
++#include "devices.h"
+ #include "../prom.h"
+ #define SOC_DANUBE    "Danube"
+@@ -28,6 +29,7 @@ void __init ltq_soc_detect(struct ltq_soc_info *i)
+ {
+       i->partnum = (ltq_r32(LTQ_MPS_CHIPID) & PART_MASK) >> PART_SHIFT;
+       i->rev = (ltq_r32(LTQ_MPS_CHIPID) & REV_MASK) >> REV_SHIFT;
++      sprintf(i->rev_type, "1.%d", i->rev);
+       switch (i->partnum) {
+       case SOC_ID_DANUBE1:
+       case SOC_ID_DANUBE2:
+@@ -52,3 +54,11 @@ void __init ltq_soc_detect(struct ltq_soc_info *i)
+               break;
+       }
+ }
++
++void __init ltq_soc_setup(void)
++{
++      ltq_register_asc(0);
++      ltq_register_asc(1);
++      ltq_register_gpio();
++      ltq_register_wdt();
++}
+diff --git a/arch/mips/lantiq/xway/reset.c b/arch/mips/lantiq/xway/reset.c
+index a1be36d..e701a48 100644
+--- a/arch/mips/lantiq/xway/reset.c
++++ b/arch/mips/lantiq/xway/reset.c
+@@ -15,6 +15,8 @@
+ #include <lantiq_soc.h>
++#include "../devices.h"
++
+ #define ltq_rcu_w32(x, y)     ltq_w32((x), ltq_rcu_membase + (y))
+ #define ltq_rcu_r32(x)                ltq_r32(ltq_rcu_membase + (x))
+@@ -25,12 +27,8 @@
+ #define LTQ_RCU_RST_STAT      0x0014
+ #define LTQ_RCU_STAT_SHIFT    26
+-static struct resource ltq_rcu_resource = {
+-      .name   = "rcu",
+-      .start  = LTQ_RCU_BASE_ADDR,
+-      .end    = LTQ_RCU_BASE_ADDR + LTQ_RCU_SIZE - 1,
+-      .flags  = IORESOURCE_MEM,
+-};
++static struct resource ltq_rcu_resource =
++      MEM_RES("rcu", LTQ_RCU_BASE_ADDR, LTQ_RCU_SIZE);
+ /* remapped base addr of the reset control unit */
+ static void __iomem *ltq_rcu_membase;
+@@ -67,17 +65,8 @@ static void ltq_machine_power_off(void)
+ static int __init mips_reboot_setup(void)
+ {
+-      /* insert and request the memory region */
+-      if (insert_resource(&iomem_resource, &ltq_rcu_resource) < 0)
+-              panic("Failed to insert rcu memory\n");
+-
+-      if (request_mem_region(ltq_rcu_resource.start,
+-                      resource_size(&ltq_rcu_resource), "rcu") < 0)
+-              panic("Failed to request rcu memory\n");
+-
+       /* remap rcu register range */
+-      ltq_rcu_membase = ioremap_nocache(ltq_rcu_resource.start,
+-                              resource_size(&ltq_rcu_resource));
++      ltq_rcu_membase = ltq_remap_resource(&ltq_rcu_resource);
+       if (!ltq_rcu_membase)
+               panic("Failed to remap rcu memory\n");
+diff --git a/arch/mips/lantiq/xway/setup-ase.c b/arch/mips/lantiq/xway/setup-ase.c
+deleted file mode 100644
+index f6f3267..0000000
+--- a/arch/mips/lantiq/xway/setup-ase.c
++++ /dev/null
+@@ -1,19 +0,0 @@
+-/*
+- *  This program is free software; you can redistribute it and/or modify it
+- *  under the terms of the GNU General Public License version 2 as published
+- *  by the Free Software Foundation.
+- *
+- *  Copyright (C) 2011 John Crispin <blogic@openwrt.org>
+- */
+-
+-#include <lantiq_soc.h>
+-
+-#include "../prom.h"
+-#include "devices.h"
+-
+-void __init ltq_soc_setup(void)
+-{
+-      ltq_register_ase_asc();
+-      ltq_register_gpio();
+-      ltq_register_wdt();
+-}
+diff --git a/arch/mips/lantiq/xway/setup-xway.c b/arch/mips/lantiq/xway/setup-xway.c
+deleted file mode 100644
+index c292f64..0000000
+--- a/arch/mips/lantiq/xway/setup-xway.c
++++ /dev/null
+@@ -1,20 +0,0 @@
+-/*
+- *  This program is free software; you can redistribute it and/or modify it
+- *  under the terms of the GNU General Public License version 2 as published
+- *  by the Free Software Foundation.
+- *
+- *  Copyright (C) 2011 John Crispin <blogic@openwrt.org>
+- */
+-
+-#include <lantiq_soc.h>
+-
+-#include "../prom.h"
+-#include "devices.h"
+-
+-void __init ltq_soc_setup(void)
+-{
+-      ltq_register_asc(0);
+-      ltq_register_asc(1);
+-      ltq_register_gpio();
+-      ltq_register_wdt();
+-}
+diff --git a/arch/mips/lantiq/xway/sysctrl.c b/arch/mips/lantiq/xway/sysctrl.c
+new file mode 100644
+index 0000000..a29944f
+--- /dev/null
++++ b/arch/mips/lantiq/xway/sysctrl.c
+@@ -0,0 +1,77 @@
++/*
++ *  This program is free software; you can redistribute it and/or modify it
++ *  under the terms of the GNU General Public License version 2 as published
++ *  by the Free Software Foundation.
++ *
++ *  Copyright (C) 2011 John Crispin <blogic@openwrt.org>
++ */
++
++#include <linux/ioport.h>
++
++#include <lantiq_soc.h>
++
++#include "../devices.h"
++
++/* clock control register */
++#define LTQ_CGU_IFCCR 0x0018
++
++/* the enable / disable registers */
++#define LTQ_PMU_PWDCR 0x1C
++#define LTQ_PMU_PWDSR 0x20
++
++#define ltq_pmu_w32(x, y)     ltq_w32((x), ltq_pmu_membase + (y))
++#define ltq_pmu_r32(x)                ltq_r32(ltq_pmu_membase + (x))
++
++static struct resource ltq_cgu_resource =
++      MEM_RES("cgu", LTQ_CGU_BASE_ADDR, LTQ_CGU_SIZE);
++
++static struct resource ltq_pmu_resource =
++      MEM_RES("pmu", LTQ_PMU_BASE_ADDR, LTQ_PMU_SIZE);
++
++static struct resource ltq_ebu_resource =
++      MEM_RES("ebu", LTQ_EBU_BASE_ADDR, LTQ_EBU_SIZE);
++
++void __iomem *ltq_cgu_membase;
++void __iomem *ltq_ebu_membase;
++static void __iomem *ltq_pmu_membase;
++
++void ltq_cgu_enable(unsigned int clk)
++{
++      ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) | clk, LTQ_CGU_IFCCR);
++}
++
++void ltq_pmu_enable(unsigned int module)
++{
++      int err = 1000000;
++
++      ltq_pmu_w32(ltq_pmu_r32(LTQ_PMU_PWDCR) & ~module, LTQ_PMU_PWDCR);
++      do {} while (--err && (ltq_pmu_r32(LTQ_PMU_PWDSR) & module));
++
++      if (!err)
++              panic("activating PMU module failed!\n");
++}
++EXPORT_SYMBOL(ltq_pmu_enable);
++
++void ltq_pmu_disable(unsigned int module)
++{
++      ltq_pmu_w32(ltq_pmu_r32(LTQ_PMU_PWDCR) | module, LTQ_PMU_PWDCR);
++}
++EXPORT_SYMBOL(ltq_pmu_disable);
++
++void __init ltq_soc_init(void)
++{
++      ltq_pmu_membase = ltq_remap_resource(&ltq_pmu_resource);
++      if (!ltq_pmu_membase)
++              panic("Failed to remap pmu memory\n");
++
++      ltq_cgu_membase = ltq_remap_resource(&ltq_cgu_resource);
++      if (!ltq_cgu_membase)
++              panic("Failed to remap cgu memory\n");
++
++      ltq_ebu_membase = ltq_remap_resource(&ltq_ebu_resource);
++      if (!ltq_ebu_membase)
++              panic("Failed to remap ebu memory\n");
++
++      /* make sure to unprotect the memory region where flash is located */
++      ltq_ebu_w32(ltq_ebu_r32(LTQ_EBU_BUSCON0) & ~EBU_WRDIS, LTQ_EBU_BUSCON0);
++}
+diff --git a/drivers/watchdog/lantiq_wdt.c b/drivers/watchdog/lantiq_wdt.c
+index 102aed0..179bf98 100644
+--- a/drivers/watchdog/lantiq_wdt.c
++++ b/drivers/watchdog/lantiq_wdt.c
+@@ -16,7 +16,7 @@
+ #include <linux/clk.h>
+ #include <linux/io.h>
+-#include <lantiq.h>
++#include <lantiq_soc.h>
+ /* Section 3.4 of the datasheet
+  * The password sequence protects the WDT control register from unintended
+-- 
+1.7.5.4
+
diff --git a/target/linux/lantiq/patches-3.0/0005-MIPS-lantiq-make-irq.c-support-the-FALC-ON.patch b/target/linux/lantiq/patches-3.0/0005-MIPS-lantiq-make-irq.c-support-the-FALC-ON.patch
new file mode 100644 (file)
index 0000000..7caea70
--- /dev/null
@@ -0,0 +1,74 @@
+From d9355bb07878f9aa40856cc437c43cedc87662fc Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Thu, 11 Aug 2011 12:25:55 +0200
+Subject: [PATCH 05/24] MIPS: lantiq: make irq.c support the FALC-ON
+
+There are minor differences in how irqs work on xway and falcon socs.
+Xway needs 2 quirks that we need to disable for falcon to also work with
+this code.
+
+* EBU irq does not need to send a special ack to the EBU
+* The EIU does not exist
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+Signed-off-by: Thomas Langer <thomas.langer@lantiq.com>
+Cc: linux-mips@linux-mips.org
+---
+ arch/mips/lantiq/irq.c |   24 +++++++++++++-----------
+ 1 files changed, 13 insertions(+), 11 deletions(-)
+
+diff --git a/arch/mips/lantiq/irq.c b/arch/mips/lantiq/irq.c
+index f9737bb..17c057f 100644
+--- a/arch/mips/lantiq/irq.c
++++ b/arch/mips/lantiq/irq.c
+@@ -195,7 +195,7 @@ static void ltq_hw_irqdispatch(int module)
+       do_IRQ((int)irq + INT_NUM_IM0_IRL0 + (INT_NUM_IM_OFFSET * module));
+       /* if this is a EBU irq, we need to ack it or get a deadlock */
+-      if ((irq == LTQ_ICU_EBU_IRQ) && (module == 0))
++      if ((irq == LTQ_ICU_EBU_IRQ) && (module == 0) && LTQ_EBU_PCC_ISTAT)
+               ltq_ebu_w32(ltq_ebu_r32(LTQ_EBU_PCC_ISTAT) | 0x10,
+                       LTQ_EBU_PCC_ISTAT);
+ }
+@@ -260,17 +260,19 @@ void __init arch_init_irq(void)
+       if (!ltq_icu_membase)
+               panic("Failed to remap icu memory\n");
+-      if (insert_resource(&iomem_resource, &ltq_eiu_resource) < 0)
+-              panic("Failed to insert eiu memory\n");
++      if (LTQ_EIU_BASE_ADDR) {
++              if (insert_resource(&iomem_resource, &ltq_eiu_resource) < 0)
++                      panic("Failed to insert eiu memory\n");
+-      if (request_mem_region(ltq_eiu_resource.start,
+-                      resource_size(&ltq_eiu_resource), "eiu") < 0)
+-              panic("Failed to request eiu memory\n");
++              if (request_mem_region(ltq_eiu_resource.start,
++                              resource_size(&ltq_eiu_resource), "eiu") < 0)
++                      panic("Failed to request eiu memory\n");
+-      ltq_eiu_membase = ioremap_nocache(ltq_eiu_resource.start,
++              ltq_eiu_membase = ioremap_nocache(ltq_eiu_resource.start,
+                               resource_size(&ltq_eiu_resource));
+-      if (!ltq_eiu_membase)
+-              panic("Failed to remap eiu memory\n");
++              if (!ltq_eiu_membase)
++                      panic("Failed to remap eiu memory\n");
++      }
+       /* make sure all irqs are turned off by default */
+       for (i = 0; i < 5; i++)
+@@ -296,8 +298,8 @@ void __init arch_init_irq(void)
+       for (i = INT_NUM_IRQ0;
+               i <= (INT_NUM_IRQ0 + (5 * INT_NUM_IM_OFFSET)); i++)
+-              if ((i == LTQ_EIU_IR0) || (i == LTQ_EIU_IR1) ||
+-                      (i == LTQ_EIU_IR2))
++              if (((i == LTQ_EIU_IR0) || (i == LTQ_EIU_IR1) ||
++                      (i == LTQ_EIU_IR2)) && LTQ_EIU_BASE_ADDR)
+                       irq_set_chip_and_handler(i, &ltq_eiu_type,
+                               handle_level_irq);
+               /* EIU3-5 only exist on ar9 and vr9 */
+-- 
+1.7.5.4
+
diff --git a/target/linux/lantiq/patches-3.0/0006-MIPS-lantiq-add-basic-support-for-FALC-ON.patch b/target/linux/lantiq/patches-3.0/0006-MIPS-lantiq-add-basic-support-for-FALC-ON.patch
new file mode 100644 (file)
index 0000000..e4a0b9f
--- /dev/null
@@ -0,0 +1,1064 @@
+From ff57bc17a9964d24708759c6d78a51e337563d5f Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Thu, 11 Aug 2011 14:33:04 +0200
+Subject: [PATCH 06/24] MIPS: lantiq: add basic support for FALC-ON
+
+Adds support for the FALC-ON SoC. This SoC is from the fiber to the home GPON
+series.
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+Signed-off-by: Thomas Langer <thomas.langer@lantiq.com>
+Cc: linux-mips@linux-mips.org
+---
+ .../include/asm/mach-lantiq/falcon/falcon_irq.h    |  268 ++++++++++++++++++++
+ arch/mips/include/asm/mach-lantiq/falcon/irq.h     |   18 ++
+ .../include/asm/mach-lantiq/falcon/lantiq_soc.h    |  140 ++++++++++
+ arch/mips/include/asm/mach-lantiq/lantiq.h         |    1 +
+ arch/mips/lantiq/Kconfig                           |    4 +
+ arch/mips/lantiq/Makefile                          |    1 +
+ arch/mips/lantiq/Platform                          |    1 +
+ arch/mips/lantiq/falcon/Makefile                   |    1 +
+ arch/mips/lantiq/falcon/clk.c                      |   44 ++++
+ arch/mips/lantiq/falcon/devices.c                  |   87 +++++++
+ arch/mips/lantiq/falcon/devices.h                  |   18 ++
+ arch/mips/lantiq/falcon/prom.c                     |   72 ++++++
+ arch/mips/lantiq/falcon/reset.c                    |   87 +++++++
+ arch/mips/lantiq/falcon/sysctrl.c                  |  181 +++++++++++++
+ 14 files changed, 923 insertions(+), 0 deletions(-)
+ create mode 100644 arch/mips/include/asm/mach-lantiq/falcon/falcon_irq.h
+ create mode 100644 arch/mips/include/asm/mach-lantiq/falcon/irq.h
+ create mode 100644 arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h
+ create mode 100644 arch/mips/lantiq/falcon/Makefile
+ create mode 100644 arch/mips/lantiq/falcon/clk.c
+ create mode 100644 arch/mips/lantiq/falcon/devices.c
+ create mode 100644 arch/mips/lantiq/falcon/devices.h
+ create mode 100644 arch/mips/lantiq/falcon/prom.c
+ create mode 100644 arch/mips/lantiq/falcon/reset.c
+ create mode 100644 arch/mips/lantiq/falcon/sysctrl.c
+
+diff --git a/arch/mips/include/asm/mach-lantiq/falcon/falcon_irq.h b/arch/mips/include/asm/mach-lantiq/falcon/falcon_irq.h
+new file mode 100644
+index 0000000..4dc6466
+--- /dev/null
++++ b/arch/mips/include/asm/mach-lantiq/falcon/falcon_irq.h
+@@ -0,0 +1,268 @@
++/*
++ *  This program is free software; you can redistribute it and/or modify it
++ *  under the terms of the GNU General Public License version 2 as published
++ *  by the Free Software Foundation.
++ *
++ *  Copyright (C) 2010 Thomas Langer <thomas.langer@lantiq.com>
++ */
++
++#ifndef _FALCON_IRQ__
++#define _FALCON_IRQ__
++
++#define INT_NUM_IRQ0                  8
++#define INT_NUM_IM0_IRL0              (INT_NUM_IRQ0 + 0)
++#define INT_NUM_IM1_IRL0              (INT_NUM_IM0_IRL0 + 32)
++#define INT_NUM_IM2_IRL0              (INT_NUM_IM1_IRL0 + 32)
++#define INT_NUM_IM3_IRL0              (INT_NUM_IM2_IRL0 + 32)
++#define INT_NUM_IM4_IRL0              (INT_NUM_IM3_IRL0 + 32)
++#define INT_NUM_EXTRA_START           (INT_NUM_IM4_IRL0 + 32)
++#define INT_NUM_IM_OFFSET             (INT_NUM_IM1_IRL0 - INT_NUM_IM0_IRL0)
++
++#define MIPS_CPU_TIMER_IRQ                    7
++
++/* HOST IF Event Interrupt */
++#define FALCON_IRQ_HOST                               (INT_NUM_IM0_IRL0 + 0)
++/* HOST IF Mailbox0 Receive Interrupt */
++#define FALCON_IRQ_HOST_MB0_RX                        (INT_NUM_IM0_IRL0 + 1)
++/* HOST IF Mailbox0 Transmit Interrupt */
++#define FALCON_IRQ_HOST_MB0_TX                        (INT_NUM_IM0_IRL0 + 2)
++/* HOST IF Mailbox1 Receive Interrupt */
++#define FALCON_IRQ_HOST_MB1_RX                        (INT_NUM_IM0_IRL0 + 3)
++/* HOST IF Mailbox1 Transmit Interrupt */
++#define FALCON_IRQ_HOST_MB1_TX                        (INT_NUM_IM0_IRL0 + 4)
++/* I2C Last Single Data Transfer Request */
++#define FALCON_IRQ_I2C_LSREQ                  (INT_NUM_IM0_IRL0 + 8)
++/* I2C Single Data Transfer Request */
++#define FALCON_IRQ_I2C_SREQ                   (INT_NUM_IM0_IRL0 + 9)
++/* I2C Last Burst Data Transfer Request */
++#define FALCON_IRQ_I2C_LBREQ                  (INT_NUM_IM0_IRL0 + 10)
++/* I2C Burst Data Transfer Request */
++#define FALCON_IRQ_I2C_BREQ                   (INT_NUM_IM0_IRL0 + 11)
++/* I2C Error Interrupt */
++#define FALCON_IRQ_I2C_I2C_ERR                        (INT_NUM_IM0_IRL0 + 12)
++/* I2C Protocol Interrupt */
++#define FALCON_IRQ_I2C_I2C_P                  (INT_NUM_IM0_IRL0 + 13)
++/* SSC Transmit Interrupt */
++#define FALCON_IRQ_SSC_T                      (INT_NUM_IM0_IRL0 + 14)
++/* SSC Receive Interrupt */
++#define FALCON_IRQ_SSC_R                      (INT_NUM_IM0_IRL0 + 15)
++/* SSC Error Interrupt */
++#define FALCON_IRQ_SSC_E                      (INT_NUM_IM0_IRL0 + 16)
++/* SSC Frame Interrupt */
++#define FALCON_IRQ_SSC_F                      (INT_NUM_IM0_IRL0 + 17)
++/* Advanced Encryption Standard Interrupt */
++#define FALCON_IRQ_AES_AES                    (INT_NUM_IM0_IRL0 + 27)
++/* Secure Hash Algorithm Interrupt */
++#define FALCON_IRQ_SHA_HASH                   (INT_NUM_IM0_IRL0 + 28)
++/* PCM Receive Interrupt */
++#define FALCON_IRQ_PCM_RX                     (INT_NUM_IM0_IRL0 + 29)
++/* PCM Transmit Interrupt */
++#define FALCON_IRQ_PCM_TX                     (INT_NUM_IM0_IRL0 + 30)
++/* PCM Transmit Crash Interrupt */
++#define FALCON_IRQ_PCM_HW2_CRASH              (INT_NUM_IM0_IRL0 + 31)
++
++/* EBU Serial Flash Command Error */
++#define FALCON_IRQ_EBU_SF_CMDERR              (INT_NUM_IM1_IRL0 + 0)
++/* EBU Serial Flash Command Overwrite Error */
++#define FALCON_IRQ_EBU_SF_COVERR              (INT_NUM_IM1_IRL0 + 1)
++/* EBU Serial Flash Busy */
++#define FALCON_IRQ_EBU_SF_BUSY                        (INT_NUM_IM1_IRL0 + 2)
++/* External Interrupt from GPIO P0 */
++#define FALCON_IRQ_GPIO_P0                    (INT_NUM_IM1_IRL0 + 4)
++/* External Interrupt from GPIO P1 */
++#define FALCON_IRQ_GPIO_P1                    (INT_NUM_IM1_IRL0 + 5)
++/* External Interrupt from GPIO P2 */
++#define FALCON_IRQ_GPIO_P2                    (INT_NUM_IM1_IRL0 + 6)
++/* External Interrupt from GPIO P3 */
++#define FALCON_IRQ_GPIO_P3                    (INT_NUM_IM1_IRL0 + 7)
++/* External Interrupt from GPIO P4 */
++#define FALCON_IRQ_GPIO_P4                    (INT_NUM_IM1_IRL0 + 8)
++/* 8kHz backup interrupt derived from core-PLL */
++#define FALCON_IRQ_FSC_BKP                    (INT_NUM_IM1_IRL0 + 10)
++/* FSC Timer Interrupt 0 */
++#define FALCON_IRQ_FSCT_CMP0                  (INT_NUM_IM1_IRL0 + 11)
++/* FSC Timer Interrupt 1 */
++#define FALCON_IRQ_FSCT_CMP1                  (INT_NUM_IM1_IRL0 + 12)
++/* 8kHz root interrupt derived from GPON interface */
++#define FALCON_IRQ_FSC_ROOT                   (INT_NUM_IM1_IRL0 + 13)
++/* Time of Day */
++#define FALCON_IRQ_TOD                                (INT_NUM_IM1_IRL0 + 14)
++/* PMA Interrupt from IntNode of the 200MHz Domain */
++#define FALCON_IRQ_PMA_200M                   (INT_NUM_IM1_IRL0 + 15)
++/* PMA Interrupt from IntNode of the TX Clk Domain */
++#define FALCON_IRQ_PMA_TX                     (INT_NUM_IM1_IRL0 + 16)
++/* PMA Interrupt from IntNode of the RX Clk Domain */
++#define FALCON_IRQ_PMA_RX                     (INT_NUM_IM1_IRL0 + 17)
++/* SYS1 Interrupt */
++#define FALCON_IRQ_SYS1                               (INT_NUM_IM1_IRL0 + 20)
++/* SYS GPE Interrupt */
++#define FALCON_IRQ_SYS_GPE                    (INT_NUM_IM1_IRL0 + 21)
++/* Watchdog Access Error Interrupt */
++#define FALCON_IRQ_WDT_AEIR                   (INT_NUM_IM1_IRL0 + 24)
++/* Watchdog Prewarning Interrupt */
++#define FALCON_IRQ_WDT_PIR                    (INT_NUM_IM1_IRL0 + 25)
++/* SBIU interrupt */
++#define FALCON_IRQ_SBIU0                      (INT_NUM_IM1_IRL0 + 27)
++/* FPI Bus Control Unit Interrupt */
++#define FALCON_IRQ_BCU0                               (INT_NUM_IM1_IRL0 + 29)
++/* DDR Controller Interrupt */
++#define FALCON_IRQ_DDR                                (INT_NUM_IM1_IRL0 + 30)
++/* Crossbar Error Interrupt */
++#define FALCON_IRQ_XBAR_ERROR                 (INT_NUM_IM1_IRL0 + 31)
++
++/* ICTRLL 0 Interrupt */
++#define FALCON_IRQ_ICTRLL0                    (INT_NUM_IM2_IRL0 + 0)
++/* ICTRLL 1 Interrupt */
++#define FALCON_IRQ_ICTRLL1                    (INT_NUM_IM2_IRL0 + 1)
++/* ICTRLL 2 Interrupt */
++#define FALCON_IRQ_ICTRLL2                    (INT_NUM_IM2_IRL0 + 2)
++/* ICTRLL 3 Interrupt */
++#define FALCON_IRQ_ICTRLL3                    (INT_NUM_IM2_IRL0 + 3)
++/* OCTRLL 0 Interrupt */
++#define FALCON_IRQ_OCTRLL0                    (INT_NUM_IM2_IRL0 + 4)
++/* OCTRLL 1 Interrupt */
++#define FALCON_IRQ_OCTRLL1                    (INT_NUM_IM2_IRL0 + 5)
++/* OCTRLL 2 Interrupt */
++#define FALCON_IRQ_OCTRLL2                    (INT_NUM_IM2_IRL0 + 6)
++/* OCTRLL 3 Interrupt */
++#define FALCON_IRQ_OCTRLL3                    (INT_NUM_IM2_IRL0 + 7)
++/* OCTRLG Interrupt */
++#define FALCON_IRQ_OCTRLG                     (INT_NUM_IM2_IRL0 + 9)
++/* IQM Interrupt */
++#define FALCON_IRQ_IQM                                (INT_NUM_IM2_IRL0 + 10)
++/* FSQM Interrupt */
++#define FALCON_IRQ_FSQM                               (INT_NUM_IM2_IRL0 + 11)
++/* TMU Interrupt */
++#define FALCON_IRQ_TMU                                (INT_NUM_IM2_IRL0 + 12)
++/* LINK1 Interrupt */
++#define FALCON_IRQ_LINK1                      (INT_NUM_IM2_IRL0 + 14)
++/* ICTRLC 0 Interrupt */
++#define FALCON_IRQ_ICTRLC0                    (INT_NUM_IM2_IRL0 + 16)
++/* ICTRLC 1 Interrupt */
++#define FALCON_IRQ_ICTRLC1                    (INT_NUM_IM2_IRL0 + 17)
++/* OCTRLC Interrupt */
++#define FALCON_IRQ_OCTRLC                     (INT_NUM_IM2_IRL0 + 18)
++/* CONFIG Break Interrupt */
++#define FALCON_IRQ_CONFIG_BREAK                       (INT_NUM_IM2_IRL0 + 19)
++/* CONFIG Interrupt */
++#define FALCON_IRQ_CONFIG                     (INT_NUM_IM2_IRL0 + 20)
++/* Dispatcher Interrupt */
++#define FALCON_IRQ_DISP                               (INT_NUM_IM2_IRL0 + 21)
++/* TBM Interrupt */
++#define FALCON_IRQ_TBM                                (INT_NUM_IM2_IRL0 + 22)
++/* GTC Downstream Interrupt */
++#define FALCON_IRQ_GTC_DS                     (INT_NUM_IM2_IRL0 + 29)
++/* GTC Upstream Interrupt */
++#define FALCON_IRQ_GTC_US                     (INT_NUM_IM2_IRL0 + 30)
++/* EIM Interrupt */
++#define FALCON_IRQ_EIM                                (INT_NUM_IM2_IRL0 + 31)
++
++/* ASC0 Transmit Interrupt */
++#define FALCON_IRQ_ASC0_T                     (INT_NUM_IM3_IRL0 + 0)
++/* ASC0 Receive Interrupt */
++#define FALCON_IRQ_ASC0_R                     (INT_NUM_IM3_IRL0 + 1)
++/* ASC0 Error Interrupt */
++#define FALCON_IRQ_ASC0_E                     (INT_NUM_IM3_IRL0 + 2)
++/* ASC0 Transmit Buffer Interrupt */
++#define FALCON_IRQ_ASC0_TB                    (INT_NUM_IM3_IRL0 + 3)
++/* ASC0 Autobaud Start Interrupt */
++#define FALCON_IRQ_ASC0_ABST                  (INT_NUM_IM3_IRL0 + 4)
++/* ASC0 Autobaud Detection Interrupt */
++#define FALCON_IRQ_ASC0_ABDET                 (INT_NUM_IM3_IRL0 + 5)
++/* ASC1 Modem Status Interrupt */
++#define FALCON_IRQ_ASC0_MS                    (INT_NUM_IM3_IRL0 + 6)
++/* ASC0 Soft Flow Control Interrupt */
++#define FALCON_IRQ_ASC0_SFC                   (INT_NUM_IM3_IRL0 + 7)
++/* ASC1 Transmit Interrupt */
++#define FALCON_IRQ_ASC1_T                     (INT_NUM_IM3_IRL0 + 8)
++/* ASC1 Receive Interrupt */
++#define FALCON_IRQ_ASC1_R                     (INT_NUM_IM3_IRL0 + 9)
++/* ASC1 Error Interrupt */
++#define FALCON_IRQ_ASC1_E                     (INT_NUM_IM3_IRL0 + 10)
++/* ASC1 Transmit Buffer Interrupt */
++#define FALCON_IRQ_ASC1_TB                    (INT_NUM_IM3_IRL0 + 11)
++/* ASC1 Autobaud Start Interrupt */
++#define FALCON_IRQ_ASC1_ABST                  (INT_NUM_IM3_IRL0 + 12)
++/* ASC1 Autobaud Detection Interrupt */
++#define FALCON_IRQ_ASC1_ABDET                 (INT_NUM_IM3_IRL0 + 13)
++/* ASC1 Modem Status Interrupt */
++#define FALCON_IRQ_ASC1_MS                    (INT_NUM_IM3_IRL0 + 14)
++/* ASC1 Soft Flow Control Interrupt */
++#define FALCON_IRQ_ASC1_SFC                   (INT_NUM_IM3_IRL0 + 15)
++/* GPTC Timer/Counter 1A Interrupt */
++#define FALCON_IRQ_GPTC_TC1A                  (INT_NUM_IM3_IRL0 + 16)
++/* GPTC Timer/Counter 1B Interrupt */
++#define FALCON_IRQ_GPTC_TC1B                  (INT_NUM_IM3_IRL0 + 17)
++/* GPTC Timer/Counter 2A Interrupt */
++#define FALCON_IRQ_GPTC_TC2A                  (INT_NUM_IM3_IRL0 + 18)
++/* GPTC Timer/Counter 2B Interrupt */
++#define FALCON_IRQ_GPTC_TC2B                  (INT_NUM_IM3_IRL0 + 19)
++/* GPTC Timer/Counter 3A Interrupt */
++#define FALCON_IRQ_GPTC_TC3A                  (INT_NUM_IM3_IRL0 + 20)
++/* GPTC Timer/Counter 3B Interrupt */
++#define FALCON_IRQ_GPTC_TC3B                  (INT_NUM_IM3_IRL0 + 21)
++/* DFEV0, Channel 1 Transmit Interrupt */
++#define FALCON_IRQ_DFEV0_2TX                  (INT_NUM_IM3_IRL0 + 26)
++/* DFEV0, Channel 1 Receive Interrupt */
++#define FALCON_IRQ_DFEV0_2RX                  (INT_NUM_IM3_IRL0 + 27)
++/* DFEV0, Channel 1 General Purpose Interrupt */
++#define FALCON_IRQ_DFEV0_2GP                  (INT_NUM_IM3_IRL0 + 28)
++/* DFEV0, Channel 0 Transmit Interrupt */
++#define FALCON_IRQ_DFEV0_1TX                  (INT_NUM_IM3_IRL0 + 29)
++/* DFEV0, Channel 0 Receive Interrupt */
++#define FALCON_IRQ_DFEV0_1RX                  (INT_NUM_IM3_IRL0 + 30)
++/* DFEV0, Channel 0 General Purpose Interrupt */
++#define FALCON_IRQ_DFEV0_1GP                  (INT_NUM_IM3_IRL0 + 31)
++
++/* ICTRLL 0 Error */
++#define FALCON_IRQ_ICTRLL0_ERR                        (INT_NUM_IM4_IRL0 + 0)
++/* ICTRLL 1 Error */
++#define FALCON_IRQ_ICTRLL1_ERR                        (INT_NUM_IM4_IRL0 + 1)
++/* ICTRLL 2 Error */
++#define FALCON_IRQ_ICTRLL2_ERR                        (INT_NUM_IM4_IRL0 + 2)
++/* ICTRLL 3 Error */
++#define FALCON_IRQ_ICTRLL3_ERR                        (INT_NUM_IM4_IRL0 + 3)
++/* OCTRLL 0 Error */
++#define FALCON_IRQ_OCTRLL0_ERR                        (INT_NUM_IM4_IRL0 + 4)
++/* OCTRLL 1 Error */
++#define FALCON_IRQ_OCTRLL1_ERR                        (INT_NUM_IM4_IRL0 + 5)
++/* OCTRLL 2 Error */
++#define FALCON_IRQ_OCTRLL2_ERR                        (INT_NUM_IM4_IRL0 + 6)
++/* OCTRLL 3 Error */
++#define FALCON_IRQ_OCTRLL3_ERR                        (INT_NUM_IM4_IRL0 + 7)
++/* ICTRLG Error */
++#define FALCON_IRQ_ICTRLG_ERR                 (INT_NUM_IM4_IRL0 + 8)
++/* OCTRLG Error */
++#define FALCON_IRQ_OCTRLG_ERR                 (INT_NUM_IM4_IRL0 + 9)
++/* IQM Error */
++#define FALCON_IRQ_IQM_ERR                    (INT_NUM_IM4_IRL0 + 10)
++/* FSQM Error */
++#define FALCON_IRQ_FSQM_ERR                   (INT_NUM_IM4_IRL0 + 11)
++/* TMU Error */
++#define FALCON_IRQ_TMU_ERR                    (INT_NUM_IM4_IRL0 + 12)
++/* MPS Status Interrupt #0 (VPE1 to VPE0) */
++#define FALCON_IRQ_MPS_IR0                    (INT_NUM_IM4_IRL0 + 14)
++/* MPS Status Interrupt #1 (VPE1 to VPE0) */
++#define FALCON_IRQ_MPS_IR1                    (INT_NUM_IM4_IRL0 + 15)
++/* MPS Status Interrupt #2 (VPE1 to VPE0) */
++#define FALCON_IRQ_MPS_IR2                    (INT_NUM_IM4_IRL0 + 16)
++/* MPS Status Interrupt #3 (VPE1 to VPE0) */
++#define FALCON_IRQ_MPS_IR3                    (INT_NUM_IM4_IRL0 + 17)
++/* MPS Status Interrupt #4 (VPE1 to VPE0) */
++#define FALCON_IRQ_MPS_IR4                    (INT_NUM_IM4_IRL0 + 18)
++/* MPS Status Interrupt #5 (VPE1 to VPE0) */
++#define FALCON_IRQ_MPS_IR5                    (INT_NUM_IM4_IRL0 + 19)
++/* MPS Status Interrupt #6 (VPE1 to VPE0) */
++#define FALCON_IRQ_MPS_IR6                    (INT_NUM_IM4_IRL0 + 20)
++/* MPS Status Interrupt #7 (VPE1 to VPE0) */
++#define FALCON_IRQ_MPS_IR7                    (INT_NUM_IM4_IRL0 + 21)
++/* MPS Status Interrupt #8 (VPE1 to VPE0) */
++#define FALCON_IRQ_MPS_IR8                    (INT_NUM_IM4_IRL0 + 22)
++/* VPE0 Exception Level Flag Interrupt */
++#define FALCON_IRQ_VPE0_EXL                   (INT_NUM_IM4_IRL0 + 29)
++/* VPE0 Error Level Flag Interrupt */
++#define FALCON_IRQ_VPE0_ERL                   (INT_NUM_IM4_IRL0 + 30)
++/* VPE0 Performance Monitoring Counter Interrupt */
++#define FALCON_IRQ_VPE0_PMCIR                 (INT_NUM_IM4_IRL0 + 31)
++
++#endif /* _FALCON_IRQ__ */
+diff --git a/arch/mips/include/asm/mach-lantiq/falcon/irq.h b/arch/mips/include/asm/mach-lantiq/falcon/irq.h
+new file mode 100644
+index 0000000..2caccd9
+--- /dev/null
++++ b/arch/mips/include/asm/mach-lantiq/falcon/irq.h
+@@ -0,0 +1,18 @@
++/*
++ *  This program is free software; you can redistribute it and/or modify it
++ *  under the terms of the GNU General Public License version 2 as published
++ *  by the Free Software Foundation.
++ *
++ *  Copyright (C) 2011 Thomas Langer <thomas.langer@lantiq.com>
++ */
++
++#ifndef __FALCON_IRQ_H
++#define __FALCON_IRQ_H
++
++#include <falcon_irq.h>
++
++#define NR_IRQS 328
++
++#include_next <irq.h>
++
++#endif
+diff --git a/arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h b/arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h
+new file mode 100644
+index 0000000..c092531
+--- /dev/null
++++ b/arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h
+@@ -0,0 +1,140 @@
++/*
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 as published
++ * by the Free Software Foundation.
++ *
++ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
++ */
++
++#ifndef _LTQ_FALCON_H__
++#define _LTQ_FALCON_H__
++
++#ifdef CONFIG_SOC_FALCON
++
++#include <lantiq.h>
++
++/* Chip IDs */
++#define SOC_ID_FALCON         0x01B8
++
++/* SoC Types */
++#define SOC_TYPE_FALCON               0x01
++
++/* ASC0/1 - serial port */
++#define LTQ_ASC0_BASE_ADDR    0x1E100C00
++#define LTQ_ASC1_BASE_ADDR    0x1E100B00
++#define LTQ_ASC_SIZE          0x100
++
++#define LTQ_ASC_TIR(x)          (INT_NUM_IM3_IRL0 + (x * 8))
++#define LTQ_ASC_RIR(x)          (INT_NUM_IM3_IRL0 + (x * 8) + 1)
++#define LTQ_ASC_EIR(x)          (INT_NUM_IM3_IRL0 + (x * 8) + 2)
++
++/* during early_printk no ioremap possible at this early stage
++   lets use KSEG1 instead  */
++#define LTQ_EARLY_ASC         KSEG1ADDR(LTQ_ASC0_BASE_ADDR)
++
++/* ICU - interrupt control unit */
++#define LTQ_ICU_BASE_ADDR     0x1F880200
++#define LTQ_ICU_SIZE          0x100
++
++/* WDT */
++#define LTQ_WDT_BASE_ADDR     0x1F8803F0
++#define LTQ_WDT_SIZE          0x10
++
++#define LTQ_RST_CAUSE_WDTRST  0x0002
++
++/* EBU - external bus unit */
++#define LTQ_EBU_BASE_ADDR       0x18000000
++#define LTQ_EBU_SIZE            0x0100
++
++#define LTQ_EBU_MODCON  0x000C
++
++/* GPIO */
++#define LTQ_GPIO0_BASE_ADDR     0x1D810000
++#define LTQ_GPIO0_SIZE          0x0080
++#define LTQ_GPIO1_BASE_ADDR     0x1E800100
++#define LTQ_GPIO1_SIZE          0x0080
++#define LTQ_GPIO2_BASE_ADDR     0x1D810100
++#define LTQ_GPIO2_SIZE          0x0080
++#define LTQ_GPIO3_BASE_ADDR     0x1E800200
++#define LTQ_GPIO3_SIZE          0x0080
++#define LTQ_GPIO4_BASE_ADDR     0x1E800300
++#define LTQ_GPIO4_SIZE          0x0080
++#define LTQ_PADCTRL0_BASE_ADDR  0x1DB01000
++#define LTQ_PADCTRL0_SIZE       0x0100
++#define LTQ_PADCTRL1_BASE_ADDR  0x1E800400
++#define LTQ_PADCTRL1_SIZE       0x0100
++#define LTQ_PADCTRL2_BASE_ADDR  0x1DB02000
++#define LTQ_PADCTRL2_SIZE       0x0100
++#define LTQ_PADCTRL3_BASE_ADDR  0x1E800500
++#define LTQ_PADCTRL3_SIZE       0x0100
++#define LTQ_PADCTRL4_BASE_ADDR  0x1E800600
++#define LTQ_PADCTRL4_SIZE       0x0100
++
++/* CHIP ID */
++#define LTQ_STATUS_BASE_ADDR  0x1E802000
++
++#define LTQ_FALCON_CHIPID     ((u32 *)(KSEG1 + LTQ_STATUS_BASE_ADDR + 0x0c))
++#define LTQ_FALCON_CHIPCONF   ((u32 *)(KSEG1 + LTQ_STATUS_BASE_ADDR + 0x40))
++
++/* SYSCTL - start/stop/restart/configure/... different parts of the Soc */
++#define LTQ_SYS1_BASE_ADDR      0x1EF00000
++#define LTQ_SYS1_SIZE           0x0100
++#define LTQ_STATUS_BASE_ADDR  0x1E802000
++#define LTQ_STATUS_SIZE               0x0080
++#define LTQ_SYS_ETH_BASE_ADDR 0x1DB00000
++#define LTQ_SYS_ETH_SIZE      0x0100
++#define LTQ_SYS_GPE_BASE_ADDR 0x1D700000
++#define LTQ_SYS_GPE_SIZE      0x0100
++
++#define SYSCTL_SYS1           0
++#define SYSCTL_SYSETH         1
++#define SYSCTL_SYSGPE         2
++
++/* Activation Status Register */
++#define ACTS_ASC1_ACT 0x00000800
++#define ACTS_P0               0x00010000
++#define ACTS_P1               0x00010000
++#define ACTS_P2               0x00020000
++#define ACTS_P3               0x00020000
++#define ACTS_P4               0x00040000
++#define ACTS_PADCTRL0 0x00100000
++#define ACTS_PADCTRL1 0x00100000
++#define ACTS_PADCTRL2 0x00200000
++#define ACTS_PADCTRL3 0x00200000
++#define ACTS_PADCTRL4 0x00400000
++
++extern void ltq_sysctl_activate(int module, unsigned int mask);
++extern void ltq_sysctl_deactivate(int module, unsigned int mask);
++extern void ltq_sysctl_clken(int module, unsigned int mask);
++extern void ltq_sysctl_clkdis(int module, unsigned int mask);
++extern void ltq_sysctl_reboot(int module, unsigned int mask);
++extern int ltq_gpe_is_activated(unsigned int mask);
++
++/* global register ranges */
++extern __iomem void *ltq_ebu_membase;
++extern __iomem void *ltq_sys1_membase;
++#define ltq_ebu_w32(x, y)     ltq_w32((x), ltq_ebu_membase + (y))
++#define ltq_ebu_r32(x)                ltq_r32(ltq_ebu_membase + (x))
++#define ltq_ebu_w32_mask(clear, set, reg)   \
++      ltq_ebu_w32((ltq_ebu_r32(reg) & ~(clear)) | (set), reg)
++
++#define ltq_sys1_w32(x, y)    ltq_w32((x), ltq_sys1_membase + (y))
++#define ltq_sys1_r32(x)               ltq_r32(ltq_sys1_membase + (x))
++#define ltq_sys1_w32_mask(clear, set, reg)   \
++      ltq_sys1_w32((ltq_sys1_r32(reg) & ~(clear)) | (set), reg)
++
++/* gpio_request wrapper to help configure the pin */
++extern int ltq_gpio_request(unsigned int pin, unsigned int val,
++                              unsigned int dir, const char *name);
++extern int ltq_gpio_mux_set(unsigned int pin, unsigned int mux);
++
++/* to keep the irq code generic we need to define these to 0 as falcon
++   has no EIU/EBU */
++#define LTQ_EIU_BASE_ADDR     0
++#define LTQ_EBU_PCC_ISTAT     0
++
++#define ltq_is_ar9()  0
++#define ltq_is_vr9()  0
++
++#endif /* CONFIG_SOC_FALCON */
++#endif /* _LTQ_XWAY_H__ */
+diff --git a/arch/mips/include/asm/mach-lantiq/lantiq.h b/arch/mips/include/asm/mach-lantiq/lantiq.h
+index 66d7300..188de0f 100644
+--- a/arch/mips/include/asm/mach-lantiq/lantiq.h
++++ b/arch/mips/include/asm/mach-lantiq/lantiq.h
+@@ -25,6 +25,7 @@ extern unsigned int ltq_get_soc_type(void);
+ /* clock speeds */
+ #define CLOCK_60M     60000000
+ #define CLOCK_83M     83333333
++#define CLOCK_100M    100000000
+ #define CLOCK_111M    111111111
+ #define CLOCK_133M    133333333
+ #define CLOCK_167M    166666667
+diff --git a/arch/mips/lantiq/Kconfig b/arch/mips/lantiq/Kconfig
+index 3fccf21..cb6b39f 100644
+--- a/arch/mips/lantiq/Kconfig
++++ b/arch/mips/lantiq/Kconfig
+@@ -16,8 +16,12 @@ config SOC_XWAY
+       bool "XWAY"
+       select SOC_TYPE_XWAY
+       select HW_HAS_PCI
++
++config SOC_FALCON
++      bool "FALCON"
+ endchoice
+ source "arch/mips/lantiq/xway/Kconfig"
++source "arch/mips/lantiq/falcon/Kconfig"
+ endif
+diff --git a/arch/mips/lantiq/Makefile b/arch/mips/lantiq/Makefile
+index e5dae0e..7e9c69e 100644
+--- a/arch/mips/lantiq/Makefile
++++ b/arch/mips/lantiq/Makefile
+@@ -9,3 +9,4 @@ obj-y := irq.o setup.o clk.o prom.o devices.o
+ obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
+ obj-$(CONFIG_SOC_TYPE_XWAY) += xway/
++obj-$(CONFIG_SOC_FALCON) += falcon/
+diff --git a/arch/mips/lantiq/Platform b/arch/mips/lantiq/Platform
+index f3dff05..b3ec498 100644
+--- a/arch/mips/lantiq/Platform
++++ b/arch/mips/lantiq/Platform
+@@ -6,3 +6,4 @@ platform-$(CONFIG_LANTIQ)      += lantiq/
+ cflags-$(CONFIG_LANTIQ)               += -I$(srctree)/arch/mips/include/asm/mach-lantiq
+ load-$(CONFIG_LANTIQ)         = 0xffffffff80002000
+ cflags-$(CONFIG_SOC_TYPE_XWAY)        += -I$(srctree)/arch/mips/include/asm/mach-lantiq/xway
++cflags-$(CONFIG_SOC_FALCON)   += -I$(srctree)/arch/mips/include/asm/mach-lantiq/falcon
+diff --git a/arch/mips/lantiq/falcon/Makefile b/arch/mips/lantiq/falcon/Makefile
+new file mode 100644
+index 0000000..e9c7455
+--- /dev/null
++++ b/arch/mips/lantiq/falcon/Makefile
+@@ -0,0 +1 @@
++obj-y := clk.o prom.o reset.o sysctrl.o devices.o
+diff --git a/arch/mips/lantiq/falcon/clk.c b/arch/mips/lantiq/falcon/clk.c
+new file mode 100644
+index 0000000..1a550ea
+--- /dev/null
++++ b/arch/mips/lantiq/falcon/clk.c
+@@ -0,0 +1,44 @@
++/*
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 as published
++ * by the Free Software Foundation.
++ *
++ * Copyright (C) 2011 Thomas Langer <thomas.langer@lantiq.com>
++ * Copyright (C) 2011 John Crispin <blogic@openwrt.org>
++ */
++
++#include <linux/ioport.h>
++#include <linux/module.h>
++
++#include <lantiq_soc.h>
++
++#include "devices.h"
++
++/* CPU0 Clock Control Register */
++#define LTQ_SYS1_CPU0CC               0x0040
++/* clock divider bit */
++#define LTQ_CPU0CC_CPUDIV     0x0001
++
++unsigned int
++ltq_get_io_region_clock(void)
++{
++      return CLOCK_200M;
++}
++EXPORT_SYMBOL(ltq_get_io_region_clock);
++
++unsigned int
++ltq_get_cpu_hz(void)
++{
++      if (ltq_sys1_r32(LTQ_SYS1_CPU0CC) & LTQ_CPU0CC_CPUDIV)
++              return CLOCK_200M;
++      else
++              return CLOCK_400M;
++}
++EXPORT_SYMBOL(ltq_get_cpu_hz);
++
++unsigned int
++ltq_get_fpi_hz(void)
++{
++      return CLOCK_100M;
++}
++EXPORT_SYMBOL(ltq_get_fpi_hz);
+diff --git a/arch/mips/lantiq/falcon/devices.c b/arch/mips/lantiq/falcon/devices.c
+new file mode 100644
+index 0000000..c4606f2
+--- /dev/null
++++ b/arch/mips/lantiq/falcon/devices.c
+@@ -0,0 +1,87 @@
++/*
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 as published
++ * by the Free Software Foundation.
++ *
++ * Copyright (C) 2011 Thomas Langer <thomas.langer@lantiq.com>
++ * Copyright (C) 2011 John Crispin <blogic@openwrt.org>
++ */
++
++#include <linux/platform_device.h>
++#include <linux/mtd/nand.h>
++
++#include <lantiq_soc.h>
++
++#include "devices.h"
++
++/* nand flash */
++/* address lines used for NAND control signals */
++#define NAND_ADDR_ALE         0x10000
++#define NAND_ADDR_CLE         0x20000
++/* Ready/Busy Status */
++#define MODCON_STS            0x0002
++/* Ready/Busy Status Edge */
++#define MODCON_STSEDGE                0x0004
++
++static const char *part_probes[] = { "cmdlinepart", NULL };
++
++static int
++falcon_nand_ready(struct mtd_info *mtd)
++{
++      u32 modcon = ltq_ebu_r32(LTQ_EBU_MODCON);
++
++      return (((modcon & (MODCON_STS | MODCON_STSEDGE)) ==
++                                              (MODCON_STS | MODCON_STSEDGE)));
++}
++
++static void
++falcon_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
++{
++      struct nand_chip *this = mtd->priv;
++      unsigned long nandaddr = (unsigned long) this->IO_ADDR_W;
++
++      if (ctrl & NAND_CTRL_CHANGE) {
++              nandaddr &= ~(NAND_ADDR_ALE | NAND_ADDR_CLE);
++
++              if (ctrl & NAND_CLE)
++                      nandaddr |= NAND_ADDR_CLE;
++              if (ctrl & NAND_ALE)
++                      nandaddr |= NAND_ADDR_ALE;
++
++              this->IO_ADDR_W = (void __iomem *) nandaddr;
++      }
++
++      if (cmd != NAND_CMD_NONE)
++              writeb(cmd, this->IO_ADDR_W);
++}
++
++static struct platform_nand_data falcon_flash_nand_data = {
++      .chip = {
++              .nr_chips               = 1,
++              .chip_delay             = 25,
++              .part_probe_types       = part_probes,
++      },
++      .ctrl = {
++              .cmd_ctrl               = falcon_hwcontrol,
++              .dev_ready              = falcon_nand_ready,
++      }
++};
++
++static struct resource ltq_nand_res =
++      MEM_RES("nand", LTQ_FLASH_START, LTQ_FLASH_MAX);
++
++static struct platform_device ltq_flash_nand = {
++      .name           = "gen_nand",
++      .id             = -1,
++      .num_resources  = 1,
++      .resource       = &ltq_nand_res,
++      .dev            = {
++              .platform_data = &falcon_flash_nand_data,
++      },
++};
++
++void __init
++falcon_register_nand(void)
++{
++      platform_device_register(&ltq_flash_nand);
++}
+diff --git a/arch/mips/lantiq/falcon/devices.h b/arch/mips/lantiq/falcon/devices.h
+new file mode 100644
+index 0000000..e802a7c
+--- /dev/null
++++ b/arch/mips/lantiq/falcon/devices.h
+@@ -0,0 +1,18 @@
++/*
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * Copyright (C) 2011 Thomas Langer <thomas.langer@lantiq.com>
++ * Copyright (C) 2011 John Crispin <blogic@openwrt.org>
++ */
++
++#ifndef _FALCON_DEVICES_H__
++#define _FALCON_DEVICES_H__
++
++#include "../devices.h"
++
++extern void falcon_register_nand(void);
++
++#endif
+diff --git a/arch/mips/lantiq/falcon/prom.c b/arch/mips/lantiq/falcon/prom.c
+new file mode 100644
+index 0000000..89367c4
+--- /dev/null
++++ b/arch/mips/lantiq/falcon/prom.c
+@@ -0,0 +1,72 @@
++/*
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 as published
++ * by the Free Software Foundation.
++ *
++ * Copyright (C) 2011 Thomas Langer <thomas.langer@lantiq.com>
++ * Copyright (C) 2011 John Crispin <blogic@openwrt.org>
++ */
++
++#include <lantiq_soc.h>
++
++#include "devices.h"
++
++#include "../prom.h"
++
++#define SOC_FALCON            "Falcon"
++
++#define PART_SHIFT    12
++#define PART_MASK     0x0FFFF000
++#define REV_SHIFT     28
++#define REV_MASK      0xF0000000
++#define SREV_SHIFT    22
++#define SREV_MASK     0x03C00000
++
++#define MUXC_SIF_RX_PIN               112
++#define MUXC_SIF_TX_PIN               113
++
++/* this parameter allows us enable/disable asc1 via commandline */
++static int register_asc1;
++static int __init
++ltq_parse_asc1(char *p)
++{
++      register_asc1 = 1;
++      return 0;
++}
++__setup("use_asc1", ltq_parse_asc1);
++
++void __init
++ltq_soc_setup(void)
++{
++      ltq_register_asc(0);
++      ltq_register_wdt();
++      falcon_register_gpio();
++      if (register_asc1) {
++              ltq_register_asc(1);
++              if (ltq_gpio_request(MUXC_SIF_RX_PIN, 3, 0, "asc1-rx"))
++                      pr_err("failed to request asc1-rx");
++              if (ltq_gpio_request(MUXC_SIF_TX_PIN, 3, 1, "asc1-tx"))
++                      pr_err("failed to request asc1-tx");
++              ltq_sysctl_activate(SYSCTL_SYS1, ACTS_ASC1_ACT);
++      }
++}
++
++void __init
++ltq_soc_detect(struct ltq_soc_info *i)
++{
++      i->partnum = (ltq_r32(LTQ_FALCON_CHIPID) & PART_MASK) >> PART_SHIFT;
++      i->rev = (ltq_r32(LTQ_FALCON_CHIPID) & REV_MASK) >> REV_SHIFT;
++      i->srev = (ltq_r32(LTQ_FALCON_CHIPCONF) & SREV_MASK) >> SREV_SHIFT;
++      sprintf(i->rev_type, "%c%d%d", (i->srev & 0x4) ? ('B') : ('A'),
++              i->rev & 0x7, i->srev & 0x3);
++      switch (i->partnum) {
++      case SOC_ID_FALCON:
++              i->name = SOC_FALCON;
++              i->type = SOC_TYPE_FALCON;
++              break;
++
++      default:
++              unreachable();
++              break;
++      }
++}
+diff --git a/arch/mips/lantiq/falcon/reset.c b/arch/mips/lantiq/falcon/reset.c
+new file mode 100644
+index 0000000..d3289ca
+--- /dev/null
++++ b/arch/mips/lantiq/falcon/reset.c
+@@ -0,0 +1,87 @@
++/*
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 as published
++ * by the Free Software Foundation.
++ *
++ * Copyright (C) 2011 Thomas Langer <thomas.langer@lantiq.com>
++ * Copyright (C) 2011 John Crispin <blogic@openwrt.org>
++ */
++
++#include <linux/init.h>
++#include <linux/io.h>
++#include <linux/pm.h>
++#include <asm/reboot.h>
++#include <linux/module.h>
++
++#include <lantiq_soc.h>
++
++/* CPU0 Reset Source Register */
++#define LTQ_SYS1_CPU0RS               0x0040
++/* reset cause mask */
++#define LTQ_CPU0RS_MASK               0x0003
++
++int
++ltq_reset_cause(void)
++{
++      return ltq_sys1_r32(LTQ_SYS1_CPU0RS) & LTQ_CPU0RS_MASK;
++}
++EXPORT_SYMBOL_GPL(ltq_reset_cause);
++
++#define BOOT_REG_BASE (KSEG1 | 0x1F200000)
++#define BOOT_PW1_REG  (BOOT_REG_BASE | 0x20)
++#define BOOT_PW2_REG  (BOOT_REG_BASE | 0x24)
++#define BOOT_PW1      0x4C545100
++#define BOOT_PW2      0x0051544C
++
++#define WDT_REG_BASE  (KSEG1 | 0x1F8803F0)
++#define WDT_PW1               0x00BE0000
++#define WDT_PW2               0x00DC0000
++
++static void
++ltq_machine_restart(char *command)
++{
++      pr_notice("System restart\n");
++      local_irq_disable();
++
++      /* reboot magic */
++      ltq_w32(BOOT_PW1, (void *)BOOT_PW1_REG); /* 'LTQ\0' */
++      ltq_w32(BOOT_PW2, (void *)BOOT_PW2_REG); /* '\0QTL' */
++      ltq_w32(0, (void *)BOOT_REG_BASE); /* reset Bootreg RVEC */
++
++      /* watchdog magic */
++      ltq_w32(WDT_PW1, (void *)WDT_REG_BASE);
++      ltq_w32(WDT_PW2 |
++              (0x3 << 26) | /* PWL */
++              (0x2 << 24) | /* CLKDIV */
++              (0x1 << 31) | /* enable */
++              (1), /* reload */
++              (void *)WDT_REG_BASE);
++      unreachable();
++}
++
++static void
++ltq_machine_halt(void)
++{
++      pr_notice("System halted.\n");
++      local_irq_disable();
++      unreachable();
++}
++
++static void
++ltq_machine_power_off(void)
++{
++      pr_notice("Please turn off the power now.\n");
++      local_irq_disable();
++      unreachable();
++}
++
++static int __init
++mips_reboot_setup(void)
++{
++      _machine_restart = ltq_machine_restart;
++      _machine_halt = ltq_machine_halt;
++      pm_power_off = ltq_machine_power_off;
++      return 0;
++}
++
++arch_initcall(mips_reboot_setup);
+diff --git a/arch/mips/lantiq/falcon/sysctrl.c b/arch/mips/lantiq/falcon/sysctrl.c
+new file mode 100644
+index 0000000..d20b46b
+--- /dev/null
++++ b/arch/mips/lantiq/falcon/sysctrl.c
+@@ -0,0 +1,181 @@
++/*
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 as published
++ * by the Free Software Foundation.
++ *
++ * Copyright (C) 2011 Thomas Langer <thomas.langer@lantiq.com>
++ * Copyright (C) 2011 John Crispin <blogic@openwrt.org>
++ */
++
++#include <linux/ioport.h>
++#include <asm/delay.h>
++
++#include <lantiq_soc.h>
++
++#include "devices.h"
++
++/* infrastructure control register */
++#define SYS1_INFRAC           0x00bc
++/* Configuration fuses for drivers and pll */
++#define STATUS_CONFIG         0x0040
++
++/* GPE frequency selection */
++#define GPPC_OFFSET           24
++#define GPEFREQ_MASK          0x00000C0
++#define GPEFREQ_OFFSET                10
++/* Clock status register */
++#define LTQ_SYSCTL_CLKS               0x0000
++/* Clock enable register */
++#define LTQ_SYSCTL_CLKEN      0x0004
++/* Clock clear register */
++#define LTQ_SYSCTL_CLKCLR     0x0008
++/* Activation Status Register */
++#define LTQ_SYSCTL_ACTS               0x0020
++/* Activation Register */
++#define LTQ_SYSCTL_ACT                0x0024
++/* Deactivation Register */
++#define LTQ_SYSCTL_DEACT      0x0028
++/* reboot Register */
++#define LTQ_SYSCTL_RBT                0x002c
++
++static struct resource ltq_sysctl_res[] = {
++      MEM_RES("sys1", LTQ_SYS1_BASE_ADDR, LTQ_SYS1_SIZE),
++      MEM_RES("syseth", LTQ_SYS_ETH_BASE_ADDR, LTQ_SYS_ETH_SIZE),
++      MEM_RES("sysgpe", LTQ_SYS_GPE_BASE_ADDR, LTQ_SYS_GPE_SIZE),
++};
++
++static struct resource ltq_status_res =
++      MEM_RES("status", LTQ_STATUS_BASE_ADDR, LTQ_STATUS_SIZE);
++static struct resource ltq_ebu_res =
++      MEM_RES("ebu", LTQ_EBU_BASE_ADDR, LTQ_EBU_SIZE);
++
++static void __iomem *ltq_sysctl[3];
++static void __iomem *ltq_status_membase;
++void __iomem *ltq_sys1_membase;
++void __iomem *ltq_ebu_membase;
++
++#define ltq_reg_w32(m, x, y)  ltq_w32((x), ltq_sysctl[m] + (y))
++#define ltq_reg_r32(m, x)     ltq_r32(ltq_sysctl[m] + (x))
++#define ltq_reg_w32_mask(m, clear, set, reg)  \
++              ltq_reg_w32(m, (ltq_reg_r32(m, reg) & ~(clear)) | (set), reg)
++
++#define ltq_status_w32(x, y)  ltq_w32((x), ltq_status_membase + (y))
++#define ltq_status_r32(x)     ltq_r32(ltq_status_membase + (x))
++
++static inline void
++ltq_sysctl_wait(int module, unsigned int mask, unsigned int test)
++{
++      int err = 1000000;
++
++      do {} while (--err && ((ltq_reg_r32(module, LTQ_SYSCTL_ACTS)
++                                      & mask) != test));
++      if (!err)
++              pr_err("module de/activation failed %d %08X %08X\n",
++                                                      module, mask, test);
++}
++
++void
++ltq_sysctl_activate(int module, unsigned int mask)
++{
++      if (module > SYSCTL_SYSGPE)
++              return;
++
++      ltq_reg_w32(module, mask, LTQ_SYSCTL_CLKEN);
++      ltq_reg_w32(module, mask, LTQ_SYSCTL_ACT);
++      ltq_sysctl_wait(module, mask, mask);
++}
++EXPORT_SYMBOL(ltq_sysctl_activate);
++
++void
++ltq_sysctl_deactivate(int module, unsigned int mask)
++{
++      if (module > SYSCTL_SYSGPE)
++              return;
++
++      ltq_reg_w32(module, mask, LTQ_SYSCTL_CLKCLR);
++      ltq_reg_w32(module, mask, LTQ_SYSCTL_DEACT);
++      ltq_sysctl_wait(module, mask, 0);
++}
++EXPORT_SYMBOL(ltq_sysctl_deactivate);
++
++void
++ltq_sysctl_clken(int module, unsigned int mask)
++{
++      if (module > SYSCTL_SYSGPE)
++              return;
++
++      ltq_reg_w32(module, mask, LTQ_SYSCTL_CLKEN);
++      ltq_sysctl_wait(module, mask, mask);
++}
++EXPORT_SYMBOL(ltq_sysctl_clken);
++
++void
++ltq_sysctl_clkdis(int module, unsigned int mask)
++{
++      if (module > SYSCTL_SYSGPE)
++              return;
++
++      ltq_reg_w32(module, mask, LTQ_SYSCTL_CLKCLR);
++      ltq_sysctl_wait(module, mask, 0);
++}
++EXPORT_SYMBOL(ltq_sysctl_clkdis);
++
++void
++ltq_sysctl_reboot(int module, unsigned int mask)
++{
++      unsigned int act;
++
++      if (module > SYSCTL_SYSGPE)
++              return;
++
++      act = ltq_reg_r32(module, LTQ_SYSCTL_ACT);
++      if ((~act & mask) != 0)
++              ltq_sysctl_activate(module, ~act & mask);
++      ltq_reg_w32(module, act & mask, LTQ_SYSCTL_RBT);
++      ltq_sysctl_wait(module, mask, mask);
++}
++EXPORT_SYMBOL(ltq_sysctl_reboot);
++
++/* enable the ONU core */
++static void
++ltq_gpe_enable(void)
++{
++      unsigned int freq;
++      unsigned int status;
++
++      /* if if the clock is already enabled */
++      status = ltq_reg_r32(SYSCTL_SYS1, SYS1_INFRAC);
++      if (status & (1 << (GPPC_OFFSET + 1)))
++              return;
++
++      if (ltq_status_r32(STATUS_CONFIG) == 0)
++              freq = 1; /* use 625MHz on unfused chip */
++      else
++              freq = (ltq_status_r32(STATUS_CONFIG) &
++                      GPEFREQ_MASK) >>
++                      GPEFREQ_OFFSET;
++
++      /* apply new frequency */
++      ltq_reg_w32_mask(SYSCTL_SYS1, 7 << (GPPC_OFFSET + 1),
++              freq << (GPPC_OFFSET + 2) , SYS1_INFRAC);
++      udelay(1);
++
++      /* enable new frequency */
++      ltq_reg_w32_mask(SYSCTL_SYS1, 0, 1 << (GPPC_OFFSET + 1), SYS1_INFRAC);
++      udelay(1);
++}
++
++void __init
++ltq_soc_init(void)
++{
++      int i;
++
++      for (i = 0; i < 3; i++)
++              ltq_sysctl[i] = ltq_remap_resource(&ltq_sysctl_res[i]);
++
++      ltq_sys1_membase = ltq_sysctl[0];
++      ltq_status_membase = ltq_remap_resource(&ltq_status_res);
++      ltq_ebu_membase = ltq_remap_resource(&ltq_ebu_res);
++
++      ltq_gpe_enable();
++}
+-- 
+1.7.5.4
+
diff --git a/target/linux/lantiq/patches-3.0/0007-MIPS-lantiq-add-support-for-FALC-ON-GPIOs.patch b/target/linux/lantiq/patches-3.0/0007-MIPS-lantiq-add-support-for-FALC-ON-GPIOs.patch
new file mode 100644 (file)
index 0000000..0d8b92d
--- /dev/null
@@ -0,0 +1,501 @@
+From 02d9df56be1ba23c7bec51c94e5d2ac0d13d2d78 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Thu, 11 Aug 2011 14:35:02 +0200
+Subject: [PATCH 07/24] MIPS: lantiq: add support for FALC-ON GPIOs
+
+FALC-ON uses a different GPIO core than the other Lantiq SoCs. This patch adds
+the new driver.
+
+Signed-off-by: Thomas Langer <thomas.langer@lantiq.com>
+Signed-off-by: John Crispin <blogic@openwrt.org>
+Cc: linux-mips@linux-mips.org
+---
+ arch/mips/lantiq/falcon/Makefile  |    2 +-
+ arch/mips/lantiq/falcon/devices.c |   41 ++++
+ arch/mips/lantiq/falcon/devices.h |    2 +
+ arch/mips/lantiq/falcon/gpio.c    |  398 +++++++++++++++++++++++++++++++++++++
+ 4 files changed, 442 insertions(+), 1 deletions(-)
+ create mode 100644 arch/mips/lantiq/falcon/gpio.c
+
+diff --git a/arch/mips/lantiq/falcon/Makefile b/arch/mips/lantiq/falcon/Makefile
+index e9c7455..de72209 100644
+--- a/arch/mips/lantiq/falcon/Makefile
++++ b/arch/mips/lantiq/falcon/Makefile
+@@ -1 +1 @@
+-obj-y := clk.o prom.o reset.o sysctrl.o devices.o
++obj-y := clk.o prom.o reset.o sysctrl.o devices.o gpio.o
+diff --git a/arch/mips/lantiq/falcon/devices.c b/arch/mips/lantiq/falcon/devices.c
+index c4606f2..4f47b44 100644
+--- a/arch/mips/lantiq/falcon/devices.c
++++ b/arch/mips/lantiq/falcon/devices.c
+@@ -9,6 +9,7 @@
+ #include <linux/platform_device.h>
+ #include <linux/mtd/nand.h>
++#include <linux/gpio.h>
+ #include <lantiq_soc.h>
+@@ -85,3 +86,43 @@ falcon_register_nand(void)
+ {
+       platform_device_register(&ltq_flash_nand);
+ }
++
++/* gpio */
++#define DECLARE_GPIO_RES(port) \
++static struct resource falcon_gpio ## port ## _res[] = { \
++      MEM_RES("gpio"#port, LTQ_GPIO ## port ## _BASE_ADDR, \
++              LTQ_GPIO ## port ## _SIZE), \
++      MEM_RES("padctrl"#port, LTQ_PADCTRL ## port ## _BASE_ADDR, \
++              LTQ_PADCTRL ## port ## _SIZE), \
++      IRQ_RES("gpio_mux"#port, FALCON_IRQ_GPIO_P ## port) \
++}
++DECLARE_GPIO_RES(0);
++DECLARE_GPIO_RES(1);
++DECLARE_GPIO_RES(2);
++DECLARE_GPIO_RES(3);
++DECLARE_GPIO_RES(4);
++
++void __init
++falcon_register_gpio(void)
++{
++      platform_device_register_simple("falcon_gpio", 0,
++              falcon_gpio0_res, ARRAY_SIZE(falcon_gpio0_res));
++      platform_device_register_simple("falcon_gpio", 1,
++              falcon_gpio1_res, ARRAY_SIZE(falcon_gpio1_res));
++      platform_device_register_simple("falcon_gpio", 2,
++              falcon_gpio2_res, ARRAY_SIZE(falcon_gpio2_res));
++      ltq_sysctl_activate(SYSCTL_SYS1, ACTS_PADCTRL1 | ACTS_P1);
++      ltq_sysctl_activate(SYSCTL_SYSETH, ACTS_PADCTRL0 |
++              ACTS_PADCTRL2 | ACTS_P0 | ACTS_P2);
++}
++
++void __init
++falcon_register_gpio_extra(void)
++{
++      platform_device_register_simple("falcon_gpio", 3,
++              falcon_gpio3_res, ARRAY_SIZE(falcon_gpio3_res));
++      platform_device_register_simple("falcon_gpio", 4,
++              falcon_gpio4_res, ARRAY_SIZE(falcon_gpio4_res));
++      ltq_sysctl_activate(SYSCTL_SYS1,
++              ACTS_PADCTRL3 | ACTS_PADCTRL4 | ACTS_P3 | ACTS_P4);
++}
+diff --git a/arch/mips/lantiq/falcon/devices.h b/arch/mips/lantiq/falcon/devices.h
+index e802a7c..18be8b6 100644
+--- a/arch/mips/lantiq/falcon/devices.h
++++ b/arch/mips/lantiq/falcon/devices.h
+@@ -14,5 +14,7 @@
+ #include "../devices.h"
+ extern void falcon_register_nand(void);
++extern void falcon_register_gpio(void);
++extern void falcon_register_gpio_extra(void);
+ #endif
+diff --git a/arch/mips/lantiq/falcon/gpio.c b/arch/mips/lantiq/falcon/gpio.c
+new file mode 100644
+index 0000000..b87582d
+--- /dev/null
++++ b/arch/mips/lantiq/falcon/gpio.c
+@@ -0,0 +1,398 @@
++/*
++ *  This program is free software; you can redistribute it and/or modify it
++ *  under the terms of the GNU General Public License version 2 as published
++ *  by the Free Software Foundation.
++ *
++ *  Copyright (C) 2011 Thomas Langer <thomas.langer@lantiq.com>
++ *  Copyright (C) 2011 John Crispin <blogic@openwrt.org>
++ */
++
++#include <linux/gpio.h>
++#include <linux/interrupt.h>
++#include <linux/slab.h>
++#include <linux/platform_device.h>
++
++#include <lantiq_soc.h>
++
++/* Multiplexer Control Register */
++#define LTQ_PADC_MUX(x)         (x * 0x4)
++/* Pad Control Availability Register */
++#define LTQ_PADC_AVAIL          0x000000F0
++
++/* Data Output Register */
++#define LTQ_GPIO_OUT            0x00000000
++/* Data Input Register */
++#define LTQ_GPIO_IN             0x00000004
++/* Direction Register */
++#define LTQ_GPIO_DIR            0x00000008
++/* External Interrupt Control Register 0 */
++#define LTQ_GPIO_EXINTCR0       0x00000018
++/* External Interrupt Control Register 1 */
++#define LTQ_GPIO_EXINTCR1       0x0000001C
++/* IRN Capture Register */
++#define LTQ_GPIO_IRNCR          0x00000020
++/* IRN Interrupt Configuration Register */
++#define LTQ_GPIO_IRNCFG               0x0000002C
++/* IRN Interrupt Enable Set Register */
++#define LTQ_GPIO_IRNRNSET       0x00000030
++/* IRN Interrupt Enable Clear Register */
++#define LTQ_GPIO_IRNENCLR       0x00000034
++/* Output Set Register */
++#define LTQ_GPIO_OUTSET         0x00000040
++/* Output Cler Register */
++#define LTQ_GPIO_OUTCLR         0x00000044
++/* Direction Clear Register */
++#define LTQ_GPIO_DIRSET         0x00000048
++/* Direction Set Register */
++#define LTQ_GPIO_DIRCLR         0x0000004C
++
++/* turn a gpio_chip into a falcon_gpio_port */
++#define ctop(c)               container_of(c, struct falcon_gpio_port, gpio_chip)
++/* turn a irq_data into a falcon_gpio_port */
++#define itop(i)               ((struct falcon_gpio_port *) irq_get_chip_data(i->irq))
++
++#define ltq_pad_r32(p, reg)           ltq_r32(p->pad + reg)
++#define ltq_pad_w32(p, val, reg)      ltq_w32(val, p->pad + reg)
++#define ltq_pad_w32_mask(c, clear, set, reg) \
++              ltq_pad_w32(c, (ltq_pad_r32(c, reg) & ~(clear)) | (set), reg)
++
++#define ltq_port_r32(p, reg)          ltq_r32(p->port + reg)
++#define ltq_port_w32(p, val, reg)     ltq_w32(val, p->port + reg)
++#define ltq_port_w32_mask(p, clear, set, reg) \
++              ltq_port_w32(p, (ltq_port_r32(p, reg) & ~(clear)) | (set), reg)
++
++#define MAX_PORTS             5
++#define PINS_PER_PORT         32
++
++struct falcon_gpio_port {
++      struct gpio_chip gpio_chip;
++      void __iomem *pad;
++      void __iomem *port;
++      unsigned int irq_base;
++      unsigned int chained_irq;
++};
++
++static struct falcon_gpio_port ltq_gpio_port[MAX_PORTS];
++
++int gpio_to_irq(unsigned int gpio)
++{
++      return __gpio_to_irq(gpio);
++}
++EXPORT_SYMBOL(gpio_to_irq);
++
++int ltq_gpio_mux_set(unsigned int pin, unsigned int mux)
++{
++      int port = pin / 100;
++      int offset = pin % 100;
++      struct falcon_gpio_port *gpio_port;
++
++      if ((offset >= PINS_PER_PORT) || (port >= MAX_PORTS))
++              return -EINVAL;
++
++      gpio_port = &ltq_gpio_port[port];
++      ltq_pad_w32(gpio_port, mux & 0x3, LTQ_PADC_MUX(offset));
++
++      return 0;
++}
++EXPORT_SYMBOL(ltq_gpio_mux_set);
++
++int ltq_gpio_request(unsigned int pin, unsigned int val,
++              unsigned int dir, const char *name)
++{
++      int port = pin / 100;
++      int offset = pin % 100;
++
++      if (offset >= PINS_PER_PORT || port >= MAX_PORTS)
++              return -EINVAL;
++
++      if (gpio_request(pin, name)) {
++              pr_err("failed to setup lantiq gpio: %s\n", name);
++              return -EBUSY;
++      }
++
++      if (dir)
++              gpio_direction_output(pin, 1);
++      else
++              gpio_direction_input(pin);
++
++      return ltq_gpio_mux_set(pin, val);
++}
++EXPORT_SYMBOL(ltq_gpio_request);
++
++static int
++falcon_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
++{
++      ltq_port_w32(ctop(chip), 1 << offset, LTQ_GPIO_DIRCLR);
++
++      return 0;
++}
++
++static void
++falcon_gpio_set(struct gpio_chip *chip, unsigned int offset, int value)
++{
++      if (value)
++              ltq_port_w32(ctop(chip), 1 << offset, LTQ_GPIO_OUTSET);
++      else
++              ltq_port_w32(ctop(chip), 1 << offset, LTQ_GPIO_OUTCLR);
++}
++
++static int
++falcon_gpio_direction_output(struct gpio_chip *chip,
++                      unsigned int offset, int value)
++{
++      falcon_gpio_set(chip, offset, value);
++      ltq_port_w32(ctop(chip), 1 << offset, LTQ_GPIO_DIRSET);
++
++      return 0;
++}
++
++static int
++falcon_gpio_get(struct gpio_chip *chip, unsigned int offset)
++{
++      if ((ltq_port_r32(ctop(chip), LTQ_GPIO_DIR) >> offset) & 1)
++              return (ltq_port_r32(ctop(chip), LTQ_GPIO_OUT) >> offset) & 1;
++      else
++              return (ltq_port_r32(ctop(chip), LTQ_GPIO_IN) >> offset) & 1;
++}
++
++static int
++falcon_gpio_request(struct gpio_chip *chip, unsigned offset)
++{
++      if ((ltq_pad_r32(ctop(chip), LTQ_PADC_AVAIL) >> offset) & 1) {
++              if (ltq_pad_r32(ctop(chip), LTQ_PADC_MUX(offset)) > 1)
++                      return -EBUSY;
++              /* switch on gpio function */
++              ltq_pad_w32(ctop(chip), 1, LTQ_PADC_MUX(offset));
++              return 0;
++      }
++
++      return -ENODEV;
++}
++
++static void
++falcon_gpio_free(struct gpio_chip *chip, unsigned offset)
++{
++      if ((ltq_pad_r32(ctop(chip), LTQ_PADC_AVAIL) >> offset) & 1) {
++              if (ltq_pad_r32(ctop(chip), LTQ_PADC_MUX(offset)) > 1)
++                      return;
++              /* switch off gpio function */
++              ltq_pad_w32(ctop(chip), 0, LTQ_PADC_MUX(offset));
++      }
++}
++
++static int
++falcon_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
++{
++      return ctop(chip)->irq_base + offset;
++}
++
++static void
++falcon_gpio_disable_irq(struct irq_data *d)
++{
++      unsigned int offset = d->irq - itop(d)->irq_base;
++
++      ltq_port_w32(itop(d), 1 << offset, LTQ_GPIO_IRNENCLR);
++}
++
++static void
++falcon_gpio_enable_irq(struct irq_data *d)
++{
++      unsigned int offset = d->irq - itop(d)->irq_base;
++
++      if (!ltq_pad_r32(itop(d), LTQ_PADC_MUX(offset)) < 1)
++              /* switch on gpio function */
++              ltq_pad_w32(itop(d), 1, LTQ_PADC_MUX(offset));
++
++      ltq_port_w32(itop(d), 1 << offset, LTQ_GPIO_IRNRNSET);
++}
++
++static void
++falcon_gpio_ack_irq(struct irq_data *d)
++{
++      unsigned int offset = d->irq - itop(d)->irq_base;
++
++      ltq_port_w32(itop(d), 1 << offset, LTQ_GPIO_IRNCR);
++}
++
++static void
++falcon_gpio_mask_and_ack_irq(struct irq_data *d)
++{
++      unsigned int offset = d->irq - itop(d)->irq_base;
++
++      ltq_port_w32(itop(d), 1 << offset, LTQ_GPIO_IRNENCLR);
++      ltq_port_w32(itop(d), 1 << offset, LTQ_GPIO_IRNCR);
++}
++
++static struct irq_chip falcon_gpio_irq_chip;
++static int
++falcon_gpio_irq_type(struct irq_data *d, unsigned int type)
++{
++      unsigned int offset = d->irq - itop(d)->irq_base;
++      unsigned int mask = 1 << offset;
++
++      if ((type & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_NONE)
++              return 0;
++
++      if ((type & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) != 0) {
++              /* level triggered */
++              ltq_port_w32_mask(itop(d), 0, mask, LTQ_GPIO_IRNCFG);
++              irq_set_chip_and_handler_name(d->irq,
++                              &falcon_gpio_irq_chip, handle_level_irq, "mux");
++      } else {
++              /* edge triggered */
++              ltq_port_w32_mask(itop(d), mask, 0, LTQ_GPIO_IRNCFG);
++              irq_set_chip_and_handler_name(d->irq,
++                      &falcon_gpio_irq_chip, handle_simple_irq, "mux");
++      }
++
++      if ((type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) {
++              ltq_port_w32_mask(itop(d), mask, 0, LTQ_GPIO_EXINTCR0);
++              ltq_port_w32_mask(itop(d), 0, mask, LTQ_GPIO_EXINTCR1);
++      } else {
++              if ((type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_LEVEL_HIGH)) != 0)
++                      /* positive logic: rising edge, high level */
++                      ltq_port_w32_mask(itop(d), mask, 0, LTQ_GPIO_EXINTCR0);
++              else
++                      /* negative logic: falling edge, low level */
++                      ltq_port_w32_mask(itop(d), 0, mask, LTQ_GPIO_EXINTCR0);
++              ltq_port_w32_mask(itop(d), mask, 0, LTQ_GPIO_EXINTCR1);
++      }
++
++      return gpio_direction_input(itop(d)->gpio_chip.base + offset);
++}
++
++static void
++falcon_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
++{
++      struct falcon_gpio_port *gpio_port = irq_desc_get_handler_data(desc);
++      unsigned long irncr;
++      int offset;
++
++      /* acknowledge interrupt */
++      irncr = ltq_port_r32(gpio_port, LTQ_GPIO_IRNCR);
++      ltq_port_w32(gpio_port, irncr, LTQ_GPIO_IRNCR);
++
++      desc->irq_data.chip->irq_ack(&desc->irq_data);
++
++      for_each_set_bit(offset, &irncr, gpio_port->gpio_chip.ngpio)
++              generic_handle_irq(gpio_port->irq_base + offset);
++}
++
++static struct irq_chip falcon_gpio_irq_chip = {
++      .name = "gpio_irq_mux",
++      .irq_mask = falcon_gpio_disable_irq,
++      .irq_unmask = falcon_gpio_enable_irq,
++      .irq_ack = falcon_gpio_ack_irq,
++      .irq_mask_ack = falcon_gpio_mask_and_ack_irq,
++      .irq_set_type = falcon_gpio_irq_type,
++};
++
++static struct irqaction gpio_cascade = {
++      .handler = no_action,
++      .flags = IRQF_DISABLED,
++      .name = "gpio_cascade",
++};
++
++static int
++falcon_gpio_probe(struct platform_device *pdev)
++{
++      struct falcon_gpio_port *gpio_port;
++      int ret, i;
++      struct resource *gpiores, *padres;
++      int irq;
++
++      if (pdev->id >= MAX_PORTS)
++              return -ENODEV;
++
++      gpiores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++      padres = platform_get_resource(pdev, IORESOURCE_MEM, 1);
++      irq = platform_get_irq(pdev, 0);
++      if (!gpiores || !padres)
++              return -ENODEV;
++
++      gpio_port = &ltq_gpio_port[pdev->id];
++      gpio_port->gpio_chip.label = "falcon-gpio";
++      gpio_port->gpio_chip.direction_input = falcon_gpio_direction_input;
++      gpio_port->gpio_chip.direction_output = falcon_gpio_direction_output;
++      gpio_port->gpio_chip.get = falcon_gpio_get;
++      gpio_port->gpio_chip.set = falcon_gpio_set;
++      gpio_port->gpio_chip.request = falcon_gpio_request;
++      gpio_port->gpio_chip.free = falcon_gpio_free;
++      gpio_port->gpio_chip.base = 100 * pdev->id;
++      gpio_port->gpio_chip.ngpio = 32;
++      gpio_port->gpio_chip.dev = &pdev->dev;
++
++      gpio_port->port = ltq_remap_resource(gpiores);
++      gpio_port->pad = ltq_remap_resource(padres);
++
++      if (!gpio_port->port || !gpio_port->pad) {
++              dev_err(&pdev->dev, "Could not map io ranges\n");
++              ret = -ENOMEM;
++              goto err;
++      }
++
++      if (irq > 0) {
++              /* irq_chip support */
++              gpio_port->gpio_chip.to_irq = falcon_gpio_to_irq;
++              gpio_port->irq_base = INT_NUM_EXTRA_START + (32 * pdev->id);
++
++              for (i = 0; i < 32; i++) {
++                      irq_set_chip_and_handler_name(gpio_port->irq_base + i,
++                              &falcon_gpio_irq_chip, handle_simple_irq,
++                              "mux");
++                      irq_set_chip_data(gpio_port->irq_base + i, gpio_port);
++                      /* set to negative logic (falling edge, low level) */
++                      ltq_port_w32_mask(gpio_port, 0, 1 << i,
++                              LTQ_GPIO_EXINTCR0);
++              }
++
++              gpio_port->chained_irq = irq;
++              setup_irq(irq, &gpio_cascade);
++              irq_set_handler_data(irq, gpio_port);
++              irq_set_chained_handler(irq, falcon_gpio_irq_handler);
++      }
++
++      ret = gpiochip_add(&gpio_port->gpio_chip);
++      if (ret < 0) {
++              dev_err(&pdev->dev, "Could not register gpiochip %d, %d\n",
++                      pdev->id, ret);
++              goto err;
++      }
++      platform_set_drvdata(pdev, gpio_port);
++      return ret;
++
++err:
++      dev_err(&pdev->dev, "Error in gpio_probe %d, %d\n", pdev->id, ret);
++      if (gpiores)
++              release_resource(gpiores);
++      if (padres)
++              release_resource(padres);
++
++      if (gpio_port->port)
++              iounmap(gpio_port->port);
++      if (gpio_port->pad)
++              iounmap(gpio_port->pad);
++      return ret;
++}
++
++static struct platform_driver falcon_gpio_driver = {
++      .probe = falcon_gpio_probe,
++      .driver = {
++              .name = "falcon_gpio",
++              .owner = THIS_MODULE,
++      },
++};
++
++int __init
++falcon_gpio_init(void)
++{
++      int ret;
++
++      pr_info("FALC(tm) ON GPIO Driver, (C) 2011 Lantiq Deutschland Gmbh\n");
++      ret = platform_driver_register(&falcon_gpio_driver);
++      if (ret)
++              pr_err("falcon_gpio: Error registering platform driver!");
++      return ret;
++}
++
++postcore_initcall(falcon_gpio_init);
+-- 
+1.7.5.4
+
diff --git a/target/linux/lantiq/patches-3.0/0008-MIPS-lantiq-add-support-for-the-EASY98000-evaluation.patch b/target/linux/lantiq/patches-3.0/0008-MIPS-lantiq-add-support-for-the-EASY98000-evaluation.patch
new file mode 100644 (file)
index 0000000..2383584
--- /dev/null
@@ -0,0 +1,179 @@
+From ec6ba0f79c010a878d679c057fb6306b50a201b0 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Thu, 11 Aug 2011 14:09:35 +0200
+Subject: [PATCH 08/24] MIPS: lantiq: add support for the EASY98000 evaluation
+ board
+
+This patch adds the machine code for the EASY9800 evaluation board.
+
+Signed-off-by: Thomas Langer <thomas.langer@lantiq.com>
+Signed-off-by: John Crispin <blogic@openwrt.org>
+Cc: linux-mips@linux-mips.org
+---
+ arch/mips/lantiq/falcon/Kconfig          |   11 +++
+ arch/mips/lantiq/falcon/Makefile         |    1 +
+ arch/mips/lantiq/falcon/mach-easy98000.c |  110 ++++++++++++++++++++++++++++++
+ arch/mips/lantiq/machtypes.h             |    5 ++
+ 4 files changed, 127 insertions(+), 0 deletions(-)
+ create mode 100644 arch/mips/lantiq/falcon/Kconfig
+ create mode 100644 arch/mips/lantiq/falcon/mach-easy98000.c
+
+diff --git a/arch/mips/lantiq/falcon/Kconfig b/arch/mips/lantiq/falcon/Kconfig
+new file mode 100644
+index 0000000..03e999d
+--- /dev/null
++++ b/arch/mips/lantiq/falcon/Kconfig
+@@ -0,0 +1,11 @@
++if SOC_FALCON
++
++menu "MIPS Machine"
++
++config LANTIQ_MACH_EASY98000
++      bool "Easy98000"
++      default y
++
++endmenu
++
++endif
+diff --git a/arch/mips/lantiq/falcon/Makefile b/arch/mips/lantiq/falcon/Makefile
+index de72209..56b22eb 100644
+--- a/arch/mips/lantiq/falcon/Makefile
++++ b/arch/mips/lantiq/falcon/Makefile
+@@ -1 +1,2 @@
+ obj-y := clk.o prom.o reset.o sysctrl.o devices.o gpio.o
++obj-$(CONFIG_LANTIQ_MACH_EASY98000) += mach-easy98000.o
+diff --git a/arch/mips/lantiq/falcon/mach-easy98000.c b/arch/mips/lantiq/falcon/mach-easy98000.c
+new file mode 100644
+index 0000000..361b8f0
+--- /dev/null
++++ b/arch/mips/lantiq/falcon/mach-easy98000.c
+@@ -0,0 +1,110 @@
++/*
++ *  This program is free software; you can redistribute it and/or modify it
++ *  under the terms of the GNU General Public License version 2 as published
++ *  by the Free Software Foundation.
++ *
++ *  Copyright (C) 2011 Thomas Langer <thomas.langer@lantiq.com>
++ *  Copyright (C) 2011 John Crispin <blogic@openwrt.org>
++ */
++
++#include <linux/platform_device.h>
++#include <linux/mtd/partitions.h>
++#include <linux/spi/spi.h>
++#include <linux/spi/spi_gpio.h>
++#include <linux/spi/eeprom.h>
++
++#include "../machtypes.h"
++
++#include "devices.h"
++
++static struct mtd_partition easy98000_nor_partitions[] = {
++      {
++              .name   = "uboot",
++              .offset = 0x0,
++              .size   = 0x40000,
++      },
++      {
++              .name   = "uboot_env",
++              .offset = 0x40000,
++              .size   = 0x40000,      /* 2 sectors for redundant env. */
++      },
++      {
++              .name   = "linux",
++              .offset = 0x80000,
++              .size   = 0xF80000,     /* map only 16 MiB */
++      },
++};
++
++struct physmap_flash_data easy98000_nor_flash_data = {
++      .nr_parts       = ARRAY_SIZE(easy98000_nor_partitions),
++      .parts          = easy98000_nor_partitions,
++};
++
++/* setup gpio based spi bus/device for access to the eeprom on the board */
++#define SPI_GPIO_MRST         102
++#define SPI_GPIO_MTSR         103
++#define SPI_GPIO_CLK          104
++#define SPI_GPIO_CS0          105
++#define SPI_GPIO_CS1          106
++#define SPI_GPIO_BUS_NUM      1
++
++static struct spi_gpio_platform_data easy98000_spi_gpio_data = {
++      .sck            = SPI_GPIO_CLK,
++      .mosi           = SPI_GPIO_MTSR,
++      .miso           = SPI_GPIO_MRST,
++      .num_chipselect = 2,
++};
++
++static struct platform_device easy98000_spi_gpio_device = {
++      .name                   = "spi_gpio",
++      .id                     = SPI_GPIO_BUS_NUM,
++      .dev.platform_data      = &easy98000_spi_gpio_data,
++};
++
++static struct spi_eeprom at25160n = {
++      .byte_len       = 16 * 1024 / 8,
++      .name           = "at25160n",
++      .page_size      = 32,
++      .flags          = EE_ADDR2,
++};
++
++static struct spi_board_info easy98000_spi_gpio_devices __initdata = {
++      .modalias               = "at25",
++      .bus_num                = SPI_GPIO_BUS_NUM,
++      .max_speed_hz           = 1000 * 1000,
++      .mode                   = SPI_MODE_3,
++      .chip_select            = 1,
++      .controller_data        = (void *) SPI_GPIO_CS1,
++      .platform_data          = &at25160n,
++};
++
++static void __init
++easy98000_init_common(void)
++{
++      spi_register_board_info(&easy98000_spi_gpio_devices, 1);
++      platform_device_register(&easy98000_spi_gpio_device);
++}
++
++static void __init
++easy98000_init(void)
++{
++      easy98000_init_common();
++      ltq_register_nor(&easy98000_nor_flash_data);
++}
++
++static void __init
++easy98000nand_init(void)
++{
++      easy98000_init_common();
++      falcon_register_nand();
++}
++
++MIPS_MACHINE(LANTIQ_MACH_EASY98000,
++                      "EASY98000",
++                      "EASY98000 Eval Board",
++                      easy98000_init);
++
++MIPS_MACHINE(LANTIQ_MACH_EASY98000NAND,
++                      "EASY98000NAND",
++                      "EASY98000 Eval Board (NAND Flash)",
++                      easy98000nand_init);
+diff --git a/arch/mips/lantiq/machtypes.h b/arch/mips/lantiq/machtypes.h
+index 7e01b8c..dfc6af7 100644
+--- a/arch/mips/lantiq/machtypes.h
++++ b/arch/mips/lantiq/machtypes.h
+@@ -15,6 +15,11 @@ enum lantiq_mach_type {
+       LTQ_MACH_GENERIC = 0,
+       LTQ_MACH_EASY50712,     /* Danube evaluation board */
+       LTQ_MACH_EASY50601,     /* Amazon SE evaluation board */
++
++      /* FALCON */
++      LANTIQ_MACH_EASY98000,          /* Falcon Eval Board, NOR Flash */
++      LANTIQ_MACH_EASY98000SF,        /* Falcon Eval Board, Serial Flash */
++      LANTIQ_MACH_EASY98000NAND,      /* Falcon Eval Board, NAND Flash */
+ };
+ #endif
+-- 
+1.7.5.4
+
diff --git a/target/linux/lantiq/patches-3.0/0009-MIPS-make-oprofile-use-cp0_perfcount_irq-if-it-is-se.patch b/target/linux/lantiq/patches-3.0/0009-MIPS-make-oprofile-use-cp0_perfcount_irq-if-it-is-se.patch
new file mode 100644 (file)
index 0000000..ed35805
--- /dev/null
@@ -0,0 +1,56 @@
+From 88bb1794592e3fe9c8d65ce73ee851e11dbbd26b Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Wed, 24 Aug 2011 13:24:11 +0200
+Subject: [PATCH 09/24] MIPS: make oprofile use cp0_perfcount_irq if it is set
+
+The patch makes the oprofile code use the performance counters irq.
+
+This patch is written by Felix Fietkau.
+
+Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+Signed-off-by: John Crispin <blogic@openwrt.org>
+Cc: linux-mips@linux-mips.org
+---
+ arch/mips/oprofile/op_model_mipsxx.c |   12 ++++++++++++
+ 1 files changed, 12 insertions(+), 0 deletions(-)
+
+diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c
+index 54759f1..86cf234 100644
+--- a/arch/mips/oprofile/op_model_mipsxx.c
++++ b/arch/mips/oprofile/op_model_mipsxx.c
+@@ -298,6 +298,11 @@ static void reset_counters(void *arg)
+       }
+ }
++static irqreturn_t mipsxx_perfcount_int(int irq, void *dev_id)
++{
++      return mipsxx_perfcount_handler();
++}
++
+ static int __init mipsxx_init(void)
+ {
+       int counters;
+@@ -374,6 +379,10 @@ static int __init mipsxx_init(void)
+       save_perf_irq = perf_irq;
+       perf_irq = mipsxx_perfcount_handler;
++      if (cp0_perfcount_irq >= 0)
++              return request_irq(cp0_perfcount_irq, mipsxx_perfcount_int,
++                      IRQF_SHARED, "Perfcounter", save_perf_irq);
++
+       return 0;
+ }
+@@ -381,6 +390,9 @@ static void mipsxx_exit(void)
+ {
+       int counters = op_model_mipsxx_ops.num_counters;
++      if (cp0_perfcount_irq >= 0)
++              free_irq(cp0_perfcount_irq, save_perf_irq);
++
+       counters = counters_per_cpu_to_total(counters);
+       on_each_cpu(reset_counters, (void *)(long)counters, 1);
+-- 
+1.7.5.4
+
diff --git a/target/linux/lantiq/patches-3.0/0010-MIPS-enable-oprofile-support-on-lantiq-targets.patch b/target/linux/lantiq/patches-3.0/0010-MIPS-enable-oprofile-support-on-lantiq-targets.patch
new file mode 100644 (file)
index 0000000..2f6d1a1
--- /dev/null
@@ -0,0 +1,52 @@
+From cc4b9cdff8665a414ae51101d3a0ca6ed7444a27 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Wed, 24 Aug 2011 13:28:55 +0200
+Subject: [PATCH 10/24] MIPS: enable oprofile support on lantiq targets
+
+This patch sets the performance counters irq and HAVE_OPROFILE flag.
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+Cc: linux-mips@linux-mips.org
+---
+ arch/mips/Kconfig      |    1 +
+ arch/mips/lantiq/irq.c |    5 +++++
+ 2 files changed, 6 insertions(+), 0 deletions(-)
+
+diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
+index b122adc..0cf5bbd 100644
+--- a/arch/mips/Kconfig
++++ b/arch/mips/Kconfig
+@@ -230,6 +230,7 @@ config LANTIQ
+       select SWAP_IO_SPACE
+       select BOOT_RAW
+       select HAVE_CLK
++      select HAVE_OPROFILE
+       select MIPS_MACHINE
+ config LASAT
+diff --git a/arch/mips/lantiq/irq.c b/arch/mips/lantiq/irq.c
+index 17c057f..0b2ed87 100644
+--- a/arch/mips/lantiq/irq.c
++++ b/arch/mips/lantiq/irq.c
+@@ -40,6 +40,9 @@
+ #define MAX_EIU                       6
++/* the performance counter */
++#define LTQ_PERF_IRQ          (INT_NUM_IM4_IRL0 + 31)
++
+ /* irqs generated by device attached to the EBU need to be acked in
+  * a special manner
+  */
+@@ -318,6 +321,8 @@ void __init arch_init_irq(void)
+       set_c0_status(IE_SW0 | IE_SW1 | IE_IRQ0 | IE_IRQ1 |
+               IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5);
+ #endif
++
++      cp0_perfcount_irq = LTQ_PERF_IRQ;
+ }
+ unsigned int __cpuinit get_c0_compare_int(void)
+-- 
+1.7.5.4
+
diff --git a/target/linux/lantiq/patches-3.0/0011-MIPS-lantiq-adds-falcon-I2C.patch b/target/linux/lantiq/patches-3.0/0011-MIPS-lantiq-adds-falcon-I2C.patch
new file mode 100644 (file)
index 0000000..84af96f
--- /dev/null
@@ -0,0 +1,904 @@
+From 6437f41dfdf9475178e22ab0dd886af033f90cc2 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Thu, 29 Sep 2011 21:10:16 +0200
+Subject: [PATCH 11/24] MIPS: lantiq: adds falcon I2C
+
+---
+ arch/mips/lantiq/falcon/devices.c |   21 +
+ arch/mips/lantiq/falcon/devices.h |    1 +
+ drivers/i2c/busses/Kconfig        |    4 +
+ drivers/i2c/busses/Makefile       |    1 +
+ drivers/i2c/busses/i2c-falcon.c   |  815 +++++++++++++++++++++++++++++++++++++
+ 5 files changed, 842 insertions(+), 0 deletions(-)
+ create mode 100644 drivers/i2c/busses/i2c-falcon.c
+
+diff --git a/arch/mips/lantiq/falcon/devices.c b/arch/mips/lantiq/falcon/devices.c
+index 4f47b44..a998b6b 100644
+--- a/arch/mips/lantiq/falcon/devices.c
++++ b/arch/mips/lantiq/falcon/devices.c
+@@ -126,3 +126,24 @@ falcon_register_gpio_extra(void)
+       ltq_sysctl_activate(SYSCTL_SYS1,
+               ACTS_PADCTRL3 | ACTS_PADCTRL4 | ACTS_P3 | ACTS_P4);
+ }
++
++/* i2c */
++static struct resource falcon_i2c_resources[] = {
++      MEM_RES("i2c", GPON_I2C_BASE,GPON_I2C_END),
++      IRQ_RES("i2c_lb", FALCON_IRQ_I2C_LBREQ),
++      IRQ_RES("i2c_b", FALCON_IRQ_I2C_BREQ),
++      IRQ_RES("i2c_err", FALCON_IRQ_I2C_I2C_ERR),
++      IRQ_RES("i2c_p", FALCON_IRQ_I2C_I2C_P),
++};
++
++void __init falcon_register_i2c(void)
++{
++      platform_device_register_simple("i2c-falcon", 0,
++      falcon_i2c_resources, ARRAY_SIZE(falcon_i2c_resources));
++      sys1_hw_activate(ACTS_I2C_ACT);
++}
++
++void __init falcon_register_crypto(void)
++{
++      platform_device_register_simple("ltq_falcon_deu", 0, NULL, 0);
++}
+diff --git a/arch/mips/lantiq/falcon/devices.h b/arch/mips/lantiq/falcon/devices.h
+index 18be8b6..2fdcb08 100644
+--- a/arch/mips/lantiq/falcon/devices.h
++++ b/arch/mips/lantiq/falcon/devices.h
+@@ -16,5 +16,6 @@
+ extern void falcon_register_nand(void);
+ extern void falcon_register_gpio(void);
+ extern void falcon_register_gpio_extra(void);
++extern void falcon_register_i2c(void);
+ #endif
+diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
+index 646068e..e6c3ab6 100644
+--- a/drivers/i2c/busses/Kconfig
++++ b/drivers/i2c/busses/Kconfig
+@@ -284,6 +284,10 @@ config I2C_POWERMAC
+ comment "I2C system bus drivers (mostly embedded / system-on-chip)"
++config I2C_FALCON
++      tristate "Falcon I2C interface"
++#     depends on SOC_FALCON
++
+ config I2C_AT91
+       tristate "Atmel AT91 I2C Two-Wire interface (TWI)"
+       depends on ARCH_AT91 && EXPERIMENTAL && BROKEN
+diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
+index e6cf294..83e9250 100644
+--- a/drivers/i2c/busses/Makefile
++++ b/drivers/i2c/busses/Makefile
+@@ -82,5 +82,6 @@ obj-$(CONFIG_I2C_SIBYTE)     += i2c-sibyte.o
+ obj-$(CONFIG_I2C_STUB)                += i2c-stub.o
+ obj-$(CONFIG_SCx200_ACB)      += scx200_acb.o
+ obj-$(CONFIG_SCx200_I2C)      += scx200_i2c.o
++obj-$(CONFIG_I2C_FALCON)      += i2c-falcon.o
+ ccflags-$(CONFIG_I2C_DEBUG_BUS) := -DDEBUG
+diff --git a/drivers/i2c/busses/i2c-falcon.c b/drivers/i2c/busses/i2c-falcon.c
+new file mode 100644
+index 0000000..7bb1253
+--- /dev/null
++++ b/drivers/i2c/busses/i2c-falcon.c
+@@ -0,0 +1,815 @@
++/*
++ * Lantiq FALC(tm) ON - I2C bus adapter
++ *
++ * Parts based on i2c-designware.c and other i2c drivers from Linux 2.6.33
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++
++/* #define DEBUG */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/delay.h>
++#include <linux/slab.h> /* for kzalloc, kfree */
++#include <linux/i2c.h>
++#include <linux/clk.h>
++#include <linux/errno.h>
++#include <linux/sched.h>
++#include <linux/err.h>
++#include <linux/interrupt.h>
++#include <linux/platform_device.h>
++#include <linux/io.h>
++#include <linux/gpio.h>
++
++#include <falcon/lantiq_soc.h>
++
++/* CURRENT ISSUES:
++ * - no high speed support
++ * - supports only master mode
++ * - ten bit mode is not tested (no slave devices)
++ */
++
++/* mapping for access macros */
++#define reg_r32(reg)          __raw_readl(reg)
++#define reg_w32(val, reg)     __raw_writel(val, reg)
++#define reg_w32_mask(clear, set, reg) \
++                              reg_w32((reg_r32(reg) & ~(clear)) | (set), reg)
++#define reg_r32_table(reg, idx) reg_r32(&((uint32_t *)&reg)[idx])
++#define reg_w32_table(val, reg, idx) reg_w32(val, &((uint32_t *)&reg)[idx])
++#define i2c   (priv->membase)
++#include <falcon/i2c_reg.h>
++
++#define DRV_NAME "i2c-falcon"
++#define DRV_VERSION "1.01"
++
++#define FALCON_I2C_BUSY_TIMEOUT               20 /* ms */
++
++#ifdef DEBUG
++#define FALCON_I2C_XFER_TIMEOUT               25*HZ
++#else
++#define FALCON_I2C_XFER_TIMEOUT               HZ
++#endif
++#if defined(DEBUG) && 0
++#define PRINTK(arg...) printk(arg)
++#else
++#define PRINTK(arg...) do {} while (0)
++#endif
++
++#define FALCON_I2C_IMSC_DEFAULT_MASK  (I2C_IMSC_I2C_P_INT_EN | \
++                                       I2C_IMSC_I2C_ERR_INT_EN)
++
++#define FALCON_I2C_ARB_LOST   (1 << 0)
++#define FALCON_I2C_NACK               (1 << 1)
++#define FALCON_I2C_RX_UFL     (1 << 2)
++#define FALCON_I2C_RX_OFL     (1 << 3)
++#define FALCON_I2C_TX_UFL     (1 << 4)
++#define FALCON_I2C_TX_OFL     (1 << 5)
++
++struct falcon_i2c {
++      struct mutex mutex;
++
++      enum {
++              FALCON_I2C_MODE_100     = 1,
++              FALCON_I2C_MODE_400     = 2,
++              FALCON_I2C_MODE_3400    = 3
++      } mode;                         /* current speed mode */
++
++      struct clk *clk;                /* clock input for i2c hardware block */
++      struct gpon_reg_i2c __iomem *membase;   /* base of mapped registers */
++      int irq_lb, irq_b, irq_err, irq_p;      /* last burst, burst, error,
++                                                 protocol IRQs */
++
++      struct i2c_adapter adap;
++      struct device *dev;
++
++      struct completion       cmd_complete;
++
++      /* message transfer data */
++      /* current message */
++      struct i2c_msg          *current_msg;
++      /* number of messages to handle */
++      int                     msgs_num;
++      /* current buffer */
++      u8                      *msg_buf;
++      /* remaining length of current buffer */
++      u32                     msg_buf_len;
++      /* error status of the current transfer */
++      int                     msg_err;
++
++      /* master status codes */
++      enum {
++              STATUS_IDLE,
++              STATUS_ADDR,    /* address phase */
++              STATUS_WRITE,
++              STATUS_READ,
++              STATUS_READ_END,
++              STATUS_STOP
++      } status;
++};
++
++static irqreturn_t falcon_i2c_isr(int irq, void *dev_id);
++
++static inline void enable_burst_irq(struct falcon_i2c *priv)
++{
++      i2c_w32_mask(0, I2C_IMSC_LBREQ_INT_EN | I2C_IMSC_BREQ_INT_EN, imsc);
++}
++static inline void disable_burst_irq(struct falcon_i2c *priv)
++{
++      i2c_w32_mask(I2C_IMSC_LBREQ_INT_EN | I2C_IMSC_BREQ_INT_EN, 0, imsc);
++}
++
++static void prepare_msg_send_addr(struct falcon_i2c *priv)
++{
++      struct i2c_msg *msg = priv->current_msg;
++      int rd = !!(msg->flags & I2C_M_RD);     /* extends to 0 or 1 */
++      u16 addr = msg->addr;
++
++      /* new i2c_msg */
++      priv->msg_buf = msg->buf;
++      priv->msg_buf_len = msg->len;
++      if (rd)
++              priv->status = STATUS_READ;
++      else
++              priv->status = STATUS_WRITE;
++
++      /* send slave address */
++      if (msg->flags & I2C_M_TEN) {
++              i2c_w32(0xf0 | ((addr & 0x300) >> 7) | rd, txd);
++              i2c_w32(addr & 0xff, txd);
++      } else
++              i2c_w32((addr & 0x7f) << 1 | rd, txd);
++}
++
++static void set_tx_len(struct falcon_i2c *priv)
++{
++      struct i2c_msg *msg = priv->current_msg;
++      int len = (msg->flags & I2C_M_TEN) ? 2 : 1;
++
++      PRINTK("set_tx_len %cX\n", (msg->flags & I2C_M_RD)?'R':'T');
++
++      priv->status = STATUS_ADDR;
++
++      if (!(msg->flags & I2C_M_RD)) {
++              len += msg->len;
++      } else {
++              /* set maximum received packet size (before rx int!) */
++              i2c_w32(msg->len, mrps_ctrl);
++      }
++      i2c_w32(len, tps_ctrl);
++      enable_burst_irq(priv);
++}
++
++static int falcon_i2c_hw_init(struct i2c_adapter *adap)
++{
++      struct falcon_i2c *priv = i2c_get_adapdata(adap);
++
++      /* disable bus */
++      i2c_w32_mask(I2C_RUN_CTRL_RUN_EN, 0, run_ctrl);
++
++#ifndef DEBUG
++      /* set normal operation clock divider */
++      i2c_w32(1 << I2C_CLC_RMC_OFFSET, clc);
++#else
++      /* for debugging a higher divider value! */
++      i2c_w32(0xF0 << I2C_CLC_RMC_OFFSET, clc);
++#endif
++
++      /* set frequency */
++      if (priv->mode == FALCON_I2C_MODE_100) {
++              dev_dbg(priv->dev, "set standard mode (100 kHz)\n");
++              i2c_w32(0, fdiv_high_cfg);
++              i2c_w32((1 << I2C_FDIV_CFG_INC_OFFSET) |
++                      (499 << I2C_FDIV_CFG_DEC_OFFSET),
++                      fdiv_cfg);
++      } else if (priv->mode == FALCON_I2C_MODE_400) {
++              dev_dbg(priv->dev, "set fast mode (400 kHz)\n");
++              i2c_w32(0, fdiv_high_cfg);
++              i2c_w32((1 << I2C_FDIV_CFG_INC_OFFSET) |
++                      (124 << I2C_FDIV_CFG_DEC_OFFSET),
++                      fdiv_cfg);
++      } else if (priv->mode == FALCON_I2C_MODE_3400) {
++              dev_dbg(priv->dev, "set high mode (3.4 MHz)\n");
++              i2c_w32(0, fdiv_cfg);
++              /* TODO recalculate value for 100MHz input */
++              i2c_w32((41 << I2C_FDIV_HIGH_CFG_INC_OFFSET) |
++                      (152 << I2C_FDIV_HIGH_CFG_DEC_OFFSET),
++                      fdiv_high_cfg);
++      } else {
++              dev_warn(priv->dev, "unknown mode\n");
++              return -ENODEV;
++      }
++
++      /* configure fifo */
++      i2c_w32(I2C_FIFO_CFG_TXFC | /* tx fifo as flow controller */
++              I2C_FIFO_CFG_RXFC | /* rx fifo as flow controller */
++              I2C_FIFO_CFG_TXFA_TXFA2 | /* tx fifo 4-byte aligned */
++              I2C_FIFO_CFG_RXFA_RXFA2 | /* rx fifo 4-byte aligned */
++              I2C_FIFO_CFG_TXBS_TXBS0 | /* tx fifo burst size is 1 word */
++              I2C_FIFO_CFG_RXBS_RXBS0,  /* rx fifo burst size is 1 word */
++              fifo_cfg);
++
++      /* configure address */
++      i2c_w32(I2C_ADDR_CFG_SOPE_EN |  /* generate stop when no more data in the
++                                         fifo */
++              I2C_ADDR_CFG_SONA_EN |  /* generate stop when NA received */
++              I2C_ADDR_CFG_MnS_EN |   /* we are master device */
++              0,                      /* our slave address (not used!) */
++              addr_cfg);
++
++      /* enable bus */
++      i2c_w32_mask(0, I2C_RUN_CTRL_RUN_EN, run_ctrl);
++
++      return 0;
++}
++
++static int falcon_i2c_wait_bus_not_busy(struct falcon_i2c *priv)
++{
++      int timeout = FALCON_I2C_BUSY_TIMEOUT;
++
++      while ((i2c_r32(bus_stat) & I2C_BUS_STAT_BS_MASK)
++                               != I2C_BUS_STAT_BS_FREE) {
++              if (timeout <= 0) {
++                      dev_warn(priv->dev, "timeout waiting for bus ready\n");
++                      return -ETIMEDOUT;
++              }
++              timeout--;
++              mdelay(1);
++      }
++
++      return 0;
++}
++
++static void falcon_i2c_tx(struct falcon_i2c *priv, int last)
++{
++      if (priv->msg_buf_len && priv->msg_buf) {
++              i2c_w32(*priv->msg_buf, txd);
++
++              if (--priv->msg_buf_len)
++                      priv->msg_buf++;
++              else
++                      priv->msg_buf = NULL;
++      } else
++              last = 1;
++
++      if (last) {
++              disable_burst_irq(priv);
++      }
++}
++
++static void falcon_i2c_rx(struct falcon_i2c *priv, int last)
++{
++      u32 fifo_stat,timeout;
++      if (priv->msg_buf_len && priv->msg_buf) {
++              timeout = 5000000;
++              do {
++                      fifo_stat = i2c_r32(ffs_stat);
++              } while (!fifo_stat && --timeout);
++              if (!timeout) {
++                      last = 1;
++                      PRINTK("\nrx timeout\n");
++                      goto err;
++              }
++              while (fifo_stat) {
++                      *priv->msg_buf = i2c_r32(rxd);
++                      if (--priv->msg_buf_len)
++                              priv->msg_buf++;
++                      else {
++                              priv->msg_buf = NULL;
++                              last = 1;
++                              break;
++                      }
++                      #if 0
++                      fifo_stat = i2c_r32(ffs_stat);
++                      #else
++                      /* do not read more than burst size, otherwise no "last
++                      burst" is generated and the transaction is blocked! */
++                      fifo_stat = 0;
++                      #endif
++              }
++      } else {
++              last = 1;
++      }
++err:
++      if (last) {
++              disable_burst_irq(priv);
++
++              if (priv->status == STATUS_READ_END) {
++                      /* do the STATUS_STOP and complete() here, as sometimes
++                         the tx_end is already seen before this is finished */
++                      priv->status = STATUS_STOP;
++                      complete(&priv->cmd_complete);
++              } else {
++                      i2c_w32(I2C_ENDD_CTRL_SETEND, endd_ctrl);
++                      priv->status = STATUS_READ_END;
++              }
++      }
++}
++
++static void falcon_i2c_xfer_init(struct falcon_i2c *priv)
++{
++      /* enable interrupts */
++      i2c_w32(FALCON_I2C_IMSC_DEFAULT_MASK, imsc);
++
++      /* trigger transfer of first msg */
++      set_tx_len(priv);
++}
++
++static void dump_msgs(struct i2c_msg msgs[], int num, int rx)
++{
++#if defined(DEBUG)
++      int i, j;
++      printk("Messages %d %s\n", num, rx ? "out" : "in");
++      for (i = 0; i < num; i++) {
++              printk("%2d %cX Msg(%d) addr=0x%X: ", i,
++                      (msgs[i].flags & I2C_M_RD)?'R':'T',
++                      msgs[i].len, msgs[i].addr);
++              if (!(msgs[i].flags & I2C_M_RD) || rx) {
++                      for (j = 0; j < msgs[i].len; j++)
++                              printk("%02X ", msgs[i].buf[j]);
++              }
++              printk("\n");
++      }
++#endif
++}
++
++static void falcon_i2c_release_bus(struct falcon_i2c *priv)
++{
++      if ((i2c_r32(bus_stat) & I2C_BUS_STAT_BS_MASK) == I2C_BUS_STAT_BS_BM)
++              i2c_w32(I2C_ENDD_CTRL_SETEND, endd_ctrl);
++}
++
++static int falcon_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
++                         int num)
++{
++      struct falcon_i2c *priv = i2c_get_adapdata(adap);
++      int ret;
++
++      dev_dbg(priv->dev, "xfer %u messages\n", num);
++      dump_msgs(msgs, num, 0);
++
++      mutex_lock(&priv->mutex);
++
++      INIT_COMPLETION(priv->cmd_complete);
++      priv->current_msg = msgs;
++      priv->msgs_num = num;
++      priv->msg_err = 0;
++      priv->status = STATUS_IDLE;
++
++      /* wait for the bus to become ready */
++      ret = falcon_i2c_wait_bus_not_busy(priv);
++      if (ret)
++              goto done;
++
++      while (priv->msgs_num) {
++              /* start the transfers */
++              falcon_i2c_xfer_init(priv);
++
++              /* wait for transfers to complete */
++              ret = wait_for_completion_interruptible_timeout(
++                      &priv->cmd_complete, FALCON_I2C_XFER_TIMEOUT);
++              if (ret == 0) {
++                      dev_err(priv->dev, "controller timed out\n");
++                      falcon_i2c_hw_init(adap);
++                      ret = -ETIMEDOUT;
++                      goto done;
++              } else if (ret < 0)
++                      goto done;
++
++              if (priv->msg_err) {
++                      if (priv->msg_err & FALCON_I2C_NACK)
++                              ret = -ENXIO;
++                      else
++                              ret = -EREMOTEIO;
++                      goto done;
++              }
++              if (--priv->msgs_num) {
++                      priv->current_msg++;
++              }
++      }
++      /* no error? */
++      ret = num;
++
++done:
++      falcon_i2c_release_bus(priv);
++
++      mutex_unlock(&priv->mutex);
++
++      if (ret>=0)
++              dump_msgs(msgs, num, 1);
++
++      PRINTK("XFER ret %d\n", ret);
++      return ret;
++}
++
++static irqreturn_t falcon_i2c_isr_burst(int irq, void *dev_id)
++{
++      struct falcon_i2c *priv = dev_id;
++      struct i2c_msg *msg = priv->current_msg;
++      int last = (irq == priv->irq_lb);
++
++      if (last)
++              PRINTK("LB ");
++      else
++              PRINTK("B ");
++
++      if (msg->flags & I2C_M_RD) {
++              switch (priv->status) {
++              case STATUS_ADDR:
++                      PRINTK("X");
++                      prepare_msg_send_addr(priv);
++                      disable_burst_irq(priv);
++                      break;
++              case STATUS_READ:
++              case STATUS_READ_END:
++                      PRINTK("R");
++                      falcon_i2c_rx(priv, last);
++                      break;
++              default:
++                      disable_burst_irq(priv);
++                      printk("Status R %d\n", priv->status);
++                      break;
++              }
++      } else {
++              switch (priv->status) {
++              case STATUS_ADDR:
++                      PRINTK("x");
++                      prepare_msg_send_addr(priv);
++                      break;
++              case STATUS_WRITE:
++                      PRINTK("w");
++                      falcon_i2c_tx(priv, last);
++                      break;
++              default:
++                      disable_burst_irq(priv);
++                      printk("Status W %d\n", priv->status);
++                      break;
++              }
++      }
++
++      i2c_w32(I2C_ICR_BREQ_INT_CLR | I2C_ICR_LBREQ_INT_CLR, icr);
++      return IRQ_HANDLED;
++}
++
++static void falcon_i2c_isr_prot(struct falcon_i2c *priv)
++{
++      u32 i_pro = i2c_r32(p_irqss);
++
++      PRINTK("i2c-p");
++
++      /* not acknowledge */
++      if (i_pro & I2C_P_IRQSS_NACK) {
++              priv->msg_err |= FALCON_I2C_NACK;
++              PRINTK(" nack");
++      }
++
++      /* arbitration lost */
++      if (i_pro & I2C_P_IRQSS_AL) {
++              priv->msg_err |= FALCON_I2C_ARB_LOST;
++              PRINTK(" arb-lost");
++      }
++      /* tx -> rx switch */
++      if (i_pro & I2C_P_IRQSS_RX)
++              PRINTK(" rx");
++
++      /* tx end */
++      if (i_pro & I2C_P_IRQSS_TX_END)
++              PRINTK(" txend");
++      PRINTK("\n");
++
++      if (!priv->msg_err) {
++              /* tx -> rx switch */
++              if (i_pro & I2C_P_IRQSS_RX) {
++                      priv->status = STATUS_READ;
++                      enable_burst_irq(priv);
++              }
++              if (i_pro & I2C_P_IRQSS_TX_END) {
++                      if (priv->status == STATUS_READ)
++                              priv->status = STATUS_READ_END;
++                      else {
++                              disable_burst_irq(priv);
++                              priv->status = STATUS_STOP;
++                      }
++              }
++      }
++
++      i2c_w32(i_pro, p_irqsc);
++}
++
++static irqreturn_t falcon_i2c_isr(int irq, void *dev_id)
++{
++      u32 i_raw, i_err=0;
++      struct falcon_i2c *priv = dev_id;
++
++      i_raw = i2c_r32(mis);
++      PRINTK("i_raw 0x%08X\n", i_raw);
++
++      /* error interrupt */
++      if (i_raw & I2C_RIS_I2C_ERR_INT_INTOCC) {
++              i_err = i2c_r32(err_irqss);
++              PRINTK("i_err 0x%08X bus_stat 0x%04X\n",
++                      i_err, i2c_r32(bus_stat));
++
++              /* tx fifo overflow (8) */
++              if (i_err & I2C_ERR_IRQSS_TXF_OFL)
++                      priv->msg_err |= FALCON_I2C_TX_OFL;
++
++              /* tx fifo underflow (4) */
++              if (i_err & I2C_ERR_IRQSS_TXF_UFL)
++                      priv->msg_err |= FALCON_I2C_TX_UFL;
++
++              /* rx fifo overflow (2) */
++              if (i_err & I2C_ERR_IRQSS_RXF_OFL)
++                      priv->msg_err |= FALCON_I2C_RX_OFL;
++
++              /* rx fifo underflow (1) */
++              if (i_err & I2C_ERR_IRQSS_RXF_UFL)
++                      priv->msg_err |= FALCON_I2C_RX_UFL;
++
++              i2c_w32(i_err, err_irqsc);
++      }
++
++      /* protocol interrupt */
++      if (i_raw & I2C_RIS_I2C_P_INT_INTOCC)
++              falcon_i2c_isr_prot(priv);
++
++      if ((priv->msg_err) || (priv->status == STATUS_STOP))
++              complete(&priv->cmd_complete);
++
++      return IRQ_HANDLED;
++}
++
++static u32 falcon_i2c_functionality(struct i2c_adapter *adap)
++{
++      return  I2C_FUNC_I2C |
++              I2C_FUNC_10BIT_ADDR |
++              I2C_FUNC_SMBUS_EMUL;
++}
++
++static struct i2c_algorithm falcon_i2c_algorithm = {
++      .master_xfer    = falcon_i2c_xfer,
++      .functionality  = falcon_i2c_functionality,
++};
++
++static int __devinit falcon_i2c_probe(struct platform_device *pdev)
++{
++      int ret = 0;
++      struct falcon_i2c *priv;
++      struct i2c_adapter *adap;
++      struct resource *mmres, *ioarea,
++                      *irqres_lb, *irqres_b, *irqres_err, *irqres_p;
++      struct clk *clk;
++
++      dev_dbg(&pdev->dev, "probing\n");
++
++      mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++      irqres_lb = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
++                                               "i2c_lb");
++      irqres_b = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "i2c_b");
++      irqres_err = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
++                                                "i2c_err");
++      irqres_p = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "i2c_p");
++
++      if (!mmres || !irqres_lb || !irqres_b || !irqres_err || !irqres_p) {
++              dev_err(&pdev->dev, "no resources\n");
++              return -ENODEV;
++      }
++
++      clk = clk_get(&pdev->dev, "fpi");
++      if (IS_ERR(clk)) {
++              dev_err(&pdev->dev, "failed to get fpi clk\n");
++              return -ENOENT;
++      }
++
++      if (clk_get_rate(clk) != 100000000) {
++              dev_err(&pdev->dev, "input clock is not 100MHz\n");
++              return -ENOENT;
++      }
++
++      /* allocate private data */
++      priv = kzalloc(sizeof(*priv), GFP_KERNEL);
++      if (!priv) {
++              dev_err(&pdev->dev, "can't allocate private data\n");
++              return -ENOMEM;
++      }
++
++      adap = &priv->adap;
++      i2c_set_adapdata(adap, priv);
++      adap->owner = THIS_MODULE;
++      adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
++      strlcpy(adap->name, DRV_NAME "-adapter", sizeof(adap->name));
++      adap->algo = &falcon_i2c_algorithm;
++
++      priv->mode = FALCON_I2C_MODE_100;
++      priv->clk = clk;
++      priv->dev = &pdev->dev;
++
++      init_completion(&priv->cmd_complete);
++      mutex_init(&priv->mutex);
++
++      ret = ltq_gpio_request(107, 0, 0, 0, DRV_NAME":sda");
++      if (ret) {
++              dev_err(&pdev->dev, "I2C gpio 107 (sda) not available\n");
++              ret = -ENXIO;
++              goto err_free_priv;
++      }
++      ret = ltq_gpio_request(108, 0, 0, 0, DRV_NAME":scl");
++      if (ret) {
++              gpio_free(107);
++              dev_err(&pdev->dev, "I2C gpio 108 (scl) not available\n");
++              ret = -ENXIO;
++              goto err_free_priv;
++      }
++
++      ioarea = request_mem_region(mmres->start, resource_size(mmres),
++                                       pdev->name);
++
++      if (ioarea == NULL) {
++              dev_err(&pdev->dev, "I2C region already claimed\n");
++              ret = -ENXIO;
++              goto err_free_gpio;
++      }
++
++      /* map memory */
++      priv->membase = ioremap_nocache(mmres->start & ~KSEG1,
++              resource_size(mmres));
++      if (priv->membase == NULL) {
++              ret = -ENOMEM;
++              goto err_release_region;
++      }
++
++      priv->irq_lb = irqres_lb->start;
++      ret = request_irq(priv->irq_lb, falcon_i2c_isr_burst, IRQF_DISABLED,
++                        irqres_lb->name, priv);
++      if (ret) {
++              dev_err(&pdev->dev, "can't get last burst IRQ %d\n", irqres_lb->start);
++              ret = -ENODEV;
++              goto err_unmap_mem;
++      }
++
++      priv->irq_b = irqres_b->start;
++      ret = request_irq(priv->irq_b, falcon_i2c_isr_burst, IRQF_DISABLED,
++                        irqres_b->name, priv);
++      if (ret) {
++              dev_err(&pdev->dev, "can't get burst IRQ %d\n", irqres_b->start);
++              ret = -ENODEV;
++              goto err_free_lb_irq;
++      }
++
++      priv->irq_err = irqres_err->start;
++      ret = request_irq(priv->irq_err, falcon_i2c_isr, IRQF_DISABLED,
++                        irqres_err->name, priv);
++      if (ret) {
++              dev_err(&pdev->dev, "can't get error IRQ %d\n", irqres_err->start);
++              ret = -ENODEV;
++              goto err_free_b_irq;
++      }
++
++      priv->irq_p = irqres_p->start;
++      ret = request_irq(priv->irq_p, falcon_i2c_isr, IRQF_DISABLED,
++                        irqres_p->name, priv);
++      if (ret) {
++              dev_err(&pdev->dev, "can't get protocol IRQ %d\n", irqres_p->start);
++              ret = -ENODEV;
++              goto err_free_err_irq;
++      }
++
++      dev_dbg(&pdev->dev, "mapped io-space to %p\n", priv->membase);
++      dev_dbg(&pdev->dev, "use IRQs %d, %d, %d, %d\n", irqres_lb->start,
++          irqres_b->start, irqres_err->start, irqres_p->start);
++
++      /* add our adapter to the i2c stack */
++      ret = i2c_add_numbered_adapter(adap);
++      if (ret) {
++              dev_err(&pdev->dev, "can't register I2C adapter\n");
++              goto err_free_p_irq;
++      }
++
++      platform_set_drvdata(pdev, priv);
++      i2c_set_adapdata(adap, priv);
++
++      /* print module version information */
++      dev_dbg(&pdev->dev, "module id=%u revision=%u\n",
++              (i2c_r32(id) & I2C_ID_ID_MASK) >> I2C_ID_ID_OFFSET,
++              (i2c_r32(id) & I2C_ID_REV_MASK) >> I2C_ID_REV_OFFSET);
++
++      /* initialize HW */
++      ret = falcon_i2c_hw_init(adap);
++      if (ret) {
++              dev_err(&pdev->dev, "can't configure adapter\n");
++              goto err_remove_adapter;
++      }
++
++      dev_info(&pdev->dev, "version %s\n", DRV_VERSION);
++
++      return 0;
++
++err_remove_adapter:
++      i2c_del_adapter(adap);
++      platform_set_drvdata(pdev, NULL);
++
++err_free_p_irq:
++      free_irq(priv->irq_p, priv);
++
++err_free_err_irq:
++      free_irq(priv->irq_err, priv);
++
++err_free_b_irq:
++      free_irq(priv->irq_b, priv);
++
++err_free_lb_irq:
++      free_irq(priv->irq_lb, priv);
++
++err_unmap_mem:
++      iounmap(priv->membase);
++
++err_release_region:
++      release_mem_region(mmres->start, resource_size(mmres));
++
++err_free_gpio:
++      gpio_free(108);
++      gpio_free(107);
++
++err_free_priv:
++      kfree(priv);
++
++      return ret;
++}
++
++static int __devexit falcon_i2c_remove(struct platform_device *pdev)
++{
++      struct falcon_i2c *priv = platform_get_drvdata(pdev);
++      struct resource *mmres;
++
++      /* disable bus */
++      i2c_w32_mask(I2C_RUN_CTRL_RUN_EN, 0, run_ctrl);
++
++      /* remove driver */
++      platform_set_drvdata(pdev, NULL);
++      i2c_del_adapter(&priv->adap);
++
++      free_irq(priv->irq_lb, priv);
++      free_irq(priv->irq_b, priv);
++      free_irq(priv->irq_err, priv);
++      free_irq(priv->irq_p, priv);
++
++      iounmap(priv->membase);
++
++      gpio_free(108);
++      gpio_free(107);
++
++      kfree(priv);
++
++      mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++      release_mem_region(mmres->start, resource_size(mmres));
++
++      dev_dbg(&pdev->dev, "removed\n");
++
++      return 0;
++}
++
++static struct platform_driver falcon_i2c_driver = {
++      .probe  = falcon_i2c_probe,
++      .remove = __devexit_p(falcon_i2c_remove),
++      .driver = {
++              .name   = DRV_NAME,
++              .owner  = THIS_MODULE,
++      },
++};
++
++static int __init falcon_i2c_init(void)
++{
++      int ret;
++
++      ret = platform_driver_register(&falcon_i2c_driver);
++
++      if (ret)
++              pr_debug(DRV_NAME ": can't register platform driver\n");
++
++      return ret;
++}
++
++static void __exit falcon_i2c_exit(void)
++{
++      platform_driver_unregister(&falcon_i2c_driver);
++}
++
++module_init(falcon_i2c_init);
++module_exit(falcon_i2c_exit);
++
++MODULE_DESCRIPTION("Lantiq FALC(tm) ON - I2C bus adapter");
++MODULE_ALIAS("platform:" DRV_NAME);
++MODULE_LICENSE("GPL");
++MODULE_VERSION(DRV_VERSION);
+-- 
+1.7.5.4
+
diff --git a/target/linux/lantiq/patches-3.0/0012-MIPS-lantiq-adds-GPIO3-support-on-AR9.patch b/target/linux/lantiq/patches-3.0/0012-MIPS-lantiq-adds-GPIO3-support-on-AR9.patch
new file mode 100644 (file)
index 0000000..e20b66b
--- /dev/null
@@ -0,0 +1,212 @@
+From 6b5e2ee7c8f9722d59213f17d423b3f90d80f822 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Sat, 13 Aug 2011 13:59:50 +0200
+Subject: [PATCH 12/24] MIPS: lantiq: adds GPIO3 support on AR9
+
+There are 3 16bit and 1 8bit gpio ports on AR9. The gpio driver needs a hack
+at 2 places to make the different register layout of the GPIO3 work properly
+with the driver. Before only GPIO0-2 were supported. As the GPIO number scheme
+clashes with the new size, we also move the other gpio chips to new offsets.
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+Signed-off-by: Thomas Langer <thomas.langer@lantiq.com>
+---
+ .../mips/include/asm/mach-lantiq/xway/lantiq_soc.h |    2 +
+ arch/mips/lantiq/xway/devices.c                    |    3 +
+ arch/mips/lantiq/xway/gpio.c                       |   62 ++++++++++++++++----
+ arch/mips/lantiq/xway/gpio_ebu.c                   |    3 +-
+ arch/mips/lantiq/xway/gpio_stp.c                   |    3 +-
+ 5 files changed, 57 insertions(+), 16 deletions(-)
+
+diff --git a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
+index da8ff95..421768e 100644
+--- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
++++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
+@@ -113,7 +113,9 @@
+ #define LTQ_GPIO0_BASE_ADDR   0x1E100B10
+ #define LTQ_GPIO1_BASE_ADDR   0x1E100B40
+ #define LTQ_GPIO2_BASE_ADDR   0x1E100B70
++#define LTQ_GPIO3_BASE_ADDR   0x1E100BA0
+ #define LTQ_GPIO_SIZE         0x30
++#define LTQ_GPIO3_SIZE                0x10
+ /* SSC */
+ #define LTQ_SSC_BASE_ADDR     0x1e100800
+diff --git a/arch/mips/lantiq/xway/devices.c b/arch/mips/lantiq/xway/devices.c
+index 9bacaa8..b7efac5 100644
+--- a/arch/mips/lantiq/xway/devices.c
++++ b/arch/mips/lantiq/xway/devices.c
+@@ -34,6 +34,7 @@ static struct resource ltq_gpio_resource[] = {
+       MEM_RES("gpio0", LTQ_GPIO0_BASE_ADDR, LTQ_GPIO_SIZE),
+       MEM_RES("gpio1", LTQ_GPIO1_BASE_ADDR, LTQ_GPIO_SIZE),
+       MEM_RES("gpio2", LTQ_GPIO2_BASE_ADDR, LTQ_GPIO_SIZE),
++      MEM_RES("gpio3", LTQ_GPIO3_BASE_ADDR, LTQ_GPIO3_SIZE),
+ };
+ void __init ltq_register_gpio(void)
+@@ -47,6 +48,8 @@ void __init ltq_register_gpio(void)
+       if (ltq_is_ar9() || ltq_is_vr9()) {
+               platform_device_register_simple("ltq_gpio", 2,
+                       &ltq_gpio_resource[2], 1);
++              platform_device_register_simple("ltq_gpio", 3,
++                      &ltq_gpio_resource[3], 1);
+       }
+ }
+diff --git a/arch/mips/lantiq/xway/gpio.c b/arch/mips/lantiq/xway/gpio.c
+index a321451..2c48c17 100644
+--- a/arch/mips/lantiq/xway/gpio.c
++++ b/arch/mips/lantiq/xway/gpio.c
+@@ -21,9 +21,15 @@
+ #define LTQ_GPIO_ALTSEL0      0x0C
+ #define LTQ_GPIO_ALTSEL1      0x10
+ #define LTQ_GPIO_OD           0x14
++#define LTQ_GPIO3_OD          0x24
++#define LTQ_GPIO3_ALTSEL1     0x24
++/* PORT3 only has 8 pins and its register layout
++   is slightly different */
+ #define PINS_PER_PORT         16
+-#define MAX_PORTS             3
++#define PINS_PORT3            8
++#define MAX_PORTS             4
++#define MAX_PIN                       56
+ #define ltq_gpio_getbit(m, r, p)      (!!(ltq_r32(m + r) & (1 << p)))
+ #define ltq_gpio_setbit(m, r, p)      ltq_w32_mask(0, (1 << p), m + r)
+@@ -53,7 +59,7 @@ int ltq_gpio_request(unsigned int pin, unsigned int alt0,
+ {
+       int id = 0;
+-      if (pin >= (MAX_PORTS * PINS_PER_PORT))
++      if (pin >= MAX_PIN)
+               return -EINVAL;
+       if (gpio_request(pin, name)) {
+               pr_err("failed to setup lantiq gpio: %s\n", name);
+@@ -73,12 +79,21 @@ int ltq_gpio_request(unsigned int pin, unsigned int alt0,
+       else
+               ltq_gpio_clearbit(ltq_gpio_port[id].membase,
+                       LTQ_GPIO_ALTSEL0, pin);
+-      if (alt1)
+-              ltq_gpio_setbit(ltq_gpio_port[id].membase,
+-                      LTQ_GPIO_ALTSEL1, pin);
+-      else
+-              ltq_gpio_clearbit(ltq_gpio_port[id].membase,
+-                      LTQ_GPIO_ALTSEL1, pin);
++      if (id == 3) {
++              if (alt1)
++                      ltq_gpio_setbit(ltq_gpio_port[1].membase,
++                              LTQ_GPIO3_ALTSEL1, pin);
++              else
++                      ltq_gpio_clearbit(ltq_gpio_port[1].membase,
++                              LTQ_GPIO3_ALTSEL1, pin);
++      } else {
++              if (alt1)
++                      ltq_gpio_setbit(ltq_gpio_port[id].membase,
++                              LTQ_GPIO_ALTSEL1, pin);
++              else
++                      ltq_gpio_clearbit(ltq_gpio_port[id].membase,
++                              LTQ_GPIO_ALTSEL1, pin);
++      }
+       return 0;
+ }
+ EXPORT_SYMBOL(ltq_gpio_request);
+@@ -104,7 +119,11 @@ static int ltq_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
+ {
+       struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip);
+-      ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_OD, offset);
++      if (chip->ngpio == PINS_PORT3)
++              ltq_gpio_clearbit(ltq_gpio_port[0].membase,
++                              LTQ_GPIO3_OD, offset);
++      else
++              ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_OD, offset);
+       ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_DIR, offset);
+       return 0;
+@@ -115,7 +134,10 @@ static int ltq_gpio_direction_output(struct gpio_chip *chip,
+ {
+       struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip);
+-      ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_OD, offset);
++      if (chip->ngpio == PINS_PORT3)
++              ltq_gpio_setbit(ltq_gpio_port[0].membase, LTQ_GPIO3_OD, offset);
++      else
++              ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_OD, offset);
+       ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_DIR, offset);
+       ltq_gpio_set(chip, offset, value);
+@@ -127,7 +149,11 @@ static int ltq_gpio_req(struct gpio_chip *chip, unsigned offset)
+       struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip);
+       ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_ALTSEL0, offset);
+-      ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_ALTSEL1, offset);
++      if (chip->ngpio == PINS_PORT3)
++              ltq_gpio_clearbit(ltq_gpio_port[1].membase,
++                              LTQ_GPIO3_ALTSEL1, offset);
++      else
++              ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_ALTSEL1, offset);
+       return 0;
+ }
+@@ -140,6 +166,15 @@ static int ltq_gpio_probe(struct platform_device *pdev)
+                       pdev->id);
+               return -EINVAL;
+       }
++
++      /* dirty hack - The registers of port3 are not mapped linearly.
++         Port 3 may only load if Port 1/2 are mapped */
++      if ((pdev->id == 3) && (!ltq_gpio_port[1].membase || !ltq_gpio_port[2].membase)) {
++              dev_err(&pdev->dev,
++                      "ports 1/2 need to be loaded before port 3 works\n");
++              return -ENOMEM;
++      }
++
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res) {
+               dev_err(&pdev->dev, "failed to get memory for gpio port %d\n",
+@@ -169,7 +204,10 @@ static int ltq_gpio_probe(struct platform_device *pdev)
+       ltq_gpio_port[pdev->id].chip.set = ltq_gpio_set;
+       ltq_gpio_port[pdev->id].chip.request = ltq_gpio_req;
+       ltq_gpio_port[pdev->id].chip.base = PINS_PER_PORT * pdev->id;
+-      ltq_gpio_port[pdev->id].chip.ngpio = PINS_PER_PORT;
++      if (pdev->id == 3)
++              ltq_gpio_port[pdev->id].chip.ngpio = PINS_PORT3;
++      else
++              ltq_gpio_port[pdev->id].chip.ngpio = PINS_PER_PORT;
+       platform_set_drvdata(pdev, &ltq_gpio_port[pdev->id]);
+       return gpiochip_add(&ltq_gpio_port[pdev->id].chip);
+ }
+diff --git a/arch/mips/lantiq/xway/gpio_ebu.c b/arch/mips/lantiq/xway/gpio_ebu.c
+index a479355..729f8e3 100644
+--- a/arch/mips/lantiq/xway/gpio_ebu.c
++++ b/arch/mips/lantiq/xway/gpio_ebu.c
+@@ -61,9 +61,8 @@ static struct gpio_chip ltq_ebu_chip = {
+       .label = "ltq_ebu",
+       .direction_output = ltq_ebu_direction_output,
+       .set = ltq_ebu_set,
+-      .base = 72,
++      .base = 100,
+       .ngpio = 16,
+-      .can_sleep = 1,
+       .owner = THIS_MODULE,
+ };
+diff --git a/arch/mips/lantiq/xway/gpio_stp.c b/arch/mips/lantiq/xway/gpio_stp.c
+index 67d59d6..c01294e 100644
+--- a/arch/mips/lantiq/xway/gpio_stp.c
++++ b/arch/mips/lantiq/xway/gpio_stp.c
+@@ -70,9 +70,8 @@ static struct gpio_chip ltq_stp_chip = {
+       .label = "ltq_stp",
+       .direction_output = ltq_stp_direction_output,
+       .set = ltq_stp_set,
+-      .base = 48,
++      .base = 200,
+       .ngpio = 24,
+-      .can_sleep = 1,
+       .owner = THIS_MODULE,
+ };
+-- 
+1.7.5.4
+
diff --git a/target/linux/lantiq/patches-3.0/0013-MIPS-lantiq-adds-FALC-ON-spi-driver.patch b/target/linux/lantiq/patches-3.0/0013-MIPS-lantiq-adds-FALC-ON-spi-driver.patch
new file mode 100644 (file)
index 0000000..ddc624f
--- /dev/null
@@ -0,0 +1,659 @@
+From 2bd534c30688bcb3f70f1816fbcff813fc746103 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Sat, 27 Aug 2011 18:12:26 +0200
+Subject: [PATCH 13/24] MIPS: lantiq: adds FALC-ON spi driver
+
+The external bus unit (EBU) found on the FALC-ON SoC has spi emulation that is
+designed for serial flash access.
+
+Signed-off-by: Thomas Langer <thomas.langer@lantiq.com>
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ arch/mips/lantiq/falcon/devices.c        |   12 +-
+ arch/mips/lantiq/falcon/devices.h        |    4 +
+ arch/mips/lantiq/falcon/mach-easy98000.c |   27 ++
+ drivers/spi/Kconfig                      |    4 +
+ drivers/spi/Makefile                     |    1 +
+ drivers/spi/spi-falcon.c                 |  477 ++++++++++++++++++++++++++++++
+ 6 files changed, 523 insertions(+), 2 deletions(-)
+ create mode 100644 drivers/spi/spi-falcon.c
+
+Index: linux-3.0.3/arch/mips/lantiq/falcon/devices.c
+===================================================================
+--- linux-3.0.3.orig/arch/mips/lantiq/falcon/devices.c 2011-10-05 12:30:34.584838403 +0200
++++ linux-3.0.3/arch/mips/lantiq/falcon/devices.c      2011-10-05 12:42:58.696870214 +0200
+@@ -129,7 +129,7 @@
+ /* i2c */
+ static struct resource falcon_i2c_resources[] = {
+-      MEM_RES("i2c", GPON_I2C_BASE,GPON_I2C_END),
++      MEM_RES("i2c", LTQ_I2C_BASE_ADDR, LTQ_I2C_SIZE),
+       IRQ_RES("i2c_lb", FALCON_IRQ_I2C_LBREQ),
+       IRQ_RES("i2c_b", FALCON_IRQ_I2C_BREQ),
+       IRQ_RES("i2c_err", FALCON_IRQ_I2C_I2C_ERR),
+@@ -140,10 +140,18 @@
+ {
+       platform_device_register_simple("i2c-falcon", 0,
+       falcon_i2c_resources, ARRAY_SIZE(falcon_i2c_resources));
+-      sys1_hw_activate(ACTS_I2C_ACT);
++      ltq_sysctl_activate(SYSCTL_SYS1, ACTS_I2C_ACT);
+ }
+-void __init falcon_register_crypto(void)
++/* spi flash */
++static struct platform_device ltq_spi = {
++      .name                   = "falcon_spi",
++      .num_resources          = 0,
++};
++
++void __init
++falcon_register_spi_flash(struct spi_board_info *data)
+ {
+-      platform_device_register_simple("ltq_falcon_deu", 0, NULL, 0);
++      spi_register_board_info(data, 1);
++      platform_device_register(&ltq_spi);
+ }
+Index: linux-3.0.3/arch/mips/lantiq/falcon/devices.h
+===================================================================
+--- linux-3.0.3.orig/arch/mips/lantiq/falcon/devices.h 2011-10-05 12:30:34.584838403 +0200
++++ linux-3.0.3/arch/mips/lantiq/falcon/devices.h      2011-10-05 12:30:34.600838405 +0200
+@@ -11,11 +11,15 @@
+ #ifndef _FALCON_DEVICES_H__
+ #define _FALCON_DEVICES_H__
++#include <linux/spi/spi.h>
++#include <linux/spi/flash.h>
++
+ #include "../devices.h"
+ extern void falcon_register_nand(void);
+ extern void falcon_register_gpio(void);
+ extern void falcon_register_gpio_extra(void);
+ extern void falcon_register_i2c(void);
++extern void falcon_register_spi_flash(struct spi_board_info *data);
+ #endif
+Index: linux-3.0.3/arch/mips/lantiq/falcon/mach-easy98000.c
+===================================================================
+--- linux-3.0.3.orig/arch/mips/lantiq/falcon/mach-easy98000.c  2011-10-05 12:30:34.552838402 +0200
++++ linux-3.0.3/arch/mips/lantiq/falcon/mach-easy98000.c       2011-10-05 12:30:34.600838405 +0200
+@@ -40,6 +40,21 @@
+       .parts          = easy98000_nor_partitions,
+ };
++static struct flash_platform_data easy98000_spi_flash_platform_data = {
++      .name = "sflash",
++      .parts = easy98000_nor_partitions,
++      .nr_parts = ARRAY_SIZE(easy98000_nor_partitions)
++};
++
++static struct spi_board_info easy98000_spi_flash_data __initdata = {
++      .modalias               = "m25p80",
++      .bus_num                = 0,
++      .chip_select            = 0,
++      .max_speed_hz           = 10 * 1000 * 1000,
++      .mode                   = SPI_MODE_3,
++      .platform_data          = &easy98000_spi_flash_platform_data
++};
++
+ /* setup gpio based spi bus/device for access to the eeprom on the board */
+ #define SPI_GPIO_MRST         102
+ #define SPI_GPIO_MTSR         103
+@@ -93,6 +108,13 @@
+ }
+ static void __init
++easy98000sf_init(void)
++{
++      easy98000_init_common();
++      falcon_register_spi_flash(&easy98000_spi_flash_data);
++}
++
++static void __init
+ easy98000nand_init(void)
+ {
+       easy98000_init_common();
+@@ -104,6 +126,11 @@
+                       "EASY98000 Eval Board",
+                       easy98000_init);
++MIPS_MACHINE(LANTIQ_MACH_EASY98000SF,
++                      "EASY98000SF",
++                      "EASY98000 Eval Board (Serial Flash)",
++                      easy98000sf_init);
++
+ MIPS_MACHINE(LANTIQ_MACH_EASY98000NAND,
+                       "EASY98000NAND",
+                       "EASY98000 Eval Board (NAND Flash)",
+Index: linux-3.0.3/drivers/spi/Kconfig
+===================================================================
+--- linux-3.0.3.orig/drivers/spi/Kconfig       2011-10-05 12:30:33.608838362 +0200
++++ linux-3.0.3/drivers/spi/Kconfig    2011-10-05 12:41:56.864867570 +0200
+@@ -219,6 +219,10 @@
+         This drivers supports the MPC52xx SPI controller in master SPI
+         mode.
++config SPI_FALCON
++      tristate "Falcon SPI controller support"
++      depends on SOC_FALCON
++
+ config SPI_MPC52xx_PSC
+       tristate "Freescale MPC52xx PSC SPI controller"
+       depends on PPC_MPC52xx && EXPERIMENTAL
+Index: linux-3.0.3/drivers/spi/Makefile
+===================================================================
+--- linux-3.0.3.orig/drivers/spi/Makefile      2011-10-05 12:30:33.608838362 +0200
++++ linux-3.0.3/drivers/spi/Makefile   2011-10-05 12:41:56.884867571 +0200
+@@ -56,6 +56,7 @@
+ obj-$(CONFIG_SPI_SH_MSIOF)            += spi_sh_msiof.o
+ obj-$(CONFIG_SPI_STMP3XXX)            += spi_stmp.o
+ obj-$(CONFIG_SPI_NUC900)              += spi_nuc900.o
++obj-$(CONFIG_SPI_FALCON)              += spi-falcon.o
+ # special build for s3c24xx spi driver with fiq support
+ spi_s3c24xx_hw-y                      := spi_s3c24xx.o
+Index: linux-3.0.3/drivers/spi/spi-falcon.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-3.0.3/drivers/spi/spi-falcon.c       2011-10-05 12:30:34.600838405 +0200
+@@ -0,0 +1,477 @@
++/*
++ *  This program is free software; you can redistribute it and/or modify it
++ *  under the terms of the GNU General Public License version 2 as published
++ *  by the Free Software Foundation.
++ *
++ *  Copyright (C) 2010 Thomas Langer <thomas.langer@lantiq.com>
++ */
++
++#include <linux/module.h>
++#include <linux/device.h>
++#include <linux/platform_device.h>
++#include <linux/spi/spi.h>
++#include <linux/delay.h>
++#include <linux/workqueue.h>
++
++#include <lantiq_soc.h>
++
++#define DRV_NAME                      "falcon_spi"
++
++#define FALCON_SPI_XFER_BEGIN         (1 << 0)
++#define FALCON_SPI_XFER_END           (1 << 1)
++
++/* Bus Read Configuration Register0 */
++#define LTQ_BUSRCON0  0x00000010
++/* Bus Write Configuration Register0 */
++#define LTQ_BUSWCON0  0x00000018
++/* Serial Flash Configuration Register */
++#define LTQ_SFCON     0x00000080
++/* Serial Flash Time Register */
++#define LTQ_SFTIME    0x00000084
++/* Serial Flash Status Register */
++#define LTQ_SFSTAT    0x00000088
++/* Serial Flash Command Register */
++#define LTQ_SFCMD     0x0000008C
++/* Serial Flash Address Register */
++#define LTQ_SFADDR    0x00000090
++/* Serial Flash Data Register */
++#define LTQ_SFDATA    0x00000094
++/* Serial Flash I/O Control Register */
++#define LTQ_SFIO      0x00000098
++/* EBU Clock Control Register */
++#define LTQ_EBUCC     0x000000C4
++
++/* Dummy Phase Length */
++#define SFCMD_DUMLEN_OFFSET   16
++#define SFCMD_DUMLEN_MASK     0x000F0000
++/* Chip Select */
++#define SFCMD_CS_OFFSET               24
++#define SFCMD_CS_MASK         0x07000000
++/* field offset */
++#define SFCMD_ALEN_OFFSET     20
++#define SFCMD_ALEN_MASK               0x00700000
++/* SCK Rise-edge Position */
++#define SFTIME_SCKR_POS_OFFSET        8
++#define SFTIME_SCKR_POS_MASK  0x00000F00
++/* SCK Period */
++#define SFTIME_SCK_PER_OFFSET 0
++#define SFTIME_SCK_PER_MASK   0x0000000F
++/* SCK Fall-edge Position */
++#define SFTIME_SCKF_POS_OFFSET        12
++#define SFTIME_SCKF_POS_MASK  0x0000F000
++/* Device Size */
++#define SFCON_DEV_SIZE_A23_0  0x03000000
++#define SFCON_DEV_SIZE_MASK   0x0F000000
++/* Read Data Position */
++#define SFTIME_RD_POS_MASK    0x000F0000
++/* Data Output */
++#define SFIO_UNUSED_WD_MASK   0x0000000F
++/* Command Opcode mask */
++#define SFCMD_OPC_MASK                0x000000FF
++/* dlen bytes of data to write */
++#define SFCMD_DIR_WRITE               0x00000100
++/* Data Length offset */
++#define SFCMD_DLEN_OFFSET     9
++/* Command Error */
++#define SFSTAT_CMD_ERR                0x20000000
++/* Access Command Pending */
++#define SFSTAT_CMD_PEND               0x00400000
++/* Frequency set to 100MHz. */
++#define EBUCC_EBUDIV_SELF100  0x00000001
++/* Serial Flash */
++#define BUSRCON0_AGEN_SERIAL_FLASH    0xF0000000
++/* 8-bit multiplexed */
++#define BUSRCON0_PORTW_8_BIT_MUX      0x00000000
++/* Serial Flash */
++#define BUSWCON0_AGEN_SERIAL_FLASH    0xF0000000
++/* Chip Select after opcode */
++#define SFCMD_KEEP_CS_KEEP_SELECTED   0x00008000
++
++struct falcon_spi {
++      u32 sfcmd; /* for caching of opcode, direction, ... */
++      struct spi_master *master;
++};
++
++int
++falcon_spi_xfer(struct spi_device *spi,
++                  struct spi_transfer *t,
++                  unsigned long flags)
++{
++      struct device *dev = &spi->dev;
++      struct falcon_spi *priv = spi_master_get_devdata(spi->master);
++      const u8 *txp = t->tx_buf;
++      u8 *rxp = t->rx_buf;
++      unsigned int bytelen = ((8 * t->len + 7) / 8);
++      unsigned int len, alen, dumlen;
++      u32 val;
++      enum {
++              state_init,
++              state_command_prepare,
++              state_write,
++              state_read,
++              state_disable_cs,
++              state_end
++      } state = state_init;
++
++      do {
++              switch (state) {
++              case state_init: /* detect phase of upper layer sequence */
++              {
++                      /* initial write ? */
++                      if (flags & FALCON_SPI_XFER_BEGIN) {
++                              if (!txp) {
++                                      dev_err(dev,
++                                              "BEGIN without tx data!\n");
++                                      return -1;
++                              }
++                              /*
++                               * Prepare the parts of the sfcmd register,
++                               * which should not
++                               * change during a sequence!
++                               * Only exception are the length fields,
++                               * especially alen and dumlen.
++                               */
++
++                              priv->sfcmd = ((spi->chip_select
++                                              << SFCMD_CS_OFFSET)
++                                             & SFCMD_CS_MASK);
++                              priv->sfcmd |= SFCMD_KEEP_CS_KEEP_SELECTED;
++                              priv->sfcmd |= *txp;
++                              txp++;
++                              bytelen--;
++                              if (bytelen) {
++                                      /* more data:
++                                       * maybe address and/or dummy */
++                                      state = state_command_prepare;
++                                      break;
++                              } else {
++                                      dev_dbg(dev, "write cmd %02X\n",
++                                              priv->sfcmd & SFCMD_OPC_MASK);
++                              }
++                      }
++                      /* continued write ? */
++                      if (txp && bytelen) {
++                              state = state_write;
++                              break;
++                      }
++                      /* read data? */
++                      if (rxp && bytelen) {
++                              state = state_read;
++                              break;
++                      }
++                      /* end of sequence? */
++                      if (flags & FALCON_SPI_XFER_END)
++                              state = state_disable_cs;
++                      else
++                              state = state_end;
++                      break;
++              }
++              case state_command_prepare: /* collect tx data for
++                                             address and dummy phase */
++              {
++                      /* txp is valid, already checked */
++                      val = 0;
++                      alen = 0;
++                      dumlen = 0;
++                      while (bytelen > 0) {
++                              if (alen < 3) {
++                                      val = (val<<8)|(*txp++);
++                                      alen++;
++                              } else if ((dumlen < 15) && (*txp == 0)) {
++                                      /*
++                                       * assume dummy bytes are set to 0
++                                       * from upper layer
++                                       */
++                                      dumlen++;
++                                      txp++;
++                              } else
++                                      break;
++                              bytelen--;
++                      }
++                      priv->sfcmd &= ~(SFCMD_ALEN_MASK | SFCMD_DUMLEN_MASK);
++                      priv->sfcmd |= (alen << SFCMD_ALEN_OFFSET) |
++                                       (dumlen << SFCMD_DUMLEN_OFFSET);
++                      if (alen > 0)
++                              ltq_ebu_w32(val, LTQ_SFADDR);
++
++                      dev_dbg(dev, "write cmd %02X, alen=%d "
++                              "(addr=%06X) dumlen=%d\n",
++                              priv->sfcmd & SFCMD_OPC_MASK,
++                              alen, val, dumlen);
++
++                      if (bytelen > 0) {
++                              /* continue with write */
++                              state = state_write;
++                      } else if (flags & FALCON_SPI_XFER_END) {
++                              /* end of sequence? */
++                              state = state_disable_cs;
++                      } else {
++                              /* go to end and expect another
++                               * call (read or write) */
++                              state = state_end;
++                      }
++                      break;
++              }
++              case state_write:
++              {
++                      /* txp still valid */
++                      priv->sfcmd |= SFCMD_DIR_WRITE;
++                      len = 0;
++                      val = 0;
++                      do {
++                              if (bytelen--)
++                                      val |= (*txp++) << (8 * len++);
++                              if ((flags & FALCON_SPI_XFER_END)
++                                  && (bytelen == 0)) {
++                                      priv->sfcmd &=
++                                              ~SFCMD_KEEP_CS_KEEP_SELECTED;
++                              }
++                              if ((len == 4) || (bytelen == 0)) {
++                                      ltq_ebu_w32(val, LTQ_SFDATA);
++                                      ltq_ebu_w32(priv->sfcmd
++                                              | (len<<SFCMD_DLEN_OFFSET),
++                                              LTQ_SFCMD);
++                                      len = 0;
++                                      val = 0;
++                                      priv->sfcmd &= ~(SFCMD_ALEN_MASK
++                                                       | SFCMD_DUMLEN_MASK);
++                              }
++                      } while (bytelen);
++                      state = state_end;
++                      break;
++              }
++              case state_read:
++              {
++                      /* read data */
++                      priv->sfcmd &= ~SFCMD_DIR_WRITE;
++                      do {
++                              if ((flags & FALCON_SPI_XFER_END)
++                                  && (bytelen <= 4)) {
++                                      priv->sfcmd &=
++                                              ~SFCMD_KEEP_CS_KEEP_SELECTED;
++                              }
++                              len = (bytelen > 4) ? 4 : bytelen;
++                              bytelen -= len;
++                              ltq_ebu_w32(priv->sfcmd
++                                      |(len<<SFCMD_DLEN_OFFSET), LTQ_SFCMD);
++                              priv->sfcmd &= ~(SFCMD_ALEN_MASK
++                                               | SFCMD_DUMLEN_MASK);
++                              do {
++                                      val = ltq_ebu_r32(LTQ_SFSTAT);
++                                      if (val & SFSTAT_CMD_ERR) {
++                                              /* reset error status */
++                                              dev_err(dev, "SFSTAT: CMD_ERR "
++                                                      "(%x)\n", val);
++                                              ltq_ebu_w32(SFSTAT_CMD_ERR,
++                                                      LTQ_SFSTAT);
++                                              return -1;
++                                      }
++                              } while (val & SFSTAT_CMD_PEND);
++                              val = ltq_ebu_r32(LTQ_SFDATA);
++                              do {
++                                      *rxp = (val & 0xFF);
++                                      rxp++;
++                                      val >>= 8;
++                                      len--;
++                              } while (len);
++                      } while (bytelen);
++                      state = state_end;
++                      break;
++              }
++              case state_disable_cs:
++              {
++                      priv->sfcmd &= ~SFCMD_KEEP_CS_KEEP_SELECTED;
++                      ltq_ebu_w32(priv->sfcmd | (0 << SFCMD_DLEN_OFFSET),
++                              LTQ_SFCMD);
++                      val = ltq_ebu_r32(LTQ_SFSTAT);
++                      if (val & SFSTAT_CMD_ERR) {
++                              /* reset error status */
++                              dev_err(dev, "SFSTAT: CMD_ERR (%x)\n", val);
++                              ltq_ebu_w32(SFSTAT_CMD_ERR, LTQ_SFSTAT);
++                              return -1;
++                      }
++                      state = state_end;
++                      break;
++              }
++              case state_end:
++                      break;
++              }
++      } while (state != state_end);
++
++      return 0;
++}
++
++static int
++falcon_spi_setup(struct spi_device *spi)
++{
++      struct device *dev = &spi->dev;
++      const u32 ebuclk = CLOCK_100M;
++      unsigned int i;
++      unsigned long flags;
++
++      dev_dbg(dev, "setup\n");
++
++      if (spi->master->bus_num > 0 || spi->chip_select > 0)
++              return -ENODEV;
++
++      spin_lock_irqsave(&ebu_lock, flags);
++
++      if (ebuclk < spi->max_speed_hz) {
++              /* set EBU clock to 100 MHz */
++              ltq_sys1_w32_mask(0, EBUCC_EBUDIV_SELF100, LTQ_EBUCC);
++              i = 1; /* divider */
++      } else {
++              /* set EBU clock to 50 MHz */
++              ltq_sys1_w32_mask(EBUCC_EBUDIV_SELF100, 0, LTQ_EBUCC);
++
++              /* search for suitable divider */
++              for (i = 1; i < 7; i++) {
++                      if (ebuclk / i <= spi->max_speed_hz)
++                              break;
++              }
++      }
++
++      /* setup period of serial clock */
++      ltq_ebu_w32_mask(SFTIME_SCKF_POS_MASK
++                   | SFTIME_SCKR_POS_MASK
++                   | SFTIME_SCK_PER_MASK,
++                   (i << SFTIME_SCKR_POS_OFFSET)
++                   | (i << (SFTIME_SCK_PER_OFFSET + 1)),
++                   LTQ_SFTIME);
++
++      /* set some bits of unused_wd, to not trigger HOLD/WP
++       * signals on non QUAD flashes */
++      ltq_ebu_w32((SFIO_UNUSED_WD_MASK & (0x8 | 0x4)), LTQ_SFIO);
++
++      ltq_ebu_w32(BUSRCON0_AGEN_SERIAL_FLASH | BUSRCON0_PORTW_8_BIT_MUX,
++              LTQ_BUSRCON0);
++      ltq_ebu_w32(BUSWCON0_AGEN_SERIAL_FLASH, LTQ_BUSWCON0);
++      /* set address wrap around to maximum for 24-bit addresses */
++      ltq_ebu_w32_mask(SFCON_DEV_SIZE_MASK, SFCON_DEV_SIZE_A23_0, LTQ_SFCON);
++
++      spin_unlock_irqrestore(&ebu_lock, flags);
++
++      return 0;
++}
++
++static int
++falcon_spi_transfer(struct spi_device *spi, struct spi_message *m)
++{
++      struct falcon_spi *priv = spi_master_get_devdata(spi->master);
++      struct spi_transfer *t;
++      unsigned long spi_flags;
++      unsigned long flags;
++      int ret = 0;
++
++      priv->sfcmd = 0;
++      m->actual_length = 0;
++
++      spi_flags = FALCON_SPI_XFER_BEGIN;
++      list_for_each_entry(t, &m->transfers, transfer_list) {
++              if (list_is_last(&t->transfer_list, &m->transfers))
++                      spi_flags |= FALCON_SPI_XFER_END;
++
++              spin_lock_irqsave(&ebu_lock, flags);
++              ret = falcon_spi_xfer(spi, t, spi_flags);
++              spin_unlock_irqrestore(&ebu_lock, flags);
++
++              if (ret)
++                      break;
++
++              m->actual_length += t->len;
++
++              if (t->delay_usecs || t->cs_change)
++                      BUG();
++
++              spi_flags = 0;
++      }
++
++      m->status = ret;
++      m->complete(m->context);
++
++      return 0;
++}
++
++static void
++falcon_spi_cleanup(struct spi_device *spi)
++{
++      struct device *dev = &spi->dev;
++
++      dev_dbg(dev, "cleanup\n");
++}
++
++static int __devinit
++falcon_spi_probe(struct platform_device *pdev)
++{
++      struct device *dev = &pdev->dev;
++      struct falcon_spi *priv;
++      struct spi_master *master;
++      int ret;
++
++      dev_dbg(dev, "probing\n");
++
++      master = spi_alloc_master(&pdev->dev, sizeof(*priv));
++      if (!master) {
++              dev_err(dev, "no memory for spi_master\n");
++              return -ENOMEM;
++      }
++
++      priv = spi_master_get_devdata(master);
++      priv->master = master;
++
++      master->mode_bits = SPI_MODE_3;
++      master->num_chipselect = 1;
++      master->bus_num = 0;
++
++      master->setup = falcon_spi_setup;
++      master->transfer = falcon_spi_transfer;
++      master->cleanup = falcon_spi_cleanup;
++
++      platform_set_drvdata(pdev, priv);
++
++      ret = spi_register_master(master);
++      if (ret)
++              spi_master_put(master);
++
++      return ret;
++}
++
++static int __devexit
++falcon_spi_remove(struct platform_device *pdev)
++{
++      struct device *dev = &pdev->dev;
++      struct falcon_spi *priv = platform_get_drvdata(pdev);
++
++      dev_dbg(dev, "removed\n");
++
++      spi_unregister_master(priv->master);
++
++      return 0;
++}
++
++static struct platform_driver falcon_spi_driver = {
++      .probe  = falcon_spi_probe,
++      .remove = __devexit_p(falcon_spi_remove),
++      .driver = {
++              .name   = DRV_NAME,
++              .owner  = THIS_MODULE
++      }
++};
++
++static int __init
++falcon_spi_init(void)
++{
++      return platform_driver_register(&falcon_spi_driver);
++}
++
++static void __exit
++falcon_spi_exit(void)
++{
++      platform_driver_unregister(&falcon_spi_driver);
++}
++
++module_init(falcon_spi_init);
++module_exit(falcon_spi_exit);
++
++MODULE_LICENSE("GPL");
++MODULE_DESCRIPTION("Lantiq Falcon SPI controller driver");
+Index: linux-3.0.3/arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h
+===================================================================
+--- linux-3.0.3.orig/arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h     2011-10-05 12:38:16.176858136 +0200
++++ linux-3.0.3/arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h  2011-10-05 12:39:54.936862358 +0200
+@@ -48,6 +48,10 @@
+ #define LTQ_EBU_MODCON  0x000C
++/* I2C */
++#define LTQ_I2C_BASE_ADDR     0x1E200000
++#define LTQ_I2C_SIZE          0x00010000
++
+ /* GPIO */
+ #define LTQ_GPIO0_BASE_ADDR     0x1D810000
+ #define LTQ_GPIO0_SIZE          0x0080
+@@ -92,6 +96,7 @@
+ /* Activation Status Register */
+ #define ACTS_ASC1_ACT 0x00000800
++#define ACTS_I2C_ACT  0x00004000
+ #define ACTS_P0               0x00010000
+ #define ACTS_P1               0x00010000
+ #define ACTS_P2               0x00020000
diff --git a/target/linux/lantiq/patches-3.0/0014-MIPS-lantiq-adds-xway-spi.patch b/target/linux/lantiq/patches-3.0/0014-MIPS-lantiq-adds-xway-spi.patch
new file mode 100644 (file)
index 0000000..0fe4f54
--- /dev/null
@@ -0,0 +1,1156 @@
+From e29263339db41d49d79482c93463c4c0cbe764d7 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Fri, 30 Sep 2011 14:23:42 +0200
+Subject: [PATCH 14/24] MIPS: lantiq: adds xway spi
+
+---
+ .../mips/include/asm/mach-lantiq/lantiq_platform.h |    9 +
+ .../mips/include/asm/mach-lantiq/xway/lantiq_irq.h |    2 +
+ .../mips/include/asm/mach-lantiq/xway/lantiq_soc.h |    1 +
+ drivers/spi/Kconfig                                |    8 +
+ drivers/spi/Makefile                               |    2 +-
+ drivers/spi/spi-xway.c                             | 1062 ++++++++++++++++++++
+ 6 files changed, 1083 insertions(+), 1 deletions(-)
+ create mode 100644 drivers/spi/spi-xway.c
+
+Index: linux-3.0.3/arch/mips/include/asm/mach-lantiq/lantiq_platform.h
+===================================================================
+--- linux-3.0.3.orig/arch/mips/include/asm/mach-lantiq/lantiq_platform.h       2011-08-17 19:57:16.000000000 +0200
++++ linux-3.0.3/arch/mips/include/asm/mach-lantiq/lantiq_platform.h    2011-10-04 20:05:23.962311503 +0200
+@@ -50,4 +50,13 @@
+       int mii_mode;
+ };
++
++struct ltq_spi_platform_data {
++      u16 num_chipselect;
++};
++
++struct ltq_spi_controller_data {
++      unsigned gpio;
++};
++
+ #endif
+Index: linux-3.0.3/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h
+===================================================================
+--- linux-3.0.3.orig/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h       2011-08-17 19:57:16.000000000 +0200
++++ linux-3.0.3/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h    2011-10-04 20:05:23.962311503 +0200
+@@ -27,6 +27,8 @@
+ #define LTQ_SSC_TIR           (INT_NUM_IM0_IRL0 + 15)
+ #define LTQ_SSC_RIR           (INT_NUM_IM0_IRL0 + 14)
++#define LTQ_SSC_TIR_AR9               (INT_NUM_IM0_IRL0 + 14)
++#define LTQ_SSC_RIR_AR9               (INT_NUM_IM0_IRL0 + 15)
+ #define LTQ_SSC_EIR           (INT_NUM_IM0_IRL0 + 16)
+ #define LTQ_MEI_DYING_GASP_INT        (INT_NUM_IM1_IRL0 + 21)
+Index: linux-3.0.3/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
+===================================================================
+--- linux-3.0.3.orig/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h       2011-10-04 20:03:54.934307699 +0200
++++ linux-3.0.3/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h    2011-10-04 20:05:23.966311504 +0200
+@@ -81,6 +81,7 @@
+ #define PMU_DMA                       0x0020
+ #define PMU_USB                       0x8041
++#define PMU_SPI                       0x0100
+ #define PMU_LED                       0x0800
+ #define PMU_GPT                       0x1000
+ #define PMU_PPE                       0x2000
+Index: linux-3.0.3/drivers/spi/Kconfig
+===================================================================
+--- linux-3.0.3.orig/drivers/spi/Kconfig       2011-10-04 20:05:07.030310779 +0200
++++ linux-3.0.3/drivers/spi/Kconfig    2011-10-04 20:05:23.966311504 +0200
+@@ -433,6 +433,14 @@
+       help
+         SPI driver for Nuvoton NUC900 series ARM SoCs
++config SPI_XWAY
++      tristate "Lantiq XWAY SPI controller"
++      depends on LANTIQ && SOC_TYPE_XWAY
++      select SPI_BITBANG
++      help
++        This driver supports the Lantiq SoC SPI controller in master
++        mode.
++
+ #
+ # Add new SPI master controllers in alphabetical order above this line
+ #
+Index: linux-3.0.3/drivers/spi/Makefile
+===================================================================
+--- linux-3.0.3.orig/drivers/spi/Makefile      2011-10-04 20:05:20.000000000 +0200
++++ linux-3.0.3/drivers/spi/Makefile   2011-10-04 20:05:35.802312011 +0200
+@@ -57,6 +57,7 @@
+ obj-$(CONFIG_SPI_STMP3XXX)            += spi_stmp.o
+ obj-$(CONFIG_SPI_NUC900)              += spi_nuc900.o
+ obj-$(CONFIG_SPI_FALCON)              += spi-falcon.o
++obj-$(CONFIG_SPI_XWAY)                        += spi-xway.o
+ # special build for s3c24xx spi driver with fiq support
+ spi_s3c24xx_hw-y                      := spi_s3c24xx.o
+Index: linux-3.0.3/drivers/spi/spi-xway.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-3.0.3/drivers/spi/spi-xway.c 2011-10-04 20:05:23.966311504 +0200
+@@ -0,0 +1,1062 @@
++/*
++ * Lantiq SoC SPI controller
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck <daniel.schwierzeck@googlemail.com>
++ *
++ * This program is free software; you can distribute it and/or modify it
++ * under the terms of the GNU General Public License (Version 2) as
++ * published by the Free Software Foundation.
++ */
++
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/workqueue.h>
++#include <linux/platform_device.h>
++#include <linux/io.h>
++#include <linux/sched.h>
++#include <linux/delay.h>
++#include <linux/interrupt.h>
++#include <linux/completion.h>
++#include <linux/spinlock.h>
++#include <linux/err.h>
++#include <linux/clk.h>
++#include <linux/gpio.h>
++#include <linux/spi/spi.h>
++#include <linux/spi/spi_bitbang.h>
++
++#include <lantiq_soc.h>
++#include <lantiq_platform.h>
++
++#define LTQ_SPI_CLC           0x00    /* Clock control */
++#define LTQ_SPI_PISEL         0x04    /* Port input select */
++#define LTQ_SPI_ID            0x08    /* Identification */
++#define LTQ_SPI_CON           0x10    /* Control */
++#define LTQ_SPI_STAT          0x14    /* Status */
++#define LTQ_SPI_WHBSTATE      0x18    /* Write HW modified state */
++#define LTQ_SPI_TB            0x20    /* Transmit buffer */
++#define LTQ_SPI_RB            0x24    /* Receive buffer */
++#define LTQ_SPI_RXFCON                0x30    /* Receive FIFO control */
++#define LTQ_SPI_TXFCON                0x34    /* Transmit FIFO control */
++#define LTQ_SPI_FSTAT         0x38    /* FIFO status */
++#define LTQ_SPI_BRT           0x40    /* Baudrate timer */
++#define LTQ_SPI_BRSTAT                0x44    /* Baudrate timer status */
++#define LTQ_SPI_SFCON         0x60    /* Serial frame control */
++#define LTQ_SPI_SFSTAT                0x64    /* Serial frame status */
++#define LTQ_SPI_GPOCON                0x70    /* General purpose output control */
++#define LTQ_SPI_GPOSTAT               0x74    /* General purpose output status */
++#define LTQ_SPI_FGPO          0x78    /* Forced general purpose output */
++#define LTQ_SPI_RXREQ         0x80    /* Receive request */
++#define LTQ_SPI_RXCNT         0x84    /* Receive count */
++#define LTQ_SPI_DMACON                0xEC    /* DMA control */
++#define LTQ_SPI_IRNEN         0xF4    /* Interrupt node enable */
++#define LTQ_SPI_IRNICR                0xF8    /* Interrupt node interrupt capture */
++#define LTQ_SPI_IRNCR         0xFC    /* Interrupt node control */
++
++#define LTQ_SPI_CLC_SMC_SHIFT 16      /* Clock divider for sleep mode */
++#define LTQ_SPI_CLC_SMC_MASK  0xFF
++#define LTQ_SPI_CLC_RMC_SHIFT 8       /* Clock divider for normal run mode */
++#define LTQ_SPI_CLC_RMC_MASK  0xFF
++#define LTQ_SPI_CLC_DISS      BIT(1)  /* Disable status bit */
++#define LTQ_SPI_CLC_DISR      BIT(0)  /* Disable request bit */
++
++#define LTQ_SPI_ID_TXFS_SHIFT 24      /* Implemented TX FIFO size */
++#define LTQ_SPI_ID_TXFS_MASK  0x3F
++#define LTQ_SPI_ID_RXFS_SHIFT 16      /* Implemented RX FIFO size */
++#define LTQ_SPI_ID_RXFS_MASK  0x3F
++#define LTQ_SPI_ID_REV_MASK   0x1F    /* Hardware revision number */
++#define LTQ_SPI_ID_CFG                BIT(5)  /* DMA interface support */
++
++#define LTQ_SPI_CON_BM_SHIFT  16      /* Data width selection */
++#define LTQ_SPI_CON_BM_MASK   0x1F
++#define LTQ_SPI_CON_EM                BIT(24) /* Echo mode */
++#define LTQ_SPI_CON_IDLE      BIT(23) /* Idle bit value */
++#define LTQ_SPI_CON_ENBV      BIT(22) /* Enable byte valid control */
++#define LTQ_SPI_CON_RUEN      BIT(12) /* Receive underflow error enable */
++#define LTQ_SPI_CON_TUEN      BIT(11) /* Transmit underflow error enable */
++#define LTQ_SPI_CON_AEN               BIT(10) /* Abort error enable */
++#define LTQ_SPI_CON_REN               BIT(9)  /* Receive overflow error enable */
++#define LTQ_SPI_CON_TEN               BIT(8)  /* Transmit overflow error enable */
++#define LTQ_SPI_CON_LB                BIT(7)  /* Loopback control */
++#define LTQ_SPI_CON_PO                BIT(6)  /* Clock polarity control */
++#define LTQ_SPI_CON_PH                BIT(5)  /* Clock phase control */
++#define LTQ_SPI_CON_HB                BIT(4)  /* Heading control */
++#define LTQ_SPI_CON_RXOFF     BIT(1)  /* Switch receiver off */
++#define LTQ_SPI_CON_TXOFF     BIT(0)  /* Switch transmitter off */
++
++#define LTQ_SPI_STAT_RXBV_MASK        0x7
++#define LTQ_SPI_STAT_RXBV_SHIFT       28
++#define LTQ_SPI_STAT_BSY      BIT(13) /* Busy flag */
++#define LTQ_SPI_STAT_RUE      BIT(12) /* Receive underflow error flag */
++#define LTQ_SPI_STAT_TUE      BIT(11) /* Transmit underflow error flag */
++#define LTQ_SPI_STAT_AE               BIT(10) /* Abort error flag */
++#define LTQ_SPI_STAT_RE               BIT(9)  /* Receive error flag */
++#define LTQ_SPI_STAT_TE               BIT(8)  /* Transmit error flag */
++#define LTQ_SPI_STAT_MS               BIT(1)  /* Master/slave select bit */
++#define LTQ_SPI_STAT_EN               BIT(0)  /* Enable bit */
++
++#define LTQ_SPI_WHBSTATE_SETTUE       BIT(15) /* Set transmit underflow error flag */
++#define LTQ_SPI_WHBSTATE_SETAE        BIT(14) /* Set abort error flag */
++#define LTQ_SPI_WHBSTATE_SETRE        BIT(13) /* Set receive error flag */
++#define LTQ_SPI_WHBSTATE_SETTE        BIT(12) /* Set transmit error flag */
++#define LTQ_SPI_WHBSTATE_CLRTUE       BIT(11) /* Clear transmit underflow error flag */
++#define LTQ_SPI_WHBSTATE_CLRAE        BIT(10) /* Clear abort error flag */
++#define LTQ_SPI_WHBSTATE_CLRRE        BIT(9)  /* Clear receive error flag */
++#define LTQ_SPI_WHBSTATE_CLRTE        BIT(8)  /* Clear transmit error flag */
++#define LTQ_SPI_WHBSTATE_SETME        BIT(7)  /* Set mode error flag */
++#define LTQ_SPI_WHBSTATE_CLRME        BIT(6)  /* Clear mode error flag */
++#define LTQ_SPI_WHBSTATE_SETRUE       BIT(5)  /* Set receive underflow error flag */
++#define LTQ_SPI_WHBSTATE_CLRRUE       BIT(4)  /* Clear receive underflow error flag */
++#define LTQ_SPI_WHBSTATE_SETMS        BIT(3)  /* Set master select bit */
++#define LTQ_SPI_WHBSTATE_CLRMS        BIT(2)  /* Clear master select bit */
++#define LTQ_SPI_WHBSTATE_SETEN        BIT(1)  /* Set enable bit (operational mode) */
++#define LTQ_SPI_WHBSTATE_CLREN        BIT(0)  /* Clear enable bit (config mode */
++#define LTQ_SPI_WHBSTATE_CLR_ERRORS   0x0F50
++
++#define LTQ_SPI_RXFCON_RXFITL_SHIFT   8       /* FIFO interrupt trigger level */
++#define LTQ_SPI_RXFCON_RXFITL_MASK    0x3F
++#define LTQ_SPI_RXFCON_RXFLU          BIT(1)  /* FIFO flush */
++#define LTQ_SPI_RXFCON_RXFEN          BIT(0)  /* FIFO enable */
++
++#define LTQ_SPI_TXFCON_TXFITL_SHIFT   8       /* FIFO interrupt trigger level */
++#define LTQ_SPI_TXFCON_TXFITL_MASK    0x3F
++#define LTQ_SPI_TXFCON_TXFLU          BIT(1)  /* FIFO flush */
++#define LTQ_SPI_TXFCON_TXFEN          BIT(0)  /* FIFO enable */
++
++#define LTQ_SPI_FSTAT_RXFFL_MASK      0x3f
++#define LTQ_SPI_FSTAT_RXFFL_SHIFT     0
++#define LTQ_SPI_FSTAT_TXFFL_MASK      0x3f
++#define LTQ_SPI_FSTAT_TXFFL_SHIFT     8
++
++#define LTQ_SPI_GPOCON_ISCSBN_SHIFT   8
++#define LTQ_SPI_GPOCON_INVOUTN_SHIFT  0
++
++#define LTQ_SPI_FGPO_SETOUTN_SHIFT    8
++#define LTQ_SPI_FGPO_CLROUTN_SHIFT    0
++
++#define LTQ_SPI_RXREQ_RXCNT_MASK      0xFFFF  /* Receive count value */
++#define LTQ_SPI_RXCNT_TODO_MASK               0xFFFF  /* Recevie to-do value */
++
++#define LTQ_SPI_IRNEN_F               BIT(3)  /* Frame end interrupt request */
++#define LTQ_SPI_IRNEN_E               BIT(2)  /* Error end interrupt request */
++#define LTQ_SPI_IRNEN_T               BIT(1)  /* Transmit end interrupt request */
++#define LTQ_SPI_IRNEN_R               BIT(0)  /* Receive end interrupt request */
++#define LTQ_SPI_IRNEN_ALL     0xF
++
++/* Hard-wired GPIOs used by SPI controller */
++#define LTQ_SPI_GPIO_DI       16
++#define LTQ_SPI_GPIO_DO               17
++#define LTQ_SPI_GPIO_CLK      18
++
++struct ltq_spi {
++      struct spi_bitbang      bitbang;
++      struct completion       done;
++      spinlock_t              lock;
++
++      struct device           *dev;
++      void __iomem            *base;
++      struct clk              *clk;
++
++      int                     status;
++      int                     irq[3];
++
++      const u8                *tx;
++      u8                      *rx;
++      u32                     tx_cnt;
++      u32                     rx_cnt;
++      u32                     len;
++      struct spi_transfer     *curr_transfer;
++
++      u32 (*get_tx) (struct ltq_spi *);
++
++      u16                     txfs;
++      u16                     rxfs;
++      unsigned                dma_support:1;
++      unsigned                cfg_mode:1;
++
++};
++
++struct ltq_spi_controller_state {
++      void (*cs_activate) (struct spi_device *);
++      void (*cs_deactivate) (struct spi_device *);
++};
++
++struct ltq_spi_irq_map {
++      char            *name;
++      irq_handler_t   handler;
++};
++
++struct ltq_spi_cs_gpio_map {
++      unsigned        gpio;
++      unsigned        altsel0;
++      unsigned        altsel1;
++};
++
++static inline struct ltq_spi *ltq_spi_to_hw(struct spi_device *spi)
++{
++      return spi_master_get_devdata(spi->master);
++}
++
++static inline u32 ltq_spi_reg_read(struct ltq_spi *hw, u32 reg)
++{
++      return ioread32be(hw->base + reg);
++}
++
++static inline void ltq_spi_reg_write(struct ltq_spi *hw, u32 val, u32 reg)
++{
++      iowrite32be(val, hw->base + reg);
++}
++
++static inline void ltq_spi_reg_setbit(struct ltq_spi *hw, u32 bits, u32 reg)
++{
++      u32 val;
++
++      val = ltq_spi_reg_read(hw, reg);
++      val |= bits;
++      ltq_spi_reg_write(hw, val, reg);
++}
++
++static inline void ltq_spi_reg_clearbit(struct ltq_spi *hw, u32 bits, u32 reg)
++{
++      u32 val;
++
++      val = ltq_spi_reg_read(hw, reg);
++      val &= ~bits;
++      ltq_spi_reg_write(hw, val, reg);
++}
++
++static void ltq_spi_hw_enable(struct ltq_spi *hw)
++{
++      u32 clc;
++
++      /* Power-up mdule */
++      ltq_pmu_enable(PMU_SPI);
++
++      /*
++       * Set clock divider for run mode to 1 to
++       * run at same frequency as FPI bus
++       */
++      clc = (1 << LTQ_SPI_CLC_RMC_SHIFT);
++      ltq_spi_reg_write(hw, clc, LTQ_SPI_CLC);
++}
++
++static void ltq_spi_hw_disable(struct ltq_spi *hw)
++{
++      /* Set clock divider to 0 and set module disable bit */
++      ltq_spi_reg_write(hw, LTQ_SPI_CLC_DISS, LTQ_SPI_CLC);
++
++      /* Power-down mdule */
++      ltq_pmu_disable(PMU_SPI);
++}
++
++static void ltq_spi_reset_fifos(struct ltq_spi *hw)
++{
++      u32 val;
++
++      /*
++       * Enable and flush FIFOs. Set interrupt trigger level to
++       * half of FIFO count implemented in hardware.
++       */
++      if (hw->txfs > 1) {
++              val = hw->txfs << (LTQ_SPI_TXFCON_TXFITL_SHIFT - 1);
++              val |= LTQ_SPI_TXFCON_TXFEN | LTQ_SPI_TXFCON_TXFLU;
++              ltq_spi_reg_write(hw, val, LTQ_SPI_TXFCON);
++      }
++
++      if (hw->rxfs > 1) {
++              val = hw->rxfs << (LTQ_SPI_RXFCON_RXFITL_SHIFT - 1);
++              val |= LTQ_SPI_RXFCON_RXFEN | LTQ_SPI_RXFCON_RXFLU;
++              ltq_spi_reg_write(hw, val, LTQ_SPI_RXFCON);
++      }
++}
++
++static inline int ltq_spi_wait_ready(struct ltq_spi *hw)
++{
++      u32 stat;
++      unsigned long timeout;
++
++      timeout = jiffies + msecs_to_jiffies(200);
++
++      do {
++              stat = ltq_spi_reg_read(hw, LTQ_SPI_STAT);
++              if (!(stat & LTQ_SPI_STAT_BSY))
++                      return 0;
++
++              cond_resched();
++      } while (!time_after_eq(jiffies, timeout));
++
++      dev_err(hw->dev, "SPI wait ready timed out\n");
++
++      return -ETIMEDOUT;
++}
++
++static void ltq_spi_config_mode_set(struct ltq_spi *hw)
++{
++      if (hw->cfg_mode)
++              return;
++
++      /*
++       * Putting the SPI module in config mode is only safe if no
++       * transfer is in progress as indicated by busy flag STATE.BSY.
++       */
++      if (ltq_spi_wait_ready(hw)) {
++              ltq_spi_reset_fifos(hw);
++              hw->status = -ETIMEDOUT;
++      }
++      ltq_spi_reg_write(hw, LTQ_SPI_WHBSTATE_CLREN, LTQ_SPI_WHBSTATE);
++
++      hw->cfg_mode = 1;
++}
++
++static void ltq_spi_run_mode_set(struct ltq_spi *hw)
++{
++      if (!hw->cfg_mode)
++              return;
++
++      ltq_spi_reg_write(hw, LTQ_SPI_WHBSTATE_SETEN, LTQ_SPI_WHBSTATE);
++
++      hw->cfg_mode = 0;
++}
++
++static u32 ltq_spi_tx_word_u8(struct ltq_spi *hw)
++{
++      const u8 *tx = hw->tx;
++      u32 data = *tx++;
++
++      hw->tx_cnt++;
++      hw->tx++;
++
++      return data;
++}
++
++static u32 ltq_spi_tx_word_u16(struct ltq_spi *hw)
++{
++      const u16 *tx = (u16 *) hw->tx;
++      u32 data = *tx++;
++
++      hw->tx_cnt += 2;
++      hw->tx += 2;
++
++      return data;
++}
++
++static u32 ltq_spi_tx_word_u32(struct ltq_spi *hw)
++{
++      const u32 *tx = (u32 *) hw->tx;
++      u32 data = *tx++;
++
++      hw->tx_cnt += 4;
++      hw->tx += 4;
++
++      return data;
++}
++
++static void ltq_spi_bits_per_word_set(struct spi_device *spi)
++{
++      struct ltq_spi *hw = ltq_spi_to_hw(spi);
++      u32 bm;
++      u8 bits_per_word = spi->bits_per_word;
++
++      /*
++       * Use either default value of SPI device or value
++       * from current transfer.
++       */
++      if (hw->curr_transfer && hw->curr_transfer->bits_per_word)
++              bits_per_word = hw->curr_transfer->bits_per_word;
++
++      if (bits_per_word <= 8)
++              hw->get_tx = ltq_spi_tx_word_u8;
++      else if (bits_per_word <= 16)
++              hw->get_tx = ltq_spi_tx_word_u16;
++      else if (bits_per_word <= 32)
++              hw->get_tx = ltq_spi_tx_word_u32;
++
++      /* CON.BM value = bits_per_word - 1 */
++      bm = (bits_per_word - 1) << LTQ_SPI_CON_BM_SHIFT;
++
++      ltq_spi_reg_clearbit(hw, LTQ_SPI_CON_BM_MASK <<
++                           LTQ_SPI_CON_BM_SHIFT, LTQ_SPI_CON);
++      ltq_spi_reg_setbit(hw, bm, LTQ_SPI_CON);
++}
++
++static void ltq_spi_speed_set(struct spi_device *spi)
++{
++      struct ltq_spi *hw = ltq_spi_to_hw(spi);
++      u32 br, max_speed_hz, spi_clk;
++      u32 speed_hz = spi->max_speed_hz;
++
++      /*
++       * Use either default value of SPI device or value
++       * from current transfer.
++       */
++      if (hw->curr_transfer && hw->curr_transfer->speed_hz)
++              speed_hz = hw->curr_transfer->speed_hz;
++
++      /*
++       * SPI module clock is derived from FPI bus clock dependent on
++       * divider value in CLC.RMS which is always set to 1.
++       */
++      spi_clk = clk_get_rate(hw->clk);
++
++      /*
++       * Maximum SPI clock frequency in master mode is half of
++       * SPI module clock frequency. Maximum reload value of
++       * baudrate generator BR is 2^16.
++       */
++      max_speed_hz = spi_clk / 2;
++      if (speed_hz >= max_speed_hz)
++              br = 0;
++      else
++              br = (max_speed_hz / speed_hz) - 1;
++
++      if (br > 0xFFFF)
++              br = 0xFFFF;
++
++      ltq_spi_reg_write(hw, br, LTQ_SPI_BRT);
++}
++
++static void ltq_spi_clockmode_set(struct spi_device *spi)
++{
++      struct ltq_spi *hw = ltq_spi_to_hw(spi);
++      u32 con;
++
++      con = ltq_spi_reg_read(hw, LTQ_SPI_CON);
++
++      /*
++       * SPI mode mapping in CON register:
++       * Mode CPOL CPHA CON.PO CON.PH
++       *  0    0    0      0      1
++       *  1    0    1      0      0
++       *  2    1    0      1      1
++       *  3    1    1      1      0
++       */
++      if (spi->mode & SPI_CPHA)
++              con &= ~LTQ_SPI_CON_PH;
++      else
++              con |= LTQ_SPI_CON_PH;
++
++      if (spi->mode & SPI_CPOL)
++              con |= LTQ_SPI_CON_PO;
++      else
++              con &= ~LTQ_SPI_CON_PO;
++
++      /* Set heading control */
++      if (spi->mode & SPI_LSB_FIRST)
++              con &= ~LTQ_SPI_CON_HB;
++      else
++              con |= LTQ_SPI_CON_HB;
++
++      ltq_spi_reg_write(hw, con, LTQ_SPI_CON);
++}
++
++static void ltq_spi_xmit_set(struct ltq_spi *hw, struct spi_transfer *t)
++{
++      u32 con;
++
++      con = ltq_spi_reg_read(hw, LTQ_SPI_CON);
++
++      if (t) {
++              if (t->tx_buf && t->rx_buf) {
++                      con &= ~(LTQ_SPI_CON_TXOFF | LTQ_SPI_CON_RXOFF);
++              } else if (t->rx_buf) {
++                      con &= ~LTQ_SPI_CON_RXOFF;
++                      con |= LTQ_SPI_CON_TXOFF;
++              } else if (t->tx_buf) {
++                      con &= ~LTQ_SPI_CON_TXOFF;
++                      con |= LTQ_SPI_CON_RXOFF;
++              }
++      } else
++              con |= (LTQ_SPI_CON_TXOFF | LTQ_SPI_CON_RXOFF);
++
++      ltq_spi_reg_write(hw, con, LTQ_SPI_CON);
++}
++
++static void ltq_spi_gpio_cs_activate(struct spi_device *spi)
++{
++      struct ltq_spi_controller_data *cdata = spi->controller_data;
++      int val = spi->mode & SPI_CS_HIGH ? 1 : 0;
++
++      gpio_set_value(cdata->gpio, val);
++}
++
++static void ltq_spi_gpio_cs_deactivate(struct spi_device *spi)
++{
++      struct ltq_spi_controller_data *cdata = spi->controller_data;
++      int val = spi->mode & SPI_CS_HIGH ? 0 : 1;
++
++      gpio_set_value(cdata->gpio, val);
++}
++
++static void ltq_spi_internal_cs_activate(struct spi_device *spi)
++{
++      struct ltq_spi *hw = ltq_spi_to_hw(spi);
++      u32 fgpo;
++
++      fgpo = (1 << (spi->chip_select + LTQ_SPI_FGPO_CLROUTN_SHIFT));
++      ltq_spi_reg_setbit(hw, fgpo, LTQ_SPI_FGPO);
++}
++
++static void ltq_spi_internal_cs_deactivate(struct spi_device *spi)
++{
++      struct ltq_spi *hw = ltq_spi_to_hw(spi);
++      u32 fgpo;
++
++      fgpo = (1 << (spi->chip_select + LTQ_SPI_FGPO_SETOUTN_SHIFT));
++      ltq_spi_reg_setbit(hw, fgpo, LTQ_SPI_FGPO);
++}
++
++static void ltq_spi_chipselect(struct spi_device *spi, int cs)
++{
++      struct ltq_spi *hw = ltq_spi_to_hw(spi);
++      struct ltq_spi_controller_state *cstate = spi->controller_state;
++
++      switch (cs) {
++      case BITBANG_CS_ACTIVE:
++              ltq_spi_bits_per_word_set(spi);
++              ltq_spi_speed_set(spi);
++              ltq_spi_clockmode_set(spi);
++              ltq_spi_run_mode_set(hw);
++
++              cstate->cs_activate(spi);
++              break;
++
++      case BITBANG_CS_INACTIVE:
++              cstate->cs_deactivate(spi);
++
++              ltq_spi_config_mode_set(hw);
++
++              break;
++      }
++}
++
++static int ltq_spi_setup_transfer(struct spi_device *spi,
++                                struct spi_transfer *t)
++{
++      struct ltq_spi *hw = ltq_spi_to_hw(spi);
++      u8 bits_per_word = spi->bits_per_word;
++
++      hw->curr_transfer = t;
++
++      if (t && t->bits_per_word)
++              bits_per_word = t->bits_per_word;
++
++      if (bits_per_word > 32)
++              return -EINVAL;
++
++      ltq_spi_config_mode_set(hw);
++
++      return 0;
++}
++
++static const struct ltq_spi_cs_gpio_map ltq_spi_cs[] = {
++      { 15, 1, 0 },
++      { 22, 1, 0 },
++      { 13, 0, 1 },
++      { 10, 0, 1 },
++      {  9, 0, 1 },
++      { 11, 1, 1 },
++};
++
++static int ltq_spi_setup(struct spi_device *spi)
++{
++      struct ltq_spi *hw = ltq_spi_to_hw(spi);
++      struct ltq_spi_controller_data *cdata = spi->controller_data;
++      struct ltq_spi_controller_state *cstate;
++      u32 gpocon, fgpo;
++      int ret;
++
++      /* Set default word length to 8 if not set */
++      if (!spi->bits_per_word)
++              spi->bits_per_word = 8;
++
++      if (spi->bits_per_word > 32)
++              return -EINVAL;
++
++      if (!spi->controller_state) {
++              cstate = kzalloc(sizeof(struct ltq_spi_controller_state),
++                               GFP_KERNEL);
++              if (!cstate)
++                      return -ENOMEM;
++
++              spi->controller_state = cstate;
++      } else
++              return 0;
++
++      /*
++       * Up to six GPIOs can be connected to the SPI module
++       * via GPIO alternate function to control the chip select lines.
++       * For more flexibility in board layout this driver can also control
++       * the CS lines via GPIO API. If GPIOs should be used, board setup code
++       * have to register the SPI device with struct ltq_spi_controller_data
++       * attached.
++       */
++      if (cdata && cdata->gpio) {
++              ret = gpio_request(cdata->gpio, "spi-cs");
++              if (ret)
++                      return -EBUSY;
++
++              ret = spi->mode & SPI_CS_HIGH ? 0 : 1;
++              gpio_direction_output(cdata->gpio, ret);
++
++              cstate->cs_activate = ltq_spi_gpio_cs_activate;
++              cstate->cs_deactivate = ltq_spi_gpio_cs_deactivate;
++      } else {
++              ret = ltq_gpio_request(ltq_spi_cs[spi->chip_select].gpio,
++                              ltq_spi_cs[spi->chip_select].altsel0,
++                              ltq_spi_cs[spi->chip_select].altsel1,
++                              1, "spi-cs");
++              if (ret)
++                      return -EBUSY;
++
++              gpocon = (1 << (spi->chip_select +
++                              LTQ_SPI_GPOCON_ISCSBN_SHIFT));
++
++              if (spi->mode & SPI_CS_HIGH)
++                      gpocon |= (1 << spi->chip_select);
++
++              fgpo = (1 << (spi->chip_select + LTQ_SPI_FGPO_SETOUTN_SHIFT));
++
++              ltq_spi_reg_setbit(hw, gpocon, LTQ_SPI_GPOCON);
++              ltq_spi_reg_setbit(hw, fgpo, LTQ_SPI_FGPO);
++
++              cstate->cs_activate = ltq_spi_internal_cs_activate;
++              cstate->cs_deactivate = ltq_spi_internal_cs_deactivate;
++      }
++
++      return 0;
++}
++
++static void ltq_spi_cleanup(struct spi_device *spi)
++{
++      struct ltq_spi_controller_data *cdata = spi->controller_data;
++      struct ltq_spi_controller_state *cstate = spi->controller_state;
++      unsigned gpio;
++
++      if (cdata && cdata->gpio)
++              gpio = cdata->gpio;
++      else
++              gpio = ltq_spi_cs[spi->chip_select].gpio;
++
++      gpio_free(gpio);
++      kfree(cstate);
++}
++
++static void ltq_spi_txfifo_write(struct ltq_spi *hw)
++{
++      u32 fstat, data;
++      u16 fifo_space;
++
++      /* Determine how much FIFOs are free for TX data */
++      fstat = ltq_spi_reg_read(hw, LTQ_SPI_FSTAT);
++      fifo_space = hw->txfs - ((fstat >> LTQ_SPI_FSTAT_TXFFL_SHIFT) &
++                                      LTQ_SPI_FSTAT_TXFFL_MASK);
++
++      if (!fifo_space)
++              return;
++
++      while (hw->tx_cnt < hw->len && fifo_space) {
++              data = hw->get_tx(hw);
++              ltq_spi_reg_write(hw, data, LTQ_SPI_TB);
++              fifo_space--;
++      }
++}
++
++static void ltq_spi_rxfifo_read(struct ltq_spi *hw)
++{
++      u32 fstat, data, *rx32;
++      u16 fifo_fill;
++      u8 rxbv, shift, *rx8;
++
++      /* Determine how much FIFOs are filled with RX data */
++      fstat = ltq_spi_reg_read(hw, LTQ_SPI_FSTAT);
++      fifo_fill = ((fstat >> LTQ_SPI_FSTAT_RXFFL_SHIFT)
++                      & LTQ_SPI_FSTAT_RXFFL_MASK);
++
++      if (!fifo_fill)
++              return;
++
++      /*
++       * The 32 bit FIFO is always used completely independent from the
++       * bits_per_word value. Thus four bytes have to be read at once
++       * per FIFO.
++       */
++      rx32 = (u32 *) hw->rx;
++      while (hw->len - hw->rx_cnt >= 4 && fifo_fill) {
++              *rx32++ = ltq_spi_reg_read(hw, LTQ_SPI_RB);
++              hw->rx_cnt += 4;
++              hw->rx += 4;
++              fifo_fill--;
++      }
++
++      /*
++       * If there are remaining bytes, read byte count from STAT.RXBV
++       * register and read the data byte-wise.
++       */
++      while (fifo_fill && hw->rx_cnt < hw->len) {
++              rxbv = (ltq_spi_reg_read(hw, LTQ_SPI_STAT) >>
++                      LTQ_SPI_STAT_RXBV_SHIFT) & LTQ_SPI_STAT_RXBV_MASK;
++              data = ltq_spi_reg_read(hw, LTQ_SPI_RB);
++
++              shift = (rxbv - 1) * 8;
++              rx8 = hw->rx;
++
++              while (rxbv) {
++                      *rx8++ = (data >> shift) & 0xFF;
++                      rxbv--;
++                      shift -= 8;
++                      hw->rx_cnt++;
++                      hw->rx++;
++              }
++
++              fifo_fill--;
++      }
++}
++
++static void ltq_spi_rxreq_set(struct ltq_spi *hw)
++{
++      u32 rxreq, rxreq_max, rxtodo;
++
++      rxtodo = ltq_spi_reg_read(hw, LTQ_SPI_RXCNT) & LTQ_SPI_RXCNT_TODO_MASK;
++
++      /*
++       * In RX-only mode the serial clock is activated only after writing
++       * the expected amount of RX bytes into RXREQ register.
++       * To avoid receive overflows at high clocks it is better to request
++       * only the amount of bytes that fits into all FIFOs. This value
++       * depends on the FIFO size implemented in hardware.
++       */
++      rxreq = hw->len - hw->rx_cnt;
++      rxreq_max = hw->rxfs << 2;
++      rxreq = min(rxreq_max, rxreq);
++
++      if (!rxtodo && rxreq)
++              ltq_spi_reg_write(hw, rxreq, LTQ_SPI_RXREQ);
++}
++
++static inline void ltq_spi_complete(struct ltq_spi *hw)
++{
++      complete(&hw->done);
++}
++
++irqreturn_t ltq_spi_tx_irq(int irq, void *data)
++{
++      struct ltq_spi *hw = data;
++      unsigned long flags;
++      int completed = 0;
++
++      spin_lock_irqsave(&hw->lock, flags);
++
++      if (hw->tx_cnt < hw->len)
++              ltq_spi_txfifo_write(hw);
++
++      if (hw->tx_cnt == hw->len)
++              completed = 1;
++
++      spin_unlock_irqrestore(&hw->lock, flags);
++
++      if (completed)
++              ltq_spi_complete(hw);
++
++      return IRQ_HANDLED;
++}
++
++irqreturn_t ltq_spi_rx_irq(int irq, void *data)
++{
++      struct ltq_spi *hw = data;
++      unsigned long flags;
++      int completed = 0;
++
++      spin_lock_irqsave(&hw->lock, flags);
++
++      if (hw->rx_cnt < hw->len) {
++              ltq_spi_rxfifo_read(hw);
++
++              if (hw->tx && hw->tx_cnt < hw->len)
++                      ltq_spi_txfifo_write(hw);
++      }
++
++      if (hw->rx_cnt == hw->len)
++              completed = 1;
++      else if (!hw->tx)
++              ltq_spi_rxreq_set(hw);
++
++      spin_unlock_irqrestore(&hw->lock, flags);
++
++      if (completed)
++              ltq_spi_complete(hw);
++
++      return IRQ_HANDLED;
++}
++
++irqreturn_t ltq_spi_err_irq(int irq, void *data)
++{
++      struct ltq_spi *hw = data;
++      unsigned long flags;
++
++      spin_lock_irqsave(&hw->lock, flags);
++
++      /* Disable all interrupts */
++      ltq_spi_reg_clearbit(hw, LTQ_SPI_IRNEN_ALL, LTQ_SPI_IRNEN);
++
++      /* Clear all error flags */
++      ltq_spi_reg_write(hw, LTQ_SPI_WHBSTATE_CLR_ERRORS, LTQ_SPI_WHBSTATE);
++
++      /* Flush FIFOs */
++      ltq_spi_reg_setbit(hw, LTQ_SPI_RXFCON_RXFLU, LTQ_SPI_RXFCON);
++      ltq_spi_reg_setbit(hw, LTQ_SPI_TXFCON_TXFLU, LTQ_SPI_TXFCON);
++
++      hw->status = -EIO;
++      spin_unlock_irqrestore(&hw->lock, flags);
++
++      ltq_spi_complete(hw);
++
++      return IRQ_HANDLED;
++}
++
++static int ltq_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t)
++{
++      struct ltq_spi *hw = ltq_spi_to_hw(spi);
++      u32 irq_flags = 0;
++
++      hw->tx = t->tx_buf;
++      hw->rx = t->rx_buf;
++      hw->len = t->len;
++      hw->tx_cnt = 0;
++      hw->rx_cnt = 0;
++      hw->status = 0;
++      INIT_COMPLETION(hw->done);
++
++      ltq_spi_xmit_set(hw, t);
++
++      /* Enable error interrupts */
++      ltq_spi_reg_setbit(hw, LTQ_SPI_IRNEN_E, LTQ_SPI_IRNEN);
++
++      if (hw->tx) {
++              /* Initially fill TX FIFO with as much data as possible */
++              ltq_spi_txfifo_write(hw);
++              irq_flags |= LTQ_SPI_IRNEN_T;
++
++              /* Always enable RX interrupt in Full Duplex mode */
++              if (hw->rx)
++                      irq_flags |= LTQ_SPI_IRNEN_R;
++      } else if (hw->rx) {
++              /* Start RX clock */
++              ltq_spi_rxreq_set(hw);
++
++              /* Enable RX interrupt to receive data from RX FIFOs */
++              irq_flags |= LTQ_SPI_IRNEN_R;
++      }
++
++      /* Enable TX or RX interrupts */
++      ltq_spi_reg_setbit(hw, irq_flags, LTQ_SPI_IRNEN);
++      wait_for_completion_interruptible(&hw->done);
++
++      /* Disable all interrupts */
++      ltq_spi_reg_clearbit(hw, LTQ_SPI_IRNEN_ALL, LTQ_SPI_IRNEN);
++
++      /*
++       * Return length of current transfer for bitbang utility code if
++       * no errors occured during transmission.
++       */
++      if (!hw->status)
++              hw->status = hw->len;
++
++      return hw->status;
++}
++
++static const struct ltq_spi_irq_map ltq_spi_irqs[] = {
++      { "spi_tx", ltq_spi_tx_irq },
++      { "spi_rx", ltq_spi_rx_irq },
++      { "spi_err", ltq_spi_err_irq },
++};
++
++static int __init ltq_spi_probe(struct platform_device *pdev)
++{
++      struct spi_master *master;
++      struct resource *r;
++      struct ltq_spi *hw;
++      struct ltq_spi_platform_data *pdata = pdev->dev.platform_data;
++      int ret, i;
++      u32 data, id;
++
++      master = spi_alloc_master(&pdev->dev, sizeof(struct ltq_spi));
++      if (!master) {
++              dev_err(&pdev->dev, "spi_alloc_master\n");
++              ret = -ENOMEM;
++              goto err;
++      }
++
++      hw = spi_master_get_devdata(master);
++
++      r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++      if (r == NULL) {
++              dev_err(&pdev->dev, "platform_get_resource\n");
++              ret = -ENOENT;
++              goto err_master;
++      }
++
++      r = devm_request_mem_region(&pdev->dev, r->start, resource_size(r),
++                      pdev->name);
++      if (!r) {
++              dev_err(&pdev->dev, "devm_request_mem_region\n");
++              ret = -ENXIO;
++              goto err_master;
++      }
++
++      hw->base = devm_ioremap_nocache(&pdev->dev, r->start, resource_size(r));
++      if (!hw->base) {
++              dev_err(&pdev->dev, "devm_ioremap_nocache\n");
++              ret = -ENXIO;
++              goto err_master;
++      }
++
++      hw->clk = clk_get(&pdev->dev, "fpi");
++      if (IS_ERR(hw->clk)) {
++              dev_err(&pdev->dev, "clk_get\n");
++              ret = PTR_ERR(hw->clk);
++              goto err_master;
++      }
++
++      memset(hw->irq, 0, sizeof(hw->irq));
++      for (i = 0; i < ARRAY_SIZE(ltq_spi_irqs); i++) {
++              ret = platform_get_irq_byname(pdev, ltq_spi_irqs[i].name);
++              if (0 > ret) {
++                      dev_err(&pdev->dev, "platform_get_irq_byname\n");
++                      goto err_irq;
++              }
++
++              hw->irq[i] = ret;
++              ret = request_irq(hw->irq[i], ltq_spi_irqs[i].handler,
++                                0, ltq_spi_irqs[i].name, hw);
++              if (ret) {
++                      dev_err(&pdev->dev, "request_irq\n");
++                      goto err_irq;
++              }
++      }
++
++      hw->bitbang.master = spi_master_get(master);
++      hw->bitbang.chipselect = ltq_spi_chipselect;
++      hw->bitbang.setup_transfer = ltq_spi_setup_transfer;
++      hw->bitbang.txrx_bufs = ltq_spi_txrx_bufs;
++
++      master->bus_num = pdev->id;
++      master->num_chipselect = pdata->num_chipselect;
++      master->setup = ltq_spi_setup;
++      master->cleanup = ltq_spi_cleanup;
++
++      hw->dev = &pdev->dev;
++      init_completion(&hw->done);
++      spin_lock_init(&hw->lock);
++
++      /* Set GPIO alternate functions to SPI */
++      ltq_gpio_request(LTQ_SPI_GPIO_DI, 1, 0, 0, "spi-di");
++      ltq_gpio_request(LTQ_SPI_GPIO_DO, 1, 0, 1, "spi-do");
++      ltq_gpio_request(LTQ_SPI_GPIO_CLK, 1, 0, 1, "spi-clk");
++
++      ltq_spi_hw_enable(hw);
++
++      /* Read module capabilities */
++      id = ltq_spi_reg_read(hw, LTQ_SPI_ID);
++      hw->txfs = (id >> LTQ_SPI_ID_TXFS_SHIFT) & LTQ_SPI_ID_TXFS_MASK;
++      hw->rxfs = (id >> LTQ_SPI_ID_TXFS_SHIFT) & LTQ_SPI_ID_TXFS_MASK;
++      hw->dma_support = (id & LTQ_SPI_ID_CFG) ? 1 : 0;
++
++      ltq_spi_config_mode_set(hw);
++
++      /* Enable error checking, disable TX/RX, set idle value high */
++      data = LTQ_SPI_CON_RUEN | LTQ_SPI_CON_AEN |
++          LTQ_SPI_CON_TEN | LTQ_SPI_CON_REN |
++          LTQ_SPI_CON_TXOFF | LTQ_SPI_CON_RXOFF | LTQ_SPI_CON_IDLE;
++      ltq_spi_reg_write(hw, data, LTQ_SPI_CON);
++
++      /* Enable master mode and clear error flags */
++      ltq_spi_reg_write(hw, LTQ_SPI_WHBSTATE_SETMS |
++                        LTQ_SPI_WHBSTATE_CLR_ERRORS, LTQ_SPI_WHBSTATE);
++
++      /* Reset GPIO/CS registers */
++      ltq_spi_reg_write(hw, 0x0, LTQ_SPI_GPOCON);
++      ltq_spi_reg_write(hw, 0xFF00, LTQ_SPI_FGPO);
++
++      /* Enable and flush FIFOs */
++      ltq_spi_reset_fifos(hw);
++
++      ret = spi_bitbang_start(&hw->bitbang);
++      if (ret) {
++              dev_err(&pdev->dev, "spi_bitbang_start\n");
++              goto err_bitbang;
++      }
++
++      platform_set_drvdata(pdev, hw);
++
++      pr_info("Lantiq SoC SPI controller rev %u (TXFS %u, RXFS %u, DMA %u)\n",
++              id & LTQ_SPI_ID_REV_MASK, hw->txfs, hw->rxfs, hw->dma_support);
++
++      return 0;
++
++err_bitbang:
++      ltq_spi_hw_disable(hw);
++
++err_irq:
++      clk_put(hw->clk);
++
++      for (; i > 0; i--)
++              free_irq(hw->irq[i], hw);
++
++err_master:
++      spi_master_put(master);
++
++err:
++      return ret;
++}
++
++static int __exit ltq_spi_remove(struct platform_device *pdev)
++{
++      struct ltq_spi *hw = platform_get_drvdata(pdev);
++      int ret, i;
++
++      ret = spi_bitbang_stop(&hw->bitbang);
++      if (ret)
++              return ret;
++
++      platform_set_drvdata(pdev, NULL);
++
++      ltq_spi_config_mode_set(hw);
++      ltq_spi_hw_disable(hw);
++
++      for (i = 0; i < ARRAY_SIZE(hw->irq); i++)
++              if (0 < hw->irq[i])
++                      free_irq(hw->irq[i], hw);
++
++      gpio_free(LTQ_SPI_GPIO_DI);
++      gpio_free(LTQ_SPI_GPIO_DO);
++      gpio_free(LTQ_SPI_GPIO_CLK);
++
++      clk_put(hw->clk);
++      spi_master_put(hw->bitbang.master);
++
++      return 0;
++}
++
++static struct platform_driver ltq_spi_driver = {
++      .driver = {
++                 .name = "ltq-spi",
++                 .owner = THIS_MODULE,
++                 },
++      .remove = __exit_p(ltq_spi_remove),
++};
++
++static int __init ltq_spi_init(void)
++{
++      return platform_driver_probe(&ltq_spi_driver, ltq_spi_probe);
++}
++module_init(ltq_spi_init);
++
++static void __exit ltq_spi_exit(void)
++{
++      platform_driver_unregister(&ltq_spi_driver);
++}
++module_exit(ltq_spi_exit);
++
++MODULE_DESCRIPTION("Lantiq SoC SPI controller driver");
++MODULE_AUTHOR("Daniel Schwierzeck <daniel.schwierzeck@googlemail.com>");
++MODULE_LICENSE("GPL");
++MODULE_ALIAS("platform:ltq-spi");
diff --git a/target/linux/lantiq/patches-3.0/0015-MIPS-lantiq-adds-etop-support-for-ase-ar9.patch b/target/linux/lantiq/patches-3.0/0015-MIPS-lantiq-adds-etop-support-for-ase-ar9.patch
new file mode 100644 (file)
index 0000000..40ec2bd
--- /dev/null
@@ -0,0 +1,417 @@
+From c7881d8d2b3aed9a90aa37dcf797328a9cfbe7b6 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Wed, 10 Aug 2011 15:32:16 +0200
+Subject: [PATCH 15/24] MIPS: lantiq: adds etop support for ase/ar9
+
+Extend the driver to handle the different DMA channel layout for AR9 and
+SoCs. The patch also adds support for the integrated PHY found on Amazon-SE
+and the gigabit switch found inside the AR9.
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+Signed-off-by: Thomas Langer <thomas.langer@lantiq.com>
+---
+ .../mips/include/asm/mach-lantiq/xway/lantiq_irq.h |   22 +---
+ .../mips/include/asm/mach-lantiq/xway/lantiq_soc.h |   10 ++
+ arch/mips/lantiq/xway/devices.c                    |   11 +-
+ arch/mips/lantiq/xway/mach-easy50601.c             |    5 +
+ drivers/net/lantiq_etop.c                          |  172 ++++++++++++++++++--
+ 5 files changed, 180 insertions(+), 40 deletions(-)
+
+Index: linux-3.0.3/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h
+===================================================================
+--- linux-3.0.3.orig/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h       2011-10-04 20:05:23.000000000 +0200
++++ linux-3.0.3/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h    2011-10-04 20:05:44.146312365 +0200
+@@ -40,26 +40,8 @@
+ #define MIPS_CPU_TIMER_IRQ            7
+-#define LTQ_DMA_CH0_INT            &n