lantiq: add 3.18 support
Signed-off-by: John Crispin <blogic@openwrt.org> SVN-Revision: 44348
This commit is contained in:
parent
64f9626963
commit
826b461427
49 changed files with 16771 additions and 349 deletions
|
@ -12,7 +12,7 @@ FEATURES:=squashfs
|
||||||
SUBTARGETS=xway xrx200
|
SUBTARGETS=xway xrx200
|
||||||
MAINTAINER:=John Crispin <blogic@openwrt.org>
|
MAINTAINER:=John Crispin <blogic@openwrt.org>
|
||||||
|
|
||||||
KERNEL_PATCHVER:=3.14
|
KERNEL_PATCHVER:=3.18
|
||||||
|
|
||||||
CPU_TYPE:=mips32r2
|
CPU_TYPE:=mips32r2
|
||||||
|
|
||||||
|
|
160
target/linux/lantiq/config-3.18
Normal file
160
target/linux/lantiq/config-3.18
Normal file
|
@ -0,0 +1,160 @@
|
||||||
|
CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
|
||||||
|
CONFIG_ARCH_DISCARD_MEMBLOCK=y
|
||||||
|
CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
|
||||||
|
CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
|
||||||
|
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
|
||||||
|
CONFIG_ARCH_REQUIRE_GPIOLIB=y
|
||||||
|
CONFIG_ARCH_SUPPORTS_MSI=y
|
||||||
|
CONFIG_ARCH_SUSPEND_POSSIBLE=y
|
||||||
|
CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
|
||||||
|
CONFIG_CEVT_R4K=y
|
||||||
|
CONFIG_CLKDEV_LOOKUP=y
|
||||||
|
CONFIG_CPU_BIG_ENDIAN=y
|
||||||
|
CONFIG_CPU_GENERIC_DUMP_TLB=y
|
||||||
|
CONFIG_CPU_HAS_PREFETCH=y
|
||||||
|
CONFIG_CPU_HAS_SYNC=y
|
||||||
|
CONFIG_CPU_MIPS32=y
|
||||||
|
# CONFIG_CPU_MIPS32_R1 is not set
|
||||||
|
CONFIG_CPU_MIPS32_R2=y
|
||||||
|
CONFIG_CPU_MIPSR2=y
|
||||||
|
CONFIG_CPU_R4K_CACHE_TLB=y
|
||||||
|
CONFIG_CPU_R4K_FPU=y
|
||||||
|
CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
|
||||||
|
CONFIG_CPU_SUPPORTS_HIGHMEM=y
|
||||||
|
CONFIG_CRYPTO_HASH=y
|
||||||
|
CONFIG_CRYPTO_HASH2=y
|
||||||
|
CONFIG_CSRC_R4K=y
|
||||||
|
CONFIG_DECOMPRESS_LZMA=y
|
||||||
|
CONFIG_DMA_NONCOHERENT=y
|
||||||
|
CONFIG_DTC=y
|
||||||
|
CONFIG_DT_EASY50712=y
|
||||||
|
CONFIG_EARLY_PRINTK=y
|
||||||
|
CONFIG_ETHERNET_PACKET_MANGLE=y
|
||||||
|
CONFIG_GENERIC_ATOMIC64=y
|
||||||
|
CONFIG_GENERIC_CLOCKEVENTS=y
|
||||||
|
CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
|
||||||
|
CONFIG_GENERIC_CMOS_UPDATE=y
|
||||||
|
CONFIG_GENERIC_GPIO=y
|
||||||
|
CONFIG_GENERIC_IO=y
|
||||||
|
CONFIG_GENERIC_IRQ_SHOW=y
|
||||||
|
CONFIG_GENERIC_PCI_IOMAP=y
|
||||||
|
CONFIG_GENERIC_SMP_IDLE_THREAD=y
|
||||||
|
CONFIG_GPIOLIB=y
|
||||||
|
CONFIG_GPIO_MM_LANTIQ=y
|
||||||
|
CONFIG_GPIO_STP_XWAY=y
|
||||||
|
CONFIG_GPIO_SYSFS=y
|
||||||
|
CONFIG_HARDWARE_WATCHPOINTS=y
|
||||||
|
CONFIG_HAS_DMA=y
|
||||||
|
CONFIG_HAS_IOMEM=y
|
||||||
|
CONFIG_HAS_IOPORT=y
|
||||||
|
CONFIG_HAVE_ARCH_JUMP_LABEL=y
|
||||||
|
CONFIG_HAVE_ARCH_KGDB=y
|
||||||
|
CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y
|
||||||
|
CONFIG_HAVE_CLK=y
|
||||||
|
CONFIG_HAVE_C_RECORDMCOUNT=y
|
||||||
|
CONFIG_HAVE_DEBUG_KMEMLEAK=y
|
||||||
|
CONFIG_HAVE_DMA_API_DEBUG=y
|
||||||
|
CONFIG_HAVE_DMA_ATTRS=y
|
||||||
|
CONFIG_HAVE_DYNAMIC_FTRACE=y
|
||||||
|
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
|
||||||
|
CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
|
||||||
|
CONFIG_HAVE_FUNCTION_TRACER=y
|
||||||
|
CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
|
||||||
|
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
|
||||||
|
CONFIG_HAVE_GENERIC_HARDIRQS=y
|
||||||
|
CONFIG_HAVE_IDE=y
|
||||||
|
CONFIG_HAVE_KVM=y
|
||||||
|
CONFIG_HAVE_MACH_CLKDEV=y
|
||||||
|
CONFIG_HAVE_MEMBLOCK=y
|
||||||
|
CONFIG_HAVE_MEMBLOCK_NODE_MAP=y
|
||||||
|
CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
|
||||||
|
CONFIG_HAVE_NET_DSA=y
|
||||||
|
CONFIG_HAVE_OPROFILE=y
|
||||||
|
CONFIG_HAVE_PERF_EVENTS=y
|
||||||
|
CONFIG_HW_HAS_PCI=y
|
||||||
|
CONFIG_HW_RANDOM=y
|
||||||
|
CONFIG_HZ=250
|
||||||
|
# CONFIG_HZ_100 is not set
|
||||||
|
CONFIG_HZ_250=y
|
||||||
|
CONFIG_INITRAMFS_SOURCE=""
|
||||||
|
CONFIG_IRQ_CPU=y
|
||||||
|
CONFIG_IRQ_DOMAIN=y
|
||||||
|
CONFIG_IRQ_FORCED_THREADING=y
|
||||||
|
CONFIG_LANTIQ=y
|
||||||
|
CONFIG_LANTIQ_ETOP=y
|
||||||
|
# CONFIG_LANTIQ_PHY is not set
|
||||||
|
CONFIG_LANTIQ_WDT=y
|
||||||
|
# CONFIG_LANTIQ_XRX200 is not set
|
||||||
|
CONFIG_LEDS_GPIO=y
|
||||||
|
CONFIG_MDIO_BOARDINFO=y
|
||||||
|
CONFIG_MIPS=y
|
||||||
|
# CONFIG_MIPS_HUGE_TLB_SUPPORT is not set
|
||||||
|
CONFIG_MIPS_L1_CACHE_SHIFT=5
|
||||||
|
# CONFIG_MIPS_MACHINE is not set
|
||||||
|
CONFIG_MIPS_MT_DISABLED=y
|
||||||
|
# CONFIG_MIPS_MT_SMP is not set
|
||||||
|
# CONFIG_MIPS_MT_SMTC is not set
|
||||||
|
# CONFIG_MIPS_O32_FP64_SUPPORT is not set
|
||||||
|
# CONFIG_MIPS_VPE_LOADER is not set
|
||||||
|
CONFIG_MODULES_USE_ELF_REL=y
|
||||||
|
CONFIG_MTD_CFI_ADV_OPTIONS=y
|
||||||
|
CONFIG_MTD_CFI_GEOMETRY=y
|
||||||
|
CONFIG_MTD_CMDLINE_PARTS=y
|
||||||
|
CONFIG_MTD_JEDECPROBE=y
|
||||||
|
CONFIG_MTD_LANTIQ=y
|
||||||
|
# CONFIG_MTD_NAND_XWAY is not set
|
||||||
|
CONFIG_MTD_SPLIT_FIRMWARE=y
|
||||||
|
CONFIG_MTD_UIMAGE_SPLIT=y
|
||||||
|
CONFIG_NEED_DMA_MAP_STATE=y
|
||||||
|
CONFIG_NEED_PER_CPU_KM=y
|
||||||
|
CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y
|
||||||
|
CONFIG_OF=y
|
||||||
|
CONFIG_OF_ADDRESS=y
|
||||||
|
CONFIG_OF_DEVICE=y
|
||||||
|
CONFIG_OF_EARLY_FLATTREE=y
|
||||||
|
CONFIG_OF_FLATTREE=y
|
||||||
|
CONFIG_OF_GPIO=y
|
||||||
|
CONFIG_OF_IRQ=y
|
||||||
|
CONFIG_OF_MDIO=y
|
||||||
|
CONFIG_OF_MTD=y
|
||||||
|
CONFIG_OF_NET=y
|
||||||
|
CONFIG_OF_PCI=y
|
||||||
|
CONFIG_OF_PCI_IRQ=y
|
||||||
|
CONFIG_PAGEFLAGS_EXTENDED=y
|
||||||
|
CONFIG_PCI=y
|
||||||
|
# CONFIG_PCIE_LANTIQ is not set
|
||||||
|
CONFIG_PCI_DOMAINS=y
|
||||||
|
CONFIG_PCI_LANTIQ=y
|
||||||
|
CONFIG_PERCPU_RWSEM=y
|
||||||
|
CONFIG_PERF_USE_VMALLOC=y
|
||||||
|
CONFIG_PHYLIB=y
|
||||||
|
CONFIG_PINCTRL=y
|
||||||
|
CONFIG_PINCTRL_LANTIQ=y
|
||||||
|
# CONFIG_PINCTRL_SINGLE is not set
|
||||||
|
CONFIG_PINCTRL_XWAY=y
|
||||||
|
# CONFIG_PREEMPT_RCU is not set
|
||||||
|
CONFIG_PROC_DEVICETREE=y
|
||||||
|
CONFIG_PSB6970_PHY=y
|
||||||
|
CONFIG_RTL8366RB_PHY=y
|
||||||
|
CONFIG_RTL8366_SMI=y
|
||||||
|
# CONFIG_SCSI_DMA is not set
|
||||||
|
# CONFIG_SERIAL_8250 is not set
|
||||||
|
CONFIG_SERIAL_LANTIQ=y
|
||||||
|
# CONFIG_SOC_AMAZON_SE is not set
|
||||||
|
# CONFIG_SOC_FALCON is not set
|
||||||
|
CONFIG_SOC_TYPE_XWAY=y
|
||||||
|
CONFIG_SOC_XWAY=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_TICK_CPU_ACCOUNTING=y
|
||||||
|
CONFIG_UIDGID_CONVERTED=y
|
||||||
|
CONFIG_USB_ARCH_HAS_XHCI=y
|
||||||
|
CONFIG_USE_OF=y
|
||||||
|
CONFIG_ZONE_DMA_FLAG=0
|
|
@ -1,65 +0,0 @@
|
||||||
/dts-v1/;
|
|
||||||
|
|
||||||
/include/ "falcon.dtsi"
|
|
||||||
|
|
||||||
/ {
|
|
||||||
model = "EASY98000 - Lantiq Falcon (NOR)";
|
|
||||||
|
|
||||||
chosen {
|
|
||||||
bootargs = "console=ttyLTQ0,115200 init=/etc/preinit";
|
|
||||||
};
|
|
||||||
|
|
||||||
memory@0 {
|
|
||||||
reg = <0x0 0x2000000>;
|
|
||||||
};
|
|
||||||
|
|
||||||
localbus@10000000 {
|
|
||||||
cfi@0 {
|
|
||||||
compatible = "lantiq,nor";
|
|
||||||
bank-width = <2>;
|
|
||||||
reg = <0x0 0x4000000>;
|
|
||||||
#address-cells = <1>;
|
|
||||||
#size-cells = <1>;
|
|
||||||
|
|
||||||
partition@0 {
|
|
||||||
label = "uboot";
|
|
||||||
reg = <0x00000 0x40000>;
|
|
||||||
};
|
|
||||||
|
|
||||||
partition@10000 {
|
|
||||||
label = "uboot_env";
|
|
||||||
reg = <0x40000 0x40000>;
|
|
||||||
};
|
|
||||||
|
|
||||||
partition@20000 {
|
|
||||||
label = "firmware";
|
|
||||||
reg = <0x80000 0x3d0000>;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
pinmux0 {
|
|
||||||
compatible = "lantiq,pinctrl-falcon";
|
|
||||||
pinctrl-names = "default";
|
|
||||||
pinctrl-0 = <&state_default>;
|
|
||||||
|
|
||||||
state_default: pinmux {
|
|
||||||
asc0 {
|
|
||||||
lantiq,groups = "asc0";
|
|
||||||
lantiq,function = "asc";
|
|
||||||
};
|
|
||||||
ntr {
|
|
||||||
lantiq,groups = "ntr8k";
|
|
||||||
lantiq,function = "ntr";
|
|
||||||
};
|
|
||||||
i2c {
|
|
||||||
lantiq,groups = "i2c";
|
|
||||||
lantiq,function = "i2c";
|
|
||||||
};
|
|
||||||
hrst {
|
|
||||||
lantiq,groups = "hrst";
|
|
||||||
lantiq,function = "rst";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
|
@ -1,74 +0,0 @@
|
||||||
/dts-v1/;
|
|
||||||
|
|
||||||
/include/ "falcon.dtsi"
|
|
||||||
|
|
||||||
/ {
|
|
||||||
model = "EASY98000 - Lantiq Falcon (SFLASH)";
|
|
||||||
|
|
||||||
chosen {
|
|
||||||
bootargs = "console=ttyLTQ0,115200 init=/etc/preinit";
|
|
||||||
};
|
|
||||||
|
|
||||||
memory@0 {
|
|
||||||
reg = <0x0 0x2000000>;
|
|
||||||
};
|
|
||||||
|
|
||||||
localbus@10000000 {
|
|
||||||
#address-cells = <1>;
|
|
||||||
#size-cells = <1>;
|
|
||||||
compatible = "lantiq,sflash-falcon", "simple-bus";
|
|
||||||
busnum = <0>;
|
|
||||||
|
|
||||||
m25p80@0 {
|
|
||||||
#address-cells = <1>;
|
|
||||||
#size-cells = <1>;
|
|
||||||
compatible = "s25fl129p0";
|
|
||||||
reg = <0 0>;
|
|
||||||
linux,modalias = "m25p80", "s25fl129p0";
|
|
||||||
spi-max-frequency = <10000000>;
|
|
||||||
|
|
||||||
partition@0 {
|
|
||||||
reg = <0x0 0x00080000>;
|
|
||||||
label = "SPI (RO) U-Boot Image";
|
|
||||||
read-only;
|
|
||||||
};
|
|
||||||
|
|
||||||
partition@80000 {
|
|
||||||
reg = <0x00080000 0x00080000>;
|
|
||||||
label = "SPI (RO) DTB Image";
|
|
||||||
read-only;
|
|
||||||
};
|
|
||||||
|
|
||||||
partition@100000 {
|
|
||||||
reg = <0x00100000 0x00400000>;
|
|
||||||
label = "SPI (RO) Linux Kernel Image";
|
|
||||||
read-only;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
pinmux0 {
|
|
||||||
compatible = "lantiq,pinctrl-falcon";
|
|
||||||
pinctrl-names = "default";
|
|
||||||
pinctrl-0 = <&state_default>;
|
|
||||||
|
|
||||||
state_default: pinmux {
|
|
||||||
asc0 {
|
|
||||||
lantiq,groups = "asc0";
|
|
||||||
lantiq,function = "asc";
|
|
||||||
};
|
|
||||||
ntr {
|
|
||||||
lantiq,groups = "ntr8k";
|
|
||||||
lantiq,function = "ntr";
|
|
||||||
};
|
|
||||||
i2c {
|
|
||||||
lantiq,groups = "i2c";
|
|
||||||
lantiq,function = "i2c";
|
|
||||||
};
|
|
||||||
hrst {
|
|
||||||
lantiq,groups = "hrst";
|
|
||||||
lantiq,function = "rst";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
|
@ -9,6 +9,10 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
memory@0 {
|
||||||
|
device_type = "memory";
|
||||||
|
};
|
||||||
|
|
||||||
biu@1F800000 {
|
biu@1F800000 {
|
||||||
#address-cells = <1>;
|
#address-cells = <1>;
|
||||||
#size-cells = <1>;
|
#size-cells = <1>;
|
||||||
|
|
|
@ -13,6 +13,10 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
memory@0 {
|
||||||
|
device_type = "memory";
|
||||||
|
};
|
||||||
|
|
||||||
biu@1F800000 {
|
biu@1F800000 {
|
||||||
#address-cells = <1>;
|
#address-cells = <1>;
|
||||||
#size-cells = <1>;
|
#size-cells = <1>;
|
||||||
|
|
|
@ -1,201 +0,0 @@
|
||||||
/ {
|
|
||||||
#address-cells = <1>;
|
|
||||||
#size-cells = <1>;
|
|
||||||
compatible = "lantiq,falcon";
|
|
||||||
|
|
||||||
cpus {
|
|
||||||
cpu@0 {
|
|
||||||
compatible = "mips,mips34kc";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
localbus@10000000 {
|
|
||||||
#address-cells = <1>;
|
|
||||||
#size-cells = <1>;
|
|
||||||
compatible = "lantiq,localbus", "simple-bus";
|
|
||||||
reg = <0x10000000 0xC000000>;
|
|
||||||
ranges = <0x0 0x10000000 0xC000000>;
|
|
||||||
};
|
|
||||||
|
|
||||||
ebu@18000000 {
|
|
||||||
compatible = "lantiq,ebu-falcon";
|
|
||||||
reg = <0x18000000 0x100>;
|
|
||||||
};
|
|
||||||
|
|
||||||
sbs2@1D000000 {
|
|
||||||
#address-cells = <1>;
|
|
||||||
#size-cells = <1>;
|
|
||||||
compatible = "lantiq,sysb2", "simple-bus";
|
|
||||||
reg = <0x1D000000 0x1000000>;
|
|
||||||
ranges = <0x0 0x1D000000 0x1000000>;
|
|
||||||
|
|
||||||
sysgpe@700000 {
|
|
||||||
compatible = "lantiq,sysgpe-falcon";
|
|
||||||
reg = <0x700000 0x100>;
|
|
||||||
};
|
|
||||||
|
|
||||||
gpio0: gpio@810000 {
|
|
||||||
#gpio-cells = <2>;
|
|
||||||
compatible = "lantiq,gpio-falcon";
|
|
||||||
gpio-controller;
|
|
||||||
interrupt-parent = <&icu0>;
|
|
||||||
interrupts = <44>;
|
|
||||||
reg = <0x810000 0x80>;
|
|
||||||
lantiq,bank = <0>;
|
|
||||||
};
|
|
||||||
|
|
||||||
gpio2: gpio@810100 {
|
|
||||||
#gpio-cells = <2>;
|
|
||||||
compatible = "lantiq,gpio-falcon";
|
|
||||||
gpio-controller;
|
|
||||||
interrupt-parent = <&icu0>;
|
|
||||||
interrupts = <46>;
|
|
||||||
reg = <0x810100 0x80>;
|
|
||||||
lantiq,bank = <2>;
|
|
||||||
};
|
|
||||||
|
|
||||||
syseth@B00000 {
|
|
||||||
compatible = "lantiq,syseth-falcon";
|
|
||||||
reg = <0xB00000 0x100>;
|
|
||||||
};
|
|
||||||
|
|
||||||
pad@B01000 {
|
|
||||||
compatible = "lantiq,pad-falcon";
|
|
||||||
reg = <0xB01000 0x100>;
|
|
||||||
lantiq,bank = <0>;
|
|
||||||
};
|
|
||||||
|
|
||||||
pad@B02000 {
|
|
||||||
compatible = "lantiq,pad-falcon";
|
|
||||||
reg = <0xB02000 0x100>;
|
|
||||||
lantiq,bank = <2>;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
fpi@1E000000 {
|
|
||||||
#address-cells = <1>;
|
|
||||||
#size-cells = <1>;
|
|
||||||
compatible = "lantiq,fpi", "simple-bus";
|
|
||||||
reg = <0x1E000000 0x1000000>;
|
|
||||||
ranges = <0x0 0x1E000000 0x1000000>;
|
|
||||||
|
|
||||||
serial@100B00 {
|
|
||||||
status = "disabled";
|
|
||||||
compatible = "lantiq,asc";
|
|
||||||
reg = <0x100B00 0x100>;
|
|
||||||
interrupt-parent = <&icu0>;
|
|
||||||
interrupts = <104 105 106>;
|
|
||||||
line = <1>;
|
|
||||||
};
|
|
||||||
|
|
||||||
serial@100C00 {
|
|
||||||
compatible = "lantiq,asc";
|
|
||||||
reg = <0x100C00 0x100>;
|
|
||||||
interrupt-parent = <&icu0>;
|
|
||||||
interrupts = <104 105 106>;
|
|
||||||
line = <0>;
|
|
||||||
};
|
|
||||||
|
|
||||||
i2c@200000 {
|
|
||||||
compatible = "lantiq,lantiq-i2c";
|
|
||||||
reg = <0x200000 0x10000>;
|
|
||||||
interrupt-parent = <&icu0>;
|
|
||||||
interrupts = <18 19 20 21>;
|
|
||||||
gpios = <&gpio1 7 0 &gpio1 8 0>;
|
|
||||||
};
|
|
||||||
|
|
||||||
gpio1: gpio@800100 {
|
|
||||||
#gpio-cells = <2>;
|
|
||||||
compatible = "lantiq,gpio-falcon";
|
|
||||||
gpio-controller;
|
|
||||||
interrupt-parent = <&icu0>;
|
|
||||||
interrupts = <45>;
|
|
||||||
reg = <0x800100 0x100>;
|
|
||||||
lantiq,bank = <1>;
|
|
||||||
};
|
|
||||||
|
|
||||||
gpio3: gpio@800200 {
|
|
||||||
status = "disabled";
|
|
||||||
#gpio-cells = <2>;
|
|
||||||
compatible = "lantiq,gpio-falcon";
|
|
||||||
gpio-controller;
|
|
||||||
interrupt-parent = <&icu0>;
|
|
||||||
interrupts = <47>;
|
|
||||||
reg = <0x800200 0x100>;
|
|
||||||
lantiq,bank = <3>;
|
|
||||||
};
|
|
||||||
|
|
||||||
gpio4: gpio@800300 {
|
|
||||||
status = "disabled";
|
|
||||||
#gpio-cells = <2>;
|
|
||||||
compatible = "lantiq,gpio-falcon";
|
|
||||||
gpio-controller;
|
|
||||||
interrupt-parent = <&icu0>;
|
|
||||||
interrupts = <48>;
|
|
||||||
reg = <0x800300 0x100>;
|
|
||||||
lantiq,bank = <4>;
|
|
||||||
};
|
|
||||||
|
|
||||||
pad@800400 {
|
|
||||||
compatible = "lantiq,pad-falcon";
|
|
||||||
reg = <0x800400 0x100>;
|
|
||||||
lantiq,bank = <1>;
|
|
||||||
};
|
|
||||||
|
|
||||||
pad@800500 {
|
|
||||||
status = "disabled";
|
|
||||||
compatible = "lantiq,pad-falcon";
|
|
||||||
reg = <0x800500 0x100>;
|
|
||||||
bank = <3>;
|
|
||||||
};
|
|
||||||
|
|
||||||
pad4@800600 {
|
|
||||||
status = "disabled";
|
|
||||||
compatible = "lantiq,pad-falcon";
|
|
||||||
reg = <0x800600 0x100>;
|
|
||||||
bank = <4>;
|
|
||||||
};
|
|
||||||
|
|
||||||
status@802000 {
|
|
||||||
compatible = "lantiq,status-falcon";
|
|
||||||
reg = <0x802000 0x80>;
|
|
||||||
};
|
|
||||||
|
|
||||||
sys1@F00000 {
|
|
||||||
compatible = "lantiq,sys1-falcon";
|
|
||||||
reg = <0xF00000 0x100>;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
sbs0@1F000000 {
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
sbs1@1F700000 {
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
biu@1F800000 {
|
|
||||||
#address-cells = <1>;
|
|
||||||
#size-cells = <1>;
|
|
||||||
compatible = "lantiq,falcon";
|
|
||||||
reg = <0x1F800000 0x800000>;
|
|
||||||
ranges = <0x0 0x1F800000 0x7FFFFF>;
|
|
||||||
|
|
||||||
icu0: icu@80200 {
|
|
||||||
#interrupt-cells = <1>;
|
|
||||||
interrupt-controller;
|
|
||||||
compatible = "lantiq,icu";
|
|
||||||
reg = <0x80200 0x28
|
|
||||||
0x80228 0x28
|
|
||||||
0x80250 0x28
|
|
||||||
0x80278 0x28
|
|
||||||
0x802a0 0x28>;
|
|
||||||
};
|
|
||||||
|
|
||||||
watchdog@803F0 {
|
|
||||||
compatible = "lantiq,wdt";
|
|
||||||
reg = <0x803F0 0x10>;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
|
@ -9,6 +9,10 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
memory@0 {
|
||||||
|
device_type = "memory";
|
||||||
|
};
|
||||||
|
|
||||||
biu@1F800000 {
|
biu@1F800000 {
|
||||||
#address-cells = <1>;
|
#address-cells = <1>;
|
||||||
#size-cells = <1>;
|
#size-cells = <1>;
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,31 @@
|
||||||
|
From 17348293f7f8103c97c8d2a6b0ef36eae06ec371 Mon Sep 17 00:00:00 2001
|
||||||
|
From: John Crispin <blogic@openwrt.org>
|
||||||
|
Date: Wed, 13 Mar 2013 09:36:16 +0100
|
||||||
|
Subject: [PATCH 02/36] MIPS: lantiq: dtb image hack
|
||||||
|
|
||||||
|
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||||
|
---
|
||||||
|
arch/mips/lantiq/Makefile | 2 --
|
||||||
|
arch/mips/lantiq/prom.c | 4 +++-
|
||||||
|
2 files changed, 3 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
--- a/arch/mips/lantiq/prom.c
|
||||||
|
+++ b/arch/mips/lantiq/prom.c
|
||||||
|
@@ -58,6 +58,8 @@ static void __init prom_init_cmdline(voi
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+extern struct boot_param_header __image_dtb;
|
||||||
|
+
|
||||||
|
void __init plat_mem_setup(void)
|
||||||
|
{
|
||||||
|
ioport_resource.start = IOPORT_RESOURCE_START;
|
||||||
|
@@ -71,7 +73,7 @@ void __init plat_mem_setup(void)
|
||||||
|
* Load the builtin devicetree. This causes the chosen node to be
|
||||||
|
* parsed resulting in our memory appearing
|
||||||
|
*/
|
||||||
|
- __dt_setup_arch(__dtb_start);
|
||||||
|
+ __dt_setup_arch(&__image_dtb);
|
||||||
|
}
|
||||||
|
|
||||||
|
void __init device_tree_init(void)
|
|
@ -0,0 +1,86 @@
|
||||||
|
From 16e315864132b59749faff739230daf4cee9abbb Mon Sep 17 00:00:00 2001
|
||||||
|
From: John Crispin <blogic@openwrt.org>
|
||||||
|
Date: Wed, 13 Mar 2013 10:04:01 +0100
|
||||||
|
Subject: [PATCH 03/36] MIPS: lantiq: handle vmmc memory reservation
|
||||||
|
|
||||||
|
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||||
|
---
|
||||||
|
arch/mips/lantiq/xway/Makefile | 2 ++
|
||||||
|
arch/mips/lantiq/xway/vmmc.c | 63 ++++++++++++++++++++++++++++++++++++++++
|
||||||
|
2 files changed, 65 insertions(+)
|
||||||
|
create mode 100644 arch/mips/lantiq/xway/vmmc.c
|
||||||
|
|
||||||
|
--- a/arch/mips/lantiq/xway/Makefile
|
||||||
|
+++ b/arch/mips/lantiq/xway/Makefile
|
||||||
|
@@ -1,3 +1,5 @@
|
||||||
|
obj-y := prom.o sysctrl.o clk.o reset.o dma.o gptu.o dcdc.o
|
||||||
|
|
||||||
|
+obj-y += vmmc.o
|
||||||
|
+
|
||||||
|
obj-$(CONFIG_XRX200_PHY_FW) += xrx200_phy_fw.o
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/arch/mips/lantiq/xway/vmmc.c
|
||||||
|
@@ -0,0 +1,63 @@
|
||||||
|
+/*
|
||||||
|
+ * 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) 2012 John Crispin <blogic@openwrt.org>
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#include <linux/module.h>
|
||||||
|
+#include <linux/of_platform.h>
|
||||||
|
+#include <linux/of_gpio.h>
|
||||||
|
+#include <linux/dma-mapping.h>
|
||||||
|
+
|
||||||
|
+#include <lantiq_soc.h>
|
||||||
|
+
|
||||||
|
+static unsigned int *cp1_base = 0;
|
||||||
|
+unsigned int* ltq_get_cp1_base(void)
|
||||||
|
+{
|
||||||
|
+ if (!cp1_base)
|
||||||
|
+ panic("no cp1 base was set\n");
|
||||||
|
+ return cp1_base;
|
||||||
|
+}
|
||||||
|
+EXPORT_SYMBOL(ltq_get_cp1_base);
|
||||||
|
+
|
||||||
|
+static int vmmc_probe(struct platform_device *pdev)
|
||||||
|
+{
|
||||||
|
+#define CP1_SIZE (1 << 20)
|
||||||
|
+ int gpio_count;
|
||||||
|
+ dma_addr_t dma;
|
||||||
|
+ cp1_base =
|
||||||
|
+ (void*)CPHYSADDR(dma_alloc_coherent(NULL, CP1_SIZE, &dma, GFP_ATOMIC));
|
||||||
|
+
|
||||||
|
+ gpio_count = of_gpio_count(pdev->dev.of_node);
|
||||||
|
+ while (gpio_count > 0) {
|
||||||
|
+ enum of_gpio_flags flags;
|
||||||
|
+ int gpio = of_get_gpio_flags(pdev->dev.of_node, --gpio_count, &flags);
|
||||||
|
+ if (gpio_request(gpio, "vmmc-relay"))
|
||||||
|
+ continue;
|
||||||
|
+ dev_info(&pdev->dev, "requested GPIO %d\n", gpio);
|
||||||
|
+ gpio_direction_output(gpio, (flags & OF_GPIO_ACTIVE_LOW) ? (0) : (1));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ dev_info(&pdev->dev, "reserved %dMB at 0x%p", CP1_SIZE >> 20, cp1_base);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static const struct of_device_id vmmc_match[] = {
|
||||||
|
+ { .compatible = "lantiq,vmmc" },
|
||||||
|
+ {},
|
||||||
|
+};
|
||||||
|
+MODULE_DEVICE_TABLE(of, vmmc_match);
|
||||||
|
+
|
||||||
|
+static struct platform_driver vmmc_driver = {
|
||||||
|
+ .probe = vmmc_probe,
|
||||||
|
+ .driver = {
|
||||||
|
+ .name = "lantiq,vmmc",
|
||||||
|
+ .owner = THIS_MODULE,
|
||||||
|
+ .of_match_table = vmmc_match,
|
||||||
|
+ },
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+module_platform_driver(vmmc_driver);
|
|
@ -0,0 +1,500 @@
|
||||||
|
From 9afadf01b1be371ee88491819aa67364684461f9 Mon Sep 17 00:00:00 2001
|
||||||
|
From: John Crispin <blogic@openwrt.org>
|
||||||
|
Date: Fri, 3 Aug 2012 10:27:25 +0200
|
||||||
|
Subject: [PATCH 04/36] MIPS: lantiq: add atm hack
|
||||||
|
|
||||||
|
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||||
|
---
|
||||||
|
arch/mips/include/asm/mach-lantiq/lantiq_atm.h | 196 +++++++++++++++++++++++
|
||||||
|
arch/mips/include/asm/mach-lantiq/lantiq_ptm.h | 203 ++++++++++++++++++++++++
|
||||||
|
arch/mips/lantiq/irq.c | 2 +
|
||||||
|
arch/mips/mm/cache.c | 2 +
|
||||||
|
include/uapi/linux/atm.h | 6 +
|
||||||
|
net/atm/common.c | 6 +
|
||||||
|
net/atm/proc.c | 2 +-
|
||||||
|
7 files changed, 416 insertions(+), 1 deletion(-)
|
||||||
|
create mode 100644 arch/mips/include/asm/mach-lantiq/lantiq_atm.h
|
||||||
|
create mode 100644 arch/mips/include/asm/mach-lantiq/lantiq_ptm.h
|
||||||
|
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/arch/mips/include/asm/mach-lantiq/lantiq_atm.h
|
||||||
|
@@ -0,0 +1,196 @@
|
||||||
|
+/******************************************************************************
|
||||||
|
+**
|
||||||
|
+** FILE NAME : ifx_atm.h
|
||||||
|
+** PROJECT : UEIP
|
||||||
|
+** MODULES : ATM
|
||||||
|
+**
|
||||||
|
+** DATE : 17 Jun 2009
|
||||||
|
+** AUTHOR : Xu Liang
|
||||||
|
+** DESCRIPTION : Global ATM driver header file
|
||||||
|
+** COPYRIGHT : Copyright (c) 2006
|
||||||
|
+** Infineon Technologies AG
|
||||||
|
+** Am Campeon 1-12, 85579 Neubiberg, Germany
|
||||||
|
+**
|
||||||
|
+** This program is free software; you can redistribute it and/or modify
|
||||||
|
+** it under the terms of the GNU General Public License as published by
|
||||||
|
+** the Free Software Foundation; either version 2 of the License, or
|
||||||
|
+** (at your option) any later version.
|
||||||
|
+**
|
||||||
|
+** HISTORY
|
||||||
|
+** $Date $Author $Comment
|
||||||
|
+** 07 JUL 2009 Xu Liang Init Version
|
||||||
|
+*******************************************************************************/
|
||||||
|
+
|
||||||
|
+#ifndef IFX_ATM_H
|
||||||
|
+#define IFX_ATM_H
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+/*!
|
||||||
|
+ \defgroup IFX_ATM UEIP Project - ATM driver module
|
||||||
|
+ \brief UEIP Project - ATM driver module, support Danube, Amazon-SE, AR9, VR9.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+/*!
|
||||||
|
+ \defgroup IFX_ATM_IOCTL IOCTL Commands
|
||||||
|
+ \ingroup IFX_ATM
|
||||||
|
+ \brief IOCTL Commands used by user application.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+/*!
|
||||||
|
+ \defgroup IFX_ATM_STRUCT Structures
|
||||||
|
+ \ingroup IFX_ATM
|
||||||
|
+ \brief Structures used by user application.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+/*!
|
||||||
|
+ \file ifx_atm.h
|
||||||
|
+ \ingroup IFX_ATM
|
||||||
|
+ \brief ATM driver header file
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * ####################################
|
||||||
|
+ * Definition
|
||||||
|
+ * ####################################
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+/*!
|
||||||
|
+ \addtogroup IFX_ATM_STRUCT
|
||||||
|
+ */
|
||||||
|
+/*@{*/
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * ATM MIB
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+/*!
|
||||||
|
+ \struct atm_cell_ifEntry_t
|
||||||
|
+ \brief Structure used for Cell Level MIB Counters.
|
||||||
|
+
|
||||||
|
+ User application use this structure to call IOCTL command "PPE_ATM_MIB_CELL".
|
||||||
|
+ */
|
||||||
|
+typedef struct {
|
||||||
|
+ __u32 ifHCInOctets_h; /*!< byte counter of ingress cells (upper 32 bits, total 64 bits) */
|
||||||
|
+ __u32 ifHCInOctets_l; /*!< byte counter of ingress cells (lower 32 bits, total 64 bits) */
|
||||||
|
+ __u32 ifHCOutOctets_h; /*!< byte counter of egress cells (upper 32 bits, total 64 bits) */
|
||||||
|
+ __u32 ifHCOutOctets_l; /*!< byte counter of egress cells (lower 32 bits, total 64 bits) */
|
||||||
|
+ __u32 ifInErrors; /*!< counter of error ingress cells */
|
||||||
|
+ __u32 ifInUnknownProtos; /*!< counter of unknown ingress cells */
|
||||||
|
+ __u32 ifOutErrors; /*!< counter of error egress cells */
|
||||||
|
+} atm_cell_ifEntry_t;
|
||||||
|
+
|
||||||
|
+/*!
|
||||||
|
+ \struct atm_aal5_ifEntry_t
|
||||||
|
+ \brief Structure used for AAL5 Frame Level MIB Counters.
|
||||||
|
+
|
||||||
|
+ User application use this structure to call IOCTL command "PPE_ATM_MIB_AAL5".
|
||||||
|
+ */
|
||||||
|
+typedef struct {
|
||||||
|
+ __u32 ifHCInOctets_h; /*!< byte counter of ingress packets (upper 32 bits, total 64 bits) */
|
||||||
|
+ __u32 ifHCInOctets_l; /*!< byte counter of ingress packets (lower 32 bits, total 64 bits) */
|
||||||
|
+ __u32 ifHCOutOctets_h; /*!< byte counter of egress packets (upper 32 bits, total 64 bits) */
|
||||||
|
+ __u32 ifHCOutOctets_l; /*!< byte counter of egress packets (lower 32 bits, total 64 bits) */
|
||||||
|
+ __u32 ifInUcastPkts; /*!< counter of ingress packets */
|
||||||
|
+ __u32 ifOutUcastPkts; /*!< counter of egress packets */
|
||||||
|
+ __u32 ifInErrors; /*!< counter of error ingress packets */
|
||||||
|
+ __u32 ifInDiscards; /*!< counter of dropped ingress packets */
|
||||||
|
+ __u32 ifOutErros; /*!< counter of error egress packets */
|
||||||
|
+ __u32 ifOutDiscards; /*!< counter of dropped egress packets */
|
||||||
|
+} atm_aal5_ifEntry_t;
|
||||||
|
+
|
||||||
|
+/*!
|
||||||
|
+ \struct atm_aal5_vcc_t
|
||||||
|
+ \brief Structure used for per PVC AAL5 Frame Level MIB Counters.
|
||||||
|
+
|
||||||
|
+ This structure is a part of structure "atm_aal5_vcc_x_t".
|
||||||
|
+ */
|
||||||
|
+typedef struct {
|
||||||
|
+ __u32 aal5VccCrcErrors; /*!< counter of ingress packets with CRC error */
|
||||||
|
+ __u32 aal5VccSarTimeOuts; /*!< counter of ingress packets with Re-assemble timeout */ //no timer support yet
|
||||||
|
+ __u32 aal5VccOverSizedSDUs; /*!< counter of oversized ingress packets */
|
||||||
|
+} atm_aal5_vcc_t;
|
||||||
|
+
|
||||||
|
+/*!
|
||||||
|
+ \struct atm_aal5_vcc_x_t
|
||||||
|
+ \brief Structure used for per PVC AAL5 Frame Level MIB Counters.
|
||||||
|
+
|
||||||
|
+ User application use this structure to call IOCTL command "PPE_ATM_MIB_VCC".
|
||||||
|
+ */
|
||||||
|
+typedef struct {
|
||||||
|
+ int vpi; /*!< VPI of the VCC to get MIB counters */
|
||||||
|
+ int vci; /*!< VCI of the VCC to get MIB counters */
|
||||||
|
+ atm_aal5_vcc_t mib_vcc; /*!< structure to get MIB counters */
|
||||||
|
+} atm_aal5_vcc_x_t;
|
||||||
|
+
|
||||||
|
+/*@}*/
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * ####################################
|
||||||
|
+ * IOCTL
|
||||||
|
+ * ####################################
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+/*!
|
||||||
|
+ \addtogroup IFX_ATM_IOCTL
|
||||||
|
+ */
|
||||||
|
+/*@{*/
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * ioctl Command
|
||||||
|
+ */
|
||||||
|
+/*!
|
||||||
|
+ \brief ATM IOCTL Magic Number
|
||||||
|
+ */
|
||||||
|
+#define PPE_ATM_IOC_MAGIC 'o'
|
||||||
|
+/*!
|
||||||
|
+ \brief ATM IOCTL Command - Get Cell Level MIB Counters
|
||||||
|
+
|
||||||
|
+ This command is obsolete. User can get cell level MIB from DSL API.
|
||||||
|
+ This command uses structure "atm_cell_ifEntry_t" as parameter for output of MIB counters.
|
||||||
|
+ */
|
||||||
|
+#define PPE_ATM_MIB_CELL _IOW(PPE_ATM_IOC_MAGIC, 0, atm_cell_ifEntry_t)
|
||||||
|
+/*!
|
||||||
|
+ \brief ATM IOCTL Command - Get AAL5 Level MIB Counters
|
||||||
|
+
|
||||||
|
+ Get AAL5 packet counters.
|
||||||
|
+ This command uses structure "atm_aal5_ifEntry_t" as parameter for output of MIB counters.
|
||||||
|
+ */
|
||||||
|
+#define PPE_ATM_MIB_AAL5 _IOW(PPE_ATM_IOC_MAGIC, 1, atm_aal5_ifEntry_t)
|
||||||
|
+/*!
|
||||||
|
+ \brief ATM IOCTL Command - Get Per PVC MIB Counters
|
||||||
|
+
|
||||||
|
+ Get AAL5 packet counters for each PVC.
|
||||||
|
+ This command uses structure "atm_aal5_vcc_x_t" as parameter for input of VPI/VCI information and output of MIB counters.
|
||||||
|
+ */
|
||||||
|
+#define PPE_ATM_MIB_VCC _IOWR(PPE_ATM_IOC_MAGIC, 2, atm_aal5_vcc_x_t)
|
||||||
|
+/*!
|
||||||
|
+ \brief Total Number of ATM IOCTL Commands
|
||||||
|
+ */
|
||||||
|
+#define PPE_ATM_IOC_MAXNR 3
|
||||||
|
+
|
||||||
|
+/*@}*/
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * ####################################
|
||||||
|
+ * API
|
||||||
|
+ * ####################################
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#ifdef __KERNEL__
|
||||||
|
+struct port_cell_info {
|
||||||
|
+ unsigned int port_num;
|
||||||
|
+ unsigned int tx_link_rate[2];
|
||||||
|
+};
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+#endif // IFX_ATM_H
|
||||||
|
+
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/arch/mips/include/asm/mach-lantiq/lantiq_ptm.h
|
||||||
|
@@ -0,0 +1,203 @@
|
||||||
|
+/******************************************************************************
|
||||||
|
+**
|
||||||
|
+** FILE NAME : ifx_ptm.h
|
||||||
|
+** PROJECT : UEIP
|
||||||
|
+** MODULES : PTM
|
||||||
|
+**
|
||||||
|
+** DATE : 17 Jun 2009
|
||||||
|
+** AUTHOR : Xu Liang
|
||||||
|
+** DESCRIPTION : Global PTM driver header file
|
||||||
|
+** COPYRIGHT : Copyright (c) 2006
|
||||||
|
+** Infineon Technologies AG
|
||||||
|
+** Am Campeon 1-12, 85579 Neubiberg, Germany
|
||||||
|
+**
|
||||||
|
+** This program is free software; you can redistribute it and/or modify
|
||||||
|
+** it under the terms of the GNU General Public License as published by
|
||||||
|
+** the Free Software Foundation; either version 2 of the License, or
|
||||||
|
+** (at your option) any later version.
|
||||||
|
+**
|
||||||
|
+** HISTORY
|
||||||
|
+** $Date $Author $Comment
|
||||||
|
+** 07 JUL 2009 Xu Liang Init Version
|
||||||
|
+*******************************************************************************/
|
||||||
|
+
|
||||||
|
+#ifndef IFX_PTM_H
|
||||||
|
+#define IFX_PTM_H
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+/*!
|
||||||
|
+ \defgroup IFX_PTM UEIP Project - PTM driver module
|
||||||
|
+ \brief UEIP Project - PTM driver module, support Danube, Amazon-SE, AR9, VR9.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+/*!
|
||||||
|
+ \defgroup IFX_PTM_IOCTL IOCTL Commands
|
||||||
|
+ \ingroup IFX_PTM
|
||||||
|
+ \brief IOCTL Commands used by user application.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+/*!
|
||||||
|
+ \defgroup IFX_PTM_STRUCT Structures
|
||||||
|
+ \ingroup IFX_PTM
|
||||||
|
+ \brief Structures used by user application.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+/*!
|
||||||
|
+ \file ifx_ptm.h
|
||||||
|
+ \ingroup IFX_PTM
|
||||||
|
+ \brief PTM driver header file
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * ####################################
|
||||||
|
+ * Definition
|
||||||
|
+ * ####################################
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * ####################################
|
||||||
|
+ * IOCTL
|
||||||
|
+ * ####################################
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+/*!
|
||||||
|
+ \addtogroup IFX_PTM_IOCTL
|
||||||
|
+ */
|
||||||
|
+/*@{*/
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * ioctl Command
|
||||||
|
+ */
|
||||||
|
+/*!
|
||||||
|
+ \brief PTM IOCTL Command - Get codeword MIB counters.
|
||||||
|
+
|
||||||
|
+ This command uses structure "PTM_CW_IF_ENTRY_T" to get codeword level MIB counters.
|
||||||
|
+ */
|
||||||
|
+#define IFX_PTM_MIB_CW_GET SIOCDEVPRIVATE + 1
|
||||||
|
+/*!
|
||||||
|
+ \brief PTM IOCTL Command - Get packet MIB counters.
|
||||||
|
+
|
||||||
|
+ This command uses structure "PTM_FRAME_MIB_T" to get packet level MIB counters.
|
||||||
|
+ */
|
||||||
|
+#define IFX_PTM_MIB_FRAME_GET SIOCDEVPRIVATE + 2
|
||||||
|
+/*!
|
||||||
|
+ \brief PTM IOCTL Command - Get firmware configuration (CRC).
|
||||||
|
+
|
||||||
|
+ This command uses structure "IFX_PTM_CFG_T" to get firmware configuration (CRC).
|
||||||
|
+ */
|
||||||
|
+#define IFX_PTM_CFG_GET SIOCDEVPRIVATE + 3
|
||||||
|
+/*!
|
||||||
|
+ \brief PTM IOCTL Command - Set firmware configuration (CRC).
|
||||||
|
+
|
||||||
|
+ This command uses structure "IFX_PTM_CFG_T" to set firmware configuration (CRC).
|
||||||
|
+ */
|
||||||
|
+#define IFX_PTM_CFG_SET SIOCDEVPRIVATE + 4
|
||||||
|
+/*!
|
||||||
|
+ \brief PTM IOCTL Command - Program priority value to TX queue mapping.
|
||||||
|
+
|
||||||
|
+ This command uses structure "IFX_PTM_PRIO_Q_MAP_T" to program priority value to TX queue mapping.
|
||||||
|
+ */
|
||||||
|
+#define IFX_PTM_MAP_PKT_PRIO_TO_Q SIOCDEVPRIVATE + 14
|
||||||
|
+
|
||||||
|
+/*@}*/
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+/*!
|
||||||
|
+ \addtogroup IFX_PTM_STRUCT
|
||||||
|
+ */
|
||||||
|
+/*@{*/
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * ioctl Data Type
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+/*!
|
||||||
|
+ \typedef PTM_CW_IF_ENTRY_T
|
||||||
|
+ \brief Wrapping of structure "ptm_cw_ifEntry_t".
|
||||||
|
+ */
|
||||||
|
+/*!
|
||||||
|
+ \struct ptm_cw_ifEntry_t
|
||||||
|
+ \brief Structure used for CodeWord level MIB counters.
|
||||||
|
+ */
|
||||||
|
+typedef struct ptm_cw_ifEntry_t {
|
||||||
|
+ uint32_t ifRxNoIdleCodewords; /*!< output, number of ingress user codeword */
|
||||||
|
+ uint32_t ifRxIdleCodewords; /*!< output, number of ingress idle codeword */
|
||||||
|
+ uint32_t ifRxCodingViolation; /*!< output, number of error ingress codeword */
|
||||||
|
+ uint32_t ifTxNoIdleCodewords; /*!< output, number of egress user codeword */
|
||||||
|
+ uint32_t ifTxIdleCodewords; /*!< output, number of egress idle codeword */
|
||||||
|
+} PTM_CW_IF_ENTRY_T;
|
||||||
|
+
|
||||||
|
+/*!
|
||||||
|
+ \typedef PTM_FRAME_MIB_T
|
||||||
|
+ \brief Wrapping of structure "ptm_frame_mib_t".
|
||||||
|
+ */
|
||||||
|
+/*!
|
||||||
|
+ \struct ptm_frame_mib_t
|
||||||
|
+ \brief Structure used for packet level MIB counters.
|
||||||
|
+ */
|
||||||
|
+typedef struct ptm_frame_mib_t {
|
||||||
|
+ uint32_t RxCorrect; /*!< output, number of ingress packet */
|
||||||
|
+ uint32_t TC_CrcError; /*!< output, number of egress packet with CRC error */
|
||||||
|
+ uint32_t RxDropped; /*!< output, number of dropped ingress packet */
|
||||||
|
+ uint32_t TxSend; /*!< output, number of egress packet */
|
||||||
|
+} PTM_FRAME_MIB_T;
|
||||||
|
+
|
||||||
|
+/*!
|
||||||
|
+ \typedef IFX_PTM_CFG_T
|
||||||
|
+ \brief Wrapping of structure "ptm_cfg_t".
|
||||||
|
+ */
|
||||||
|
+/*!
|
||||||
|
+ \struct ptm_cfg_t
|
||||||
|
+ \brief Structure used for ETH/TC CRC configuration.
|
||||||
|
+ */
|
||||||
|
+typedef struct ptm_cfg_t {
|
||||||
|
+ uint32_t RxEthCrcPresent; /*!< input/output, ingress packet has ETH CRC */
|
||||||
|
+ uint32_t RxEthCrcCheck; /*!< input/output, check ETH CRC of ingress packet */
|
||||||
|
+ uint32_t RxTcCrcCheck; /*!< input/output, check TC CRC of ingress codeword */
|
||||||
|
+ uint32_t RxTcCrcLen; /*!< input/output, length of TC CRC of ingress codeword */
|
||||||
|
+ uint32_t TxEthCrcGen; /*!< input/output, generate ETH CRC for egress packet */
|
||||||
|
+ uint32_t TxTcCrcGen; /*!< input/output, generate TC CRC for egress codeword */
|
||||||
|
+ uint32_t TxTcCrcLen; /*!< input/output, length of TC CRC of egress codeword */
|
||||||
|
+} IFX_PTM_CFG_T;
|
||||||
|
+
|
||||||
|
+/*!
|
||||||
|
+ \typedef IFX_PTM_PRIO_Q_MAP_T
|
||||||
|
+ \brief Wrapping of structure "ppe_prio_q_map".
|
||||||
|
+ */
|
||||||
|
+/*!
|
||||||
|
+ \struct ppe_prio_q_map
|
||||||
|
+ \brief Structure used for Priority Value to TX Queue mapping.
|
||||||
|
+ */
|
||||||
|
+typedef struct ppe_prio_q_map {
|
||||||
|
+ int pkt_prio;
|
||||||
|
+ int qid;
|
||||||
|
+ int vpi; // ignored in eth interface
|
||||||
|
+ int vci; // ignored in eth interface
|
||||||
|
+} IFX_PTM_PRIO_Q_MAP_T;
|
||||||
|
+
|
||||||
|
+/*@}*/
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * ####################################
|
||||||
|
+ * API
|
||||||
|
+ * ####################################
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#ifdef __KERNEL__
|
||||||
|
+struct port_cell_info {
|
||||||
|
+ unsigned int port_num;
|
||||||
|
+ unsigned int tx_link_rate[2];
|
||||||
|
+};
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+#endif // IFX_PTM_H
|
||||||
|
+
|
||||||
|
--- a/arch/mips/lantiq/irq.c
|
||||||
|
+++ b/arch/mips/lantiq/irq.c
|
||||||
|
@@ -14,6 +14,7 @@
|
||||||
|
#include <linux/of_platform.h>
|
||||||
|
#include <linux/of_address.h>
|
||||||
|
#include <linux/of_irq.h>
|
||||||
|
+#include <linux/module.h>
|
||||||
|
|
||||||
|
#include <asm/bootinfo.h>
|
||||||
|
#include <asm/irq_cpu.h>
|
||||||
|
@@ -99,6 +100,7 @@ void ltq_mask_and_ack_irq(struct irq_dat
|
||||||
|
ltq_icu_w32(im, ltq_icu_r32(im, ier) & ~BIT(offset), ier);
|
||||||
|
ltq_icu_w32(im, BIT(offset), isr);
|
||||||
|
}
|
||||||
|
+EXPORT_SYMBOL(ltq_mask_and_ack_irq);
|
||||||
|
|
||||||
|
static void ltq_ack_irq(struct irq_data *d)
|
||||||
|
{
|
||||||
|
--- a/arch/mips/mm/cache.c
|
||||||
|
+++ b/arch/mips/mm/cache.c
|
||||||
|
@@ -59,6 +59,8 @@ void (*_dma_cache_wback)(unsigned long s
|
||||||
|
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 || CONFIG_DMA_MAYBE_COHERENT */
|
||||||
|
|
||||||
|
--- a/include/uapi/linux/atm.h
|
||||||
|
+++ b/include/uapi/linux/atm.h
|
||||||
|
@@ -130,8 +130,14 @@
|
||||||
|
#define ATM_ABR 4
|
||||||
|
#define ATM_ANYCLASS 5 /* compatible with everything */
|
||||||
|
|
||||||
|
+#define ATM_VBR_NRT ATM_VBR
|
||||||
|
+#define ATM_VBR_RT 6
|
||||||
|
+#define ATM_UBR_PLUS 7
|
||||||
|
+#define ATM_GFR 8
|
||||||
|
+
|
||||||
|
#define ATM_MAX_PCR -1 /* maximum available PCR */
|
||||||
|
|
||||||
|
+
|
||||||
|
struct atm_trafprm {
|
||||||
|
unsigned char traffic_class; /* traffic class (ATM_UBR, ...) */
|
||||||
|
int max_pcr; /* maximum PCR in cells per second */
|
||||||
|
--- a/net/atm/common.c
|
||||||
|
+++ b/net/atm/common.c
|
||||||
|
@@ -62,11 +62,17 @@ static void vcc_remove_socket(struct soc
|
||||||
|
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);
|
||||||
|
--- a/net/atm/proc.c
|
||||||
|
+++ b/net/atm/proc.c
|
||||||
|
@@ -154,7 +154,7 @@ static void *vcc_seq_next(struct seq_fil
|
||||||
|
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 */
|
|
@ -0,0 +1,90 @@
|
||||||
|
From 223f1c46e109a8420765aee099a5d1dc4ab7ee98 Mon Sep 17 00:00:00 2001
|
||||||
|
From: John Crispin <blogic@openwrt.org>
|
||||||
|
Date: Tue, 3 Sep 2013 13:18:12 +0200
|
||||||
|
Subject: [PATCH 05/36] MIPS: lantiq: add reset-controller api support
|
||||||
|
|
||||||
|
Add a reset-controller binding for the reset registers found on the lantiq
|
||||||
|
SoC.
|
||||||
|
|
||||||
|
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||||
|
---
|
||||||
|
arch/mips/lantiq/xway/reset.c | 61 +++++++++++++++++++++++++++++++++++++++++
|
||||||
|
1 file changed, 61 insertions(+)
|
||||||
|
|
||||||
|
--- a/arch/mips/lantiq/xway/reset.c
|
||||||
|
+++ b/arch/mips/lantiq/xway/reset.c
|
||||||
|
@@ -14,6 +14,7 @@
|
||||||
|
#include <linux/delay.h>
|
||||||
|
#include <linux/of_address.h>
|
||||||
|
#include <linux/of_platform.h>
|
||||||
|
+#include <linux/reset-controller.h>
|
||||||
|
|
||||||
|
#include <asm/reboot.h>
|
||||||
|
|
||||||
|
@@ -113,6 +114,66 @@ void ltq_reset_once(unsigned int module,
|
||||||
|
ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) & ~module, RCU_RST_REQ);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int ltq_assert_device(struct reset_controller_dev *rcdev,
|
||||||
|
+ unsigned long id)
|
||||||
|
+{
|
||||||
|
+ u32 val;
|
||||||
|
+
|
||||||
|
+ if (id < 8)
|
||||||
|
+ return -1;
|
||||||
|
+
|
||||||
|
+ val = ltq_rcu_r32(RCU_RST_REQ);
|
||||||
|
+ val |= BIT(id);
|
||||||
|
+ ltq_rcu_w32(val, RCU_RST_REQ);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int ltq_deassert_device(struct reset_controller_dev *rcdev,
|
||||||
|
+ unsigned long id)
|
||||||
|
+{
|
||||||
|
+ u32 val;
|
||||||
|
+
|
||||||
|
+ if (id < 8)
|
||||||
|
+ return -1;
|
||||||
|
+
|
||||||
|
+ val = ltq_rcu_r32(RCU_RST_REQ);
|
||||||
|
+ val &= ~BIT(id);
|
||||||
|
+ ltq_rcu_w32(val, RCU_RST_REQ);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int ltq_reset_device(struct reset_controller_dev *rcdev,
|
||||||
|
+ unsigned long id)
|
||||||
|
+{
|
||||||
|
+ ltq_assert_device(rcdev, id);
|
||||||
|
+ return ltq_deassert_device(rcdev, id);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static struct reset_control_ops reset_ops = {
|
||||||
|
+ .reset = ltq_reset_device,
|
||||||
|
+ .assert = ltq_assert_device,
|
||||||
|
+ .deassert = ltq_deassert_device,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct reset_controller_dev reset_dev = {
|
||||||
|
+ .ops = &reset_ops,
|
||||||
|
+ .owner = THIS_MODULE,
|
||||||
|
+ .nr_resets = 32,
|
||||||
|
+ .of_reset_n_cells = 1,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+void ltq_rst_init(void)
|
||||||
|
+{
|
||||||
|
+ reset_dev.of_node = of_find_compatible_node(NULL, NULL,
|
||||||
|
+ "lantiq,xway-reset");
|
||||||
|
+ if (!reset_dev.of_node)
|
||||||
|
+ pr_err("Failed to find reset controller node");
|
||||||
|
+ else
|
||||||
|
+ reset_controller_register(&reset_dev);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void ltq_machine_restart(char *command)
|
||||||
|
{
|
||||||
|
local_irq_disable();
|
|
@ -0,0 +1,29 @@
|
||||||
|
From f81979f4b297693ac70616feaa4a79bdcb11db35 Mon Sep 17 00:00:00 2001
|
||||||
|
From: John Crispin <blogic@openwrt.org>
|
||||||
|
Date: Thu, 7 Aug 2014 18:55:57 +0200
|
||||||
|
Subject: [PATCH 06/36] MIPS: lantiq: reboot gphy on restart
|
||||||
|
|
||||||
|
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||||
|
---
|
||||||
|
arch/mips/lantiq/xway/reset.c | 9 ++++++++-
|
||||||
|
1 file changed, 8 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
--- a/arch/mips/lantiq/xway/reset.c
|
||||||
|
+++ b/arch/mips/lantiq/xway/reset.c
|
||||||
|
@@ -176,8 +176,15 @@ void ltq_rst_init(void)
|
||||||
|
|
||||||
|
static void ltq_machine_restart(char *command)
|
||||||
|
{
|
||||||
|
+ u32 val = ltq_rcu_r32(RCU_RST_REQ);
|
||||||
|
+
|
||||||
|
+ if (of_device_is_compatible(ltq_rcu_np, "lantiq,rcu-xrx200"))
|
||||||
|
+ val |= RCU_RD_GPHY1_XRX200 | RCU_RD_GPHY0_XRX200;
|
||||||
|
+
|
||||||
|
+ val |= RCU_RD_SRST;
|
||||||
|
+
|
||||||
|
local_irq_disable();
|
||||||
|
- ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) | RCU_RD_SRST, RCU_RST_REQ);
|
||||||
|
+ ltq_rcu_w32(val, RCU_RST_REQ);
|
||||||
|
unreachable();
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,111 @@
|
||||||
|
From d27ec8bb97db0f60d81ab255d51ac4e967362067 Mon Sep 17 00:00:00 2001
|
||||||
|
From: John Crispin <blogic@openwrt.org>
|
||||||
|
Date: Thu, 7 Aug 2014 18:34:19 +0200
|
||||||
|
Subject: [PATCH 07/36] MIPS: lantiq: add basic tffs driver
|
||||||
|
|
||||||
|
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||||
|
---
|
||||||
|
arch/mips/lantiq/xway/Makefile | 2 +-
|
||||||
|
arch/mips/lantiq/xway/tffs.c | 87 ++++++++++++++++++++++++++++++++++++++++
|
||||||
|
2 files changed, 88 insertions(+), 1 deletion(-)
|
||||||
|
create mode 100644 arch/mips/lantiq/xway/tffs.c
|
||||||
|
|
||||||
|
--- a/arch/mips/lantiq/xway/Makefile
|
||||||
|
+++ b/arch/mips/lantiq/xway/Makefile
|
||||||
|
@@ -1,5 +1,5 @@
|
||||||
|
obj-y := prom.o sysctrl.o clk.o reset.o dma.o gptu.o dcdc.o
|
||||||
|
|
||||||
|
-obj-y += vmmc.o
|
||||||
|
+obj-y += vmmc.o tffs.o
|
||||||
|
|
||||||
|
obj-$(CONFIG_XRX200_PHY_FW) += xrx200_phy_fw.o
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/arch/mips/lantiq/xway/tffs.c
|
||||||
|
@@ -0,0 +1,87 @@
|
||||||
|
+#include <linux/module.h>
|
||||||
|
+#include <linux/mtd/mtd.h>
|
||||||
|
+#include <linux/errno.h>
|
||||||
|
+#include <linux/slab.h>
|
||||||
|
+
|
||||||
|
+struct tffs_entry {
|
||||||
|
+ uint16_t id;
|
||||||
|
+ uint16_t len;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct tffs_id {
|
||||||
|
+ uint32_t id;
|
||||||
|
+ char *name;
|
||||||
|
+ unsigned char *val;
|
||||||
|
+ uint32_t offset;
|
||||||
|
+ uint32_t len;
|
||||||
|
+} ids[] = {
|
||||||
|
+ { 0x01A9, "annex" },
|
||||||
|
+ { 0x0188, "maca" },
|
||||||
|
+ { 0x0189, "macb" },
|
||||||
|
+ { 0x018a, "macwlan" },
|
||||||
|
+ { 0x0195, "macwlan2" },
|
||||||
|
+ { 0x018b, "macdsl" },
|
||||||
|
+ { 0x01C2, "webgui_pass" },
|
||||||
|
+ { 0x01AB, "wlan_key" },
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct mtd_info *tffs1, *tffs2;
|
||||||
|
+
|
||||||
|
+static struct tffs_id* tffs_find_id(int id)
|
||||||
|
+{
|
||||||
|
+ int i;
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < ARRAY_SIZE(ids); i++)
|
||||||
|
+ if (id == ids[i].id)
|
||||||
|
+ return &ids[i];
|
||||||
|
+
|
||||||
|
+ return NULL;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void tffs_index(void)
|
||||||
|
+{
|
||||||
|
+ struct tffs_entry *E = NULL;
|
||||||
|
+ struct tffs_entry entry;
|
||||||
|
+ int ret, retlen;
|
||||||
|
+
|
||||||
|
+ while ((unsigned int) E + sizeof(struct tffs_entry) < tffs2->size) {
|
||||||
|
+ struct tffs_id *id;
|
||||||
|
+ int len;
|
||||||
|
+
|
||||||
|
+ ret = mtd_read(tffs2, (unsigned int) E, sizeof(struct tffs_entry), &retlen, (unsigned char *)&entry);
|
||||||
|
+ if (ret)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ if (entry.id == 0xffff)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ id = tffs_find_id(entry.id);
|
||||||
|
+ if (id) {
|
||||||
|
+ id->offset = (uint32_t) E;
|
||||||
|
+ id->len = entry.len;
|
||||||
|
+ id->val = kzalloc(entry.len + 1, GFP_KERNEL);
|
||||||
|
+ mtd_read(tffs2, ((unsigned int) E) + sizeof(struct tffs_entry), entry.len, &retlen, id->val);
|
||||||
|
+
|
||||||
|
+ }
|
||||||
|
+ //printk(KERN_INFO "found entry at 0x%08X-> [<0x%x> %u bytes]\n", (uint32_t) E, entry.id, entry.len);
|
||||||
|
+ if (id && id->name)
|
||||||
|
+ printk(KERN_INFO "found entry name -> %s=%s\n", id->name, id->val);
|
||||||
|
+
|
||||||
|
+ len = (entry.len + 3) & ~0x03;
|
||||||
|
+ E = (struct tffs_entry *)(((unsigned int)E) + sizeof(struct tffs_entry) + len);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int __init tffs_init(void)
|
||||||
|
+{
|
||||||
|
+ tffs1 = get_mtd_device_nm("tffs (1)");
|
||||||
|
+ tffs2 = get_mtd_device_nm("tffs (2)");
|
||||||
|
+ if (IS_ERR(tffs1) || IS_ERR(tffs2))
|
||||||
|
+ return -1;
|
||||||
|
+
|
||||||
|
+ tffs_index();
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+late_initcall(tffs_init);
|
||||||
|
+
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,21 @@
|
||||||
|
From ed348924cd59ef0c8a4bc4e015e2b7e581a00fa8 Mon Sep 17 00:00:00 2001
|
||||||
|
From: John Crispin <blogic@openwrt.org>
|
||||||
|
Date: Tue, 12 Aug 2014 21:40:41 +0200
|
||||||
|
Subject: [PATCH 09/36] MIPS: lantiq: command line work around
|
||||||
|
|
||||||
|
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||||
|
---
|
||||||
|
arch/mips/lantiq/prom.c | 2 ++
|
||||||
|
1 file changed, 2 insertions(+)
|
||||||
|
|
||||||
|
--- a/arch/mips/lantiq/prom.c
|
||||||
|
+++ b/arch/mips/lantiq/prom.c
|
||||||
|
@@ -74,6 +74,8 @@ void __init plat_mem_setup(void)
|
||||||
|
* parsed resulting in our memory appearing
|
||||||
|
*/
|
||||||
|
__dt_setup_arch(&__image_dtb);
|
||||||
|
+
|
||||||
|
+ strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void __init device_tree_init(void)
|
|
@ -0,0 +1,39 @@
|
||||||
|
From 6804142b47f2634b0657e4dfcec7a34e982b6ddb Mon Sep 17 00:00:00 2001
|
||||||
|
From: John Crispin <blogic@openwrt.org>
|
||||||
|
Date: Wed, 10 Sep 2014 22:29:21 +0200
|
||||||
|
Subject: [PATCH 10/36] MIPS: lantiq: export soc type
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
|
||||||
|
---
|
||||||
|
arch/mips/include/asm/mach-lantiq/lantiq.h | 2 ++
|
||||||
|
arch/mips/lantiq/prom.c | 5 +++++
|
||||||
|
2 files changed, 7 insertions(+)
|
||||||
|
|
||||||
|
--- a/arch/mips/include/asm/mach-lantiq/lantiq.h
|
||||||
|
+++ b/arch/mips/include/asm/mach-lantiq/lantiq.h
|
||||||
|
@@ -48,6 +48,8 @@ extern struct clk *clk_get_ppe(void);
|
||||||
|
extern unsigned char ltq_boot_select(void);
|
||||||
|
/* find out what caused the last cpu reset */
|
||||||
|
extern int ltq_reset_cause(void);
|
||||||
|
+/* find out the soc type */
|
||||||
|
+extern int ltq_soc_type(void);
|
||||||
|
|
||||||
|
#define IOPORT_RESOURCE_START 0x10000000
|
||||||
|
#define IOPORT_RESOURCE_END 0xffffffff
|
||||||
|
--- a/arch/mips/lantiq/prom.c
|
||||||
|
+++ b/arch/mips/lantiq/prom.c
|
||||||
|
@@ -36,6 +36,11 @@ const char *get_system_type(void)
|
||||||
|
return soc_info.sys_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
+int ltq_soc_type(void)
|
||||||
|
+{
|
||||||
|
+ return soc_info.type;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void prom_free_prom_memory(void)
|
||||||
|
{
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
From 85f0df34dee96048515ef1e01d88524bd579f8e0 Mon Sep 17 00:00:00 2001
|
||||||
|
From: John Crispin <blogic@openwrt.org>
|
||||||
|
Date: Wed, 10 Sep 2014 22:39:19 +0200
|
||||||
|
Subject: [PATCH 11/36] lantiq: add support for xrx200 firmware depending on
|
||||||
|
soc type
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
|
||||||
|
---
|
||||||
|
arch/mips/lantiq/xway/xrx200_phy_fw.c | 18 +++++++++++++++++-
|
||||||
|
1 file changed, 17 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
--- a/arch/mips/lantiq/xway/xrx200_phy_fw.c
|
||||||
|
+++ b/arch/mips/lantiq/xway/xrx200_phy_fw.c
|
||||||
|
@@ -24,7 +24,23 @@ static dma_addr_t xway_gphy_load(struct
|
||||||
|
void *fw_addr;
|
||||||
|
size_t size;
|
||||||
|
|
||||||
|
- if (of_property_read_string(pdev->dev.of_node, "firmware", &fw_name)) {
|
||||||
|
+ if (of_get_property(pdev->dev.of_node, "firmware1", NULL) || of_get_property(pdev->dev.of_node, "firmware2", NULL)) {
|
||||||
|
+ switch(ltq_soc_type()) {
|
||||||
|
+ case SOC_TYPE_VR9:
|
||||||
|
+ if (of_property_read_string(pdev->dev.of_node, "firmware1", &fw_name)) {
|
||||||
|
+ dev_err(&pdev->dev, "failed to load firmware filename\n");
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+ break;
|
||||||
|
+ case SOC_TYPE_VR9_2:
|
||||||
|
+ if (of_property_read_string(pdev->dev.of_node, "firmware2", &fw_name)) {
|
||||||
|
+ dev_err(&pdev->dev, "failed to load firmware filename\n");
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ else if (of_property_read_string(pdev->dev.of_node, "firmware", &fw_name)) {
|
||||||
|
dev_err(&pdev->dev, "failed to load firmware filename\n");
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,79 @@
|
||||||
|
From 25494c55a4007a1409f53ddbafd661636e47ea34 Mon Sep 17 00:00:00 2001
|
||||||
|
From: John Crispin <blogic@openwrt.org>
|
||||||
|
Date: Fri, 9 Aug 2013 20:38:15 +0200
|
||||||
|
Subject: [PATCH 12/36] pinctrl/lantiq: fix up pinmux
|
||||||
|
|
||||||
|
We found out how to set the gphy led pinmuxing.
|
||||||
|
|
||||||
|
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||||
|
---
|
||||||
|
drivers/pinctrl/pinctrl-xway.c | 28 ++++++++++++++++++++++++++--
|
||||||
|
1 file changed, 26 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/pinctrl/pinctrl-xway.c
|
||||||
|
+++ b/drivers/pinctrl/pinctrl-xway.c
|
||||||
|
@@ -609,10 +609,9 @@ static struct pinctrl_desc xway_pctrl_de
|
||||||
|
.confops = &xway_pinconf_ops,
|
||||||
|
};
|
||||||
|
|
||||||
|
-static inline int xway_mux_apply(struct pinctrl_dev *pctrldev,
|
||||||
|
+static int mux_apply(struct ltq_pinmux_info *info,
|
||||||
|
int pin, int mux)
|
||||||
|
{
|
||||||
|
- struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
|
||||||
|
int port = PORT(pin);
|
||||||
|
u32 alt1_reg = GPIO_ALT1(pin);
|
||||||
|
|
||||||
|
@@ -632,6 +631,14 @@ static inline int xway_mux_apply(struct
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static inline int xway_mux_apply(struct pinctrl_dev *pctrldev,
|
||||||
|
+ int pin, int mux)
|
||||||
|
+{
|
||||||
|
+ struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
|
||||||
|
+
|
||||||
|
+ return mux_apply(info, pin, mux);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static const struct ltq_cfg_param xway_cfg_params[] = {
|
||||||
|
{"lantiq,pull", LTQ_PINCONF_PARAM_PULL},
|
||||||
|
{"lantiq,open-drain", LTQ_PINCONF_PARAM_OPEN_DRAIN},
|
||||||
|
@@ -676,6 +683,10 @@ static int xway_gpio_dir_out(struct gpio
|
||||||
|
{
|
||||||
|
struct ltq_pinmux_info *info = dev_get_drvdata(chip->dev);
|
||||||
|
|
||||||
|
+ if (PORT(pin) == PORT3)
|
||||||
|
+ gpio_setbit(info->membase[0], GPIO3_OD, PORT_PIN(pin));
|
||||||
|
+ else
|
||||||
|
+ gpio_setbit(info->membase[0], GPIO_OD(pin), PORT_PIN(pin));
|
||||||
|
gpio_setbit(info->membase[0], GPIO_DIR(pin), PORT_PIN(pin));
|
||||||
|
xway_gpio_set(chip, pin, val);
|
||||||
|
|
||||||
|
@@ -696,6 +707,18 @@ static void xway_gpio_free(struct gpio_c
|
||||||
|
pinctrl_free_gpio(gpio);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int xway_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
|
||||||
|
+{
|
||||||
|
+ struct ltq_pinmux_info *info = dev_get_drvdata(chip->dev);
|
||||||
|
+ int i;
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < info->num_exin; i++)
|
||||||
|
+ if (info->exin[i] == offset)
|
||||||
|
+ return ltq_eiu_get_irq(i);
|
||||||
|
+
|
||||||
|
+ return -1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static struct gpio_chip xway_chip = {
|
||||||
|
.label = "gpio-xway",
|
||||||
|
.direction_input = xway_gpio_dir_in,
|
||||||
|
@@ -704,6 +727,7 @@ static struct gpio_chip xway_chip = {
|
||||||
|
.set = xway_gpio_set,
|
||||||
|
.request = xway_gpio_req,
|
||||||
|
.free = xway_gpio_free,
|
||||||
|
+ .to_irq = xway_gpio_to_irq,
|
||||||
|
.base = -1,
|
||||||
|
};
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
From 8e34da603f442624bb70e887d8f42064bb924224 Mon Sep 17 00:00:00 2001
|
||||||
|
From: John Crispin <blogic@openwrt.org>
|
||||||
|
Date: Sun, 28 Jul 2013 18:03:54 +0200
|
||||||
|
Subject: [PATCH 13/36] MTD: lantiq: xway: fix invalid operator
|
||||||
|
|
||||||
|
xway_read_byte should use a logic or and not an add operator when working out
|
||||||
|
the nand address.
|
||||||
|
|
||||||
|
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||||
|
---
|
||||||
|
drivers/mtd/nand/xway_nand.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
--- a/drivers/mtd/nand/xway_nand.c
|
||||||
|
+++ b/drivers/mtd/nand/xway_nand.c
|
||||||
|
@@ -124,7 +124,7 @@ static unsigned char xway_read_byte(stru
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&ebu_lock, flags);
|
||||||
|
- ret = ltq_r8((void __iomem *)(nandaddr + NAND_READ_DATA));
|
||||||
|
+ ret = ltq_r8((void __iomem *)(nandaddr | NAND_READ_DATA));
|
||||||
|
spin_unlock_irqrestore(&ebu_lock, flags);
|
||||||
|
|
||||||
|
return ret;
|
|
@ -0,0 +1,44 @@
|
||||||
|
From b454cefd675fc1bd3d8c690c1bd1d8f4678e9922 Mon Sep 17 00:00:00 2001
|
||||||
|
From: John Crispin <blogic@openwrt.org>
|
||||||
|
Date: Sun, 28 Jul 2013 18:06:39 +0200
|
||||||
|
Subject: [PATCH 14/36] MTD: lantiq: xway: the latched command should be
|
||||||
|
persistent
|
||||||
|
|
||||||
|
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||||
|
---
|
||||||
|
drivers/mtd/nand/xway_nand.c | 12 ++++++------
|
||||||
|
1 file changed, 6 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/mtd/nand/xway_nand.c
|
||||||
|
+++ b/drivers/mtd/nand/xway_nand.c
|
||||||
|
@@ -54,6 +54,8 @@
|
||||||
|
#define NAND_CON_CSMUX (1 << 1)
|
||||||
|
#define NAND_CON_NANDM 1
|
||||||
|
|
||||||
|
+static u32 xway_latchcmd;
|
||||||
|
+
|
||||||
|
static void xway_reset_chip(struct nand_chip *chip)
|
||||||
|
{
|
||||||
|
unsigned long nandaddr = (unsigned long) chip->IO_ADDR_W;
|
||||||
|
@@ -94,17 +96,15 @@ static void xway_cmd_ctrl(struct mtd_inf
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
if (ctrl & NAND_CTRL_CHANGE) {
|
||||||
|
- nandaddr &= ~(NAND_WRITE_CMD | NAND_WRITE_ADDR);
|
||||||
|
if (ctrl & NAND_CLE)
|
||||||
|
- nandaddr |= NAND_WRITE_CMD;
|
||||||
|
- else
|
||||||
|
- nandaddr |= NAND_WRITE_ADDR;
|
||||||
|
- this->IO_ADDR_W = (void __iomem *) nandaddr;
|
||||||
|
+ xway_latchcmd = NAND_WRITE_CMD;
|
||||||
|
+ else if (ctrl & NAND_ALE)
|
||||||
|
+ xway_latchcmd = NAND_WRITE_ADDR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cmd != NAND_CMD_NONE) {
|
||||||
|
spin_lock_irqsave(&ebu_lock, flags);
|
||||||
|
- writeb(cmd, this->IO_ADDR_W);
|
||||||
|
+ writeb(cmd, (void __iomem *) (nandaddr | xway_latchcmd));
|
||||||
|
while ((ltq_ebu_r32(EBU_NAND_WAIT) & NAND_WAIT_WR_C) == 0)
|
||||||
|
;
|
||||||
|
spin_unlock_irqrestore(&ebu_lock, flags);
|
|
@ -0,0 +1,41 @@
|
||||||
|
From 76e153079f02d26e3357302d2886a0c8aaaec64d Mon Sep 17 00:00:00 2001
|
||||||
|
From: John Crispin <blogic@openwrt.org>
|
||||||
|
Date: Sun, 28 Jul 2013 18:02:06 +0200
|
||||||
|
Subject: [PATCH 15/36] MTD: lantiq: xway: remove endless loop
|
||||||
|
|
||||||
|
The reset loop logic could run into a endless loop. Lets fix it as requested.
|
||||||
|
|
||||||
|
--> http://lists.infradead.org/pipermail/linux-mtd/2012-September/044240.html
|
||||||
|
|
||||||
|
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||||
|
---
|
||||||
|
drivers/mtd/nand/xway_nand.c | 10 ++++++++--
|
||||||
|
1 file changed, 8 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/mtd/nand/xway_nand.c
|
||||||
|
+++ b/drivers/mtd/nand/xway_nand.c
|
||||||
|
@@ -59,16 +59,22 @@ static u32 xway_latchcmd;
|
||||||
|
static void xway_reset_chip(struct nand_chip *chip)
|
||||||
|
{
|
||||||
|
unsigned long nandaddr = (unsigned long) chip->IO_ADDR_W;
|
||||||
|
+ unsigned long timeout;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
nandaddr &= ~NAND_WRITE_ADDR;
|
||||||
|
nandaddr |= NAND_WRITE_CMD;
|
||||||
|
|
||||||
|
/* finish with a reset */
|
||||||
|
+ timeout = jiffies + msecs_to_jiffies(20);
|
||||||
|
+
|
||||||
|
spin_lock_irqsave(&ebu_lock, flags);
|
||||||
|
writeb(NAND_WRITE_CMD_RESET, (void __iomem *) nandaddr);
|
||||||
|
- while ((ltq_ebu_r32(EBU_NAND_WAIT) & NAND_WAIT_WR_C) == 0)
|
||||||
|
- ;
|
||||||
|
+ do {
|
||||||
|
+ if ((ltq_ebu_r32(EBU_NAND_WAIT) & NAND_WAIT_WR_C) == 0)
|
||||||
|
+ break;
|
||||||
|
+ cond_resched();
|
||||||
|
+ } while (!time_after_eq(jiffies, timeout));
|
||||||
|
spin_unlock_irqrestore(&ebu_lock, flags);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
From 65df9d63eaee02c25e879b33dd42aceb78e57842 Mon Sep 17 00:00:00 2001
|
||||||
|
From: John Crispin <blogic@openwrt.org>
|
||||||
|
Date: Sun, 28 Jul 2013 17:59:51 +0200
|
||||||
|
Subject: [PATCH 16/36] MTD: lantiq: xway: add missing write_buf and read_buf
|
||||||
|
to nand driver
|
||||||
|
|
||||||
|
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||||
|
---
|
||||||
|
drivers/mtd/nand/xway_nand.c | 28 ++++++++++++++++++++++++++++
|
||||||
|
1 file changed, 28 insertions(+)
|
||||||
|
|
||||||
|
--- a/drivers/mtd/nand/xway_nand.c
|
||||||
|
+++ b/drivers/mtd/nand/xway_nand.c
|
||||||
|
@@ -136,6 +136,32 @@ static unsigned char xway_read_byte(stru
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void xway_read_buf(struct mtd_info *mtd, u_char *buf, int len)
|
||||||
|
+{
|
||||||
|
+ struct nand_chip *this = mtd->priv;
|
||||||
|
+ unsigned long nandaddr = (unsigned long) this->IO_ADDR_R;
|
||||||
|
+ unsigned long flags;
|
||||||
|
+ int i;
|
||||||
|
+
|
||||||
|
+ spin_lock_irqsave(&ebu_lock, flags);
|
||||||
|
+ for (i = 0; i < len; i++)
|
||||||
|
+ buf[i] = ltq_r8((void __iomem *)(nandaddr | NAND_READ_DATA));
|
||||||
|
+ spin_unlock_irqrestore(&ebu_lock, flags);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void xway_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
|
||||||
|
+{
|
||||||
|
+ struct nand_chip *this = mtd->priv;
|
||||||
|
+ unsigned long nandaddr = (unsigned long) this->IO_ADDR_W;
|
||||||
|
+ unsigned long flags;
|
||||||
|
+ int i;
|
||||||
|
+
|
||||||
|
+ spin_lock_irqsave(&ebu_lock, flags);
|
||||||
|
+ for (i = 0; i < len; i++)
|
||||||
|
+ ltq_w8(buf[i], (void __iomem *)(nandaddr | NAND_WRITE_DATA));
|
||||||
|
+ spin_unlock_irqrestore(&ebu_lock, flags);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int xway_nand_probe(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct nand_chip *this = platform_get_drvdata(pdev);
|
||||||
|
@@ -181,6 +207,8 @@ static struct platform_nand_data xway_na
|
||||||
|
.dev_ready = xway_dev_ready,
|
||||||
|
.select_chip = xway_select_chip,
|
||||||
|
.read_byte = xway_read_byte,
|
||||||
|
+ .read_buf = xway_read_buf,
|
||||||
|
+ .write_buf = xway_write_buf,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
|
@ -0,0 +1,89 @@
|
||||||
|
From aa705c1b0860da91f2ed1a4c0b57337e6de689e1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: John Crispin <blogic@openwrt.org>
|
||||||
|
Date: Thu, 7 Aug 2014 18:55:31 +0200
|
||||||
|
Subject: [PATCH 17/36] MTD: xway: fix nand locking
|
||||||
|
|
||||||
|
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||||
|
---
|
||||||
|
drivers/mtd/nand/xway_nand.c | 15 +++------------
|
||||||
|
1 file changed, 3 insertions(+), 12 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/mtd/nand/xway_nand.c
|
||||||
|
+++ b/drivers/mtd/nand/xway_nand.c
|
||||||
|
@@ -80,13 +80,16 @@ static void xway_reset_chip(struct nand_
|
||||||
|
|
||||||
|
static void xway_select_chip(struct mtd_info *mtd, int chip)
|
||||||
|
{
|
||||||
|
+ static unsigned long csflags;
|
||||||
|
|
||||||
|
switch (chip) {
|
||||||
|
case -1:
|
||||||
|
ltq_ebu_w32_mask(NAND_CON_CE, 0, EBU_NAND_CON);
|
||||||
|
ltq_ebu_w32_mask(NAND_CON_NANDM, 0, EBU_NAND_CON);
|
||||||
|
+ spin_unlock_irqrestore(&ebu_lock, csflags);
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
+ spin_lock_irqsave(&ebu_lock, csflags);
|
||||||
|
ltq_ebu_w32_mask(0, NAND_CON_NANDM, EBU_NAND_CON);
|
||||||
|
ltq_ebu_w32_mask(0, NAND_CON_CE, EBU_NAND_CON);
|
||||||
|
break;
|
||||||
|
@@ -99,7 +102,6 @@ static void xway_cmd_ctrl(struct mtd_inf
|
||||||
|
{
|
||||||
|
struct nand_chip *this = mtd->priv;
|
||||||
|
unsigned long nandaddr = (unsigned long) this->IO_ADDR_W;
|
||||||
|
- unsigned long flags;
|
||||||
|
|
||||||
|
if (ctrl & NAND_CTRL_CHANGE) {
|
||||||
|
if (ctrl & NAND_CLE)
|
||||||
|
@@ -109,11 +111,9 @@ static void xway_cmd_ctrl(struct mtd_inf
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cmd != NAND_CMD_NONE) {
|
||||||
|
- spin_lock_irqsave(&ebu_lock, flags);
|
||||||
|
writeb(cmd, (void __iomem *) (nandaddr | xway_latchcmd));
|
||||||
|
while ((ltq_ebu_r32(EBU_NAND_WAIT) & NAND_WAIT_WR_C) == 0)
|
||||||
|
;
|
||||||
|
- spin_unlock_irqrestore(&ebu_lock, flags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -126,12 +126,9 @@ static unsigned char xway_read_byte(stru
|
||||||
|
{
|
||||||
|
struct nand_chip *this = mtd->priv;
|
||||||
|
unsigned long nandaddr = (unsigned long) this->IO_ADDR_R;
|
||||||
|
- unsigned long flags;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
- spin_lock_irqsave(&ebu_lock, flags);
|
||||||
|
ret = ltq_r8((void __iomem *)(nandaddr | NAND_READ_DATA));
|
||||||
|
- spin_unlock_irqrestore(&ebu_lock, flags);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
@@ -140,26 +137,20 @@ static void xway_read_buf(struct mtd_inf
|
||||||
|
{
|
||||||
|
struct nand_chip *this = mtd->priv;
|
||||||
|
unsigned long nandaddr = (unsigned long) this->IO_ADDR_R;
|
||||||
|
- unsigned long flags;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
- spin_lock_irqsave(&ebu_lock, flags);
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
buf[i] = ltq_r8((void __iomem *)(nandaddr | NAND_READ_DATA));
|
||||||
|
- spin_unlock_irqrestore(&ebu_lock, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void xway_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
|
||||||
|
{
|
||||||
|
struct nand_chip *this = mtd->priv;
|
||||||
|
unsigned long nandaddr = (unsigned long) this->IO_ADDR_W;
|
||||||
|
- unsigned long flags;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
- spin_lock_irqsave(&ebu_lock, flags);
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
ltq_w8(buf[i], (void __iomem *)(nandaddr | NAND_WRITE_DATA));
|
||||||
|
- spin_unlock_irqrestore(&ebu_lock, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int xway_nand_probe(struct platform_device *pdev)
|
|
@ -0,0 +1,125 @@
|
||||||
|
From 997a8965db8417266bea3fbdcfa3e5655a1b52fa Mon Sep 17 00:00:00 2001
|
||||||
|
From: John Crispin <blogic@openwrt.org>
|
||||||
|
Date: Tue, 9 Sep 2014 23:12:15 +0200
|
||||||
|
Subject: [PATCH 18/36] MTD: nand: lots of xrx200 fixes
|
||||||
|
|
||||||
|
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||||
|
---
|
||||||
|
drivers/mtd/nand/xway_nand.c | 63 ++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
1 file changed, 63 insertions(+)
|
||||||
|
|
||||||
|
--- a/drivers/mtd/nand/xway_nand.c
|
||||||
|
+++ b/drivers/mtd/nand/xway_nand.c
|
||||||
|
@@ -54,8 +54,27 @@
|
||||||
|
#define NAND_CON_CSMUX (1 << 1)
|
||||||
|
#define NAND_CON_NANDM 1
|
||||||
|
|
||||||
|
+#define DANUBE_PCI_REG32( addr ) (*(volatile u32 *)(addr))
|
||||||
|
+#define PCI_CR_PR_OFFSET (KSEG1+0x1E105400)
|
||||||
|
+#define PCI_CR_PC_ARB (PCI_CR_PR_OFFSET + 0x0080)
|
||||||
|
+
|
||||||
|
static u32 xway_latchcmd;
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * req_mask provides a mechanism to prevent interference between
|
||||||
|
+ * nand and pci (probably only relevant for the BT Home Hub 2B).
|
||||||
|
+ * Setting it causes the corresponding pci req pins to be masked
|
||||||
|
+ * during nand access, and also moves ebu locking from the read/write
|
||||||
|
+ * functions to the chip select function to ensure that the whole
|
||||||
|
+ * operation runs with interrupts disabled.
|
||||||
|
+ * In addition it switches on some extra waiting in xway_cmd_ctrl().
|
||||||
|
+ * This seems to be necessary if the ebu_cs1 pin has open-drain disabled,
|
||||||
|
+ * which in turn seems to be necessary for the nor chip to be recognised
|
||||||
|
+ * reliably, on a board (Home Hub 2B again) which has both nor and nand.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+static __be32 req_mask = 0;
|
||||||
|
+
|
||||||
|
static void xway_reset_chip(struct nand_chip *chip)
|
||||||
|
{
|
||||||
|
unsigned long nandaddr = (unsigned long) chip->IO_ADDR_W;
|
||||||
|
@@ -86,12 +105,24 @@ static void xway_select_chip(struct mtd_
|
||||||
|
case -1:
|
||||||
|
ltq_ebu_w32_mask(NAND_CON_CE, 0, EBU_NAND_CON);
|
||||||
|
ltq_ebu_w32_mask(NAND_CON_NANDM, 0, EBU_NAND_CON);
|
||||||
|
+
|
||||||
|
+ if (req_mask) {
|
||||||
|
+ /* Unmask all external PCI request */
|
||||||
|
+ DANUBE_PCI_REG32(PCI_CR_PC_ARB) &= ~(req_mask << 16);
|
||||||
|
+ }
|
||||||
|
spin_unlock_irqrestore(&ebu_lock, csflags);
|
||||||
|
+
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
spin_lock_irqsave(&ebu_lock, csflags);
|
||||||
|
+ if (req_mask) {
|
||||||
|
+ /* Mask all external PCI request */
|
||||||
|
+ DANUBE_PCI_REG32(PCI_CR_PC_ARB) |= (req_mask << 16);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
ltq_ebu_w32_mask(0, NAND_CON_NANDM, EBU_NAND_CON);
|
||||||
|
ltq_ebu_w32_mask(0, NAND_CON_CE, EBU_NAND_CON);
|
||||||
|
+
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
BUG();
|
||||||
|
@@ -103,6 +134,12 @@ static void xway_cmd_ctrl(struct mtd_inf
|
||||||
|
struct nand_chip *this = mtd->priv;
|
||||||
|
unsigned long nandaddr = (unsigned long) this->IO_ADDR_W;
|
||||||
|
|
||||||
|
+ if (req_mask) {
|
||||||
|
+ if (cmd != NAND_CMD_STATUS)
|
||||||
|
+ ltq_ebu_w32(EBU_NAND_WAIT, 0); /* Clear nand ready */
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+
|
||||||
|
if (ctrl & NAND_CTRL_CHANGE) {
|
||||||
|
if (ctrl & NAND_CLE)
|
||||||
|
xway_latchcmd = NAND_WRITE_CMD;
|
||||||
|
@@ -115,6 +152,24 @@ static void xway_cmd_ctrl(struct mtd_inf
|
||||||
|
while ((ltq_ebu_r32(EBU_NAND_WAIT) & NAND_WAIT_WR_C) == 0)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ if (req_mask) {
|
||||||
|
+ /*
|
||||||
|
+ * program and erase have their own busy handlers
|
||||||
|
+ * status and sequential in needs no delay
|
||||||
|
+ */
|
||||||
|
+ switch (cmd) {
|
||||||
|
+ case NAND_CMD_ERASE1:
|
||||||
|
+ case NAND_CMD_SEQIN:
|
||||||
|
+ case NAND_CMD_STATUS:
|
||||||
|
+ case NAND_CMD_READID:
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* wait until command is processed */
|
||||||
|
+ while ((ltq_ebu_r32(EBU_NAND_WAIT) & NAND_WAIT_RD) == 0)
|
||||||
|
+ ;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
static int xway_dev_ready(struct mtd_info *mtd)
|
||||||
|
@@ -157,6 +212,8 @@ static int xway_nand_probe(struct platfo
|
||||||
|
{
|
||||||
|
struct nand_chip *this = platform_get_drvdata(pdev);
|
||||||
|
unsigned long nandaddr = (unsigned long) this->IO_ADDR_W;
|
||||||
|
+ const __be32 *req_mask_ptr = of_get_property(pdev->dev.of_node,
|
||||||
|
+ "req-mask", NULL);
|
||||||
|
const __be32 *cs = of_get_property(pdev->dev.of_node,
|
||||||
|
"lantiq,cs", NULL);
|
||||||
|
u32 cs_flag = 0;
|
||||||
|
@@ -165,6 +222,12 @@ static int xway_nand_probe(struct platfo
|
||||||
|
if (cs && (*cs == 1))
|
||||||
|
cs_flag = NAND_CON_IN_CS1 | NAND_CON_OUT_CS1;
|
||||||
|
|
||||||
|
+ /*
|
||||||
|
+ * Load the PCI req lines to mask from the device tree. If the
|
||||||
|
+ * property is not present, setting req_mask to 0 disables masking.
|
||||||
|
+ */
|
||||||
|
+ req_mask = (req_mask_ptr ? *req_mask_ptr : 0);
|
||||||
|
+
|
||||||
|
/* setup the EBU to run in NAND mode on our base addr */
|
||||||
|
ltq_ebu_w32(CPHYSADDR(nandaddr)
|
||||||
|
| ADDSEL1_MASK(3) | ADDSEL1_REGEN, EBU_ADDSEL1);
|
|
@ -0,0 +1,25 @@
|
||||||
|
From e3b20f04e9f9cae1babe091fdc1d08d7703ae344 Mon Sep 17 00:00:00 2001
|
||||||
|
From: John Crispin <blogic@openwrt.org>
|
||||||
|
Date: Thu, 7 Aug 2014 18:18:00 +0200
|
||||||
|
Subject: [PATCH 20/36] MTD: lantiq: handle NO_XIP on cfi0001 flash
|
||||||
|
|
||||||
|
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||||
|
---
|
||||||
|
drivers/mtd/maps/lantiq-flash.c | 6 +++++-
|
||||||
|
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
--- a/drivers/mtd/maps/lantiq-flash.c
|
||||||
|
+++ b/drivers/mtd/maps/lantiq-flash.c
|
||||||
|
@@ -139,7 +139,11 @@ ltq_mtd_probe(struct platform_device *pd
|
||||||
|
if (!ltq_mtd->map)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
- ltq_mtd->map->phys = ltq_mtd->res->start;
|
||||||
|
+ if (of_find_property(pdev->dev.of_node, "lantiq,noxip", NULL))
|
||||||
|
+ ltq_mtd->map->phys = NO_XIP;
|
||||||
|
+ else
|
||||||
|
+ ltq_mtd->map->phys = ltq_mtd->res->start;
|
||||||
|
+ ltq_mtd->res->start;
|
||||||
|
ltq_mtd->map->size = resource_size(ltq_mtd->res);
|
||||||
|
ltq_mtd->map->virt = devm_ioremap_resource(&pdev->dev, ltq_mtd->res);
|
||||||
|
if (IS_ERR(ltq_mtd->map->virt))
|
|
@ -0,0 +1,36 @@
|
||||||
|
From 4400e1f593ea40a51912128adb4f53d59e62cad8 Mon Sep 17 00:00:00 2001
|
||||||
|
From: John Crispin <blogic@openwrt.org>
|
||||||
|
Date: Wed, 10 Sep 2014 22:40:18 +0200
|
||||||
|
Subject: [PATCH 22/36] MTD: m25p80: allow loading mtd name from OF
|
||||||
|
|
||||||
|
In accordance with the physmap flash we should honour the linux,mtd-name
|
||||||
|
property when deciding what name the mtd device has.
|
||||||
|
|
||||||
|
Signed-off-by: Thomas Langer <thomas.langer@lantiq.com>
|
||||||
|
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||||
|
---
|
||||||
|
drivers/mtd/devices/m25p80.c | 6 ++++++
|
||||||
|
1 file changed, 6 insertions(+)
|
||||||
|
|
||||||
|
--- a/drivers/mtd/devices/m25p80.c
|
||||||
|
+++ b/drivers/mtd/devices/m25p80.c
|
||||||
|
@@ -198,6 +198,10 @@ static int m25p_probe(struct spi_device
|
||||||
|
enum read_mode mode = SPI_NOR_NORMAL;
|
||||||
|
char *flash_name = NULL;
|
||||||
|
int ret;
|
||||||
|
+ const char __maybe_unused *of_mtd_name = NULL;
|
||||||
|
+
|
||||||
|
+ of_property_read_string(spi->dev.of_node,
|
||||||
|
+ "linux,mtd-name", &of_mtd_name);
|
||||||
|
|
||||||
|
data = dev_get_platdata(&spi->dev);
|
||||||
|
|
||||||
|
@@ -229,6 +233,8 @@ static int m25p_probe(struct spi_device
|
||||||
|
|
||||||
|
if (data && data->name)
|
||||||
|
flash->mtd.name = data->name;
|
||||||
|
+ else if (of_mtd_name)
|
||||||
|
+ flash->mtd.name = of_mtd_name;
|
||||||
|
|
||||||
|
/* For some (historical?) reason many platforms provide two different
|
||||||
|
* names in flash_platform_data: "name" and "type". Quite often name is
|
|
@ -0,0 +1,271 @@
|
||||||
|
From 0a63ab263725c427051a8bbaa0732b749627da27 Mon Sep 17 00:00:00 2001
|
||||||
|
From: John Crispin <blogic@openwrt.org>
|
||||||
|
Date: Thu, 7 Aug 2014 18:15:36 +0200
|
||||||
|
Subject: [PATCH 23/36] NET: PHY: adds driver for lantiq PHY11G
|
||||||
|
|
||||||
|
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||||
|
---
|
||||||
|
drivers/net/phy/Kconfig | 5 +
|
||||||
|
drivers/net/phy/Makefile | 1 +
|
||||||
|
drivers/net/phy/lantiq.c | 231 ++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
3 files changed, 237 insertions(+)
|
||||||
|
create mode 100644 drivers/net/phy/lantiq.c
|
||||||
|
|
||||||
|
--- a/drivers/net/phy/Kconfig
|
||||||
|
+++ b/drivers/net/phy/Kconfig
|
||||||
|
@@ -164,6 +164,11 @@ config RTL8306_PHY
|
||||||
|
tristate "Driver for Realtek RTL8306S switches"
|
||||||
|
select SWCONFIG
|
||||||
|
|
||||||
|
+config LANTIQ_PHY
|
||||||
|
+ tristate "Driver for Lantiq PHYs"
|
||||||
|
+ ---help---
|
||||||
|
+ Supports the 11G and 22E PHYs.
|
||||||
|
+
|
||||||
|
config FIXED_PHY
|
||||||
|
bool "Driver for MDIO Bus/PHY emulation with fixed speed/link PHYs"
|
||||||
|
depends on PHYLIB=y
|
||||||
|
--- a/drivers/net/phy/Makefile
|
||||||
|
+++ b/drivers/net/phy/Makefile
|
||||||
|
@@ -40,6 +40,7 @@ obj-$(CONFIG_NATIONAL_PHY) += national.o
|
||||||
|
obj-$(CONFIG_DP83640_PHY) += dp83640.o
|
||||||
|
obj-$(CONFIG_STE10XP) += ste10Xp.o
|
||||||
|
obj-$(CONFIG_MICREL_PHY) += micrel.o
|
||||||
|
+obj-$(CONFIG_LANTIQ_PHY) += lantiq.o
|
||||||
|
obj-$(CONFIG_MDIO_OCTEON) += mdio-octeon.o
|
||||||
|
obj-$(CONFIG_MICREL_KS8995MA) += spi_ks8995.o
|
||||||
|
obj-$(CONFIG_AT803X_PHY) += at803x.o
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/drivers/net/phy/lantiq.c
|
||||||
|
@@ -0,0 +1,231 @@
|
||||||
|
+/*
|
||||||
|
+ * This program is free software; you can redistribute it and/or modify
|
||||||
|
+ * it under the terms of the GNU General Public License as published by
|
||||||
|
+ * the Free Software Foundation; either version 2 of the License, or
|
||||||
|
+ * (at your option) any later version.
|
||||||
|
+ *
|
||||||
|
+ * This program is distributed in the hope that it will be useful,
|
||||||
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
+ * GNU General Public License for more details.
|
||||||
|
+ *
|
||||||
|
+ * You should have received a copy of the GNU General Public License
|
||||||
|
+ * along with this program; if not, write to the Free Software
|
||||||
|
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
+ *
|
||||||
|
+ * Copyright (C) 2012 Daniel Schwierzeck <daniel.schwierzeck@googlemail.com>
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#include <linux/module.h>
|
||||||
|
+#include <linux/phy.h>
|
||||||
|
+
|
||||||
|
+#define MII_MMDCTRL 0x0d
|
||||||
|
+#define MII_MMDDATA 0x0e
|
||||||
|
+
|
||||||
|
+#define MII_VR9_11G_IMASK 0x19 /* interrupt mask */
|
||||||
|
+#define MII_VR9_11G_ISTAT 0x1a /* interrupt status */
|
||||||
|
+
|
||||||
|
+#define INT_VR9_11G_WOL BIT(15) /* Wake-On-LAN */
|
||||||
|
+#define INT_VR9_11G_ANE BIT(11) /* Auto-Neg error */
|
||||||
|
+#define INT_VR9_11G_ANC BIT(10) /* Auto-Neg complete */
|
||||||
|
+#define INT_VR9_11G_ADSC BIT(5) /* Link auto-downspeed detect */
|
||||||
|
+#define INT_VR9_11G_DXMC BIT(2) /* Duplex mode change */
|
||||||
|
+#define INT_VR9_11G_LSPC BIT(1) /* Link speed change */
|
||||||
|
+#define INT_VR9_11G_LSTC BIT(0) /* Link state change */
|
||||||
|
+#define INT_VR9_11G_MASK (INT_VR9_11G_LSTC | INT_VR9_11G_ADSC)
|
||||||
|
+
|
||||||
|
+#define ADVERTISED_MPD BIT(10) /* Multi-port device */
|
||||||
|
+
|
||||||
|
+#define MMD_DEVAD 0x1f
|
||||||
|
+#define MMD_ACTYPE_SHIFT 14
|
||||||
|
+#define MMD_ACTYPE_ADDRESS (0 << MMD_ACTYPE_SHIFT)
|
||||||
|
+#define MMD_ACTYPE_DATA (1 << MMD_ACTYPE_SHIFT)
|
||||||
|
+#define MMD_ACTYPE_DATA_PI (2 << MMD_ACTYPE_SHIFT)
|
||||||
|
+#define MMD_ACTYPE_DATA_PIWR (3 << MMD_ACTYPE_SHIFT)
|
||||||
|
+
|
||||||
|
+static __maybe_unused int vr9_gphy_mmd_read(struct phy_device *phydev,
|
||||||
|
+ u16 regnum)
|
||||||
|
+{
|
||||||
|
+ phy_write(phydev, MII_MMDCTRL, MMD_ACTYPE_ADDRESS | MMD_DEVAD);
|
||||||
|
+ phy_write(phydev, MII_MMDDATA, regnum);
|
||||||
|
+ phy_write(phydev, MII_MMDCTRL, MMD_ACTYPE_DATA | MMD_DEVAD);
|
||||||
|
+
|
||||||
|
+ return phy_read(phydev, MII_MMDDATA);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static __maybe_unused int vr9_gphy_mmd_write(struct phy_device *phydev,
|
||||||
|
+ u16 regnum, u16 val)
|
||||||
|
+{
|
||||||
|
+ phy_write(phydev, MII_MMDCTRL, MMD_ACTYPE_ADDRESS | MMD_DEVAD);
|
||||||
|
+ phy_write(phydev, MII_MMDDATA, regnum);
|
||||||
|
+ phy_write(phydev, MII_MMDCTRL, MMD_ACTYPE_DATA | MMD_DEVAD);
|
||||||
|
+ phy_write(phydev, MII_MMDDATA, val);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int vr9_gphy_config_init(struct phy_device *phydev)
|
||||||
|
+{
|
||||||
|
+ int err;
|
||||||
|
+
|
||||||
|
+ dev_dbg(&phydev->dev, "%s\n", __func__);
|
||||||
|
+
|
||||||
|
+ /* Mask all interrupts */
|
||||||
|
+ err = phy_write(phydev, MII_VR9_11G_IMASK, 0);
|
||||||
|
+ if (err)
|
||||||
|
+ return err;
|
||||||
|
+
|
||||||
|
+ /* Clear all pending interrupts */
|
||||||
|
+ phy_read(phydev, MII_VR9_11G_ISTAT);
|
||||||
|
+
|
||||||
|
+ vr9_gphy_mmd_write(phydev, 0x1e0, 0xc5);
|
||||||
|
+ vr9_gphy_mmd_write(phydev, 0x1e1, 0x67);
|
||||||
|
+ vr9_gphy_mmd_write(phydev, 0x1e2, 0x42);
|
||||||
|
+ vr9_gphy_mmd_write(phydev, 0x1e3, 0x10);
|
||||||
|
+ vr9_gphy_mmd_write(phydev, 0x1e4, 0x70);
|
||||||
|
+ vr9_gphy_mmd_write(phydev, 0x1e5, 0x03);
|
||||||
|
+ vr9_gphy_mmd_write(phydev, 0x1e6, 0x20);
|
||||||
|
+ vr9_gphy_mmd_write(phydev, 0x1e7, 0x00);
|
||||||
|
+ vr9_gphy_mmd_write(phydev, 0x1e8, 0x40);
|
||||||
|
+ vr9_gphy_mmd_write(phydev, 0x1e9, 0x20);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int vr9_gphy_config_aneg(struct phy_device *phydev)
|
||||||
|
+{
|
||||||
|
+ int reg, err;
|
||||||
|
+
|
||||||
|
+ /* Advertise as multi-port device */
|
||||||
|
+ reg = phy_read(phydev, MII_CTRL1000);
|
||||||
|
+ reg |= ADVERTISED_MPD;
|
||||||
|
+ err = phy_write(phydev, MII_CTRL1000, reg);
|
||||||
|
+ if (err)
|
||||||
|
+ return err;
|
||||||
|
+
|
||||||
|
+ return genphy_config_aneg(phydev);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int vr9_gphy_ack_interrupt(struct phy_device *phydev)
|
||||||
|
+{
|
||||||
|
+ int reg;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Possible IRQ numbers:
|
||||||
|
+ * - IM3_IRL18 for GPHY0
|
||||||
|
+ * - IM3_IRL17 for GPHY1
|
||||||
|
+ *
|
||||||
|
+ * Due to a silicon bug IRQ lines are not really independent from
|
||||||
|
+ * each other. Sometimes the two lines are driven at the same time
|
||||||
|
+ * if only one GPHY core raises the interrupt.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+ reg = phy_read(phydev, MII_VR9_11G_ISTAT);
|
||||||
|
+
|
||||||
|
+ return (reg < 0) ? reg : 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int vr9_gphy_did_interrupt(struct phy_device *phydev)
|
||||||
|
+{
|
||||||
|
+ int reg;
|
||||||
|
+
|
||||||
|
+ reg = phy_read(phydev, MII_VR9_11G_ISTAT);
|
||||||
|
+
|
||||||
|
+ return reg > 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int vr9_gphy_config_intr(struct phy_device *phydev)
|
||||||
|
+{
|
||||||
|
+ int err;
|
||||||
|
+
|
||||||
|
+ if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
|
||||||
|
+ err = phy_write(phydev, MII_VR9_11G_IMASK, INT_VR9_11G_MASK);
|
||||||
|
+ else
|
||||||
|
+ err = phy_write(phydev, MII_VR9_11G_IMASK, 0);
|
||||||
|
+
|
||||||
|
+ return err;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static struct phy_driver lantiq_phy[] = {
|
||||||
|
+ {
|
||||||
|
+ .phy_id = 0xd565a400,
|
||||||
|
+ .phy_id_mask = 0xffffffff,
|
||||||
|
+ .name = "Lantiq XWAY PEF7071",
|
||||||
|
+ .features = (PHY_GBIT_FEATURES | SUPPORTED_Pause),
|
||||||
|
+ .flags = 0, /*PHY_HAS_INTERRUPT,*/
|
||||||
|
+ .config_init = vr9_gphy_config_init,
|
||||||
|
+ .config_aneg = vr9_gphy_config_aneg,
|
||||||
|
+ .read_status = genphy_read_status,
|
||||||
|
+ .ack_interrupt = vr9_gphy_ack_interrupt,
|
||||||
|
+ .did_interrupt = vr9_gphy_did_interrupt,
|
||||||
|
+ .config_intr = vr9_gphy_config_intr,
|
||||||
|
+ .driver = { .owner = THIS_MODULE },
|
||||||
|
+ }, {
|
||||||
|
+ .phy_id = 0x030260D0,
|
||||||
|
+ .phy_id_mask = 0xfffffff0,
|
||||||
|
+ .name = "Lantiq XWAY VR9 GPHY 11G v1.3",
|
||||||
|
+ .features = (PHY_GBIT_FEATURES | SUPPORTED_Pause),
|
||||||
|
+ .flags = 0, /*PHY_HAS_INTERRUPT,*/
|
||||||
|
+ .config_init = vr9_gphy_config_init,
|
||||||
|
+ .config_aneg = vr9_gphy_config_aneg,
|
||||||
|
+ .read_status = genphy_read_status,
|
||||||
|
+ .ack_interrupt = vr9_gphy_ack_interrupt,
|
||||||
|
+ .did_interrupt = vr9_gphy_did_interrupt,
|
||||||
|
+ .config_intr = vr9_gphy_config_intr,
|
||||||
|
+ .driver = { .owner = THIS_MODULE },
|
||||||
|
+ }, {
|
||||||
|
+ .phy_id = 0xd565a408,
|
||||||
|
+ .phy_id_mask = 0xfffffff8,
|
||||||
|
+ .name = "Lantiq XWAY VR9 GPHY 11G v1.4",
|
||||||
|
+ .features = (PHY_GBIT_FEATURES | SUPPORTED_Pause),
|
||||||
|
+ .flags = 0, /*PHY_HAS_INTERRUPT,*/
|
||||||
|
+ .config_init = vr9_gphy_config_init,
|
||||||
|
+ .config_aneg = vr9_gphy_config_aneg,
|
||||||
|
+ .read_status = genphy_read_status,
|
||||||
|
+ .ack_interrupt = vr9_gphy_ack_interrupt,
|
||||||
|
+ .did_interrupt = vr9_gphy_did_interrupt,
|
||||||
|
+ .config_intr = vr9_gphy_config_intr,
|
||||||
|
+ .driver = { .owner = THIS_MODULE },
|
||||||
|
+ }, {
|
||||||
|
+ .phy_id = 0xd565a418,
|
||||||
|
+ .phy_id_mask = 0xfffffff8,
|
||||||
|
+ .name = "Lantiq XWAY XRX PHY22F v1.4",
|
||||||
|
+ .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause),
|
||||||
|
+ .flags = 0, /*PHY_HAS_INTERRUPT,*/
|
||||||
|
+ .config_init = vr9_gphy_config_init,
|
||||||
|
+ .config_aneg = vr9_gphy_config_aneg,
|
||||||
|
+ .read_status = genphy_read_status,
|
||||||
|
+ .ack_interrupt = vr9_gphy_ack_interrupt,
|
||||||
|
+ .did_interrupt = vr9_gphy_did_interrupt,
|
||||||
|
+ .config_intr = vr9_gphy_config_intr,
|
||||||
|
+ .driver = { .owner = THIS_MODULE },
|
||||||
|
+ },
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static int __init ltq_phy_init(void)
|
||||||
|
+{
|
||||||
|
+ int i;
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < ARRAY_SIZE(lantiq_phy); i++) {
|
||||||
|
+ int err = phy_driver_register(&lantiq_phy[i]);
|
||||||
|
+ if (err)
|
||||||
|
+ pr_err("lantiq_phy: failed to load %s\n", lantiq_phy[i].name);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void __exit ltq_phy_exit(void)
|
||||||
|
+{
|
||||||
|
+ int i;
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < ARRAY_SIZE(lantiq_phy); i++)
|
||||||
|
+ phy_driver_unregister(&lantiq_phy[i]);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+module_init(ltq_phy_init);
|
||||||
|
+module_exit(ltq_phy_exit);
|
||||||
|
+
|
||||||
|
+MODULE_DESCRIPTION("Lantiq PHY drivers");
|
||||||
|
+MODULE_AUTHOR("Daniel Schwierzeck <daniel.schwierzeck@googlemail.com>");
|
||||||
|
+MODULE_LICENSE("GPL");
|
|
@ -0,0 +1,364 @@
|
||||||
|
From 77e89d5a28be35058041c79e9874ab26f222c603 Mon Sep 17 00:00:00 2001
|
||||||
|
From: John Crispin <blogic@openwrt.org>
|
||||||
|
Date: Mon, 22 Oct 2012 09:26:24 +0200
|
||||||
|
Subject: [PATCH 24/36] NET: lantiq: adds PHY11G firmware blobs
|
||||||
|
|
||||||
|
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||||
|
---
|
||||||
|
firmware/Makefile | 4 +
|
||||||
|
firmware/lantiq/COPYING | 286 +++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
firmware/lantiq/README | 45 ++++++++
|
||||||
|
3 files changed, 335 insertions(+)
|
||||||
|
create mode 100644 firmware/lantiq/COPYING
|
||||||
|
create mode 100644 firmware/lantiq/README
|
||||||
|
|
||||||
|
--- a/firmware/Makefile
|
||||||
|
+++ b/firmware/Makefile
|
||||||
|
@@ -134,6 +134,10 @@ fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_P
|
||||||
|
fw-shipped-$(CONFIG_USB_SERIAL_XIRCOM) += keyspan_pda/xircom_pgs.fw
|
||||||
|
fw-shipped-$(CONFIG_USB_VICAM) += vicam/firmware.fw
|
||||||
|
fw-shipped-$(CONFIG_VIDEO_CPIA2) += cpia2/stv0672_vp4.bin
|
||||||
|
+fw-shipped-$(CONFIG_LANTIQ_XRX200) += lantiq/vr9_phy11g_a1x.bin
|
||||||
|
+fw-shipped-$(CONFIG_LANTIQ_XRX200) += lantiq/vr9_phy11g_a2x.bin
|
||||||
|
+fw-shipped-$(CONFIG_LANTIQ_XRX200) += lantiq/vr9_phy22f_a1x.bin
|
||||||
|
+fw-shipped-$(CONFIG_LANTIQ_XRX200) += lantiq/vr9_phy22f_a2x.bin
|
||||||
|
fw-shipped-$(CONFIG_YAM) += yam/1200.bin yam/9600.bin
|
||||||
|
|
||||||
|
fw-shipped-all := $(fw-shipped-y) $(fw-shipped-m) $(fw-shipped-)
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/firmware/lantiq/COPYING
|
||||||
|
@@ -0,0 +1,286 @@
|
||||||
|
+All firmware files are copyrighted by Lantiq Deutschland GmbH.
|
||||||
|
+The files have been extracted from header files found in Lantiq BSPs.
|
||||||
|
+If not stated otherwise all files are licensed under GPL.
|
||||||
|
+
|
||||||
|
+=======================================================================
|
||||||
|
+
|
||||||
|
+ GNU GENERAL PUBLIC LICENSE
|
||||||
|
+ Version 2, June 1991
|
||||||
|
+
|
||||||
|
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||||
|
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
+ Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
+ of this license document, but changing it is not allowed.
|
||||||
|
+
|
||||||
|
+ Preamble
|
||||||
|
+
|
||||||
|
+ The licenses for most software are designed to take away your
|
||||||
|
+freedom to share and change it. By contrast, the GNU General Public
|
||||||
|
+License is intended to guarantee your freedom to share and change free
|
||||||
|
+software--to make sure the software is free for all its users. This
|
||||||
|
+General Public License applies to most of the Free Software
|
||||||
|
+Foundation's software and to any other program whose authors commit to
|
||||||
|
+using it. (Some other Free Software Foundation software is covered by
|
||||||
|
+the GNU Library General Public License instead.) You can apply it to
|
||||||
|
+your programs, too.
|
||||||
|
+
|
||||||
|
+ When we speak of free software, we are referring to freedom, not
|
||||||
|
+price. Our General Public Licenses are designed to make sure that you
|
||||||
|
+have the freedom to distribute copies of free software (and charge for
|
||||||
|
+this service if you wish), that you receive source code or can get it
|
||||||
|
+if you want it, that you can change the software or use pieces of it
|
||||||
|
+in new free programs; and that you know you can do these things.
|
||||||
|
+
|
||||||
|
+ To protect your rights, we need to make restrictions that forbid
|
||||||
|
+anyone to deny you these rights or to ask you to surrender the rights.
|
||||||
|
+These restrictions translate to certain responsibilities for you if you
|
||||||
|
+distribute copies of the software, or if you modify it.
|
||||||
|
+
|
||||||
|
+ For example, if you distribute copies of such a program, whether
|
||||||
|
+gratis or for a fee, you must give the recipients all the rights that
|
||||||
|
+you have. You must make sure that they, too, receive or can get the
|
||||||
|
+source code. And you must show them these terms so they know their
|
||||||
|
+rights.
|
||||||
|
+
|
||||||
|
+ We protect your rights with two steps: (1) copyright the software, and
|
||||||
|
+(2) offer you this license which gives you legal permission to copy,
|
||||||
|
+distribute and/or modify the software.
|
||||||
|
+
|
||||||
|
+ Also, for each author's protection and ours, we want to make certain
|
||||||
|
+that everyone understands that there is no warranty for this free
|
||||||
|
+software. If the software is modified by someone else and passed on, we
|
||||||
|
+want its recipients to know that what they have is not the original, so
|
||||||
|
+that any problems introduced by others will not reflect on the original
|
||||||
|
+authors' reputations.
|
||||||
|
+
|
||||||
|
+ Finally, any free program is threatened constantly by software
|
||||||
|
+patents. We wish to avoid the danger that redistributors of a free
|
||||||
|
+program will individually obtain patent licenses, in effect making the
|
||||||
|
+program proprietary. To prevent this, we have made it clear that any
|
||||||
|
+patent must be licensed for everyone's free use or not licensed at all.
|
||||||
|
+
|
||||||
|
+ The precise terms and conditions for copying, distribution and
|
||||||
|
+modification follow.
|
||||||
|
+
|
||||||
|
+ GNU GENERAL PUBLIC LICENSE
|
||||||
|
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
+
|
||||||
|
+ 0. This License applies to any program or other work which contains
|
||||||
|
+a notice placed by the copyright holder saying it may be distributed
|
||||||
|
+under the terms of this General Public License. The "Program", below,
|
||||||
|
+refers to any such program or work, and a "work based on the Program"
|
||||||
|
+means either the Program or any derivative work under copyright law:
|
||||||
|
+that is to say, a work containing the Program or a portion of it,
|
||||||
|
+either verbatim or with modifications and/or translated into another
|
||||||
|
+language. (Hereinafter, translation is included without limitation in
|
||||||
|
+the term "modification".) Each licensee is addressed as "you".
|
||||||
|
+
|
||||||
|
+Activities other than copying, distribution and modification are not
|
||||||
|
+covered by this License; they are outside its scope. The act of
|
||||||
|
+running the Program is not restricted, and the output from the Program
|
||||||
|
+is covered only if its contents constitute a work based on the
|
||||||
|
+Program (independent of having been made by running the Program).
|
||||||
|
+Whether that is true depends on what the Program does.
|
||||||
|
+
|
||||||
|
+ 1. You may copy and distribute verbatim copies of the Program's
|
||||||
|
+source code as you receive it, in any medium, provided that you
|
||||||
|
+conspicuously and appropriately publish on each copy an appropriate
|
||||||
|
+copyright notice and disclaimer of warranty; keep intact all the
|
||||||
|
+notices that refer to this License and to the absence of any warranty;
|
||||||
|
+and give any other recipients of the Program a copy of this License
|
||||||
|
+along with the Program.
|
||||||
|
+
|
||||||
|
+You may charge a fee for the physical act of transferring a copy, and
|
||||||
|
+you may at your option offer warranty protection in exchange for a fee.
|
||||||
|
+
|
||||||
|
+ 2. You may modify your copy or copies of the Program or any portion
|
||||||
|
+of it, thus forming a work based on the Program, and copy and
|
||||||
|
+distribute such modifications or work under the terms of Section 1
|
||||||
|
+above, provided that you also meet all of these conditions:
|
||||||
|
+
|
||||||
|
+ a) You must cause the modified files to carry prominent notices
|
||||||
|
+ stating that you changed the files and the date of any change.
|
||||||
|
+
|
||||||
|
+ b) You must cause any work that you distribute or publish, that in
|
||||||
|
+ whole or in part contains or is derived from the Program or any
|
||||||
|
+ part thereof, to be licensed as a whole at no charge to all third
|
||||||
|
+ parties under the terms of this License.
|
||||||
|
+
|
||||||
|
+ c) If the modified program normally reads commands interactively
|
||||||
|
+ when run, you must cause it, when started running for such
|
||||||
|
+ interactive use in the most ordinary way, to print or display an
|
||||||
|
+ announcement including an appropriate copyright notice and a
|
||||||
|
+ notice that there is no warranty (or else, saying that you provide
|
||||||
|
+ a warranty) and that users may redistribute the program under
|
||||||
|
+ these conditions, and telling the user how to view a copy of this
|
||||||
|
+ License. (Exception: if the Program itself is interactive but
|
||||||
|
+ does not normally print such an announcement, your work based on
|
||||||
|
+ the Program is not required to print an announcement.)
|
||||||
|
+
|
||||||
|
+These requirements apply to the modified work as a whole. If
|
||||||
|
+identifiable sections of that work are not derived from the Program,
|
||||||
|
+and can be reasonably considered independent and separate works in
|
||||||
|
+themselves, then this License, and its terms, do not apply to those
|
||||||
|
+sections when you distribute them as separate works. But when you
|
||||||
|
+distribute the same sections as part of a whole which is a work based
|
||||||
|
+on the Program, the distribution of the whole must be on the terms of
|
||||||
|
+this License, whose permissions for other licensees extend to the
|
||||||
|
+entire whole, and thus to each and every part regardless of who wrote it.
|
||||||
|
+
|
||||||
|
+Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
+your rights to work written entirely by you; rather, the intent is to
|
||||||
|
+exercise the right to control the distribution of derivative or
|
||||||
|
+collective works based on the Program.
|
||||||
|
+
|
||||||
|
+In addition, mere aggregation of another work not based on the Program
|
||||||
|
+with the Program (or with a work based on the Program) on a volume of
|
||||||
|
+a storage or distribution medium does not bring the other work under
|
||||||
|
+the scope of this License.
|
||||||
|
+
|
||||||
|
+ 3. You may copy and distribute the Program (or a work based on it,
|
||||||
|
+under Section 2) in object code or executable form under the terms of
|
||||||
|
+Sections 1 and 2 above provided that you also do one of the following:
|
||||||
|
+
|
||||||
|
+ a) Accompany it with the complete corresponding machine-readable
|
||||||
|
+ source code, which must be distributed under the terms of Sections
|
||||||
|
+ 1 and 2 above on a medium customarily used for software interchange; or,
|
||||||
|
+
|
||||||
|
+ b) Accompany it with a written offer, valid for at least three
|
||||||
|
+ years, to give any third party, for a charge no more than your
|
||||||
|
+ cost of physically performing source distribution, a complete
|
||||||
|
+ machine-readable copy of the corresponding source code, to be
|
||||||
|
+ distributed under the terms of Sections 1 and 2 above on a medium
|
||||||
|
+ customarily used for software interchange; or,
|
||||||
|
+
|
||||||
|
+ c) Accompany it with the information you received as to the offer
|
||||||
|
+ to distribute corresponding source code. (This alternative is
|
||||||
|
+ allowed only for noncommercial distribution and only if you
|
||||||
|
+ received the program in object code or executable form with such
|
||||||
|
+ an offer, in accord with Subsection b above.)
|
||||||
|
+
|
||||||
|
+The source code for a work means the preferred form of the work for
|
||||||
|
+making modifications to it. For an executable work, complete source
|
||||||
|
+code means all the source code for all modules it contains, plus any
|
||||||
|
+associated interface definition files, plus the scripts used to
|
||||||
|
+control compilation and installation of the executable. However, as a
|
||||||
|
+special exception, the source code distributed need not include
|
||||||
|
+anything that is normally distributed (in either source or binary
|
||||||
|
+form) with the major components (compiler, kernel, and so on) of the
|
||||||
|
+operating system on which the executable runs, unless that component
|
||||||
|
+itself accompanies the executable.
|
||||||
|
+
|
||||||
|
+If distribution of executable or object code is made by offering
|
||||||
|
+access to copy from a designated place, then offering equivalent
|
||||||
|
+access to copy the source code from the same place counts as
|
||||||
|
+distribution of the source code, even though third parties are not
|
||||||
|
+compelled to copy the source along with the object code.
|
||||||
|
+
|
||||||
|
+ 4. You may not copy, modify, sublicense, or distribute the Program
|
||||||
|
+except as expressly provided under this License. Any attempt
|
||||||
|
+otherwise to copy, modify, sublicense or distribute the Program is
|
||||||
|
+void, and will automatically terminate your rights under this License.
|
||||||
|
+However, parties who have received copies, or rights, from you under
|
||||||
|
+this License will not have their licenses terminated so long as such
|
||||||
|
+parties remain in full compliance.
|
||||||
|
+
|
||||||
|
+ 5. You are not required to accept this License, since you have not
|
||||||
|
+signed it. However, nothing else grants you permission to modify or
|
||||||
|
+distribute the Program or its derivative works. These actions are
|
||||||
|
+prohibited by law if you do not accept this License. Therefore, by
|
||||||
|
+modifying or distributing the Program (or any work based on the
|
||||||
|
+Program), you indicate your acceptance of this License to do so, and
|
||||||
|
+all its terms and conditions for copying, distributing or modifying
|
||||||
|
+the Program or works based on it.
|
||||||
|
+
|
||||||
|
+ 6. Each time you redistribute the Program (or any work based on the
|
||||||
|
+Program), the recipient automatically receives a license from the
|
||||||
|
+original licensor to copy, distribute or modify the Program subject to
|
||||||
|
+these terms and conditions. You may not impose any further
|
||||||
|
+restrictions on the recipients' exercise of the rights granted herein.
|
||||||
|
+You are not responsible for enforcing compliance by third parties to
|
||||||
|
+this License.
|
||||||
|
+
|
||||||
|
+ 7. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
+infringement or for any other reason (not limited to patent issues),
|
||||||
|
+conditions are imposed on you (whether by court order, agreement or
|
||||||
|
+otherwise) that contradict the conditions of this License, they do not
|
||||||
|
+excuse you from the conditions of this License. If you cannot
|
||||||
|
+distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
+License and any other pertinent obligations, then as a consequence you
|
||||||
|
+may not distribute the Program at all. For example, if a patent
|
||||||
|
+license would not permit royalty-free redistribution of the Program by
|
||||||
|
+all those who receive copies directly or indirectly through you, then
|
||||||
|
+the only way you could satisfy both it and this License would be to
|
||||||
|
+refrain entirely from distribution of the Program.
|
||||||
|
+
|
||||||
|
+If any portion of this section is held invalid or unenforceable under
|
||||||
|
+any particular circumstance, the balance of the section is intended to
|
||||||
|
+apply and the section as a whole is intended to apply in other
|
||||||
|
+circumstances.
|
||||||
|
+
|
||||||
|
+It is not the purpose of this section to induce you to infringe any
|
||||||
|
+patents or other property right claims or to contest validity of any
|
||||||
|
+such claims; this section has the sole purpose of protecting the
|
||||||
|
+integrity of the free software distribution system, which is
|
||||||
|
+implemented by public license practices. Many people have made
|
||||||
|
+generous contributions to the wide range of software distributed
|
||||||
|
+through that system in reliance on consistent application of that
|
||||||
|
+system; it is up to the author/donor to decide if he or she is willing
|
||||||
|
+to distribute software through any other system and a licensee cannot
|
||||||
|
+impose that choice.
|
||||||
|
+
|
||||||
|
+This section is intended to make thoroughly clear what is believed to
|
||||||
|
+be a consequence of the rest of this License.
|
||||||
|
+
|
||||||
|
+ 8. If the distribution and/or use of the Program is restricted in
|
||||||
|
+certain countries either by patents or by copyrighted interfaces, the
|
||||||
|
+original copyright holder who places the Program under this License
|
||||||
|
+may add an explicit geographical distribution limitation excluding
|
||||||
|
+those countries, so that distribution is permitted only in or among
|
||||||
|
+countries not thus excluded. In such case, this License incorporates
|
||||||
|
+the limitation as if written in the body of this License.
|
||||||
|
+
|
||||||
|
+ 9. The Free Software Foundation may publish revised and/or new versions
|
||||||
|
+of the General Public License from time to time. Such new versions will
|
||||||
|
+be similar in spirit to the present version, but may differ in detail to
|
||||||
|
+address new problems or concerns.
|
||||||
|
+
|
||||||
|
+Each version is given a distinguishing version number. If the Program
|
||||||
|
+specifies a version number of this License which applies to it and "any
|
||||||
|
+later version", you have the option of following the terms and conditions
|
||||||
|
+either of that version or of any later version published by the Free
|
||||||
|
+Software Foundation. If the Program does not specify a version number of
|
||||||
|
+this License, you may choose any version ever published by the Free Software
|
||||||
|
+Foundation.
|
||||||
|
+
|
||||||
|
+ 10. If you wish to incorporate parts of the Program into other free
|
||||||
|
+programs whose distribution conditions are different, write to the author
|
||||||
|
+to ask for permission. For software which is copyrighted by the Free
|
||||||
|
+Software Foundation, write to the Free Software Foundation; we sometimes
|
||||||
|
+make exceptions for this. Our decision will be guided by the two goals
|
||||||
|
+of preserving the free status of all derivatives of our free software and
|
||||||
|
+of promoting the sharing and reuse of software generally.
|
||||||
|
+
|
||||||
|
+ NO WARRANTY
|
||||||
|
+
|
||||||
|
+ 11. 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.
|
||||||
|
+
|
||||||
|
+ 12. 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.
|
||||||
|
+
|
||||||
|
+ END OF TERMS AND CONDITIONS
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/firmware/lantiq/README
|
||||||
|
@@ -0,0 +1,45 @@
|
||||||
|
+#
|
||||||
|
+# This program is free software; you can redistribute it and/or
|
||||||
|
+# modify it under the terms of the GNU General Public License as
|
||||||
|
+# published by the Free Software Foundation; either version 2 of
|
||||||
|
+# the License, or (at your option) any later version.
|
||||||
|
+#
|
||||||
|
+# This program is distributed in the hope that it will be useful,
|
||||||
|
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
+# GNU General Public License for more details.
|
||||||
|
+#
|
||||||
|
+# You should have received a copy of the GNU General Public License
|
||||||
|
+# along with this program; if not, write to the Free Software
|
||||||
|
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||||
|
+# MA 02111-1307 USA
|
||||||
|
+#
|
||||||
|
+# (C) Copyright 2007 - 2012
|
||||||
|
+# Lantiq Deutschland GmbH
|
||||||
|
+#
|
||||||
|
+# (C) Copyright 2012
|
||||||
|
+# Daniel Schwierzeck <daniel.schwierzeck@googlemail.com>
|
||||||
|
+#
|
||||||
|
+
|
||||||
|
+#
|
||||||
|
+# How to use
|
||||||
|
+#
|
||||||
|
+Configure kernel with:
|
||||||
|
+CONFIG_FW_LOADER=y
|
||||||
|
+CONFIG_EXTRA_FIRMWARE_DIR="FIRMWARE_DIR"
|
||||||
|
+CONFIG_EXTRA_FIRMWARE="FIRMWARE_FILES"
|
||||||
|
+
|
||||||
|
+where FIRMWARE_DIR should point to this git tree and FIRMWARE_FILES is a list
|
||||||
|
+of space separated files from list below.
|
||||||
|
+
|
||||||
|
+#
|
||||||
|
+# Firmware files
|
||||||
|
+#
|
||||||
|
+
|
||||||
|
+# GPHY core on Lantiq XWAY VR9 v1.1
|
||||||
|
+lantiq/vr9_phy11g_a1x.bin
|
||||||
|
+lantiq/vr9_phy22f_a1x.bin
|
||||||
|
+
|
||||||
|
+# GPHY core on Lantiq XWAY VR9 v1.2
|
||||||
|
+lantiq/vr9_phy11g_a2x.bin
|
||||||
|
+lantiq/vr9_phy22f_a2x.bin
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,53 @@
|
||||||
|
From c6feeeb407a3b8a6597ae377ba4dd138e185e3dd Mon Sep 17 00:00:00 2001
|
||||||
|
From: John Crispin <blogic@openwrt.org>
|
||||||
|
Date: Sun, 27 Jul 2014 09:38:50 +0100
|
||||||
|
Subject: [PATCH 26/36] NET: multi phy support
|
||||||
|
|
||||||
|
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||||
|
---
|
||||||
|
drivers/net/phy/phy.c | 9 ++++++---
|
||||||
|
include/linux/phy.h | 1 +
|
||||||
|
2 files changed, 7 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/net/phy/phy.c
|
||||||
|
+++ b/drivers/net/phy/phy.c
|
||||||
|
@@ -819,7 +819,8 @@ void phy_state_machine(struct work_struc
|
||||||
|
/* If the link is down, give up on negotiation for now */
|
||||||
|
if (!phydev->link) {
|
||||||
|
phydev->state = PHY_NOLINK;
|
||||||
|
- netif_carrier_off(phydev->attached_dev);
|
||||||
|
+ if (!phydev->no_auto_carrier_off)
|
||||||
|
+ netif_carrier_off(phydev->attached_dev);
|
||||||
|
phydev->adjust_link(phydev->attached_dev);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
@@ -892,7 +893,8 @@ void phy_state_machine(struct work_struc
|
||||||
|
netif_carrier_on(phydev->attached_dev);
|
||||||
|
} else {
|
||||||
|
phydev->state = PHY_NOLINK;
|
||||||
|
- netif_carrier_off(phydev->attached_dev);
|
||||||
|
+ if (!phydev->no_auto_carrier_off)
|
||||||
|
+ netif_carrier_off(phydev->attached_dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
phydev->adjust_link(phydev->attached_dev);
|
||||||
|
@@ -904,7 +906,8 @@ void phy_state_machine(struct work_struc
|
||||||
|
case PHY_HALTED:
|
||||||
|
if (phydev->link) {
|
||||||
|
phydev->link = 0;
|
||||||
|
- netif_carrier_off(phydev->attached_dev);
|
||||||
|
+ if (!phydev->no_auto_carrier_off)
|
||||||
|
+ netif_carrier_off(phydev->attached_dev);
|
||||||
|
phydev->adjust_link(phydev->attached_dev);
|
||||||
|
do_suspend = true;
|
||||||
|
}
|
||||||
|
--- a/include/linux/phy.h
|
||||||
|
+++ b/include/linux/phy.h
|
||||||
|
@@ -364,6 +364,7 @@ struct phy_device {
|
||||||
|
bool is_c45;
|
||||||
|
bool is_internal;
|
||||||
|
bool has_fixups;
|
||||||
|
+ bool no_auto_carrier_off;
|
||||||
|
|
||||||
|
enum phy_state state;
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
From f393898476aef3e4f49c27725c3d2dd70fca38fe Mon Sep 17 00:00:00 2001
|
||||||
|
From: John Crispin <blogic@openwrt.org>
|
||||||
|
Date: Sun, 27 Jul 2014 09:40:01 +0100
|
||||||
|
Subject: [PATCH 27/36] NET: add of_get_mac_address_mtd()
|
||||||
|
|
||||||
|
Many embedded devices have information such as mac addresses stored inside mtd
|
||||||
|
devices. This patch allows us to add a property inside a node describing a
|
||||||
|
network interface. The new property points at a mtd partition with an offset
|
||||||
|
where the mac address can be found.
|
||||||
|
|
||||||
|
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||||
|
---
|
||||||
|
drivers/of/of_net.c | 37 +++++++++++++++++++++++++++++++++++++
|
||||||
|
include/linux/of_net.h | 1 +
|
||||||
|
2 files changed, 38 insertions(+)
|
||||||
|
|
||||||
|
--- a/drivers/of/of_net.c
|
||||||
|
+++ b/drivers/of/of_net.c
|
||||||
|
@@ -10,6 +10,7 @@
|
||||||
|
#include <linux/of_net.h>
|
||||||
|
#include <linux/phy.h>
|
||||||
|
#include <linux/export.h>
|
||||||
|
+#include <linux/mtd/mtd.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* of_get_phy_mode - Get phy mode for given device_node
|
||||||
|
@@ -75,3 +76,39 @@ const void *of_get_mac_address(struct de
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(of_get_mac_address);
|
||||||
|
+
|
||||||
|
+int of_get_mac_address_mtd(struct device_node *np, void *mac)
|
||||||
|
+{
|
||||||
|
+ struct device_node *mtd_np = NULL;
|
||||||
|
+ size_t retlen;
|
||||||
|
+ int size, ret;
|
||||||
|
+ struct mtd_info *mtd;
|
||||||
|
+ const char *part;
|
||||||
|
+ const __be32 *list;
|
||||||
|
+ phandle phandle;
|
||||||
|
+
|
||||||
|
+ list = of_get_property(np, "mtd-mac-address", &size);
|
||||||
|
+ if (!list || (size != (2 * sizeof(*list))))
|
||||||
|
+ return -ENOENT;
|
||||||
|
+
|
||||||
|
+ phandle = be32_to_cpup(list++);
|
||||||
|
+ if (phandle)
|
||||||
|
+ mtd_np = of_find_node_by_phandle(phandle);
|
||||||
|
+
|
||||||
|
+ if (!mtd_np)
|
||||||
|
+ return -ENOENT;
|
||||||
|
+
|
||||||
|
+ part = of_get_property(mtd_np, "label", NULL);
|
||||||
|
+ if (!part)
|
||||||
|
+ part = mtd_np->name;
|
||||||
|
+
|
||||||
|
+ mtd = get_mtd_device_nm(part);
|
||||||
|
+ if (IS_ERR(mtd))
|
||||||
|
+ return PTR_ERR(mtd);
|
||||||
|
+
|
||||||
|
+ ret = mtd_read(mtd, be32_to_cpup(list), 6, &retlen, (u_char *) mac);
|
||||||
|
+ put_mtd_device(mtd);
|
||||||
|
+
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+EXPORT_SYMBOL_GPL(of_get_mac_address_mtd);
|
||||||
|
--- a/include/linux/of_net.h
|
||||||
|
+++ b/include/linux/of_net.h
|
||||||
|
@@ -11,6 +11,7 @@
|
||||||
|
#include <linux/of.h>
|
||||||
|
extern int of_get_phy_mode(struct device_node *np);
|
||||||
|
extern const void *of_get_mac_address(struct device_node *np);
|
||||||
|
+extern int of_get_mac_address_mtd(struct device_node *np, void *mac);
|
||||||
|
#else
|
||||||
|
static inline int of_get_phy_mode(struct device_node *np)
|
||||||
|
{
|
|
@ -0,0 +1,908 @@
|
||||||
|
From 870ed9cae083ff8a60a739ef7e74c5a1800533be Mon Sep 17 00:00:00 2001
|
||||||
|
From: John Crispin <blogic@openwrt.org>
|
||||||
|
Date: Tue, 9 Sep 2014 22:45:34 +0200
|
||||||
|
Subject: [PATCH 28/36] NET: lantiq: various etop fixes
|
||||||
|
|
||||||
|
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||||
|
---
|
||||||
|
drivers/net/ethernet/lantiq_etop.c | 555 +++++++++++++++++++++++++-----------
|
||||||
|
1 file changed, 389 insertions(+), 166 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/net/ethernet/lantiq_etop.c
|
||||||
|
+++ b/drivers/net/ethernet/lantiq_etop.c
|
||||||
|
@@ -11,7 +11,7 @@
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
- * Copyright (C) 2011 John Crispin <blogic@openwrt.org>
|
||||||
|
+ * Copyright (C) 2011-12 John Crispin <blogic@openwrt.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
@@ -30,11 +30,16 @@
|
||||||
|
#include <linux/mm.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/ethtool.h>
|
||||||
|
+#include <linux/if_vlan.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/delay.h>
|
||||||
|
#include <linux/io.h>
|
||||||
|
#include <linux/dma-mapping.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
+#include <linux/clk.h>
|
||||||
|
+#include <linux/of_net.h>
|
||||||
|
+#include <linux/of_irq.h>
|
||||||
|
+#include <linux/of_platform.h>
|
||||||
|
|
||||||
|
#include <asm/checksum.h>
|
||||||
|
|
||||||
|
@@ -42,7 +47,7 @@
|
||||||
|
#include <xway_dma.h>
|
||||||
|
#include <lantiq_platform.h>
|
||||||
|
|
||||||
|
-#define LTQ_ETOP_MDIO 0x11804
|
||||||
|
+#define LTQ_ETOP_MDIO_ACC 0x11804
|
||||||
|
#define MDIO_REQUEST 0x80000000
|
||||||
|
#define MDIO_READ 0x40000000
|
||||||
|
#define MDIO_ADDR_MASK 0x1f
|
||||||
|
@@ -51,44 +56,91 @@
|
||||||
|
#define MDIO_REG_OFFSET 0x10
|
||||||
|
#define MDIO_VAL_MASK 0xffff
|
||||||
|
|
||||||
|
-#define PPE32_CGEN 0x800
|
||||||
|
-#define LQ_PPE32_ENET_MAC_CFG 0x1840
|
||||||
|
+#define LTQ_ETOP_MDIO_CFG 0x11800
|
||||||
|
+#define MDIO_CFG_MASK 0x6
|
||||||
|
+
|
||||||
|
+#define LTQ_ETOP_CFG 0x11808
|
||||||
|
+#define LTQ_ETOP_IGPLEN 0x11820
|
||||||
|
+#define LTQ_ETOP_MAC_CFG 0x11840
|
||||||
|
|
||||||
|
#define LTQ_ETOP_ENETS0 0x11850
|
||||||
|
#define LTQ_ETOP_MAC_DA0 0x1186C
|
||||||
|
#define LTQ_ETOP_MAC_DA1 0x11870
|
||||||
|
-#define LTQ_ETOP_CFG 0x16020
|
||||||
|
-#define LTQ_ETOP_IGPLEN 0x16080
|
||||||
|
+
|
||||||
|
+#define MAC_CFG_MASK 0xfff
|
||||||
|
+#define MAC_CFG_CGEN (1 << 11)
|
||||||
|
+#define MAC_CFG_DUPLEX (1 << 2)
|
||||||
|
+#define MAC_CFG_SPEED (1 << 1)
|
||||||
|
+#define MAC_CFG_LINK (1 << 0)
|
||||||
|
|
||||||
|
#define MAX_DMA_CHAN 0x8
|
||||||
|
#define MAX_DMA_CRC_LEN 0x4
|
||||||
|
#define MAX_DMA_DATA_LEN 0x600
|
||||||
|
|
||||||
|
#define ETOP_FTCU BIT(28)
|
||||||
|
-#define ETOP_MII_MASK 0xf
|
||||||
|
-#define ETOP_MII_NORMAL 0xd
|
||||||
|
-#define ETOP_MII_REVERSE 0xe
|
||||||
|
#define ETOP_PLEN_UNDER 0x40
|
||||||
|
-#define ETOP_CGEN 0x800
|
||||||
|
+#define ETOP_CFG_MII0 0x01
|
||||||
|
|
||||||
|
-/* use 2 static channels for TX/RX */
|
||||||
|
-#define LTQ_ETOP_TX_CHANNEL 1
|
||||||
|
-#define LTQ_ETOP_RX_CHANNEL 6
|
||||||
|
-#define IS_TX(x) (x == LTQ_ETOP_TX_CHANNEL)
|
||||||
|
-#define IS_RX(x) (x == LTQ_ETOP_RX_CHANNEL)
|
||||||
|
+#define ETOP_CFG_MASK 0xfff
|
||||||
|
+#define ETOP_CFG_FEN0 (1 << 8)
|
||||||
|
+#define ETOP_CFG_SEN0 (1 << 6)
|
||||||
|
+#define ETOP_CFG_OFF1 (1 << 3)
|
||||||
|
+#define ETOP_CFG_REMII0 (1 << 1)
|
||||||
|
+#define ETOP_CFG_OFF0 (1 << 0)
|
||||||
|
+
|
||||||
|
+#define LTQ_GBIT_MDIO_CTL 0xCC
|
||||||
|
+#define LTQ_GBIT_MDIO_DATA 0xd0
|
||||||
|
+#define LTQ_GBIT_GCTL0 0x68
|
||||||
|
+#define LTQ_GBIT_PMAC_HD_CTL 0x8c
|
||||||
|
+#define LTQ_GBIT_P0_CTL 0x4
|
||||||
|
+#define LTQ_GBIT_PMAC_RX_IPG 0xa8
|
||||||
|
+#define LTQ_GBIT_RGMII_CTL 0x78
|
||||||
|
+
|
||||||
|
+#define PMAC_HD_CTL_AS (1 << 19)
|
||||||
|
+#define PMAC_HD_CTL_RXSH (1 << 22)
|
||||||
|
+
|
||||||
|
+/* Switch Enable (0=disable, 1=enable) */
|
||||||
|
+#define GCTL0_SE 0x80000000
|
||||||
|
+/* Disable MDIO auto polling (0=disable, 1=enable) */
|
||||||
|
+#define PX_CTL_DMDIO 0x00400000
|
||||||
|
+
|
||||||
|
+/* MDC clock divider, clock = 25MHz/((MDC_CLOCK + 1) * 2) */
|
||||||
|
+#define MDC_CLOCK_MASK 0xff000000
|
||||||
|
+#define MDC_CLOCK_OFFSET 24
|
||||||
|
+
|
||||||
|
+/* register information for the gbit's MDIO bus */
|
||||||
|
+#define MDIO_XR9_REQUEST 0x00008000
|
||||||
|
+#define MDIO_XR9_READ 0x00000800
|
||||||
|
+#define MDIO_XR9_WRITE 0x00000400
|
||||||
|
+#define MDIO_XR9_REG_MASK 0x1f
|
||||||
|
+#define MDIO_XR9_ADDR_MASK 0x1f
|
||||||
|
+#define MDIO_XR9_RD_MASK 0xffff
|
||||||
|
+#define MDIO_XR9_REG_OFFSET 0
|
||||||
|
+#define MDIO_XR9_ADDR_OFFSET 5
|
||||||
|
+#define MDIO_XR9_WR_OFFSET 16
|
||||||
|
|
||||||
|
+#define LTQ_DMA_ETOP ((of_machine_is_compatible("lantiq,ase")) ? \
|
||||||
|
+ (INT_NUM_IM3_IRL0) : (INT_NUM_IM2_IRL0))
|
||||||
|
+
|
||||||
|
+/* the newer xway socks have a embedded 3/7 port gbit multiplexer */
|
||||||
|
#define ltq_etop_r32(x) ltq_r32(ltq_etop_membase + (x))
|
||||||
|
#define ltq_etop_w32(x, y) ltq_w32(x, ltq_etop_membase + (y))
|
||||||
|
#define ltq_etop_w32_mask(x, y, z) \
|
||||||
|
ltq_w32_mask(x, y, ltq_etop_membase + (z))
|
||||||
|
|
||||||
|
-#define DRV_VERSION "1.0"
|
||||||
|
+#define ltq_gbit_r32(x) ltq_r32(ltq_gbit_membase + (x))
|
||||||
|
+#define ltq_gbit_w32(x, y) ltq_w32(x, ltq_gbit_membase + (y))
|
||||||
|
+#define ltq_gbit_w32_mask(x, y, z) \
|
||||||
|
+ ltq_w32_mask(x, y, ltq_gbit_membase + (z))
|
||||||
|
+
|
||||||
|
+#define DRV_VERSION "1.2"
|
||||||
|
|
||||||
|
static void __iomem *ltq_etop_membase;
|
||||||
|
+static void __iomem *ltq_gbit_membase;
|
||||||
|
|
||||||
|
struct ltq_etop_chan {
|
||||||
|
- int idx;
|
||||||
|
int tx_free;
|
||||||
|
+ int irq;
|
||||||
|
struct net_device *netdev;
|
||||||
|
struct napi_struct napi;
|
||||||
|
struct ltq_dma_channel dma;
|
||||||
|
@@ -98,22 +150,35 @@ struct ltq_etop_chan {
|
||||||
|
struct ltq_etop_priv {
|
||||||
|
struct net_device *netdev;
|
||||||
|
struct platform_device *pdev;
|
||||||
|
- struct ltq_eth_data *pldata;
|
||||||
|
struct resource *res;
|
||||||
|
|
||||||
|
struct mii_bus *mii_bus;
|
||||||
|
struct phy_device *phydev;
|
||||||
|
|
||||||
|
- struct ltq_etop_chan ch[MAX_DMA_CHAN];
|
||||||
|
- int tx_free[MAX_DMA_CHAN >> 1];
|
||||||
|
+ struct ltq_etop_chan txch;
|
||||||
|
+ struct ltq_etop_chan rxch;
|
||||||
|
+
|
||||||
|
+ int tx_irq;
|
||||||
|
+ int rx_irq;
|
||||||
|
+
|
||||||
|
+ const void *mac;
|
||||||
|
+ int mii_mode;
|
||||||
|
|
||||||
|
spinlock_t lock;
|
||||||
|
+
|
||||||
|
+ struct clk *clk_ppe;
|
||||||
|
+ struct clk *clk_switch;
|
||||||
|
+ struct clk *clk_ephy;
|
||||||
|
+ struct clk *clk_ephycgu;
|
||||||
|
};
|
||||||
|
|
||||||
|
+static int ltq_etop_mdio_wr(struct mii_bus *bus, int phy_addr,
|
||||||
|
+ int phy_reg, u16 phy_data);
|
||||||
|
+
|
||||||
|
static int
|
||||||
|
ltq_etop_alloc_skb(struct ltq_etop_chan *ch)
|
||||||
|
{
|
||||||
|
- ch->skb[ch->dma.desc] = netdev_alloc_skb(ch->netdev, MAX_DMA_DATA_LEN);
|
||||||
|
+ ch->skb[ch->dma.desc] = dev_alloc_skb(MAX_DMA_DATA_LEN);
|
||||||
|
if (!ch->skb[ch->dma.desc])
|
||||||
|
return -ENOMEM;
|
||||||
|
ch->dma.desc_base[ch->dma.desc].addr = dma_map_single(NULL,
|
||||||
|
@@ -148,8 +213,11 @@ ltq_etop_hw_receive(struct ltq_etop_chan
|
||||||
|
spin_unlock_irqrestore(&priv->lock, flags);
|
||||||
|
|
||||||
|
skb_put(skb, len);
|
||||||
|
+ skb->dev = ch->netdev;
|
||||||
|
skb->protocol = eth_type_trans(skb, ch->netdev);
|
||||||
|
netif_receive_skb(skb);
|
||||||
|
+ ch->netdev->stats.rx_packets++;
|
||||||
|
+ ch->netdev->stats.rx_bytes += len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
@@ -157,8 +225,10 @@ ltq_etop_poll_rx(struct napi_struct *nap
|
||||||
|
{
|
||||||
|
struct ltq_etop_chan *ch = container_of(napi,
|
||||||
|
struct ltq_etop_chan, napi);
|
||||||
|
+ struct ltq_etop_priv *priv = netdev_priv(ch->netdev);
|
||||||
|
int rx = 0;
|
||||||
|
int complete = 0;
|
||||||
|
+ unsigned long flags;
|
||||||
|
|
||||||
|
while ((rx < budget) && !complete) {
|
||||||
|
struct ltq_dma_desc *desc = &ch->dma.desc_base[ch->dma.desc];
|
||||||
|
@@ -172,7 +242,9 @@ ltq_etop_poll_rx(struct napi_struct *nap
|
||||||
|
}
|
||||||
|
if (complete || !rx) {
|
||||||
|
napi_complete(&ch->napi);
|
||||||
|
+ spin_lock_irqsave(&priv->lock, flags);
|
||||||
|
ltq_dma_ack_irq(&ch->dma);
|
||||||
|
+ spin_unlock_irqrestore(&priv->lock, flags);
|
||||||
|
}
|
||||||
|
return rx;
|
||||||
|
}
|
||||||
|
@@ -184,12 +256,14 @@ ltq_etop_poll_tx(struct napi_struct *nap
|
||||||
|
container_of(napi, struct ltq_etop_chan, napi);
|
||||||
|
struct ltq_etop_priv *priv = netdev_priv(ch->netdev);
|
||||||
|
struct netdev_queue *txq =
|
||||||
|
- netdev_get_tx_queue(ch->netdev, ch->idx >> 1);
|
||||||
|
+ netdev_get_tx_queue(ch->netdev, ch->dma.nr >> 1);
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&priv->lock, flags);
|
||||||
|
while ((ch->dma.desc_base[ch->tx_free].ctl &
|
||||||
|
(LTQ_DMA_OWN | LTQ_DMA_C)) == LTQ_DMA_C) {
|
||||||
|
+ ch->netdev->stats.tx_packets++;
|
||||||
|
+ ch->netdev->stats.tx_bytes += ch->skb[ch->tx_free]->len;
|
||||||
|
dev_kfree_skb_any(ch->skb[ch->tx_free]);
|
||||||
|
ch->skb[ch->tx_free] = NULL;
|
||||||
|
memset(&ch->dma.desc_base[ch->tx_free], 0,
|
||||||
|
@@ -202,7 +276,9 @@ ltq_etop_poll_tx(struct napi_struct *nap
|
||||||
|
if (netif_tx_queue_stopped(txq))
|
||||||
|
netif_tx_start_queue(txq);
|
||||||
|
napi_complete(&ch->napi);
|
||||||
|
+ spin_lock_irqsave(&priv->lock, flags);
|
||||||
|
ltq_dma_ack_irq(&ch->dma);
|
||||||
|
+ spin_unlock_irqrestore(&priv->lock, flags);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -210,9 +286,10 @@ static irqreturn_t
|
||||||
|
ltq_etop_dma_irq(int irq, void *_priv)
|
||||||
|
{
|
||||||
|
struct ltq_etop_priv *priv = _priv;
|
||||||
|
- int ch = irq - LTQ_DMA_CH0_INT;
|
||||||
|
-
|
||||||
|
- napi_schedule(&priv->ch[ch].napi);
|
||||||
|
+ if (irq == priv->txch.dma.irq)
|
||||||
|
+ napi_schedule(&priv->txch.napi);
|
||||||
|
+ else
|
||||||
|
+ napi_schedule(&priv->rxch.napi);
|
||||||
|
return IRQ_HANDLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -224,7 +301,7 @@ ltq_etop_free_channel(struct net_device
|
||||||
|
ltq_dma_free(&ch->dma);
|
||||||
|
if (ch->dma.irq)
|
||||||
|
free_irq(ch->dma.irq, priv);
|
||||||
|
- if (IS_RX(ch->idx)) {
|
||||||
|
+ if (ch == &priv->txch) {
|
||||||
|
int desc;
|
||||||
|
for (desc = 0; desc < LTQ_DESC_NUM; desc++)
|
||||||
|
dev_kfree_skb_any(ch->skb[ch->dma.desc]);
|
||||||
|
@@ -235,65 +312,133 @@ static void
|
||||||
|
ltq_etop_hw_exit(struct net_device *dev)
|
||||||
|
{
|
||||||
|
struct ltq_etop_priv *priv = netdev_priv(dev);
|
||||||
|
- int i;
|
||||||
|
|
||||||
|
- ltq_pmu_disable(PMU_PPE);
|
||||||
|
- for (i = 0; i < MAX_DMA_CHAN; i++)
|
||||||
|
- if (IS_TX(i) || IS_RX(i))
|
||||||
|
- ltq_etop_free_channel(dev, &priv->ch[i]);
|
||||||
|
+ clk_disable(priv->clk_ppe);
|
||||||
|
+
|
||||||
|
+ if (of_machine_is_compatible("lantiq,ar9"))
|
||||||
|
+ clk_disable(priv->clk_switch);
|
||||||
|
+
|
||||||
|
+ if (of_machine_is_compatible("lantiq,ase")) {
|
||||||
|
+ clk_disable(priv->clk_ephy);
|
||||||
|
+ clk_disable(priv->clk_ephycgu);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ltq_etop_free_channel(dev, &priv->txch);
|
||||||
|
+ ltq_etop_free_channel(dev, &priv->rxch);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+ltq_etop_gbit_init(struct net_device *dev)
|
||||||
|
+{
|
||||||
|
+ struct ltq_etop_priv *priv = netdev_priv(dev);
|
||||||
|
+
|
||||||
|
+ clk_enable(priv->clk_switch);
|
||||||
|
+
|
||||||
|
+ /* enable gbit port0 on the SoC */
|
||||||
|
+ ltq_gbit_w32_mask((1 << 17), (1 << 18), LTQ_GBIT_P0_CTL);
|
||||||
|
+
|
||||||
|
+ ltq_gbit_w32_mask(0, GCTL0_SE, LTQ_GBIT_GCTL0);
|
||||||
|
+ /* disable MDIO auto polling mode */
|
||||||
|
+ ltq_gbit_w32_mask(0, PX_CTL_DMDIO, LTQ_GBIT_P0_CTL);
|
||||||
|
+ /* set 1522 packet size */
|
||||||
|
+ ltq_gbit_w32_mask(0x300, 0, LTQ_GBIT_GCTL0);
|
||||||
|
+ /* disable pmac & dmac headers */
|
||||||
|
+ ltq_gbit_w32_mask(PMAC_HD_CTL_AS | PMAC_HD_CTL_RXSH, 0,
|
||||||
|
+ LTQ_GBIT_PMAC_HD_CTL);
|
||||||
|
+ /* Due to traffic halt when burst length 8,
|
||||||
|
+ replace default IPG value with 0x3B */
|
||||||
|
+ ltq_gbit_w32(0x3B, LTQ_GBIT_PMAC_RX_IPG);
|
||||||
|
+ /* set mdc clock to 2.5 MHz */
|
||||||
|
+ ltq_gbit_w32_mask(MDC_CLOCK_MASK, 4 << MDC_CLOCK_OFFSET,
|
||||||
|
+ LTQ_GBIT_RGMII_CTL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
ltq_etop_hw_init(struct net_device *dev)
|
||||||
|
{
|
||||||
|
struct ltq_etop_priv *priv = netdev_priv(dev);
|
||||||
|
- int i;
|
||||||
|
+ int mii_mode = priv->mii_mode;
|
||||||
|
|
||||||
|
- ltq_pmu_enable(PMU_PPE);
|
||||||
|
+ clk_enable(priv->clk_ppe);
|
||||||
|
+
|
||||||
|
+ if (of_machine_is_compatible("lantiq,ar9")) {
|
||||||
|
+ ltq_etop_gbit_init(dev);
|
||||||
|
+ /* force the etops link to the gbit to MII */
|
||||||
|
+ mii_mode = PHY_INTERFACE_MODE_MII;
|
||||||
|
+ }
|
||||||
|
+ ltq_etop_w32_mask(MDIO_CFG_MASK, 0, LTQ_ETOP_MDIO_CFG);
|
||||||
|
+ ltq_etop_w32_mask(MAC_CFG_MASK, MAC_CFG_CGEN | MAC_CFG_DUPLEX |
|
||||||
|
+ MAC_CFG_SPEED | MAC_CFG_LINK, LTQ_ETOP_MAC_CFG);
|
||||||
|
|
||||||
|
- switch (priv->pldata->mii_mode) {
|
||||||
|
+ switch (mii_mode) {
|
||||||
|
case PHY_INTERFACE_MODE_RMII:
|
||||||
|
- ltq_etop_w32_mask(ETOP_MII_MASK,
|
||||||
|
- ETOP_MII_REVERSE, LTQ_ETOP_CFG);
|
||||||
|
+ ltq_etop_w32_mask(ETOP_CFG_MASK, ETOP_CFG_REMII0 | ETOP_CFG_OFF1 |
|
||||||
|
+ ETOP_CFG_SEN0 | ETOP_CFG_FEN0, LTQ_ETOP_CFG);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PHY_INTERFACE_MODE_MII:
|
||||||
|
- ltq_etop_w32_mask(ETOP_MII_MASK,
|
||||||
|
- ETOP_MII_NORMAL, LTQ_ETOP_CFG);
|
||||||
|
+ ltq_etop_w32_mask(ETOP_CFG_MASK, ETOP_CFG_OFF1 |
|
||||||
|
+ ETOP_CFG_SEN0 | ETOP_CFG_FEN0, LTQ_ETOP_CFG);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
+ if (of_machine_is_compatible("lantiq,ase")) {
|
||||||
|
+ clk_enable(priv->clk_ephy);
|
||||||
|
+ /* disable external MII */
|
||||||
|
+ ltq_etop_w32_mask(0, ETOP_CFG_MII0, LTQ_ETOP_CFG);
|
||||||
|
+ /* enable clock for internal PHY */
|
||||||
|
+ clk_enable(priv->clk_ephycgu);
|
||||||
|
+ /* we need to write this magic to the internal phy to
|
||||||
|
+ make it work */
|
||||||
|
+ ltq_etop_mdio_wr(NULL, 0x8, 0x12, 0xC020);
|
||||||
|
+ pr_info("Selected EPHY mode\n");
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
netdev_err(dev, "unknown mii mode %d\n",
|
||||||
|
- priv->pldata->mii_mode);
|
||||||
|
+ mii_mode);
|
||||||
|
return -ENOTSUPP;
|
||||||
|
}
|
||||||
|
|
||||||
|
- /* enable crc generation */
|
||||||
|
- ltq_etop_w32(PPE32_CGEN, LQ_PPE32_ENET_MAC_CFG);
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+ltq_etop_dma_init(struct net_device *dev)
|
||||||
|
+{
|
||||||
|
+ struct ltq_etop_priv *priv = netdev_priv(dev);
|
||||||
|
+ int tx = priv->tx_irq - LTQ_DMA_ETOP;
|
||||||
|
+ int rx = priv->rx_irq - LTQ_DMA_ETOP;
|
||||||
|
+ int err;
|
||||||
|
|
||||||
|
ltq_dma_init_port(DMA_PORT_ETOP);
|
||||||
|
|
||||||
|
- for (i = 0; i < MAX_DMA_CHAN; i++) {
|
||||||
|
- int irq = LTQ_DMA_CH0_INT + i;
|
||||||
|
- struct ltq_etop_chan *ch = &priv->ch[i];
|
||||||
|
-
|
||||||
|
- ch->idx = ch->dma.nr = i;
|
||||||
|
-
|
||||||
|
- if (IS_TX(i)) {
|
||||||
|
- ltq_dma_alloc_tx(&ch->dma);
|
||||||
|
- request_irq(irq, ltq_etop_dma_irq, 0, "etop_tx", priv);
|
||||||
|
- } else if (IS_RX(i)) {
|
||||||
|
- ltq_dma_alloc_rx(&ch->dma);
|
||||||
|
- for (ch->dma.desc = 0; ch->dma.desc < LTQ_DESC_NUM;
|
||||||
|
- ch->dma.desc++)
|
||||||
|
- if (ltq_etop_alloc_skb(ch))
|
||||||
|
- return -ENOMEM;
|
||||||
|
- ch->dma.desc = 0;
|
||||||
|
- request_irq(irq, ltq_etop_dma_irq, 0, "etop_rx", priv);
|
||||||
|
+ priv->txch.dma.nr = tx;
|
||||||
|
+ ltq_dma_alloc_tx(&priv->txch.dma);
|
||||||
|
+ err = request_irq(priv->tx_irq, ltq_etop_dma_irq, 0, "eth_tx", priv);
|
||||||
|
+ if (err) {
|
||||||
|
+ netdev_err(dev, "failed to allocate tx irq\n");
|
||||||
|
+ goto err_out;
|
||||||
|
+ }
|
||||||
|
+ priv->txch.dma.irq = priv->tx_irq;
|
||||||
|
+
|
||||||
|
+ priv->rxch.dma.nr = rx;
|
||||||
|
+ ltq_dma_alloc_rx(&priv->rxch.dma);
|
||||||
|
+ for (priv->rxch.dma.desc = 0; priv->rxch.dma.desc < LTQ_DESC_NUM;
|
||||||
|
+ priv->rxch.dma.desc++) {
|
||||||
|
+ if (ltq_etop_alloc_skb(&priv->rxch)) {
|
||||||
|
+ netdev_err(dev, "failed to allocate skbs\n");
|
||||||
|
+ err = -ENOMEM;
|
||||||
|
+ goto err_out;
|
||||||
|
}
|
||||||
|
- ch->dma.irq = irq;
|
||||||
|
}
|
||||||
|
- return 0;
|
||||||
|
+ priv->rxch.dma.desc = 0;
|
||||||
|
+ err = request_irq(priv->rx_irq, ltq_etop_dma_irq, 0, "eth_rx", priv);
|
||||||
|
+ if (err)
|
||||||
|
+ netdev_err(dev, "failed to allocate rx irq\n");
|
||||||
|
+ else
|
||||||
|
+ priv->rxch.dma.irq = priv->rx_irq;
|
||||||
|
+err_out:
|
||||||
|
+ return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
@@ -309,7 +454,10 @@ ltq_etop_get_settings(struct net_device
|
||||||
|
{
|
||||||
|
struct ltq_etop_priv *priv = netdev_priv(dev);
|
||||||
|
|
||||||
|
- return phy_ethtool_gset(priv->phydev, cmd);
|
||||||
|
+ if (priv->phydev)
|
||||||
|
+ return phy_ethtool_gset(priv->phydev, cmd);
|
||||||
|
+ else
|
||||||
|
+ return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
@@ -317,7 +465,10 @@ ltq_etop_set_settings(struct net_device
|
||||||
|
{
|
||||||
|
struct ltq_etop_priv *priv = netdev_priv(dev);
|
||||||
|
|
||||||
|
- return phy_ethtool_sset(priv->phydev, cmd);
|
||||||
|
+ if (priv->phydev)
|
||||||
|
+ return phy_ethtool_sset(priv->phydev, cmd);
|
||||||
|
+ else
|
||||||
|
+ return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
@@ -325,7 +476,10 @@ ltq_etop_nway_reset(struct net_device *d
|
||||||
|
{
|
||||||
|
struct ltq_etop_priv *priv = netdev_priv(dev);
|
||||||
|
|
||||||
|
- return phy_start_aneg(priv->phydev);
|
||||||
|
+ if (priv->phydev)
|
||||||
|
+ return phy_start_aneg(priv->phydev);
|
||||||
|
+ else
|
||||||
|
+ return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct ethtool_ops ltq_etop_ethtool_ops = {
|
||||||
|
@@ -336,6 +490,39 @@ static const struct ethtool_ops ltq_etop
|
||||||
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
+ltq_etop_mdio_wr_xr9(struct mii_bus *bus, int phy_addr,
|
||||||
|
+ int phy_reg, u16 phy_data)
|
||||||
|
+{
|
||||||
|
+ u32 val = MDIO_XR9_REQUEST | MDIO_XR9_WRITE |
|
||||||
|
+ (phy_data << MDIO_XR9_WR_OFFSET) |
|
||||||
|
+ ((phy_addr & MDIO_XR9_ADDR_MASK) << MDIO_XR9_ADDR_OFFSET) |
|
||||||
|
+ ((phy_reg & MDIO_XR9_REG_MASK) << MDIO_XR9_REG_OFFSET);
|
||||||
|
+
|
||||||
|
+ while (ltq_gbit_r32(LTQ_GBIT_MDIO_CTL) & MDIO_XR9_REQUEST)
|
||||||
|
+ ;
|
||||||
|
+ ltq_gbit_w32(val, LTQ_GBIT_MDIO_CTL);
|
||||||
|
+ while (ltq_gbit_r32(LTQ_GBIT_MDIO_CTL) & MDIO_XR9_REQUEST)
|
||||||
|
+ ;
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+ltq_etop_mdio_rd_xr9(struct mii_bus *bus, int phy_addr, int phy_reg)
|
||||||
|
+{
|
||||||
|
+ u32 val = MDIO_XR9_REQUEST | MDIO_XR9_READ |
|
||||||
|
+ ((phy_addr & MDIO_XR9_ADDR_MASK) << MDIO_XR9_ADDR_OFFSET) |
|
||||||
|
+ ((phy_reg & MDIO_XR9_REG_MASK) << MDIO_XR9_REG_OFFSET);
|
||||||
|
+
|
||||||
|
+ while (ltq_gbit_r32(LTQ_GBIT_MDIO_CTL) & MDIO_XR9_REQUEST)
|
||||||
|
+ ;
|
||||||
|
+ ltq_gbit_w32(val, LTQ_GBIT_MDIO_CTL);
|
||||||
|
+ while (ltq_gbit_r32(LTQ_GBIT_MDIO_CTL) & MDIO_XR9_REQUEST)
|
||||||
|
+ ;
|
||||||
|
+ val = ltq_gbit_r32(LTQ_GBIT_MDIO_DATA) & MDIO_XR9_RD_MASK;
|
||||||
|
+ return val;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
ltq_etop_mdio_wr(struct mii_bus *bus, int phy_addr, int phy_reg, u16 phy_data)
|
||||||
|
{
|
||||||
|
u32 val = MDIO_REQUEST |
|
||||||
|
@@ -343,9 +530,9 @@ ltq_etop_mdio_wr(struct mii_bus *bus, in
|
||||||
|
((phy_reg & MDIO_REG_MASK) << MDIO_REG_OFFSET) |
|
||||||
|
phy_data;
|
||||||
|
|
||||||
|
- while (ltq_etop_r32(LTQ_ETOP_MDIO) & MDIO_REQUEST)
|
||||||
|
+ while (ltq_etop_r32(LTQ_ETOP_MDIO_ACC) & MDIO_REQUEST)
|
||||||
|
;
|
||||||
|
- ltq_etop_w32(val, LTQ_ETOP_MDIO);
|
||||||
|
+ ltq_etop_w32(val, LTQ_ETOP_MDIO_ACC);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -356,12 +543,12 @@ ltq_etop_mdio_rd(struct mii_bus *bus, in
|
||||||
|
((phy_addr & MDIO_ADDR_MASK) << MDIO_ADDR_OFFSET) |
|
||||||
|
((phy_reg & MDIO_REG_MASK) << MDIO_REG_OFFSET);
|
||||||
|
|
||||||
|
- while (ltq_etop_r32(LTQ_ETOP_MDIO) & MDIO_REQUEST)
|
||||||
|
+ while (ltq_etop_r32(LTQ_ETOP_MDIO_ACC) & MDIO_REQUEST)
|
||||||
|
;
|
||||||
|
- ltq_etop_w32(val, LTQ_ETOP_MDIO);
|
||||||
|
- while (ltq_etop_r32(LTQ_ETOP_MDIO) & MDIO_REQUEST)
|
||||||
|
+ ltq_etop_w32(val, LTQ_ETOP_MDIO_ACC);
|
||||||
|
+ while (ltq_etop_r32(LTQ_ETOP_MDIO_ACC) & MDIO_REQUEST)
|
||||||
|
;
|
||||||
|
- val = ltq_etop_r32(LTQ_ETOP_MDIO) & MDIO_VAL_MASK;
|
||||||
|
+ val = ltq_etop_r32(LTQ_ETOP_MDIO_ACC) & MDIO_VAL_MASK;
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -376,14 +563,18 @@ ltq_etop_mdio_probe(struct net_device *d
|
||||||
|
{
|
||||||
|
struct ltq_etop_priv *priv = netdev_priv(dev);
|
||||||
|
struct phy_device *phydev = NULL;
|
||||||
|
- int phy_addr;
|
||||||
|
+ u32 phy_supported = (SUPPORTED_10baseT_Half
|
||||||
|
+ | SUPPORTED_10baseT_Full
|
||||||
|
+ | SUPPORTED_100baseT_Half
|
||||||
|
+ | SUPPORTED_100baseT_Full
|
||||||
|
+ | SUPPORTED_Autoneg
|
||||||
|
+ | SUPPORTED_MII
|
||||||
|
+ | SUPPORTED_TP);
|
||||||
|
|
||||||
|
- 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;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
+ if (of_machine_is_compatible("lantiq,ase"))
|
||||||
|
+ phydev = priv->mii_bus->phy_map[8];
|
||||||
|
+ else
|
||||||
|
+ phydev = priv->mii_bus->phy_map[0];
|
||||||
|
|
||||||
|
if (!phydev) {
|
||||||
|
netdev_err(dev, "no PHY found\n");
|
||||||
|
@@ -391,21 +582,18 @@ ltq_etop_mdio_probe(struct net_device *d
|
||||||
|
}
|
||||||
|
|
||||||
|
phydev = phy_connect(dev, dev_name(&phydev->dev),
|
||||||
|
- <q_etop_mdio_link, priv->pldata->mii_mode);
|
||||||
|
+ <q_etop_mdio_link, priv->mii_mode);
|
||||||
|
|
||||||
|
if (IS_ERR(phydev)) {
|
||||||
|
netdev_err(dev, "Could not attach to PHY\n");
|
||||||
|
return PTR_ERR(phydev);
|
||||||
|
}
|
||||||
|
|
||||||
|
- phydev->supported &= (SUPPORTED_10baseT_Half
|
||||||
|
- | SUPPORTED_10baseT_Full
|
||||||
|
- | SUPPORTED_100baseT_Half
|
||||||
|
- | SUPPORTED_100baseT_Full
|
||||||
|
- | SUPPORTED_Autoneg
|
||||||
|
- | SUPPORTED_MII
|
||||||
|
- | SUPPORTED_TP);
|
||||||
|
+ if (of_machine_is_compatible("lantiq,ar9"))
|
||||||
|
+ phy_supported |= SUPPORTED_1000baseT_Half
|
||||||
|
+ | SUPPORTED_1000baseT_Full;
|
||||||
|
|
||||||
|
+ phydev->supported &= phy_supported;
|
||||||
|
phydev->advertising = phydev->supported;
|
||||||
|
priv->phydev = phydev;
|
||||||
|
pr_info("%s: attached PHY [%s] (phy_addr=%s, irq=%d)\n",
|
||||||
|
@@ -430,8 +618,13 @@ ltq_etop_mdio_init(struct net_device *de
|
||||||
|
}
|
||||||
|
|
||||||
|
priv->mii_bus->priv = dev;
|
||||||
|
- priv->mii_bus->read = ltq_etop_mdio_rd;
|
||||||
|
- priv->mii_bus->write = ltq_etop_mdio_wr;
|
||||||
|
+ if (of_machine_is_compatible("lantiq,ar9")) {
|
||||||
|
+ priv->mii_bus->read = ltq_etop_mdio_rd_xr9;
|
||||||
|
+ priv->mii_bus->write = ltq_etop_mdio_wr_xr9;
|
||||||
|
+ } else {
|
||||||
|
+ priv->mii_bus->read = ltq_etop_mdio_rd;
|
||||||
|
+ priv->mii_bus->write = ltq_etop_mdio_wr;
|
||||||
|
+ }
|
||||||
|
priv->mii_bus->name = "ltq_mii";
|
||||||
|
snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
|
||||||
|
priv->pdev->name, priv->pdev->id);
|
||||||
|
@@ -480,17 +673,19 @@ static int
|
||||||
|
ltq_etop_open(struct net_device *dev)
|
||||||
|
{
|
||||||
|
struct ltq_etop_priv *priv = netdev_priv(dev);
|
||||||
|
- int i;
|
||||||
|
+ unsigned long flags;
|
||||||
|
|
||||||
|
- for (i = 0; i < MAX_DMA_CHAN; i++) {
|
||||||
|
- struct ltq_etop_chan *ch = &priv->ch[i];
|
||||||
|
+ napi_enable(&priv->txch.napi);
|
||||||
|
+ napi_enable(&priv->rxch.napi);
|
||||||
|
+
|
||||||
|
+ spin_lock_irqsave(&priv->lock, flags);
|
||||||
|
+ ltq_dma_open(&priv->txch.dma);
|
||||||
|
+ ltq_dma_open(&priv->rxch.dma);
|
||||||
|
+ spin_unlock_irqrestore(&priv->lock, flags);
|
||||||
|
+
|
||||||
|
+ if (priv->phydev)
|
||||||
|
+ phy_start(priv->phydev);
|
||||||
|
|
||||||
|
- if (!IS_TX(i) && (!IS_RX(i)))
|
||||||
|
- continue;
|
||||||
|
- ltq_dma_open(&ch->dma);
|
||||||
|
- napi_enable(&ch->napi);
|
||||||
|
- }
|
||||||
|
- phy_start(priv->phydev);
|
||||||
|
netif_tx_start_all_queues(dev);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@@ -499,18 +694,19 @@ static int
|
||||||
|
ltq_etop_stop(struct net_device *dev)
|
||||||
|
{
|
||||||
|
struct ltq_etop_priv *priv = netdev_priv(dev);
|
||||||
|
- int i;
|
||||||
|
+ unsigned long flags;
|
||||||
|
|
||||||
|
netif_tx_stop_all_queues(dev);
|
||||||
|
- phy_stop(priv->phydev);
|
||||||
|
- for (i = 0; i < MAX_DMA_CHAN; i++) {
|
||||||
|
- struct ltq_etop_chan *ch = &priv->ch[i];
|
||||||
|
-
|
||||||
|
- if (!IS_RX(i) && !IS_TX(i))
|
||||||
|
- continue;
|
||||||
|
- napi_disable(&ch->napi);
|
||||||
|
- ltq_dma_close(&ch->dma);
|
||||||
|
- }
|
||||||
|
+ if (priv->phydev)
|
||||||
|
+ phy_stop(priv->phydev);
|
||||||
|
+ napi_disable(&priv->txch.napi);
|
||||||
|
+ napi_disable(&priv->rxch.napi);
|
||||||
|
+
|
||||||
|
+ spin_lock_irqsave(&priv->lock, flags);
|
||||||
|
+ ltq_dma_close(&priv->txch.dma);
|
||||||
|
+ ltq_dma_close(&priv->rxch.dma);
|
||||||
|
+ spin_unlock_irqrestore(&priv->lock, flags);
|
||||||
|
+
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -520,16 +716,16 @@ ltq_etop_tx(struct sk_buff *skb, struct
|
||||||
|
int queue = skb_get_queue_mapping(skb);
|
||||||
|
struct netdev_queue *txq = netdev_get_tx_queue(dev, queue);
|
||||||
|
struct ltq_etop_priv *priv = netdev_priv(dev);
|
||||||
|
- struct ltq_etop_chan *ch = &priv->ch[(queue << 1) | 1];
|
||||||
|
- struct ltq_dma_desc *desc = &ch->dma.desc_base[ch->dma.desc];
|
||||||
|
- int len;
|
||||||
|
+ struct ltq_dma_desc *desc =
|
||||||
|
+ &priv->txch.dma.desc_base[priv->txch.dma.desc];
|
||||||
|
unsigned long flags;
|
||||||
|
u32 byte_offset;
|
||||||
|
+ int len;
|
||||||
|
|
||||||
|
len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len;
|
||||||
|
|
||||||
|
- if ((desc->ctl & (LTQ_DMA_OWN | LTQ_DMA_C)) || ch->skb[ch->dma.desc]) {
|
||||||
|
- dev_kfree_skb_any(skb);
|
||||||
|
+ if ((desc->ctl & (LTQ_DMA_OWN | LTQ_DMA_C)) ||
|
||||||
|
+ priv->txch.skb[priv->txch.dma.desc]) {
|
||||||
|
netdev_err(dev, "tx ring full\n");
|
||||||
|
netif_tx_stop_queue(txq);
|
||||||
|
return NETDEV_TX_BUSY;
|
||||||
|
@@ -537,7 +733,7 @@ ltq_etop_tx(struct sk_buff *skb, struct
|
||||||
|
|
||||||
|
/* dma needs to start on a 16 byte aligned address */
|
||||||
|
byte_offset = CPHYSADDR(skb->data) % 16;
|
||||||
|
- ch->skb[ch->dma.desc] = skb;
|
||||||
|
+ priv->txch.skb[priv->txch.dma.desc] = skb;
|
||||||
|
|
||||||
|
dev->trans_start = jiffies;
|
||||||
|
|
||||||
|
@@ -547,11 +743,11 @@ ltq_etop_tx(struct sk_buff *skb, struct
|
||||||
|
wmb();
|
||||||
|
desc->ctl = LTQ_DMA_OWN | LTQ_DMA_SOP | LTQ_DMA_EOP |
|
||||||
|
LTQ_DMA_TX_OFFSET(byte_offset) | (len & LTQ_DMA_SIZE_MASK);
|
||||||
|
- ch->dma.desc++;
|
||||||
|
- ch->dma.desc %= LTQ_DESC_NUM;
|
||||||
|
+ priv->txch.dma.desc++;
|
||||||
|
+ priv->txch.dma.desc %= LTQ_DESC_NUM;
|
||||||
|
spin_unlock_irqrestore(&priv->lock, flags);
|
||||||
|
|
||||||
|
- if (ch->dma.desc_base[ch->dma.desc].ctl & LTQ_DMA_OWN)
|
||||||
|
+ if (priv->txch.dma.desc_base[priv->txch.dma.desc].ctl & LTQ_DMA_OWN)
|
||||||
|
netif_tx_stop_queue(txq);
|
||||||
|
|
||||||
|
return NETDEV_TX_OK;
|
||||||
|
@@ -566,8 +762,10 @@ ltq_etop_change_mtu(struct net_device *d
|
||||||
|
struct ltq_etop_priv *priv = netdev_priv(dev);
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
+ int max = ETH_HLEN + VLAN_HLEN + new_mtu + ETH_FCS_LEN;
|
||||||
|
+
|
||||||
|
spin_lock_irqsave(&priv->lock, flags);
|
||||||
|
- ltq_etop_w32((ETOP_PLEN_UNDER << 16) | new_mtu,
|
||||||
|
+ ltq_etop_w32((ETOP_PLEN_UNDER << 16) | max,
|
||||||
|
LTQ_ETOP_IGPLEN);
|
||||||
|
spin_unlock_irqrestore(&priv->lock, flags);
|
||||||
|
}
|
||||||
|
@@ -638,6 +836,9 @@ ltq_etop_init(struct net_device *dev)
|
||||||
|
if (err)
|
||||||
|
goto err_hw;
|
||||||
|
ltq_etop_change_mtu(dev, 1500);
|
||||||
|
+ err = ltq_etop_dma_init(dev);
|
||||||
|
+ if (err)
|
||||||
|
+ goto err_hw;
|
||||||
|
|
||||||
|
memcpy(&mac, &priv->pldata->mac, sizeof(struct sockaddr));
|
||||||
|
if (!is_valid_ether_addr(mac.sa_data)) {
|
||||||
|
@@ -655,9 +856,10 @@ ltq_etop_init(struct net_device *dev)
|
||||||
|
dev->addr_assign_type = NET_ADDR_RANDOM;
|
||||||
|
|
||||||
|
ltq_etop_set_multicast_list(dev);
|
||||||
|
- err = ltq_etop_mdio_init(dev);
|
||||||
|
- if (err)
|
||||||
|
- goto err_netdev;
|
||||||
|
+ if (!ltq_etop_mdio_init(dev))
|
||||||
|
+ dev->ethtool_ops = <q_etop_ethtool_ops;
|
||||||
|
+ else
|
||||||
|
+ pr_warn("etop: mdio probe failed\n");;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err_netdev:
|
||||||
|
@@ -677,6 +879,9 @@ ltq_etop_tx_timeout(struct net_device *d
|
||||||
|
err = ltq_etop_hw_init(dev);
|
||||||
|
if (err)
|
||||||
|
goto err_hw;
|
||||||
|
+ err = ltq_etop_dma_init(dev);
|
||||||
|
+ if (err)
|
||||||
|
+ goto err_hw;
|
||||||
|
dev->trans_start = jiffies;
|
||||||
|
netif_wake_queue(dev);
|
||||||
|
return;
|
||||||
|
@@ -700,14 +905,18 @@ static const struct net_device_ops ltq_e
|
||||||
|
.ndo_tx_timeout = ltq_etop_tx_timeout,
|
||||||
|
};
|
||||||
|
|
||||||
|
-static int __init
|
||||||
|
-ltq_etop_probe(struct platform_device *pdev)
|
||||||
|
+static int ltq_etop_probe(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct net_device *dev;
|
||||||
|
struct ltq_etop_priv *priv;
|
||||||
|
- struct resource *res;
|
||||||
|
+ struct resource *res, *gbit_res, irqres[2];
|
||||||
|
int err;
|
||||||
|
- int i;
|
||||||
|
+
|
||||||
|
+ err = of_irq_to_resource_table(pdev->dev.of_node, irqres, 2);
|
||||||
|
+ if (err != 2) {
|
||||||
|
+ dev_err(&pdev->dev, "failed to get etop irqs\n");
|
||||||
|
+ return -EINVAL;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
|
if (!res) {
|
||||||
|
@@ -733,30 +942,58 @@ ltq_etop_probe(struct platform_device *p
|
||||||
|
goto err_out;
|
||||||
|
}
|
||||||
|
|
||||||
|
- dev = alloc_etherdev_mq(sizeof(struct ltq_etop_priv), 4);
|
||||||
|
- if (!dev) {
|
||||||
|
- err = -ENOMEM;
|
||||||
|
- goto err_out;
|
||||||
|
+ if (of_machine_is_compatible("lantiq,ar9")) {
|
||||||
|
+ gbit_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
|
||||||
|
+ if (!gbit_res) {
|
||||||
|
+ dev_err(&pdev->dev, "failed to get gbit resource\n");
|
||||||
|
+ err = -ENOENT;
|
||||||
|
+ goto err_out;
|
||||||
|
+ }
|
||||||
|
+ ltq_gbit_membase = devm_ioremap_nocache(&pdev->dev,
|
||||||
|
+ gbit_res->start, resource_size(gbit_res));
|
||||||
|
+ if (!ltq_gbit_membase) {
|
||||||
|
+ dev_err(&pdev->dev, "failed to remap gigabit switch %d\n",
|
||||||
|
+ pdev->id);
|
||||||
|
+ err = -ENOMEM;
|
||||||
|
+ goto err_out;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ dev = alloc_etherdev_mq(sizeof(struct ltq_etop_priv), 4);
|
||||||
|
strcpy(dev->name, "eth%d");
|
||||||
|
dev->netdev_ops = <q_eth_netdev_ops;
|
||||||
|
- dev->ethtool_ops = <q_etop_ethtool_ops;
|
||||||
|
priv = netdev_priv(dev);
|
||||||
|
priv->res = res;
|
||||||
|
priv->pdev = pdev;
|
||||||
|
- priv->pldata = dev_get_platdata(&pdev->dev);
|
||||||
|
priv->netdev = dev;
|
||||||
|
+ priv->tx_irq = irqres[0].start;
|
||||||
|
+ priv->rx_irq = irqres[1].start;
|
||||||
|
+ priv->mii_mode = of_get_phy_mode(pdev->dev.of_node);
|
||||||
|
+ of_get_mac_address_mtd(pdev->dev.of_node, priv->mac);
|
||||||
|
+
|
||||||
|
+ priv->clk_ppe = clk_get(&pdev->dev, NULL);
|
||||||
|
+ if (IS_ERR(priv->clk_ppe))
|
||||||
|
+ return PTR_ERR(priv->clk_ppe);
|
||||||
|
+ if (of_machine_is_compatible("lantiq,ar9")) {
|
||||||
|
+ priv->clk_switch = clk_get(&pdev->dev, "switch");
|
||||||
|
+ if (IS_ERR(priv->clk_switch))
|
||||||
|
+ return PTR_ERR(priv->clk_switch);
|
||||||
|
+ }
|
||||||
|
+ if (of_machine_is_compatible("lantiq,ase")) {
|
||||||
|
+ priv->clk_ephy = clk_get(&pdev->dev, "ephy");
|
||||||
|
+ if (IS_ERR(priv->clk_ephy))
|
||||||
|
+ return PTR_ERR(priv->clk_ephy);
|
||||||
|
+ priv->clk_ephycgu = clk_get(&pdev->dev, "ephycgu");
|
||||||
|
+ if (IS_ERR(priv->clk_ephycgu))
|
||||||
|
+ return PTR_ERR(priv->clk_ephycgu);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
spin_lock_init(&priv->lock);
|
||||||
|
|
||||||
|
- for (i = 0; i < MAX_DMA_CHAN; i++) {
|
||||||
|
- if (IS_TX(i))
|
||||||
|
- netif_napi_add(dev, &priv->ch[i].napi,
|
||||||
|
- ltq_etop_poll_tx, 8);
|
||||||
|
- else if (IS_RX(i))
|
||||||
|
- netif_napi_add(dev, &priv->ch[i].napi,
|
||||||
|
- ltq_etop_poll_rx, 32);
|
||||||
|
- priv->ch[i].netdev = dev;
|
||||||
|
- }
|
||||||
|
+ netif_napi_add(dev, &priv->txch.napi, ltq_etop_poll_tx, 8);
|
||||||
|
+ netif_napi_add(dev, &priv->rxch.napi, ltq_etop_poll_rx, 32);
|
||||||
|
+ priv->txch.netdev = dev;
|
||||||
|
+ priv->rxch.netdev = dev;
|
||||||
|
|
||||||
|
err = register_netdev(dev);
|
||||||
|
if (err)
|
||||||
|
@@ -785,32 +1022,23 @@ ltq_etop_remove(struct platform_device *
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static const struct of_device_id ltq_etop_match[] = {
|
||||||
|
+ { .compatible = "lantiq,etop-xway" },
|
||||||
|
+ {},
|
||||||
|
+};
|
||||||
|
+MODULE_DEVICE_TABLE(of, ltq_etop_match);
|
||||||
|
+
|
||||||
|
static struct platform_driver ltq_mii_driver = {
|
||||||
|
+ .probe = ltq_etop_probe,
|
||||||
|
.remove = ltq_etop_remove,
|
||||||
|
.driver = {
|
||||||
|
.name = "ltq_etop",
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
+ .of_match_table = ltq_etop_match,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
-int __init
|
||||||
|
-init_ltq_etop(void)
|
||||||
|
-{
|
||||||
|
- int ret = platform_driver_probe(<q_mii_driver, ltq_etop_probe);
|
||||||
|
-
|
||||||
|
- if (ret)
|
||||||
|
- pr_err("ltq_etop: Error registering platform driver!");
|
||||||
|
- return ret;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-static void __exit
|
||||||
|
-exit_ltq_etop(void)
|
||||||
|
-{
|
||||||
|
- platform_driver_unregister(<q_mii_driver);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-module_init(init_ltq_etop);
|
||||||
|
-module_exit(exit_ltq_etop);
|
||||||
|
+module_platform_driver(ltq_mii_driver);
|
||||||
|
|
||||||
|
MODULE_AUTHOR("John Crispin <blogic@openwrt.org>");
|
||||||
|
MODULE_DESCRIPTION("Lantiq SoC ETOP");
|
|
@ -0,0 +1,166 @@
|
||||||
|
From cc809a441d8f2924f785eb863dfa6aef47a25b0b Mon Sep 17 00:00:00 2001
|
||||||
|
From: John Crispin <blogic@openwrt.org>
|
||||||
|
Date: Tue, 12 Aug 2014 20:49:27 +0200
|
||||||
|
Subject: [PATCH 30/36] GPIO: add named gpio exports
|
||||||
|
|
||||||
|
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||||
|
---
|
||||||
|
drivers/gpio/gpiolib-of.c | 68 +++++++++++++++++++++++++++++++++++++++++
|
||||||
|
drivers/gpio/gpiolib.c | 11 +++++--
|
||||||
|
include/asm-generic/gpio.h | 5 +++
|
||||||
|
include/linux/gpio/consumer.h | 8 +++++
|
||||||
|
4 files changed, 90 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/gpio/gpiolib-of.c
|
||||||
|
+++ b/drivers/gpio/gpiolib-of.c
|
||||||
|
@@ -22,6 +22,8 @@
|
||||||
|
#include <linux/of_gpio.h>
|
||||||
|
#include <linux/pinctrl/pinctrl.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
+#include <linux/init.h>
|
||||||
|
+#include <linux/platform_device.h>
|
||||||
|
|
||||||
|
#include "gpiolib.h"
|
||||||
|
|
||||||
|
@@ -315,3 +317,69 @@ void of_gpiochip_remove(struct gpio_chip
|
||||||
|
gpiochip_remove_pin_ranges(chip);
|
||||||
|
of_node_put(chip->of_node);
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+static struct of_device_id gpio_export_ids[] = {
|
||||||
|
+ { .compatible = "gpio-export" },
|
||||||
|
+ { /* sentinel */ }
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static int __init of_gpio_export_probe(struct platform_device *pdev)
|
||||||
|
+{
|
||||||
|
+ struct device_node *np = pdev->dev.of_node;
|
||||||
|
+ struct device_node *cnp;
|
||||||
|
+ u32 val;
|
||||||
|
+ int nb = 0;
|
||||||
|
+
|
||||||
|
+ for_each_child_of_node(np, cnp) {
|
||||||
|
+ const char *name = NULL;
|
||||||
|
+ int gpio;
|
||||||
|
+ bool dmc;
|
||||||
|
+ int max_gpio = 1;
|
||||||
|
+ int i;
|
||||||
|
+
|
||||||
|
+ of_property_read_string(cnp, "gpio-export,name", &name);
|
||||||
|
+
|
||||||
|
+ if (!name)
|
||||||
|
+ max_gpio = of_gpio_count(cnp);
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < max_gpio; i++) {
|
||||||
|
+ unsigned flags = 0;
|
||||||
|
+ enum of_gpio_flags of_flags;
|
||||||
|
+
|
||||||
|
+ gpio = of_get_gpio_flags(cnp, i, &of_flags);
|
||||||
|
+
|
||||||
|
+ if (of_flags == OF_GPIO_ACTIVE_LOW)
|
||||||
|
+ flags |= GPIOF_ACTIVE_LOW;
|
||||||
|
+
|
||||||
|
+ if (!of_property_read_u32(cnp, "gpio-export,output", &val))
|
||||||
|
+ flags |= val ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
|
||||||
|
+ else
|
||||||
|
+ flags |= GPIOF_IN;
|
||||||
|
+
|
||||||
|
+ if (devm_gpio_request_one(&pdev->dev, gpio, flags, name ? name : of_node_full_name(np)))
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ dmc = of_property_read_bool(cnp, "gpio-export,direction_may_change");
|
||||||
|
+ gpio_export_with_name(gpio, dmc, name);
|
||||||
|
+ nb++;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ dev_info(&pdev->dev, "%d gpio(s) exported\n", nb);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static struct platform_driver gpio_export_driver = {
|
||||||
|
+ .driver = {
|
||||||
|
+ .name = "gpio-export",
|
||||||
|
+ .owner = THIS_MODULE,
|
||||||
|
+ .of_match_table = of_match_ptr(gpio_export_ids),
|
||||||
|
+ },
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static int __init of_gpio_export_init(void)
|
||||||
|
+{
|
||||||
|
+ return platform_driver_probe(&gpio_export_driver, of_gpio_export_probe);
|
||||||
|
+}
|
||||||
|
+device_initcall(of_gpio_export_init);
|
||||||
|
--- a/include/asm-generic/gpio.h
|
||||||
|
+++ b/include/asm-generic/gpio.h
|
||||||
|
@@ -123,6 +123,12 @@ static inline int gpio_export(unsigned g
|
||||||
|
return gpiod_export(gpio_to_desc(gpio), direction_may_change);
|
||||||
|
}
|
||||||
|
|
||||||
|
+int __gpiod_export(struct gpio_desc *desc, bool direction_may_change, const char *name);
|
||||||
|
+static inline int gpio_export_with_name(unsigned gpio, bool direction_may_change, const char *name)
|
||||||
|
+{
|
||||||
|
+ return __gpiod_export(gpio_to_desc(gpio), direction_may_change, name);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static inline int gpio_export_link(struct device *dev, const char *name,
|
||||||
|
unsigned gpio)
|
||||||
|
{
|
||||||
|
--- a/include/linux/gpio/consumer.h
|
||||||
|
+++ b/include/linux/gpio/consumer.h
|
||||||
|
@@ -323,6 +323,7 @@ static inline int desc_to_gpio(const str
|
||||||
|
|
||||||
|
#if IS_ENABLED(CONFIG_GPIOLIB) && IS_ENABLED(CONFIG_GPIO_SYSFS)
|
||||||
|
|
||||||
|
+int _gpiod_export(struct gpio_desc *desc, bool direction_may_change, const char *name);
|
||||||
|
int gpiod_export(struct gpio_desc *desc, bool direction_may_change);
|
||||||
|
int gpiod_export_link(struct device *dev, const char *name,
|
||||||
|
struct gpio_desc *desc);
|
||||||
|
@@ -331,6 +332,13 @@ void gpiod_unexport(struct gpio_desc *de
|
||||||
|
|
||||||
|
#else /* CONFIG_GPIOLIB && CONFIG_GPIO_SYSFS */
|
||||||
|
|
||||||
|
+static inline int _gpiod_export(struct gpio_desc *desc,
|
||||||
|
+ bool direction_may_change,
|
||||||
|
+ const char *name)
|
||||||
|
+{
|
||||||
|
+ return -ENOSYS;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static inline int gpiod_export(struct gpio_desc *desc,
|
||||||
|
bool direction_may_change)
|
||||||
|
{
|
||||||
|
--- a/drivers/gpio/gpiolib-sysfs.c
|
||||||
|
+++ b/drivers/gpio/gpiolib-sysfs.c
|
||||||
|
@@ -517,7 +517,7 @@ static struct class gpio_class = {
|
||||||
|
*
|
||||||
|
* Returns zero on success, else an error.
|
||||||
|
*/
|
||||||
|
-int gpiod_export(struct gpio_desc *desc, bool direction_may_change)
|
||||||
|
+int __gpiod_export(struct gpio_desc *desc, bool direction_may_change, const char *name)
|
||||||
|
{
|
||||||
|
unsigned long flags;
|
||||||
|
int status;
|
||||||
|
@@ -557,6 +557,8 @@ int gpiod_export(struct gpio_desc *desc,
|
||||||
|
offset = gpio_chip_hwgpio(desc);
|
||||||
|
if (desc->chip->names && desc->chip->names[offset])
|
||||||
|
ioname = desc->chip->names[offset];
|
||||||
|
+ if (name)
|
||||||
|
+ ioname = name;
|
||||||
|
|
||||||
|
dev = device_create_with_groups(&gpio_class, desc->chip->dev,
|
||||||
|
MKDEV(0, 0), desc, gpio_groups,
|
||||||
|
@@ -593,6 +595,12 @@ fail_unlock:
|
||||||
|
gpiod_dbg(desc, "%s: status %d\n", __func__, status);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
+EXPORT_SYMBOL_GPL(__gpiod_export);
|
||||||
|
+
|
||||||
|
+int gpiod_export(struct gpio_desc *desc, bool direction_may_change)
|
||||||
|
+{
|
||||||
|
+ return __gpiod_export(desc, direction_may_change, NULL);
|
||||||
|
+}
|
||||||
|
EXPORT_SYMBOL_GPL(gpiod_export);
|
||||||
|
|
||||||
|
static int match_export(struct device *dev, const void *data)
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,31 @@
|
||||||
|
From 326714a47233e4a524afa0c8398276fddf0dbd4d Mon Sep 17 00:00:00 2001
|
||||||
|
From: John Crispin <blogic@openwrt.org>
|
||||||
|
Date: Thu, 6 Dec 2012 19:59:53 +0100
|
||||||
|
Subject: [PATCH 32/36] USB: fix roothub for IFXHCD
|
||||||
|
|
||||||
|
---
|
||||||
|
arch/mips/lantiq/Kconfig | 1 +
|
||||||
|
drivers/usb/core/hub.c | 2 +-
|
||||||
|
2 files changed, 2 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
--- a/arch/mips/lantiq/Kconfig
|
||||||
|
+++ b/arch/mips/lantiq/Kconfig
|
||||||
|
@@ -3,6 +3,7 @@ if LANTIQ
|
||||||
|
config SOC_TYPE_XWAY
|
||||||
|
bool
|
||||||
|
select PINCTRL_XWAY
|
||||||
|
+ select USB_ARCH_HAS_HCD
|
||||||
|
default n
|
||||||
|
|
||||||
|
choice
|
||||||
|
--- a/drivers/usb/core/hub.c
|
||||||
|
+++ b/drivers/usb/core/hub.c
|
||||||
|
@@ -4319,7 +4319,7 @@ hub_port_init (struct usb_hub *hub, stru
|
||||||
|
udev->ttport = hdev->ttport;
|
||||||
|
} else if (udev->speed != USB_SPEED_HIGH
|
||||||
|
&& hdev->speed == USB_SPEED_HIGH) {
|
||||||
|
- if (!hub->tt.hub) {
|
||||||
|
+ if (hdev->parent && !hub->tt.hub) {
|
||||||
|
dev_err(&udev->dev, "parent hub has no TT\n");
|
||||||
|
retval = -EINVAL;
|
||||||
|
goto fail;
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,45 @@
|
||||||
|
From b1b9fca8c317afc3f2b78bb54f877e8a830a819d Mon Sep 17 00:00:00 2001
|
||||||
|
From: John Crispin <blogic@openwrt.org>
|
||||||
|
Date: Fri, 9 Aug 2013 18:47:27 +0200
|
||||||
|
Subject: [PATCH 34/36] reset: Fix compile when reset RESET_CONTROLLER is not
|
||||||
|
selected
|
||||||
|
|
||||||
|
Drivers need to protect their reset api calls with #ifdef to avoid compile
|
||||||
|
errors.
|
||||||
|
|
||||||
|
This patch adds dummy wrappers in the same way that linux/of.h does it.
|
||||||
|
|
||||||
|
Cc: linux-kernel@vger.kernel.org
|
||||||
|
Cc: Philipp Zabel <p.zabel@pengutronix.de>
|
||||||
|
Cc: Gabor Juhos <juhosg@openwrt.org>
|
||||||
|
---
|
||||||
|
include/linux/reset-controller.h | 16 ++++++++++++++
|
||||||
|
include/linux/reset.h | 43 ++++++++++++++++++++++++++++++++++++++
|
||||||
|
2 files changed, 59 insertions(+)
|
||||||
|
|
||||||
|
--- a/include/linux/reset-controller.h
|
||||||
|
+++ b/include/linux/reset-controller.h
|
||||||
|
@@ -46,7 +46,23 @@ struct reset_controller_dev {
|
||||||
|
unsigned int nr_resets;
|
||||||
|
};
|
||||||
|
|
||||||
|
+#if defined(CONFIG_RESET_CONTROLLER)
|
||||||
|
+
|
||||||
|
int reset_controller_register(struct reset_controller_dev *rcdev);
|
||||||
|
void reset_controller_unregister(struct reset_controller_dev *rcdev);
|
||||||
|
|
||||||
|
+#else
|
||||||
|
+
|
||||||
|
+static inline int reset_controller_register(struct reset_controller_dev *rcdev)
|
||||||
|
+{
|
||||||
|
+ return -ENOSYS;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void reset_controller_unregister(struct reset_controller_dev *rcdev)
|
||||||
|
+{
|
||||||
|
+
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
#endif
|
|
@ -0,0 +1,614 @@
|
||||||
|
From f8c5db89e793a4bc6c1e87bd7b3a5cec16b75bc3 Mon Sep 17 00:00:00 2001
|
||||||
|
From: John Crispin <blogic@openwrt.org>
|
||||||
|
Date: Wed, 10 Sep 2014 22:42:14 +0200
|
||||||
|
Subject: [PATCH 35/36] owrt: lantiq: wifi and ethernet eeprom handling
|
||||||
|
|
||||||
|
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||||
|
---
|
||||||
|
arch/mips/include/asm/mach-lantiq/pci-ath-fixup.h | 6 +
|
||||||
|
.../mips/include/asm/mach-lantiq/xway/lantiq_soc.h | 3 +
|
||||||
|
arch/mips/lantiq/xway/Makefile | 3 +
|
||||||
|
arch/mips/lantiq/xway/ath_eep.c | 282 ++++++++++++++++++++
|
||||||
|
arch/mips/lantiq/xway/eth_mac.c | 76 ++++++
|
||||||
|
arch/mips/lantiq/xway/pci-ath-fixup.c | 109 ++++++++
|
||||||
|
arch/mips/lantiq/xway/rt_eep.c | 60 +++++
|
||||||
|
7 files changed, 539 insertions(+)
|
||||||
|
create mode 100644 arch/mips/include/asm/mach-lantiq/pci-ath-fixup.h
|
||||||
|
create mode 100644 arch/mips/lantiq/xway/ath_eep.c
|
||||||
|
create mode 100644 arch/mips/lantiq/xway/eth_mac.c
|
||||||
|
create mode 100644 arch/mips/lantiq/xway/pci-ath-fixup.c
|
||||||
|
create mode 100644 arch/mips/lantiq/xway/rt_eep.c
|
||||||
|
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/arch/mips/include/asm/mach-lantiq/pci-ath-fixup.h
|
||||||
|
@@ -0,0 +1,6 @@
|
||||||
|
+#ifndef _PCI_ATH_FIXUP
|
||||||
|
+#define _PCI_ATH_FIXUP
|
||||||
|
+
|
||||||
|
+void ltq_pci_ath_fixup(unsigned slot, u16 *cal_data) __init;
|
||||||
|
+
|
||||||
|
+#endif /* _PCI_ATH_FIXUP */
|
||||||
|
--- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
|
||||||
|
+++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
|
||||||
|
@@ -90,5 +90,8 @@ int xrx200_gphy_boot(struct device *dev,
|
||||||
|
extern void ltq_pmu_enable(unsigned int module);
|
||||||
|
extern void ltq_pmu_disable(unsigned int module);
|
||||||
|
|
||||||
|
+/* allow the ethernet driver to load a flash mapped mac addr */
|
||||||
|
+const u8* ltq_get_eth_mac(void);
|
||||||
|
+
|
||||||
|
#endif /* CONFIG_SOC_TYPE_XWAY */
|
||||||
|
#endif /* _LTQ_XWAY_H__ */
|
||||||
|
--- a/arch/mips/lantiq/xway/Makefile
|
||||||
|
+++ b/arch/mips/lantiq/xway/Makefile
|
||||||
|
@@ -2,4 +2,7 @@ obj-y := prom.o sysctrl.o clk.o reset.o
|
||||||
|
|
||||||
|
obj-y += vmmc.o tffs.o
|
||||||
|
|
||||||
|
+obj-y += eth_mac.o
|
||||||
|
+obj-$(CONFIG_PCI) += ath_eep.o rt_eep.o pci-ath-fixup.o
|
||||||
|
+
|
||||||
|
obj-$(CONFIG_XRX200_PHY_FW) += xrx200_phy_fw.o
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/arch/mips/lantiq/xway/ath_eep.c
|
||||||
|
@@ -0,0 +1,282 @@
|
||||||
|
+/*
|
||||||
|
+ * Copyright (C) 2011 Luca Olivetti <luca@ventoso.org>
|
||||||
|
+ * Copyright (C) 2011 John Crispin <blogic@openwrt.org>
|
||||||
|
+ * Copyright (C) 2011 Andrej Vlašić <andrej.vlasic0@gmail.com>
|
||||||
|
+ * Copyright (C) 2013 Álvaro Fernández Rojas <noltari@gmail.com>
|
||||||
|
+ * Copyright (C) 2013 Daniel Gimpelevich <daniel@gimpelevich.san-francisco.ca.us>
|
||||||
|
+ *
|
||||||
|
+ * This program is free software; you can redistribute it and/or modify it
|
||||||
|
+ * under the terms of the GNU General Public License version 2 as published
|
||||||
|
+ * by the Free Software Foundation.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#include <linux/init.h>
|
||||||
|
+#include <linux/module.h>
|
||||||
|
+#include <linux/platform_device.h>
|
||||||
|
+#include <linux/etherdevice.h>
|
||||||
|
+#include <linux/ath5k_platform.h>
|
||||||
|
+#include <linux/ath9k_platform.h>
|
||||||
|
+#include <linux/pci.h>
|
||||||
|
+#include <linux/err.h>
|
||||||
|
+#include <linux/mtd/mtd.h>
|
||||||
|
+#include <pci-ath-fixup.h>
|
||||||
|
+#include <lantiq_soc.h>
|
||||||
|
+
|
||||||
|
+extern int (*ltq_pci_plat_dev_init)(struct pci_dev *dev);
|
||||||
|
+struct ath5k_platform_data ath5k_pdata;
|
||||||
|
+struct ath9k_platform_data ath9k_pdata = {
|
||||||
|
+ .led_pin = -1,
|
||||||
|
+};
|
||||||
|
+static u8 athxk_eeprom_mac[6];
|
||||||
|
+
|
||||||
|
+static int ath9k_pci_plat_dev_init(struct pci_dev *dev)
|
||||||
|
+{
|
||||||
|
+ dev->dev.platform_data = &ath9k_pdata;
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int ath9k_eep_load;
|
||||||
|
+int __init of_ath9k_eeprom_probe(struct platform_device *pdev)
|
||||||
|
+{
|
||||||
|
+ struct device_node *np = pdev->dev.of_node, *mtd_np;
|
||||||
|
+ struct resource *eep_res, *mac_res = NULL;
|
||||||
|
+ void __iomem *eep, *mac;
|
||||||
|
+ int mac_offset, led_pin;
|
||||||
|
+ u32 mac_inc = 0, pci_slot = 0;
|
||||||
|
+ int i;
|
||||||
|
+ struct mtd_info *the_mtd;
|
||||||
|
+ size_t flash_readlen;
|
||||||
|
+ const __be32 *list;
|
||||||
|
+ const char *part;
|
||||||
|
+ phandle phandle;
|
||||||
|
+
|
||||||
|
+ if ((list = of_get_property(np, "ath,eep-flash", &i)) && i == 2 *
|
||||||
|
+ sizeof(*list) && (phandle = be32_to_cpup(list++)) &&
|
||||||
|
+ (mtd_np = of_find_node_by_phandle(phandle)) && ((part =
|
||||||
|
+ of_get_property(mtd_np, "label", NULL)) || (part =
|
||||||
|
+ mtd_np->name)) && (the_mtd = get_mtd_device_nm(part))
|
||||||
|
+ != ERR_PTR(-ENODEV)) {
|
||||||
|
+ i = mtd_read(the_mtd, be32_to_cpup(list),
|
||||||
|
+ ATH9K_PLAT_EEP_MAX_WORDS << 1, &flash_readlen,
|
||||||
|
+ (void *) ath9k_pdata.eeprom_data);
|
||||||
|
+ if (!of_property_read_u32(np, "ath,mac-offset", &mac_offset)) {
|
||||||
|
+ size_t mac_readlen;
|
||||||
|
+ mtd_read(the_mtd, mac_offset, 6, &mac_readlen,
|
||||||
|
+ (void *) athxk_eeprom_mac);
|
||||||
|
+ }
|
||||||
|
+ put_mtd_device(the_mtd);
|
||||||
|
+ if ((sizeof(ath9k_pdata.eeprom_data) != flash_readlen) || i) {
|
||||||
|
+ dev_err(&pdev->dev, "failed to load eeprom from mtd\n");
|
||||||
|
+ return -ENODEV;
|
||||||
|
+ }
|
||||||
|
+ } else {
|
||||||
|
+ eep_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
|
+ mac_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
|
||||||
|
+
|
||||||
|
+ if (!eep_res) {
|
||||||
|
+ dev_err(&pdev->dev, "failed to load eeprom address\n");
|
||||||
|
+ return -ENODEV;
|
||||||
|
+ }
|
||||||
|
+ if (resource_size(eep_res) != ATH9K_PLAT_EEP_MAX_WORDS << 1) {
|
||||||
|
+ dev_err(&pdev->dev, "eeprom has an invalid size\n");
|
||||||
|
+ return -EINVAL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ eep = ioremap(eep_res->start, resource_size(eep_res));
|
||||||
|
+ memcpy_fromio(ath9k_pdata.eeprom_data, eep,
|
||||||
|
+ ATH9K_PLAT_EEP_MAX_WORDS << 1);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (of_find_property(np, "ath,eep-swap", NULL))
|
||||||
|
+ for (i = 0; i < ATH9K_PLAT_EEP_MAX_WORDS; i++)
|
||||||
|
+ ath9k_pdata.eeprom_data[i] = swab16(ath9k_pdata.eeprom_data[i]);
|
||||||
|
+
|
||||||
|
+ if (of_find_property(np, "ath,eep-endian", NULL)) {
|
||||||
|
+ ath9k_pdata.endian_check = true;
|
||||||
|
+
|
||||||
|
+ dev_info(&pdev->dev, "endian check enabled.\n");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!is_valid_ether_addr(athxk_eeprom_mac)) {
|
||||||
|
+ if (mac_res) {
|
||||||
|
+ if (resource_size(mac_res) != 6) {
|
||||||
|
+ dev_err(&pdev->dev, "mac has an invalid size\n");
|
||||||
|
+ return -EINVAL;
|
||||||
|
+ }
|
||||||
|
+ mac = ioremap(mac_res->start, resource_size(mac_res));
|
||||||
|
+ memcpy_fromio(athxk_eeprom_mac, mac, 6);
|
||||||
|
+ } else if (ltq_get_eth_mac()) {
|
||||||
|
+ memcpy(athxk_eeprom_mac, ltq_get_eth_mac(), 6);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ if (!is_valid_ether_addr(athxk_eeprom_mac)) {
|
||||||
|
+ dev_warn(&pdev->dev, "using random mac\n");
|
||||||
|
+ random_ether_addr(athxk_eeprom_mac);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!of_property_read_u32(np, "ath,mac-increment", &mac_inc))
|
||||||
|
+ athxk_eeprom_mac[5] += mac_inc;
|
||||||
|
+
|
||||||
|
+ ath9k_pdata.macaddr = athxk_eeprom_mac;
|
||||||
|
+ ltq_pci_plat_dev_init = ath9k_pci_plat_dev_init;
|
||||||
|
+
|
||||||
|
+ if (!of_property_read_u32(np, "ath,pci-slot", &pci_slot)) {
|
||||||
|
+ ltq_pci_ath_fixup(pci_slot, ath9k_pdata.eeprom_data);
|
||||||
|
+
|
||||||
|
+ dev_info(&pdev->dev, "pci slot: %u\n", pci_slot);
|
||||||
|
+ if (ath9k_eep_load) {
|
||||||
|
+ struct pci_dev *d = NULL;
|
||||||
|
+ while ((d = pci_get_device(PCI_VENDOR_ID_ATHEROS,
|
||||||
|
+ PCI_ANY_ID, d)) != NULL)
|
||||||
|
+ pci_fixup_device(pci_fixup_early, d);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!of_property_read_u32(np, "ath,led-pin", &led_pin)) {
|
||||||
|
+ ath9k_pdata.led_pin = led_pin;
|
||||||
|
+ dev_info(&pdev->dev, "using led pin %d.\n", led_pin);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ dev_info(&pdev->dev, "loaded ath9k eeprom\n");
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static struct of_device_id ath9k_eeprom_ids[] = {
|
||||||
|
+ { .compatible = "ath9k,eeprom" },
|
||||||
|
+ { }
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct platform_driver ath9k_eeprom_driver = {
|
||||||
|
+ .driver = {
|
||||||
|
+ .name = "ath9k,eeprom",
|
||||||
|
+ .owner = THIS_MODULE,
|
||||||
|
+ .of_match_table = of_match_ptr(ath9k_eeprom_ids),
|
||||||
|
+ },
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static int __init of_ath9k_eeprom_init(void)
|
||||||
|
+{
|
||||||
|
+ int ret = platform_driver_probe(&ath9k_eeprom_driver, of_ath9k_eeprom_probe);
|
||||||
|
+
|
||||||
|
+ if (ret)
|
||||||
|
+ ath9k_eep_load = 1;
|
||||||
|
+
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int __init of_ath9k_eeprom_init_late(void)
|
||||||
|
+{
|
||||||
|
+ if (!ath9k_eep_load)
|
||||||
|
+ return 0;
|
||||||
|
+ return platform_driver_probe(&ath9k_eeprom_driver, of_ath9k_eeprom_probe);
|
||||||
|
+}
|
||||||
|
+late_initcall(of_ath9k_eeprom_init_late);
|
||||||
|
+subsys_initcall(of_ath9k_eeprom_init);
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+static int ath5k_pci_plat_dev_init(struct pci_dev *dev)
|
||||||
|
+{
|
||||||
|
+ dev->dev.platform_data = &ath5k_pdata;
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int __init of_ath5k_eeprom_probe(struct platform_device *pdev)
|
||||||
|
+{
|
||||||
|
+ struct device_node *np = pdev->dev.of_node, *mtd_np;
|
||||||
|
+ struct resource *eep_res, *mac_res = NULL;
|
||||||
|
+ void __iomem *eep, *mac;
|
||||||
|
+ int mac_offset;
|
||||||
|
+ u32 mac_inc = 0;
|
||||||
|
+ int i;
|
||||||
|
+ struct mtd_info *the_mtd;
|
||||||
|
+ size_t flash_readlen;
|
||||||
|
+ const __be32 *list;
|
||||||
|
+ const char *part;
|
||||||
|
+ phandle phandle;
|
||||||
|
+
|
||||||
|
+ if ((list = of_get_property(np, "ath,eep-flash", &i)) && i == 2 *
|
||||||
|
+ sizeof(*list) && (phandle = be32_to_cpup(list++)) &&
|
||||||
|
+ (mtd_np = of_find_node_by_phandle(phandle)) && ((part =
|
||||||
|
+ of_get_property(mtd_np, "label", NULL)) || (part =
|
||||||
|
+ mtd_np->name)) && (the_mtd = get_mtd_device_nm(part))
|
||||||
|
+ != ERR_PTR(-ENODEV)) {
|
||||||
|
+ i = mtd_read(the_mtd, be32_to_cpup(list),
|
||||||
|
+ ATH5K_PLAT_EEP_MAX_WORDS << 1, &flash_readlen,
|
||||||
|
+ (void *) ath5k_pdata.eeprom_data);
|
||||||
|
+ put_mtd_device(the_mtd);
|
||||||
|
+ if ((sizeof(ATH5K_PLAT_EEP_MAX_WORDS << 1) != flash_readlen)
|
||||||
|
+ || i) {
|
||||||
|
+ dev_err(&pdev->dev, "failed to load eeprom from mtd\n");
|
||||||
|
+ return -ENODEV;
|
||||||
|
+ }
|
||||||
|
+ } else {
|
||||||
|
+ eep_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
|
+ mac_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
|
||||||
|
+
|
||||||
|
+ if (!eep_res) {
|
||||||
|
+ dev_err(&pdev->dev, "failed to load eeprom address\n");
|
||||||
|
+ return -ENODEV;
|
||||||
|
+ }
|
||||||
|
+ if (resource_size(eep_res) != ATH5K_PLAT_EEP_MAX_WORDS << 1) {
|
||||||
|
+ dev_err(&pdev->dev, "eeprom has an invalid size\n");
|
||||||
|
+ return -EINVAL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ eep = ioremap(eep_res->start, resource_size(eep_res));
|
||||||
|
+ ath5k_pdata.eeprom_data = kmalloc(ATH5K_PLAT_EEP_MAX_WORDS<<1,
|
||||||
|
+ GFP_KERNEL);
|
||||||
|
+ memcpy_fromio(ath5k_pdata.eeprom_data, eep,
|
||||||
|
+ ATH5K_PLAT_EEP_MAX_WORDS << 1);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (of_find_property(np, "ath,eep-swap", NULL))
|
||||||
|
+ for (i = 0; i < ATH5K_PLAT_EEP_MAX_WORDS; i++)
|
||||||
|
+ ath5k_pdata.eeprom_data[i] = swab16(ath5k_pdata.eeprom_data[i]);
|
||||||
|
+
|
||||||
|
+ if (!of_property_read_u32(np, "ath,mac-offset", &mac_offset)) {
|
||||||
|
+ memcpy_fromio(athxk_eeprom_mac, (void*) ath5k_pdata.eeprom_data + mac_offset, 6);
|
||||||
|
+ } else if (mac_res) {
|
||||||
|
+ if (resource_size(mac_res) != 6) {
|
||||||
|
+ dev_err(&pdev->dev, "mac has an invalid size\n");
|
||||||
|
+ return -EINVAL;
|
||||||
|
+ }
|
||||||
|
+ mac = ioremap(mac_res->start, resource_size(mac_res));
|
||||||
|
+ memcpy_fromio(athxk_eeprom_mac, mac, 6);
|
||||||
|
+ } else if (ltq_get_eth_mac())
|
||||||
|
+ memcpy(athxk_eeprom_mac, ltq_get_eth_mac(), 6);
|
||||||
|
+ else {
|
||||||
|
+ dev_warn(&pdev->dev, "using random mac\n");
|
||||||
|
+ random_ether_addr(athxk_eeprom_mac);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!of_property_read_u32(np, "ath,mac-increment", &mac_inc))
|
||||||
|
+ athxk_eeprom_mac[5] += mac_inc;
|
||||||
|
+
|
||||||
|
+ ath5k_pdata.macaddr = athxk_eeprom_mac;
|
||||||
|
+ ltq_pci_plat_dev_init = ath5k_pci_plat_dev_init;
|
||||||
|
+
|
||||||
|
+ dev_info(&pdev->dev, "loaded ath5k eeprom\n");
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static struct of_device_id ath5k_eeprom_ids[] = {
|
||||||
|
+ { .compatible = "ath5k,eeprom" },
|
||||||
|
+ { }
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct platform_driver ath5k_eeprom_driver = {
|
||||||
|
+ .driver = {
|
||||||
|
+ .name = "ath5k,eeprom",
|
||||||
|
+ .owner = THIS_MODULE,
|
||||||
|
+ .of_match_table = of_match_ptr(ath5k_eeprom_ids),
|
||||||
|
+ },
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static int __init of_ath5k_eeprom_init(void)
|
||||||
|
+{
|
||||||
|
+ return platform_driver_probe(&ath5k_eeprom_driver, of_ath5k_eeprom_probe);
|
||||||
|
+}
|
||||||
|
+device_initcall(of_ath5k_eeprom_init);
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/arch/mips/lantiq/xway/eth_mac.c
|
||||||
|
@@ -0,0 +1,76 @@
|
||||||
|
+/*
|
||||||
|
+ * Copyright (C) 2012 John Crispin <blogic@openwrt.org>
|
||||||
|
+ *
|
||||||
|
+ * This program is free software; you can redistribute it and/or modify it
|
||||||
|
+ * under the terms of the GNU General Public License version 2 as published
|
||||||
|
+ * by the Free Software Foundation.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#include <linux/init.h>
|
||||||
|
+#include <linux/module.h>
|
||||||
|
+#include <linux/of_platform.h>
|
||||||
|
+#include <linux/if_ether.h>
|
||||||
|
+
|
||||||
|
+static u8 eth_mac[6];
|
||||||
|
+static int eth_mac_set;
|
||||||
|
+
|
||||||
|
+const u8* ltq_get_eth_mac(void)
|
||||||
|
+{
|
||||||
|
+ return eth_mac;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int __init setup_ethaddr(char *str)
|
||||||
|
+{
|
||||||
|
+ eth_mac_set = mac_pton(str, eth_mac);
|
||||||
|
+ return !eth_mac_set;
|
||||||
|
+}
|
||||||
|
+__setup("ethaddr=", setup_ethaddr);
|
||||||
|
+
|
||||||
|
+int __init of_eth_mac_probe(struct platform_device *pdev)
|
||||||
|
+{
|
||||||
|
+ struct device_node *np = pdev->dev.of_node;
|
||||||
|
+ struct resource *mac_res;
|
||||||
|
+ void __iomem *mac;
|
||||||
|
+ u32 mac_inc = 0;
|
||||||
|
+
|
||||||
|
+ if (eth_mac_set) {
|
||||||
|
+ dev_err(&pdev->dev, "mac was already set by bootloader\n");
|
||||||
|
+ return -EINVAL;
|
||||||
|
+ }
|
||||||
|
+ mac_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
|
+
|
||||||
|
+ if (!mac_res) {
|
||||||
|
+ dev_err(&pdev->dev, "failed to load mac\n");
|
||||||
|
+ return -EINVAL;
|
||||||
|
+ }
|
||||||
|
+ if (resource_size(mac_res) != 6) {
|
||||||
|
+ dev_err(&pdev->dev, "mac has an invalid size\n");
|
||||||
|
+ return -EINVAL;
|
||||||
|
+ }
|
||||||
|
+ mac = ioremap(mac_res->start, resource_size(mac_res));
|
||||||
|
+ memcpy_fromio(eth_mac, mac, 6);
|
||||||
|
+
|
||||||
|
+ if (!of_property_read_u32(np, "mac-increment", &mac_inc))
|
||||||
|
+ eth_mac[5] += mac_inc;
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static struct of_device_id eth_mac_ids[] = {
|
||||||
|
+ { .compatible = "lantiq,eth-mac" },
|
||||||
|
+ { /* sentinel */ }
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct platform_driver eth_mac_driver = {
|
||||||
|
+ .driver = {
|
||||||
|
+ .name = "lantiq,eth-mac",
|
||||||
|
+ .owner = THIS_MODULE,
|
||||||
|
+ .of_match_table = of_match_ptr(eth_mac_ids),
|
||||||
|
+ },
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static int __init of_eth_mac_init(void)
|
||||||
|
+{
|
||||||
|
+ return platform_driver_probe(ð_mac_driver, of_eth_mac_probe);
|
||||||
|
+}
|
||||||
|
+device_initcall(of_eth_mac_init);
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/arch/mips/lantiq/xway/pci-ath-fixup.c
|
||||||
|
@@ -0,0 +1,109 @@
|
||||||
|
+/*
|
||||||
|
+ * Atheros AP94 reference board PCI initialization
|
||||||
|
+ *
|
||||||
|
+ * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
|
||||||
|
+ *
|
||||||
|
+ * This program is free software; you can redistribute it and/or modify it
|
||||||
|
+ * under the terms of the GNU General Public License version 2 as published
|
||||||
|
+ * by the Free Software Foundation.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#include <linux/pci.h>
|
||||||
|
+#include <linux/init.h>
|
||||||
|
+#include <linux/delay.h>
|
||||||
|
+#include <lantiq_soc.h>
|
||||||
|
+
|
||||||
|
+#define LTQ_PCI_MEM_BASE 0x18000000
|
||||||
|
+
|
||||||
|
+struct ath_fixup {
|
||||||
|
+ u16 *cal_data;
|
||||||
|
+ unsigned slot;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static int ath_num_fixups;
|
||||||
|
+static struct ath_fixup ath_fixups[2];
|
||||||
|
+
|
||||||
|
+static void ath_pci_fixup(struct pci_dev *dev)
|
||||||
|
+{
|
||||||
|
+ void __iomem *mem;
|
||||||
|
+ u16 *cal_data = NULL;
|
||||||
|
+ u16 cmd;
|
||||||
|
+ u32 bar0;
|
||||||
|
+ u32 val;
|
||||||
|
+ unsigned i;
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < ath_num_fixups; i++) {
|
||||||
|
+ if (ath_fixups[i].cal_data == NULL)
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ if (ath_fixups[i].slot != PCI_SLOT(dev->devfn))
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ cal_data = ath_fixups[i].cal_data;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (cal_data == NULL)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ if (*cal_data != 0xa55a) {
|
||||||
|
+ pr_err("pci %s: invalid calibration data\n", pci_name(dev));
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ pr_info("pci %s: fixup device configuration\n", pci_name(dev));
|
||||||
|
+
|
||||||
|
+ mem = ioremap(LTQ_PCI_MEM_BASE, 0x10000);
|
||||||
|
+ if (!mem) {
|
||||||
|
+ pr_err("pci %s: ioremap error\n", pci_name(dev));
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &bar0);
|
||||||
|
+ pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, LTQ_PCI_MEM_BASE);
|
||||||
|
+ pci_read_config_word(dev, PCI_COMMAND, &cmd);
|
||||||
|
+ cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
|
||||||
|
+ pci_write_config_word(dev, PCI_COMMAND, cmd);
|
||||||
|
+
|
||||||
|
+ /* set pointer to first reg address */
|
||||||
|
+ cal_data += 3;
|
||||||
|
+ while (*cal_data != 0xffff) {
|
||||||
|
+ u32 reg;
|
||||||
|
+ reg = *cal_data++;
|
||||||
|
+ val = *cal_data++;
|
||||||
|
+ val |= (*cal_data++) << 16;
|
||||||
|
+
|
||||||
|
+ ltq_w32(swab32(val), mem + reg);
|
||||||
|
+ udelay(100);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ pci_read_config_dword(dev, PCI_VENDOR_ID, &val);
|
||||||
|
+ dev->vendor = val & 0xffff;
|
||||||
|
+ dev->device = (val >> 16) & 0xffff;
|
||||||
|
+
|
||||||
|
+ pci_read_config_dword(dev, PCI_CLASS_REVISION, &val);
|
||||||
|
+ dev->revision = val & 0xff;
|
||||||
|
+ dev->class = val >> 8; /* upper 3 bytes */
|
||||||
|
+
|
||||||
|
+ pr_info("pci %s: fixup info: [%04x:%04x] revision %02x class %#08x\n",
|
||||||
|
+ pci_name(dev), dev->vendor, dev->device, dev->revision, dev->class);
|
||||||
|
+
|
||||||
|
+ pci_read_config_word(dev, PCI_COMMAND, &cmd);
|
||||||
|
+ cmd &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
|
||||||
|
+ pci_write_config_word(dev, PCI_COMMAND, cmd);
|
||||||
|
+
|
||||||
|
+ pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, bar0);
|
||||||
|
+
|
||||||
|
+ iounmap(mem);
|
||||||
|
+}
|
||||||
|
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATHEROS, PCI_ANY_ID, ath_pci_fixup);
|
||||||
|
+
|
||||||
|
+void __init ltq_pci_ath_fixup(unsigned slot, u16 *cal_data)
|
||||||
|
+{
|
||||||
|
+ if (ath_num_fixups >= ARRAY_SIZE(ath_fixups))
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ ath_fixups[ath_num_fixups].slot = slot;
|
||||||
|
+ ath_fixups[ath_num_fixups].cal_data = cal_data;
|
||||||
|
+ ath_num_fixups++;
|
||||||
|
+}
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/arch/mips/lantiq/xway/rt_eep.c
|
||||||
|
@@ -0,0 +1,60 @@
|
||||||
|
+/*
|
||||||
|
+ * Copyright (C) 2011 John Crispin <blogic@openwrt.org>
|
||||||
|
+ *
|
||||||
|
+ * This program is free software; you can redistribute it and/or modify it
|
||||||
|
+ * under the terms of the GNU General Public License version 2 as published
|
||||||
|
+ * by the Free Software Foundation.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#include <linux/init.h>
|
||||||
|
+#include <linux/module.h>
|
||||||
|
+#include <linux/pci.h>
|
||||||
|
+#include <linux/platform_device.h>
|
||||||
|
+#include <linux/rt2x00_platform.h>
|
||||||
|
+
|
||||||
|
+extern int (*ltq_pci_plat_dev_init)(struct pci_dev *dev);
|
||||||
|
+static struct rt2x00_platform_data rt2x00_pdata;
|
||||||
|
+
|
||||||
|
+static int rt2x00_pci_plat_dev_init(struct pci_dev *dev)
|
||||||
|
+{
|
||||||
|
+ dev->dev.platform_data = &rt2x00_pdata;
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int __init of_ralink_eeprom_probe(struct platform_device *pdev)
|
||||||
|
+{
|
||||||
|
+ struct device_node *np = pdev->dev.of_node;
|
||||||
|
+ const char *eeprom;
|
||||||
|
+
|
||||||
|
+ if (of_property_read_string(np, "ralink,eeprom", &eeprom)) {
|
||||||
|
+ dev_err(&pdev->dev, "failed to load eeprom filename\n");
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ rt2x00_pdata.eeprom_file_name = kstrdup(eeprom, GFP_KERNEL);
|
||||||
|
+// rt2x00_pdata.mac_address = mac;
|
||||||
|
+ ltq_pci_plat_dev_init = rt2x00_pci_plat_dev_init;
|
||||||
|
+
|
||||||
|
+ dev_info(&pdev->dev, "using %s as eeprom\n", eeprom);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static struct of_device_id ralink_eeprom_ids[] = {
|
||||||
|
+ { .compatible = "ralink,eeprom" },
|
||||||
|
+ { }
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct platform_driver ralink_eeprom_driver = {
|
||||||
|
+ .driver = {
|
||||||
|
+ .name = "ralink,eeprom",
|
||||||
|
+ .owner = THIS_MODULE,
|
||||||
|
+ .of_match_table = of_match_ptr(ralink_eeprom_ids),
|
||||||
|
+ },
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static int __init of_ralink_eeprom_init(void)
|
||||||
|
+{
|
||||||
|
+ return platform_driver_probe(&ralink_eeprom_driver, of_ralink_eeprom_probe);
|
||||||
|
+}
|
||||||
|
+device_initcall(of_ralink_eeprom_init);
|
||||||
|
--- a/drivers/net/ethernet/lantiq_etop.c
|
||||||
|
+++ b/drivers/net/ethernet/lantiq_etop.c
|
||||||
|
@@ -161,7 +161,7 @@ struct ltq_etop_priv {
|
||||||
|
int tx_irq;
|
||||||
|
int rx_irq;
|
||||||
|
|
||||||
|
- const void *mac;
|
||||||
|
+ void *mac;
|
||||||
|
int mii_mode;
|
||||||
|
|
||||||
|
spinlock_t lock;
|
||||||
|
@@ -840,7 +840,11 @@ ltq_etop_init(struct net_device *dev)
|
||||||
|
if (err)
|
||||||
|
goto err_hw;
|
||||||
|
|
||||||
|
- memcpy(&mac, &priv->pldata->mac, sizeof(struct sockaddr));
|
||||||
|
+ if (priv->mac)
|
||||||
|
+ memcpy(&mac, priv->mac, sizeof(struct sockaddr));
|
||||||
|
+ else
|
||||||
|
+ memcpy(&mac, ltq_get_eth_mac(), sizeof(struct sockaddr));
|
||||||
|
+
|
||||||
|
if (!is_valid_ether_addr(mac.sa_data)) {
|
||||||
|
pr_warn("etop: invalid MAC, using random\n");
|
||||||
|
eth_random_addr(mac.sa_data);
|
|
@ -0,0 +1,32 @@
|
||||||
|
From dba8578e06aedf1e67312ebfc6162e2fadc9448d Mon Sep 17 00:00:00 2001
|
||||||
|
From: John Crispin <blogic@openwrt.org>
|
||||||
|
Date: Thu, 7 Aug 2014 18:32:12 +0200
|
||||||
|
Subject: [PATCH 36/36] owrt: generic dtb image hack
|
||||||
|
|
||||||
|
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||||
|
---
|
||||||
|
arch/mips/kernel/head.S | 3 +++
|
||||||
|
1 file changed, 3 insertions(+)
|
||||||
|
|
||||||
|
--- a/arch/mips/kernel/head.S
|
||||||
|
+++ b/arch/mips/kernel/head.S
|
||||||
|
@@ -86,6 +86,9 @@ EXPORT(__image_cmdline)
|
||||||
|
.fill 0x400
|
||||||
|
#endif /* CONFIG_IMAGE_CMDLINE_HACK */
|
||||||
|
|
||||||
|
+ .ascii "OWRTDTB:"
|
||||||
|
+ EXPORT(__image_dtb)
|
||||||
|
+ .fill 0x4000
|
||||||
|
__REF
|
||||||
|
|
||||||
|
NESTED(kernel_entry, 16, sp) # kernel entry point
|
||||||
|
--- a/arch/mips/lantiq/Kconfig
|
||||||
|
+++ b/arch/mips/lantiq/Kconfig
|
||||||
|
@@ -32,7 +32,6 @@ choice
|
||||||
|
config DT_EASY50712
|
||||||
|
bool "Easy50712"
|
||||||
|
depends on SOC_XWAY
|
||||||
|
- select BUILTIN_DTB
|
||||||
|
endchoice
|
||||||
|
|
||||||
|
config PCI_LANTIQ
|
|
@ -0,0 +1,74 @@
|
||||||
|
From baea71233ed1796651cab6ead484a18666a765aa Mon Sep 17 00:00:00 2001
|
||||||
|
From: John Crispin <blogic@openwrt.org>
|
||||||
|
Date: Thu, 11 Sep 2014 19:25:25 +0200
|
||||||
|
Subject: [PATCH] MIPS: lantiq: move eiu init after irq_domain register
|
||||||
|
|
||||||
|
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||||
|
---
|
||||||
|
arch/mips/lantiq/irq.c | 48 ++++++++++++++++++++++++------------------------
|
||||||
|
1 file changed, 24 insertions(+), 24 deletions(-)
|
||||||
|
|
||||||
|
--- a/arch/mips/lantiq/irq.c
|
||||||
|
+++ b/arch/mips/lantiq/irq.c
|
||||||
|
@@ -380,30 +380,6 @@ int __init icu_of_init(struct device_nod
|
||||||
|
panic("Failed to remap icu memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
- /* the external interrupts are optional and xway only */
|
||||||
|
- eiu_node = of_find_compatible_node(NULL, NULL, "lantiq,eiu-xway");
|
||||||
|
- if (eiu_node && !of_address_to_resource(eiu_node, 0, &res)) {
|
||||||
|
- /* find out how many external irq sources we have */
|
||||||
|
- exin_avail = of_irq_count(eiu_node);
|
||||||
|
-
|
||||||
|
- if (exin_avail > MAX_EIU)
|
||||||
|
- exin_avail = MAX_EIU;
|
||||||
|
-
|
||||||
|
- ret = of_irq_to_resource_table(eiu_node,
|
||||||
|
- ltq_eiu_irq, exin_avail);
|
||||||
|
- if (ret != exin_avail)
|
||||||
|
- panic("failed to load external irq resources");
|
||||||
|
-
|
||||||
|
- if (request_mem_region(res.start, resource_size(&res),
|
||||||
|
- res.name) < 0)
|
||||||
|
- pr_err("Failed to request eiu memory");
|
||||||
|
-
|
||||||
|
- ltq_eiu_membase = ioremap_nocache(res.start,
|
||||||
|
- resource_size(&res));
|
||||||
|
- if (!ltq_eiu_membase)
|
||||||
|
- panic("Failed to remap eiu memory");
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
/* turn off all irqs by default */
|
||||||
|
for (i = 0; i < MAX_IM; i++) {
|
||||||
|
/* make sure all irqs are turned off by default */
|
||||||
|
@@ -460,6 +436,30 @@ int __init icu_of_init(struct device_nod
|
||||||
|
if (MIPS_CPU_TIMER_IRQ != 7)
|
||||||
|
irq_create_mapping(ltq_domain, MIPS_CPU_TIMER_IRQ);
|
||||||
|
|
||||||
|
+ /* the external interrupts are optional and xway only */
|
||||||
|
+ eiu_node = of_find_compatible_node(NULL, NULL, "lantiq,eiu-xway");
|
||||||
|
+ if (eiu_node && !of_address_to_resource(eiu_node, 0, &res)) {
|
||||||
|
+ /* find out how many external irq sources we have */
|
||||||
|
+ exin_avail = of_irq_count(eiu_node);
|
||||||
|
+
|
||||||
|
+ if (exin_avail > MAX_EIU)
|
||||||
|
+ exin_avail = MAX_EIU;
|
||||||
|
+
|
||||||
|
+ ret = of_irq_to_resource_table(eiu_node,
|
||||||
|
+ ltq_eiu_irq, exin_avail);
|
||||||
|
+ if (ret != exin_avail)
|
||||||
|
+ panic("failed to load external irq resources");
|
||||||
|
+
|
||||||
|
+ if (request_mem_region(res.start, resource_size(&res),
|
||||||
|
+ res.name) < 0)
|
||||||
|
+ pr_err("Failed to request eiu memory");
|
||||||
|
+
|
||||||
|
+ ltq_eiu_membase = ioremap_nocache(res.start,
|
||||||
|
+ resource_size(&res));
|
||||||
|
+ if (!ltq_eiu_membase)
|
||||||
|
+ panic("Failed to remap eiu memory");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
Return correct value for fpi clock on ar9.
|
||||||
|
|
||||||
|
Signed-off-by: Ben Mulvihill <ben.mulvihill@gmail.com>
|
||||||
|
---
|
||||||
|
arch/mips/lantiq/xway/clk.c | 5 +++--
|
||||||
|
1 file changed, 3 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
--- a/arch/mips/lantiq/xway/clk.c
|
||||||
|
+++ b/arch/mips/lantiq/xway/clk.c
|
||||||
|
@@ -87,8 +87,9 @@ unsigned long ltq_ar9_fpi_hz(void)
|
||||||
|
unsigned long sys = ltq_ar9_sys_hz();
|
||||||
|
|
||||||
|
if (ltq_cgu_r32(CGU_SYS) & BIT(0))
|
||||||
|
- return sys;
|
||||||
|
- return sys >> 1;
|
||||||
|
+ return sys / 3;
|
||||||
|
+ else
|
||||||
|
+ return sys / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long ltq_ar9_cpu_hz(void)
|
192
target/linux/lantiq/patches-3.18/0101-mtd-split.patch
Normal file
192
target/linux/lantiq/patches-3.18/0101-mtd-split.patch
Normal file
|
@ -0,0 +1,192 @@
|
||||||
|
--- a/arch/mips/lantiq/xway/Makefile
|
||||||
|
+++ b/arch/mips/lantiq/xway/Makefile
|
||||||
|
@@ -1,6 +1,6 @@
|
||||||
|
obj-y := prom.o sysctrl.o clk.o reset.o dma.o timer.o dcdc.o
|
||||||
|
|
||||||
|
-obj-y += vmmc.o tffs.o
|
||||||
|
+obj-y += vmmc.o tffs.o mtd_split.o
|
||||||
|
|
||||||
|
obj-y += eth_mac.o
|
||||||
|
obj-$(CONFIG_PCI) += ath_eep.o rt_eep.o pci-ath-fixup.o
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/arch/mips/lantiq/xway/mtd_split.c
|
||||||
|
@@ -0,0 +1,129 @@
|
||||||
|
+#include <linux/magic.h>
|
||||||
|
+#include <linux/root_dev.h>
|
||||||
|
+#include <linux/mtd/mtd.h>
|
||||||
|
+#include <linux/mtd/partitions.h>
|
||||||
|
+
|
||||||
|
+#define ROOTFS_SPLIT_NAME "rootfs_data"
|
||||||
|
+
|
||||||
|
+struct squashfs_super_block {
|
||||||
|
+ __le32 s_magic;
|
||||||
|
+ __le32 pad0[9];
|
||||||
|
+ __le64 bytes_used;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static void split_brnimage_kernel(struct mtd_info *master, const char *name,
|
||||||
|
+ int offset, int size)
|
||||||
|
+{
|
||||||
|
+ unsigned long buf[4];
|
||||||
|
+ // Assume at most 2MB of kernel image
|
||||||
|
+ unsigned long end = offset + (2 << 20);
|
||||||
|
+ unsigned long part_size = offset + 0x400 - 12;
|
||||||
|
+ size_t len;
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ if (strcmp(name, "firmware") != 0)
|
||||||
|
+ return;
|
||||||
|
+ while (part_size < end) {
|
||||||
|
+ long size_min = part_size - 0x400 - 12 - offset;
|
||||||
|
+ long size_max = part_size + 12 - offset;
|
||||||
|
+ ret = mtd_read(master, part_size, 16, &len, (void *)buf);
|
||||||
|
+ if (ret || len != 16)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ if (le32_to_cpu(buf[0]) < size_min ||
|
||||||
|
+ le32_to_cpu(buf[0]) > size_max) {
|
||||||
|
+ part_size += 0x400;
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (le32_to_cpu(buf[3]) == SQUASHFS_MAGIC) {
|
||||||
|
+ part_size += 12 - offset;
|
||||||
|
+ __mtd_add_partition(master, "rootfs", offset + part_size,
|
||||||
|
+ size - part_size, false);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+ part_size += 0x400;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void split_eva_kernel(struct mtd_info *master, const char *name,
|
||||||
|
+ int offset, int size)
|
||||||
|
+{
|
||||||
|
+#define EVA_MAGIC 0xfeed1281
|
||||||
|
+ unsigned long magic = 0;
|
||||||
|
+ unsigned long part_size = 0, p;
|
||||||
|
+ size_t len;
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ if (strcmp(name, CONFIG_MTD_SPLIT_FIRMWARE_NAME) != 0)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ ret = mtd_read(master, offset, 4, &len, (void *)&magic);
|
||||||
|
+ if (ret || len != sizeof(magic))
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ if (le32_to_cpu(magic) != EVA_MAGIC)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ ret = mtd_read(master, offset + 4, 4, &len, (void *)&part_size);
|
||||||
|
+ if (ret || len != sizeof(part_size))
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ p = part_size = le32_to_cpu(part_size) + 0x18;
|
||||||
|
+ p &= ~0xffff;
|
||||||
|
+ p += 0x10000;
|
||||||
|
+
|
||||||
|
+ ret = mtd_read(master, offset + p, 4, &len, (void *)&magic);
|
||||||
|
+ if (ret || len != sizeof(magic))
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ if (magic == SQUASHFS_MAGIC)
|
||||||
|
+ part_size = p + 0x100;
|
||||||
|
+ else
|
||||||
|
+ part_size = mtd_pad_erasesize(master, offset, len);
|
||||||
|
+
|
||||||
|
+ if (part_size + master->erasesize > size)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ __mtd_add_partition(master, "rootfs", offset + part_size,
|
||||||
|
+ size - part_size, false);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void split_tplink_kernel(struct mtd_info *master, const char *name,
|
||||||
|
+ int offset, int size)
|
||||||
|
+{
|
||||||
|
+#define TPLINK_MAGIC 0x00000002
|
||||||
|
+ unsigned long magic = 0;
|
||||||
|
+ unsigned long part_size = 0;
|
||||||
|
+ size_t len;
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ if (strcmp(name, CONFIG_MTD_SPLIT_FIRMWARE_NAME) != 0)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ ret = mtd_read(master, offset, 4, &len, (void *)&magic);
|
||||||
|
+ if (ret || len != sizeof(magic))
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ if (le32_to_cpu(magic) != TPLINK_MAGIC)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ ret = mtd_read(master, offset + 0x78, 4, &len, (void *)&part_size);
|
||||||
|
+ if (ret || len != sizeof(part_size))
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ part_size = be32_to_cpu(part_size) + 0x200;
|
||||||
|
+ if (part_size + master->erasesize > size)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ __mtd_add_partition(master, "rootfs", offset + part_size,
|
||||||
|
+ size - part_size, false);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void arch_split_mtd_part(struct mtd_info *master, const char *name,
|
||||||
|
+ int offset, int size)
|
||||||
|
+{
|
||||||
|
+ split_tplink_kernel(master, name, offset, size);
|
||||||
|
+ split_eva_kernel(master, name, offset, size);
|
||||||
|
+ split_brnimage_kernel(master, name, offset, size);
|
||||||
|
+}
|
||||||
|
--- a/include/linux/mtd/partitions.h
|
||||||
|
+++ b/include/linux/mtd/partitions.h
|
||||||
|
@@ -89,12 +89,17 @@ extern void deregister_mtd_parser(struct
|
||||||
|
int mtd_is_partition(const struct mtd_info *mtd);
|
||||||
|
int mtd_add_partition(struct mtd_info *master, const char *name,
|
||||||
|
long long offset, long long length);
|
||||||
|
+int __mtd_add_partition(struct mtd_info *master, const char *name,
|
||||||
|
+ long long offset, long long length, bool dup_check);
|
||||||
|
+
|
||||||
|
int mtd_del_partition(struct mtd_info *master, int partno);
|
||||||
|
struct mtd_info *mtdpart_get_master(const struct mtd_info *mtd);
|
||||||
|
uint64_t mtdpart_get_offset(const struct mtd_info *mtd);
|
||||||
|
uint64_t mtd_get_device_size(const struct mtd_info *mtd);
|
||||||
|
-extern void __weak arch_split_mtd_part(struct mtd_info *master,
|
||||||
|
- const char *name, int offset, int size);
|
||||||
|
+void __weak arch_split_mtd_part(struct mtd_info *master,
|
||||||
|
+ const char *name, int offset, int size);
|
||||||
|
+unsigned long
|
||||||
|
+mtd_pad_erasesize(struct mtd_info *mtd, int offset, int len);
|
||||||
|
|
||||||
|
int parse_mtd_partitions_by_type(struct mtd_info *master,
|
||||||
|
enum mtd_parser_type type,
|
||||||
|
--- a/drivers/mtd/mtdpart.c
|
||||||
|
+++ b/drivers/mtd/mtdpart.c
|
||||||
|
@@ -630,7 +630,7 @@ out_register:
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
-static int
|
||||||
|
+int
|
||||||
|
__mtd_add_partition(struct mtd_info *master, const char *name,
|
||||||
|
long long offset, long long length, bool dup_check)
|
||||||
|
{
|
||||||
|
@@ -751,7 +751,7 @@ run_parsers_by_type(struct mtd_part *sla
|
||||||
|
return nr_parts;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static inline unsigned long
|
||||||
|
+unsigned long
|
||||||
|
mtd_pad_erasesize(struct mtd_info *mtd, int offset, int len)
|
||||||
|
{
|
||||||
|
unsigned long mask = mtd->erasesize - 1;
|
||||||
|
@@ -821,7 +821,6 @@ static void split_uimage(struct mtd_info
|
||||||
|
return;
|
||||||
|
|
||||||
|
len = be32_to_cpu(hdr.size) + 0x40;
|
||||||
|
- len = mtd_pad_erasesize(master, part->offset, len);
|
||||||
|
if (len + master->erasesize > part->mtd.size)
|
||||||
|
return;
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
--- a/drivers/pinctrl/pinctrl-xway.c
|
||||||
|
+++ b/drivers/pinctrl/pinctrl-xway.c
|
||||||
|
@@ -152,10 +152,10 @@ static const struct ltq_mfp_pin xway_mfp
|
||||||
|
MFP_XWAY(GPIO41, GPIO, NONE, NONE, NONE),
|
||||||
|
MFP_XWAY(GPIO42, GPIO, MDIO, NONE, NONE),
|
||||||
|
MFP_XWAY(GPIO43, GPIO, MDIO, NONE, NONE),
|
||||||
|
- MFP_XWAY(GPIO44, GPIO, NONE, GPHY, SIN),
|
||||||
|
+ MFP_XWAY(GPIO44, GPIO, MII, SIN, GPHY),
|
||||||
|
MFP_XWAY(GPIO45, GPIO, NONE, GPHY, SIN),
|
||||||
|
MFP_XWAY(GPIO46, GPIO, NONE, NONE, EXIN),
|
||||||
|
- MFP_XWAY(GPIO47, GPIO, NONE, GPHY, SIN),
|
||||||
|
+ MFP_XWAY(GPIO47, GPIO, MII, GPHY, SIN),
|
||||||
|
MFP_XWAY(GPIO48, GPIO, EBU, NONE, NONE),
|
||||||
|
MFP_XWAY(GPIO49, GPIO, EBU, NONE, NONE),
|
||||||
|
MFP_XWAY(GPIO50, GPIO, NONE, NONE, NONE),
|
|
@ -0,0 +1,51 @@
|
||||||
|
--- a/arch/mips/pci/ifxmips_pcie.c
|
||||||
|
+++ b/arch/mips/pci/ifxmips_pcie.c
|
||||||
|
@@ -18,6 +18,8 @@
|
||||||
|
#include <linux/pci_regs.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
|
||||||
|
+#include <linux/of_platform.h>
|
||||||
|
+
|
||||||
|
#include "ifxmips_pcie.h"
|
||||||
|
#include "ifxmips_pcie_reg.h"
|
||||||
|
|
||||||
|
@@ -1048,7 +1050,7 @@ pcie_rc_initialize(int pcie_port)
|
||||||
|
extern int (*ltq_pci_plat_arch_init)(struct pci_dev *dev);
|
||||||
|
extern int (*ltq_pci_map_irq)(const struct pci_dev *dev, u8 slot, u8 pin);
|
||||||
|
|
||||||
|
-static int __init ifx_pcie_bios_init(void)
|
||||||
|
+static int __init ifx_pcie_bios_probe(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
void __iomem *io_map_base;
|
||||||
|
int pcie_port;
|
||||||
|
@@ -1090,6 +1092,30 @@ static int __init ifx_pcie_bios_init(voi
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+static const struct of_device_id ifxmips_pcie_match[] = {
|
||||||
|
+ { .compatible = "lantiq,pcie-xrx200" },
|
||||||
|
+ {},
|
||||||
|
+};
|
||||||
|
+MODULE_DEVICE_TABLE(of, ifxmips_pcie_match);
|
||||||
|
+
|
||||||
|
+static struct platform_driver ltq_pci_driver = {
|
||||||
|
+ .probe = ifx_pcie_bios_probe,
|
||||||
|
+ .driver = {
|
||||||
|
+ .name = "pcie-xrx200",
|
||||||
|
+ .owner = THIS_MODULE,
|
||||||
|
+ .of_match_table = ifxmips_pcie_match,
|
||||||
|
+ },
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+int __init ifx_pcie_bios_init(void)
|
||||||
|
+{
|
||||||
|
+ int ret = platform_driver_register(<q_pci_driver);
|
||||||
|
+ if (ret)
|
||||||
|
+ pr_info("pcie-xrx200: Error registering platform driver!");
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
arch_initcall(ifx_pcie_bios_init);
|
||||||
|
|
||||||
|
MODULE_LICENSE("GPL");
|
|
@ -0,0 +1,217 @@
|
||||||
|
--- a/drivers/mtd/maps/lantiq-flash.c
|
||||||
|
+++ b/drivers/mtd/maps/lantiq-flash.c
|
||||||
|
@@ -19,6 +19,7 @@
|
||||||
|
#include <linux/mtd/cfi.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/mtd/physmap.h>
|
||||||
|
+#include <linux/mtd/concat.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
|
||||||
|
#include <lantiq_soc.h>
|
||||||
|
@@ -38,10 +39,12 @@
|
||||||
|
LTQ_NOR_NORMAL
|
||||||
|
};
|
||||||
|
|
||||||
|
+#define MAX_RESOURCES 4
|
||||||
|
+
|
||||||
|
struct ltq_mtd {
|
||||||
|
- struct resource *res;
|
||||||
|
- struct mtd_info *mtd;
|
||||||
|
- struct map_info *map;
|
||||||
|
+ struct mtd_info *mtd[MAX_RESOURCES];
|
||||||
|
+ struct mtd_info *cmtd;
|
||||||
|
+ struct map_info map[MAX_RESOURCES];
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char ltq_map_name[] = "ltq_nor";
|
||||||
|
@@ -109,12 +112,44 @@
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
+ltq_mtd_remove(struct platform_device *pdev)
|
||||||
|
+{
|
||||||
|
+ struct ltq_mtd *ltq_mtd = platform_get_drvdata(pdev);
|
||||||
|
+ int i;
|
||||||
|
+
|
||||||
|
+ if (ltq_mtd == NULL)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ if (ltq_mtd->cmtd) {
|
||||||
|
+ mtd_device_unregister(ltq_mtd->cmtd);
|
||||||
|
+ if (ltq_mtd->cmtd != ltq_mtd->mtd[0])
|
||||||
|
+ mtd_concat_destroy(ltq_mtd->cmtd);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < MAX_RESOURCES; i++) {
|
||||||
|
+ if (ltq_mtd->mtd[i] != NULL)
|
||||||
|
+ map_destroy(ltq_mtd->mtd[i]);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ kfree(ltq_mtd);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
ltq_mtd_probe(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct mtd_part_parser_data ppdata;
|
||||||
|
struct ltq_mtd *ltq_mtd;
|
||||||
|
struct cfi_private *cfi;
|
||||||
|
- int err;
|
||||||
|
+ int err = 0;
|
||||||
|
+ int i;
|
||||||
|
+ int devices_found = 0;
|
||||||
|
+
|
||||||
|
+ static const char *rom_probe_types[] = {
|
||||||
|
+ "cfi_probe", "jedec_probe", NULL
|
||||||
|
+ };
|
||||||
|
+ const char **type;
|
||||||
|
|
||||||
|
if (of_machine_is_compatible("lantiq,falcon") &&
|
||||||
|
(ltq_boot_select() != BS_FLASH)) {
|
||||||
|
@@ -128,76 +163,88 @@
|
||||||
|
|
||||||
|
platform_set_drvdata(pdev, ltq_mtd);
|
||||||
|
|
||||||
|
- ltq_mtd->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
|
- if (!ltq_mtd->res) {
|
||||||
|
- dev_err(&pdev->dev, "failed to get memory resource\n");
|
||||||
|
- return -ENOENT;
|
||||||
|
+ for (i = 0; i < pdev->num_resources; i++) {
|
||||||
|
+ printk(KERN_NOTICE "lantiq nor flash device: %.8llx at %.8llx\n",
|
||||||
|
+ (unsigned long long)resource_size(&pdev->resource[i]),
|
||||||
|
+ (unsigned long long)pdev->resource[i].start);
|
||||||
|
+
|
||||||
|
+ if (!devm_request_mem_region(&pdev->dev,
|
||||||
|
+ pdev->resource[i].start,
|
||||||
|
+ resource_size(&pdev->resource[i]),
|
||||||
|
+ dev_name(&pdev->dev))) {
|
||||||
|
+ dev_err(&pdev->dev, "Could not reserve memory region\n");
|
||||||
|
+ return -ENOMEM;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ltq_mtd->map[i].name = ltq_map_name;
|
||||||
|
+ ltq_mtd->map[i].bankwidth = 2;
|
||||||
|
+ ltq_mtd->map[i].read = ltq_read16;
|
||||||
|
+ ltq_mtd->map[i].write = ltq_write16;
|
||||||
|
+ ltq_mtd->map[i].copy_from = ltq_copy_from;
|
||||||
|
+ ltq_mtd->map[i].copy_to = ltq_copy_to;
|
||||||
|
+
|
||||||
|
+ if (of_find_property(pdev->dev.of_node, "lantiq,noxip", NULL))
|
||||||
|
+ ltq_mtd->map[i].phys = NO_XIP;
|
||||||
|
+ else
|
||||||
|
+ ltq_mtd->map[i].phys = pdev->resource[i].start;
|
||||||
|
+ ltq_mtd->map[i].size = resource_size(&pdev->resource[i]);
|
||||||
|
+ ltq_mtd->map[i].virt = devm_ioremap(&pdev->dev, ltq_mtd->map[i].phys,
|
||||||
|
+ ltq_mtd->map[i].size);
|
||||||
|
+ if (IS_ERR(ltq_mtd->map[i].virt))
|
||||||
|
+ return PTR_ERR(ltq_mtd->map[i].virt);
|
||||||
|
+
|
||||||
|
+ if (ltq_mtd->map[i].virt == NULL) {
|
||||||
|
+ dev_err(&pdev->dev, "Failed to ioremap flash region\n");
|
||||||
|
+ err = PTR_ERR(ltq_mtd->map[i].virt);
|
||||||
|
+ goto err_out;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ltq_mtd->map[i].map_priv_1 = LTQ_NOR_PROBING;
|
||||||
|
+ for (type = rom_probe_types; !ltq_mtd->mtd[i] && *type; type++)
|
||||||
|
+ ltq_mtd->mtd[i] = do_map_probe(*type, <q_mtd->map[i]);
|
||||||
|
+ ltq_mtd->map[i].map_priv_1 = LTQ_NOR_NORMAL;
|
||||||
|
+
|
||||||
|
+ if (!ltq_mtd->mtd[i]) {
|
||||||
|
+ dev_err(&pdev->dev, "probing failed\n");
|
||||||
|
+ return -ENXIO;
|
||||||
|
+ } else {
|
||||||
|
+ devices_found++;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ltq_mtd->mtd[i]->owner = THIS_MODULE;
|
||||||
|
+ ltq_mtd->mtd[i]->dev.parent = &pdev->dev;
|
||||||
|
+
|
||||||
|
+ cfi = ltq_mtd->map[i].fldrv_priv;
|
||||||
|
+ cfi->addr_unlock1 ^= 1;
|
||||||
|
+ cfi->addr_unlock2 ^= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ltq_mtd->map = devm_kzalloc(&pdev->dev, sizeof(struct map_info),
|
||||||
|
- GFP_KERNEL);
|
||||||
|
- if (!ltq_mtd->map)
|
||||||
|
- return -ENOMEM;
|
||||||
|
-
|
||||||
|
- if (of_find_property(pdev->dev.of_node, "lantiq,noxip", NULL))
|
||||||
|
- ltq_mtd->map->phys = NO_XIP;
|
||||||
|
- else
|
||||||
|
- ltq_mtd->map->phys = ltq_mtd->res->start;
|
||||||
|
- ltq_mtd->res->start;
|
||||||
|
- ltq_mtd->map->size = resource_size(ltq_mtd->res);
|
||||||
|
- ltq_mtd->map->virt = devm_ioremap_resource(&pdev->dev, ltq_mtd->res);
|
||||||
|
- if (IS_ERR(ltq_mtd->map->virt))
|
||||||
|
- return PTR_ERR(ltq_mtd->map->virt);
|
||||||
|
-
|
||||||
|
- ltq_mtd->map->name = ltq_map_name;
|
||||||
|
- ltq_mtd->map->bankwidth = 2;
|
||||||
|
- ltq_mtd->map->read = ltq_read16;
|
||||||
|
- ltq_mtd->map->write = ltq_write16;
|
||||||
|
- ltq_mtd->map->copy_from = ltq_copy_from;
|
||||||
|
- ltq_mtd->map->copy_to = ltq_copy_to;
|
||||||
|
-
|
||||||
|
- ltq_mtd->map->map_priv_1 = LTQ_NOR_PROBING;
|
||||||
|
- ltq_mtd->mtd = do_map_probe("cfi_probe", ltq_mtd->map);
|
||||||
|
- ltq_mtd->map->map_priv_1 = LTQ_NOR_NORMAL;
|
||||||
|
-
|
||||||
|
- if (!ltq_mtd->mtd) {
|
||||||
|
- dev_err(&pdev->dev, "probing failed\n");
|
||||||
|
- return -ENXIO;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- ltq_mtd->mtd->owner = THIS_MODULE;
|
||||||
|
-
|
||||||
|
- cfi = ltq_mtd->map->fldrv_priv;
|
||||||
|
- cfi->addr_unlock1 ^= 1;
|
||||||
|
- cfi->addr_unlock2 ^= 1;
|
||||||
|
+ if (devices_found == 1) {
|
||||||
|
+ ltq_mtd->cmtd = ltq_mtd->mtd[0];
|
||||||
|
+ } else if (devices_found > 1) {
|
||||||
|
+ /*
|
||||||
|
+ * We detected multiple devices. Concatenate them together.
|
||||||
|
+ */
|
||||||
|
+ ltq_mtd->cmtd = mtd_concat_create(ltq_mtd->mtd, devices_found, dev_name(&pdev->dev));
|
||||||
|
+ if (ltq_mtd->cmtd == NULL)
|
||||||
|
+ err = -ENXIO;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
ppdata.of_node = pdev->dev.of_node;
|
||||||
|
- err = mtd_device_parse_register(ltq_mtd->mtd, ltq_probe_types,
|
||||||
|
+ err = mtd_device_parse_register(ltq_mtd->cmtd, ltq_probe_types,
|
||||||
|
&ppdata, NULL, 0);
|
||||||
|
if (err) {
|
||||||
|
dev_err(&pdev->dev, "failed to add partitions\n");
|
||||||
|
- goto err_destroy;
|
||||||
|
+ goto err_out;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
-err_destroy:
|
||||||
|
- map_destroy(ltq_mtd->mtd);
|
||||||
|
+err_out:
|
||||||
|
+ ltq_mtd_remove(pdev);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int
|
||||||
|
-ltq_mtd_remove(struct platform_device *pdev)
|
||||||
|
-{
|
||||||
|
- struct ltq_mtd *ltq_mtd = platform_get_drvdata(pdev);
|
||||||
|
-
|
||||||
|
- if (ltq_mtd && ltq_mtd->mtd) {
|
||||||
|
- mtd_device_unregister(ltq_mtd->mtd);
|
||||||
|
- map_destroy(ltq_mtd->mtd);
|
||||||
|
- }
|
||||||
|
- return 0;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
static const struct of_device_id ltq_mtd_match[] = {
|
||||||
|
{ .compatible = "lantiq,nor" },
|
||||||
|
{},
|
|
@ -1,13 +1,28 @@
|
||||||
CONFIG_ADM6996_PHY=y
|
CONFIG_ADM6996_PHY=y
|
||||||
CONFIG_AR8216_PHY=y
|
CONFIG_AR8216_PHY=y
|
||||||
|
# CONFIG_ARCH_HAS_SG_CHAIN is not set
|
||||||
|
CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
|
||||||
|
CONFIG_ARCH_MIGHT_HAVE_PC_SERIO=y
|
||||||
|
# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set
|
||||||
CONFIG_CLONE_BACKWARDS=y
|
CONFIG_CLONE_BACKWARDS=y
|
||||||
|
CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y
|
||||||
|
CONFIG_CPU_SUPPORTS_MSA=y
|
||||||
CONFIG_CRC16=y
|
CONFIG_CRC16=y
|
||||||
CONFIG_CRYPTO_DEFLATE=y
|
CONFIG_CRYPTO_DEFLATE=y
|
||||||
CONFIG_CRYPTO_LZO=y
|
CONFIG_CRYPTO_LZO=y
|
||||||
CONFIG_FIRMWARE_IN_KERNEL=y
|
CONFIG_FIRMWARE_IN_KERNEL=y
|
||||||
CONFIG_GPIO_DEVRES=y
|
CONFIG_GPIO_DEVRES=y
|
||||||
|
CONFIG_HAS_IOPORT_MAP=y
|
||||||
# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
|
# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
|
||||||
|
CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
|
||||||
|
CONFIG_HAVE_ARCH_TRACEHOOK=y
|
||||||
# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
|
# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
|
||||||
|
CONFIG_HAVE_BPF_JIT=y
|
||||||
|
CONFIG_HAVE_CC_STACKPROTECTOR=y
|
||||||
|
CONFIG_HAVE_CONTEXT_TRACKING=y
|
||||||
|
CONFIG_HAVE_DEBUG_STACKOVERFLOW=y
|
||||||
|
CONFIG_HAVE_DMA_CONTIGUOUS=y
|
||||||
|
CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
|
||||||
CONFIG_HZ_PERIODIC=y
|
CONFIG_HZ_PERIODIC=y
|
||||||
CONFIG_INPUT=y
|
CONFIG_INPUT=y
|
||||||
CONFIG_INPUT_EVDEV=y
|
CONFIG_INPUT_EVDEV=y
|
||||||
|
@ -15,19 +30,19 @@ CONFIG_INPUT_POLLDEV=y
|
||||||
CONFIG_IRQCHIP=y
|
CONFIG_IRQCHIP=y
|
||||||
CONFIG_IRQ_WORK=y
|
CONFIG_IRQ_WORK=y
|
||||||
# CONFIG_ISDN is not set
|
# CONFIG_ISDN is not set
|
||||||
|
CONFIG_KERNFS=y
|
||||||
CONFIG_LANTIQ_PHY=y
|
CONFIG_LANTIQ_PHY=y
|
||||||
CONFIG_LANTIQ_XRX200=y
|
CONFIG_LANTIQ_XRX200=y
|
||||||
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
|
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
|
||||||
|
CONFIG_LIBFDT=y
|
||||||
CONFIG_LZO_COMPRESS=y
|
CONFIG_LZO_COMPRESS=y
|
||||||
CONFIG_LZO_DECOMPRESS=y
|
CONFIG_LZO_DECOMPRESS=y
|
||||||
CONFIG_M25PXX_USE_FAST_READ=y
|
|
||||||
CONFIG_MTD_M25P80=y
|
|
||||||
CONFIG_MTD_NAND=y
|
CONFIG_MTD_NAND=y
|
||||||
CONFIG_MTD_NAND_ECC=y
|
CONFIG_MTD_NAND_ECC=y
|
||||||
CONFIG_MTD_NAND_PLATFORM=y
|
CONFIG_MTD_NAND_PLATFORM=y
|
||||||
CONFIG_MTD_NAND_XWAY=y
|
CONFIG_MTD_NAND_XWAY=y
|
||||||
# CONFIG_MTD_PHYSMAP_OF is not set
|
# CONFIG_MTD_PHYSMAP_OF is not set
|
||||||
# CONFIG_MTD_SM_COMMON is not set
|
CONFIG_MTD_SPLIT_SUPPORT=y
|
||||||
CONFIG_MTD_UBI=y
|
CONFIG_MTD_UBI=y
|
||||||
CONFIG_MTD_UBI_BEB_LIMIT=20
|
CONFIG_MTD_UBI_BEB_LIMIT=20
|
||||||
CONFIG_MTD_UBI_BLOCK=y
|
CONFIG_MTD_UBI_BLOCK=y
|
||||||
|
@ -35,9 +50,10 @@ CONFIG_MTD_UBI_BLOCK=y
|
||||||
# CONFIG_MTD_UBI_GLUEBI is not set
|
# CONFIG_MTD_UBI_GLUEBI is not set
|
||||||
CONFIG_MTD_UBI_WL_THRESHOLD=4096
|
CONFIG_MTD_UBI_WL_THRESHOLD=4096
|
||||||
CONFIG_NLS=y
|
CONFIG_NLS=y
|
||||||
|
# CONFIG_NO_IOPORT_MAP is not set
|
||||||
|
CONFIG_OF_ADDRESS_PCI=y
|
||||||
CONFIG_PCIE_LANTIQ=y
|
CONFIG_PCIE_LANTIQ=y
|
||||||
# CONFIG_PCI_LANTIQ is not set
|
# CONFIG_PCI_LANTIQ is not set
|
||||||
# CONFIG_PROC_DEVICETREE is not set
|
|
||||||
# CONFIG_RCU_STALL_COMMON is not set
|
# CONFIG_RCU_STALL_COMMON is not set
|
||||||
CONFIG_RTL8306_PHY=y
|
CONFIG_RTL8306_PHY=y
|
||||||
CONFIG_RTL8366S_PHY=y
|
CONFIG_RTL8366S_PHY=y
|
||||||
|
@ -48,6 +64,7 @@ CONFIG_SPI_BITBANG=y
|
||||||
CONFIG_SPI_GPIO=y
|
CONFIG_SPI_GPIO=y
|
||||||
CONFIG_SPI_MASTER=y
|
CONFIG_SPI_MASTER=y
|
||||||
CONFIG_SPI_XWAY=y
|
CONFIG_SPI_XWAY=y
|
||||||
|
CONFIG_SYS_SUPPORTS_MIPS16=y
|
||||||
CONFIG_UBIFS_FS=y
|
CONFIG_UBIFS_FS=y
|
||||||
CONFIG_UBIFS_FS_ADVANCED_COMPR=y
|
CONFIG_UBIFS_FS_ADVANCED_COMPR=y
|
||||||
CONFIG_UBIFS_FS_LZO=y
|
CONFIG_UBIFS_FS_LZO=y
|
||||||
|
|
|
@ -1,13 +1,28 @@
|
||||||
CONFIG_ADM6996_PHY=y
|
CONFIG_ADM6996_PHY=y
|
||||||
CONFIG_AR8216_PHY=y
|
CONFIG_AR8216_PHY=y
|
||||||
|
# CONFIG_ARCH_HAS_SG_CHAIN is not set
|
||||||
|
CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
|
||||||
|
CONFIG_ARCH_MIGHT_HAVE_PC_SERIO=y
|
||||||
|
# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set
|
||||||
CONFIG_CLONE_BACKWARDS=y
|
CONFIG_CLONE_BACKWARDS=y
|
||||||
|
CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y
|
||||||
|
CONFIG_CPU_SUPPORTS_MSA=y
|
||||||
CONFIG_CRC16=y
|
CONFIG_CRC16=y
|
||||||
CONFIG_CRYPTO_DEFLATE=y
|
CONFIG_CRYPTO_DEFLATE=y
|
||||||
CONFIG_CRYPTO_LZO=y
|
CONFIG_CRYPTO_LZO=y
|
||||||
CONFIG_FIRMWARE_IN_KERNEL=y
|
CONFIG_FIRMWARE_IN_KERNEL=y
|
||||||
CONFIG_GPIO_DEVRES=y
|
CONFIG_GPIO_DEVRES=y
|
||||||
|
CONFIG_HAS_IOPORT_MAP=y
|
||||||
# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
|
# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
|
||||||
|
CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
|
||||||
|
CONFIG_HAVE_ARCH_TRACEHOOK=y
|
||||||
# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
|
# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
|
||||||
|
CONFIG_HAVE_BPF_JIT=y
|
||||||
|
CONFIG_HAVE_CC_STACKPROTECTOR=y
|
||||||
|
CONFIG_HAVE_CONTEXT_TRACKING=y
|
||||||
|
CONFIG_HAVE_DEBUG_STACKOVERFLOW=y
|
||||||
|
CONFIG_HAVE_DMA_CONTIGUOUS=y
|
||||||
|
CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
|
||||||
CONFIG_HZ_PERIODIC=y
|
CONFIG_HZ_PERIODIC=y
|
||||||
CONFIG_INPUT=y
|
CONFIG_INPUT=y
|
||||||
CONFIG_INPUT_EVDEV=y
|
CONFIG_INPUT_EVDEV=y
|
||||||
|
@ -15,17 +30,17 @@ CONFIG_INPUT_POLLDEV=y
|
||||||
CONFIG_IRQCHIP=y
|
CONFIG_IRQCHIP=y
|
||||||
CONFIG_IRQ_WORK=y
|
CONFIG_IRQ_WORK=y
|
||||||
# CONFIG_ISDN is not set
|
# CONFIG_ISDN is not set
|
||||||
|
CONFIG_KERNFS=y
|
||||||
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
|
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
|
||||||
|
CONFIG_LIBFDT=y
|
||||||
CONFIG_LZO_COMPRESS=y
|
CONFIG_LZO_COMPRESS=y
|
||||||
CONFIG_LZO_DECOMPRESS=y
|
CONFIG_LZO_DECOMPRESS=y
|
||||||
CONFIG_M25PXX_USE_FAST_READ=y
|
|
||||||
CONFIG_MTD_M25P80=y
|
|
||||||
CONFIG_MTD_NAND=y
|
CONFIG_MTD_NAND=y
|
||||||
CONFIG_MTD_NAND_ECC=y
|
CONFIG_MTD_NAND_ECC=y
|
||||||
CONFIG_MTD_NAND_PLATFORM=y
|
CONFIG_MTD_NAND_PLATFORM=y
|
||||||
CONFIG_MTD_NAND_XWAY=y
|
CONFIG_MTD_NAND_XWAY=y
|
||||||
# CONFIG_MTD_PHYSMAP_OF is not set
|
# CONFIG_MTD_PHYSMAP_OF is not set
|
||||||
# CONFIG_MTD_SM_COMMON is not set
|
CONFIG_MTD_SPLIT_SUPPORT=y
|
||||||
CONFIG_MTD_SPLIT_UIMAGE_FW=y
|
CONFIG_MTD_SPLIT_UIMAGE_FW=y
|
||||||
CONFIG_MTD_UBI=y
|
CONFIG_MTD_UBI=y
|
||||||
CONFIG_MTD_UBI_BEB_LIMIT=20
|
CONFIG_MTD_UBI_BEB_LIMIT=20
|
||||||
|
@ -34,7 +49,8 @@ CONFIG_MTD_UBI_BLOCK=y
|
||||||
# CONFIG_MTD_UBI_GLUEBI is not set
|
# CONFIG_MTD_UBI_GLUEBI is not set
|
||||||
CONFIG_MTD_UBI_WL_THRESHOLD=4096
|
CONFIG_MTD_UBI_WL_THRESHOLD=4096
|
||||||
CONFIG_NLS=y
|
CONFIG_NLS=y
|
||||||
# CONFIG_PROC_DEVICETREE is not set
|
# CONFIG_NO_IOPORT_MAP is not set
|
||||||
|
CONFIG_OF_ADDRESS_PCI=y
|
||||||
# CONFIG_RCU_STALL_COMMON is not set
|
# CONFIG_RCU_STALL_COMMON is not set
|
||||||
CONFIG_RTL8306_PHY=y
|
CONFIG_RTL8306_PHY=y
|
||||||
CONFIG_RTL8366S_PHY=y
|
CONFIG_RTL8366S_PHY=y
|
||||||
|
@ -45,6 +61,7 @@ CONFIG_SPI_BITBANG=y
|
||||||
CONFIG_SPI_GPIO=y
|
CONFIG_SPI_GPIO=y
|
||||||
CONFIG_SPI_MASTER=y
|
CONFIG_SPI_MASTER=y
|
||||||
CONFIG_SPI_XWAY=y
|
CONFIG_SPI_XWAY=y
|
||||||
|
CONFIG_SYS_SUPPORTS_MIPS16=y
|
||||||
CONFIG_UBIFS_FS=y
|
CONFIG_UBIFS_FS=y
|
||||||
CONFIG_UBIFS_FS_ADVANCED_COMPR=y
|
CONFIG_UBIFS_FS_ADVANCED_COMPR=y
|
||||||
CONFIG_UBIFS_FS_LZO=y
|
CONFIG_UBIFS_FS_LZO=y
|
||||||
|
|
Loading…
Reference in a new issue