* update kernel to .37 * add support for falcon (big thank you goes to lantiq !!)

SVN-Revision: 26021
v19.07.3_mercusys_ac12_duma
John Crispin 13 years ago
parent 58a5102338
commit c75b0ca1a8

@ -9,10 +9,10 @@ include $(TOPDIR)/rules.mk
ARCH:=mips
BOARD:=lantiq
BOARDNAME:=Lantiq GPON/XWAY
FEATURES:=squashfs jffs2 atm
SUBTARGETS:=xway
FEATURES:=squashfs jffs2
SUBTARGETS:=falcon xway
LINUX_VERSION:=2.6.35.11
LINUX_VERSION:=2.6.37.2
CFLAGS=-Os -pipe -mips32r2 -mtune=mips32r2 -funit-at-a-time

@ -1,24 +1,38 @@
# CONFIG_TC35815 is not set
# CONFIG_TINY_RCU is not set
# CONFIG_TREE_PREEMPT_RCU is not set
# CONFIG_HAVE_IDE is not set
CONFIG_32BIT=y
# CONFIG_64BIT is not set
# CONFIG_ALCHEMY_GPIO_INDIRECT is not set
# CONFIG_AR7 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_AUTO_IRQ_AFFINITY is not set
# CONFIG_BCM47XX is not set
# CONFIG_BCM63XX is not set
CONFIG_BITREVERSE=y
CONFIG_BKL=y
# CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set
# CONFIG_CAVIUM_OCTEON_SIMULATOR is not set
CONFIG_CEVT_R4K=y
CONFIG_CEVT_R4K_LIB=y
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_LOONGSON2F 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
@ -32,122 +46,126 @@
# 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_DM9000 is not set
# CONFIG_FSNOTIFY is not set
# CONFIG_HZ_100 is not set
# CONFIG_LOONGSON_UART_BASE is not set
# CONFIG_MACH_ALCHEMY is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MACH_JAZZ is not set
# CONFIG_MACH_LOONGSON is not set
# CONFIG_MACH_TX39XX is not set
# CONFIG_MACH_TX49XX is not set
# CONFIG_MACH_VR41XX is not set
# CONFIG_MIKROTIK_RB532 is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_MT_SMP is not set
# CONFIG_MIPS_MT_SMTC is not set
# CONFIG_MIPS_SIM is not set
# CONFIG_MIPS_VPE_LOADER is not set
# CONFIG_NO_IOPORT is not set
# CONFIG_NXP_STB220 is not set
# CONFIG_NXP_STB225 is not set
# CONFIG_PMC_MSP is not set
# CONFIG_PMC_YOSEMITE is not set
# CONFIG_PNX8550_JBS is not set
# CONFIG_PNX8550_STB810 is not set
# CONFIG_POWERTV is not set
# CONFIG_SCSI_DMA is not set
# CONFIG_SERIAL_8250 is not set
# CONFIG_SERIAL_8250_EXTENDED is not set
# CONFIG_SGI_IP22 is not set
# CONFIG_SGI_IP27 is not set
# CONFIG_SGI_IP28 is not set
# CONFIG_SGI_IP32 is not set
# CONFIG_SIBYTE_BIGSUR is not set
# CONFIG_SIBYTE_CARMEL is not set
# CONFIG_SIBYTE_CRHINE is not set
# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SIBYTE_LITTLESUR is not set
# CONFIG_SIBYTE_RHONE is not set
# CONFIG_SIBYTE_SENTOSA is not set
# CONFIG_SIBYTE_SWARM is not set
CONFIG_32BIT=y
CONFIG_ADM6996_PHY=y
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_ARCH_REQUIRE_GPIOLIB=y
CONFIG_ARCH_SUPPORTS_OPROFILE=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_BITREVERSE=y
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_R2=y
CONFIG_CPU_MIPSR2=y
CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
CONFIG_CPU_SUPPORTS_HIGHMEM=y
CONFIG_CRYPTO_BLKCIPHER=y
CONFIG_CRYPTO_BLKCIPHER2=y
CONFIG_CRYPTO_HW=y
CONFIG_CRYPTO_RNG2=y
CONFIG_CRYPTO_WORKQUEUE=y
CONFIG_CSRC_R4K=y
CONFIG_CSRC_R4K_LIB=y
CONFIG_DECOMPRESS_LZMA=y
CONFIG_DEVPORT=y
# CONFIG_DM9000 is not set
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_DEPRECATED is not set
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
# CONFIG_GENERIC_PENDING_IRQ is not set
CONFIG_GPIOLIB=y
CONFIG_GPIO_SYSFS=y
# CONFIG_HARDIRQS_SW_RESEND is not set
CONFIG_HARDWARE_WATCHPOINTS=y
CONFIG_HAS_DMA=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAVE_ARCH_KGDB=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 is not set
CONFIG_HAVE_OPROFILE=y
CONFIG_HAVE_PERF_EVENTS=y
# CONFIG_HAVE_SPARSE_IRQ is not set
CONFIG_HW_RANDOM=y
CONFIG_HZ=250
# CONFIG_HZ_100 is not set
CONFIG_HZ_250=y
# CONFIG_I2C_FALCON is not set
CONFIG_IFX_UDP_REDIRECT=y
CONFIG_IMAGE_CMDLINE_HACK=y
CONFIG_INITRAMFS_SOURCE=""
CONFIG_IRQ_CPU=y
# CONFIG_IRQ_PER_CPU is not set
CONFIG_LANTIQ=y
CONFIG_LANTIQ_WDT=y
CONFIG_LEDS_GPIO=y
CONFIG_LOONGSON_UART_BASE=y
# CONFIG_MACH_ALCHEMY is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MACH_JAZZ is not set
# CONFIG_MACH_LOONGSON is not set
CONFIG_MACH_NO_WESTBRIDGE=y
# CONFIG_MACH_TX39XX is not set
# CONFIG_MACH_TX49XX is not set
# CONFIG_MACH_VR41XX is not set
# CONFIG_MIKROTIK_RB532 is not set
CONFIG_MIPS=y
# CONFIG_MIPS_COBALT is not set
CONFIG_MIPS_L1_CACHE_SHIFT=5
CONFIG_MIPS_MACHINE=y
# CONFIG_MIPS_MALTA is not set
CONFIG_MIPS_MT_DISABLED=y
# CONFIG_MIPS_MT_SMP is not set
# CONFIG_MIPS_MT_SMTC is not set
# CONFIG_MIPS_SIM 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_NO_IOPORT is not set
# CONFIG_NXP_STB220 is not set
# CONFIG_NXP_STB225 is not set
CONFIG_PAGEFLAGS_EXTENDED=y
CONFIG_PCI=y
CONFIG_PCI_DOMAINS=y
CONFIG_PERF_USE_VMALLOC=y
CONFIG_PHYLIB=y
# CONFIG_PMC_MSP is not set
# CONFIG_PMC_YOSEMITE is not set
# CONFIG_PNX8550_JBS is not set
# CONFIG_PNX8550_STB810 is not set
# CONFIG_POWERTV is not set
# CONFIG_PREEMPT_RCU is not set
# CONFIG_QUOTACTL is not set
CONFIG_SCHED_OMIT_FRAME_POINTER=y
# CONFIG_SCSI_DMA is not set
# CONFIG_SERIAL_8250 is not set
# CONFIG_SERIAL_8250_EXTENDED is not set
CONFIG_SERIAL_LANTIQ=y
# CONFIG_SGI_IP22 is not set
# CONFIG_SGI_IP27 is not set
# CONFIG_SGI_IP28 is not set
# CONFIG_SGI_IP32 is not set
# CONFIG_SIBYTE_BIGSUR is not set
# CONFIG_SIBYTE_CARMEL is not set
# CONFIG_SIBYTE_CRHINE is not set
# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SIBYTE_LITTLESUR is not set
# CONFIG_SIBYTE_RHONE is not set
# CONFIG_SIBYTE_SENTOSA is not set
# CONFIG_SIBYTE_SWARM is not set
CONFIG_SOC_LANTIQ=y
CONFIG_SWAP_IO_SPACE=y
CONFIG_SWCONFIG=y
CONFIG_SYS_HAS_CPU_MIPS32_R1=y
@ -157,7 +175,9 @@ CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
CONFIG_SYS_SUPPORTS_MULTITHREADING=y
# CONFIG_TC35815 is not set
CONFIG_TINY_RCU=y
CONFIG_TRAD_SIGNALS=y
# CONFIG_TREE_PREEMPT_RCU is not set
CONFIG_TREE_RCU=y
CONFIG_ZONE_DMA_FLAG=0
CONFIG_IFX_UDP_REDIRECT=y

@ -0,0 +1,31 @@
CONFIG_CPU_MIPSR2_IRQ_EI=y
CONFIG_CPU_MIPSR2_IRQ_VI=y
# CONFIG_CRYPTO is not set
CONFIG_DM9000=y
CONFIG_DM9000_DEBUGLEVEL=4
CONFIG_DM9000_FORCE_SIMPLE_PHY_POLL=y
CONFIG_HAVE_IDE=y
CONFIG_HW_HAS_PCI=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_LANTIQ_PROM_ASC0=y
# CONFIG_LANTIQ_PROM_ASC1 is not set
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_MTSCHED=y
# CONFIG_PCI is not set
# CONFIG_PERFCTRS is not set
CONFIG_SOC_LANTIQ_FALCON=y
# CONFIG_SOC_LANTIQ_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

@ -0,0 +1,14 @@
define Profile/Generic
NAME:=Generic - all boards
PACKAGES:= \
kmod-leds-gpio \
kmod-dm9000 \
kmod-i2c-core kmod-i2c-algo-bit kmod-i2c-gpio kmod-eeprom-at24 \
kmod-spi-bitbang kmod-spi-gpio kmod-eeprom-at25 \
gpon-dti-agent \
uboot-easy980x0_norflash uboot-easy980x0_serialflash uboot-easy98020
endef
$(eval $(call Profile,Generic))

@ -0,0 +1,27 @@
define Profile/EASY98000
NAME:=EASY98000
PACKAGES:= \
kmod-dm9000 \
kmod-i2c-core kmod-i2c-algo-bit kmod-i2c-gpio kmod-eeprom-at24 \
kmod-spi-bitbang kmod-spi-gpio kmod-eeprom-at25 \
uboot-easy980x0_norflash uboot-easy980x0_serialflash
endef
define Profile/EASY98000/Description
Lantiq EASY98000 evalkit
endef
$(eval $(call Profile,EASY98000))
define Profile/EASY98020
NAME:=EASY98020
PACKAGES:= \
kmod-leds-gpio uboot-easy98020
endef
define Profile/EASY98020/Description
Lantiq EASY98020 evalkit
endef
$(eval $(call Profile,EASY98020))

@ -0,0 +1,13 @@
ARCH:=mips
SUBTARGET:=falcon
BOARDNAME:=Falcon
FEATURES:=squashfs jffs2
DEVICE_TYPE:=other
DEFAULT_PACKAGES+= kmod-ifxos gpon-base-files kmod-leds-gpio \
kmod-gpon-optic-drv gpon-optic-drv kmod-gpon-onu-drv gpon-onu-drv \
gpon-pe-firmware gpon-omci-api gpon-omci-onu gpon-luci
define Target/Description
Lantiq Falcon
endef

@ -71,6 +71,14 @@ define Image/Build/Profile/EASY50812
$(call Image/Build/$(1),$(1),EASY50812)
endef
define Image/BuildKernel/Profile/ARV3527P
$(call Image/BuildKernel/Template,ARV3527P,$(xway_cmdline))
endef
define Image/Build/Profile/ARV3527P
$(call Image/Build/$(1),$(1),ARV3527P)
endef
define Image/BuildKernel/Profile/ARV4518PW
$(call Image/BuildKernel/Template,ARV4518PW,$(xway_cmdline))
endef
@ -115,6 +123,7 @@ define Image/BuildKernel/Profile/Generic
$(call Image/BuildKernel/Template,EASY4010,$(xway_cmdline))
$(call Image/BuildKernel/Template,EASY50712,$(xway_cmdline))
$(call Image/BuildKernel/Template,EASY50812,$(xway_cmdline))
$(call Image/BuildKernel/Template,ARV3527P,$(xway_cmdline))
$(call Image/BuildKernel/Template,ARV4510PW,$(xway_cmdline))
$(call Image/BuildKernel/Template,ARV4518PW,$(xway_cmdline))
$(call Image/BuildKernel/Template,ARV4520PW,$(xway_cmdline))
@ -130,6 +139,7 @@ define Image/Build/Profile/Generic
$(call Image/Build/$(1),$(1),EASY4010)
$(call Image/Build/$(1),$(1),EASY50712)
$(call Image/Build/$(1),$(1),EASY50812)
$(call Image/Build/$(1),$(1),ARV3527P)
$(call Image/Build/$(1),$(1),ARV4510PW)
$(call Image/Build/$(1),$(1),ARV4518PW)
$(call Image/Build/$(1),$(1),ARV4520PW)
@ -144,15 +154,17 @@ endef
endif
ifeq ($(CONFIG_TARGET_lantiq_falcon),y)
define Image/BuildKernel
define Image/BuildKernel/Profile/Generic
$(call Image/BuildKernel/Template,EASY98000,$(falcon_cmdline))
$(call Image/BuildKernel/Template,EASY98020,$(falcon_cmdline))
$(call Image/BuildKernel/Template,NONE)
endef
define Image/Build
define Image/Build/Profile/Generic
$(call Image/Build/$(1),$(1),EASY98000)
$(call Image/Build/$(1),$(1),EASY98020)
$(call Image/Build/$(1),$(1),NONE)
$(CP) $(KDIR)/root.$(1) $(BIN_DIR)/$(IMG_PREFIX)-$(1).rootfs
$(CP) $(KDIR)/root.$(1) $(BIN_DIR)/$(IMG_PREFIX)-$(1).rootfs
endef
endif

@ -33,7 +33,8 @@ define KernelPackage/usb-dwc-otg
KCONFIG:=CONFIG_DWC_OTG \
CONFIG_DWC_OTG_DEBUG=n \
CONFIG_DWC_OTG_LANTIQ=y \
CONFIG_DWC_OTG_HOST_ONLY=y
CONFIG_DWC_OTG_HOST_ONLY=y \
CONFIG_DWC_OTG_DEVICE_ONLY=n
FILES:=$(LINUX_DIR)/drivers/usb/dwc_otg/dwc_otg.ko
AUTOLOAD:=$(call AutoLoad,50,dwc_otg)
endef
@ -44,4 +45,18 @@ endef
$(eval $(call KernelPackage,usb-dwc-otg))
I2C_FALCON_MODULES:= \
CONFIG_I2C_FALCON:drivers/i2c/busses/i2c-falcon
define KernelPackage/i2c-falcon-lantiq
TITLE:=Falcon I2C controller
$(call i2c_defaults,$(I2C_FALCON_MODULES),52)
DEPENDS:=kmod-i2c-core @TARGET_lantiq
endef
define KernelPackage/i2c-falcon-lantiq/description
Kernel support for the Falcon I2C controller
endef
$(eval $(call KernelPackage,i2c-falcon-lantiq))

@ -1,6 +1,6 @@
--- a/arch/mips/kernel/cevt-r4k.c
+++ b/arch/mips/kernel/cevt-r4k.c
@@ -22,6 +22,22 @@
@@ -23,6 +23,22 @@
#ifndef CONFIG_MIPS_MT_SMTC
@ -23,11 +23,11 @@
static int mips_next_event(unsigned long delta,
struct clock_event_device *evt)
{
@@ -31,6 +47,7 @@ static int mips_next_event(unsigned long
@@ -32,6 +48,7 @@
cnt = read_c0_count();
cnt += delta;
write_c0_compare(cnt);
+ compare_change_hazard();
res = ((int)(read_c0_count() - cnt) > 0) ? -ETIME : 0;
res = ((int)(read_c0_count() - cnt) >= 0) ? -ETIME : 0;
return res;
}

@ -1,12 +1,12 @@
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -650,6 +650,9 @@ handle_percpu_irq(unsigned int irq, stru
@@ -678,6 +678,9 @@
kstat_incr_irqs_this_cpu(irq, desc);
+ if (unlikely(!desc->action || (desc->status & IRQ_DISABLED)))
+ return;
+
if (desc->chip->ack)
desc->chip->ack(irq);
if (desc->irq_data.chip->irq_ack)
desc->irq_data.chip->irq_ack(&desc->irq_data);

@ -1,6 +1,6 @@
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -139,6 +139,9 @@
@@ -157,6 +157,9 @@
otherwise choose R3000.
@ -10,7 +10,7 @@
config MACH_JAZZ
bool "Jazz family of machines"
select ARC
@@ -695,6 +698,7 @@
@@ -729,6 +732,7 @@
source "arch/mips/vr41xx/Kconfig"
source "arch/mips/cavium-octeon/Kconfig"
source "arch/mips/loongson/Kconfig"
@ -18,26 +18,6 @@
endmenu
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -339,6 +339,17 @@
load-$(CONFIG_MIPS_COBALT) += 0xffffffff80080000
#
+# Lantiq
+#
+load-$(CONFIG_LANTIQ) += 0xffffffff80002000
+core-$(CONFIG_LANTIQ) += arch/mips/lantiq/
+cflags-$(CONFIG_LANTIQ) += -I$(srctree)/arch/mips/include/asm/mach-lantiq
+core-$(CONFIG_SOC_LANTIQ_FALCON) += arch/mips/lantiq/falcon/
+cflags-$(CONFIG_SOC_LANTIQ_FALCON) += -I$(srctree)/arch/mips/include/asm/mach-lantiq/falcon
+core-$(CONFIG_SOC_LANTIQ_XWAY) += arch/mips/lantiq/xway/
+cflags-$(CONFIG_SOC_LANTIQ_XWAY) += -I$(srctree)/arch/mips/include/asm/mach-lantiq/xway
+
+#
# DECstation family
#
core-$(CONFIG_MACH_DECSTATION) += arch/mips/dec/
--- /dev/null
+++ b/arch/mips/lantiq/Kconfig
@@ -0,0 +1,36 @@
@ -79,9 +59,10 @@
+endif
--- /dev/null
+++ b/arch/mips/lantiq/Makefile
@@ -0,0 +1,2 @@
@@ -0,0 +1,3 @@
+obj-y := irq.o setup.o clk.o prom.o
+obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
+obj-$(CONFIG_SOC_LANTIQ_XWAY) += xway/
--- /dev/null
+++ b/arch/mips/lantiq/irq.c
@@ -0,0 +1,218 @@
@ -645,3 +626,24 @@
+void lq_soc_detect(struct lq_soc_info *i);
+
+#endif
--- a/arch/mips/Kbuild.platforms
+++ b/arch/mips/Kbuild.platforms
@@ -11,6 +11,7 @@
platforms += jazz
platforms += jz4740
platforms += lasat
+platforms += lantiq
platforms += loongson
platforms += mipssim
platforms += mti-malta
--- /dev/null
+++ b/arch/mips/lantiq/Platform
@@ -0,0 +1,8 @@
+#
+# Lantiq
+#
+
+platform-$(CONFIG_LANTIQ) += lantiq/
+cflags-$(CONFIG_LANTIQ) += -I$(srctree)/arch/mips/include/asm/mach-lantiq
+load-$(CONFIG_LANTIQ) = 0xffffffff80002000
+cflags-$(CONFIG_SOC_LANTIQ_XWAY) += -I$(srctree)/arch/mips/include/asm/mach-lantiq/xway

@ -615,7 +615,7 @@
+}
--- /dev/null
+++ b/arch/mips/lantiq/xway/devices.c
@@ -0,0 +1,313 @@
@@ -0,0 +1,336 @@
+/*
+ * 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
@ -871,13 +871,23 @@
+ },
+};
+
+static unsigned int *cp1_base;
+unsigned int*
+lq_get_cp1_base(void)
+{
+ return cp1_base;
+}
+EXPORT_SYMBOL(lq_get_cp1_base);
+
+void __init
+lq_register_tapi(void)
+{
+#define CP1_SIZE (1 << 20)
+ dma_addr_t dma;
+ mps_device.dev.platform_data =
+ cp1_base =
+ (void*)CPHYSADDR(dma_alloc_coherent(NULL, CP1_SIZE, &dma, GFP_ATOMIC));
+ mps_device.dev.platform_data = cp1_base;
+ platform_device_register(&mps_device);
+ platform_device_register(&vmmc_device);
+}
@ -929,9 +939,22 @@
+{
+ platform_device_register_simple(name, 0, 0, 0);
+}
+
+/* madwifi */
+int lantiq_emulate_madwifi_eep = 0;
+EXPORT_SYMBOL(lantiq_emulate_madwifi_eep);
+
+void __init
+lq_register_madwifi_eep(void)
+{
+ lantiq_emulate_madwifi_eep = 1;
+}
+
+
+
--- /dev/null
+++ b/arch/mips/lantiq/xway/devices.h
@@ -0,0 +1,26 @@
@@ -0,0 +1,28 @@
+/*
+ * 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
@ -952,6 +975,8 @@
+extern void __init lq_register_gpio_leds(struct gpio_led *leds, int cnt);
+extern void __init lq_register_pci(struct lq_pci_data *data);
+extern void __init lq_register_nor(struct physmap_flash_data *data);
+extern void __init lq_register_tapi(void);
+extern void __init lq_register_madwifi_eep(void);
+extern void __init lq_register_wdt(void);
+extern void __init lq_register_ethernet(struct lq_eth_data *eth);
+extern void __init lq_register_asc(int port);
@ -1856,13 +1881,13 @@
+ struct timer_dev_timer timer[MAX_NUM_OF_32BIT_TIMER_BLOCKS * 2];
+};
+
+static int gptu_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
+static long gptu_ioctl(struct file *, unsigned int, unsigned long);
+static int gptu_open(struct inode *, struct file *);
+static int gptu_release(struct inode *, struct file *);
+
+static struct file_operations gptu_fops = {
+ .owner = THIS_MODULE,
+ .ioctl = gptu_ioctl,
+ .unlocked_ioctl = gptu_ioctl,
+ .open = gptu_open,
+ .release = gptu_release
+};
@ -2376,7 +2401,7 @@
+}
+EXPORT_SYMBOL(lq_set_counter);
+
+static int gptu_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+static long gptu_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ int ret;

@ -1,7 +1,7 @@
--- a/arch/mips/lantiq/Kconfig
+++ b/arch/mips/lantiq/Kconfig
@@ -33,4 +33,19 @@ endchoice
source "arch/mips/lantiq/falcon/Kconfig"
@@ -33,4 +33,19 @@
#source "arch/mips/lantiq/falcon/Kconfig"
source "arch/mips/lantiq/xway/Kconfig"
+if EARLY_PRINTK
@ -44,7 +44,7 @@
+#define LQ_ASC_BASE KSEG1ADDR(LQ_ASC1_BASE)
+#endif
+
+#elif CONFIG_SOC_LANTIQ_FALCON
+#elif defined(CONFIG_SOC_LANTIQ_FALCON)
+#include <falcon/gpon_reg_base.h>
+#ifdef CONFIG_LANTIQ_PROM_ASC0
+#define LQ_ASC_BASE GPON_ASC0_BASE

@ -1,18 +1,16 @@
--- a/arch/mips/lantiq/setup.c
+++ b/arch/mips/lantiq/setup.c
@@ -12,7 +12,10 @@
@@ -12,7 +12,8 @@
#include <linux/ioport.h>
#include <lantiq.h>
-#include <lantiq_regs.h>
+
+#include <machine.h>
+
+static unsigned int *cp1_base;
void __init
plat_mem_setup(void)
@@ -31,6 +34,7 @@
@@ -31,6 +32,7 @@
ioport_resource.end = IOPORT_RESOURCE_END;
iomem_resource.start = IOMEM_RESOURCE_START;
iomem_resource.end = IOMEM_RESOURCE_END;
@ -20,23 +18,11 @@
while (*envp)
{
@@ -42,6 +46,37 @@
}
envp++;
}
+// memsize -= 2;
@@ -45,3 +47,25 @@
memsize *= 1024 * 1024;
+// cp1_base = (unsigned int*)(KSEG1 | memsize);
add_memory_region(0x00000000, memsize, BOOT_MEM_RAM);
}
+
+unsigned int*
+lq_get_cp1_base(void)
+{
+ return cp1_base;
+}
+EXPORT_SYMBOL(lq_get_cp1_base);
+
+static int __init
+lq_machine_setup(void)
+{

@ -0,0 +1,90 @@
--- /dev/null
+++ b/arch/mips/include/asm/mach-lantiq/dev-leds-gpio.h
@@ -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 lq_add_device_leds_gpio(int id,
+ unsigned num_leds,
+ struct gpio_led *leds) __init;
+
+#endif /* _LANTIQ_DEV_LEDS_GPIO_H */
--- /dev/null
+++ b/arch/mips/lantiq/dev-leds-gpio.c
@@ -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 lq_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);
+}
--- a/arch/mips/lantiq/Makefile
+++ b/arch/mips/lantiq/Makefile
@@ -1,2 +1,2 @@
-obj-y := irq.o setup.o clk.o prom.o
+obj-y := dev-leds-gpio.o irq.o setup.o clk.o prom.o
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o

@ -1,6 +1,6 @@
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -1397,6 +1397,14 @@
@@ -1454,6 +1454,14 @@
help
Support for Console on the NWP serial ports.
@ -17,10 +17,10 @@
depends on QUICC_ENGINE
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -84,3 +84,4 @@
obj-$(CONFIG_SERIAL_GRLIB_GAISLER_APBUART) += apbuart.o
obj-$(CONFIG_SERIAL_ALTERA_JTAGUART) += altera_jtaguart.o
obj-$(CONFIG_SERIAL_ALTERA_UART) += altera_uart.o
@@ -89,3 +89,4 @@
obj-$(CONFIG_SERIAL_MRST_MAX3110) += mrst_max3110.o
obj-$(CONFIG_SERIAL_MFD_HSU) += mfd.o
obj-$(CONFIG_SERIAL_OMAP) += omap-serial.o
+obj-$(CONFIG_SERIAL_LANTIQ) += lantiq.o
--- /dev/null
+++ b/drivers/serial/lantiq.c

@ -1,8 +1,8 @@
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -251,6 +251,12 @@
help
Support for flash chips on NETtel/SecureEdge/SnapGear boards.
@@ -260,6 +260,12 @@
Support for parsing CFE image tag and creating MTD partitions on
Broadcom BCM63xx boards.
+config MTD_LANTIQ
+ bool "Lantiq SoC NOR support"
@ -16,13 +16,13 @@
--- a/drivers/mtd/maps/Makefile
+++ b/drivers/mtd/maps/Makefile
@@ -59,3 +59,4 @@
obj-$(CONFIG_MTD_RBTX4939) += rbtx4939-flash.o
obj-$(CONFIG_MTD_VMU) += vmu-flash.o
obj-$(CONFIG_MTD_GPIO_ADDR) += gpio-addr-flash.o
+obj-$(CONFIG_MTD_LANTIQ) += lantiq.o
obj-$(CONFIG_MTD_BCM963XX) += bcm963xx-flash.o
+obj-$(CONFIG_MTD_LANTIQ) += lantiq.o
--- /dev/null
+++ b/drivers/mtd/maps/lantiq.c
@@ -0,0 +1,169 @@
@@ -0,0 +1,173 @@
+/*
+ * 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
@ -48,6 +48,10 @@
+#include <lantiq.h>
+#include <lantiq_platform.h>
+
+#ifdef CONFIG_SOC_LANTIQ_XWAY
+#include <xway.h>
+#endif
+
+static map_word
+lq_read16(struct map_info *map, unsigned long adr)
+{
@ -194,7 +198,7 @@
+MODULE_DESCRIPTION("Lantiq SoC NOR");
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -41,7 +41,11 @@
@@ -40,7 +40,11 @@
/* #define CMDSET0001_DISABLE_WRITE_SUSPEND */
// debugging, turns off buffer write mode if set to 1
@ -207,7 +211,7 @@
/* Intel chips */
#define I82802AB 0x00ad
@@ -1491,6 +1495,9 @@
@@ -1493,6 +1497,9 @@
int ret=0;
adr += chip->start;
@ -219,7 +223,7 @@
case FL_WRITING:
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
@@ -40,7 +40,11 @@
@@ -39,7 +39,11 @@
#include <linux/mtd/xip.h>
#define AMD_BOOTLOC_BUG
@ -232,7 +236,7 @@
#define MAX_WORD_RETRIES 3
@@ -1156,6 +1160,10 @@
@@ -1167,6 +1171,10 @@
adr += chip->start;

@ -1,99 +0,0 @@
--- a/drivers/mtd/maps/lantiq.c
+++ b/drivers/mtd/maps/lantiq.c
@@ -24,6 +24,10 @@
#include <lantiq.h>
#include <lantiq_platform.h>
+#ifdef CONFIG_SOC_LANTIQ_XWAY
+#include <xway.h>
+#endif
+
static map_word
lq_read16(struct map_info *map, unsigned long adr)
{
@@ -77,6 +81,75 @@ lq_copy_to(struct map_info *map, unsigne
spin_unlock_irqrestore(&ebu_lock, flags);
}
+static unsigned long
+find_uImage_size(struct map_info *map, unsigned long offset)
+{
+#define UBOOT_MAGIC 0x56190527
+ unsigned long magic;
+ unsigned long temp;
+ map->copy_from(map, &magic, offset, 4);
+ if (le32_to_cpu(magic) != UBOOT_MAGIC)
+ return 0;
+ map->copy_from(map, &temp, offset + 12, 4);
+ return temp + 0x40;
+}
+
+static int
+detect_squashfs_partition(struct map_info *map, unsigned long offset)
+{
+ unsigned long temp;
+ map->copy_from(map, &temp, offset, 4);
+ return le32_to_cpu(temp) == SQUASHFS_MAGIC;
+}
+
+static struct mtd_partition split_partitions[] = {
+ {
+ .name = "kernel",
+ .offset = 0x0,
+ .size = 0x0,
+ }, {
+ .name = "rootfs",
+ .offset = 0x0,
+ .size = 0x0,
+ },
+};
+
+static int
+mtd_split_linux(struct map_info *map, struct mtd_info *mtd,
+ struct mtd_partition *parts, int nr_parts)
+{
+ int base_part = 0;
+ int i;
+ for (i = 0; i < nr_parts && !base_part; i++) {
+ if(!strcmp("linux", parts[i].name))
+ base_part = i;
+ }
+ if (!base_part)
+ return 0;
+ split_partitions[0].size = find_uImage_size(map, parts[base_part].offset);
+ if (!split_partitions[0].size) {
+ printk(KERN_INFO "lq_nor: no uImage found in linux partition");
+ return -1;
+ }
+ if (!detect_squashfs_partition(map,
+ parts[base_part].offset + split_partitions[0].size)) {
+ split_partitions[0].size &= ~(mtd->erasesize - 1);
+ split_partitions[0].size += mtd->erasesize;
+ }
+ split_partitions[0].offset = parts[base_part].offset;
+ split_partitions[1].offset =
+ parts[base_part].offset + split_partitions[0].size;
+ split_partitions[1].size =
+ parts[base_part].size - split_partitions[0].size;
+
+ base_part++;
+ add_mtd_partitions(mtd, parts, base_part);
+ add_mtd_partitions(mtd, split_partitions, 2);
+ if(nr_parts != base_part)
+ add_mtd_partitions(mtd, &parts[base_part], nr_parts - base_part);
+ return nr_parts + 2;
+}
+
static const char *part_probe_types[] = { "cmdlinepart", NULL };
static struct map_info lq_map = {
@@ -142,7 +215,8 @@ lq_mtd_probe(struct platform_device *pde
parts = lq_mtd_data->parts;
}
- add_mtd_partitions(lq_mtd, parts, nr_parts);
+ if (!mtd_split_linux(&lq_map, lq_mtd, parts, nr_parts))
+ add_mtd_partitions(lq_mtd, parts, nr_parts);
return 0;
}

@ -0,0 +1,116 @@
--- a/drivers/mtd/Kconfig
+++ b/drivers/mtd/Kconfig
@@ -63,6 +63,10 @@ config MTD_ROOTFS_SPLIT
depends on MTD_PARTITIONS
default y
+config MTD_UIMAGE_SPLIT
+ bool "Automatically split 'linux' partition into 'kernel' and 'rootfs'"
+ default y
+
config MTD_REDBOOT_PARTS
tristate "RedBoot partition table parsing"
depends on MTD_PARTITIONS
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -722,6 +722,82 @@ static int refresh_rootfs_split(struct m
}
#endif /* CONFIG_MTD_ROOTFS_SPLIT */
+
+#ifdef CONFIG_MTD_UIMAGE_SPLIT
+static unsigned long find_uimage_size(struct mtd_info *mtd,
+ unsigned long offset)
+{
+#define UBOOT_MAGIC 0x56190527
+ unsigned long magic = 0;
+ unsigned long temp;
+ size_t len;
+ int ret;
+
+ ret = mtd->read(mtd, offset, 4, &len, (void *)&magic);
+ if (ret || len != sizeof(magic))
+ return 0;
+
+ if (le32_to_cpu(magic) != UBOOT_MAGIC)
+ return 0;
+
+ ret = mtd->read(mtd, offset + 12, 4, &len, (void *)&temp);
+ if (ret || len != sizeof(temp))
+ return 0;
+
+ return temp + 0x40;
+}
+
+static int detect_squashfs_partition(struct mtd_info *mtd, unsigned long offset)
+{
+ unsigned long temp;
+ size_t len;
+ int ret;
+
+ ret = mtd->read(mtd, offset, 4, &len, (void *)&temp);
+ if (ret || len != sizeof(temp))
+ return 0;
+
+ return le32_to_cpu(temp) == SQUASHFS_MAGIC;
+}
+
+static int split_uimage(struct mtd_info *mtd,
+ const struct mtd_partition *part)
+{
+ static struct mtd_partition split_partitions[] = {
+ {
+ .name = "kernel",
+ .offset = 0x0,
+ .size = 0x0,
+ }, {
+ .name = "rootfs",
+ .offset = 0x0,
+ .size = 0x0,
+ },
+ };
+
+ split_partitions[0].size = find_uimage_size(mtd, part->offset);
+ if (!split_partitions[0].size) {
+ printk(KERN_NOTICE "no uImage found in linux partition\n");
+ return -1;
+ }
+
+ if (!detect_squashfs_partition(mtd,
+ part->offset
+ + split_partitions[0].size)) {
+ split_partitions[0].size &= ~(mtd->erasesize - 1);
+ split_partitions[0].size += mtd->erasesize;
+ }
+
+ split_partitions[0].offset = part->offset;
+ split_partitions[1].offset = part->offset + split_partitions[0].size;
+ split_partitions[1].size = part->size - split_partitions[0].size;
+
+ add_mtd_partitions(mtd, split_partitions, 2);
+
+ return 0;
+}
+#endif
+
/*
* This function, given a master MTD object and a partition table, creates
* and registers slave MTD objects which are bound to the master according to
@@ -746,6 +822,17 @@ int add_mtd_partitions(struct mtd_info *
if (!slave)
return -ENOMEM;
+#ifdef CONFIG_MTD_UIMAGE_SPLIT
+ if (!strcmp(parts[i].name, "linux")) {
+ ret = split_uimage(master, &parts[i]);
+
+ if (ret) {
+ printk(KERN_WARNING
+ "Can't split linux partition\n");
+ }
+ }
+#endif
+
if (!strcmp(parts[i].name, "rootfs")) {
#ifdef CONFIG_MTD_ROOTFS_ROOT_DEV
if (ROOT_DEV == 0) {

@ -1,6 +1,6 @@
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -343,6 +343,12 @@ config MACB
@@ -358,6 +358,12 @@
source "drivers/net/arm/Kconfig"
@ -15,7 +15,7 @@
depends on ARM || MIPS || SUPERH
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -204,6 +204,7 @@ obj-$(CONFIG_SNI_82596) += sni_82596.o
@@ -213,6 +213,7 @@
obj-$(CONFIG_MVME16x_NET) += 82596.o
obj-$(CONFIG_BVME6000_NET) += 82596.o
obj-$(CONFIG_SC92031) += sc92031.o

@ -1,8 +1,8 @@
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -840,6 +840,12 @@ config TXX9_WDT
help
Hardware driver for the built-in watchdog timer on TXx9 MIPS SoCs.
@@ -930,6 +930,12 @@
To compile this driver as a loadable module, choose M here.
The module will be called bcm63xx_wdt.
+config LANTIQ_WDT
+ bool "Lantiq SoC watchdog"
@ -15,10 +15,10 @@
# POWERPC Architecture
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -112,6 +112,7 @@ obj-$(CONFIG_PNX833X_WDT) += pnx833x_wdt
obj-$(CONFIG_SIBYTE_WDOG) += sb_wdog.o
obj-$(CONFIG_AR7_WDT) += ar7_wdt.o
@@ -119,6 +119,7 @@
obj-$(CONFIG_TXX9_WDT) += txx9wdt.o
obj-$(CONFIG_OCTEON_WDT) += octeon-wdt.o
octeon-wdt-y := octeon-wdt-main.o octeon-wdt-nmi.o
+obj-$(CONFIG_LANTIQ_WDT) += lantiq_wdt.o
# PARISC Architecture
@ -167,7 +167,7 @@
+static const struct file_operations lq_wdt_fops = {
+ .owner = THIS_MODULE,
+ .write = lq_wdt_write,
+ .ioctl = lq_wdt_ioctl,
+ .unlocked_ioctl = lq_wdt_ioctl,
+ .open = lq_wdt_open,
+ .release = lq_wdt_release,
+};

@ -1,8 +1,8 @@
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -243,4 +243,75 @@
OMAP processors have SHA1/MD5 hw accelerator. Select this if you
want to use the OMAP module for SHA1/MD5 algorithms.
@@ -252,4 +252,75 @@
OMAP processors have AES module accelerator. Select this if you
want to use the OMAP module for AES algorithms.
+config CRYPTO_DEV_LANTIQ
+ tristate "Support for Lantiq crypto engine"
@ -6168,7 +6168,7 @@
+#endif /* DEU_FALCON_H */
--- a/arch/mips/lantiq/xway/devices.h
+++ b/arch/mips/lantiq/xway/devices.h
@@ -22,5 +22,6 @@
@@ -24,5 +24,6 @@
extern void __init lq_register_ethernet(struct lq_eth_data *eth);
extern void __init lq_register_asc(int port);
extern void __init lq_register_gpio_buttons(struct gpio_button *buttons, int cnt);

@ -249,7 +249,7 @@
+#endif /* CONFIG_IFX_UDP_REDIRECT* */
--- a/net/ipv4/Makefile
+++ b/net/ipv4/Makefile
@@ -14,6 +14,9 @@ obj-y := route.o inetpeer.o protocol
@@ -14,6 +14,9 @@
inet_fragment.o
obj-$(CONFIG_SYSCTL) += sysctl_net_ipv4.o
@ -261,7 +261,7 @@
obj-$(CONFIG_PROC_FS) += proc.o
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -106,6 +106,10 @@
@@ -107,6 +107,10 @@
#include <net/xfrm.h>
#include "udp_impl.h"
@ -272,7 +272,7 @@
struct udp_table udp_table __read_mostly;
EXPORT_SYMBOL(udp_table);
@@ -782,7 +786,7 @@ int udp_sendmsg(struct kiocb *iocb, stru
@@ -784,7 +788,7 @@
u8 tos;
int err, is_udplite = IS_UDPLITE(sk);
int corkreq = up->corkflag || msg->msg_flags&MSG_MORE;
@ -281,7 +281,7 @@
if (len > 0xFFFF)
return -EMSGSIZE;
@@ -944,6 +948,12 @@ back_from_confirm:
@@ -946,6 +950,12 @@
do_append_data:
up->len += ulen;
@ -294,7 +294,7 @@
getfrag = is_udplite ? udplite_getfrag : ip_generic_getfrag;
err = ip_append_data(sk, getfrag, msg->msg_iov, ulen,
sizeof(struct udphdr), &ipc, &rt,
@@ -1518,6 +1528,7 @@ int __udp4_lib_rcv(struct sk_buff *skb,
@@ -1573,6 +1583,7 @@
struct rtable *rt = skb_rtable(skb);
__be32 saddr, daddr;
struct net *net = dev_net(skb->dev);
@ -302,7 +302,7 @@
/*
* Validate the packet.
@@ -1550,7 +1561,16 @@ int __udp4_lib_rcv(struct sk_buff *skb,
@@ -1605,7 +1616,16 @@
sk = __udp4_lib_lookup_skb(skb, uh->source, uh->dest, udptable);
if (sk != NULL) {
@ -320,8 +320,8 @@
sock_put(sk);
/* a return value > 0 means to resubmit the input, but
@@ -1845,7 +1865,7 @@ struct proto udp_prot = {
#endif
@@ -1902,7 +1922,7 @@
.clear_sk = sk_prot_clear_portaddr_nulls,
};
EXPORT_SYMBOL(udp_prot);
-
@ -331,7 +331,7 @@
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -72,6 +72,12 @@ config INET
@@ -72,6 +72,12 @@
Short answer: say Y.

@ -11,7 +11,7 @@
--- a/net/atm/proc.c
+++ b/net/atm/proc.c
@@ -153,7 +153,7 @@
@@ -154,7 +154,7 @@
static void pvc_info(struct seq_file *seq, struct atm_vcc *vcc)
{
static const char *const class_name[] = {
@ -22,7 +22,7 @@
"???", "5", "???", "???", /* 4- 7 */
--- a/net/atm/common.c
+++ b/net/atm/common.c
@@ -60,11 +60,17 @@
@@ -62,11 +62,17 @@
write_unlock_irq(&vcc_sklist_lock);
}

@ -1,11 +1,12 @@
--- a/arch/mips/include/asm/mach-lantiq/machine.h
+++ b/arch/mips/include/asm/mach-lantiq/machine.h
@@ -11,4 +11,14 @@
@@ -11,4 +11,15 @@
LANTIQ_MACH_EASY4010, /* Twinpass evalkit */
LANTIQ_MACH_EASY50712, /* Danube evalkit */
LANTIQ_MACH_EASY50812, /* AR9 eval board */
+
+ /* Arcadyan */
+ LANTIQ_MACH_ARV3527P, /* Arcor easybox a401 */
+ LANTIQ_MACH_ARV4510PW, /* Wippies Homebox */
+ LANTIQ_MACH_ARV4518PW, /* Airties WAV-221, SMC-7908A-ISP */
+ LANTIQ_MACH_ARV4520PW, /* Airties WAV-281, Arcor EasyboxA800 */
@ -37,7 +38,7 @@
+obj-$(CONFIG_LANTIQ_MACH_ARV45XX) += mach-arv45xx.o
--- /dev/null
+++ b/arch/mips/lantiq/xway/mach-arv45xx.c
@@ -0,0 +1,514 @@
@@ -0,0 +1,504 @@
+/*
+ * 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
@ -73,41 +74,17 @@
+ {
+ .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 arv4518_partitions[] =
+{
+ {
+ .name = "uboot",
+ .offset = 0x0,
+ .size = 0x40000,
+ },
+ {
+ .name = "uboot_env",
+ .offset = 0x40000,
+ .offset = 0x10000,
+ .size = 0x10000,
+ },
+ {
+ .name = "linux",
+ .offset = 0x50000,
+ .size = 0x3a0000,
+ .offset = 0x20000,
+ .size = 0x3d0000,
+ },
+ {
+ .name = "board_config",
@ -121,17 +98,17 @@
+ {
+ .name = "uboot",
+ .offset = 0x0,
+ .size = 0x40000,
+ .size = 0x10000,
+ },
+ {
+ .name = "uboot_env",
+ .offset = 0x40000,
+ .offset = 0x10000,
+ .size = 0x10000,
+ },
+ {
+ .name = "linux",
+ .offset = 0x50000,
+ .size = 0x7a0000,
+ .offset = 0x20000,
+ .size = 0x7d0000,
+ },
+ {
+ .name = "board_config",
@ -149,13 +126,6 @@
+#endif
+};
+
+static struct physmap_flash_data arv4518_flash_data = {
+#ifdef CONFIG_MTD_PARTITIONS
+ .nr_parts = ARRAY_SIZE(arv4518_partitions),
+ .parts = arv4518_partitions,
+#endif
+};
+
+static struct physmap_flash_data arv75xx_flash_data = {
+#ifdef CONFIG_MTD_PARTITIONS
+ .nr_parts = ARRAY_SIZE(arv75xx_partitions),
@ -332,7 +302,7 @@
+#define ARV45XX_BRN_ATH 0x3f0478
+ int i;
+ unsigned char eeprom_mac[6];
+ u16 eeprom_data[ATH5K_PLAT_EEP_MAX_WORDS];
+ static u16 eeprom_data[ATH5K_PLAT_EEP_MAX_WORDS];
+ u32 *p = (u32*)arv45xx_ath5k_eeprom_data;
+
+ memcpy_fromio(eeprom_mac,
@ -359,6 +329,24 @@
+}
+
+static void __init
+arv3527p_init(void)
+{
+ lq_register_gpio();
+ lq_register_gpio_stp();
+ //lq_register_gpio_leds(arv3527p_leds_gpio, ARRAY_SIZE(arv3527p_leds_gpio));
+ lq_register_asc(0);
+ lq_register_asc(1);
+ lq_register_nor(&arv45xx_flash_data);
+ lq_register_wdt();
+ arv45xx_register_ethernet();
+}
+
+MIPS_MACHINE(LANTIQ_MACH_ARV3527P,
+ "ARV3527P",
+ "ARV3527P - Arcor Easybox 401",
+ arv3527p_init);
+
+static void __init
+arv4510pw_init(void)
+{
+ lq_register_gpio();
@ -367,7 +355,6 @@
+ lq_register_asc(0);
+ lq_register_asc(1);
+ lq_register_nor(&arv45xx_flash_data);
+ lq_register_pci(&lq_pci_data);
+ lq_pci_data.irq[15] = (INT_NUM_IM2_IRL0 + 31);
+ lq_pci_data.gpio |= PCI_EXIN1 | PCI_REQ2;
+ lq_register_pci(&lq_pci_data);
@ -393,10 +380,11 @@
+ lq_register_gpio_buttons(arv4518pw_gpio_buttons, ARRAY_SIZE(arv4518pw_gpio_buttons));
+ lq_register_asc(0);
+ lq_register_asc(1);
+ lq_register_nor(&arv4518_flash_data);
+ lq_register_nor(&arv45xx_flash_data);
+ lq_pci_data.gpio = PCI_GNT2 | PCI_REQ2;
+ lq_register_pci(&lq_pci_data);
+ lq_register_wdt();
+ lq_register_madwifi_eep();
+ xway_register_dwc(ARV4518PW_USB);
+ arv45xx_register_ethernet();
+ arv45xx_register_ath5k();
@ -426,6 +414,7 @@
+ lq_register_nor(&arv45xx_flash_data);
+ lq_register_pci(&lq_pci_data);
+ lq_register_wdt();
+ lq_register_tapi();
+ arv45xx_register_ethernet();
+ xway_register_dwc(ARV4520PW_USB);
+
@ -452,9 +441,10 @@
+ lq_register_gpio_leds(arv452cpw_leds_gpio, ARRAY_SIZE(arv452cpw_leds_gpio));
+ lq_register_asc(0);
+ lq_register_asc(1);
+ lq_register_nor(&arv4518_flash_data);
+ lq_register_nor(&arv45xx_flash_data);
+ lq_register_pci(&lq_pci_data);
+ lq_register_wdt();
+ lq_register_madwifi_eep();
+ xway_register_dwc(ARV452CPW_USB);
+ arv45xx_register_ethernet();
+ arv45xx_register_ath5k();
@ -488,6 +478,7 @@
+ lq_pci_data.clock = PCI_CLOCK_INT;
+ lq_register_pci(&lq_pci_data);
+ lq_register_wdt();
+ lq_register_madwifi_eep();
+ lq_eth_data.mii_mode = MII_MODE;
+ arv45xx_register_ethernet();
+}

@ -1,6 +1,6 @@
--- a/drivers/usb/Kconfig
+++ b/drivers/usb/Kconfig
@@ -111,6 +111,8 @@
@@ -113,6 +113,8 @@
source "drivers/usb/host/Kconfig"
@ -39,9 +39,9 @@
+ bool "HOST ONLY MODE"
+ depends on DWC_OTG
+
+config DWC_OTG_DEVICE_ONLY
+ bool "DEVICE ONLY MODE"
+ depends on DWC_OTG
+#config DWC_OTG_DEVICE_ONLY
+# bool "DEVICE ONLY MODE"
+# depends on DWC_OTG
+endchoice
+
+choice

@ -1,6 +1,6 @@
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -1699,6 +1699,28 @@
@@ -1837,6 +1837,28 @@ config MIPS_VPE_LOADER
Includes a loader for loading an elf relocatable object
onto another VPE and running it.
@ -110,7 +110,7 @@
/* TCStatus fields (per TC) */
#define TCSTATUS_TASID (_ULCAST_(0xff))
#define TCSTATUS_IXMT_SHIFT 10
@@ -350,6 +390,14 @@
@@ -350,6 +390,14 @@ do { \
#define write_vpe_c0_vpecontrol(val) mttc0(1, 1, val)
#define read_vpe_c0_vpeconf0() mftc0(1, 2)
#define write_vpe_c0_vpeconf0(val) mttc0(1, 2, val)
@ -125,7 +125,7 @@
#define read_vpe_c0_count() mftc0(9, 0)
#define write_vpe_c0_count(val) mttc0(9, 0, val)
#define read_vpe_c0_status() mftc0(12, 0)
@@ -381,6 +429,12 @@
@@ -381,6 +429,12 @@ do { \
#define write_tc_c0_tchalt(val) mttc0(2, 4, val)
#define read_tc_c0_tccontext() mftc0(2, 5)
#define write_tc_c0_tccontext(val) mttc0(2, 5, val)
@ -140,7 +140,7 @@
#define read_tc_gpr_sp() mftgpr(29)
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -84,7 +84,8 @@
@@ -85,7 +85,8 @@ obj-$(CONFIG_MIPS32_O32) += binfmt_elfo3
obj-$(CONFIG_KGDB) += kgdb.o
obj-$(CONFIG_PROC_FS) += proc.o
@ -152,7 +152,7 @@
obj-$(CONFIG_I8253) += i8253.o
--- a/arch/mips/kernel/mips-mt.c
+++ b/arch/mips/kernel/mips-mt.c
@@ -21,26 +21,95 @@
@@ -21,26 +21,96 @@
#include <asm/cacheflush.h>
int vpelimit;
@ -228,7 +228,8 @@
+ tlbsiz = (((config1val >> 25) & 0x3f) + 1);
+ if (tlbsiz > 64)
+ tlbsiz = 64;
+ cpu_data[0].tlbsize = current_cpu_data.tlbsize = tlbsiz;
+ cpu_data[0].tlbsize = tlbsiz;
+ current_cpu_data.tlbsize = tlbsiz;
+ }
+
+ }
@ -253,7 +254,7 @@
/*
* Dump new MIPS MT state for the core. Does not leave TCs halted.
@@ -78,18 +147,18 @@
@@ -78,18 +148,18 @@ void mips_mt_regdump(unsigned long mvpct
if ((read_tc_c0_tcbind() & TCBIND_CURVPE) == i) {
printk(" VPE %d\n", i);
printk(" VPEControl : %08lx\n",
@ -279,7 +280,7 @@
break; /* Next VPE */
}
}
@@ -287,6 +356,9 @@
@@ -287,6 +357,9 @@ void mips_mt_set_cpuoptions(void)
printk("Mapped %ld ITC cells starting at 0x%08x\n",
((itcblkgrn & 0x7fe00000) >> 20), itc_base);
}
@ -299,7 +300,7 @@
#include <asm/bootinfo.h>
#include <asm/cpu.h>
#include <asm/cpu-features.h>
@@ -108,3 +109,19 @@
@@ -108,3 +109,19 @@ const struct seq_operations cpuinfo_op =
.stop = c_stop,
.show = show_cpuinfo,
};
@ -321,7 +322,7 @@
+}
--- a/arch/mips/kernel/smtc.c
+++ b/arch/mips/kernel/smtc.c
@@ -1336,6 +1336,13 @@
@@ -1335,6 +1335,13 @@ void smtc_get_new_mmu_context(struct mm_
asid = asid_cache(cpu);
do {
@ -337,7 +338,7 @@
flush_icache_all();
--- a/arch/mips/kernel/vpe.c
+++ b/arch/mips/kernel/vpe.c
@@ -76,6 +76,58 @@
@@ -76,6 +76,58 @@ static struct kspd_notifications kspd_ev
static int kspd_events_reqd;
#endif
@ -396,7 +397,7 @@
/* grab the likely amount of memory we will need. */
#ifdef CONFIG_MIPS_VPE_LOADER_TOM
#define P_SIZE (2 * 1024 * 1024)
@@ -268,6 +320,13 @@
@@ -268,6 +320,13 @@ static void *alloc_progmem(unsigned long
void *addr;
#ifdef CONFIG_MIPS_VPE_LOADER_TOM
@ -410,7 +411,7 @@
/*
* This means you must tell Linux to use less memory than you
* physically have, for example by passing a mem= boot argument.
@@ -746,6 +805,12 @@
@@ -746,6 +805,12 @@ static int vpe_run(struct vpe * v)
}
/* Write the address we want it to start running from in the TCPC register. */
@ -423,7 +424,7 @@
write_tc_c0_tcrestart((unsigned long)v->__start);
write_tc_c0_tccontext((unsigned long)0);
@@ -759,6 +824,20 @@
@@ -759,6 +824,20 @@ static int vpe_run(struct vpe * v)
write_tc_c0_tchalt(read_tc_c0_tchalt() & ~TCHALT_H);
@ -444,7 +445,7 @@
/*
* The sde-kit passes 'memsize' to __start in $a3, so set something
* here... Or set $a3 to zero and define DFLT_STACK_SIZE and
@@ -833,6 +912,9 @@
@@ -833,6 +912,9 @@ static int find_vpe_symbols(struct vpe *
if ( (v->__start == 0) || (v->shared_ptr == NULL))
return -1;
@ -454,7 +455,7 @@
return 0;
}
@@ -994,6 +1076,15 @@
@@ -994,6 +1076,15 @@ static int vpe_elfload(struct vpe * v)
(unsigned long)v->load_addr + v->len);
if ((find_vpe_symbols(v, sechdrs, symindex, strtab, &mod)) < 0) {
@ -470,7 +471,7 @@
if (v->__start == 0) {
printk(KERN_WARNING "VPE loader: program does not contain "
"a __start symbol\n");
@@ -1064,6 +1155,9 @@
@@ -1064,6 +1155,9 @@ static int vpe_open(struct inode *inode,
struct vpe_notifications *not;
struct vpe *v;
int ret;
@ -480,7 +481,7 @@
if (minor != iminor(inode)) {
/* assume only 1 device at the moment. */
@@ -1090,14 +1184,23 @@
@@ -1090,6 +1184,12 @@ static int vpe_open(struct inode *inode,
cleanup_tc(get_tc(tclimit));
}
@ -492,11 +493,15 @@
+#else
/* this of-course trashes what was there before... */
v->pbuffer = vmalloc(P_SIZE);
if (!v->pbuffer) {
@@ -1097,11 +1197,13 @@ static int vpe_open(struct inode *inode,
return -ENOMEM;
}
v->plen = P_SIZE;
+#endif
v->load_addr = NULL;
v->len = 0;
-
+#if 0
v->uid = filp->f_cred->fsuid;
v->gid = filp->f_cred->fsgid;
@ -504,7 +509,7 @@
#ifdef CONFIG_MIPS_APSP_KSPD
/* get kspd to tell us when a syscall_exit happens */
@@ -1350,6 +1453,133 @@
@@ -1349,6 +1451,133 @@ static void kspd_sp_exit( int sp_id)
cleanup_tc(get_tc(sp_id));
}
#endif
@ -638,7 +643,7 @@
static ssize_t store_kill(struct device *dev, struct device_attribute *attr,
const char *buf, size_t len)
@@ -1431,6 +1661,18 @@
@@ -1430,6 +1659,18 @@ static int __init vpe_module_init(void)
printk("VPE loader: not a MIPS MT capable processor\n");
return -ENODEV;
}
@ -657,7 +662,7 @@
if (vpelimit == 0) {
printk(KERN_WARNING "No VPEs reserved for AP/SP, not "
@@ -1475,10 +1717,12 @@
@@ -1474,10 +1715,12 @@ static int __init vpe_module_init(void)
mtflags = dmt();
vpflags = dvpe();
@ -671,7 +676,7 @@
val = read_c0_mvpconf0();
hw_tcs = (val & MVPCONF0_PTC) + 1;
@@ -1490,6 +1734,7 @@
@@ -1489,6 +1732,7 @@ static int __init vpe_module_init(void)
* reschedule send IPIs or similar we might hang.
*/
clear_c0_mvpcontrol(MVPCONTROL_VPC);
@ -679,7 +684,7 @@
evpe(vpflags);
emt(mtflags);
local_irq_restore(flags);
@@ -1515,6 +1760,7 @@
@@ -1514,6 +1758,7 @@ static int __init vpe_module_init(void)
}
v->ntcs = hw_tcs - tclimit;
@ -687,7 +692,7 @@
/* add the tc to the list of this vpe's tc's. */
list_add(&t->tc, &v->tc);
@@ -1583,6 +1829,7 @@
@@ -1582,6 +1827,7 @@ static int __init vpe_module_init(void)
out_reenable:
/* release config state */
clear_c0_mvpcontrol(MVPCONTROL_VPC);
@ -835,7 +840,7 @@
+ * Write to perf counter registers based on text input
+ */
+
+#define TXTBUFSZ 1024
+#define TXTBUFSZ 100
+
+static int proc_write_mtsched(struct file *file, const char *buffer,
+ unsigned long count, void *data)
@ -1048,7 +1053,7 @@
+ * Write to perf counter registers based on text input
+ */
+
+#define TXTBUFSZ 1024
+#define TXTBUFSZ 100
+
+static int proc_write_perf(struct file *file, const char *buffer,
+ unsigned long count, void *data)

@ -1,6 +1,6 @@
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -1706,6 +1706,28 @@
@@ -1844,6 +1844,28 @@
help
IFX included extensions in APRP
@ -113,7 +113,7 @@
write_vpe_c0_cause(0);
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -1348,6 +1348,106 @@
@@ -1347,6 +1347,106 @@
__setup("coherentio", setcoherentio);
#endif
@ -220,7 +220,7 @@
void __cpuinit r4k_cache_init(void)
{
extern void build_clear_page(void);
@@ -1367,6 +1467,78 @@
@@ -1366,6 +1466,78 @@
break;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -0,0 +1,827 @@
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -76,5 +76,6 @@
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
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -281,6 +281,10 @@
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
--- /dev/null
+++ b/drivers/i2c/busses/i2c-falcon.c
@@ -0,0 +1,802 @@
+/*
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/* #define DEBUG */
+
+#include <linux/module.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+/* CURRENT ISSUES:
+ * - no high speed support
+ * - rx issue with "address mode" & "tx end" interrupts
+ * - ten bit mode is not tested
+ */
+
+/* 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>
+
+/* enable hacks to overcome current issue */
+#define FALCON_FIX_ME
+
+#define FALCON_I2C_ADDR 0x00
+#define FALCON_I2C_READY_TIMEOUT 1000
+#define FALCON_I2C_WAIT_TIMEOUT 10
+
+#define DRV_NAME "i2c-falcon"
+
+#if defined(DEBUG)
+#define static /* no static functions for better debugging */
+#endif
+
+#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)
+#define FALCON_I2C_BURST_REQ (1 << 6)
+#define FALCON_I2C_RX (1 << 7)
+#define FALCON_I2C_TX_END (1 << 8)
+#define FALCON_I2C_ADDR_MATCH (1 << 9) /* doesn't trigger */
+
+struct falcon_i2c {
+ spinlock_t lock;
+
+ enum {
+ FALCON_I2C_MODE_100 = 1,
+ FALCON_I2C_MODE_400 = 2,
+ FALCON_I2C_MODE_3400 = 3
+ } mode; /* current speed mode */
+
+ int ten_bit; /* current address mode */
+ unsigned long status; /* bus events holder */
+ 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 completion done;
+ struct i2c_adapter adap;
+ struct device *dev;
+};
+
+#define FALCON_I2C_ERROR_MASK (FALCON_I2C_NACK \
+ | FALCON_I2C_ARB_LOST \
+ | FALCON_I2C_RX_OFL \
+ | FALCON_I2C_RX_UFL \
+ | FALCON_I2C_TX_OFL \
+ | FALCON_I2C_TX_UFL)
+
+#define FALCON_I2C_ERROR(priv) (priv->status & FALCON_I2C_ERROR_MASK)
+#define FALCON_I2C_ERROR_CLEAR(priv) do { \
+ priv->status &= \
+ ~FALCON_I2C_ERROR_MASK; \
+ } while (0)
+
+static void falcon_addr_configure(struct falcon_i2c *priv, int ten_bit)
+{
+ u32 ten_bit_mask = ten_bit ? I2C_ADDR_CFG_TBAM_10bit : 0;
+
+ /* 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 */
+ | ten_bit_mask
+ | FALCON_I2C_ADDR, /* our address */
+ addr_cfg);
+}
+
+static irqreturn_t falcon_i2c_isr(int irq, void *dev_id)
+{
+ u32 i_raw, i_pro, i_err;
+ struct falcon_i2c *priv = dev_id;
+ unsigned long flags;
+ unsigned int old_status;
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ old_status = (unsigned int)priv->status;
+
+ i_raw = i2c_r32(mis);
+
+ /* protocol interrupt */
+ if (i_raw & I2C_RIS_I2C_P_INT_INTOCC) {
+ i_pro = i2c_r32(p_irqss);
+
+ /* tx -> rx switch */
+ if (i_pro & I2C_P_IRQSS_RX)
+ priv->status |= FALCON_I2C_RX;
+
+ /* tx end */
+ if (i_pro & I2C_P_IRQSS_TX_END)
+ priv->status |= FALCON_I2C_TX_END;
+
+ /* not acknowledge */
+ if (i_pro & I2C_P_IRQSS_NACK)
+ priv->status |= FALCON_I2C_NACK;
+
+ /* arbitration lost */
+ if (i_pro & I2C_P_IRQSS_AL)
+ priv->status |= FALCON_I2C_ARB_LOST;
+
+ /* address match */
+ if (i_pro & I2C_P_IRQSS_AM)
+ priv->status |= FALCON_I2C_ADDR_MATCH;
+
+ i2c_w32(i_pro, p_irqsc);
+ }
+
+ /* error interrupt */
+ if (i_raw & I2C_RIS_I2C_ERR_INT_INTOCC) {
+ i_err = i2c_r32(err_irqss);
+
+ /* tx fifo overflow */
+ if (i_err & I2C_ERR_IRQSS_TXF_OFL)
+ priv->status |= FALCON_I2C_TX_OFL;
+
+ /* tx fifo underflow */
+ if (i_err & I2C_ERR_IRQSS_TXF_UFL)
+ priv->status |= FALCON_I2C_TX_UFL;
+
+ /* rx fifo overflow */
+ if (i_err & I2C_ERR_IRQSS_RXF_OFL)
+ priv->status |= FALCON_I2C_RX_OFL;
+
+ /* rx fifo underflow */
+ if (i_err & I2C_ERR_IRQSS_RXF_UFL)
+ priv->status |= FALCON_I2C_RX_UFL;
+
+ i2c_w32(i_err, err_irqsc);
+ }
+
+ /* burst request */
+ if (i_raw & I2C_RIS_BREQ_INT_INTOCC) {
+ i2c_w32_mask(I2C_IMSC_BREQ_INT_EN, 0, imsc);
+ i2c_w32_mask(0, I2C_ICR_BREQ_INT_CLR, icr);
+
+ priv->status |= FALCON_I2C_BURST_REQ;
+ }
+
+ /* last burst request */
+ if (i_raw & I2C_RIS_LBREQ_INT_INTOCC) {
+ i2c_w32_mask(I2C_IMSC_LBREQ_INT_EN, 0, imsc);
+ i2c_w32_mask(0, I2C_ICR_LBREQ_INT_CLR, icr);
+
+ priv->status |= FALCON_I2C_BURST_REQ;
+ }
+
+ if (old_status != (unsigned int)priv->status)
+ complete(&priv->done);
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ return IRQ_HANDLED;
+}
+
+static int falcon_i2c_ready(struct falcon_i2c *priv)
+{
+ int timeout;
+ u32 bus_stat;
+ unsigned long flags;
+ int ret;
+
+ for (timeout = 0; timeout < FALCON_I2C_READY_TIMEOUT; timeout++) {
+ bus_stat = i2c_r32(bus_stat);
+
+ if (bus_stat & I2C_BUS_STAT_BS_SC) {
+ cpu_relax();
+ } else {
+ spin_lock_irqsave(&priv->lock, flags);
+
+ if (FALCON_I2C_ERROR(priv)) {
+ ret = priv->status;
+
+ dev_dbg(priv->dev, "bus ready wait error 0x%08lx\n", priv->status);
+
+ FALCON_I2C_ERROR_CLEAR(priv);
+ } else {
+ ret = 0;
+ }
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ return ret;
+ }
+ }
+
+ dev_dbg(priv->dev, "bus ready wait timeout\n");
+
+ return -ETIME;
+}
+
+static int falcon_i2c_wait(struct falcon_i2c *priv, unsigned long status)
+{
+ int ret = 0;
+ unsigned long flags;
+ unsigned int timeout;
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ priv->status &= FALCON_I2C_BURST_REQ;
+
+ /* check if the event already occurred */
+ if ((priv->status & status) == status) {
+ priv->status &= ~status;
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ return 0;
+ }
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ /* unmask burst interrupts */
+ i2c_w32_mask(0, I2C_IMSC_LBREQ_INT_EN | I2C_IMSC_BREQ_INT_EN, imsc);
+
+ for (timeout = 0; timeout < FALCON_I2C_WAIT_TIMEOUT; timeout++) {
+ /* wait for the data request */
+ wait_for_completion_timeout(&priv->done, HZ / 10);
+
+ /* handle errors */
+ spin_lock_irqsave(&priv->lock, flags);
+
+ if (FALCON_I2C_ERROR(priv)) {
+ dev_dbg(priv->dev, "wait error 0x%08lx (waiting for 0x%08lx)\n",
+ priv->status,
+ status);
+
+ if (priv->status & FALCON_I2C_NACK)
+ ret = -ENXIO;
+ else
+ ret = -EREMOTEIO;
+
+ FALCON_I2C_ERROR_CLEAR(priv);
+ } else {
+ if ((priv->status & status) == status) {
+ priv->status &= ~status;
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ return 0;
+ }
+ }
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ if (ret)
+ return ret;
+ }
+
+ dev_dbg(priv->dev, "wait timeout error 0x%08lx (waiting for 0x%08lx)\n",
+ priv->status,
+ status);
+
+ return -ETIME;
+}
+
+static int falcon_i2c_tx(struct falcon_i2c *priv, int ten_bit, u16 addr,
+ u8 *buf, int len)
+{
+ int i;
+ int ret;
+
+ dev_dbg(priv->dev, "%s\n", __func__);
+
+ /* tell fifo the number of bytes we are going to send */
+ i2c_w32(len + (ten_bit ? 2 : 1), tps_ctrl);
+
+ /* wait for the data request */
+ ret = falcon_i2c_wait(priv, FALCON_I2C_BURST_REQ);
+ if (ret)
+ return ret;
+
+ /* send slave address */
+ if (ten_bit) {
+ i2c_w32(0x78 | ((addr >> 7) & 0x7), txd);
+ i2c_w32(0x78 | ((addr & 0x7f) << 1) | 0, txd);
+ } else {
+ i2c_w32((addr << 1) | 0, txd);
+ }
+
+ /* fill fifo */
+ for (i = 0; i < len; i++) {
+ ret = falcon_i2c_wait(priv, FALCON_I2C_BURST_REQ);
+ if (ret)
+ return ret;
+
+ i2c_w32(buf[i], txd);
+ }
+
+ return falcon_i2c_wait(priv, FALCON_I2C_TX_END);
+}
+
+static int falcon_i2c_rx(struct falcon_i2c *priv, int ten_bit, u16 addr,
+ u8 *buf, int len)
+{
+ int i;
+ int ret;
+
+ dev_dbg(priv->dev, "%s\n", __func__);
+
+ /* we need to transmit address only */
+ i2c_w32(ten_bit ? 2 : 1, tps_ctrl);
+
+ /* set maximum received packet size */
+ i2c_w32(len, mrps_ctrl);
+
+ /* wait for the data request */
+ ret = falcon_i2c_wait(priv, FALCON_I2C_BURST_REQ);
+ if (ret)
+ return ret;
+
+ /* write down the address */
+ if (ten_bit) {
+ i2c_w32(0x78 | ((addr >> 7) & 0x7), txd);
+ i2c_w32(0x78 | ((addr & 0x7f) << 1) | 1, txd);
+ } else {
+ i2c_w32((addr << 1) | 1, txd);
+ }
+
+ /* wait for the read request */
+ ret = falcon_i2c_wait(priv, FALCON_I2C_TX_END
+#ifndef FALCON_FIX_ME
+ | FALCON_I2C_ADDR_MATCH
+#endif
+ | FALCON_I2C_RX);
+
+ if (ret)
+ return ret;
+
+ /* read bytes */
+ for (i = 0; i < len; i++) {
+#ifdef FALCON_FIX_ME
+ while (i2c_r32(rps_stat) == 0)
+ cpu_relax();
+#else
+ ret = falcon_i2c_wait(priv, FALCON_I2C_BURST_REQ);
+
+ if (ret)
+ return ret;
+#endif
+
+ buf[i] = i2c_r32(rxd);
+ }
+
+#ifndef FALCON_FIX_ME
+ /* wait for transmission end */
+ return falcon_i2c_wait(priv, FALCON_I2C_TX_END);
+#else
+ return 0;
+#endif
+}
+
+static int falcon_i2c_xfer_msg(struct falcon_i2c *priv, struct i2c_msg *msg)
+{
+ int ret;
+ int ten_bit;
+ unsigned long flags;
+
+ dev_dbg(priv->dev, "%s %u byte(s) %s 0x%02x\n",
+ (msg->flags & I2C_M_RD) ? "read" : "write", msg->len,
+ (msg->flags & I2C_M_RD) ? "from" : "to", msg->addr);
+
+ if (msg->flags & I2C_M_TEN)
+ ten_bit = 1;
+ else
+ ten_bit = 0;
+
+ /* reconfigure bus if need to send message in different address mode */
+ spin_lock_irqsave(&priv->lock, flags);
+ if (ten_bit != priv->ten_bit) {
+
+ /* disable bus */
+ i2c_w32_mask(I2C_RUN_CTRL_RUN_EN, 0, run_ctrl);
+
+ /* reconfigure address */
+ falcon_addr_configure(priv, ten_bit);
+
+ /* enable bus */
+ i2c_w32_mask(0, I2C_RUN_CTRL_RUN_EN, run_ctrl);
+
+ priv->ten_bit = ten_bit;
+ }
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ /* read/write actual message */
+ if (msg->flags & I2C_M_RD)
+ ret = falcon_i2c_rx(priv, ten_bit, msg->addr, msg->buf,
+ msg->len);
+ else
+ ret = falcon_i2c_tx(priv, ten_bit, msg->addr, msg->buf,
+ msg->len);
+
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int falcon_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msg,
+ int num)
+{
+ int i;
+ int ret;
+ unsigned long flags;
+ struct falcon_i2c *priv = i2c_get_adapdata(adap);
+
+ dev_dbg(priv->dev, "xfer %u messages\n", num);
+
+ /* transfer each message */
+ for (i = 0; i < num; i++) {
+#ifdef FALCON_FIX_ME
+ /* disable bus */
+ i2c_w32_mask(I2C_RUN_CTRL_RUN_EN, 0, run_ctrl);
+ /* enable bus */
+ i2c_w32_mask(0, I2C_RUN_CTRL_RUN_EN, run_ctrl);
+#endif
+
+ /* clear bus status */
+ spin_lock_irqsave(&priv->lock, flags);
+ priv->status = 0;
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ /* wait for the bus to become ready */
+ ret = falcon_i2c_ready(priv);
+ if (ret)
+ return ret;
+
+ /* transfer message */
+ ret = falcon_i2c_xfer_msg(priv, &msg[i]);
+
+ if (ret)
+ return ret;
+
+ /* check for unhandled errors */
+ spin_lock_irqsave(&priv->lock, flags);
+ if (FALCON_I2C_ERROR(priv))
+ ret = priv->status;
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ if (ret) {
+ dev_warn(priv->dev, "message %u unhandled error 0x%x\n",
+ i, ret);
+
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static u32 falcon_i2c_func(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_func,
+};
+
+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);
+
+ /* set normal operation clock divider */
+ i2c_w32(1 << I2C_CLC_RMC_OFFSET, clc);
+
+ /* 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_CFG_INC_OFFSET)
+ | (152 << I2C_FDIV_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 */
+ falcon_addr_configure(priv, priv->ten_bit);
+
+ /* enable bus */
+ i2c_w32_mask(0, I2C_RUN_CTRL_RUN_EN, run_ctrl);
+
+ /* mask burst interrupts */
+ i2c_w32_mask(I2C_IMSC_LBREQ_INT_EN | I2C_IMSC_BREQ_INT_EN, 0, imsc);
+
+ /* enable interrupts */
+ i2c_w32(I2C_IMSC_LBREQ_INT_EN
+ | I2C_IMSC_BREQ_INT_EN
+ | I2C_IMSC_I2C_P_INT_EN
+ | I2C_IMSC_I2C_ERR_INT_EN,
+ imsc);
+
+ return 0;
+}
+
+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->ten_bit = 0;
+ priv->mode = FALCON_I2C_MODE_100;
+ priv->clk = clk;
+ priv->dev = &pdev->dev;
+
+ spin_lock_init(&priv->lock);
+
+ 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_priv;
+ }
+
+ /* 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, 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, 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);
+
+ init_completion(&priv->done);
+
+ /* initialize HW */
+ ret = falcon_i2c_hw_init(adap);
+ if (ret) {
+ dev_err(&pdev->dev, "can't configure adapter\n");
+ goto err_remove_adapter;
+ }
+
+ 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_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);
+
+ 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)
+ printk(KERN_DEBUG DRV_NAME ": can't register platform driver");
+
+ 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:i2c_falcon");
+MODULE_LICENSE("GPL");

@ -0,0 +1,497 @@
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -22,6 +22,7 @@ obj-$(CONFIG_SPI_DESIGNWARE) += dw_spi.
obj-$(CONFIG_SPI_DW_PCI) += dw_spi_pci.o
obj-$(CONFIG_SPI_DW_MMIO) += dw_spi_mmio.o
obj-$(CONFIG_SPI_EP93XX) += ep93xx_spi.o
+obj-$(CONFIG_SPI_FALCON) += spi_falcon.o
obj-$(CONFIG_SPI_GPIO) += spi_gpio.o
obj-$(CONFIG_SPI_GPIO_OLD) += spi_gpio_old.o
obj-$(CONFIG_SPI_IMX) += spi_imx.o
--- /dev/null
+++ b/drivers/spi/spi_falcon.c
@@ -0,0 +1,471 @@
+/*
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#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.h> /* ebu_lock */
+#include <falcon/ebu_reg.h>
+#include <falcon/sys1_reg.h>
+
+#define DRV_NAME "falcon_spi"
+
+#define FALCON_SPI_XFER_BEGIN (1 << 0)
+#define FALCON_SPI_XFER_END (1 << 1)
+
+/* 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 ebu (priv->ebu_membase)
+#define sys1 (priv->sys1_membase)
+
+struct falcon_spi {
+ u32 sfcmd; /* for caching of opcode, direction, ... */
+
+ struct spi_master *master;
+
+ struct gpon_reg_ebu __iomem *ebu_membase;
+ struct gpon_reg_sys1 __iomem *sys1_membase;
+};
+
+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)
+ ebu_w32(val, 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)) {
+ ebu_w32(val, sfdata);
+ ebu_w32(priv->sfcmd
+ | (len<<SFCMD_DLEN_OFFSET),
+ 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;
+ ebu_w32(priv->sfcmd
+ |(len<<SFCMD_DLEN_OFFSET), sfcmd);
+ priv->sfcmd &= ~(SFCMD_ALEN_MASK
+ | SFCMD_DUMLEN_MASK);
+ do {
+ val = ebu_r32(sfstat);
+ if (val & SFSTAT_CMD_ERR) {
+ /* reset error status */
+ dev_err(dev, "SFSTAT: CMD_ERR "
+ "(%x)\n", val);
+ ebu_w32(SFSTAT_CMD_ERR, sfstat);
+ return -1;
+ }
+ } while (val & SFSTAT_CMD_PEND);
+ val = ebu_r32(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;
+ ebu_w32(priv->sfcmd | (0<<SFCMD_DLEN_OFFSET), sfcmd);
+ val = ebu_r32(sfstat);
+ if (val & SFSTAT_CMD_ERR) {
+ /* reset error status */
+ dev_err(dev, "SFSTAT: CMD_ERR (%x)\n", val);
+ ebu_w32(SFSTAT_CMD_ERR, 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;
+ struct falcon_spi *priv = spi_master_get_devdata(spi->master);
+ const u32 ebuclk = 100*1000*1000;
+ 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 */
+ sys1_w32_mask(0, EBUCC_EBUDIV_SELF100, ebucc);
+ i = 1; /* divider */
+ } else {
+ /* set EBU clock to 50 MHz */
+ sys1_w32_mask(EBUCC_EBUDIV_SELF100, 0, ebucc);
+
+ /* search for suitable divider */
+ for (i = 1; i < 7; i++) {
+ if (ebuclk / i <= spi->max_speed_hz)
+ break;
+ }
+ }
+
+ /* setup period of serial clock */
+ 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)),
+ sftime);
+
+ /* set some bits of unused_wd, to not trigger HOLD/WP
+ * signals on non QUAD flashes */
+ ebu_w32((SFIO_UNUSED_WD_MASK & (0x8|0x4)), sfio);
+
+ ebu_w32(BUSRCON0_AGEN_SERIAL_FLASH | BUSRCON0_PORTW_8_BIT_MUX,
+ busrcon0);
+ ebu_w32(BUSWCON0_AGEN_SERIAL_FLASH, buswcon0);
+ /* set address wrap around to maximum for 24-bit addresses */
+ ebu_w32_mask(SFCON_DEV_SIZE_MASK, SFCON_DEV_SIZE_A23_0, 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;
+ struct resource *memres_ebu, *memres_sys1;
+ int ret;
+
+ dev_dbg(dev, "probing\n");
+
+ memres_ebu = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ebu");
+ memres_sys1 = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+ "sys1");
+
+ if (!memres_ebu || !memres_sys1) {
+ dev_err(dev, "no resources\n");
+ return -ENODEV;
+ }
+
+ 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->ebu_membase = ioremap_nocache(memres_ebu->start & ~KSEG1,
+ resource_size(memres_ebu));
+
+ if (!priv->ebu_membase) {
+ dev_err(dev, "can't map ebu memory\n");
+
+ ret = -ENOMEM;
+ goto free_master;
+ }
+
+ priv->sys1_membase = ioremap_nocache(memres_sys1->start & ~KSEG1,
+ resource_size(memres_sys1));
+
+ if (!priv->sys1_membase) {
+ dev_err(dev, "can't map sys1 memory\n");
+
+ ret = -ENOMEM;
+ goto unmap_ebu;
+ }
+
+ 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)
+ goto unmap_sys1;
+
+ return 0;
+
+unmap_sys1:
+ iounmap(priv->sys1_membase);
+
+unmap_ebu:
+ iounmap(priv->ebu_membase);
+
+free_master:
+ 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);
+
+ iounmap(priv->sys1_membase);
+ iounmap(priv->ebu_membase);
+
+ 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");
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -169,6 +169,10 @@ config SPI_LM70_LLP
which interfaces to an LM70 temperature sensor using
a parallel port.
+config SPI_FALCON
+ tristate "Falcon SPI controller support"
+ depends on SOC_LANTIQ_FALCON
+
config SPI_MPC52xx
tristate "Freescale MPC52xx SPI (non-PSC) controller support"
depends on PPC_MPC52xx && SPI

@ -0,0 +1,10 @@
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -206,6 +206,7 @@ static void m25p_addr2cmd(struct m25p *f
cmd[1] = addr >> (flash->addr_width * 8 - 8);
cmd[2] = addr >> (flash->addr_width * 8 - 16);
cmd[3] = addr >> (flash->addr_width * 8 - 24);
+ cmd[4] = 0;
}
static int m25p_cmdsz(struct m25p *flash)

@ -0,0 +1,193 @@
--- a/arch/mips/lantiq/falcon/Makefile
+++ b/arch/mips/lantiq/falcon/Makefile
@@ -1,3 +1,4 @@
obj-y := clk-falcon.o devices.o gpio.o prom.o sysctrl.o reset.o
obj-y += softdog_vpe.o
obj-$(CONFIG_LANTIQ_MACH_EASY98000) += mach-easy98000.o
+obj-$(CONFIG_LANTIQ_MACH_EASY98000) += dev-leds-easy98000-cpld.o
--- /dev/null
+++ b/arch/mips/lantiq/falcon/dev-leds-easy98000-cpld.c
@@ -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 lq_r16(reg) __raw_readw(reg)
+#define lq_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)
+{
+ lq_w16(lq_r16(base) | mask, base);
+}
+
+void led_clear(u8 mask, u16 *base)
+{
+ lq_w16(lq_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 = 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");
+
--- /dev/null
+++ b/arch/mips/lantiq/falcon/dev-leds-easy98000-cpld.h
@@ -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_ */

@ -0,0 +1,120 @@
--- /dev/null
+++ b/arch/mips/lantiq/falcon/mach-easy98020.c
@@ -0,0 +1,97 @@
+#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 <machine.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
+
+extern unsigned char lq_ethaddr[6];
+
+#ifdef CONFIG_MTD_PARTITIONS
+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)
+};
+#endif
+
+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,
+#ifdef CONFIG_MTD_PARTITIONS
+ .platform_data = &easy98020_spi_flash_platform_data
+#endif
+};
+
+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,
+ }
+};
+
+static void __init easy98020_init(void)
+{
+ falcon_register_asc(0);
+ falcon_register_gpio();
+ falcon_register_wdt();
+ falcon_register_i2c();
+ falcon_register_spi_flash(&easy98020_spi_flash_data);
+ lq_add_device_leds_gpio(-1, ARRAY_SIZE(easy98020_leds_gpio),
+ easy98020_leds_gpio);
+ falcon_register_crypto();
+}
+
+MIPS_MACHINE(LANTIQ_MACH_EASY98020,
+ "EASY98020",
+ "EASY98020 Eval Board",
+ easy98020_init);
--- a/arch/mips/lantiq/falcon/Kconfig
+++ b/arch/mips/lantiq/falcon/Kconfig
@@ -6,6 +6,10 @@ config LANTIQ_MACH_EASY98000
bool "Easy98000"
default y
+config LANTIQ_MACH_EASY98020
+ bool "Easy98020"
+ default y
+
endmenu
endif
--- a/arch/mips/lantiq/falcon/Makefile
+++ b/arch/mips/lantiq/falcon/Makefile
@@ -2,3 +2,4 @@ obj-y := clk-falcon.o devices.o gpio.o p
obj-y += softdog_vpe.o
obj-$(CONFIG_LANTIQ_MACH_EASY98000) += mach-easy98000.o
obj-$(CONFIG_LANTIQ_MACH_EASY98000) += dev-leds-easy98000-cpld.o
+obj-$(CONFIG_LANTIQ_MACH_EASY98020) += mach-easy98020.o

@ -0,0 +1,136 @@
--- /dev/null
+++ b/arch/mips/lantiq/falcon/mach-95C3AM1.c
@@ -0,0 +1,103 @@
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/i2c-gpio.h>
+#include <machine.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 lq_ethaddr[6];
+
+#ifdef CONFIG_MTD_PARTITIONS
+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)
+};
+#endif
+
+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,
+#ifdef CONFIG_MTD_PARTITIONS
+ .platform_data = &board_95C3AM1_flash_platform_data
+#endif
+};
+
+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_asc(0);
+ falcon_register_gpio();
+ falcon_register_wdt();
+ falcon_register_i2c();
+ falcon_register_spi_flash(&board_95C3AM1_flash_data);
+ platform_device_register(&board_95C3AM1_i2c_gpio_device);
+ lq_add_device_leds_gpio(-1, ARRAY_SIZE(board_95C3AM1_leds_gpio),
+ board_95C3AM1_leds_gpio);
+ falcon_register_crypto();
+}
+
+MIPS_MACHINE(LANTIQ_MACH_95C3AM1,
+ "95C3AM1",
+ "95C3AM1 Board",
+ board_95C3AM1_init);
--- a/arch/mips/include/asm/mach-lantiq/machine.h
+++ b/arch/mips/include/asm/mach-lantiq/machine.h
@@ -7,6 +7,7 @@ enum lantiq_mach_type {
LANTIQ_MACH_EASY98000, /* Falcon Eval Board, NOR Flash */
LANTIQ_MACH_EASY98000SF, /* Falcon Eval Board, Serial Flash */
LANTIQ_MACH_EASY98020, /* Falcon Reference Board */
+ LANTIQ_MACH_95C3AM1, /* Board 95C3AM1 */
/* XWAY */
LANTIQ_MACH_EASY4010, /* Twinpass evalkit */
--- a/arch/mips/lantiq/falcon/Kconfig
+++ b/arch/mips/lantiq/falcon/Kconfig
@@ -10,6 +10,10 @@ config LANTIQ_MACH_EASY98020
bool "Easy98020"
default y
+config LANTIQ_MACH_95C3AM1
+ bool "95C3AM1"
+ default y
+
endmenu
endif
--- a/arch/mips/lantiq/falcon/Makefile
+++ b/arch/mips/lantiq/falcon/Makefile
@@ -3,3 +3,4 @@ obj-y += softdog_vpe.o
obj-$(CONFIG_LANTIQ_MACH_EASY98000) += mach-easy98000.o
obj-$(CONFIG_LANTIQ_MACH_EASY98000) += dev-leds-easy98000-cpld.o
obj-$(CONFIG_LANTIQ_MACH_EASY98020) += mach-easy98020.o
+obj-$(CONFIG_LANTIQ_MACH_95C3AM1) += mach-95C3AM1.o

@ -1,9 +1,9 @@
CONFIG_ADM6996_PHY=y
CONFIG_AR8216_PHY=y
# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
# CONFIG_CRYPTO_HW is not set
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y
CONFIG_HAVE_IDE=y
CONFIG_HW_HAS_PCI=y
CONFIG_IMAGE_CMDLINE_HACK=y
CONFIG_INPUT=y
CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_GPIO_BUTTONS is not set
@ -16,13 +16,7 @@ CONFIG_LANTIQ_MACH_EASY50712=y
CONFIG_LANTIQ_MACH_EASY50812=y
# CONFIG_LANTIQ_PROM_ASC0 is not set
CONFIG_LANTIQ_PROM_ASC1=y
CONFIG_LANTIQ_WDT=y
CONFIG_LEDS_GPIO=y
# CONFIG_LOONGSON_MC146818 is not set
CONFIG_LOONGSON_UART_BASE=y
CONFIG_NEED_DMA_MAP_STATE=y
CONFIG_RTL8306_PHY=y
CONFIG_SCSI_MOD=y
CONFIG_SOC_LANTIQ=y
# CONFIG_SOC_LANTIQ_FALCON is not set
CONFIG_SOC_LANTIQ_XWAY=y
CONFIG_USB_SUPPORT=y

@ -1,8 +1,32 @@
define Profile/ARV3527P
NAME:=ARV3527P - Arcor Easybox 401
PACKAGES:=kmod-ledtrig-netdev kmod-leds-gpio kmod-button-hotplug kmod-ltq-dsl-firmware-b
endef
define Profile/ARV3527P/Description
Package set optimized for the ARV3527P
endef
$(eval $(call Profile,ARV3527P))
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
endef
define Profile/ARV4510PW/Description
Package set optimized for the ARV4518PW
endef
$(eval $(call Profile,ARV4510PW))
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 ltq-dsl-firmware-a
kmod-madwifi wpad-mini kmod-ltq-dsl-firmware-a
endef
define Profile/ARV4518PW/Description
@ -15,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 ltq-dsl-firmware-a
kmod-rt61-pci wpad-mini kmod-ltq-dsl-firmware-b
endef
define Profile/ARV4520PW/Description
@ -28,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 ltq-dsl-firmware-b
kmod-madwifi wpad-mini kmod-ltq-dsl-firmware-b
endef
define Profile/ARV4525PW/Description
@ -41,7 +65,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 ltq-dsl-firmware-b
kmod-madwifi wpad-mini kmod-ltq-dsl-firmware-b
endef
define Profile/ARV452CPW/Description
@ -54,7 +78,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 \
ltq-dsl-firmware-b
kmod-ltq-dsl-firmware-b
endef
define Profile/ARV752DPW22/Description

Loading…
Cancel
Save