mirror of
git://projects.qi-hardware.com/openwrt-xburst.git
synced 2025-04-21 12:27:27 +03:00
[lantiq] adds new lantiq kernel. once the codebase is fully tested and know to be working on all the devices previously supported by ifxmips, we will drop ifxmips support.
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@24526 3c298f89-4303-0410-b956-a3cf2f4a3e73
This commit is contained in:
25
target/linux/lantiq/Makefile
Normal file
25
target/linux/lantiq/Makefile
Normal file
@@ -0,0 +1,25 @@
|
||||
#
|
||||
# Copyright (C) 2007-2010 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
ARCH:=mips
|
||||
BOARD:=lantiq
|
||||
BOARDNAME:=Lantiq GPON/XWAY
|
||||
FEATURES:=squashfs jffs2 atm
|
||||
SUBTARGETS:=xway
|
||||
|
||||
LINUX_VERSION:=2.6.35.9
|
||||
|
||||
CFLAGS=-Os -pipe -mips32r2 -mtune=mips32r2 -funit-at-a-time
|
||||
|
||||
include $(INCLUDE_DIR)/target.mk
|
||||
|
||||
define Target/Description
|
||||
Build firmware images for Lantiq SoC
|
||||
endef
|
||||
|
||||
$(eval $(call BuildTarget))
|
||||
26
target/linux/lantiq/base-files/etc/config/network
Normal file
26
target/linux/lantiq/base-files/etc/config/network
Normal file
@@ -0,0 +1,26 @@
|
||||
config interface loopback
|
||||
option ifname lo
|
||||
option proto static
|
||||
option ipaddr 127.0.0.1
|
||||
option netmask 255.0.0.0
|
||||
|
||||
config interface lan
|
||||
option ifname eth0
|
||||
option type bridge
|
||||
option proto static
|
||||
option ipaddr 192.168.1.1
|
||||
option netmask 255.255.255.0
|
||||
|
||||
config atm-bridge
|
||||
option unit 0
|
||||
option encaps llc
|
||||
option vpi 1
|
||||
option vci 32
|
||||
option payload bridged # some ISPs need this set to 'routed'
|
||||
|
||||
config interface wan
|
||||
option ifname nas0
|
||||
option proto pppoe
|
||||
option username ""
|
||||
option password ""
|
||||
option unit 0
|
||||
4
target/linux/lantiq/base-files/etc/inittab
Normal file
4
target/linux/lantiq/base-files/etc/inittab
Normal file
@@ -0,0 +1,4 @@
|
||||
::sysinit:/etc/init.d/rcS S boot
|
||||
::shutdown:/etc/init.d/rcS K stop
|
||||
ttyS0::askfirst:/bin/ash --login
|
||||
ttyS1::askfirst:/bin/ash --login
|
||||
25
target/linux/lantiq/base-files/lib/upgrade/platform.sh
Executable file
25
target/linux/lantiq/base-files/lib/upgrade/platform.sh
Executable file
@@ -0,0 +1,25 @@
|
||||
PART_NAME=linux
|
||||
|
||||
platform_check_image() {
|
||||
[ "$ARGC" -gt 1 ] && return 1
|
||||
|
||||
case "$(get_magic_word "$1")" in
|
||||
# .trx files
|
||||
2705) return 0;;
|
||||
*)
|
||||
echo "Invalid image type"
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# use default for platform_do_upgrade()
|
||||
|
||||
disable_watchdog() {
|
||||
killall watchdog
|
||||
( ps | grep -v 'grep' | grep '/dev/watchdog' ) && {
|
||||
echo 'Could not disable watchdog'
|
||||
return 1
|
||||
}
|
||||
}
|
||||
append sysupgrade_pre_upgrade disable_watchdog
|
||||
163
target/linux/lantiq/config-default
Normal file
163
target/linux/lantiq/config-default
Normal file
@@ -0,0 +1,163 @@
|
||||
# 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_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_SUPPORTS_MSI is not set
|
||||
# CONFIG_BCM47XX is not set
|
||||
# CONFIG_BCM63XX is not set
|
||||
# CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set
|
||||
# CONFIG_CAVIUM_OCTEON_SIMULATOR is not set
|
||||
# CONFIG_CPU_CAVIUM_OCTEON is not set
|
||||
# CONFIG_CPU_LITTLE_ENDIAN is not set
|
||||
# CONFIG_CPU_LOONGSON2E is not set
|
||||
# CONFIG_CPU_LOONGSON2F is not set
|
||||
# CONFIG_CPU_MIPS32_R1 is not set
|
||||
# CONFIG_CPU_MIPS64_R1 is not set
|
||||
# CONFIG_CPU_MIPS64_R2 is not set
|
||||
# CONFIG_CPU_NEVADA is not set
|
||||
# CONFIG_CPU_R10000 is not set
|
||||
# CONFIG_CPU_R3000 is not set
|
||||
# CONFIG_CPU_R4300 is not set
|
||||
# CONFIG_CPU_R4X00 is not set
|
||||
# CONFIG_CPU_R5000 is not set
|
||||
# CONFIG_CPU_R5432 is not set
|
||||
# CONFIG_CPU_R5500 is not set
|
||||
# CONFIG_CPU_R6000 is not set
|
||||
# CONFIG_CPU_R8000 is not set
|
||||
# CONFIG_CPU_RM7000 is not set
|
||||
# CONFIG_CPU_RM9000 is not set
|
||||
# CONFIG_CPU_SB1 is not set
|
||||
# CONFIG_CPU_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_DMA_NEED_PCI_MAP_STATE=y
|
||||
CONFIG_DMA_NONCOHERENT=y
|
||||
CONFIG_EARLY_PRINTK=y
|
||||
CONFIG_GENERIC_CLOCKEVENTS=y
|
||||
CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
|
||||
CONFIG_GENERIC_CMOS_UPDATE=y
|
||||
CONFIG_GENERIC_FIND_LAST_BIT=y
|
||||
CONFIG_GENERIC_FIND_NEXT_BIT=y
|
||||
CONFIG_GENERIC_GPIO=y
|
||||
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
|
||||
CONFIG_GPIOLIB=y
|
||||
CONFIG_GPIO_SYSFS=y
|
||||
CONFIG_HARDWARE_WATCHPOINTS=y
|
||||
CONFIG_HAS_DMA=y
|
||||
CONFIG_HAS_IOMEM=y
|
||||
CONFIG_HAS_IOPORT=y
|
||||
CONFIG_HAVE_ARCH_KGDB=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_OPROFILE=y
|
||||
CONFIG_HW_RANDOM=y
|
||||
CONFIG_HZ=250
|
||||
CONFIG_HZ_250=y
|
||||
CONFIG_INITRAMFS_SOURCE=""
|
||||
CONFIG_IRQ_CPU=y
|
||||
CONFIG_LANTIQ=y
|
||||
CONFIG_MIPS=y
|
||||
CONFIG_MIPS_L1_CACHE_SHIFT=5
|
||||
CONFIG_MIPS_MACHINE=y
|
||||
CONFIG_MIPS_MT_DISABLED=y
|
||||
CONFIG_MTD_CFI_ADV_OPTIONS=y
|
||||
CONFIG_MTD_CFI_GEOMETRY=y
|
||||
CONFIG_MTD_CMDLINE_PARTS=y
|
||||
CONFIG_MTD_LANTIQ=y
|
||||
CONFIG_NLS=y
|
||||
CONFIG_PAGEFLAGS_EXTENDED=y
|
||||
CONFIG_PCI=y
|
||||
CONFIG_PCI_DOMAINS=y
|
||||
CONFIG_PHYLIB=y
|
||||
CONFIG_SCHED_OMIT_FRAME_POINTER=y
|
||||
CONFIG_SERIAL_LANTIQ=y
|
||||
CONFIG_SWAP_IO_SPACE=y
|
||||
CONFIG_SWCONFIG=y
|
||||
CONFIG_SYS_HAS_CPU_MIPS32_R1=y
|
||||
CONFIG_SYS_HAS_CPU_MIPS32_R2=y
|
||||
CONFIG_SYS_HAS_EARLY_PRINTK=y
|
||||
CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
|
||||
CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
|
||||
CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
|
||||
CONFIG_SYS_SUPPORTS_MULTITHREADING=y
|
||||
CONFIG_TRAD_SIGNALS=y
|
||||
CONFIG_TREE_RCU=y
|
||||
CONFIG_ZONE_DMA_FLAG=0
|
||||
CONFIG_IFX_UDP_REDIRECT=y
|
||||
89
target/linux/lantiq/image/Makefile
Normal file
89
target/linux/lantiq/image/Makefile
Normal file
@@ -0,0 +1,89 @@
|
||||
#
|
||||
# Copyright (C) 2010 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
include $(TOPDIR)/rules.mk
|
||||
include $(INCLUDE_DIR)/image.mk
|
||||
|
||||
JFFS2_BLOCKSIZE = 64k 128k 256k
|
||||
|
||||
xway_cmdline=-console=ttyS1,115200 rootfstype=squashfs,jffs2
|
||||
falcon_cmdline=-console=ttyS0,115200 rootfstype=squashfs,jffs2
|
||||
|
||||
define CompressLzma
|
||||
$(STAGING_DIR_HOST)/bin/lzma e $(1) $(2)
|
||||
endef
|
||||
|
||||
define PatchKernelLzma
|
||||
cp $(KDIR)/vmlinux $(KDIR)/vmlinux-$(1)
|
||||
$(STAGING_DIR_HOST)/bin/patch-cmdline $(KDIR)/vmlinux-$(1) '$(strip $(2))'
|
||||
$(call CompressLzma,$(KDIR)/vmlinux-$(1),$(KDIR)/vmlinux-$(1).lzma)
|
||||
endef
|
||||
|
||||
define MkImageLzma
|
||||
mkimage -A mips -O linux -T kernel -a 0x80002000 -C lzma \
|
||||
-e 0x80002000 -n 'MIPS OpenWrt Linux-$(LINUX_VERSION)' \
|
||||
-d $(KDIR)/vmlinux-$(1).lzma $(KDIR)/uImage-$(1)
|
||||
endef
|
||||
|
||||
define Image/Build/squashfs
|
||||
cat $(KDIR)/uImage-$(2) $(KDIR)/root.$(1) > $(BIN_DIR)/$(IMG_PREFIX)-$(2)-$(1).image
|
||||
$(call prepare_generic_squashfs,$(BIN_DIR)/$(IMG_PREFIX)-$(2)-$(1).image)
|
||||
endef
|
||||
|
||||
define Image/Build/jffs2-64k
|
||||
dd if=$(KDIR)/uImage-$(2) of=$(KDIR)/uImage-$(2)-$(1) bs=64k conv=sync
|
||||
cat $(KDIR)/uImage-$(2)-$(1) $(KDIR)/root.$(1) > $(BIN_DIR)/$(IMG_PREFIX)-$(2)-$(1).image
|
||||
endef
|
||||
|
||||
define Image/Build/jffs2-128k
|
||||
dd if=$(KDIR)/uImage-$(2) of=$(KDIR)/uImage-$(2)-$(1) bs=128k conv=sync
|
||||
cat $(KDIR)/uImage-$(2)-$(1) $(KDIR)/root.$(1) > $(BIN_DIR)/$(IMG_PREFIX)-$(2)-$(1).image
|
||||
endef
|
||||
|
||||
define Image/Build/jffs2-256k
|
||||
dd if=$(KDIR)/uImage-$(2) of=$(KDIR)/uImage-$(2)-$(1) bs=256k conv=sync
|
||||
cat $(KDIR)/uImage-$(2)-$(1) $(KDIR)/root.$(1) > $(BIN_DIR)/$(IMG_PREFIX)-$(2)-$(1).image
|
||||
endef
|
||||
|
||||
define Image/BuildKernel/Template
|
||||
$(call PatchKernelLzma,$(1),$(if $(2),$(2) machtype=$(1),))
|
||||
$(call MkImageLzma,$(1))
|
||||
$(CP) $(KDIR)/uImage-$(1) $(BIN_DIR)/$(IMG_PREFIX)-$(1)-uImage
|
||||
endef
|
||||
|
||||
ifeq ($(CONFIG_SOC_LANTIQ_XWAY),y)
|
||||
define Image/BuildKernel
|
||||
$(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,ARV452,$(xway_cmdline))
|
||||
$(call Image/BuildKernel/Template,NONE)
|
||||
endef
|
||||
|
||||
define Image/Build
|
||||
$(call Image/Build/$(1),$(1),EASY4010)
|
||||
$(call Image/Build/$(1),$(1),EASY50712)
|
||||
$(call Image/Build/$(1),$(1),EASY50812)
|
||||
$(call Image/Build/$(1),$(1),ARV452)
|
||||
$(call Image/Build/$(1),$(1),NONE)
|
||||
$(CP) $(KDIR)/root.$(1) $(BIN_DIR)/$(IMG_PREFIX)-$(1).rootfs
|
||||
endef
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_SOC_LANTIQ_FALCON),y)
|
||||
define Image/BuildKernel
|
||||
$(call Image/BuildKernel/Template,EASY98000,$(falcon_cmdline))
|
||||
$(call Image/BuildKernel/Template,NONE)
|
||||
endef
|
||||
|
||||
define Image/Build
|
||||
$(call Image/Build/$(1),$(1),EASY98000)
|
||||
$(call Image/Build/$(1),$(1),NONE)
|
||||
$(CP) $(KDIR)/root.$(1) $(BIN_DIR)/$(IMG_PREFIX)-$(1).rootfs
|
||||
endef
|
||||
endif
|
||||
|
||||
$(eval $(call BuildImage))
|
||||
47
target/linux/lantiq/modules.mk
Normal file
47
target/linux/lantiq/modules.mk
Normal file
@@ -0,0 +1,47 @@
|
||||
#
|
||||
# Copyright (C) 2010 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
define KernelPackage/lantiq-deu
|
||||
TITLE:=Lantiq data encryption unit
|
||||
SUBMENU:=$(CRYPTO_MENU)
|
||||
DEPENDS:=@TARGET_lantiq
|
||||
KCONFIG:=CONFIG_CRYPTO_DEV_LANTIQ \
|
||||
CONFIG_CRYPTO_HW=y \
|
||||
CONFIG_CRYPTO_DEV_LANTIQ_AES=y \
|
||||
CONFIG_CRYPTO_DEV_LANTIQ_DES=y \
|
||||
CONFIG_CRYPTO_DEV_LANTIQ_MD5=y \
|
||||
CONFIG_CRYPTO_DEV_LANTIQ_SHA1=y
|
||||
$(call AddDepends/crypto)
|
||||
endef
|
||||
|
||||
define KernelPackage/lantiq-deu/description
|
||||
Kernel support for the Lantiq crypto HW
|
||||
endef
|
||||
|
||||
$(eval $(call KernelPackage,lantiq-deu))
|
||||
|
||||
USB_MENU:=USB Support
|
||||
|
||||
define KernelPackage/usb-dwc-otg
|
||||
TITLE:=Synopsis DWC_OTG support
|
||||
SUBMENU:=$(USB_MENU)
|
||||
DEPENDS+=@TARGET_lantiq_xway +kmod-usb-core
|
||||
KCONFIG:=CONFIG_DWC_OTG \
|
||||
CONFIG_DWC_OTG_DEBUG=n \
|
||||
CONFIG_DWC_OTG_LANTIQ=y \
|
||||
CONFIG_DWC_OTG_HOST_ONLY=y
|
||||
FILES:=$(LINUX_DIR)/drivers/usb/dwc_otg/dwc_otg.ko
|
||||
AUTOLOAD:=$(call AutoLoad,50,dwc_otg)
|
||||
endef
|
||||
|
||||
define KernelPackage/usb-dwc-otg/description
|
||||
Kernel support for Synopsis USB on XWAY
|
||||
endef
|
||||
|
||||
$(eval $(call KernelPackage,usb-dwc-otg))
|
||||
|
||||
|
||||
35
target/linux/lantiq/patches/000-mips-bad-intctl.patch
Normal file
35
target/linux/lantiq/patches/000-mips-bad-intctl.patch
Normal file
@@ -0,0 +1,35 @@
|
||||
--- a/arch/mips/kernel/traps.c
|
||||
+++ b/arch/mips/kernel/traps.c
|
||||
@@ -1496,7 +1496,18 @@ void __cpuinit per_cpu_trap_init(void)
|
||||
if (cpu_has_mips_r2) {
|
||||
cp0_compare_irq_shift = CAUSEB_TI - CAUSEB_IP;
|
||||
cp0_compare_irq = (read_c0_intctl() >> INTCTLB_IPTI) & 7;
|
||||
+
|
||||
+ if (!cp0_compare_irq)
|
||||
+ cp0_compare_irq = CP0_LEGACY_COMPARE_IRQ;
|
||||
+
|
||||
cp0_perfcount_irq = (read_c0_intctl() >> INTCTLB_IPPCI) & 7;
|
||||
+
|
||||
+ if (!cp0_perfcount_irq)
|
||||
+ cp0_perfcount_irq = CP0_LEGACY_PERFCNT_IRQ;
|
||||
+
|
||||
+ if (arch_fixup_c0_irqs)
|
||||
+ arch_fixup_c0_irqs();
|
||||
+
|
||||
if (cp0_perfcount_irq == cp0_compare_irq)
|
||||
cp0_perfcount_irq = -1;
|
||||
} else {
|
||||
--- a/arch/mips/include/asm/irq.h
|
||||
+++ b/arch/mips/include/asm/irq.h
|
||||
@@ -133,9 +133,11 @@ extern void free_irqno(unsigned int irq)
|
||||
* IE7. Since R2 their number has to be read from the c0_intctl register.
|
||||
*/
|
||||
#define CP0_LEGACY_COMPARE_IRQ 7
|
||||
+#define CP0_LEGACY_PERFCNT_IRQ 7
|
||||
|
||||
extern int cp0_compare_irq;
|
||||
extern int cp0_compare_irq_shift;
|
||||
extern int cp0_perfcount_irq;
|
||||
+extern void __weak arch_fixup_c0_irqs(void);
|
||||
|
||||
#endif /* _ASM_IRQ_H */
|
||||
@@ -0,0 +1,33 @@
|
||||
--- a/arch/mips/kernel/cevt-r4k.c
|
||||
+++ b/arch/mips/kernel/cevt-r4k.c
|
||||
@@ -22,6 +22,22 @@
|
||||
|
||||
#ifndef CONFIG_MIPS_MT_SMTC
|
||||
|
||||
+/*
|
||||
+ * Compare interrupt can be routed and latched outside the core,
|
||||
+ * so a single execution hazard barrier may not be enough to give
|
||||
+ * it time to clear as seen in the Cause register. 4 time the
|
||||
+ * pipeline depth seems reasonably conservative, and empirically
|
||||
+ * works better in configurations with high CPU/bus clock ratios.
|
||||
+ */
|
||||
+
|
||||
+#define compare_change_hazard() \
|
||||
+ do { \
|
||||
+ irq_disable_hazard(); \
|
||||
+ irq_disable_hazard(); \
|
||||
+ irq_disable_hazard(); \
|
||||
+ irq_disable_hazard(); \
|
||||
+ } while (0)
|
||||
+
|
||||
static int mips_next_event(unsigned long delta,
|
||||
struct clock_event_device *evt)
|
||||
{
|
||||
@@ -31,6 +47,7 @@ static int mips_next_event(unsigned long
|
||||
cnt = read_c0_count();
|
||||
cnt += delta;
|
||||
write_c0_compare(cnt);
|
||||
+ compare_change_hazard();
|
||||
res = ((int)(read_c0_count() - cnt) > 0) ? -ETIME : 0;
|
||||
return res;
|
||||
}
|
||||
12
target/linux/lantiq/patches/020-genirq_fix.patch
Normal file
12
target/linux/lantiq/patches/020-genirq_fix.patch
Normal file
@@ -0,0 +1,12 @@
|
||||
--- a/kernel/irq/chip.c
|
||||
+++ b/kernel/irq/chip.c
|
||||
@@ -650,6 +650,9 @@ handle_percpu_irq(unsigned int irq, stru
|
||||
|
||||
kstat_incr_irqs_this_cpu(irq, desc);
|
||||
|
||||
+ if (unlikely(!desc->action || (desc->status & IRQ_DISABLED)))
|
||||
+ return;
|
||||
+
|
||||
if (desc->chip->ack)
|
||||
desc->chip->ack(irq);
|
||||
|
||||
641
target/linux/lantiq/patches/100-board.patch
Normal file
641
target/linux/lantiq/patches/100-board.patch
Normal file
@@ -0,0 +1,641 @@
|
||||
--- a/arch/mips/Kconfig
|
||||
+++ b/arch/mips/Kconfig
|
||||
@@ -139,6 +139,9 @@ config MACH_DECSTATION
|
||||
|
||||
otherwise choose R3000.
|
||||
|
||||
+config LANTIQ
|
||||
+ bool "Lantiq MIPS"
|
||||
+
|
||||
config MACH_JAZZ
|
||||
bool "Jazz family of machines"
|
||||
select ARC
|
||||
@@ -693,6 +696,7 @@ source "arch/mips/txx9/Kconfig"
|
||||
source "arch/mips/vr41xx/Kconfig"
|
||||
source "arch/mips/cavium-octeon/Kconfig"
|
||||
source "arch/mips/loongson/Kconfig"
|
||||
+source "arch/mips/lantiq/Kconfig"
|
||||
|
||||
endmenu
|
||||
|
||||
--- a/arch/mips/Makefile
|
||||
+++ b/arch/mips/Makefile
|
||||
@@ -317,6 +317,17 @@ cflags-$(CONFIG_MIPS_COBALT) += -I$(srct
|
||||
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 @@
|
||||
+if LANTIQ
|
||||
+
|
||||
+config SOC_LANTIQ
|
||||
+ bool
|
||||
+ select DMA_NONCOHERENT
|
||||
+ select IRQ_CPU
|
||||
+ select CEVT_R4K
|
||||
+ select CSRC_R4K
|
||||
+ select SYS_HAS_CPU_MIPS32_R1
|
||||
+ select SYS_HAS_CPU_MIPS32_R2
|
||||
+ select SYS_SUPPORTS_BIG_ENDIAN
|
||||
+ select SYS_SUPPORTS_32BIT_KERNEL
|
||||
+ select SYS_SUPPORTS_MULTITHREADING
|
||||
+ select SYS_HAS_EARLY_PRINTK
|
||||
+ select HW_HAS_PCI
|
||||
+ select ARCH_REQUIRE_GPIOLIB
|
||||
+ select SWAP_IO_SPACE
|
||||
+ select MIPS_MACHINE
|
||||
+
|
||||
+choice
|
||||
+ prompt "SoC Type"
|
||||
+ default SOC_LANTIQ_XWAY
|
||||
+
|
||||
+#config SOC_LANTIQ_FALCON
|
||||
+# bool "FALCON"
|
||||
+# select SOC_LANTIQ
|
||||
+
|
||||
+config SOC_LANTIQ_XWAY
|
||||
+ bool "XWAY"
|
||||
+ select SOC_LANTIQ
|
||||
+endchoice
|
||||
+
|
||||
+#source "arch/mips/lantiq/falcon/Kconfig"
|
||||
+source "arch/mips/lantiq/xway/Kconfig"
|
||||
+
|
||||
+endif
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/Makefile
|
||||
@@ -0,0 +1,2 @@
|
||||
+obj-y := irq.o setup.o clk.o prom.o
|
||||
+obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/irq.c
|
||||
@@ -0,0 +1,212 @@
|
||||
+/*
|
||||
+ * This program is free software; you can redistribute it and/or modify it
|
||||
+ * under the terms of the GNU General Public License version 2 as published
|
||||
+ * by the Free Software Foundation.
|
||||
+ *
|
||||
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
|
||||
+ */
|
||||
+
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/interrupt.h>
|
||||
+
|
||||
+#include <asm/bootinfo.h>
|
||||
+#include <asm/irq_cpu.h>
|
||||
+
|
||||
+#include <lantiq.h>
|
||||
+#include <irq.h>
|
||||
+
|
||||
+#define LQ_ICU_BASE_ADDR (KSEG1 | 0x1F880200)
|
||||
+
|
||||
+#define LQ_ICU_IM0_ISR ((u32 *)(LQ_ICU_BASE_ADDR + 0x0000))
|
||||
+#define LQ_ICU_IM0_IER ((u32 *)(LQ_ICU_BASE_ADDR + 0x0008))
|
||||
+#define LQ_ICU_IM0_IOSR ((u32 *)(LQ_ICU_BASE_ADDR + 0x0010))
|
||||
+#define LQ_ICU_IM0_IRSR ((u32 *)(LQ_ICU_BASE_ADDR + 0x0018))
|
||||
+#define LQ_ICU_IM0_IMR ((u32 *)(LQ_ICU_BASE_ADDR + 0x0020))
|
||||
+
|
||||
+#define LQ_ICU_IM1_ISR ((u32 *)(LQ_ICU_BASE_ADDR + 0x0028))
|
||||
+#define LQ_ICU_IM2_ISR ((u32 *)(LQ_ICU_BASE_ADDR + 0x0050))
|
||||
+#define LQ_ICU_IM3_ISR ((u32 *)(LQ_ICU_BASE_ADDR + 0x0078))
|
||||
+#define LQ_ICU_IM4_ISR ((u32 *)(LQ_ICU_BASE_ADDR + 0x00A0))
|
||||
+
|
||||
+#define LQ_ICU_OFFSET (LQ_ICU_IM1_ISR - LQ_ICU_IM0_ISR)
|
||||
+
|
||||
+void
|
||||
+lq_disable_irq(unsigned int irq_nr)
|
||||
+{
|
||||
+ u32 *ier = LQ_ICU_IM0_IER;
|
||||
+ irq_nr -= INT_NUM_IRQ0;
|
||||
+ ier += LQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET);
|
||||
+ irq_nr %= INT_NUM_IM_OFFSET;
|
||||
+ lq_w32(lq_r32(ier) & ~(1 << irq_nr), ier);
|
||||
+}
|
||||
+EXPORT_SYMBOL(lq_disable_irq);
|
||||
+
|
||||
+void
|
||||
+lq_mask_and_ack_irq(unsigned int irq_nr)
|
||||
+{
|
||||
+ u32 *ier = LQ_ICU_IM0_IER;
|
||||
+ u32 *isr = LQ_ICU_IM0_ISR;
|
||||
+ irq_nr -= INT_NUM_IRQ0;
|
||||
+ ier += LQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET);
|
||||
+ isr += LQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET);
|
||||
+ irq_nr %= INT_NUM_IM_OFFSET;
|
||||
+ lq_w32(lq_r32(ier) & ~(1 << irq_nr), ier);
|
||||
+ lq_w32((1 << irq_nr), isr);
|
||||
+}
|
||||
+EXPORT_SYMBOL(lq_mask_and_ack_irq);
|
||||
+
|
||||
+static void
|
||||
+lq_ack_irq(unsigned int irq_nr)
|
||||
+{
|
||||
+ u32 *isr = LQ_ICU_IM0_ISR;
|
||||
+ irq_nr -= INT_NUM_IRQ0;
|
||||
+ isr += LQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET);
|
||||
+ irq_nr %= INT_NUM_IM_OFFSET;
|
||||
+ lq_w32((1 << irq_nr), isr);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+lq_enable_irq(unsigned int irq_nr)
|
||||
+{
|
||||
+ u32 *ier = LQ_ICU_IM0_IER;
|
||||
+ irq_nr -= INT_NUM_IRQ0;
|
||||
+ ier += LQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET);
|
||||
+ irq_nr %= INT_NUM_IM_OFFSET;
|
||||
+ lq_w32(lq_r32(ier) | (1 << irq_nr), ier);
|
||||
+}
|
||||
+EXPORT_SYMBOL(lq_enable_irq);
|
||||
+
|
||||
+static unsigned int
|
||||
+lq_startup_irq(unsigned int irq)
|
||||
+{
|
||||
+ lq_enable_irq(irq);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+lq_end_irq(unsigned int irq)
|
||||
+{
|
||||
+ if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
|
||||
+ lq_enable_irq(irq);
|
||||
+}
|
||||
+
|
||||
+static struct irq_chip
|
||||
+lq_irq_type = {
|
||||
+ "lq_irq",
|
||||
+ .startup = lq_startup_irq,
|
||||
+ .enable = lq_enable_irq,
|
||||
+ .disable = lq_disable_irq,
|
||||
+ .unmask = lq_enable_irq,
|
||||
+ .ack = lq_ack_irq,
|
||||
+ .mask = lq_disable_irq,
|
||||
+ .mask_ack = lq_mask_and_ack_irq,
|
||||
+ .end = lq_end_irq,
|
||||
+};
|
||||
+
|
||||
+static void
|
||||
+lq_hw_irqdispatch(int module)
|
||||
+{
|
||||
+ u32 irq;
|
||||
+
|
||||
+ irq = lq_r32(LQ_ICU_IM0_IOSR + (module * LQ_ICU_OFFSET));
|
||||
+ if (irq == 0)
|
||||
+ return;
|
||||
+
|
||||
+ /* silicon bug causes only the msb set to 1 to be valid. all
|
||||
+ other bits might be bogus */
|
||||
+ irq = __fls(irq);
|
||||
+ do_IRQ((int)irq + INT_NUM_IM0_IRL0 + (INT_NUM_IM_OFFSET * module));
|
||||
+}
|
||||
+
|
||||
+#define DEFINE_HWx_IRQDISPATCH(x) \
|
||||
+static void lq_hw ## x ## _irqdispatch(void)\
|
||||
+{\
|
||||
+ lq_hw_irqdispatch(x); \
|
||||
+}
|
||||
+static void lq_hw5_irqdispatch(void)
|
||||
+{
|
||||
+ do_IRQ(MIPS_CPU_TIMER_IRQ);
|
||||
+}
|
||||
+DEFINE_HWx_IRQDISPATCH(0)
|
||||
+DEFINE_HWx_IRQDISPATCH(1)
|
||||
+DEFINE_HWx_IRQDISPATCH(2)
|
||||
+DEFINE_HWx_IRQDISPATCH(3)
|
||||
+DEFINE_HWx_IRQDISPATCH(4)
|
||||
+/*DEFINE_HWx_IRQDISPATCH(5)*/
|
||||
+
|
||||
+asmlinkage void
|
||||
+plat_irq_dispatch(void)
|
||||
+{
|
||||
+ unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
|
||||
+ unsigned int i;
|
||||
+
|
||||
+ if (pending & CAUSEF_IP7)
|
||||
+ {
|
||||
+ do_IRQ(MIPS_CPU_TIMER_IRQ);
|
||||
+ goto out;
|
||||
+ } else {
|
||||
+ for (i = 0; i < 5; i++)
|
||||
+ {
|
||||
+ if (pending & (CAUSEF_IP2 << i))
|
||||
+ {
|
||||
+ lq_hw_irqdispatch(i);
|
||||
+ goto out;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ printk(KERN_ALERT "Spurious IRQ: CAUSE=0x%08x\n", read_c0_status());
|
||||
+
|
||||
+out:
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+static struct irqaction
|
||||
+cascade = {
|
||||
+ .handler = no_action,
|
||||
+ .flags = IRQF_DISABLED,
|
||||
+ .name = "cascade",
|
||||
+};
|
||||
+
|
||||
+void __init
|
||||
+arch_init_irq(void)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < 5; i++)
|
||||
+ lq_w32(0, LQ_ICU_IM0_IER + (i * LQ_ICU_OFFSET));
|
||||
+
|
||||
+ mips_cpu_irq_init();
|
||||
+
|
||||
+ for (i = 2; i <= 6; i++)
|
||||
+ setup_irq(i, &cascade);
|
||||
+
|
||||
+ if (cpu_has_vint) {
|
||||
+ printk(KERN_INFO "Setting up vectored interrupts\n");
|
||||
+ set_vi_handler(2, lq_hw0_irqdispatch);
|
||||
+ set_vi_handler(3, lq_hw1_irqdispatch);
|
||||
+ set_vi_handler(4, lq_hw2_irqdispatch);
|
||||
+ set_vi_handler(5, lq_hw3_irqdispatch);
|
||||
+ set_vi_handler(6, lq_hw4_irqdispatch);
|
||||
+ set_vi_handler(7, lq_hw5_irqdispatch);
|
||||
+ }
|
||||
+
|
||||
+ for (i = INT_NUM_IRQ0; i <= (INT_NUM_IRQ0 + (5 * INT_NUM_IM_OFFSET)); i++)
|
||||
+ set_irq_chip_and_handler(i, &lq_irq_type,
|
||||
+ handle_level_irq);
|
||||
+
|
||||
+ #if !defined(CONFIG_MIPS_MT_SMP) && !defined(CONFIG_MIPS_MT_SMTC)
|
||||
+ set_c0_status(IE_IRQ0 | IE_IRQ1 | IE_IRQ2 |
|
||||
+ IE_IRQ3 | IE_IRQ4 | IE_IRQ5);
|
||||
+ #else
|
||||
+ set_c0_status(IE_SW0 | IE_SW1 | IE_IRQ0 | IE_IRQ1 |
|
||||
+ IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5);
|
||||
+ #endif
|
||||
+}
|
||||
+
|
||||
+void __cpuinit
|
||||
+arch_fixup_c0_irqs(void)
|
||||
+{
|
||||
+ /* FIXME: check for CPUID and only do fix for specific chips/versions */
|
||||
+ cp0_compare_irq = CP0_LEGACY_COMPARE_IRQ;
|
||||
+ cp0_perfcount_irq = CP0_LEGACY_PERFCNT_IRQ;
|
||||
+}
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/setup.c
|
||||
@@ -0,0 +1,47 @@
|
||||
+/*
|
||||
+ * This program is free software; you can redistribute it and/or modify it
|
||||
+ * under the terms of the GNU General Public License version 2 as published
|
||||
+ * by the Free Software Foundation.
|
||||
+ *
|
||||
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
|
||||
+ */
|
||||
+
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/ioport.h>
|
||||
+
|
||||
+#include <lantiq.h>
|
||||
+#include <lantiq_regs.h>
|
||||
+
|
||||
+void __init
|
||||
+plat_mem_setup(void)
|
||||
+{
|
||||
+ /* assume 16M as default */
|
||||
+ int memsize = 16;
|
||||
+ char **envp = (char **) KSEG1ADDR(fw_arg2);
|
||||
+ u32 status;
|
||||
+
|
||||
+ /* make sure to have no "reverse endian" for user mode! */
|
||||
+ status = read_c0_status();
|
||||
+ status &= (~(1<<25));
|
||||
+ write_c0_status(status);
|
||||
+
|
||||
+ ioport_resource.start = IOPORT_RESOURCE_START;
|
||||
+ ioport_resource.end = IOPORT_RESOURCE_END;
|
||||
+ iomem_resource.start = IOMEM_RESOURCE_START;
|
||||
+ iomem_resource.end = IOMEM_RESOURCE_END;
|
||||
+
|
||||
+ while (*envp)
|
||||
+ {
|
||||
+ char *e = (char *)KSEG1ADDR(*envp);
|
||||
+ if (!strncmp(e, "memsize=", 8))
|
||||
+ {
|
||||
+ e += 8;
|
||||
+ memsize = simple_strtoul(e, NULL, 10);
|
||||
+ }
|
||||
+ envp++;
|
||||
+ }
|
||||
+ memsize *= 1024 * 1024;
|
||||
+ add_memory_region(0x00000000, memsize, BOOT_MEM_RAM);
|
||||
+}
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/clk.c
|
||||
@@ -0,0 +1,141 @@
|
||||
+/*
|
||||
+ * This program is free software; you can redistribute it and/or modify it
|
||||
+ * under the terms of the GNU General Public License version 2 as published
|
||||
+ * by the Free Software Foundation.
|
||||
+ *
|
||||
+ * Copyright (C) 2010 Thomas Langer, Lantiq Deutschland
|
||||
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
|
||||
+ */
|
||||
+
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/types.h>
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/err.h>
|
||||
+#include <linux/list.h>
|
||||
+
|
||||
+#include <asm/time.h>
|
||||
+#include <asm/irq.h>
|
||||
+#include <asm/div64.h>
|
||||
+
|
||||
+#include <lantiq.h>
|
||||
+#ifdef CONFIG_SOC_LANTIQ_XWAY
|
||||
+#include <xway.h>
|
||||
+#endif
|
||||
+
|
||||
+extern unsigned long lq_get_cpu_hz(void);
|
||||
+extern unsigned long lq_get_fpi_hz(void);
|
||||
+extern unsigned long lq_get_io_region_clock(void);
|
||||
+
|
||||
+struct clk {
|
||||
+ const char *name;
|
||||
+ unsigned long rate;
|
||||
+ unsigned long (*get_rate) (void);
|
||||
+};
|
||||
+
|
||||
+static struct clk *cpu_clk = 0;
|
||||
+static int cpu_clk_cnt = 0;
|
||||
+
|
||||
+static unsigned int r4k_offset;
|
||||
+static unsigned int r4k_cur;
|
||||
+
|
||||
+static struct clk cpu_clk_generic[] = {
|
||||
+ {
|
||||
+ .name = "cpu",
|
||||
+ .get_rate = lq_get_cpu_hz,
|
||||
+ }, {
|
||||
+ .name = "fpi",
|
||||
+ .get_rate = lq_get_fpi_hz,
|
||||
+ }, {
|
||||
+ .name = "io",
|
||||
+ .get_rate = lq_get_io_region_clock,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+void
|
||||
+clk_init(void)
|
||||
+{
|
||||
+ int i;
|
||||
+ cpu_clk = cpu_clk_generic;
|
||||
+ cpu_clk_cnt = ARRAY_SIZE(cpu_clk_generic);
|
||||
+ for(i = 0; i < cpu_clk_cnt; i++)
|
||||
+ printk("%s: %ld\n", cpu_clk[i].name, clk_get_rate(&cpu_clk[i]));
|
||||
+}
|
||||
+
|
||||
+static inline int
|
||||
+clk_good(struct clk *clk)
|
||||
+{
|
||||
+ return clk && !IS_ERR(clk);
|
||||
+}
|
||||
+
|
||||
+unsigned long
|
||||
+clk_get_rate(struct clk *clk)
|
||||
+{
|
||||
+ if (unlikely(!clk_good(clk)))
|
||||
+ return 0;
|
||||
+
|
||||
+ if (clk->rate != 0)
|
||||
+ return clk->rate;
|
||||
+
|
||||
+ if (clk->get_rate != NULL)
|
||||
+ return clk->get_rate();
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+EXPORT_SYMBOL(clk_get_rate);
|
||||
+
|
||||
+struct clk*
|
||||
+clk_get(struct device *dev, const char *id)
|
||||
+{
|
||||
+ int i;
|
||||
+ for(i = 0; i < cpu_clk_cnt; i++)
|
||||
+ if (!strcmp(id, cpu_clk[i].name))
|
||||
+ return &cpu_clk[i];
|
||||
+ BUG();
|
||||
+ return ERR_PTR(-ENOENT);
|
||||
+}
|
||||
+EXPORT_SYMBOL(clk_get);
|
||||
+
|
||||
+void
|
||||
+clk_put(struct clk *clk)
|
||||
+{
|
||||
+ /* not used */
|
||||
+}
|
||||
+EXPORT_SYMBOL(clk_put);
|
||||
+
|
||||
+static inline u32
|
||||
+lq_get_counter_resolution(void)
|
||||
+{
|
||||
+ u32 res;
|
||||
+ __asm__ __volatile__(
|
||||
+ ".set push\n"
|
||||
+ ".set mips32r2\n"
|
||||
+ ".set noreorder\n"
|
||||
+ "rdhwr %0, $3\n"
|
||||
+ "ehb\n"
|
||||
+ ".set pop\n"
|
||||
+ : "=&r" (res)
|
||||
+ : /* no input */
|
||||
+ : "memory");
|
||||
+ instruction_hazard();
|
||||
+ return res;
|
||||
+}
|
||||
+
|
||||
+void __init
|
||||
+plat_time_init(void)
|
||||
+{
|
||||
+ struct clk *clk = clk_get(0, "cpu");
|
||||
+ mips_hpt_frequency = clk_get_rate(clk) / lq_get_counter_resolution();
|
||||
+ r4k_cur = (read_c0_count() + r4k_offset);
|
||||
+ write_c0_compare(r4k_cur);
|
||||
+
|
||||
+#ifdef CONFIG_SOC_LANTIQ_XWAY
|
||||
+#define LQ_GPTU_GPT_CLC ((u32 *)(LQ_GPTU_BASE_ADDR + 0x0000))
|
||||
+ lq_pmu_enable(PMU_GPT);
|
||||
+ lq_pmu_enable(PMU_FPI);
|
||||
+
|
||||
+ lq_w32(0x100, LQ_GPTU_GPT_CLC);
|
||||
+#endif
|
||||
+}
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/prom.c
|
||||
@@ -0,0 +1,118 @@
|
||||
+/*
|
||||
+ * This program is free software; you can redistribute it and/or modify it
|
||||
+ * under the terms of the GNU General Public License version 2 as published
|
||||
+ * by the Free Software Foundation.
|
||||
+ *
|
||||
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
|
||||
+ */
|
||||
+
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/clk.h>
|
||||
+#include <asm/bootinfo.h>
|
||||
+#include <asm/time.h>
|
||||
+
|
||||
+#include <lantiq.h>
|
||||
+
|
||||
+#include "prom.h"
|
||||
+
|
||||
+static struct lq_soc_info soc_info;
|
||||
+
|
||||
+/* for Multithreading (APRP) on MIPS34K */
|
||||
+unsigned long physical_memsize;
|
||||
+
|
||||
+/* all access to the ebu must be locked */
|
||||
+DEFINE_SPINLOCK(ebu_lock);
|
||||
+EXPORT_SYMBOL_GPL(ebu_lock);
|
||||
+
|
||||
+extern void clk_init(void);
|
||||
+
|
||||
+unsigned int
|
||||
+lq_get_cpu_ver(void)
|
||||
+{
|
||||
+ return soc_info.rev;
|
||||
+}
|
||||
+EXPORT_SYMBOL(lq_get_cpu_ver);
|
||||
+
|
||||
+unsigned int
|
||||
+lq_get_soc_type(void)
|
||||
+{
|
||||
+ return soc_info.type;
|
||||
+}
|
||||
+EXPORT_SYMBOL(lq_get_soc_type);
|
||||
+
|
||||
+const char*
|
||||
+get_system_type(void)
|
||||
+{
|
||||
+ return soc_info.sys_type;
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+prom_free_prom_memory(void)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+#ifdef CONFIG_IMAGE_CMDLINE_HACK
|
||||
+extern char __image_cmdline[];
|
||||
+
|
||||
+static void __init
|
||||
+prom_init_image_cmdline(void)
|
||||
+{
|
||||
+ char *p = __image_cmdline;
|
||||
+ int replace = 0;
|
||||
+
|
||||
+ if (*p == '-') {
|
||||
+ replace = 1;
|
||||
+ p++;
|
||||
+ }
|
||||
+
|
||||
+ if (*p == '\0')
|
||||
+ return;
|
||||
+
|
||||
+ if (replace) {
|
||||
+ strlcpy(arcs_cmdline, p, sizeof(arcs_cmdline));
|
||||
+ } else {
|
||||
+ strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline));
|
||||
+ strlcat(arcs_cmdline, p, sizeof(arcs_cmdline));
|
||||
+ }
|
||||
+}
|
||||
+#else
|
||||
+static void __init prom_init_image_cmdline(void) { return; }
|
||||
+#endif
|
||||
+
|
||||
+static void __init
|
||||
+prom_init_cmdline(void)
|
||||
+{
|
||||
+ int argc = fw_arg0;
|
||||
+ char **argv = (char**)KSEG1ADDR(fw_arg1);
|
||||
+ int i;
|
||||
+
|
||||
+ arcs_cmdline[0] = '\0';
|
||||
+ if(argc)
|
||||
+ for (i = 1; i < argc; i++)
|
||||
+ {
|
||||
+ strlcat(arcs_cmdline, (char*)KSEG1ADDR(argv[i]), COMMAND_LINE_SIZE);
|
||||
+ if(i + 1 != argc)
|
||||
+ strlcat(arcs_cmdline, " ", COMMAND_LINE_SIZE);
|
||||
+ }
|
||||
+
|
||||
+ if (!*arcs_cmdline)
|
||||
+ strcpy(&(arcs_cmdline[0]),
|
||||
+ "console=ttyS1,115200 rootfstype=squashfs,jffs2");
|
||||
+ prom_init_image_cmdline();
|
||||
+}
|
||||
+
|
||||
+void __init
|
||||
+prom_init(void)
|
||||
+{
|
||||
+ struct clk *clk;
|
||||
+ lq_soc_detect(&soc_info);
|
||||
+
|
||||
+ clk_init();
|
||||
+ clk = clk_get(0, "cpu");
|
||||
+ snprintf(soc_info.sys_type, LQ_SYS_TYPE_LEN - 1, "%s rev1.%d %ldMhz",
|
||||
+ soc_info.name, soc_info.rev, clk_get_rate(clk) / 1000000);
|
||||
+ soc_info.sys_type[LQ_SYS_TYPE_LEN - 1] = '\0';
|
||||
+ printk("SoC: %s\n", soc_info.sys_type);
|
||||
+
|
||||
+ prom_init_cmdline();
|
||||
+}
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/prom.h
|
||||
@@ -0,0 +1,24 @@
|
||||
+/*
|
||||
+ * This program is free software; you can redistribute it and/or modify it
|
||||
+ * under the terms of the GNU General Public License version 2 as published
|
||||
+ * by the Free Software Foundation.
|
||||
+ *
|
||||
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
|
||||
+ */
|
||||
+
|
||||
+#ifndef _LQ_PROM_H__
|
||||
+#define _LQ_PROM_H__
|
||||
+
|
||||
+#define LQ_SYS_TYPE_LEN 0x100
|
||||
+
|
||||
+struct lq_soc_info {
|
||||
+ unsigned char *name;
|
||||
+ unsigned int rev;
|
||||
+ unsigned int partnum;
|
||||
+ unsigned int type;
|
||||
+ unsigned char sys_type[LQ_SYS_TYPE_LEN];
|
||||
+};
|
||||
+
|
||||
+void lq_soc_detect(struct lq_soc_info *i);
|
||||
+
|
||||
+#endif
|
||||
136
target/linux/lantiq/patches/101-header.patch
Normal file
136
target/linux/lantiq/patches/101-header.patch
Normal file
@@ -0,0 +1,136 @@
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/include/asm/mach-lantiq/war.h
|
||||
@@ -0,0 +1,24 @@
|
||||
+/*
|
||||
+ * This file is subject to the terms and conditions of the GNU General Public
|
||||
+ * License. See the file "COPYING" in the main directory of this archive
|
||||
+ * for more details.
|
||||
+ *
|
||||
+ */
|
||||
+#ifndef __ASM_MIPS_MACH_LANTIQ_WAR_H
|
||||
+#define __ASM_MIPS_MACH_LANTIQ_WAR_H
|
||||
+
|
||||
+#define R4600_V1_INDEX_ICACHEOP_WAR 0
|
||||
+#define R4600_V1_HIT_CACHEOP_WAR 0
|
||||
+#define R4600_V2_HIT_CACHEOP_WAR 0
|
||||
+#define R5432_CP0_INTERRUPT_WAR 0
|
||||
+#define BCM1250_M3_WAR 0
|
||||
+#define SIBYTE_1956_WAR 0
|
||||
+#define MIPS4K_ICACHE_REFILL_WAR 0
|
||||
+#define MIPS_CACHE_SYNC_WAR 0
|
||||
+#define TX49XX_ICACHE_INDEX_INV_WAR 0
|
||||
+#define RM9000_CDEX_SMP_WAR 0
|
||||
+#define ICACHE_REFILLS_WORKAROUND_WAR 0
|
||||
+#define R10000_LLSC_WAR 0
|
||||
+#define MIPS34K_MISSED_ITLB_WAR 0
|
||||
+
|
||||
+#endif
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/include/asm/mach-lantiq/lantiq.h
|
||||
@@ -0,0 +1,47 @@
|
||||
+/*
|
||||
+ * This program is free software; you can redistribute it and/or modify it
|
||||
+ * under the terms of the GNU General Public License version 2 as published
|
||||
+ * by the Free Software Foundation.
|
||||
+ *
|
||||
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
|
||||
+ */
|
||||
+
|
||||
+#ifndef _LANTIQ_H__
|
||||
+#define _LANTIQ_H__
|
||||
+
|
||||
+/* generic reg access functions */
|
||||
+#define lq_r32(reg) __raw_readl(reg)
|
||||
+#define lq_w32(val, reg) __raw_writel(val, reg)
|
||||
+#define lq_w32_mask(clear, set, reg) lq_w32((lq_r32(reg) & ~clear) | set, reg)
|
||||
+
|
||||
+extern unsigned int lq_get_cpu_ver(void);
|
||||
+extern unsigned int lq_get_soc_type(void);
|
||||
+
|
||||
+/* clock speeds */
|
||||
+#define CLOCK_60M 60000000
|
||||
+#define CLOCK_83M 83333333
|
||||
+#define CLOCK_111M 111111111
|
||||
+#define CLOCK_111M 111111111
|
||||
+#define CLOCK_133M 133333333
|
||||
+#define CLOCK_167M 166666667
|
||||
+#define CLOCK_200M 200000000
|
||||
+#define CLOCK_333M 333333333
|
||||
+#define CLOCK_400M 400000000
|
||||
+
|
||||
+/* spinlock all ebu i/o */
|
||||
+extern spinlock_t ebu_lock;
|
||||
+
|
||||
+/* some irq helpers */
|
||||
+extern void lq_disable_irq(unsigned int irq_nr);
|
||||
+extern void lq_mask_and_ack_irq(unsigned int irq_nr);
|
||||
+extern void lq_enable_irq(unsigned int irq_nr);
|
||||
+
|
||||
+#define IOPORT_RESOURCE_START 0x10000000
|
||||
+#define IOPORT_RESOURCE_END 0xffffffff
|
||||
+#define IOMEM_RESOURCE_START 0x10000000
|
||||
+#define IOMEM_RESOURCE_END 0xffffffff
|
||||
+
|
||||
+#define LQ_FLASH_START 0x10000000
|
||||
+#define LQ_FLASH_MAX 0x04000000
|
||||
+
|
||||
+#endif
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/include/asm/mach-lantiq/lantiq_regs.h
|
||||
@@ -0,0 +1,17 @@
|
||||
+/*
|
||||
+ * This program is free software; you can redistribute it and/or modify it
|
||||
+ * under the terms of the GNU General Public License version 2 as published
|
||||
+ * by the Free Software Foundation.
|
||||
+ *
|
||||
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
|
||||
+ */
|
||||
+
|
||||
+#ifndef _LANTIQ_REGS_H__
|
||||
+#define _LANTIQ_REGS_H__
|
||||
+
|
||||
+#ifdef CONFIG_SOC_LANTIQ_XWAY
|
||||
+#include <xway.h>
|
||||
+#include <xway_irq.h>
|
||||
+#endif
|
||||
+
|
||||
+#endif
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/include/asm/mach-lantiq/lantiq_platform.h
|
||||
@@ -0,0 +1,36 @@
|
||||
+/*
|
||||
+ * This program is free software; you can redistribute it and/or modify it
|
||||
+ * under the terms of the GNU General Public License version 2 as published
|
||||
+ * by the Free Software Foundation.
|
||||
+ *
|
||||
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
|
||||
+ */
|
||||
+
|
||||
+#ifndef _LANTIQ_PLATFORM_H__
|
||||
+#define _LANTIQ_PLATFORM_H__
|
||||
+
|
||||
+#include <linux/mtd/partitions.h>
|
||||
+
|
||||
+/* struct used to pass info to network drivers */
|
||||
+enum {
|
||||
+ MII_MODE,
|
||||
+ REV_MII_MODE,
|
||||
+};
|
||||
+
|
||||
+struct lq_eth_data {
|
||||
+ unsigned char *mac;
|
||||
+ int mii_mode;
|
||||
+};
|
||||
+
|
||||
+/* struct used to pass info to the pci core */
|
||||
+enum {
|
||||
+ PCI_CLOCK_INT = 0,
|
||||
+ PCI_CLOCK_EXT
|
||||
+};
|
||||
+
|
||||
+struct lq_pci_data {
|
||||
+ int clock;
|
||||
+ int req_mask;
|
||||
+};
|
||||
+
|
||||
+#endif
|
||||
3129
target/linux/lantiq/patches/104-board_xway.patch
Normal file
3129
target/linux/lantiq/patches/104-board_xway.patch
Normal file
File diff suppressed because it is too large
Load Diff
565
target/linux/lantiq/patches/105-header_xway.patch
Normal file
565
target/linux/lantiq/patches/105-header_xway.patch
Normal file
@@ -0,0 +1,565 @@
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/include/asm/mach-lantiq/xway/irq.h
|
||||
@@ -0,0 +1,18 @@
|
||||
+/*
|
||||
+ * This program is free software; you can redistribute it and/or modify it
|
||||
+ * under the terms of the GNU General Public License version 2 as published
|
||||
+ * by the Free Software Foundation.
|
||||
+ *
|
||||
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
|
||||
+ */
|
||||
+
|
||||
+#ifndef __LANTIQ_IRQ_H
|
||||
+#define __LANTIQ_IRQ_H
|
||||
+
|
||||
+#include <xway_irq.h>
|
||||
+
|
||||
+#define NR_IRQS 256
|
||||
+
|
||||
+#include_next <irq.h>
|
||||
+
|
||||
+#endif
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/include/asm/mach-lantiq/lantiq_timer.h
|
||||
@@ -0,0 +1,155 @@
|
||||
+#ifndef __DANUBE_GPTU_DEV_H__2005_07_26__10_19__
|
||||
+#define __DANUBE_GPTU_DEV_H__2005_07_26__10_19__
|
||||
+
|
||||
+
|
||||
+/******************************************************************************
|
||||
+ Copyright (c) 2002, Infineon Technologies. All rights reserved.
|
||||
+
|
||||
+ No Warranty
|
||||
+ Because the program is licensed free of charge, there is no warranty for
|
||||
+ the program, to the extent permitted by applicable law. Except when
|
||||
+ otherwise stated in writing the copyright holders and/or other parties
|
||||
+ provide the program "as is" without warranty of any kind, either
|
||||
+ expressed or implied, including, but not limited to, the implied
|
||||
+ warranties of merchantability and fitness for a particular purpose. The
|
||||
+ entire risk as to the quality and performance of the program is with
|
||||
+ you. should the program prove defective, you assume the cost of all
|
||||
+ necessary servicing, repair or correction.
|
||||
+
|
||||
+ In no event unless required by applicable law or agreed to in writing
|
||||
+ will any copyright holder, or any other party who may modify and/or
|
||||
+ redistribute the program as permitted above, be liable to you for
|
||||
+ damages, including any general, special, incidental or consequential
|
||||
+ damages arising out of the use or inability to use the program
|
||||
+ (including but not limited to loss of data or data being rendered
|
||||
+ inaccurate or losses sustained by you or third parties or a failure of
|
||||
+ the program to operate with any other programs), even if such holder or
|
||||
+ other party has been advised of the possibility of such damages.
|
||||
+******************************************************************************/
|
||||
+
|
||||
+
|
||||
+/*
|
||||
+ * ####################################
|
||||
+ * Definition
|
||||
+ * ####################################
|
||||
+ */
|
||||
+
|
||||
+/*
|
||||
+ * Available Timer/Counter Index
|
||||
+ */
|
||||
+#define TIMER(n, X) (n * 2 + (X ? 1 : 0))
|
||||
+#define TIMER_ANY 0x00
|
||||
+#define TIMER1A TIMER(1, 0)
|
||||
+#define TIMER1B TIMER(1, 1)
|
||||
+#define TIMER2A TIMER(2, 0)
|
||||
+#define TIMER2B TIMER(2, 1)
|
||||
+#define TIMER3A TIMER(3, 0)
|
||||
+#define TIMER3B TIMER(3, 1)
|
||||
+
|
||||
+/*
|
||||
+ * Flag of Timer/Counter
|
||||
+ * These flags specify the way in which timer is configured.
|
||||
+ */
|
||||
+/* Bit size of timer/counter. */
|
||||
+#define TIMER_FLAG_16BIT 0x0000
|
||||
+#define TIMER_FLAG_32BIT 0x0001
|
||||
+/* Switch between timer and counter. */
|
||||
+#define TIMER_FLAG_TIMER 0x0000
|
||||
+#define TIMER_FLAG_COUNTER 0x0002
|
||||
+/* Stop or continue when overflowing/underflowing. */
|
||||
+#define TIMER_FLAG_ONCE 0x0000
|
||||
+#define TIMER_FLAG_CYCLIC 0x0004
|
||||
+/* Count up or counter down. */
|
||||
+#define TIMER_FLAG_UP 0x0000
|
||||
+#define TIMER_FLAG_DOWN 0x0008
|
||||
+/* Count on specific level or edge. */
|
||||
+#define TIMER_FLAG_HIGH_LEVEL_SENSITIVE 0x0000
|
||||
+#define TIMER_FLAG_LOW_LEVEL_SENSITIVE 0x0040
|
||||
+#define TIMER_FLAG_RISE_EDGE 0x0010
|
||||
+#define TIMER_FLAG_FALL_EDGE 0x0020
|
||||
+#define TIMER_FLAG_ANY_EDGE 0x0030
|
||||
+/* Signal is syncronous to module clock or not. */
|
||||
+#define TIMER_FLAG_UNSYNC 0x0000
|
||||
+#define TIMER_FLAG_SYNC 0x0080
|
||||
+/* Different interrupt handle type. */
|
||||
+#define TIMER_FLAG_NO_HANDLE 0x0000
|
||||
+#if defined(__KERNEL__)
|
||||
+ #define TIMER_FLAG_CALLBACK_IN_IRQ 0x0100
|
||||
+#endif // defined(__KERNEL__)
|
||||
+#define TIMER_FLAG_SIGNAL 0x0300
|
||||
+/* Internal clock source or external clock source */
|
||||
+#define TIMER_FLAG_INT_SRC 0x0000
|
||||
+#define TIMER_FLAG_EXT_SRC 0x1000
|
||||
+
|
||||
+
|
||||
+/*
|
||||
+ * ioctl Command
|
||||
+ */
|
||||
+#define GPTU_REQUEST_TIMER 0x01 /* General method to setup timer/counter. */
|
||||
+#define GPTU_FREE_TIMER 0x02 /* Free timer/counter. */
|
||||
+#define GPTU_START_TIMER 0x03 /* Start or resume timer/counter. */
|
||||
+#define GPTU_STOP_TIMER 0x04 /* Suspend timer/counter. */
|
||||
+#define GPTU_GET_COUNT_VALUE 0x05 /* Get current count value. */
|
||||
+#define GPTU_CALCULATE_DIVIDER 0x06 /* Calculate timer divider from given freq.*/
|
||||
+#define GPTU_SET_TIMER 0x07 /* Simplified method to setup timer. */
|
||||
+#define GPTU_SET_COUNTER 0x08 /* Simplified method to setup counter. */
|
||||
+
|
||||
+/*
|
||||
+ * Data Type Used to Call ioctl
|
||||
+ */
|
||||
+struct gptu_ioctl_param {
|
||||
+ unsigned int timer; /* In command GPTU_REQUEST_TIMER, GPTU_SET_TIMER, and *
|
||||
+ * GPTU_SET_COUNTER, this field is ID of expected *
|
||||
+ * timer/counter. If it's zero, a timer/counter would *
|
||||
+ * be dynamically allocated and ID would be stored in *
|
||||
+ * this field. *
|
||||
+ * In command GPTU_GET_COUNT_VALUE, this field is *
|
||||
+ * ignored. *
|
||||
+ * In other command, this field is ID of timer/counter *
|
||||
+ * allocated. */
|
||||
+ unsigned int flag; /* In command GPTU_REQUEST_TIMER, GPTU_SET_TIMER, and *
|
||||
+ * GPTU_SET_COUNTER, this field contains flags to *
|
||||
+ * specify how to configure timer/counter. *
|
||||
+ * In command GPTU_START_TIMER, zero indicate start *
|
||||
+ * and non-zero indicate resume timer/counter. *
|
||||
+ * In other command, this field is ignored. */
|
||||
+ unsigned long value; /* In command GPTU_REQUEST_TIMER, this field contains *
|
||||
+ * init/reload value. *
|
||||
+ * In command GPTU_SET_TIMER, this field contains *
|
||||
+ * frequency (0.001Hz) of timer. *
|
||||
+ * In command GPTU_GET_COUNT_VALUE, current count *
|
||||
+ * value would be stored in this field. *
|
||||
+ * In command GPTU_CALCULATE_DIVIDER, this field *
|
||||
+ * contains frequency wanted, and after calculation, *
|
||||
+ * divider would be stored in this field to overwrite *
|
||||
+ * the frequency. *
|
||||
+ * In other command, this field is ignored. */
|
||||
+ int pid; /* In command GPTU_REQUEST_TIMER and GPTU_SET_TIMER, *
|
||||
+ * if signal is required, this field contains process *
|
||||
+ * ID to which signal would be sent. *
|
||||
+ * In other command, this field is ignored. */
|
||||
+ int sig; /* In command GPTU_REQUEST_TIMER and GPTU_SET_TIMER, *
|
||||
+ * if signal is required, this field contains signal *
|
||||
+ * number which would be sent. *
|
||||
+ * In other command, this field is ignored. */
|
||||
+};
|
||||
+
|
||||
+/*
|
||||
+ * ####################################
|
||||
+ * Data Type
|
||||
+ * ####################################
|
||||
+ */
|
||||
+typedef void (*timer_callback)(unsigned long arg);
|
||||
+
|
||||
+extern int ifxmips_request_timer(unsigned int, unsigned int, unsigned long, unsigned long, unsigned long);
|
||||
+extern int ifxmips_free_timer(unsigned int);
|
||||
+extern int ifxmips_start_timer(unsigned int, int);
|
||||
+extern int ifxmips_stop_timer(unsigned int);
|
||||
+extern int ifxmips_reset_counter_flags(u32 timer, u32 flags);
|
||||
+extern int ifxmips_get_count_value(unsigned int, unsigned long *);
|
||||
+extern u32 ifxmips_cal_divider(unsigned long);
|
||||
+extern int ifxmips_set_timer(unsigned int, unsigned int, int, int, unsigned int, unsigned long, unsigned long);
|
||||
+extern int ifxmips_set_counter(unsigned int timer, unsigned int flag,
|
||||
+ u32 reload, unsigned long arg1, unsigned long arg2);
|
||||
+
|
||||
+#endif /* __DANUBE_GPTU_DEV_H__2005_07_26__10_19__ */
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/include/asm/mach-lantiq/xway/xway.h
|
||||
@@ -0,0 +1,121 @@
|
||||
+/*
|
||||
+ * This program is free software; you can redistribute it and/or modify it
|
||||
+ * under the terms of the GNU General Public License version 2 as published
|
||||
+ * by the Free Software Foundation.
|
||||
+ *
|
||||
+ * Copyright (C) 2005 infineon
|
||||
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
|
||||
+ */
|
||||
+
|
||||
+#ifdef CONFIG_SOC_LANTIQ_XWAY
|
||||
+
|
||||
+#ifndef _LQ_XWAY_H__
|
||||
+#define _LQ_XWAY_H__
|
||||
+
|
||||
+#include <lantiq.h>
|
||||
+
|
||||
+/* request a non-gpio and set the PIO config */
|
||||
+extern int lq_gpio_request(unsigned int pin, unsigned int alt0,
|
||||
+ unsigned int alt1, unsigned int dir, const char *name);
|
||||
+extern int lq_gpio_setconfig(unsigned int pin, unsigned int reg, unsigned int val);
|
||||
+
|
||||
+extern void lq_pmu_enable(unsigned int module);
|
||||
+extern void lq_pmu_disable(unsigned int module);
|
||||
+
|
||||
+extern unsigned int lq_get_fpi_bus_clock(int bus);
|
||||
+
|
||||
+#define BOARD_SYSTEM_TYPE "LANTIQ"
|
||||
+
|
||||
+/*------------ Chip IDs */
|
||||
+#define SOC_ID_DANUBE1 0x129
|
||||
+#define SOC_ID_DANUBE2 0x12B
|
||||
+#define SOC_ID_TWINPASS 0x12D
|
||||
+#define SOC_ID_ARX188 0x16C
|
||||
+#define SOC_ID_ARX168 0x16D
|
||||
+#define SOC_ID_ARX182 0x16F
|
||||
+
|
||||
+/*------------ SoC Types */
|
||||
+#define SOC_TYPE_DANUBE 0x01
|
||||
+#define SOC_TYPE_TWINPASS 0x02
|
||||
+#define SOC_TYPE_AR9 0x03
|
||||
+
|
||||
+/*------------ ASC0/1 */
|
||||
+#define LQ_ASC0_BASE 0x1E100400
|
||||
+#define LQ_ASC1_BASE 0x1E100C00
|
||||
+#define LQ_ASC_SIZE 0x400
|
||||
+
|
||||
+/*------------ RCU */
|
||||
+#define LQ_RCU_BASE_ADDR 0xBF203000
|
||||
+
|
||||
+/*------------ GPTU */
|
||||
+#define LQ_GPTU_BASE_ADDR 0xB8000300
|
||||
+
|
||||
+/*------------ EBU */
|
||||
+#define LQ_EBU_GPIO_START 0x14000000
|
||||
+#define LQ_EBU_GPIO_SIZE 0x1000
|
||||
+
|
||||
+#define LQ_EBU_BASE_ADDR 0xBE105300
|
||||
+
|
||||
+#define LQ_EBU_BUSCON0 ((u32 *)(LQ_EBU_BASE_ADDR + 0x0060))
|
||||
+#define LQ_EBU_PCC_CON ((u32 *)(LQ_EBU_BASE_ADDR + 0x0090))
|
||||
+#define LQ_EBU_PCC_IEN ((u32 *)(LQ_EBU_BASE_ADDR + 0x00A4))
|
||||
+#define LQ_EBU_PCC_ISTAT ((u32 *)(LQ_EBU_BASE_ADDR + 0x00A0))
|
||||
+#define LQ_EBU_BUSCON1 ((u32 *)(LQ_EBU_BASE_ADDR + 0x0064))
|
||||
+#define LQ_EBU_ADDRSEL1 ((u32 *)(LQ_EBU_BASE_ADDR + 0x0024))
|
||||
+
|
||||
+#define EBU_WRDIS 0x80000000
|
||||
+
|
||||
+/*------------ CGU */
|
||||
+#define LQ_CGU_BASE_ADDR (KSEG1 + 0x1F103000)
|
||||
+
|
||||
+/*------------ PMU */
|
||||
+#define LQ_PMU_BASE_ADDR (KSEG1 + 0x1F102000)
|
||||
+
|
||||
+#define PMU_DMA 0x0020
|
||||
+#define PMU_USB 0x8041
|
||||
+#define PMU_LED 0x0800
|
||||
+#define PMU_GPT 0x1000
|
||||
+#define PMU_PPE 0x2000
|
||||
+#define PMU_FPI 0x4000
|
||||
+#define PMU_SWITCH 0x10000000
|
||||
+
|
||||
+/*------------ ETOP */
|
||||
+#define LQ_PPE32_BASE_ADDR 0xBE180000
|
||||
+#define LQ_PPE32_SIZE 0x40000
|
||||
+
|
||||
+/*------------ DMA */
|
||||
+#define LQ_DMA_BASE_ADDR 0xBE104100
|
||||
+
|
||||
+/*------------ PCI */
|
||||
+#define PCI_CR_PR_BASE_ADDR (KSEG1 + 0x1E105400)
|
||||
+#define PCI_CS_PR_BASE_ADDR (KSEG1 + 0x17000000)
|
||||
+
|
||||
+/*------------ WDT */
|
||||
+#define LQ_WDT_BASE 0x1F880000
|
||||
+#define LQ_WDT_SIZE 0x400
|
||||
+
|
||||
+/*------------ Serial To Parallel conversion */
|
||||
+#define LQ_STP_BASE 0x1E100BB0
|
||||
+#define LQ_STP_SIZE 0x40
|
||||
+
|
||||
+/*------------ GPIO */
|
||||
+#define LQ_GPIO0_BASE_ADDR 0x1E100B10
|
||||
+#define LQ_GPIO1_BASE_ADDR 0x1E100B40
|
||||
+#define LQ_GPIO_SIZE 0x30
|
||||
+
|
||||
+/*------------ SSC */
|
||||
+#define LQ_SSC_BASE_ADDR (KSEG1 + 0x1e100800)
|
||||
+
|
||||
+/*------------ MEI */
|
||||
+#define LQ_MEI_BASE_ADDR (KSEG1 + 0x1E116000)
|
||||
+
|
||||
+/*------------ DEU */
|
||||
+#define LQ_DEU_BASE (KSEG1 + 0x1E103100)
|
||||
+
|
||||
+/*------------ MPS */
|
||||
+#define LQ_MPS_BASE_ADDR (KSEG1 + 0x1F107000)
|
||||
+#define LQ_MPS_CHIPID ((u32 *)(LQ_MPS_BASE_ADDR + 0x0344))
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
+#endif
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/include/asm/mach-lantiq/xway/xway_dma.h
|
||||
@@ -0,0 +1,144 @@
|
||||
+/*
|
||||
+ * 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.
|
||||
+ *
|
||||
+ * 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.
|
||||
+ *
|
||||
+ * Copyright (C) 2005 infineon
|
||||
+ * Copyright (C) 2007 John Crispin <blogic@openwrt.org>
|
||||
+ *
|
||||
+ */
|
||||
+#ifndef _LQ_DMA_H__
|
||||
+#define _LQ_DMA_H__
|
||||
+
|
||||
+#define RCV_INT 1
|
||||
+#define TX_BUF_FULL_INT 2
|
||||
+#define TRANSMIT_CPT_INT 4
|
||||
+#define LQ_DMA_CH_ON 1
|
||||
+#define LQ_DMA_CH_OFF 0
|
||||
+#define LQ_DMA_CH_DEFAULT_WEIGHT 100
|
||||
+
|
||||
+enum attr_t{
|
||||
+ TX = 0,
|
||||
+ RX = 1,
|
||||
+ RESERVED = 2,
|
||||
+ DEFAULT = 3,
|
||||
+};
|
||||
+
|
||||
+#define DMA_OWN 1
|
||||
+#define CPU_OWN 0
|
||||
+#define DMA_MAJOR 250
|
||||
+
|
||||
+#define DMA_DESC_OWN_CPU 0x0
|
||||
+#define DMA_DESC_OWN_DMA 0x80000000
|
||||
+#define DMA_DESC_CPT_SET 0x40000000
|
||||
+#define DMA_DESC_SOP_SET 0x20000000
|
||||
+#define DMA_DESC_EOP_SET 0x10000000
|
||||
+
|
||||
+#define MISCFG_MASK 0x40
|
||||
+#define RDERR_MASK 0x20
|
||||
+#define CHOFF_MASK 0x10
|
||||
+#define DESCPT_MASK 0x8
|
||||
+#define DUR_MASK 0x4
|
||||
+#define EOP_MASK 0x2
|
||||
+
|
||||
+#define DMA_DROP_MASK (1<<31)
|
||||
+
|
||||
+#define LQ_DMA_RX -1
|
||||
+#define LQ_DMA_TX 1
|
||||
+
|
||||
+struct dma_chan_map {
|
||||
+ const char *dev_name;
|
||||
+ enum attr_t dir;
|
||||
+ int pri;
|
||||
+ int irq;
|
||||
+ int rel_chan_no;
|
||||
+};
|
||||
+
|
||||
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
|
||||
+struct rx_desc {
|
||||
+ u32 data_length:16;
|
||||
+ volatile u32 reserved:7;
|
||||
+ volatile u32 byte_offset:2;
|
||||
+ volatile u32 Burst_length_offset:3;
|
||||
+ volatile u32 EoP:1;
|
||||
+ volatile u32 Res:1;
|
||||
+ volatile u32 C:1;
|
||||
+ volatile u32 OWN:1;
|
||||
+ volatile u32 Data_Pointer; /* fixme: should be 28 bits here */
|
||||
+};
|
||||
+
|
||||
+struct tx_desc {
|
||||
+ volatile u32 data_length:16;
|
||||
+ volatile u32 reserved1:7;
|
||||
+ volatile u32 byte_offset:5;
|
||||
+ volatile u32 EoP:1;
|
||||
+ volatile u32 SoP:1;
|
||||
+ volatile u32 C:1;
|
||||
+ volatile u32 OWN:1;
|
||||
+ volatile u32 Data_Pointer; /* fixme: should be 28 bits here */
|
||||
+};
|
||||
+#else /* BIG */
|
||||
+struct rx_desc {
|
||||
+ union {
|
||||
+ struct {
|
||||
+ volatile u32 OWN:1;
|
||||
+ volatile u32 C:1;
|
||||
+ volatile u32 SoP:1;
|
||||
+ volatile u32 EoP:1;
|
||||
+ volatile u32 Burst_length_offset:3;
|
||||
+ volatile u32 byte_offset:2;
|
||||
+ volatile u32 reserve:7;
|
||||
+ volatile u32 data_length:16;
|
||||
+ } field;
|
||||
+ volatile u32 word;
|
||||
+ } status;
|
||||
+ volatile u32 Data_Pointer;
|
||||
+};
|
||||
+
|
||||
+struct tx_desc {
|
||||
+ union {
|
||||
+ struct {
|
||||
+ volatile u32 OWN:1;
|
||||
+ volatile u32 C:1;
|
||||
+ volatile u32 SoP:1;
|
||||
+ volatile u32 EoP:1;
|
||||
+ volatile u32 byte_offset:5;
|
||||
+ volatile u32 reserved:7;
|
||||
+ volatile u32 data_length:16;
|
||||
+ } field;
|
||||
+ volatile u32 word;
|
||||
+ } status;
|
||||
+ volatile u32 Data_Pointer;
|
||||
+};
|
||||
+#endif /* ENDIAN */
|
||||
+
|
||||
+struct dma_channel_info {
|
||||
+ /* relative channel number */
|
||||
+ int rel_chan_no;
|
||||
+ /* class for this channel for QoS */
|
||||
+ int pri;
|
||||
+ /* specify byte_offset */
|
||||
+ int byte_offset;
|
||||
+ /* direction */
|
||||
+ int dir;
|
||||
+ /* irq number */
|
||||
+ int irq;
|
||||
+ /* descriptor parameter */
|
||||
+ int desc_base;
|
||||
+ int desc_len;
|
||||
+ int curr_desc;
|
||||
+ int prev_desc; /* only used if it is a tx channel*/
|
||||
+ /* weight setting for WFQ algorithm*/
|
||||
+ int weight;
|
||||
+ int default_weight;
|
||||
+ int packet_size;
|
||||
+ int burst_len;
|
||||
+ /* on or off of this channel */
|
||||
+ int control;
|
||||
+ /* optional information for the upper layer devices */
|
||||
+#if defined(CONFIG_LQ_ETHERNET_D2) || defined(CONFIG_LQ_PPA)
|
||||
+ void *opt[64];
|
||||
+#else
|
||||
+ void *opt[25];
|
||||
+#endif
|
||||
+ /* Pointer to the peripheral device who is using this channel */
|
||||
+ void *dma_dev;
|
||||
+ /* channel operations */
|
||||
+ void (*open)(struct dma_channel_info *pCh);
|
||||
+ void (*close)(struct dma_channel_info *pCh);
|
||||
+ void (*reset)(struct dma_channel_info *pCh);
|
||||
+ void (*enable_irq)(struct dma_channel_info *pCh);
|
||||
+ void (*disable_irq)(struct dma_channel_info *pCh);
|
||||
+};
|
||||
+
|
||||
+struct dma_device_info {
|
||||
+ /* device name of this peripheral */
|
||||
+ char device_name[15];
|
||||
+ int reserved;
|
||||
+ int tx_burst_len;
|
||||
+ int rx_burst_len;
|
||||
+ int default_weight;
|
||||
+ int current_tx_chan;
|
||||
+ int current_rx_chan;
|
||||
+ int num_tx_chan;
|
||||
+ int num_rx_chan;
|
||||
+ int max_rx_chan_num;
|
||||
+ int max_tx_chan_num;
|
||||
+ struct dma_channel_info *tx_chan[20];
|
||||
+ struct dma_channel_info *rx_chan[20];
|
||||
+ /*functions, optional*/
|
||||
+ u8 *(*buffer_alloc)(int len, int *offset, void **opt);
|
||||
+ void (*buffer_free)(u8 *dataptr, void *opt);
|
||||
+ int (*intr_handler)(struct dma_device_info *info, int status);
|
||||
+ void *priv; /* used by peripheral driver only */
|
||||
+};
|
||||
+
|
||||
+struct dma_device_info *dma_device_reserve(char *dev_name);
|
||||
+void dma_device_release(struct dma_device_info *dev);
|
||||
+void dma_device_register(struct dma_device_info *info);
|
||||
+void dma_device_unregister(struct dma_device_info *info);
|
||||
+int dma_device_read(struct dma_device_info *info, u8 **dataptr, void **opt);
|
||||
+int dma_device_write(struct dma_device_info *info, u8 *dataptr, int len,
|
||||
+ void *opt);
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/include/asm/mach-lantiq/xway/xway_irq.h
|
||||
@@ -0,0 +1,62 @@
|
||||
+/*
|
||||
+ * This program is free software; you can redistribute it and/or modify it
|
||||
+ * under the terms of the GNU General Public License version 2 as published
|
||||
+ * by the Free Software Foundation.
|
||||
+ *
|
||||
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
|
||||
+ */
|
||||
+
|
||||
+#ifndef _LANTIQ_XWAY_IRQ_H__
|
||||
+#define _LANTIQ_XWAY_IRQ_H__
|
||||
+
|
||||
+#define INT_NUM_IRQ0 8
|
||||
+#define INT_NUM_IM0_IRL0 (INT_NUM_IRQ0 + 0)
|
||||
+#define INT_NUM_IM1_IRL0 (INT_NUM_IRQ0 + 32)
|
||||
+#define INT_NUM_IM2_IRL0 (INT_NUM_IRQ0 + 64)
|
||||
+#define INT_NUM_IM3_IRL0 (INT_NUM_IRQ0 + 96)
|
||||
+#define INT_NUM_IM4_IRL0 (INT_NUM_IRQ0 + 128)
|
||||
+#define INT_NUM_IM_OFFSET (INT_NUM_IM1_IRL0 - INT_NUM_IM0_IRL0)
|
||||
+
|
||||
+#define LQ_ASC_TIR(x) (INT_NUM_IM3_IRL0 + (x * 7))
|
||||
+#define LQ_ASC_RIR(x) (INT_NUM_IM3_IRL0 + (x * 7) + 2)
|
||||
+#define LQ_ASC_EIR(x) (INT_NUM_IM3_IRL0 + (x * 7) + 3)
|
||||
+
|
||||
+#define LQ_SSC_TIR (INT_NUM_IM0_IRL0 + 15)
|
||||
+#define LQ_SSC_RIR (INT_NUM_IM0_IRL0 + 14)
|
||||
+#define LQ_SSC_EIR (INT_NUM_IM0_IRL0 + 16)
|
||||
+
|
||||
+#define LQ_MEI_DYING_GASP_INT (INT_NUM_IM1_IRL0 + 21)
|
||||
+#define LQ_MEI_INT (INT_NUM_IM1_IRL0 + 23)
|
||||
+
|
||||
+#define LQ_TIMER6_INT (INT_NUM_IM1_IRL0 + 23)
|
||||
+#define LQ_USB_INT (INT_NUM_IM1_IRL0 + 22)
|
||||
+#define LQ_USB_OC_INT (INT_NUM_IM4_IRL0 + 23)
|
||||
+
|
||||
+#define MIPS_CPU_TIMER_IRQ 7
|
||||
+
|
||||
+#define LQ_DMA_CH0_INT (INT_NUM_IM2_IRL0)
|
||||
+#define LQ_DMA_CH1_INT (INT_NUM_IM2_IRL0 + 1)
|
||||
+#define LQ_DMA_CH2_INT (INT_NUM_IM2_IRL0 + 2)
|
||||
+#define LQ_DMA_CH3_INT (INT_NUM_IM2_IRL0 + 3)
|
||||
+#define LQ_DMA_CH4_INT (INT_NUM_IM2_IRL0 + 4)
|
||||
+#define LQ_DMA_CH5_INT (INT_NUM_IM2_IRL0 + 5)
|
||||
+#define LQ_DMA_CH6_INT (INT_NUM_IM2_IRL0 + 6)
|
||||
+#define LQ_DMA_CH7_INT (INT_NUM_IM2_IRL0 + 7)
|
||||
+#define LQ_DMA_CH8_INT (INT_NUM_IM2_IRL0 + 8)
|
||||
+#define LQ_DMA_CH9_INT (INT_NUM_IM2_IRL0 + 9)
|
||||
+#define LQ_DMA_CH10_INT (INT_NUM_IM2_IRL0 + 10)
|
||||
+#define LQ_DMA_CH11_INT (INT_NUM_IM2_IRL0 + 11)
|
||||
+#define LQ_DMA_CH12_INT (INT_NUM_IM2_IRL0 + 25)
|
||||
+#define LQ_DMA_CH13_INT (INT_NUM_IM2_IRL0 + 26)
|
||||
+#define LQ_DMA_CH14_INT (INT_NUM_IM2_IRL0 + 27)
|
||||
+#define LQ_DMA_CH15_INT (INT_NUM_IM2_IRL0 + 28)
|
||||
+#define LQ_DMA_CH16_INT (INT_NUM_IM2_IRL0 + 29)
|
||||
+#define LQ_DMA_CH17_INT (INT_NUM_IM2_IRL0 + 30)
|
||||
+#define LQ_DMA_CH18_INT (INT_NUM_IM2_IRL0 + 16)
|
||||
+#define LQ_DMA_CH19_INT (INT_NUM_IM2_IRL0 + 21)
|
||||
+
|
||||
+#define LQ_PPE_MBOX_INT (INT_NUM_IM2_IRL0 + 24)
|
||||
+
|
||||
+#define INT_NUM_IM4_IRL14 (INT_NUM_IM4_IRL0 + 14)
|
||||
+
|
||||
+#endif
|
||||
93
target/linux/lantiq/patches/106-early_printk.patch
Normal file
93
target/linux/lantiq/patches/106-early_printk.patch
Normal file
@@ -0,0 +1,93 @@
|
||||
--- a/arch/mips/lantiq/Kconfig
|
||||
+++ b/arch/mips/lantiq/Kconfig
|
||||
@@ -33,4 +33,19 @@ endchoice
|
||||
source "arch/mips/lantiq/falcon/Kconfig"
|
||||
source "arch/mips/lantiq/xway/Kconfig"
|
||||
|
||||
+if EARLY_PRINTK
|
||||
+choice
|
||||
+ prompt "Early printk port"
|
||||
+ default LANTIQ_PROM_ASC1
|
||||
+ help
|
||||
+ Choose which serial port is used, until the console driver is loaded
|
||||
+
|
||||
+config LANTIQ_PROM_ASC0
|
||||
+ bool "ASC0"
|
||||
+
|
||||
+config LANTIQ_PROM_ASC1
|
||||
+ bool "ASC1"
|
||||
+endchoice
|
||||
+endif
|
||||
+
|
||||
endif
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/early_printk.c
|
||||
@@ -0,0 +1,68 @@
|
||||
+/*
|
||||
+ * This program is free software; you can redistribute it and/or modify it
|
||||
+ * under the terms of the GNU General Public License version 2 as published
|
||||
+ * by the Free Software Foundation.
|
||||
+ *
|
||||
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
|
||||
+ */
|
||||
+
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/cpu.h>
|
||||
+
|
||||
+#include <lantiq.h>
|
||||
+
|
||||
+#ifdef CONFIG_SOC_LANTIQ_XWAY
|
||||
+#include <xway.h>
|
||||
+#ifdef CONFIG_LANTIQ_PROM_ASC0
|
||||
+#define LQ_ASC_BASE KSEG1ADDR(LQ_ASC0_BASE)
|
||||
+#else
|
||||
+#define LQ_ASC_BASE KSEG1ADDR(LQ_ASC1_BASE)
|
||||
+#endif
|
||||
+
|
||||
+#elif CONFIG_SOC_LANTIQ_FALCON
|
||||
+#include <falcon/gpon_reg_base.h>
|
||||
+#ifdef CONFIG_LANTIQ_PROM_ASC0
|
||||
+#define LQ_ASC_BASE GPON_ASC0_BASE
|
||||
+#else
|
||||
+#define LQ_ASC_BASE GPON_ASC1_BASE
|
||||
+#endif
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
+#define ASC_BUF 1024
|
||||
+#define LQ_ASC_FSTAT 0x0048
|
||||
+#define LQ_ASC_TBUF 0x0020
|
||||
+#define TXMASK 0x3F00
|
||||
+#define TXOFFSET 8
|
||||
+
|
||||
+static char buf[ASC_BUF];
|
||||
+
|
||||
+void
|
||||
+prom_putchar(char c)
|
||||
+{
|
||||
+ unsigned long flags;
|
||||
+
|
||||
+ local_irq_save(flags);
|
||||
+ while ((lq_r32((u32 *)(LQ_ASC_BASE + LQ_ASC_FSTAT)) & TXMASK) >> TXOFFSET);
|
||||
+
|
||||
+ if (c == '\n')
|
||||
+ lq_w32('\r', (u32 *)(LQ_ASC_BASE + LQ_ASC_TBUF));
|
||||
+ lq_w32(c, (u32 *)(LQ_ASC_BASE + LQ_ASC_TBUF));
|
||||
+ local_irq_restore(flags);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+early_printf(const char *fmt, ...)
|
||||
+{
|
||||
+ va_list args;
|
||||
+ int l;
|
||||
+ char *p, *buf_end;
|
||||
+
|
||||
+ va_start(args, fmt);
|
||||
+ l = vsnprintf(buf, ASC_BUF, fmt, args);
|
||||
+ va_end(args);
|
||||
+ buf_end = buf + l;
|
||||
+
|
||||
+ for (p = buf; p < buf_end; p++)
|
||||
+ prom_putchar(*p);
|
||||
+}
|
||||
55
target/linux/lantiq/patches/110-machine.patch
Normal file
55
target/linux/lantiq/patches/110-machine.patch
Normal file
@@ -0,0 +1,55 @@
|
||||
--- a/arch/mips/lantiq/setup.c
|
||||
+++ b/arch/mips/lantiq/setup.c
|
||||
@@ -13,7 +13,8 @@
|
||||
#include <linux/ioport.h>
|
||||
|
||||
#include <lantiq.h>
|
||||
-#include <lantiq_regs.h>
|
||||
+
|
||||
+#include <machine.h>
|
||||
|
||||
void __init
|
||||
plat_mem_setup(void)
|
||||
@@ -46,3 +47,25 @@ plat_mem_setup(void)
|
||||
memsize *= 1024 * 1024;
|
||||
add_memory_region(0x00000000, memsize, BOOT_MEM_RAM);
|
||||
}
|
||||
+
|
||||
+static int __init
|
||||
+lq_machine_setup(void)
|
||||
+{
|
||||
+ mips_machine_setup();
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void __init
|
||||
+mach_generic_init(void)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+MIPS_MACHINE(LANTIQ_MACH_GENERIC,
|
||||
+ "Generic",
|
||||
+ "Generic",
|
||||
+ mach_generic_init);
|
||||
+
|
||||
+arch_initcall(lq_machine_setup);
|
||||
+
|
||||
+/* for backward compatibility, define "board=" as alias for "machtype=" */
|
||||
+__setup("board=", mips_machtype_setup);
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/include/asm/mach-lantiq/machine.h
|
||||
@@ -0,0 +1,14 @@
|
||||
+#include <asm/mips_machine.h>
|
||||
+
|
||||
+enum lantiq_mach_type {
|
||||
+ LANTIQ_MACH_GENERIC,
|
||||
+
|
||||
+ /* FALCON */
|
||||
+ LANTIQ_MACH_EASY98000, /* Falcon Eval Board, NOR Flash */
|
||||
+ LANTIQ_MACH_EASY98020, /* Falcon Reference Board */
|
||||
+
|
||||
+ /* XWAY */
|
||||
+ LANTIQ_MACH_EASY4010, /* Twinpass evalkit */
|
||||
+ LANTIQ_MACH_EASY50712, /* Danube evalkit */
|
||||
+ LANTIQ_MACH_EASY50812, /* AR9 eval board */
|
||||
+};
|
||||
799
target/linux/lantiq/patches/200-serial.patch
Normal file
799
target/linux/lantiq/patches/200-serial.patch
Normal file
@@ -0,0 +1,799 @@
|
||||
--- a/drivers/serial/Kconfig
|
||||
+++ b/drivers/serial/Kconfig
|
||||
@@ -1397,6 +1397,14 @@
|
||||
help
|
||||
Support for Console on the NWP serial ports.
|
||||
|
||||
+config SERIAL_LANTIQ
|
||||
+ bool "Lantiq serial driver"
|
||||
+ depends on LANTIQ
|
||||
+ select SERIAL_CORE
|
||||
+ select SERIAL_CORE_CONSOLE
|
||||
+ help
|
||||
+ Driver for the Lantiq SoC ASC hardware
|
||||
+
|
||||
config SERIAL_QE
|
||||
tristate "Freescale QUICC Engine serial port support"
|
||||
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
|
||||
+obj-$(CONFIG_SERIAL_LANTIQ) += lantiq.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/serial/lantiq.c
|
||||
@@ -0,0 +1,772 @@
|
||||
+/*
|
||||
+ * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
|
||||
+ *
|
||||
+ * 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.
|
||||
+ *
|
||||
+ * 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
|
||||
+ *
|
||||
+ * Copyright (C) 2004 Infineon IFAP DC COM CPE
|
||||
+ * Copyright (C) 2007 Felix Fietkau <nbd@openwrt.org>
|
||||
+ * Copyright (C) 2007 John Crispin <blogic@openwrt.org>
|
||||
+ * Copyright (C) 2010 Thomas Langer, Lantiq Deutschland
|
||||
+ */
|
||||
+
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/ioport.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/console.h>
|
||||
+#include <linux/sysrq.h>
|
||||
+#include <linux/device.h>
|
||||
+#include <linux/tty.h>
|
||||
+#include <linux/tty_flip.h>
|
||||
+#include <linux/serial_core.h>
|
||||
+#include <linux/serial.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/clk.h>
|
||||
+
|
||||
+#define lq_r32(reg) __raw_readl(reg)
|
||||
+#define lq_r8(reg) __raw_readb(reg)
|
||||
+#define lq_w32(val, reg) __raw_writel(val, reg)
|
||||
+#define lq_w8(val, reg) __raw_writeb(val, reg)
|
||||
+#define lq_w32_mask(clear, set, reg) lq_w32((lq_r32(reg) & ~(clear)) | (set), reg)
|
||||
+
|
||||
+#define PORT_IFXMIPSASC 111
|
||||
+#define MAXPORTS 2
|
||||
+
|
||||
+#define UART_DUMMY_UER_RX 1
|
||||
+
|
||||
+#define DRVNAME "lq_asc"
|
||||
+
|
||||
+#ifdef __BIG_ENDIAN
|
||||
+#define IFXMIPS_ASC_TBUF (0x0020 + 3)
|
||||
+#define IFXMIPS_ASC_RBUF (0x0024 + 3)
|
||||
+#else
|
||||
+#define IFXMIPS_ASC_TBUF 0x0020
|
||||
+#define IFXMIPS_ASC_RBUF 0x0024
|
||||
+#endif
|
||||
+
|
||||
+#define IFXMIPS_ASC_FSTAT 0x0048
|
||||
+#define IFXMIPS_ASC_WHBSTATE 0x0018
|
||||
+#define IFXMIPS_ASC_STATE 0x0014
|
||||
+#define IFXMIPS_ASC_IRNCR 0x00F8
|
||||
+#define IFXMIPS_ASC_CLC 0x0000
|
||||
+#define IFXMIPS_ASC_ID 0x0008
|
||||
+#define IFXMIPS_ASC_PISEL 0x0004
|
||||
+#define IFXMIPS_ASC_TXFCON 0x0044
|
||||
+#define IFXMIPS_ASC_RXFCON 0x0040
|
||||
+#define IFXMIPS_ASC_CON 0x0010
|
||||
+#define IFXMIPS_ASC_BG 0x0050
|
||||
+#define IFXMIPS_ASC_IRNREN 0x00F4
|
||||
+
|
||||
+#define ASC_IRNREN_TX 0x1
|
||||
+#define ASC_IRNREN_RX 0x2
|
||||
+#define ASC_IRNREN_ERR 0x4
|
||||
+#define ASC_IRNREN_TX_BUF 0x8
|
||||
+#define ASC_IRNCR_TIR 0x1
|
||||
+#define ASC_IRNCR_RIR 0x2
|
||||
+#define ASC_IRNCR_EIR 0x4
|
||||
+
|
||||
+#define ASCOPT_CSIZE 0x3
|
||||
+#define ASCOPT_CS7 0x1
|
||||
+#define ASCOPT_CS8 0x2
|
||||
+#define ASCOPT_PARENB 0x4
|
||||
+#define ASCOPT_STOPB 0x8
|
||||
+#define ASCOPT_PARODD 0x0
|
||||
+#define ASCOPT_CREAD 0x20
|
||||
+#define TXFIFO_FL 1
|
||||
+#define RXFIFO_FL 1
|
||||
+#define ASCCLC_DISS 0x2
|
||||
+#define ASCCLC_RMCMASK 0x0000FF00
|
||||
+#define ASCCLC_RMCOFFSET 8
|
||||
+#define ASCCON_M_8ASYNC 0x0
|
||||
+#define ASCCON_M_7ASYNC 0x2
|
||||
+#define ASCCON_ODD 0x00000020
|
||||
+#define ASCCON_STP 0x00000080
|
||||
+#define ASCCON_BRS 0x00000100
|
||||
+#define ASCCON_FDE 0x00000200
|
||||
+#define ASCCON_R 0x00008000
|
||||
+#define ASCCON_FEN 0x00020000
|
||||
+#define ASCCON_ROEN 0x00080000
|
||||
+#define ASCCON_TOEN 0x00100000
|
||||
+#define ASCSTATE_PE 0x00010000
|
||||
+#define ASCSTATE_FE 0x00020000
|
||||
+#define ASCSTATE_ROE 0x00080000
|
||||
+#define ASCSTATE_ANY (ASCSTATE_ROE|ASCSTATE_PE|ASCSTATE_FE)
|
||||
+#define ASCWHBSTATE_CLRREN 0x00000001
|
||||
+#define ASCWHBSTATE_SETREN 0x00000002
|
||||
+#define ASCWHBSTATE_CLRPE 0x00000004
|
||||
+#define ASCWHBSTATE_CLRFE 0x00000008
|
||||
+#define ASCWHBSTATE_CLRROE 0x00000020
|
||||
+#define ASCTXFCON_TXFEN 0x0001
|
||||
+#define ASCTXFCON_TXFFLU 0x0002
|
||||
+#define ASCTXFCON_TXFITLMASK 0x3F00
|
||||
+#define ASCTXFCON_TXFITLOFF 8
|
||||
+#define ASCRXFCON_RXFEN 0x0001
|
||||
+#define ASCRXFCON_RXFFLU 0x0002
|
||||
+#define ASCRXFCON_RXFITLMASK 0x3F00
|
||||
+#define ASCRXFCON_RXFITLOFF 8
|
||||
+#define ASCFSTAT_RXFFLMASK 0x003F
|
||||
+#define ASCFSTAT_TXFFLMASK 0x3F00
|
||||
+#define ASCFSTAT_TXFFLOFF 8
|
||||
+#define ASCFSTAT_RXFREEMASK 0x003F0000
|
||||
+#define ASCFSTAT_RXFREEOFF 16
|
||||
+#define ASCFSTAT_TXFREEMASK 0x3F000000
|
||||
+#define ASCFSTAT_TXFREEOFF 24
|
||||
+
|
||||
+static void lqasc_tx_chars(struct uart_port *port);
|
||||
+extern void prom_printf(const char *fmt, ...);
|
||||
+static struct lq_uart_port *lqasc_port[2];
|
||||
+static struct uart_driver lqasc_reg;
|
||||
+
|
||||
+struct lq_uart_port {
|
||||
+ struct uart_port port;
|
||||
+ struct clk *clk;
|
||||
+ unsigned int tx_irq;
|
||||
+ unsigned int rx_irq;
|
||||
+ unsigned int err_irq;
|
||||
+};
|
||||
+
|
||||
+static inline struct
|
||||
+lq_uart_port *to_lq_uart_port(struct uart_port *port)
|
||||
+{
|
||||
+ return container_of(port, struct lq_uart_port, port);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+lqasc_stop_tx(struct uart_port *port)
|
||||
+{
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+lqasc_start_tx(struct uart_port *port)
|
||||
+{
|
||||
+ unsigned long flags;
|
||||
+ local_irq_save(flags);
|
||||
+ lqasc_tx_chars(port);
|
||||
+ local_irq_restore(flags);
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+lqasc_stop_rx(struct uart_port *port)
|
||||
+{
|
||||
+ lq_w32(ASCWHBSTATE_CLRREN, port->membase + IFXMIPS_ASC_WHBSTATE);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+lqasc_enable_ms(struct uart_port *port)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+lqasc_rx_chars(struct uart_port *port)
|
||||
+{
|
||||
+ struct tty_struct *tty = port->state->port.tty;
|
||||
+ unsigned int ch = 0, rsr = 0, fifocnt;
|
||||
+
|
||||
+ fifocnt = lq_r32(port->membase + IFXMIPS_ASC_FSTAT) & ASCFSTAT_RXFFLMASK;
|
||||
+ while (fifocnt--) {
|
||||
+ u8 flag = TTY_NORMAL;
|
||||
+ ch = lq_r8(port->membase + IFXMIPS_ASC_RBUF);
|
||||
+ rsr = (lq_r32(port->membase + IFXMIPS_ASC_STATE)
|
||||
+ & ASCSTATE_ANY) | UART_DUMMY_UER_RX;
|
||||
+ tty_flip_buffer_push(tty);
|
||||
+ port->icount.rx++;
|
||||
+
|
||||
+ /*
|
||||
+ * Note that the error handling code is
|
||||
+ * out of the main execution path
|
||||
+ */
|
||||
+ if (rsr & ASCSTATE_ANY) {
|
||||
+ if (rsr & ASCSTATE_PE) {
|
||||
+ port->icount.parity++;
|
||||
+ lq_w32_mask(0, ASCWHBSTATE_CLRPE,
|
||||
+ port->membase + IFXMIPS_ASC_WHBSTATE);
|
||||
+ } else if (rsr & ASCSTATE_FE) {
|
||||
+ port->icount.frame++;
|
||||
+ lq_w32_mask(0, ASCWHBSTATE_CLRFE,
|
||||
+ port->membase + IFXMIPS_ASC_WHBSTATE);
|
||||
+ }
|
||||
+ if (rsr & ASCSTATE_ROE) {
|
||||
+ port->icount.overrun++;
|
||||
+ lq_w32_mask(0, ASCWHBSTATE_CLRROE,
|
||||
+ port->membase + IFXMIPS_ASC_WHBSTATE);
|
||||
+ }
|
||||
+
|
||||
+ rsr &= port->read_status_mask;
|
||||
+
|
||||
+ if (rsr & ASCSTATE_PE)
|
||||
+ flag = TTY_PARITY;
|
||||
+ else if (rsr & ASCSTATE_FE)
|
||||
+ flag = TTY_FRAME;
|
||||
+ }
|
||||
+
|
||||
+ if ((rsr & port->ignore_status_mask) == 0)
|
||||
+ tty_insert_flip_char(tty, ch, flag);
|
||||
+
|
||||
+ if (rsr & ASCSTATE_ROE)
|
||||
+ /*
|
||||
+ * Overrun is special, since it's reported
|
||||
+ * immediately, and doesn't affect the current
|
||||
+ * character
|
||||
+ */
|
||||
+ tty_insert_flip_char(tty, 0, TTY_OVERRUN);
|
||||
+ }
|
||||
+ if (ch != 0)
|
||||
+ tty_flip_buffer_push(tty);
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+lqasc_tx_chars(struct uart_port *port)
|
||||
+{
|
||||
+ struct circ_buf *xmit = &port->state->xmit;
|
||||
+ if (uart_tx_stopped(port)) {
|
||||
+ lqasc_stop_tx(port);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ while (((lq_r32(port->membase + IFXMIPS_ASC_FSTAT) &
|
||||
+ ASCFSTAT_TXFREEMASK) >> ASCFSTAT_TXFREEOFF) != 0) {
|
||||
+ if (port->x_char) {
|
||||
+ lq_w8(port->x_char, port->membase + IFXMIPS_ASC_TBUF);
|
||||
+ port->icount.tx++;
|
||||
+ port->x_char = 0;
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (uart_circ_empty(xmit))
|
||||
+ break;
|
||||
+
|
||||
+ lq_w8(port->state->xmit.buf[port->state->xmit.tail],
|
||||
+ port->membase + IFXMIPS_ASC_TBUF);
|
||||
+ xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
|
||||
+ port->icount.tx++;
|
||||
+ }
|
||||
+
|
||||
+ if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
|
||||
+ uart_write_wakeup(port);
|
||||
+}
|
||||
+
|
||||
+static irqreturn_t
|
||||
+lqasc_tx_int(int irq, void *_port)
|
||||
+{
|
||||
+ struct uart_port *port = (struct uart_port *)_port;
|
||||
+ lq_w32(ASC_IRNCR_TIR, port->membase + IFXMIPS_ASC_IRNCR);
|
||||
+ lqasc_start_tx(port);
|
||||
+ return IRQ_HANDLED;
|
||||
+}
|
||||
+
|
||||
+static irqreturn_t
|
||||
+lqasc_err_int(int irq, void *_port)
|
||||
+{
|
||||
+ struct uart_port *port = (struct uart_port *)_port;
|
||||
+ /* clear any pending interrupts */
|
||||
+ lq_w32_mask(0, ASCWHBSTATE_CLRPE | ASCWHBSTATE_CLRFE | ASCWHBSTATE_CLRROE,
|
||||
+ port->membase + IFXMIPS_ASC_WHBSTATE);
|
||||
+ return IRQ_HANDLED;
|
||||
+}
|
||||
+
|
||||
+static irqreturn_t
|
||||
+lqasc_rx_int(int irq, void *_port)
|
||||
+{
|
||||
+ struct uart_port *port = (struct uart_port *)_port;
|
||||
+ lq_w32(ASC_IRNCR_RIR, port->membase + IFXMIPS_ASC_IRNCR);
|
||||
+ lqasc_rx_chars(port);
|
||||
+ return IRQ_HANDLED;
|
||||
+}
|
||||
+
|
||||
+static unsigned int
|
||||
+lqasc_tx_empty(struct uart_port *port)
|
||||
+{
|
||||
+ int status;
|
||||
+ status = lq_r32(port->membase + IFXMIPS_ASC_FSTAT) & ASCFSTAT_TXFFLMASK;
|
||||
+ return status ? 0 : TIOCSER_TEMT;
|
||||
+}
|
||||
+
|
||||
+static unsigned int
|
||||
+lqasc_get_mctrl(struct uart_port *port)
|
||||
+{
|
||||
+ return TIOCM_CTS | TIOCM_CAR | TIOCM_DSR;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+lqasc_set_mctrl(struct uart_port *port, u_int mctrl)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+lqasc_break_ctl(struct uart_port *port, int break_state)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+lqasc_startup(struct uart_port *port)
|
||||
+{
|
||||
+ struct lq_uart_port *ifx_port = to_lq_uart_port(port);
|
||||
+ int retval;
|
||||
+
|
||||
+ port->uartclk = clk_get_rate(ifx_port->clk);
|
||||
+
|
||||
+ lq_w32_mask(ASCCLC_DISS | ASCCLC_RMCMASK, (1 << ASCCLC_RMCOFFSET),
|
||||
+ port->membase + IFXMIPS_ASC_CLC);
|
||||
+
|
||||
+ lq_w32(0, port->membase + IFXMIPS_ASC_PISEL);
|
||||
+ lq_w32(
|
||||
+ ((TXFIFO_FL << ASCTXFCON_TXFITLOFF) & ASCTXFCON_TXFITLMASK) |
|
||||
+ ASCTXFCON_TXFEN | ASCTXFCON_TXFFLU,
|
||||
+ port->membase + IFXMIPS_ASC_TXFCON);
|
||||
+ lq_w32(
|
||||
+ ((RXFIFO_FL << ASCRXFCON_RXFITLOFF) & ASCRXFCON_RXFITLMASK)
|
||||
+ | ASCRXFCON_RXFEN | ASCRXFCON_RXFFLU,
|
||||
+ port->membase + IFXMIPS_ASC_RXFCON);
|
||||
+ /* make sure other settings are written to hardware before setting enable bits */
|
||||
+ wmb();
|
||||
+ lq_w32_mask(0, ASCCON_M_8ASYNC | ASCCON_FEN | ASCCON_TOEN |
|
||||
+ ASCCON_ROEN, port->membase + IFXMIPS_ASC_CON);
|
||||
+
|
||||
+ retval = request_irq(ifx_port->tx_irq, lqasc_tx_int,
|
||||
+ IRQF_DISABLED, "asc_tx", port);
|
||||
+ if (retval) {
|
||||
+ pr_err("failed to request lqasc_tx_int\n");
|
||||
+ return retval;
|
||||
+ }
|
||||
+
|
||||
+ retval = request_irq(ifx_port->rx_irq, lqasc_rx_int,
|
||||
+ IRQF_DISABLED, "asc_rx", port);
|
||||
+ if (retval) {
|
||||
+ pr_err("failed to request lqasc_rx_int\n");
|
||||
+ goto err1;
|
||||
+ }
|
||||
+
|
||||
+ retval = request_irq(ifx_port->err_irq, lqasc_err_int,
|
||||
+ IRQF_DISABLED, "asc_err", port);
|
||||
+ if (retval) {
|
||||
+ pr_err("failed to request lqasc_err_int\n");
|
||||
+ goto err2;
|
||||
+ }
|
||||
+
|
||||
+ lq_w32(ASC_IRNREN_RX | ASC_IRNREN_ERR | ASC_IRNREN_TX,
|
||||
+ port->membase + IFXMIPS_ASC_IRNREN);
|
||||
+ return 0;
|
||||
+
|
||||
+err2:
|
||||
+ free_irq(ifx_port->rx_irq, port);
|
||||
+err1:
|
||||
+ free_irq(ifx_port->tx_irq, port);
|
||||
+ return retval;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+lqasc_shutdown(struct uart_port *port)
|
||||
+{
|
||||
+ struct lq_uart_port *ifx_port = to_lq_uart_port(port);
|
||||
+ free_irq(ifx_port->tx_irq, port);
|
||||
+ free_irq(ifx_port->rx_irq, port);
|
||||
+ free_irq(ifx_port->err_irq, port);
|
||||
+
|
||||
+ lq_w32(0, port->membase + IFXMIPS_ASC_CON);
|
||||
+ lq_w32_mask(ASCRXFCON_RXFEN, ASCRXFCON_RXFFLU,
|
||||
+ port->membase + IFXMIPS_ASC_RXFCON);
|
||||
+ lq_w32_mask(ASCTXFCON_TXFEN, ASCTXFCON_TXFFLU,
|
||||
+ port->membase + IFXMIPS_ASC_TXFCON);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+lqasc_set_termios(struct uart_port *port,
|
||||
+ struct ktermios *new, struct ktermios *old)
|
||||
+{
|
||||
+ unsigned int cflag;
|
||||
+ unsigned int iflag;
|
||||
+ unsigned int quot;
|
||||
+ unsigned int baud;
|
||||
+ unsigned int con = 0;
|
||||
+ unsigned long flags;
|
||||
+
|
||||
+ cflag = new->c_cflag;
|
||||
+ iflag = new->c_iflag;
|
||||
+
|
||||
+ switch (cflag & CSIZE) {
|
||||
+ case CS7:
|
||||
+ con = ASCCON_M_7ASYNC;
|
||||
+ break;
|
||||
+
|
||||
+ case CS5:
|
||||
+ case CS6:
|
||||
+ default:
|
||||
+ con = ASCCON_M_8ASYNC;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (cflag & CSTOPB)
|
||||
+ con |= ASCCON_STP;
|
||||
+
|
||||
+ if (cflag & PARENB) {
|
||||
+ if (!(cflag & PARODD))
|
||||
+ con &= ~ASCCON_ODD;
|
||||
+ else
|
||||
+ con |= ASCCON_ODD;
|
||||
+ }
|
||||
+
|
||||
+ port->read_status_mask = ASCSTATE_ROE;
|
||||
+ if (iflag & INPCK)
|
||||
+ port->read_status_mask |= ASCSTATE_FE | ASCSTATE_PE;
|
||||
+
|
||||
+ port->ignore_status_mask = 0;
|
||||
+ if (iflag & IGNPAR)
|
||||
+ port->ignore_status_mask |= ASCSTATE_FE | ASCSTATE_PE;
|
||||
+
|
||||
+ if (iflag & IGNBRK) {
|
||||
+ /*
|
||||
+ * If we're ignoring parity and break indicators,
|
||||
+ * ignore overruns too (for real raw support).
|
||||
+ */
|
||||
+ if (iflag & IGNPAR)
|
||||
+ port->ignore_status_mask |= ASCSTATE_ROE;
|
||||
+ }
|
||||
+
|
||||
+ if ((cflag & CREAD) == 0)
|
||||
+ port->ignore_status_mask |= UART_DUMMY_UER_RX;
|
||||
+
|
||||
+ /* set error signals - framing, parity and overrun, enable receiver */
|
||||
+ con |= ASCCON_FEN | ASCCON_TOEN | ASCCON_ROEN;
|
||||
+
|
||||
+ local_irq_save(flags);
|
||||
+
|
||||
+ /* set up CON */
|
||||
+ lq_w32_mask(0, con, port->membase + IFXMIPS_ASC_CON);
|
||||
+
|
||||
+ /* Set baud rate - take a divider of 2 into account */
|
||||
+ baud = uart_get_baud_rate(port, new, old, 0, port->uartclk / 16);
|
||||
+ quot = uart_get_divisor(port, baud);
|
||||
+ quot = quot / 2 - 1;
|
||||
+
|
||||
+ /* disable the baudrate generator */
|
||||
+ lq_w32_mask(ASCCON_R, 0, port->membase + IFXMIPS_ASC_CON);
|
||||
+
|
||||
+ /* make sure the fractional divider is off */
|
||||
+ lq_w32_mask(ASCCON_FDE, 0, port->membase + IFXMIPS_ASC_CON);
|
||||
+
|
||||
+ /* set up to use divisor of 2 */
|
||||
+ lq_w32_mask(ASCCON_BRS, 0, port->membase + IFXMIPS_ASC_CON);
|
||||
+
|
||||
+ /* now we can write the new baudrate into the register */
|
||||
+ lq_w32(quot, port->membase + IFXMIPS_ASC_BG);
|
||||
+
|
||||
+ /* turn the baudrate generator back on */
|
||||
+ lq_w32_mask(0, ASCCON_R, port->membase + IFXMIPS_ASC_CON);
|
||||
+
|
||||
+ /* enable rx */
|
||||
+ lq_w32(ASCWHBSTATE_SETREN, port->membase + IFXMIPS_ASC_WHBSTATE);
|
||||
+
|
||||
+ local_irq_restore(flags);
|
||||
+}
|
||||
+
|
||||
+static const char*
|
||||
+lqasc_type(struct uart_port *port)
|
||||
+{
|
||||
+ if (port->type == PORT_IFXMIPSASC)
|
||||
+ return DRVNAME;
|
||||
+ else
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+lqasc_release_port(struct uart_port *port)
|
||||
+{
|
||||
+ if (port->flags & UPF_IOREMAP) {
|
||||
+ iounmap(port->membase);
|
||||
+ port->membase = NULL;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+lqasc_request_port(struct uart_port *port)
|
||||
+{
|
||||
+ struct platform_device *pdev = to_platform_device(port->dev);
|
||||
+ struct resource *mmres;
|
||||
+ int size;
|
||||
+
|
||||
+ mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
+ if (!mmres)
|
||||
+ return -ENODEV;
|
||||
+ size = resource_size(mmres);
|
||||
+
|
||||
+ if (port->flags & UPF_IOREMAP) {
|
||||
+ port->membase = ioremap_nocache(port->mapbase, size);
|
||||
+ if (port->membase == NULL)
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+lqasc_config_port(struct uart_port *port, int flags)
|
||||
+{
|
||||
+ if (flags & UART_CONFIG_TYPE) {
|
||||
+ port->type = PORT_IFXMIPSASC;
|
||||
+ lqasc_request_port(port);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+lqasc_verify_port(struct uart_port *port,
|
||||
+ struct serial_struct *ser)
|
||||
+{
|
||||
+ int ret = 0;
|
||||
+ if (ser->type != PORT_UNKNOWN && ser->type != PORT_IFXMIPSASC)
|
||||
+ ret = -EINVAL;
|
||||
+ if (ser->irq < 0 || ser->irq >= NR_IRQS)
|
||||
+ ret = -EINVAL;
|
||||
+ if (ser->baud_base < 9600)
|
||||
+ ret = -EINVAL;
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static struct uart_ops lqasc_pops = {
|
||||
+ .tx_empty = lqasc_tx_empty,
|
||||
+ .set_mctrl = lqasc_set_mctrl,
|
||||
+ .get_mctrl = lqasc_get_mctrl,
|
||||
+ .stop_tx = lqasc_stop_tx,
|
||||
+ .start_tx = lqasc_start_tx,
|
||||
+ .stop_rx = lqasc_stop_rx,
|
||||
+ .enable_ms = lqasc_enable_ms,
|
||||
+ .break_ctl = lqasc_break_ctl,
|
||||
+ .startup = lqasc_startup,
|
||||
+ .shutdown = lqasc_shutdown,
|
||||
+ .set_termios = lqasc_set_termios,
|
||||
+ .type = lqasc_type,
|
||||
+ .release_port = lqasc_release_port,
|
||||
+ .request_port = lqasc_request_port,
|
||||
+ .config_port = lqasc_config_port,
|
||||
+ .verify_port = lqasc_verify_port,
|
||||
+};
|
||||
+
|
||||
+static void
|
||||
+lqasc_console_putchar(struct uart_port *port, int ch)
|
||||
+{
|
||||
+ int fifofree;
|
||||
+
|
||||
+ if (!port->membase)
|
||||
+ return;
|
||||
+
|
||||
+ do {
|
||||
+ fifofree = (lq_r32(port->membase + IFXMIPS_ASC_FSTAT)
|
||||
+ & ASCFSTAT_TXFREEMASK) >> ASCFSTAT_TXFREEOFF;
|
||||
+ } while (fifofree == 0);
|
||||
+ lq_w8(ch, port->membase + IFXMIPS_ASC_TBUF);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static void
|
||||
+lqasc_console_write(struct console *co, const char *s, u_int count)
|
||||
+{
|
||||
+ struct lq_uart_port *ifx_port;
|
||||
+ struct uart_port *port;
|
||||
+ unsigned long flags;
|
||||
+
|
||||
+ if (co->index >= MAXPORTS)
|
||||
+ return;
|
||||
+
|
||||
+ ifx_port = lqasc_port[co->index];
|
||||
+ if (!ifx_port)
|
||||
+ return;
|
||||
+
|
||||
+ port = &ifx_port->port;
|
||||
+
|
||||
+ local_irq_save(flags);
|
||||
+ uart_console_write(port, s, count, lqasc_console_putchar);
|
||||
+ local_irq_restore(flags);
|
||||
+}
|
||||
+
|
||||
+static int __init
|
||||
+lqasc_console_setup(struct console *co, char *options)
|
||||
+{
|
||||
+ struct lq_uart_port *ifx_port;
|
||||
+ struct uart_port *port;
|
||||
+ int baud = 115200;
|
||||
+ int bits = 8;
|
||||
+ int parity = 'n';
|
||||
+ int flow = 'n';
|
||||
+
|
||||
+ if (co->index >= MAXPORTS)
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ ifx_port = lqasc_port[co->index];
|
||||
+ if (!ifx_port)
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ port = &ifx_port->port;
|
||||
+
|
||||
+ port->uartclk = clk_get_rate(ifx_port->clk);
|
||||
+
|
||||
+ if (options)
|
||||
+ uart_parse_options(options, &baud, &parity, &bits, &flow);
|
||||
+ return uart_set_options(port, co, baud, parity, bits, flow);
|
||||
+}
|
||||
+
|
||||
+static struct console lqasc_console = {
|
||||
+ .name = "ttyS",
|
||||
+ .write = lqasc_console_write,
|
||||
+ .device = uart_console_device,
|
||||
+ .setup = lqasc_console_setup,
|
||||
+ .flags = CON_PRINTBUFFER,
|
||||
+ .index = -1,
|
||||
+ .data = &lqasc_reg,
|
||||
+};
|
||||
+
|
||||
+static int __init
|
||||
+lqasc_console_init(void)
|
||||
+{
|
||||
+ register_console(&lqasc_console);
|
||||
+ return 0;
|
||||
+}
|
||||
+console_initcall(lqasc_console_init);
|
||||
+
|
||||
+static struct uart_driver lqasc_reg = {
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .driver_name = DRVNAME,
|
||||
+ .dev_name = "ttyS",
|
||||
+ .major = TTY_MAJOR,
|
||||
+ .minor = 64,
|
||||
+ .nr = MAXPORTS,
|
||||
+ .cons = &lqasc_console,
|
||||
+};
|
||||
+
|
||||
+static int __devinit
|
||||
+lqasc_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct lq_uart_port *ifx_port;
|
||||
+ struct uart_port *port;
|
||||
+ struct resource *mmres, *irqres;
|
||||
+ int tx_irq, rx_irq, err_irq;
|
||||
+ struct clk *clk;
|
||||
+ int ret;
|
||||
+
|
||||
+ mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
+ irqres = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
|
||||
+ if (!mmres || !irqres)
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ if (pdev->id >= MAXPORTS)
|
||||
+ return -EBUSY;
|
||||
+
|
||||
+ if (lqasc_port[pdev->id] != NULL)
|
||||
+ return -EBUSY;
|
||||
+
|
||||
+ clk = clk_get(&pdev->dev, "fpi");
|
||||
+ if (IS_ERR(clk)) {
|
||||
+ pr_err("failed to get fpi clk\n");
|
||||
+ return -ENOENT;
|
||||
+ }
|
||||
+
|
||||
+ tx_irq = platform_get_irq_byname(pdev, "tx");
|
||||
+ if (tx_irq < 0) {
|
||||
+ /* without named resources: assume standard irq scheme */
|
||||
+ tx_irq = irqres->start;
|
||||
+ rx_irq = irqres->start+2;
|
||||
+ err_irq = irqres->start+3;
|
||||
+ } else {
|
||||
+ /* other irqs must be named also! */
|
||||
+ rx_irq = platform_get_irq_byname(pdev, "rx");
|
||||
+ err_irq = platform_get_irq_byname(pdev, "err");
|
||||
+ if ((rx_irq < 0) | (err_irq < 0))
|
||||
+ return -ENODEV;
|
||||
+ }
|
||||
+
|
||||
+ ifx_port = kzalloc(sizeof(struct lq_uart_port), GFP_KERNEL);
|
||||
+ if (!ifx_port)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ port = &ifx_port->port;
|
||||
+
|
||||
+ port->iotype = SERIAL_IO_MEM;
|
||||
+ port->flags = ASYNC_BOOT_AUTOCONF | UPF_IOREMAP;
|
||||
+ port->ops = &lqasc_pops;
|
||||
+ port->fifosize = 16;
|
||||
+ port->type = PORT_IFXMIPSASC,
|
||||
+ port->line = pdev->id;
|
||||
+ port->dev = &pdev->dev;
|
||||
+
|
||||
+ port->irq = tx_irq; /* unused, just to be backward-compatibe */
|
||||
+ port->mapbase = mmres->start;
|
||||
+
|
||||
+ ifx_port->clk = clk;
|
||||
+
|
||||
+ ifx_port->tx_irq = tx_irq;
|
||||
+ ifx_port->rx_irq = rx_irq;
|
||||
+ ifx_port->err_irq = err_irq;
|
||||
+
|
||||
+ lqasc_port[pdev->id] = ifx_port;
|
||||
+ platform_set_drvdata(pdev, ifx_port);
|
||||
+
|
||||
+ ret = uart_add_one_port(&lqasc_reg, port);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int __devexit
|
||||
+lqasc_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct lq_uart_port *ifx_port = platform_get_drvdata(pdev);
|
||||
+ int ret;
|
||||
+
|
||||
+ clk_put(ifx_port->clk);
|
||||
+ platform_set_drvdata(pdev, NULL);
|
||||
+ lqasc_port[pdev->id] = NULL;
|
||||
+ ret = uart_remove_one_port(&lqasc_reg, &ifx_port->port);
|
||||
+ kfree(ifx_port);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct platform_driver lqasc_driver = {
|
||||
+ .probe = lqasc_probe,
|
||||
+ .remove = __devexit_p(lqasc_remove),
|
||||
+
|
||||
+ .driver = {
|
||||
+ .name = DRVNAME,
|
||||
+ .owner = THIS_MODULE,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+int __init
|
||||
+init_lqasc(void)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = uart_register_driver(&lqasc_reg);
|
||||
+ if (ret != 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = platform_driver_register(&lqasc_driver);
|
||||
+ if (ret != 0)
|
||||
+ uart_unregister_driver(&lqasc_reg);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+void __exit
|
||||
+exit_lqasc(void)
|
||||
+{
|
||||
+ platform_driver_unregister(&lqasc_driver);
|
||||
+ uart_unregister_driver(&lqasc_reg);
|
||||
+}
|
||||
+
|
||||
+module_init(init_lqasc);
|
||||
+module_exit(exit_lqasc);
|
||||
+
|
||||
+MODULE_DESCRIPTION("Lantiq serial port driver");
|
||||
+MODULE_LICENSE("GPL");
|
||||
245
target/linux/lantiq/patches/210-nor.patch
Normal file
245
target/linux/lantiq/patches/210-nor.patch
Normal file
@@ -0,0 +1,245 @@
|
||||
--- a/drivers/mtd/maps/Kconfig
|
||||
+++ b/drivers/mtd/maps/Kconfig
|
||||
@@ -251,6 +251,12 @@
|
||||
help
|
||||
Support for flash chips on NETtel/SecureEdge/SnapGear boards.
|
||||
|
||||
+config MTD_LANTIQ
|
||||
+ bool "Lantiq SoC NOR support"
|
||||
+ depends on LANTIQ && MTD_PARTITIONS
|
||||
+ help
|
||||
+ Support for NOR flsh chips on Lantiq SoC
|
||||
+
|
||||
config MTD_DILNETPC
|
||||
tristate "CFI Flash device mapped on DIL/Net PC"
|
||||
depends on X86 && MTD_CONCAT && MTD_PARTITIONS && MTD_CFI_INTELEXT && BROKEN
|
||||
--- 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
|
||||
--- /dev/null
|
||||
+++ b/drivers/mtd/maps/lantiq.c
|
||||
@@ -0,0 +1,169 @@
|
||||
+/*
|
||||
+ * This program is free software; you can redistribute it and/or modify it
|
||||
+ * under the terms of the GNU General Public License version 2 as published
|
||||
+ * by the Free Software Foundation.
|
||||
+ *
|
||||
+ * Copyright (C) 2004 Liu Peng Infineon IFAP DC COM CPE
|
||||
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
|
||||
+ */
|
||||
+
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/types.h>
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/mtd/mtd.h>
|
||||
+#include <linux/mtd/map.h>
|
||||
+#include <linux/mtd/partitions.h>
|
||||
+#include <linux/mtd/cfi.h>
|
||||
+#include <linux/magic.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/mtd/physmap.h>
|
||||
+
|
||||
+#include <lantiq.h>
|
||||
+#include <lantiq_platform.h>
|
||||
+
|
||||
+static map_word
|
||||
+lq_read16(struct map_info *map, unsigned long adr)
|
||||
+{
|
||||
+ unsigned long flags;
|
||||
+ map_word temp;
|
||||
+ spin_lock_irqsave(&ebu_lock, flags);
|
||||
+ adr ^= 2;
|
||||
+ temp.x[0] = *((__u16 *)(map->virt + adr));
|
||||
+ spin_unlock_irqrestore(&ebu_lock, flags);
|
||||
+ return temp;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+lq_write16(struct map_info *map, map_word d, unsigned long adr)
|
||||
+{
|
||||
+ unsigned long flags;
|
||||
+ spin_lock_irqsave(&ebu_lock, flags);
|
||||
+ adr ^= 2;
|
||||
+ *((__u16 *)(map->virt + adr)) = d.x[0];
|
||||
+ spin_unlock_irqrestore(&ebu_lock, flags);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+lq_copy_from(struct map_info *map, void *to,
|
||||
+ unsigned long from, ssize_t len)
|
||||
+{
|
||||
+ unsigned char *p;
|
||||
+ unsigned char *to_8;
|
||||
+ unsigned long flags;
|
||||
+ spin_lock_irqsave(&ebu_lock, flags);
|
||||
+ from = (unsigned long)(from + map->virt);
|
||||
+ p = (unsigned char *) from;
|
||||
+ to_8 = (unsigned char *) to;
|
||||
+ while (len--)
|
||||
+ *to_8++ = *p++;
|
||||
+ spin_unlock_irqrestore(&ebu_lock, flags);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+lq_copy_to(struct map_info *map, unsigned long to,
|
||||
+ const void *from, ssize_t len)
|
||||
+{
|
||||
+ unsigned char *p = (unsigned char *)from;
|
||||
+ unsigned char *to_8;
|
||||
+ unsigned long flags;
|
||||
+ spin_lock_irqsave(&ebu_lock, flags);
|
||||
+ to += (unsigned long) map->virt;
|
||||
+ to_8 = (unsigned char *)to;
|
||||
+ while (len--)
|
||||
+ *p++ = *to_8++;
|
||||
+ spin_unlock_irqrestore(&ebu_lock, flags);
|
||||
+}
|
||||
+
|
||||
+static const char *part_probe_types[] = { "cmdlinepart", NULL };
|
||||
+
|
||||
+static struct map_info lq_map = {
|
||||
+ .name = "lq_nor",
|
||||
+ .bankwidth = 2,
|
||||
+ .read = lq_read16,
|
||||
+ .write = lq_write16,
|
||||
+ .copy_from = lq_copy_from,
|
||||
+ .copy_to = lq_copy_to,
|
||||
+};
|
||||
+
|
||||
+static int
|
||||
+lq_mtd_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct physmap_flash_data *lq_mtd_data =
|
||||
+ (struct physmap_flash_data*) dev_get_platdata(&pdev->dev);
|
||||
+ struct mtd_info *lq_mtd = NULL;
|
||||
+ struct mtd_partition *parts = NULL;
|
||||
+ struct resource *res = 0;
|
||||
+ int nr_parts = 0;
|
||||
+
|
||||
+#ifdef CONFIG_SOC_LANTIQ_XWAY
|
||||
+ lq_w32(lq_r32(LQ_EBU_BUSCON0) & ~EBU_WRDIS, LQ_EBU_BUSCON0);
|
||||
+#endif
|
||||
+
|
||||
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
+ if(!res)
|
||||
+ {
|
||||
+ dev_err(&pdev->dev, "failed to get memory resource");
|
||||
+ return -ENOENT;
|
||||
+ }
|
||||
+ res = request_mem_region(res->start, resource_size(res),
|
||||
+ dev_name(&pdev->dev));
|
||||
+ if(!res)
|
||||
+ {
|
||||
+ dev_err(&pdev->dev, "failed to request mem resource");
|
||||
+ return -EBUSY;
|
||||
+ }
|
||||
+
|
||||
+ lq_map.phys = res->start;
|
||||
+ lq_map.size = resource_size(res);
|
||||
+ lq_map.virt = ioremap_nocache(lq_map.phys, lq_map.size);
|
||||
+
|
||||
+ if (!lq_map.virt ) {
|
||||
+ dev_err(&pdev->dev, "failed to ioremap!\n");
|
||||
+ return -EIO;
|
||||
+ }
|
||||
+
|
||||
+ lq_mtd = (struct mtd_info *) do_map_probe("cfi_probe", &lq_map);
|
||||
+ if (!lq_mtd) {
|
||||
+ iounmap(lq_map.virt);
|
||||
+ dev_err(&pdev->dev, "probing failed\n");
|
||||
+ return -ENXIO;
|
||||
+ }
|
||||
+
|
||||
+ lq_mtd->owner = THIS_MODULE;
|
||||
+
|
||||
+ nr_parts = parse_mtd_partitions(lq_mtd, part_probe_types, &parts, 0);
|
||||
+ if (nr_parts > 0) {
|
||||
+ dev_info(&pdev->dev, "using %d partitions from cmdline", nr_parts);
|
||||
+ } else {
|
||||
+ nr_parts = lq_mtd_data->nr_parts;
|
||||
+ parts = lq_mtd_data->parts;
|
||||
+ }
|
||||
+
|
||||
+ add_mtd_partitions(lq_mtd, parts, nr_parts);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct platform_driver lq_mtd_driver = {
|
||||
+ .probe = lq_mtd_probe,
|
||||
+ .driver = {
|
||||
+ .name = "lq_nor",
|
||||
+ .owner = THIS_MODULE,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+int __init
|
||||
+init_lq_mtd(void)
|
||||
+{
|
||||
+ int ret = platform_driver_register(&lq_mtd_driver);
|
||||
+ if (ret)
|
||||
+ printk(KERN_INFO "lq_nor: error registering platfom driver");
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+module_init(init_lq_mtd);
|
||||
+
|
||||
+MODULE_LICENSE("GPL");
|
||||
+MODULE_AUTHOR("John Crispin <blogic@openwrt.org>");
|
||||
+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 @@
|
||||
/* #define CMDSET0001_DISABLE_WRITE_SUSPEND */
|
||||
|
||||
// debugging, turns off buffer write mode if set to 1
|
||||
-#define FORCE_WORD_WRITE 0
|
||||
+#ifdef CONFIG_LANTIQ
|
||||
+# define FORCE_WORD_WRITE 1
|
||||
+#else
|
||||
+# define FORCE_WORD_WRITE 0
|
||||
+#endif
|
||||
|
||||
/* Intel chips */
|
||||
#define I82802AB 0x00ad
|
||||
@@ -1491,6 +1495,9 @@
|
||||
int ret=0;
|
||||
|
||||
adr += chip->start;
|
||||
+#ifdef CONFIG_LANTIQ
|
||||
+ adr ^= 2;
|
||||
+#endif
|
||||
|
||||
switch (mode) {
|
||||
case FL_WRITING:
|
||||
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
|
||||
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
|
||||
@@ -40,7 +40,11 @@
|
||||
#include <linux/mtd/xip.h>
|
||||
|
||||
#define AMD_BOOTLOC_BUG
|
||||
-#define FORCE_WORD_WRITE 0
|
||||
+#ifdef CONFIG_LANTIQ
|
||||
+# define FORCE_WORD_WRITE 1
|
||||
+#else
|
||||
+# define FORCE_WORD_WRITE 0
|
||||
+#endif
|
||||
|
||||
#define MAX_WORD_RETRIES 3
|
||||
|
||||
@@ -1156,6 +1160,10 @@
|
||||
|
||||
adr += chip->start;
|
||||
|
||||
+#ifdef CONFIG_LANTIQ
|
||||
+ adr ^= 2;
|
||||
+#endif
|
||||
+
|
||||
mutex_lock(&chip->mutex);
|
||||
ret = get_chip(map, chip, adr, FL_WRITING);
|
||||
if (ret) {
|
||||
99
target/linux/lantiq/patches/211-nor_split.patch
Normal file
99
target/linux/lantiq/patches/211-nor_split.patch
Normal file
@@ -0,0 +1,99 @@
|
||||
--- 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;
|
||||
}
|
||||
|
||||
580
target/linux/lantiq/patches/230-xway_etop.patch
Normal file
580
target/linux/lantiq/patches/230-xway_etop.patch
Normal file
@@ -0,0 +1,580 @@
|
||||
--- a/drivers/net/Kconfig
|
||||
+++ b/drivers/net/Kconfig
|
||||
@@ -343,6 +343,12 @@ config MACB
|
||||
|
||||
source "drivers/net/arm/Kconfig"
|
||||
|
||||
+config LANTIQ_ETOP
|
||||
+ tristate "Lantiq SoC ETOP driver"
|
||||
+ depends on SOC_LANTIQ_XWAY
|
||||
+ help
|
||||
+ Support for the MII0 inside the Lantiq SoC
|
||||
+
|
||||
config AX88796
|
||||
tristate "ASIX AX88796 NE2000 clone support"
|
||||
depends on ARM || MIPS || SUPERH
|
||||
--- a/drivers/net/Makefile
|
||||
+++ b/drivers/net/Makefile
|
||||
@@ -204,6 +204,7 @@ obj-$(CONFIG_SNI_82596) += sni_82596.o
|
||||
obj-$(CONFIG_MVME16x_NET) += 82596.o
|
||||
obj-$(CONFIG_BVME6000_NET) += 82596.o
|
||||
obj-$(CONFIG_SC92031) += sc92031.o
|
||||
+obj-$(CONFIG_LANTIQ_ETOP) += lantiq_etop.o
|
||||
|
||||
# This is also a 82596 and should probably be merged
|
||||
obj-$(CONFIG_LP486E) += lp486e.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/lantiq_etop.c
|
||||
@@ -0,0 +1,552 @@
|
||||
+/*
|
||||
+ * 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.
|
||||
+ *
|
||||
+ * 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.
|
||||
+ *
|
||||
+ * Copyright (C) 2005 Wu Qi Ming <Qi-Ming.Wu@infineon.com>
|
||||
+ * Copyright (C) 2008 John Crispin <blogic@openwrt.org>
|
||||
+ */
|
||||
+
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/errno.h>
|
||||
+#include <linux/types.h>
|
||||
+#include <linux/interrupt.h>
|
||||
+#include <linux/uaccess.h>
|
||||
+#include <linux/in.h>
|
||||
+#include <linux/netdevice.h>
|
||||
+#include <linux/etherdevice.h>
|
||||
+#include <linux/phy.h>
|
||||
+#include <linux/ip.h>
|
||||
+#include <linux/tcp.h>
|
||||
+#include <linux/skbuff.h>
|
||||
+#include <linux/mm.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/ethtool.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/delay.h>
|
||||
+
|
||||
+#include <asm/checksum.h>
|
||||
+
|
||||
+#include <xway.h>
|
||||
+#include <xway_dma.h>
|
||||
+#include <lantiq_platform.h>
|
||||
+
|
||||
+#define ETHERNET_PACKET_DMA_BUFFER_SIZE 0x600
|
||||
+#define LQ_PPE32_MEM_MAP ((u32 *)(LQ_PPE32_BASE_ADDR + 0x10000))
|
||||
+#define LQ_PPE32_SRST ((u32 *)(LQ_PPE32_BASE_ADDR + 0x10080))
|
||||
+
|
||||
+/* mdio access */
|
||||
+#define LQ_PPE32_MDIO_CFG ((u32 *)(LQ_PPE32_BASE_ADDR + 0x11800))
|
||||
+#define LQ_PPE32_MDIO_ACC ((u32 *)(LQ_PPE32_BASE_ADDR + 0x11804))
|
||||
+
|
||||
+#define MDIO_ACC_REQUEST 0x80000000
|
||||
+#define MDIO_ACC_READ 0x40000000
|
||||
+#define MDIO_ACC_ADDR_MASK 0x1f
|
||||
+#define MDIO_ACC_ADDR_OFFSET 0x15
|
||||
+#define MDIO_ACC_REG_MASK 0x1f
|
||||
+#define MDIO_ACC_REG_OFFSET 0x10
|
||||
+#define MDIO_ACC_VAL_MASK 0xffff
|
||||
+
|
||||
+/* configuration */
|
||||
+#define LQ_PPE32_CFG ((u32 *)(LQ_PPE32_MEM_MAP + 0x1808))
|
||||
+
|
||||
+#define PPE32_MII_MASK 0xfffffffc
|
||||
+#define PPE32_MII_NORMAL 0x8
|
||||
+#define PPE32_MII_REVERSE 0xe
|
||||
+
|
||||
+/* packet length */
|
||||
+#define LQ_PPE32_IG_PLEN_CTRL ((u32 *)(LQ_PPE32_MEM_MAP + 0x1820))
|
||||
+
|
||||
+#define PPE32_PLEN_OVER 0x5ee
|
||||
+#define PPE32_PLEN_UNDER 0x400000
|
||||
+
|
||||
+/* enet */
|
||||
+#define LQ_PPE32_ENET_MAC_CFG ((u32 *)(LQ_PPE32_MEM_MAP + 0x1840))
|
||||
+
|
||||
+#define PPE32_CGEN 0x800
|
||||
+
|
||||
+struct lq_mii_priv {
|
||||
+ struct net_device_stats stats;
|
||||
+ struct dma_device_info *dma_device;
|
||||
+ struct sk_buff *skb;
|
||||
+
|
||||
+ struct mii_bus *mii_bus;
|
||||
+ struct phy_device *phydev;
|
||||
+ int oldlink, oldspeed, oldduplex;
|
||||
+};
|
||||
+
|
||||
+static struct net_device *lq_etop_dev;
|
||||
+static unsigned char mac_addr[MAX_ADDR_LEN];
|
||||
+
|
||||
+static int lq_mdiobus_write(struct mii_bus *bus, int phy_addr,
|
||||
+ int phy_reg, u16 phy_data)
|
||||
+{
|
||||
+ u32 val = MDIO_ACC_REQUEST |
|
||||
+ ((phy_addr & MDIO_ACC_ADDR_MASK) << MDIO_ACC_ADDR_OFFSET) |
|
||||
+ ((phy_reg & MDIO_ACC_REG_MASK) << MDIO_ACC_REG_OFFSET) |
|
||||
+ phy_data;
|
||||
+
|
||||
+ while (lq_r32(LQ_PPE32_MDIO_ACC) & MDIO_ACC_REQUEST)
|
||||
+ ;
|
||||
+ lq_w32(val, LQ_PPE32_MDIO_ACC);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int lq_mdiobus_read(struct mii_bus *bus, int phy_addr, int phy_reg)
|
||||
+{
|
||||
+ u32 val = MDIO_ACC_REQUEST | MDIO_ACC_READ |
|
||||
+ ((phy_addr & MDIO_ACC_ADDR_MASK) << MDIO_ACC_ADDR_OFFSET) |
|
||||
+ ((phy_reg & MDIO_ACC_REG_MASK) << MDIO_ACC_REG_OFFSET);
|
||||
+
|
||||
+ while (lq_r32(LQ_PPE32_MDIO_ACC) & MDIO_ACC_REQUEST)
|
||||
+ ;
|
||||
+ lq_w32(val, LQ_PPE32_MDIO_ACC);
|
||||
+ while (lq_r32(LQ_PPE32_MDIO_ACC) & MDIO_ACC_REQUEST)
|
||||
+ ;
|
||||
+ val = lq_r32(LQ_PPE32_MDIO_ACC) & MDIO_ACC_VAL_MASK;
|
||||
+ return val;
|
||||
+}
|
||||
+
|
||||
+int lq_mii_open(struct net_device *dev)
|
||||
+{
|
||||
+ struct lq_mii_priv *priv = (struct lq_mii_priv *)netdev_priv(dev);
|
||||
+ struct dma_device_info *dma_dev = priv->dma_device;
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < dma_dev->max_rx_chan_num; i++) {
|
||||
+ if ((dma_dev->rx_chan[i])->control == LQ_DMA_CH_ON)
|
||||
+ (dma_dev->rx_chan[i])->open(dma_dev->rx_chan[i]);
|
||||
+ }
|
||||
+ netif_start_queue(dev);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int lq_mii_release(struct net_device *dev)
|
||||
+{
|
||||
+ struct lq_mii_priv *priv = (struct lq_mii_priv *)netdev_priv(dev);
|
||||
+ struct dma_device_info *dma_dev = priv->dma_device;
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < dma_dev->max_rx_chan_num; i++)
|
||||
+ dma_dev->rx_chan[i]->close(dma_dev->rx_chan[i]);
|
||||
+ netif_stop_queue(dev);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int lq_mii_hw_receive(struct net_device *dev, struct dma_device_info *dma_dev)
|
||||
+{
|
||||
+ struct lq_mii_priv *priv = (struct lq_mii_priv *)netdev_priv(dev);
|
||||
+ unsigned char *buf = NULL;
|
||||
+ struct sk_buff *skb = NULL;
|
||||
+ int len = 0;
|
||||
+
|
||||
+ len = dma_device_read(dma_dev, &buf, (void **)&skb);
|
||||
+
|
||||
+ if (len >= ETHERNET_PACKET_DMA_BUFFER_SIZE) {
|
||||
+ printk(KERN_INFO "lq_etop: packet too large %d\n", len);
|
||||
+ goto lq_mii_hw_receive_err_exit;
|
||||
+ }
|
||||
+
|
||||
+ /* remove CRC */
|
||||
+ len -= 4;
|
||||
+ if (skb == NULL) {
|
||||
+ printk(KERN_INFO "lq_etop: cannot restore pointer\n");
|
||||
+ goto lq_mii_hw_receive_err_exit;
|
||||
+ }
|
||||
+
|
||||
+ if (len > (skb->end - skb->tail)) {
|
||||
+ printk(KERN_INFO "lq_etop: BUG, len:%d end:%p tail:%p\n",
|
||||
+ (len+4), skb->end, skb->tail);
|
||||
+ goto lq_mii_hw_receive_err_exit;
|
||||
+ }
|
||||
+
|
||||
+ skb_put(skb, len);
|
||||
+ skb->dev = dev;
|
||||
+ skb->protocol = eth_type_trans(skb, dev);
|
||||
+ netif_rx(skb);
|
||||
+
|
||||
+ priv->stats.rx_packets++;
|
||||
+ priv->stats.rx_bytes += len;
|
||||
+ return 0;
|
||||
+
|
||||
+lq_mii_hw_receive_err_exit:
|
||||
+ if (len == 0) {
|
||||
+ if (skb)
|
||||
+ dev_kfree_skb_any(skb);
|
||||
+ priv->stats.rx_errors++;
|
||||
+ priv->stats.rx_dropped++;
|
||||
+ return -EIO;
|
||||
+ } else {
|
||||
+ return len;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+int lq_mii_hw_tx(char *buf, int len, struct net_device *dev)
|
||||
+{
|
||||
+ int ret = 0;
|
||||
+ struct lq_mii_priv *priv = netdev_priv(dev);
|
||||
+ struct dma_device_info *dma_dev = priv->dma_device;
|
||||
+ ret = dma_device_write(dma_dev, buf, len, priv->skb);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+int lq_mii_tx(struct sk_buff *skb, struct net_device *dev)
|
||||
+{
|
||||
+ int len;
|
||||
+ char *data;
|
||||
+ struct lq_mii_priv *priv = netdev_priv(dev);
|
||||
+ struct dma_device_info *dma_dev = priv->dma_device;
|
||||
+
|
||||
+ len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len;
|
||||
+ data = skb->data;
|
||||
+ priv->skb = skb;
|
||||
+ dev->trans_start = jiffies;
|
||||
+ /* TODO: we got more than 1 dma channel,
|
||||
+ so we should do something intelligent here to select one */
|
||||
+ dma_dev->current_tx_chan = 0;
|
||||
+
|
||||
+ wmb();
|
||||
+
|
||||
+ if (lq_mii_hw_tx(data, len, dev) != len) {
|
||||
+ dev_kfree_skb_any(skb);
|
||||
+ priv->stats.tx_errors++;
|
||||
+ priv->stats.tx_dropped++;
|
||||
+ } else {
|
||||
+ priv->stats.tx_packets++;
|
||||
+ priv->stats.tx_bytes += len;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+void lq_mii_tx_timeout(struct net_device *dev)
|
||||
+{
|
||||
+ int i;
|
||||
+ struct lq_mii_priv *priv = (struct lq_mii_priv *)netdev_priv(dev);
|
||||
+
|
||||
+ priv->stats.tx_errors++;
|
||||
+ for (i = 0; i < priv->dma_device->max_tx_chan_num; i++)
|
||||
+ priv->dma_device->tx_chan[i]->disable_irq(priv->dma_device->tx_chan[i]);
|
||||
+ netif_wake_queue(dev);
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+int dma_intr_handler(struct dma_device_info *dma_dev, int status)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ switch (status) {
|
||||
+ case RCV_INT:
|
||||
+ lq_mii_hw_receive(lq_etop_dev, dma_dev);
|
||||
+ break;
|
||||
+
|
||||
+ case TX_BUF_FULL_INT:
|
||||
+ printk(KERN_INFO "lq_etop: tx buffer full\n");
|
||||
+ netif_stop_queue(lq_etop_dev);
|
||||
+ for (i = 0; i < dma_dev->max_tx_chan_num; i++) {
|
||||
+ if ((dma_dev->tx_chan[i])->control == LQ_DMA_CH_ON)
|
||||
+ dma_dev->tx_chan[i]->enable_irq(dma_dev->tx_chan[i]);
|
||||
+ }
|
||||
+ break;
|
||||
+
|
||||
+ case TRANSMIT_CPT_INT:
|
||||
+ for (i = 0; i < dma_dev->max_tx_chan_num; i++)
|
||||
+ dma_dev->tx_chan[i]->disable_irq(dma_dev->tx_chan[i]);
|
||||
+
|
||||
+ netif_wake_queue(lq_etop_dev);
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+unsigned char *lq_etop_dma_buffer_alloc(int len, int *byte_offset, void **opt)
|
||||
+{
|
||||
+ unsigned char *buffer = NULL;
|
||||
+ struct sk_buff *skb = NULL;
|
||||
+
|
||||
+ skb = dev_alloc_skb(ETHERNET_PACKET_DMA_BUFFER_SIZE);
|
||||
+ if (skb == NULL)
|
||||
+ return NULL;
|
||||
+
|
||||
+ buffer = (unsigned char *)(skb->data);
|
||||
+ skb_reserve(skb, 2);
|
||||
+ *(int *)opt = (int)skb;
|
||||
+ *byte_offset = 2;
|
||||
+
|
||||
+ return buffer;
|
||||
+}
|
||||
+
|
||||
+void lq_etop_dma_buffer_free(unsigned char *dataptr, void *opt)
|
||||
+{
|
||||
+ struct sk_buff *skb = NULL;
|
||||
+
|
||||
+ if (opt == NULL) {
|
||||
+ kfree(dataptr);
|
||||
+ } else {
|
||||
+ skb = (struct sk_buff *)opt;
|
||||
+ dev_kfree_skb_any(skb);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+lq_adjust_link(struct net_device *dev)
|
||||
+{
|
||||
+ struct lq_mii_priv *priv = netdev_priv(dev);
|
||||
+ struct phy_device *phydev = priv->phydev;
|
||||
+ int new_state = 0;
|
||||
+
|
||||
+ /* Did anything change? */
|
||||
+ if (priv->oldlink != phydev->link ||
|
||||
+ priv->oldduplex != phydev->duplex ||
|
||||
+ priv->oldspeed != phydev->speed) {
|
||||
+ /* Yes, so update status and mark as changed */
|
||||
+ new_state = 1;
|
||||
+ priv->oldduplex = phydev->duplex;
|
||||
+ priv->oldspeed = phydev->speed;
|
||||
+ priv->oldlink = phydev->link;
|
||||
+ }
|
||||
+
|
||||
+ /* If link status changed, show new status */
|
||||
+ if (new_state)
|
||||
+ phy_print_status(phydev);
|
||||
+}
|
||||
+
|
||||
+static int mii_probe(struct net_device *dev)
|
||||
+{
|
||||
+ struct lq_mii_priv *priv = netdev_priv(dev);
|
||||
+ struct phy_device *phydev = NULL;
|
||||
+ int phy_addr;
|
||||
+
|
||||
+ priv->oldlink = 0;
|
||||
+ priv->oldspeed = 0;
|
||||
+ priv->oldduplex = -1;
|
||||
+
|
||||
+ /* find the first (lowest address) PHY on the current MAC's MII bus */
|
||||
+ for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) {
|
||||
+ if (priv->mii_bus->phy_map[phy_addr]) {
|
||||
+ phydev = priv->mii_bus->phy_map[phy_addr];
|
||||
+ break; /* break out with first one found */
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (!phydev) {
|
||||
+ printk (KERN_ERR "%s: no PHY found\n", dev->name);
|
||||
+ return -ENODEV;
|
||||
+ }
|
||||
+
|
||||
+ /* now we are supposed to have a proper phydev, to attach to... */
|
||||
+ BUG_ON(!phydev);
|
||||
+ BUG_ON(phydev->attached_dev);
|
||||
+
|
||||
+ phydev = phy_connect(dev, dev_name(&phydev->dev), &lq_adjust_link,
|
||||
+ 0, PHY_INTERFACE_MODE_MII);
|
||||
+
|
||||
+ if (IS_ERR(phydev)) {
|
||||
+ printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name);
|
||||
+ return PTR_ERR(phydev);
|
||||
+ }
|
||||
+
|
||||
+ /* mask with MAC supported features */
|
||||
+ phydev->supported &= (SUPPORTED_10baseT_Half
|
||||
+ | SUPPORTED_10baseT_Full
|
||||
+ | SUPPORTED_100baseT_Half
|
||||
+ | SUPPORTED_100baseT_Full
|
||||
+ | SUPPORTED_Autoneg
|
||||
+ /* | SUPPORTED_Pause | SUPPORTED_Asym_Pause */
|
||||
+ | SUPPORTED_MII
|
||||
+ | SUPPORTED_TP);
|
||||
+
|
||||
+ phydev->advertising = phydev->supported;
|
||||
+
|
||||
+ priv->phydev = phydev;
|
||||
+
|
||||
+ printk(KERN_INFO "%s: attached PHY driver [%s] "
|
||||
+ "(mii_bus:phy_addr=%s, irq=%d)\n",
|
||||
+ dev->name, phydev->drv->name, dev_name(&phydev->dev), phydev->irq);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static int lq_mii_dev_init(struct net_device *dev)
|
||||
+{
|
||||
+ int i;
|
||||
+ struct lq_mii_priv *priv = (struct lq_mii_priv *)netdev_priv(dev);
|
||||
+ ether_setup(dev);
|
||||
+ dev->watchdog_timeo = 10 * HZ;
|
||||
+ dev->mtu = 1500;
|
||||
+ memset(priv, 0, sizeof(struct lq_mii_priv));
|
||||
+ priv->dma_device = dma_device_reserve("PPE");
|
||||
+ if (!priv->dma_device) {
|
||||
+ BUG();
|
||||
+ return -ENODEV;
|
||||
+ }
|
||||
+ priv->dma_device->buffer_alloc = &lq_etop_dma_buffer_alloc;
|
||||
+ priv->dma_device->buffer_free = &lq_etop_dma_buffer_free;
|
||||
+ priv->dma_device->intr_handler = &dma_intr_handler;
|
||||
+ priv->dma_device->max_rx_chan_num = 4;
|
||||
+
|
||||
+ for (i = 0; i < priv->dma_device->max_rx_chan_num; i++) {
|
||||
+ priv->dma_device->rx_chan[i]->packet_size = ETHERNET_PACKET_DMA_BUFFER_SIZE;
|
||||
+ priv->dma_device->rx_chan[i]->control = LQ_DMA_CH_ON;
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < priv->dma_device->max_tx_chan_num; i++)
|
||||
+ if (i == 0)
|
||||
+ priv->dma_device->tx_chan[i]->control = LQ_DMA_CH_ON;
|
||||
+ else
|
||||
+ priv->dma_device->tx_chan[i]->control = LQ_DMA_CH_OFF;
|
||||
+
|
||||
+ dma_device_register(priv->dma_device);
|
||||
+
|
||||
+ printk(KERN_INFO "%s: using mac=", dev->name);
|
||||
+ for (i = 0; i < 6; i++) {
|
||||
+ dev->dev_addr[i] = mac_addr[i];
|
||||
+ printk("%02X%c", dev->dev_addr[i], (i == 5) ? ('\n') : (':'));
|
||||
+ }
|
||||
+
|
||||
+ priv->mii_bus = mdiobus_alloc();
|
||||
+ if (priv->mii_bus == NULL)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ priv->mii_bus->priv = dev;
|
||||
+ priv->mii_bus->read = lq_mdiobus_read;
|
||||
+ priv->mii_bus->write = lq_mdiobus_write;
|
||||
+ priv->mii_bus->name = "lq_mii";
|
||||
+ snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "%x", 0);
|
||||
+ priv->mii_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
|
||||
+ for(i = 0; i < PHY_MAX_ADDR; ++i)
|
||||
+ priv->mii_bus->irq[i] = PHY_POLL;
|
||||
+
|
||||
+ mdiobus_register(priv->mii_bus);
|
||||
+
|
||||
+ return mii_probe(dev);
|
||||
+}
|
||||
+
|
||||
+static void lq_mii_chip_init(int mode)
|
||||
+{
|
||||
+ lq_pmu_enable(PMU_DMA);
|
||||
+ lq_pmu_enable(PMU_PPE);
|
||||
+
|
||||
+ if (mode == REV_MII_MODE)
|
||||
+ lq_w32_mask(PPE32_MII_MASK, PPE32_MII_REVERSE, LQ_PPE32_CFG);
|
||||
+ else if (mode == MII_MODE)
|
||||
+ lq_w32_mask(PPE32_MII_MASK, PPE32_MII_NORMAL, LQ_PPE32_CFG);
|
||||
+ lq_w32(PPE32_PLEN_UNDER | PPE32_PLEN_OVER, LQ_PPE32_IG_PLEN_CTRL);
|
||||
+ lq_w32(PPE32_CGEN, LQ_PPE32_ENET_MAC_CFG);
|
||||
+ wmb();
|
||||
+}
|
||||
+
|
||||
+static int lq_mii_eth_mac_addr(struct net_device *dev, void *p)
|
||||
+{
|
||||
+ int retcode;
|
||||
+
|
||||
+ retcode = eth_mac_addr(dev, p);
|
||||
+
|
||||
+ if (retcode)
|
||||
+ return retcode;
|
||||
+
|
||||
+ // set rx_addr for unicast filter
|
||||
+ lq_w32(((dev->dev_addr[0]<<24)|(dev->dev_addr[1]<<16)|(dev->dev_addr[2]<< 8)|dev->dev_addr[3]), (u32*)(LQ_PPE32_BASE_ADDR|(0x461b<<2)));
|
||||
+ lq_w32(((dev->dev_addr[4]<<24)|(dev->dev_addr[5]<<16)), (u32*)(LQ_PPE32_BASE_ADDR|(0x461c<<2)));
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void lq_mii_set_rx_mode (struct net_device *dev)
|
||||
+{
|
||||
+ // rx_mode promisc: unset unicast filter
|
||||
+ if ((dev->flags & IFF_PROMISC) || (dev->flags & IFF_ALLMULTI))
|
||||
+ lq_w32(lq_r32((u32*)(LQ_PPE32_BASE_ADDR|(0x4614<<2))) & ~(1<<28), (u32*)(LQ_PPE32_BASE_ADDR|(0x4614<<2)));
|
||||
+ // enable unicast filter
|
||||
+ else
|
||||
+ lq_w32(lq_r32((u32*)(LQ_PPE32_BASE_ADDR|(0x4614<<2))) | (1<<28), (u32*)(LQ_PPE32_BASE_ADDR|(0x4614<<2)));
|
||||
+}
|
||||
+
|
||||
+static const struct net_device_ops lq_eth_netdev_ops = {
|
||||
+ .ndo_init = lq_mii_dev_init,
|
||||
+ .ndo_open = lq_mii_open,
|
||||
+ .ndo_stop = lq_mii_release,
|
||||
+ .ndo_start_xmit = lq_mii_tx,
|
||||
+ .ndo_tx_timeout = lq_mii_tx_timeout,
|
||||
+ .ndo_change_mtu = eth_change_mtu,
|
||||
+ .ndo_set_mac_address = lq_mii_eth_mac_addr,
|
||||
+ .ndo_validate_addr = eth_validate_addr,
|
||||
+ .ndo_set_multicast_list = lq_mii_set_rx_mode,
|
||||
+};
|
||||
+
|
||||
+static int
|
||||
+lq_mii_probe(struct platform_device *dev)
|
||||
+{
|
||||
+ int result = 0;
|
||||
+ struct lq_eth_data *eth = (struct lq_eth_data*)dev->dev.platform_data;
|
||||
+ lq_etop_dev = alloc_etherdev(sizeof(struct lq_mii_priv));
|
||||
+ lq_etop_dev->netdev_ops = &lq_eth_netdev_ops;
|
||||
+ memcpy(mac_addr, eth->mac, 6);
|
||||
+ strcpy(lq_etop_dev->name, "eth%d");
|
||||
+ lq_mii_chip_init(eth->mii_mode);
|
||||
+ result = register_netdev(lq_etop_dev);
|
||||
+ if (result) {
|
||||
+ printk(KERN_INFO "lq_etop: error %i registering device \"%s\"\n", result, lq_etop_dev->name);
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ printk(KERN_INFO "lq_etop: driver loaded!\n");
|
||||
+
|
||||
+out:
|
||||
+ return result;
|
||||
+}
|
||||
+
|
||||
+static int lq_mii_remove(struct platform_device *dev)
|
||||
+{
|
||||
+ struct lq_mii_priv *priv = (struct lq_mii_priv *)netdev_priv(lq_etop_dev);
|
||||
+
|
||||
+ printk(KERN_INFO "lq_etop: lq_etop cleanup\n");
|
||||
+
|
||||
+ dma_device_unregister(priv->dma_device);
|
||||
+ dma_device_release(priv->dma_device);
|
||||
+ kfree(priv->dma_device);
|
||||
+ unregister_netdev(lq_etop_dev);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct platform_driver lq_mii_driver = {
|
||||
+ .probe = lq_mii_probe,
|
||||
+ .remove = lq_mii_remove,
|
||||
+ .driver = {
|
||||
+ .name = "lq_etop",
|
||||
+ .owner = THIS_MODULE,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+int __init lq_mii_init(void)
|
||||
+{
|
||||
+ int ret = platform_driver_register(&lq_mii_driver);
|
||||
+ if (ret)
|
||||
+ printk(KERN_INFO "lq_etop: Error registering platfom driver!");
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static void __exit lq_mii_cleanup(void)
|
||||
+{
|
||||
+ platform_driver_unregister(&lq_mii_driver);
|
||||
+}
|
||||
+
|
||||
+module_init(lq_mii_init);
|
||||
+module_exit(lq_mii_cleanup);
|
||||
+
|
||||
+MODULE_LICENSE("GPL");
|
||||
+MODULE_AUTHOR("John Crispin <blogic@openwrt.org>");
|
||||
+MODULE_DESCRIPTION("ethernet driver for IFXMIPS boards");
|
||||
246
target/linux/lantiq/patches/250-watchdog.patch
Normal file
246
target/linux/lantiq/patches/250-watchdog.patch
Normal file
@@ -0,0 +1,246 @@
|
||||
--- 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.
|
||||
|
||||
+config LANTIQ_WDT
|
||||
+ bool "Lantiq SoC watchdog"
|
||||
+ depends on LANTIQ
|
||||
+ help
|
||||
+ Hardware driver for the Lantiq SoC Watchdog Timer.
|
||||
+
|
||||
# PARISC Architecture
|
||||
|
||||
# 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
|
||||
obj-$(CONFIG_TXX9_WDT) += txx9wdt.o
|
||||
+obj-$(CONFIG_LANTIQ_WDT) += lantiq_wdt.o
|
||||
|
||||
# PARISC Architecture
|
||||
|
||||
--- /dev/null
|
||||
+++ b/drivers/watchdog/lantiq_wdt.c
|
||||
@@ -0,0 +1,218 @@
|
||||
+/*
|
||||
+ * This program is free software; you can redistribute it and/or modify it
|
||||
+ * under the terms of the GNU General Public License version 2 as published
|
||||
+ * by the Free Software Foundation.
|
||||
+ *
|
||||
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
|
||||
+ * Based on EP93xx wdt driver
|
||||
+ */
|
||||
+
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/fs.h>
|
||||
+#include <linux/miscdevice.h>
|
||||
+#include <linux/miscdevice.h>
|
||||
+#include <linux/watchdog.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/uaccess.h>
|
||||
+#include <linux/clk.h>
|
||||
+
|
||||
+#include <lantiq.h>
|
||||
+
|
||||
+#define LQ_WDT_PW1 0x00BE0000
|
||||
+#define LQ_WDT_PW2 0x00DC0000
|
||||
+
|
||||
+#define LQ_BIU_WDT_CR 0x3F0
|
||||
+#define LQ_BIU_WDT_SR 0x3F8
|
||||
+
|
||||
+#ifndef CONFIG_WATCHDOG_NOWAYOUT
|
||||
+static int wdt_ok_to_close;
|
||||
+#endif
|
||||
+
|
||||
+static int wdt_timeout = 30;
|
||||
+static __iomem void *wdt_membase = NULL;
|
||||
+static unsigned long io_region_clk = 0;
|
||||
+
|
||||
+static int
|
||||
+lq_wdt_enable(unsigned int timeout)
|
||||
+{
|
||||
+/* printk("%s:%s[%d] %08X\n",
|
||||
+ __FILE__, __func__, __LINE__,
|
||||
+ lq_r32(wdt_membase + LQ_BIU_WDT_SR));
|
||||
+ if(!lq_r32(wdt_membase + LQ_BIU_WDT_SR))
|
||||
+ {
|
||||
+*/ lq_w32(LQ_WDT_PW1, wdt_membase + LQ_BIU_WDT_CR);
|
||||
+ lq_w32(LQ_WDT_PW2 |
|
||||
+ (0x3 << 26) | /* PWL */
|
||||
+ (0x3 << 24) | /* CLKDIV */
|
||||
+ (0x1 << 31) | /* enable */
|
||||
+ ((timeout * (io_region_clk / 0x40000)) + 0x1000), /* reload */
|
||||
+ wdt_membase + LQ_BIU_WDT_CR);
|
||||
+// }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+lq_wdt_disable(void)
|
||||
+{
|
||||
+#ifndef CONFIG_WATCHDOG_NOWAYOUT
|
||||
+ wdt_ok_to_close = 0;
|
||||
+#endif
|
||||
+ lq_w32(LQ_WDT_PW1, wdt_membase + LQ_BIU_WDT_CR);
|
||||
+ lq_w32(LQ_WDT_PW2, wdt_membase+ LQ_BIU_WDT_CR);
|
||||
+}
|
||||
+
|
||||
+static ssize_t
|
||||
+lq_wdt_write(struct file *file, const char __user *data,
|
||||
+ size_t len, loff_t *ppos)
|
||||
+{
|
||||
+ size_t i;
|
||||
+
|
||||
+ if (!len)
|
||||
+ return 0;
|
||||
+
|
||||
+#ifndef CONFIG_WATCHDOG_NOWAYOUT
|
||||
+ for (i = 0; i != len; i++) {
|
||||
+ char c;
|
||||
+ if (get_user(c, data + i))
|
||||
+ return -EFAULT;
|
||||
+ if (c == 'V')
|
||||
+ wdt_ok_to_close = 1;
|
||||
+ }
|
||||
+#endif
|
||||
+ lq_wdt_enable(wdt_timeout);
|
||||
+ return len;
|
||||
+}
|
||||
+
|
||||
+static struct watchdog_info ident = {
|
||||
+ .options = WDIOF_MAGICCLOSE,
|
||||
+ .identity = "lq_wdt",
|
||||
+};
|
||||
+
|
||||
+static int
|
||||
+lq_wdt_ioctl(struct inode *inode, struct file *file,
|
||||
+ unsigned int cmd, unsigned long arg)
|
||||
+{
|
||||
+ int ret = -ENOTTY;
|
||||
+
|
||||
+ switch (cmd) {
|
||||
+ case WDIOC_GETSUPPORT:
|
||||
+ ret = copy_to_user((struct watchdog_info __user *)arg, &ident,
|
||||
+ sizeof(ident)) ? -EFAULT : 0;
|
||||
+ break;
|
||||
+
|
||||
+ case WDIOC_GETTIMEOUT:
|
||||
+ ret = put_user(wdt_timeout, (int __user *)arg);
|
||||
+ break;
|
||||
+
|
||||
+ case WDIOC_SETTIMEOUT:
|
||||
+ ret = get_user(wdt_timeout, (int __user *)arg);
|
||||
+ break;
|
||||
+
|
||||
+ case WDIOC_KEEPALIVE:
|
||||
+ lq_wdt_enable(wdt_timeout);
|
||||
+ ret = 0;
|
||||
+ break;
|
||||
+ }
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+lq_wdt_open(struct inode *inode, struct file *file)
|
||||
+{
|
||||
+ lq_wdt_enable(wdt_timeout);
|
||||
+ return nonseekable_open(inode, file);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+lq_wdt_release(struct inode *inode, struct file *file)
|
||||
+{
|
||||
+#ifndef CONFIG_WATCHDOG_NOWAYOUT
|
||||
+ if (wdt_ok_to_close)
|
||||
+ lq_wdt_disable();
|
||||
+ else
|
||||
+#endif
|
||||
+ printk(KERN_ERR "lq_wdt: watchdog closed without warning,"
|
||||
+ " rebooting system\n");
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct file_operations lq_wdt_fops = {
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .write = lq_wdt_write,
|
||||
+ .ioctl = lq_wdt_ioctl,
|
||||
+ .open = lq_wdt_open,
|
||||
+ .release = lq_wdt_release,
|
||||
+};
|
||||
+
|
||||
+static struct miscdevice lq_wdt_miscdev = {
|
||||
+ .minor = WATCHDOG_MINOR,
|
||||
+ .name = "watchdog",
|
||||
+ .fops = &lq_wdt_fops,
|
||||
+};
|
||||
+
|
||||
+static int
|
||||
+lq_wdt_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
+ struct clk *clk;
|
||||
+ int ret = 0;
|
||||
+ if(!res)
|
||||
+ return -ENOENT;
|
||||
+ res = request_mem_region(res->start, resource_size(res),
|
||||
+ dev_name(&pdev->dev));
|
||||
+ if(!res)
|
||||
+ return -EBUSY;
|
||||
+ wdt_membase = ioremap_nocache(res->start, resource_size(res));
|
||||
+ if(!wdt_membase)
|
||||
+ {
|
||||
+ ret = -ENOMEM;
|
||||
+ goto err_release_mem_region;
|
||||
+ }
|
||||
+ clk = clk_get(&pdev->dev, "io");
|
||||
+ io_region_clk = clk_get_rate(clk);;
|
||||
+ ret = misc_register(&lq_wdt_miscdev);
|
||||
+ if(!ret)
|
||||
+ return 0;
|
||||
+
|
||||
+ iounmap(wdt_membase);
|
||||
+err_release_mem_region:
|
||||
+ release_mem_region(res->start, resource_size(res));
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+lq_wdt_remove(struct platform_device *dev)
|
||||
+{
|
||||
+ lq_wdt_disable();
|
||||
+ misc_deregister(&lq_wdt_miscdev);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct platform_driver lq_wdt_driver = {
|
||||
+ .probe = lq_wdt_probe,
|
||||
+ .remove = lq_wdt_remove,
|
||||
+ .driver = {
|
||||
+ .name = "lq_wdt",
|
||||
+ .owner = THIS_MODULE,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static int __init
|
||||
+init_lq_wdt(void)
|
||||
+{
|
||||
+ return platform_driver_register(&lq_wdt_driver);
|
||||
+}
|
||||
+
|
||||
+static void __exit
|
||||
+exit_lq_wdt(void)
|
||||
+{
|
||||
+ platform_driver_unregister(&lq_wdt_driver);
|
||||
+}
|
||||
+
|
||||
+module_init(init_lq_wdt);
|
||||
+module_exit(exit_lq_wdt);
|
||||
+
|
||||
+MODULE_AUTHOR("John Crispin <blogic@openwrt.org>");
|
||||
+MODULE_DESCRIPTION("ifxmips Watchdog");
|
||||
+MODULE_LICENSE("GPL");
|
||||
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
|
||||
436
target/linux/lantiq/patches/260-pci.patch
Normal file
436
target/linux/lantiq/patches/260-pci.patch
Normal file
@@ -0,0 +1,436 @@
|
||||
--- a/arch/mips/pci/Makefile
|
||||
+++ b/arch/mips/pci/Makefile
|
||||
@@ -55,6 +55,7 @@ obj-$(CONFIG_ZAO_CAPCELLA) += fixup-capc
|
||||
obj-$(CONFIG_WR_PPMC) += fixup-wrppmc.o
|
||||
obj-$(CONFIG_MIKROTIK_RB532) += pci-rc32434.o ops-rc32434.o fixup-rc32434.o
|
||||
obj-$(CONFIG_CPU_CAVIUM_OCTEON) += pci-octeon.o pcie-octeon.o
|
||||
+obj-$(CONFIG_LANTIQ) += pci-lantiq.o ops-lantiq.o
|
||||
|
||||
ifdef CONFIG_PCI_MSI
|
||||
obj-$(CONFIG_CPU_CAVIUM_OCTEON) += msi-octeon.o
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/pci/ops-lantiq.c
|
||||
@@ -0,0 +1,127 @@
|
||||
+/*
|
||||
+ * This program is free software; you can redistribute it and/or modify it
|
||||
+ * under the terms of the GNU General Public License version 2 as published
|
||||
+ * by the Free Software Foundation.
|
||||
+ *
|
||||
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
|
||||
+ */
|
||||
+
|
||||
+#include <linux/types.h>
|
||||
+#include <linux/pci.h>
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/delay.h>
|
||||
+#include <linux/mm.h>
|
||||
+#include <asm/addrspace.h>
|
||||
+#include <linux/vmalloc.h>
|
||||
+
|
||||
+#include <xway.h>
|
||||
+
|
||||
+#define LQ_PCI_CFG_BUSNUM_SHF 16
|
||||
+#define LQ_PCI_CFG_DEVNUM_SHF 11
|
||||
+#define LQ_PCI_CFG_FUNNUM_SHF 8
|
||||
+
|
||||
+#define PCI_ACCESS_READ 0
|
||||
+#define PCI_ACCESS_WRITE 1
|
||||
+
|
||||
+extern u32 lq_pci_mapped_cfg;
|
||||
+
|
||||
+static int
|
||||
+lq_pci_config_access(unsigned char access_type,
|
||||
+ struct pci_bus *bus, unsigned int devfn, unsigned int where, u32 *data)
|
||||
+{
|
||||
+ unsigned long cfg_base;
|
||||
+ unsigned long flags;
|
||||
+
|
||||
+ u32 temp;
|
||||
+
|
||||
+ /* we support slot from 0 to 15 */
|
||||
+ /* dev_fn 0&0x68 (AD29) is ifxmips itself */
|
||||
+ if ((bus->number != 0) || ((devfn & 0xf8) > 0x78)
|
||||
+ || ((devfn & 0xf8) == 0) || ((devfn & 0xf8) == 0x68))
|
||||
+ return 1;
|
||||
+
|
||||
+ spin_lock_irqsave(&ebu_lock, flags);
|
||||
+
|
||||
+ cfg_base = lq_pci_mapped_cfg;
|
||||
+ cfg_base |= (bus->number << LQ_PCI_CFG_BUSNUM_SHF) | (devfn <<
|
||||
+ LQ_PCI_CFG_FUNNUM_SHF) | (where & ~0x3);
|
||||
+
|
||||
+ /* Perform access */
|
||||
+ if (access_type == PCI_ACCESS_WRITE)
|
||||
+ {
|
||||
+#ifdef CONFIG_SWAP_IO_SPACE
|
||||
+ lq_w32(swab32(*data), ((u32*)cfg_base));
|
||||
+#else
|
||||
+ lq_w32(*data, ((u32*)cfg_base));
|
||||
+#endif
|
||||
+ } else {
|
||||
+ *data = lq_r32(((u32*)(cfg_base)));
|
||||
+#ifdef CONFIG_SWAP_IO_SPACE
|
||||
+ *data = swab32(*data);
|
||||
+#endif
|
||||
+ }
|
||||
+ wmb();
|
||||
+
|
||||
+ /* clean possible Master abort */
|
||||
+ cfg_base = (lq_pci_mapped_cfg | (0x0 << LQ_PCI_CFG_FUNNUM_SHF)) + 4;
|
||||
+ temp = lq_r32(((u32*)(cfg_base)));
|
||||
+#ifdef CONFIG_SWAP_IO_SPACE
|
||||
+ temp = swab32 (temp);
|
||||
+#endif
|
||||
+ cfg_base = (lq_pci_mapped_cfg | (0x68 << LQ_PCI_CFG_FUNNUM_SHF)) + 4;
|
||||
+ lq_w32(temp, ((u32*)cfg_base));
|
||||
+
|
||||
+ spin_unlock_irqrestore(&ebu_lock, flags);
|
||||
+
|
||||
+ if (((*data) == 0xffffffff) && (access_type == PCI_ACCESS_READ))
|
||||
+ return 1;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+lq_pci_read_config_dword(struct pci_bus *bus, unsigned int devfn,
|
||||
+ int where, int size, u32 * val)
|
||||
+{
|
||||
+ u32 data = 0;
|
||||
+
|
||||
+ if (lq_pci_config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
|
||||
+ return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
+
|
||||
+ if (size == 1)
|
||||
+ *val = (data >> ((where & 3) << 3)) & 0xff;
|
||||
+ else if (size == 2)
|
||||
+ *val = (data >> ((where & 3) << 3)) & 0xffff;
|
||||
+ else
|
||||
+ *val = data;
|
||||
+
|
||||
+ return PCIBIOS_SUCCESSFUL;
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+lq_pci_write_config_dword(struct pci_bus *bus, unsigned int devfn,
|
||||
+ int where, int size, u32 val)
|
||||
+{
|
||||
+ u32 data = 0;
|
||||
+
|
||||
+ if (size == 4)
|
||||
+ {
|
||||
+ data = val;
|
||||
+ } else {
|
||||
+ if (lq_pci_config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
|
||||
+ return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
+
|
||||
+ if (size == 1)
|
||||
+ data = (data & ~(0xff << ((where & 3) << 3))) |
|
||||
+ (val << ((where & 3) << 3));
|
||||
+ else if (size == 2)
|
||||
+ data = (data & ~(0xffff << ((where & 3) << 3))) |
|
||||
+ (val << ((where & 3) << 3));
|
||||
+ }
|
||||
+
|
||||
+ if (lq_pci_config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data))
|
||||
+ return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
+
|
||||
+ return PCIBIOS_SUCCESSFUL;
|
||||
+}
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/pci/pci-lantiq.c
|
||||
@@ -0,0 +1,293 @@
|
||||
+/*
|
||||
+ * This program is free software; you can redistribute it and/or modify it
|
||||
+ * under the terms of the GNU General Public License version 2 as published
|
||||
+ * by the Free Software Foundation.
|
||||
+ *
|
||||
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
|
||||
+ */
|
||||
+
|
||||
+#include <linux/types.h>
|
||||
+#include <linux/pci.h>
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/delay.h>
|
||||
+#include <linux/mm.h>
|
||||
+#include <linux/vmalloc.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+
|
||||
+#include <asm/gpio.h>
|
||||
+#include <asm/addrspace.h>
|
||||
+
|
||||
+#include <xway.h>
|
||||
+#include <xway_irq.h>
|
||||
+#include <lantiq_platform.h>
|
||||
+
|
||||
+#define LQ_PCI_CFG_BASE 0x17000000
|
||||
+#define LQ_PCI_CFG_SIZE 0x00008000
|
||||
+#define LQ_PCI_MEM_BASE 0x18000000
|
||||
+#define LQ_PCI_MEM_SIZE 0x02000000
|
||||
+#define LQ_PCI_IO_BASE 0x1AE00000
|
||||
+#define LQ_PCI_IO_SIZE 0x00200000
|
||||
+
|
||||
+#define PCI_CR_FCI_ADDR_MAP0 ((u32 *)(PCI_CR_PR_BASE_ADDR + 0x00C0))
|
||||
+#define PCI_CR_FCI_ADDR_MAP1 ((u32 *)(PCI_CR_PR_BASE_ADDR + 0x00C4))
|
||||
+#define PCI_CR_FCI_ADDR_MAP2 ((u32 *)(PCI_CR_PR_BASE_ADDR + 0x00C8))
|
||||
+#define PCI_CR_FCI_ADDR_MAP3 ((u32 *)(PCI_CR_PR_BASE_ADDR + 0x00CC))
|
||||
+#define PCI_CR_FCI_ADDR_MAP4 ((u32 *)(PCI_CR_PR_BASE_ADDR + 0x00D0))
|
||||
+#define PCI_CR_FCI_ADDR_MAP5 ((u32 *)(PCI_CR_PR_BASE_ADDR + 0x00D4))
|
||||
+#define PCI_CR_FCI_ADDR_MAP6 ((u32 *)(PCI_CR_PR_BASE_ADDR + 0x00D8))
|
||||
+#define PCI_CR_FCI_ADDR_MAP7 ((u32 *)(PCI_CR_PR_BASE_ADDR + 0x00DC))
|
||||
+#define PCI_CR_CLK_CTRL ((u32 *)(PCI_CR_PR_BASE_ADDR + 0x0000))
|
||||
+#define PCI_CR_PCI_MOD ((u32 *)(PCI_CR_PR_BASE_ADDR + 0x0030))
|
||||
+#define PCI_CR_PC_ARB ((u32 *)(PCI_CR_PR_BASE_ADDR + 0x0080))
|
||||
+#define PCI_CR_FCI_ADDR_MAP11hg ((u32 *)(PCI_CR_PR_BASE_ADDR + 0x00E4))
|
||||
+#define PCI_CR_BAR11MASK ((u32 *)(PCI_CR_PR_BASE_ADDR + 0x0044))
|
||||
+#define PCI_CR_BAR12MASK ((u32 *)(PCI_CR_PR_BASE_ADDR + 0x0048))
|
||||
+#define PCI_CR_BAR13MASK ((u32 *)(PCI_CR_PR_BASE_ADDR + 0x004C))
|
||||
+#define PCI_CS_BASE_ADDR1 ((u32 *)(PCI_CS_PR_BASE_ADDR + 0x0010))
|
||||
+#define PCI_CR_PCI_ADDR_MAP11 ((u32 *)(PCI_CR_PR_BASE_ADDR + 0x0064))
|
||||
+#define PCI_CR_FCI_BURST_LENGTH ((u32 *)(PCI_CR_PR_BASE_ADDR + 0x00E8))
|
||||
+#define PCI_CR_PCI_EOI ((u32 *)(PCI_CR_PR_BASE_ADDR + 0x002C))
|
||||
+
|
||||
+
|
||||
+#define PCI_CS_STS_CMD ((u32 *)(PCI_CS_PR_BASE_ADDR + 0x0004))
|
||||
+
|
||||
+#define PCI_MASTER0_REQ_MASK_2BITS 8
|
||||
+#define PCI_MASTER1_REQ_MASK_2BITS 10
|
||||
+#define PCI_MASTER2_REQ_MASK_2BITS 12
|
||||
+#define INTERNAL_ARB_ENABLE_BIT 0
|
||||
+
|
||||
+#define LQ_CGU_IFCCR ((u32 *)(LQ_CGU_BASE_ADDR + 0x0018))
|
||||
+#define LQ_CGU_PCICR ((u32 *)(LQ_CGU_BASE_ADDR + 0x0034))
|
||||
+
|
||||
+extern int lq_pci_read_config_dword(struct pci_bus *bus,
|
||||
+ unsigned int devfn, int where, int size, u32 *val);
|
||||
+extern int lq_pci_write_config_dword(struct pci_bus *bus,
|
||||
+ unsigned int devfn, int where, int size, u32 val);
|
||||
+
|
||||
+u32 lq_pci_mapped_cfg;
|
||||
+
|
||||
+/* Since the PCI REQ pins can be reused for other functionality, make it possible
|
||||
+ to exclude those from interpretation by the PCI controller */
|
||||
+static int lq_pci_req_mask = 0xf;
|
||||
+
|
||||
+struct pci_ops lq_pci_ops =
|
||||
+{
|
||||
+ .read = lq_pci_read_config_dword,
|
||||
+ .write = lq_pci_write_config_dword
|
||||
+};
|
||||
+
|
||||
+static struct resource pci_io_resource =
|
||||
+{
|
||||
+ .name = "pci io space",
|
||||
+ .start = LQ_PCI_IO_BASE,
|
||||
+ .end = LQ_PCI_IO_BASE + LQ_PCI_IO_SIZE - 1,
|
||||
+ .flags = IORESOURCE_IO
|
||||
+};
|
||||
+
|
||||
+static struct resource pci_mem_resource =
|
||||
+{
|
||||
+ .name = "pci memory space",
|
||||
+ .start = LQ_PCI_MEM_BASE,
|
||||
+ .end = LQ_PCI_MEM_BASE + LQ_PCI_MEM_SIZE - 1,
|
||||
+ .flags = IORESOURCE_MEM
|
||||
+};
|
||||
+
|
||||
+static struct pci_controller lq_pci_controller =
|
||||
+{
|
||||
+ .pci_ops = &lq_pci_ops,
|
||||
+ .mem_resource = &pci_mem_resource,
|
||||
+ .mem_offset = 0x00000000UL,
|
||||
+ .io_resource = &pci_io_resource,
|
||||
+ .io_offset = 0x00000000UL,
|
||||
+};
|
||||
+
|
||||
+int
|
||||
+pcibios_plat_dev_init(struct pci_dev *dev)
|
||||
+{
|
||||
+ u8 pin;
|
||||
+
|
||||
+ pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
|
||||
+ switch(pin)
|
||||
+ {
|
||||
+ case 0:
|
||||
+ break;
|
||||
+ case 1:
|
||||
+ //falling edge level triggered:0x4, low level:0xc, rising edge:0x2
|
||||
+ lq_w32(lq_r32(LQ_EBU_PCC_CON) | 0xc, LQ_EBU_PCC_CON);
|
||||
+ lq_w32(lq_r32(LQ_EBU_PCC_IEN) | 0x10, LQ_EBU_PCC_IEN);
|
||||
+ break;
|
||||
+ case 2:
|
||||
+ case 3:
|
||||
+ case 4:
|
||||
+ printk ("WARNING: interrupt pin %d not supported yet!\n", pin);
|
||||
+ default:
|
||||
+ printk ("WARNING: invalid interrupt pin %d\n", pin);
|
||||
+ return 1;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static u32
|
||||
+lq_calc_bar11mask(void)
|
||||
+{
|
||||
+ u32 mem, bar11mask;
|
||||
+
|
||||
+ /* BAR11MASK value depends on available memory on system. */
|
||||
+ mem = num_physpages * PAGE_SIZE;
|
||||
+ bar11mask = (0x0ffffff0 & ~((1 << (fls(mem) -1)) -1)) | 8;
|
||||
+
|
||||
+ return bar11mask;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+lq_pci_setup_clk(int external_clock)
|
||||
+{
|
||||
+ /* set clock to 33Mhz */
|
||||
+ lq_w32(lq_r32(LQ_CGU_IFCCR) & ~0xf00000, LQ_CGU_IFCCR);
|
||||
+ lq_w32(lq_r32(LQ_CGU_IFCCR) | 0x800000, LQ_CGU_IFCCR);
|
||||
+ if (external_clock)
|
||||
+ {
|
||||
+ lq_w32(lq_r32(LQ_CGU_IFCCR) & ~(1 << 16), LQ_CGU_IFCCR);
|
||||
+ lq_w32((1 << 30), LQ_CGU_PCICR);
|
||||
+ } else {
|
||||
+ lq_w32(lq_r32(LQ_CGU_IFCCR) | (1 << 16), LQ_CGU_IFCCR);
|
||||
+ lq_w32((1 << 31) | (1 << 30), LQ_CGU_PCICR);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+lq_pci_setup_gpio(void)
|
||||
+{
|
||||
+ /* PCI reset line is gpio driven */
|
||||
+ lq_gpio_request(21, 0, 0, 1, "pci-reset");
|
||||
+
|
||||
+ /* PCI_REQ line */
|
||||
+ lq_gpio_request(29, 1, 0, 0, "pci-req");
|
||||
+
|
||||
+ /* PCI_GNT line */
|
||||
+ lq_gpio_request(30, 1, 0, 1, "pci-gnt");
|
||||
+}
|
||||
+
|
||||
+static int __init
|
||||
+lq_pci_startup(void)
|
||||
+{
|
||||
+ u32 temp_buffer;
|
||||
+
|
||||
+ /* setup pci clock and gpis used by pci */
|
||||
+ lq_pci_setup_gpio();
|
||||
+
|
||||
+ /* enable auto-switching between PCI and EBU */
|
||||
+ lq_w32(0xa, PCI_CR_CLK_CTRL);
|
||||
+
|
||||
+ /* busy, i.e. configuration is not done, PCI access has to be retried */
|
||||
+ lq_w32(lq_r32(PCI_CR_PCI_MOD) & ~(1 << 24), PCI_CR_PCI_MOD);
|
||||
+ wmb ();
|
||||
+ /* BUS Master/IO/MEM access */
|
||||
+ lq_w32(lq_r32(PCI_CS_STS_CMD) | 7, PCI_CS_STS_CMD);
|
||||
+
|
||||
+ /* enable external 2 PCI masters */
|
||||
+ temp_buffer = lq_r32(PCI_CR_PC_ARB);
|
||||
+ temp_buffer &= (~(lq_pci_req_mask << 16));
|
||||
+ /* enable internal arbiter */
|
||||
+ temp_buffer |= (1 << INTERNAL_ARB_ENABLE_BIT);
|
||||
+ /* enable internal PCI master reqest */
|
||||
+ temp_buffer &= (~(3 << PCI_MASTER0_REQ_MASK_2BITS));
|
||||
+
|
||||
+ /* enable EBU request */
|
||||
+ temp_buffer &= (~(3 << PCI_MASTER1_REQ_MASK_2BITS));
|
||||
+
|
||||
+ /* enable all external masters request */
|
||||
+ temp_buffer &= (~(3 << PCI_MASTER2_REQ_MASK_2BITS));
|
||||
+ lq_w32(temp_buffer, PCI_CR_PC_ARB);
|
||||
+ wmb ();
|
||||
+
|
||||
+ /* setup BAR memory regions */
|
||||
+ lq_w32(0x18000000, PCI_CR_FCI_ADDR_MAP0);
|
||||
+ lq_w32(0x18400000, PCI_CR_FCI_ADDR_MAP1);
|
||||
+ lq_w32(0x18800000, PCI_CR_FCI_ADDR_MAP2);
|
||||
+ lq_w32(0x18c00000, PCI_CR_FCI_ADDR_MAP3);
|
||||
+ lq_w32(0x19000000, PCI_CR_FCI_ADDR_MAP4);
|
||||
+ lq_w32(0x19400000, PCI_CR_FCI_ADDR_MAP5);
|
||||
+ lq_w32(0x19800000, PCI_CR_FCI_ADDR_MAP6);
|
||||
+ lq_w32(0x19c00000, PCI_CR_FCI_ADDR_MAP7);
|
||||
+ lq_w32(0x1ae00000, PCI_CR_FCI_ADDR_MAP11hg);
|
||||
+ lq_w32(lq_calc_bar11mask(), PCI_CR_BAR11MASK);
|
||||
+ lq_w32(0, PCI_CR_PCI_ADDR_MAP11);
|
||||
+ lq_w32(0, PCI_CS_BASE_ADDR1);
|
||||
+#ifdef CONFIG_SWAP_IO_SPACE
|
||||
+ /* both TX and RX endian swap are enabled */
|
||||
+ lq_w32(lq_r32(PCI_CR_PCI_EOI) | 3, PCI_CR_PCI_EOI);
|
||||
+ wmb ();
|
||||
+#endif
|
||||
+ /*TODO: disable BAR2 & BAR3 - why was this in the origianl infineon code */
|
||||
+ lq_w32(lq_r32(PCI_CR_BAR12MASK) | 0x80000000, PCI_CR_BAR12MASK);
|
||||
+ lq_w32(lq_r32(PCI_CR_BAR13MASK) | 0x80000000, PCI_CR_BAR13MASK);
|
||||
+ /*use 8 dw burst length */
|
||||
+ lq_w32(0x303, PCI_CR_FCI_BURST_LENGTH);
|
||||
+ lq_w32(lq_r32(PCI_CR_PCI_MOD) | (1 << 24), PCI_CR_PCI_MOD);
|
||||
+ wmb();
|
||||
+
|
||||
+ /* toggle reset pin */
|
||||
+ __gpio_set_value(21, 0);
|
||||
+ wmb();
|
||||
+ mdelay(1);
|
||||
+ __gpio_set_value(21, 1);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int __init
|
||||
+pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin){
|
||||
+ switch(slot)
|
||||
+ {
|
||||
+ case 13:
|
||||
+ /* IDSEL = AD29 --> USB Host Controller */
|
||||
+ return (INT_NUM_IM1_IRL0 + 17);
|
||||
+ case 14:
|
||||
+ /* IDSEL = AD30 --> mini PCI connector */
|
||||
+ return (INT_NUM_IM0_IRL0 + 22);
|
||||
+ default:
|
||||
+ printk("lq_pci: no IRQ found for slot %d, pin %d\n", slot, pin);
|
||||
+ return 0;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+lq_pci_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct lq_pci_data *lq_pci_data = (struct lq_pci_data*) pdev->dev.platform_data;
|
||||
+ extern int pci_probe_only;
|
||||
+
|
||||
+ pci_probe_only = 0;
|
||||
+ lq_pci_req_mask = lq_pci_data->req_mask;
|
||||
+ lq_pci_setup_clk(lq_pci_data->clock);
|
||||
+
|
||||
+ lq_pci_startup();
|
||||
+ lq_pci_mapped_cfg =
|
||||
+ (u32)ioremap_nocache(LQ_PCI_CFG_BASE, LQ_PCI_CFG_BASE);
|
||||
+ lq_pci_controller.io_map_base =
|
||||
+ (unsigned long)ioremap(LQ_PCI_IO_BASE, LQ_PCI_IO_SIZE - 1);
|
||||
+
|
||||
+ register_pci_controller(&lq_pci_controller);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct platform_driver
|
||||
+lq_pci_driver = {
|
||||
+ .probe = lq_pci_probe,
|
||||
+ .driver = {
|
||||
+ .name = "lq_pci",
|
||||
+ .owner = THIS_MODULE,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+int __init
|
||||
+pcibios_init(void)
|
||||
+{
|
||||
+ int ret = platform_driver_register(&lq_pci_driver);
|
||||
+ if(ret)
|
||||
+ printk(KERN_INFO "lq_pci: Error registering platfom driver!");
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+arch_initcall(pcibios_init);
|
||||
6209
target/linux/lantiq/patches/270-crypto.patch
Normal file
6209
target/linux/lantiq/patches/270-crypto.patch
Normal file
File diff suppressed because it is too large
Load Diff
346
target/linux/lantiq/patches/300-udp_redirect.patch
Normal file
346
target/linux/lantiq/patches/300-udp_redirect.patch
Normal file
@@ -0,0 +1,346 @@
|
||||
--- /dev/null
|
||||
+++ b/include/linux/udp_redirect.h
|
||||
@@ -0,0 +1,57 @@
|
||||
+#ifndef _UDP_REDIRECT_H
|
||||
+#define _UDP_REDIRECT_H
|
||||
+
|
||||
+/******************************************************************************
|
||||
+
|
||||
+ Copyright (c) 2006
|
||||
+ Infineon Technologies AG
|
||||
+ Am Campeon 1-12; 81726 Munich, Germany
|
||||
+
|
||||
+ THE DELIVERY OF THIS SOFTWARE AS WELL AS THE HEREBY GRANTED NON-EXCLUSIVE,
|
||||
+ WORLDWIDE LICENSE TO USE, COPY, MODIFY, DISTRIBUTE AND SUBLICENSE THIS
|
||||
+ SOFTWARE IS FREE OF CHARGE.
|
||||
+
|
||||
+ THE LICENSED SOFTWARE IS PROVIDED "AS IS" AND INFINEON EXPRESSLY DISCLAIMS
|
||||
+ ALL REPRESENTATIONS AND WARRANTIES, WHETHER EXPRESS OR IMPLIED, INCLUDING
|
||||
+ WITHOUT LIMITATION, WARRANTIES OR REPRESENTATIONS OF WORKMANSHIP,
|
||||
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, DURABILITY, THAT THE
|
||||
+ OPERATING OF THE LICENSED SOFTWARE WILL BE ERROR FREE OR FREE OF ANY THIRD
|
||||
+ PARTY CLAIMS, INCLUDING WITHOUT LIMITATION CLAIMS OF THIRD PARTY INTELLECTUAL
|
||||
+ PROPERTY INFRINGEMENT.
|
||||
+
|
||||
+ EXCEPT FOR ANY LIABILITY DUE TO WILFUL ACTS OR GROSS NEGLIGENCE AND EXCEPT
|
||||
+ FOR ANY PERSONAL INJURY INFINEON SHALL IN NO EVENT BE LIABLE FOR ANY CLAIM
|
||||
+ OR DAMAGES OF ANY KIND, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
+ DEALINGS IN THE SOFTWARE.
|
||||
+
|
||||
+******************************************************************************/
|
||||
+
|
||||
+/* ============================= */
|
||||
+/* Includes */
|
||||
+/* ============================= */
|
||||
+#ifndef _LINUX_TYPES_H
|
||||
+#include <linux/types.h>
|
||||
+#endif
|
||||
+
|
||||
+
|
||||
+/* ============================= */
|
||||
+/* Definitions */
|
||||
+/* ============================= */
|
||||
+#define UDP_REDIRECT_MAGIC (void*)0x55445052L
|
||||
+
|
||||
+
|
||||
+/* ============================= */
|
||||
+/* Global variable declaration */
|
||||
+/* ============================= */
|
||||
+extern int (*udp_do_redirect_fn)(struct sock *sk, struct sk_buff *skb);
|
||||
+extern int (*udpredirect_getfrag_fn)(void *p, char * to,
|
||||
+ int offset, int fraglen, int odd,
|
||||
+ struct sk_buff *skb);
|
||||
+/* ============================= */
|
||||
+/* Global function declaration */
|
||||
+/* ============================= */
|
||||
+
|
||||
+extern int udpredirect_getfrag(void *p, char * to, int offset,
|
||||
+ int fraglen, int odd, struct sk_buff *skb);
|
||||
+#endif
|
||||
--- /dev/null
|
||||
+++ b/net/ipv4/udp_redirect_symb.c
|
||||
@@ -0,0 +1,186 @@
|
||||
+/******************************************************************************
|
||||
+
|
||||
+ Copyright (c) 2006
|
||||
+ Infineon Technologies AG
|
||||
+ Am Campeon 1-12; 81726 Munich, Germany
|
||||
+
|
||||
+ THE DELIVERY OF THIS SOFTWARE AS WELL AS THE HEREBY GRANTED NON-EXCLUSIVE,
|
||||
+ WORLDWIDE LICENSE TO USE, COPY, MODIFY, DISTRIBUTE AND SUBLICENSE THIS
|
||||
+ SOFTWARE IS FREE OF CHARGE.
|
||||
+
|
||||
+ THE LICENSED SOFTWARE IS PROVIDED "AS IS" AND INFINEON EXPRESSLY DISCLAIMS
|
||||
+ ALL REPRESENTATIONS AND WARRANTIES, WHETHER EXPRESS OR IMPLIED, INCLUDING
|
||||
+ WITHOUT LIMITATION, WARRANTIES OR REPRESENTATIONS OF WORKMANSHIP,
|
||||
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, DURABILITY, THAT THE
|
||||
+ OPERATING OF THE LICENSED SOFTWARE WILL BE ERROR FREE OR FREE OF ANY THIRD
|
||||
+ PARTY CLAIMS, INCLUDING WITHOUT LIMITATION CLAIMS OF THIRD PARTY INTELLECTUAL
|
||||
+ PROPERTY INFRINGEMENT.
|
||||
+
|
||||
+ EXCEPT FOR ANY LIABILITY DUE TO WILFUL ACTS OR GROSS NEGLIGENCE AND EXCEPT
|
||||
+ FOR ANY PERSONAL INJURY INFINEON SHALL IN NO EVENT BE LIABLE FOR ANY CLAIM
|
||||
+ OR DAMAGES OF ANY KIND, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
+ DEALINGS IN THE SOFTWARE.
|
||||
+
|
||||
+******************************************************************************/
|
||||
+#if defined(CONFIG_IFX_UDP_REDIRECT) || defined(CONFIG_IFX_UDP_REDIRECT_MODULE)
|
||||
+/* ============================= */
|
||||
+/* Includes */
|
||||
+/* ============================= */
|
||||
+#include <net/checksum.h>
|
||||
+#include <net/udp.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/skbuff.h>
|
||||
+#include <linux/udp_redirect.h>
|
||||
+
|
||||
+/* ============================= */
|
||||
+/* Global variable definition */
|
||||
+/* ============================= */
|
||||
+int (*udpredirect_getfrag_fn) (void *p, char * to, int offset,
|
||||
+ int fraglen, int odd, struct sk_buff *skb) = NULL;
|
||||
+int (*udp_do_redirect_fn)(struct sock *sk, struct sk_buff *skb) = NULL;
|
||||
+
|
||||
+/* ============================= */
|
||||
+/* Local type definitions */
|
||||
+/* ============================= */
|
||||
+struct udpfakehdr
|
||||
+{
|
||||
+ struct udphdr uh;
|
||||
+ u32 saddr;
|
||||
+ u32 daddr;
|
||||
+ struct iovec *iov;
|
||||
+ u32 wcheck;
|
||||
+};
|
||||
+
|
||||
+/* ============================= */
|
||||
+/* Local function declaration */
|
||||
+/* ============================= */
|
||||
+static int udpredirect_csum_partial_copy_fromiovecend(unsigned char *kdata,
|
||||
+ struct iovec *iov, int offset, unsigned int len, __wsum *csump);
|
||||
+
|
||||
+static int udpredirect_memcpy_fromiovecend(unsigned char *kdata, struct iovec *iov, int offset,
|
||||
+ int len);
|
||||
+
|
||||
+/* ============================= */
|
||||
+/* Global function definition */
|
||||
+/* ============================= */
|
||||
+
|
||||
+/*
|
||||
+ Copy of udp_getfrag() from udp.c
|
||||
+ This function exists because no copy_from_user() is needed for udpredirect.
|
||||
+*/
|
||||
+
|
||||
+int
|
||||
+udpredirect_getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb)
|
||||
+{
|
||||
+ struct iovec *iov = from;
|
||||
+
|
||||
+ if (skb->ip_summed == CHECKSUM_PARTIAL) {
|
||||
+ if (udpredirect_memcpy_fromiovecend(to, iov, offset, len) < 0)
|
||||
+ return -EFAULT;
|
||||
+ } else {
|
||||
+ __wsum csum = 0;
|
||||
+ if (udpredirect_csum_partial_copy_fromiovecend(to, iov, offset, len, &csum) < 0)
|
||||
+ return -EFAULT;
|
||||
+ skb->csum = csum_block_add(skb->csum, csum, odd);
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int udpredirect_memcpy_fromiovecend(unsigned char *kdata, struct iovec *iov, int offset,
|
||||
+ int len)
|
||||
+{
|
||||
+ /* Skip over the finished iovecs */
|
||||
+ while (offset >= iov->iov_len) {
|
||||
+ offset -= iov->iov_len;
|
||||
+ iov++;
|
||||
+ }
|
||||
+
|
||||
+ while (len > 0) {
|
||||
+ u8 __user *base = iov->iov_base + offset;
|
||||
+ int copy = min_t(unsigned int, len, iov->iov_len - offset);
|
||||
+
|
||||
+ offset = 0;
|
||||
+ memcpy(kdata, base, copy);
|
||||
+ len -= copy;
|
||||
+ kdata += copy;
|
||||
+ iov++;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ Copy of csum_partial_copy_fromiovecend() from iovec.c
|
||||
+ This function exists because no copy_from_user() is needed for udpredirect.
|
||||
+*/
|
||||
+
|
||||
+int udpredirect_csum_partial_copy_fromiovecend(unsigned char *kdata, struct iovec *iov,
|
||||
+ int offset, unsigned int len, __wsum *csump)
|
||||
+{
|
||||
+ __wsum csum = *csump;
|
||||
+ int partial_cnt = 0, err = 0;
|
||||
+
|
||||
+ /* Skip over the finished iovecs */
|
||||
+ while (offset >= iov->iov_len) {
|
||||
+ offset -= iov->iov_len;
|
||||
+ iov++;
|
||||
+ }
|
||||
+
|
||||
+ while (len > 0) {
|
||||
+ u8 __user *base = iov->iov_base + offset;
|
||||
+ int copy = min_t(unsigned int, len, iov->iov_len - offset);
|
||||
+
|
||||
+ offset = 0;
|
||||
+
|
||||
+ /* There is a remnant from previous iov. */
|
||||
+ if (partial_cnt) {
|
||||
+ int par_len = 4 - partial_cnt;
|
||||
+
|
||||
+ /* iov component is too short ... */
|
||||
+ if (par_len > copy) {
|
||||
+ memcpy(kdata, base, copy);
|
||||
+ kdata += copy;
|
||||
+ base += copy;
|
||||
+ partial_cnt += copy;
|
||||
+ len -= copy;
|
||||
+ iov++;
|
||||
+ if (len)
|
||||
+ continue;
|
||||
+ *csump = csum_partial(kdata - partial_cnt,
|
||||
+ partial_cnt, csum);
|
||||
+ goto out;
|
||||
+ }
|
||||
+ memcpy(kdata, base, par_len);
|
||||
+ csum = csum_partial(kdata - partial_cnt, 4, csum);
|
||||
+ kdata += par_len;
|
||||
+ base += par_len;
|
||||
+ copy -= par_len;
|
||||
+ len -= par_len;
|
||||
+ partial_cnt = 0;
|
||||
+ }
|
||||
+
|
||||
+ if (len > copy) {
|
||||
+ partial_cnt = copy % 4;
|
||||
+ if (partial_cnt) {
|
||||
+ copy -= partial_cnt;
|
||||
+ memcpy(kdata + copy, base + copy, partial_cnt);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (copy) {
|
||||
+ csum = csum_partial_copy_nocheck(base, kdata, copy, csum);
|
||||
+ }
|
||||
+ len -= copy + partial_cnt;
|
||||
+ kdata += copy + partial_cnt;
|
||||
+ iov++;
|
||||
+ }
|
||||
+ *csump = csum;
|
||||
+out:
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+EXPORT_SYMBOL(udpredirect_getfrag);
|
||||
+EXPORT_SYMBOL(udp_do_redirect_fn);
|
||||
+EXPORT_SYMBOL(udpredirect_getfrag_fn);
|
||||
+#endif /* CONFIG_IFX_UDP_REDIRECT* */
|
||||
--- a/net/ipv4/Makefile
|
||||
+++ b/net/ipv4/Makefile
|
||||
@@ -14,6 +14,9 @@ obj-y := route.o inetpeer.o protocol
|
||||
inet_fragment.o
|
||||
|
||||
obj-$(CONFIG_SYSCTL) += sysctl_net_ipv4.o
|
||||
+ifneq ($(CONFIG_IFX_UDP_REDIRECT),)
|
||||
+obj-$(CONFIG_IFX_UDP_REDIRECT) += udp_redirect_symb.o
|
||||
+endif
|
||||
obj-$(CONFIG_IP_FIB_HASH) += fib_hash.o
|
||||
obj-$(CONFIG_IP_FIB_TRIE) += fib_trie.o
|
||||
obj-$(CONFIG_PROC_FS) += proc.o
|
||||
--- a/net/ipv4/udp.c
|
||||
+++ b/net/ipv4/udp.c
|
||||
@@ -106,6 +106,10 @@
|
||||
#include <net/xfrm.h>
|
||||
#include "udp_impl.h"
|
||||
|
||||
+#if defined(CONFIG_IFX_UDP_REDIRECT) || defined(CONFIG_IFX_UDP_REDIRECT_MODULE)
|
||||
+#include <linux/udp_redirect.h>
|
||||
+#endif
|
||||
+
|
||||
struct udp_table udp_table __read_mostly;
|
||||
EXPORT_SYMBOL(udp_table);
|
||||
|
||||
@@ -782,7 +786,7 @@ int udp_sendmsg(struct kiocb *iocb, stru
|
||||
u8 tos;
|
||||
int err, is_udplite = IS_UDPLITE(sk);
|
||||
int corkreq = up->corkflag || msg->msg_flags&MSG_MORE;
|
||||
- int (*getfrag)(void *, char *, int, int, int, struct sk_buff *);
|
||||
+ int (*getfrag)(void *, char *, int, int, int, struct sk_buff *) = NULL;
|
||||
|
||||
if (len > 0xFFFF)
|
||||
return -EMSGSIZE;
|
||||
@@ -944,6 +948,12 @@ back_from_confirm:
|
||||
|
||||
do_append_data:
|
||||
up->len += ulen;
|
||||
+ /* UDPREDIRECT */
|
||||
+#if defined(CONFIG_IFX_UDP_REDIRECT) || defined(CONFIG_IFX_UDP_REDIRECT_MODULE)
|
||||
+ if(udpredirect_getfrag_fn && sk->sk_user_data == UDP_REDIRECT_MAGIC)
|
||||
+ getfrag = udpredirect_getfrag_fn;
|
||||
+ else
|
||||
+#endif /* IFX_UDP_REDIRECT */
|
||||
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,
|
||||
struct rtable *rt = skb_rtable(skb);
|
||||
__be32 saddr, daddr;
|
||||
struct net *net = dev_net(skb->dev);
|
||||
+ int ret = 0;
|
||||
|
||||
/*
|
||||
* Validate the packet.
|
||||
@@ -1550,7 +1561,16 @@ int __udp4_lib_rcv(struct sk_buff *skb,
|
||||
sk = __udp4_lib_lookup_skb(skb, uh->source, uh->dest, udptable);
|
||||
|
||||
if (sk != NULL) {
|
||||
- int ret = udp_queue_rcv_skb(sk, skb);
|
||||
+ /* UDPREDIRECT */
|
||||
+#if defined(CONFIG_IFX_UDP_REDIRECT) || defined(CONFIG_IFX_UDP_REDIRECT_MODULE)
|
||||
+ if(udp_do_redirect_fn && sk->sk_user_data == UDP_REDIRECT_MAGIC)
|
||||
+ {
|
||||
+ udp_do_redirect_fn(sk,skb);
|
||||
+ kfree_skb(skb);
|
||||
+ return(0);
|
||||
+ }
|
||||
+#endif
|
||||
+ ret = udp_queue_rcv_skb(sk, skb);
|
||||
sock_put(sk);
|
||||
|
||||
/* a return value > 0 means to resubmit the input, but
|
||||
@@ -1845,7 +1865,7 @@ struct proto udp_prot = {
|
||||
#endif
|
||||
};
|
||||
EXPORT_SYMBOL(udp_prot);
|
||||
-
|
||||
+EXPORT_SYMBOL(udp_rcv);
|
||||
/* ------------------------------------------------------------------------ */
|
||||
#ifdef CONFIG_PROC_FS
|
||||
|
||||
--- a/net/Kconfig
|
||||
+++ b/net/Kconfig
|
||||
@@ -72,6 +72,12 @@ config INET
|
||||
|
||||
Short answer: say Y.
|
||||
|
||||
+config IFX_UDP_REDIRECT
|
||||
+ bool "IFX Kernel Packet Interface for UDP redirection"
|
||||
+ help
|
||||
+ You can say Y here if you want to use hooks from kernel for
|
||||
+ UDP redirection.
|
||||
+
|
||||
if INET
|
||||
source "net/ipv4/Kconfig"
|
||||
source "net/ipv6/Kconfig"
|
||||
42
target/linux/lantiq/patches/310-atm_hack.patch
Normal file
42
target/linux/lantiq/patches/310-atm_hack.patch
Normal file
@@ -0,0 +1,42 @@
|
||||
--- a/arch/mips/mm/cache.c
|
||||
+++ b/arch/mips/mm/cache.c
|
||||
@@ -52,6 +52,8 @@
|
||||
void (*_dma_cache_inv)(unsigned long start, unsigned long size);
|
||||
|
||||
EXPORT_SYMBOL(_dma_cache_wback_inv);
|
||||
+EXPORT_SYMBOL(_dma_cache_wback);
|
||||
+EXPORT_SYMBOL(_dma_cache_inv);
|
||||
|
||||
#endif /* CONFIG_DMA_NONCOHERENT */
|
||||
|
||||
--- a/net/atm/proc.c
|
||||
+++ b/net/atm/proc.c
|
||||
@@ -153,7 +153,7 @@
|
||||
static void pvc_info(struct seq_file *seq, struct atm_vcc *vcc)
|
||||
{
|
||||
static const char *const class_name[] = {
|
||||
- "off", "UBR", "CBR", "VBR", "ABR"};
|
||||
+ "off","UBR","CBR","NTR-VBR","ABR","ANY","RT-VBR","UBR+","GFR"};
|
||||
static const char *const aal_name[] = {
|
||||
"---", "1", "2", "3/4", /* 0- 3 */
|
||||
"???", "5", "???", "???", /* 4- 7 */
|
||||
--- a/net/atm/common.c
|
||||
+++ b/net/atm/common.c
|
||||
@@ -60,11 +60,17 @@
|
||||
write_unlock_irq(&vcc_sklist_lock);
|
||||
}
|
||||
|
||||
+struct sk_buff* (*ifx_atm_alloc_tx)(struct atm_vcc *, unsigned int) = NULL;
|
||||
+EXPORT_SYMBOL(ifx_atm_alloc_tx);
|
||||
+
|
||||
static struct sk_buff *alloc_tx(struct atm_vcc *vcc, unsigned int size)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
struct sock *sk = sk_atm(vcc);
|
||||
|
||||
+ if (ifx_atm_alloc_tx != NULL)
|
||||
+ return ifx_atm_alloc_tx(vcc, size);
|
||||
+
|
||||
if (sk_wmem_alloc_get(sk) && !atm_may_send(vcc, size)) {
|
||||
pr_debug("Sorry: wmem_alloc = %d, size = %d, sndbuf = %d\n",
|
||||
sk_wmem_alloc_get(sk), size, sk->sk_sndbuf);
|
||||
211
target/linux/lantiq/patches/400-mach-arv45xx.patch
Normal file
211
target/linux/lantiq/patches/400-mach-arv45xx.patch
Normal file
@@ -0,0 +1,211 @@
|
||||
--- a/arch/mips/include/asm/mach-lantiq/machine.h
|
||||
+++ b/arch/mips/include/asm/mach-lantiq/machine.h
|
||||
@@ -11,4 +11,7 @@
|
||||
LANTIQ_MACH_EASY4010, /* Twinpass evalkit */
|
||||
LANTIQ_MACH_EASY50712, /* Danube evalkit */
|
||||
LANTIQ_MACH_EASY50812, /* AR9 eval board */
|
||||
+ LANTIQ_MACH_ARV4518, /* Airties WAV-221, SMC-7908A-ISP */
|
||||
+ LANTIQ_MACH_ARV452, /* Airties WAV-281, Arcor EasyboxA800 */
|
||||
+ LANTIQ_MACH_ARV4525, /* Speedport W502V */
|
||||
};
|
||||
--- a/arch/mips/lantiq/xway/Kconfig
|
||||
+++ b/arch/mips/lantiq/xway/Kconfig
|
||||
@@ -14,6 +14,10 @@
|
||||
bool "Easy4010"
|
||||
default y
|
||||
|
||||
+config LANTIQ_MACH_ARV45XX
|
||||
+ bool "ARV45XX"
|
||||
+ default y
|
||||
+
|
||||
endmenu
|
||||
|
||||
endif
|
||||
--- a/arch/mips/lantiq/xway/Makefile
|
||||
+++ b/arch/mips/lantiq/xway/Makefile
|
||||
@@ -3,3 +3,4 @@
|
||||
obj-$(CONFIG_LANTIQ_MACH_EASY50812) += mach-easy50812.o
|
||||
obj-$(CONFIG_LANTIQ_MACH_EASY50712) += mach-easy50712.o
|
||||
obj-$(CONFIG_LANTIQ_MACH_EASY4010) += mach-easy4010.o
|
||||
+obj-$(CONFIG_LANTIQ_MACH_ARV45XX) += mach-arv45xx.o
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/xway/mach-arv45xx.c
|
||||
@@ -0,0 +1,178 @@
|
||||
+/*
|
||||
+ * This program is free software; you can redistribute it and/or modify it
|
||||
+ * under the terms of the GNU General Public License version 2 as published
|
||||
+ * by the Free Software Foundation.
|
||||
+ *
|
||||
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
|
||||
+ */
|
||||
+
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/leds.h>
|
||||
+#include <linux/gpio.h>
|
||||
+#include <linux/gpio_buttons.h>
|
||||
+#include <linux/mtd/mtd.h>
|
||||
+#include <linux/mtd/partitions.h>
|
||||
+#include <linux/mtd/physmap.h>
|
||||
+#include <linux/input.h>
|
||||
+#include <linux/etherdevice.h>
|
||||
+
|
||||
+#include <machine.h>
|
||||
+
|
||||
+#include <xway.h>
|
||||
+#include <lantiq_platform.h>
|
||||
+
|
||||
+#include "devices.h"
|
||||
+
|
||||
+#define ARV452_LATCH_SWITCH (1 << 10)
|
||||
+
|
||||
+#ifdef CONFIG_MTD_PARTITIONS
|
||||
+static struct mtd_partition arv45xx_partitions[] =
|
||||
+{
|
||||
+ {
|
||||
+ .name = "uboot",
|
||||
+ .offset = 0x0,
|
||||
+ .size = 0x20000,
|
||||
+ },
|
||||
+ {
|
||||
+ .name = "uboot_env",
|
||||
+ .offset = 0x20000,
|
||||
+ .size = 0x10000,
|
||||
+ },
|
||||
+ {
|
||||
+ .name = "linux",
|
||||
+ .offset = 0x30000,
|
||||
+ .size = 0x3c0000,
|
||||
+ },
|
||||
+ {
|
||||
+ .name = "board_config",
|
||||
+ .offset = 0x3f0000,
|
||||
+ .size = 0x10000,
|
||||
+ },
|
||||
+};
|
||||
+#endif
|
||||
+
|
||||
+static struct physmap_flash_data arv45xx_flash_data = {
|
||||
+#ifdef CONFIG_MTD_PARTITIONS
|
||||
+ .nr_parts = ARRAY_SIZE(arv45xx_partitions),
|
||||
+ .parts = arv45xx_partitions,
|
||||
+#endif
|
||||
+};
|
||||
+
|
||||
+static struct lq_pci_data lq_pci_data = {
|
||||
+ .clock = PCI_CLOCK_EXT,
|
||||
+ .req_mask = 0xf,
|
||||
+};
|
||||
+
|
||||
+static struct lq_eth_data lq_eth_data = {
|
||||
+ .mii_mode = REV_MII_MODE,
|
||||
+ .mac = "\xff\xff\xff\xff\xff\xff",
|
||||
+};
|
||||
+
|
||||
+static struct gpio_led
|
||||
+arv4518_leds_gpio[] __initdata = {
|
||||
+ { .name = "soc:blue:power", .gpio = 3, .active_low = 1, },
|
||||
+ { .name = "soc:blue:adsl", .gpio = 4, .active_low = 1, },
|
||||
+ { .name = "soc:blue:internet", .gpio = 5, .active_low = 1, },
|
||||
+ { .name = "soc:red:power", .gpio = 6, .active_low = 1, },
|
||||
+ { .name = "soc:yello:wps", .gpio = 7, .active_low = 1, },
|
||||
+ { .name = "soc:red:wps", .gpio = 9, .active_low = 1, },
|
||||
+ { .name = "soc:blue:voip", .gpio = 32, .active_low = 1, },
|
||||
+ { .name = "soc:blue:fxs1", .gpio = 33, .active_low = 1, },
|
||||
+ { .name = "soc:blue:fxs2", .gpio = 34, .active_low = 1, },
|
||||
+ { .name = "soc:blue:fxo", .gpio = 35, .active_low = 1, },
|
||||
+ { .name = "soc:blue:voice", .gpio = 36, .active_low = 1, },
|
||||
+ { .name = "soc:blue:usb", .gpio = 37, .active_low = 1, },
|
||||
+ { .name = "soc:blue:wlan", .gpio = 38, .active_low = 1, },
|
||||
+};
|
||||
+
|
||||
+static struct gpio_led
|
||||
+arv452_leds_gpio[] __initdata = {
|
||||
+ { .name = "soc:blue:power", .gpio = 3, .active_low = 1, },
|
||||
+ { .name = "soc:blue:adsl", .gpio = 4, .active_low = 1, },
|
||||
+ { .name = "soc:blue:internet", .gpio = 5, .active_low = 1, },
|
||||
+ { .name = "soc:red:power", .gpio = 6, .active_low = 1, },
|
||||
+ { .name = "soc:yello:wps", .gpio = 7, .active_low = 1, },
|
||||
+ { .name = "soc:red:wps", .gpio = 9, .active_low = 1, },
|
||||
+ { .name = "soc:blue:voip", .gpio = 32, .active_low = 1, },
|
||||
+ { .name = "soc:blue:fxs1", .gpio = 33, .active_low = 1, },
|
||||
+ { .name = "soc:blue:fxs2", .gpio = 34, .active_low = 1, },
|
||||
+ { .name = "soc:blue:fxo", .gpio = 35, .active_low = 1, },
|
||||
+ { .name = "soc:blue:voice", .gpio = 36, .active_low = 1, },
|
||||
+ { .name = "soc:blue:usb", .gpio = 37, .active_low = 1, },
|
||||
+ { .name = "soc:blue:wlan", .gpio = 38, .active_low = 1, },
|
||||
+};
|
||||
+
|
||||
+static struct gpio_led arv4525_leds_gpio[] __initdata = {
|
||||
+ { .name = "soc:green:festnetz", .gpio = 4, .active_low = 1, },
|
||||
+ { .name = "soc:green:internet", .gpio = 5, .active_low = 1, },
|
||||
+ { .name = "soc:green:dsl", .gpio = 6, .active_low = 1, },
|
||||
+ { .name = "soc:green:wlan", .gpio = 8, .active_low = 1, },
|
||||
+ { .name = "soc:green:online", .gpio = 9, .active_low = 1, },
|
||||
+};
|
||||
+
|
||||
+static void
|
||||
+arv45xx_register_ethernet(void)
|
||||
+{
|
||||
+#define ARV45XX_BRN_MAC 0x3f0016
|
||||
+ memcpy_fromio(lq_eth_data.mac,
|
||||
+ (void *)KSEG1ADDR(LQ_FLASH_START + ARV45XX_BRN_MAC), 6);
|
||||
+ lq_register_ethernet(&lq_eth_data);
|
||||
+}
|
||||
+
|
||||
+static void __init
|
||||
+arv4518_init(void)
|
||||
+{
|
||||
+ lq_register_gpio();
|
||||
+ lq_register_gpio_ebu(0);
|
||||
+ lq_register_gpio_leds(arv4518_leds_gpio, ARRAY_SIZE(arv4518_leds_gpio));
|
||||
+ lq_register_asc(0);
|
||||
+ lq_register_asc(1);
|
||||
+ lq_register_nor(&arv45xx_flash_data);
|
||||
+ lq_register_pci(&lq_pci_data);
|
||||
+ lq_register_wdt();
|
||||
+ arv45xx_register_ethernet();
|
||||
+}
|
||||
+
|
||||
+MIPS_MACHINE(LANTIQ_MACH_ARV4518,
|
||||
+ "ARV4518",
|
||||
+ "ARV4518 - SMC7908A-ISP",
|
||||
+ arv4518_init);
|
||||
+
|
||||
+static void __init
|
||||
+arv452_init(void)
|
||||
+{
|
||||
+ lq_register_gpio();
|
||||
+ lq_register_gpio_ebu(ARV452_LATCH_SWITCH);
|
||||
+ lq_register_gpio_leds(arv452_leds_gpio, ARRAY_SIZE(arv452_leds_gpio));
|
||||
+ lq_register_asc(0);
|
||||
+ lq_register_asc(1);
|
||||
+ lq_register_nor(&arv45xx_flash_data);
|
||||
+ lq_register_pci(&lq_pci_data);
|
||||
+ lq_register_wdt();
|
||||
+ arv45xx_register_ethernet();
|
||||
+}
|
||||
+
|
||||
+MIPS_MACHINE(LANTIQ_MACH_ARV452,
|
||||
+ "ARV452",
|
||||
+ "ARV452 - Airties WAV-281, Arcor A800",
|
||||
+ arv452_init);
|
||||
+
|
||||
+static void __init
|
||||
+arv4525_init(void)
|
||||
+{
|
||||
+ lq_register_gpio();
|
||||
+ lq_register_gpio_leds(arv4525_leds_gpio, ARRAY_SIZE(arv4525_leds_gpio));
|
||||
+ lq_register_asc(0);
|
||||
+ lq_register_asc(1);
|
||||
+ lq_register_nor(&arv45xx_flash_data);
|
||||
+ lq_register_pci(&lq_pci_data);
|
||||
+ lq_register_wdt();
|
||||
+ lq_eth_data.mii_mode = MII_MODE;
|
||||
+ arv45xx_register_ethernet();
|
||||
+}
|
||||
+
|
||||
+MIPS_MACHINE(LANTIQ_MACH_ARV4525,
|
||||
+ "ARV4525",
|
||||
+ "ARV4525 - Speedport W502V",
|
||||
+ arv4525_init);
|
||||
15693
target/linux/lantiq/patches/700-dwc_otg.patch
Normal file
15693
target/linux/lantiq/patches/700-dwc_otg.patch
Normal file
File diff suppressed because it is too large
Load Diff
1173
target/linux/lantiq/patches/809-mt-vpe.patch
Normal file
1173
target/linux/lantiq/patches/809-mt-vpe.patch
Normal file
File diff suppressed because it is too large
Load Diff
301
target/linux/lantiq/patches/810-ar9-cache-split.patch
Normal file
301
target/linux/lantiq/patches/810-ar9-cache-split.patch
Normal file
@@ -0,0 +1,301 @@
|
||||
--- a/arch/mips/Kconfig
|
||||
+++ b/arch/mips/Kconfig
|
||||
@@ -1706,6 +1706,28 @@
|
||||
help
|
||||
IFX included extensions in APRP
|
||||
|
||||
+config IFX_VPE_CACHE_SPLIT
|
||||
+ bool "IFX Cache Split Ways"
|
||||
+ depends on IFX_VPE_EXT
|
||||
+ help
|
||||
+ IFX extension for reserving (splitting) cache ways among VPEs. You must
|
||||
+ give kernel command line arguments vpe_icache_shared=0 or
|
||||
+ vpe_dcache_shared=0 to enable splitting of icache or dcache
|
||||
+ respectively. Then you can specify which cache ways should be
|
||||
+ assigned to which VPE. There are total 8 cache ways, 4 each
|
||||
+ for dcache and icache: dcache_way0, dcache_way1,dcache_way2,
|
||||
+ dcache_way3 and icache_way0,icache_way1, icache_way2,icache_way3.
|
||||
+
|
||||
+ For example, if you specify vpe_icache_shared=0 and icache_way2=1,
|
||||
+ then the 3rd icache way will be assigned to VPE0 and denied in VPE1.
|
||||
+
|
||||
+ For icache, software is required to make at least one cache way available
|
||||
+ for a VPE at all times i.e., one can't assign all the icache ways to one
|
||||
+ VPE.
|
||||
+
|
||||
+ By default, vpe_dcache_shared and vpe_icache_shared are set to 1
|
||||
+ (i.e., both icache and dcache are shared among VPEs)
|
||||
+
|
||||
config PERFCTRS
|
||||
bool "34K Performance counters"
|
||||
depends on MIPS_MT && PROC_FS
|
||||
--- a/arch/mips/kernel/vpe.c
|
||||
+++ b/arch/mips/kernel/vpe.c
|
||||
@@ -128,6 +128,13 @@
|
||||
EXPORT_SYMBOL(vpe1_wdog_timeout);
|
||||
|
||||
#endif
|
||||
+
|
||||
+#ifdef CONFIG_IFX_VPE_CACHE_SPLIT /* Code for splitting the cache ways among VPEs. */
|
||||
+extern int vpe_icache_shared,vpe_dcache_shared;
|
||||
+extern int icache_way0,icache_way1,icache_way2,icache_way3;
|
||||
+extern int dcache_way0,dcache_way1,dcache_way2,dcache_way3;
|
||||
+#endif
|
||||
+
|
||||
/* grab the likely amount of memory we will need. */
|
||||
#ifdef CONFIG_MIPS_VPE_LOADER_TOM
|
||||
#define P_SIZE (2 * 1024 * 1024)
|
||||
@@ -866,6 +873,65 @@
|
||||
/* enable this VPE */
|
||||
write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() | VPECONF0_VPA);
|
||||
|
||||
+#ifdef CONFIG_IFX_VPE_CACHE_SPLIT
|
||||
+ if ( (!vpe_icache_shared) || (!vpe_dcache_shared) ) {
|
||||
+
|
||||
+ /* PCP bit must be 1 to split the cache */
|
||||
+ if(read_c0_mvpconf0() & MVPCONF0_PCP) {
|
||||
+
|
||||
+ if ( !vpe_icache_shared ){
|
||||
+ write_vpe_c0_vpeconf0((read_vpe_c0_vpeconf0()) & ~VPECONF0_ICS);
|
||||
+
|
||||
+ /*
|
||||
+ * If any cache way is 1, then that way is denied
|
||||
+ * in VPE1. Otherwise assign that way to VPE1.
|
||||
+ */
|
||||
+ if (!icache_way0)
|
||||
+ write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() | VPEOPT_IWX0 );
|
||||
+ else
|
||||
+ write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() & ~VPEOPT_IWX0 );
|
||||
+ if (!icache_way1)
|
||||
+ write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() | VPEOPT_IWX1 );
|
||||
+ else
|
||||
+ write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() & ~VPEOPT_IWX1 );
|
||||
+ if (!icache_way2)
|
||||
+ write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() | VPEOPT_IWX2 );
|
||||
+ else
|
||||
+ write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() & ~VPEOPT_IWX2 );
|
||||
+ if (!icache_way3)
|
||||
+ write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() | VPEOPT_IWX3 );
|
||||
+ else
|
||||
+ write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() & ~VPEOPT_IWX3 );
|
||||
+ }
|
||||
+
|
||||
+ if ( !vpe_dcache_shared ) {
|
||||
+ write_vpe_c0_vpeconf0((read_vpe_c0_vpeconf0()) & ~VPECONF0_DCS);
|
||||
+
|
||||
+ /*
|
||||
+ * If any cache way is 1, then that way is denied
|
||||
+ * in VPE1. Otherwise assign that way to VPE1.
|
||||
+ */
|
||||
+ if (!dcache_way0)
|
||||
+ write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() | VPEOPT_DWX0 );
|
||||
+ else
|
||||
+ write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() & ~VPEOPT_DWX0 );
|
||||
+ if (!dcache_way1)
|
||||
+ write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() | VPEOPT_DWX1 );
|
||||
+ else
|
||||
+ write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() & ~VPEOPT_DWX1 );
|
||||
+ if (!dcache_way2)
|
||||
+ write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() | VPEOPT_DWX2 );
|
||||
+ else
|
||||
+ write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() & ~VPEOPT_DWX2 );
|
||||
+ if (!dcache_way3)
|
||||
+ write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() | VPEOPT_DWX3 );
|
||||
+ else
|
||||
+ write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() & ~VPEOPT_DWX3 );
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+#endif /* endif CONFIG_IFX_VPE_CACHE_SPLIT */
|
||||
+
|
||||
/* clear out any left overs from a previous program */
|
||||
write_vpe_c0_status(0);
|
||||
write_vpe_c0_cause(0);
|
||||
--- a/arch/mips/mm/c-r4k.c
|
||||
+++ b/arch/mips/mm/c-r4k.c
|
||||
@@ -1348,6 +1348,106 @@
|
||||
__setup("coherentio", setcoherentio);
|
||||
#endif
|
||||
|
||||
+#ifdef CONFIG_IFX_VPE_CACHE_SPLIT /* Code for splitting the cache ways among VPEs. */
|
||||
+
|
||||
+#include <asm/mipsmtregs.h>
|
||||
+
|
||||
+/*
|
||||
+ * By default, vpe_icache_shared and vpe_dcache_shared
|
||||
+ * values are 1 i.e., both icache and dcache are shared
|
||||
+ * among the VPEs.
|
||||
+ */
|
||||
+
|
||||
+int vpe_icache_shared = 1;
|
||||
+static int __init vpe_icache_shared_val(char *str)
|
||||
+{
|
||||
+ get_option(&str, &vpe_icache_shared);
|
||||
+ return 1;
|
||||
+}
|
||||
+__setup("vpe_icache_shared=", vpe_icache_shared_val);
|
||||
+EXPORT_SYMBOL(vpe_icache_shared);
|
||||
+
|
||||
+int vpe_dcache_shared = 1;
|
||||
+static int __init vpe_dcache_shared_val(char *str)
|
||||
+{
|
||||
+ get_option(&str, &vpe_dcache_shared);
|
||||
+ return 1;
|
||||
+}
|
||||
+__setup("vpe_dcache_shared=", vpe_dcache_shared_val);
|
||||
+EXPORT_SYMBOL(vpe_dcache_shared);
|
||||
+
|
||||
+/*
|
||||
+ * Software is required to make atleast one icache
|
||||
+ * way available for a VPE at all times i.e., one
|
||||
+ * can't assign all the icache ways to one VPE.
|
||||
+ */
|
||||
+
|
||||
+int icache_way0 = 0;
|
||||
+static int __init icache_way0_val(char *str)
|
||||
+{
|
||||
+ get_option(&str, &icache_way0);
|
||||
+ return 1;
|
||||
+}
|
||||
+__setup("icache_way0=", icache_way0_val);
|
||||
+
|
||||
+int icache_way1 = 0;
|
||||
+static int __init icache_way1_val(char *str)
|
||||
+{
|
||||
+ get_option(&str, &icache_way1);
|
||||
+ return 1;
|
||||
+}
|
||||
+__setup("icache_way1=", icache_way1_val);
|
||||
+
|
||||
+int icache_way2 = 0;
|
||||
+static int __init icache_way2_val(char *str)
|
||||
+{
|
||||
+ get_option(&str, &icache_way2);
|
||||
+ return 1;
|
||||
+}
|
||||
+__setup("icache_way2=", icache_way2_val);
|
||||
+
|
||||
+int icache_way3 = 0;
|
||||
+static int __init icache_way3_val(char *str)
|
||||
+{
|
||||
+ get_option(&str, &icache_way3);
|
||||
+ return 1;
|
||||
+}
|
||||
+__setup("icache_way3=", icache_way3_val);
|
||||
+
|
||||
+int dcache_way0 = 0;
|
||||
+static int __init dcache_way0_val(char *str)
|
||||
+{
|
||||
+ get_option(&str, &dcache_way0);
|
||||
+ return 1;
|
||||
+}
|
||||
+__setup("dcache_way0=", dcache_way0_val);
|
||||
+
|
||||
+int dcache_way1 = 0;
|
||||
+static int __init dcache_way1_val(char *str)
|
||||
+{
|
||||
+ get_option(&str, &dcache_way1);
|
||||
+ return 1;
|
||||
+}
|
||||
+__setup("dcache_way1=", dcache_way1_val);
|
||||
+
|
||||
+int dcache_way2 = 0;
|
||||
+static int __init dcache_way2_val(char *str)
|
||||
+{
|
||||
+ get_option(&str, &dcache_way2);
|
||||
+ return 1;
|
||||
+}
|
||||
+__setup("dcache_way2=", dcache_way2_val);
|
||||
+
|
||||
+int dcache_way3 = 0;
|
||||
+static int __init dcache_way3_val(char *str)
|
||||
+{
|
||||
+ get_option(&str, &dcache_way3);
|
||||
+ return 1;
|
||||
+}
|
||||
+__setup("dcache_way3=", dcache_way3_val);
|
||||
+
|
||||
+#endif /* endif CONFIG_IFX_VPE_CACHE_SPLIT */
|
||||
+
|
||||
void __cpuinit r4k_cache_init(void)
|
||||
{
|
||||
extern void build_clear_page(void);
|
||||
@@ -1367,6 +1467,78 @@
|
||||
break;
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_IFX_VPE_CACHE_SPLIT
|
||||
+ /*
|
||||
+ * We split the cache ways appropriately among the VPEs
|
||||
+ * based on cache ways values we received as command line
|
||||
+ * arguments
|
||||
+ */
|
||||
+ if ( (!vpe_icache_shared) || (!vpe_dcache_shared) ){
|
||||
+
|
||||
+ /* PCP bit must be 1 to split the cache */
|
||||
+ if(read_c0_mvpconf0() & MVPCONF0_PCP) {
|
||||
+
|
||||
+ /* Set CPA bit which enables us to modify VPEOpt register */
|
||||
+ write_c0_mvpcontrol((read_c0_mvpcontrol()) | MVPCONTROL_CPA);
|
||||
+
|
||||
+ if ( !vpe_icache_shared ){
|
||||
+ write_c0_vpeconf0((read_c0_vpeconf0()) & ~VPECONF0_ICS);
|
||||
+ /*
|
||||
+ * If any cache way is 1, then that way is denied
|
||||
+ * in VPE0. Otherwise assign that way to VPE0.
|
||||
+ */
|
||||
+ printk(KERN_DEBUG "icache is split\n");
|
||||
+ printk(KERN_DEBUG "icache_way0=%d icache_way1=%d icache_way2=%d icache_way3=%d\n",
|
||||
+ icache_way0, icache_way1,icache_way2, icache_way3);
|
||||
+ if (icache_way0)
|
||||
+ write_c0_vpeopt(read_c0_vpeopt() | VPEOPT_IWX0 );
|
||||
+ else
|
||||
+ write_c0_vpeopt(read_c0_vpeopt() & ~VPEOPT_IWX0 );
|
||||
+ if (icache_way1)
|
||||
+ write_c0_vpeopt(read_c0_vpeopt() | VPEOPT_IWX1 );
|
||||
+ else
|
||||
+ write_c0_vpeopt(read_c0_vpeopt() & ~VPEOPT_IWX1 );
|
||||
+ if (icache_way2)
|
||||
+ write_c0_vpeopt(read_c0_vpeopt() | VPEOPT_IWX2 );
|
||||
+ else
|
||||
+ write_c0_vpeopt(read_c0_vpeopt() & ~VPEOPT_IWX2 );
|
||||
+ if (icache_way3)
|
||||
+ write_c0_vpeopt(read_c0_vpeopt() | VPEOPT_IWX3 );
|
||||
+ else
|
||||
+ write_c0_vpeopt(read_c0_vpeopt() & ~VPEOPT_IWX3 );
|
||||
+ }
|
||||
+
|
||||
+ if ( !vpe_dcache_shared ) {
|
||||
+ /*
|
||||
+ * If any cache way is 1, then that way is denied
|
||||
+ * in VPE0. Otherwise assign that way to VPE0.
|
||||
+ */
|
||||
+ printk(KERN_DEBUG "dcache is split\n");
|
||||
+ printk(KERN_DEBUG "dcache_way0=%d dcache_way1=%d dcache_way2=%d dcache_way3=%d\n",
|
||||
+ dcache_way0, dcache_way1, dcache_way2, dcache_way3);
|
||||
+ write_c0_vpeconf0((read_c0_vpeconf0()) & ~VPECONF0_DCS);
|
||||
+ if (dcache_way0)
|
||||
+ write_c0_vpeopt(read_c0_vpeopt() | VPEOPT_DWX0 );
|
||||
+ else
|
||||
+ write_c0_vpeopt(read_c0_vpeopt() & ~VPEOPT_DWX0 );
|
||||
+ if (dcache_way1)
|
||||
+ write_c0_vpeopt(read_c0_vpeopt() | VPEOPT_DWX1 );
|
||||
+ else
|
||||
+ write_c0_vpeopt(read_c0_vpeopt() & ~VPEOPT_DWX1 );
|
||||
+ if (dcache_way2)
|
||||
+ write_c0_vpeopt(read_c0_vpeopt() | VPEOPT_DWX2 );
|
||||
+ else
|
||||
+ write_c0_vpeopt(read_c0_vpeopt() & ~VPEOPT_DWX2 );
|
||||
+ if (dcache_way3)
|
||||
+ write_c0_vpeopt(read_c0_vpeopt() | VPEOPT_DWX3 );
|
||||
+ else
|
||||
+ write_c0_vpeopt(read_c0_vpeopt() & ~VPEOPT_DWX3 );
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+#endif /* endif CONFIG_IFX_VPE_CACHE_SPLIT */
|
||||
+
|
||||
probe_pcache();
|
||||
setup_scache();
|
||||
|
||||
40
target/linux/lantiq/patches/900-pci_ath5k_hook.patch
Normal file
40
target/linux/lantiq/patches/900-pci_ath5k_hook.patch
Normal file
@@ -0,0 +1,40 @@
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/include/asm/mach-lantiq/pci.h
|
||||
@@ -0,0 +1,14 @@
|
||||
+/*
|
||||
+ * lantiq SoCs specific PCI definitions
|
||||
+ *
|
||||
+ * 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 __ASM_MACH_LANTIQ_PCI_H
|
||||
+#define __ASM_MACH_LANTIQ_PCI_H
|
||||
+
|
||||
+extern int (*ifxmips_pci_plat_dev_init)(struct pci_dev *dev);
|
||||
+
|
||||
+#endif
|
||||
--- a/arch/mips/pci/pci-lantiq.c
|
||||
+++ b/arch/mips/pci/pci-lantiq.c
|
||||
@@ -68,6 +68,8 @@
|
||||
|
||||
u32 lq_pci_mapped_cfg;
|
||||
|
||||
+int (*lqpci_plat_dev_init)(struct pci_dev *dev) = NULL;
|
||||
+
|
||||
/* Since the PCI REQ pins can be reused for other functionality, make it possible
|
||||
to exclude those from interpretation by the PCI controller */
|
||||
static int lq_pci_req_mask = 0xf;
|
||||
@@ -126,6 +128,10 @@
|
||||
printk ("WARNING: invalid interrupt pin %d\n", pin);
|
||||
return 1;
|
||||
}
|
||||
+
|
||||
+ if (lqpci_plat_dev_init)
|
||||
+ return lqpci_plat_dev_init(dev);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
21
target/linux/lantiq/xway/config-default
Normal file
21
target/linux/lantiq/xway/config-default
Normal file
@@ -0,0 +1,21 @@
|
||||
# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
|
||||
# CONFIG_CRYPTO_HW is not set
|
||||
CONFIG_HAVE_IDE=y
|
||||
CONFIG_HW_HAS_PCI=y
|
||||
CONFIG_IMAGE_CMDLINE_HACK=y
|
||||
CONFIG_LANTIQ_ETOP=y
|
||||
CONFIG_LANTIQ_MACH_ARV45XX=y
|
||||
CONFIG_LANTIQ_MACH_EASY4010=y
|
||||
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_SCSI_MOD=y
|
||||
CONFIG_SOC_LANTIQ=y
|
||||
CONFIG_SOC_LANTIQ_XWAY=y
|
||||
CONFIG_USB_SUPPORT=y
|
||||
11
target/linux/lantiq/xway/target.mk
Normal file
11
target/linux/lantiq/xway/target.mk
Normal file
@@ -0,0 +1,11 @@
|
||||
ARCH:=mips
|
||||
SUBTARGET:=xway
|
||||
BOARDNAME:=Xway
|
||||
FEATURES:=squashfs jffs2 atm
|
||||
|
||||
DEFAULT_PACKAGES+=uboot-lantiq-easy50712 kmod-pppoa ppp-mod-pppoa linux-atm atm-tools br2684ctl ifxmips-dsl-api ifxmips-dsl-control ifx-tapidemo
|
||||
|
||||
define Target/Description
|
||||
Lantiq XWAY (danube/twinpass/ar9)
|
||||
endef
|
||||
|
||||
Reference in New Issue
Block a user