mirror of https://github.com/hak5/openwrt-owl.git
mcs814x: add support for 3.18
Signed-off-by: Florian Fainelli <florian@openwrt.org> SVN-Revision: 45273owl
parent
c31df6e995
commit
b1ba4c5096
|
@ -0,0 +1,230 @@
|
||||||
|
CONFIG_ALIGNMENT_TRAP=y
|
||||||
|
CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
|
||||||
|
CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
|
||||||
|
# CONFIG_ARCH_HAS_SG_CHAIN is not set
|
||||||
|
CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
|
||||||
|
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
|
||||||
|
CONFIG_ARCH_MCS814X=y
|
||||||
|
CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
|
||||||
|
CONFIG_ARCH_NR_GPIO=0
|
||||||
|
CONFIG_ARCH_REQUIRE_GPIOLIB=y
|
||||||
|
# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
|
||||||
|
# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
|
||||||
|
CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y
|
||||||
|
CONFIG_ARCH_SUPPORTS_UPROBES=y
|
||||||
|
CONFIG_ARCH_SUSPEND_POSSIBLE=y
|
||||||
|
CONFIG_ARCH_USES_GETTIMEOFFSET=y
|
||||||
|
CONFIG_ARCH_USE_BUILTIN_BSWAP=y
|
||||||
|
CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y
|
||||||
|
CONFIG_ARCH_WANT_GENERAL_HUGETLB=y
|
||||||
|
CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
|
||||||
|
CONFIG_ARM=y
|
||||||
|
CONFIG_ARM_APPENDED_DTB=y
|
||||||
|
# CONFIG_ARM_ATAG_DTB_COMPAT is not set
|
||||||
|
# CONFIG_ARM_CPU_SUSPEND is not set
|
||||||
|
CONFIG_ARM_L1_CACHE_SHIFT=5
|
||||||
|
# CONFIG_ARM_THUMB is not set
|
||||||
|
CONFIG_BINFMT_MISC=y
|
||||||
|
# CONFIG_BRIDGE is not set
|
||||||
|
# CONFIG_CACHE_L2X0 is not set
|
||||||
|
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
|
||||||
|
CONFIG_CLKDEV_LOOKUP=y
|
||||||
|
CONFIG_CLONE_BACKWARDS=y
|
||||||
|
CONFIG_CMDLINE="earlyprintk"
|
||||||
|
CONFIG_CPU_32v5=y
|
||||||
|
CONFIG_CPU_ABRT_EV5TJ=y
|
||||||
|
CONFIG_CPU_ARM926T=y
|
||||||
|
# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
|
||||||
|
CONFIG_CPU_CACHE_VIVT=y
|
||||||
|
CONFIG_CPU_COPY_V4WB=y
|
||||||
|
CONFIG_CPU_CP15=y
|
||||||
|
CONFIG_CPU_CP15_MMU=y
|
||||||
|
# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
|
||||||
|
# CONFIG_CPU_ICACHE_DISABLE is not set
|
||||||
|
CONFIG_CPU_PABRT_LEGACY=y
|
||||||
|
CONFIG_CPU_TLB_V4WBI=y
|
||||||
|
CONFIG_CPU_USE_DOMAINS=y
|
||||||
|
CONFIG_CRC_CCITT=y
|
||||||
|
CONFIG_CRC_ITU_T=y
|
||||||
|
CONFIG_CRYPTO_CRC32C=y
|
||||||
|
CONFIG_CRYPTO_HASH=y
|
||||||
|
CONFIG_CRYPTO_HASH2=y
|
||||||
|
CONFIG_DEBUG_LL=y
|
||||||
|
CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
|
||||||
|
CONFIG_DEBUG_LL_UART_NONE=y
|
||||||
|
# CONFIG_DEBUG_UART_8250 is not set
|
||||||
|
# CONFIG_DEBUG_UART_PL01X is not set
|
||||||
|
# CONFIG_DEBUG_USER is not set
|
||||||
|
CONFIG_DTC=y
|
||||||
|
CONFIG_EARLY_PRINTK=y
|
||||||
|
# CONFIG_ENABLE_WARN_DEPRECATED is not set
|
||||||
|
CONFIG_FIQ=y
|
||||||
|
CONFIG_FRAME_POINTER=y
|
||||||
|
CONFIG_GENERIC_ALLOCATOR=y
|
||||||
|
CONFIG_GENERIC_ATOMIC64=y
|
||||||
|
CONFIG_GENERIC_BUG=y
|
||||||
|
CONFIG_GENERIC_IDLE_POLL_SETUP=y
|
||||||
|
CONFIG_GENERIC_IO=y
|
||||||
|
CONFIG_GENERIC_IRQ_CHIP=y
|
||||||
|
CONFIG_GENERIC_IRQ_SHOW=y
|
||||||
|
CONFIG_GENERIC_PCI_IOMAP=y
|
||||||
|
CONFIG_GENERIC_SCHED_CLOCK=y
|
||||||
|
CONFIG_GENERIC_SMP_IDLE_THREAD=y
|
||||||
|
CONFIG_GENERIC_STRNCPY_FROM_USER=y
|
||||||
|
CONFIG_GENERIC_STRNLEN_USER=y
|
||||||
|
CONFIG_GPIOLIB=y
|
||||||
|
CONFIG_GPIO_DEVRES=y
|
||||||
|
CONFIG_GPIO_MCS814X=y
|
||||||
|
CONFIG_GPIO_SYSFS=y
|
||||||
|
CONFIG_HANDLE_DOMAIN_IRQ=y
|
||||||
|
CONFIG_HARDIRQS_SW_RESEND=y
|
||||||
|
CONFIG_HAS_DMA=y
|
||||||
|
CONFIG_HAS_IOMEM=y
|
||||||
|
CONFIG_HAS_IOPORT_MAP=y
|
||||||
|
# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
|
||||||
|
CONFIG_HAVE_ARCH_AUDITSYSCALL=y
|
||||||
|
CONFIG_HAVE_ARCH_JUMP_LABEL=y
|
||||||
|
CONFIG_HAVE_ARCH_KGDB=y
|
||||||
|
CONFIG_HAVE_ARCH_PFN_VALID=y
|
||||||
|
CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
|
||||||
|
CONFIG_HAVE_ARCH_TRACEHOOK=y
|
||||||
|
# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
|
||||||
|
CONFIG_HAVE_BPF_JIT=y
|
||||||
|
CONFIG_HAVE_CC_STACKPROTECTOR=y
|
||||||
|
CONFIG_HAVE_CLK=y
|
||||||
|
CONFIG_HAVE_CONTEXT_TRACKING=y
|
||||||
|
CONFIG_HAVE_C_RECORDMCOUNT=y
|
||||||
|
CONFIG_HAVE_DEBUG_KMEMLEAK=y
|
||||||
|
CONFIG_HAVE_DMA_API_DEBUG=y
|
||||||
|
CONFIG_HAVE_DMA_ATTRS=y
|
||||||
|
CONFIG_HAVE_DMA_CONTIGUOUS=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_GENERIC_DMA_COHERENT=y
|
||||||
|
CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
|
||||||
|
CONFIG_HAVE_KERNEL_GZIP=y
|
||||||
|
CONFIG_HAVE_KERNEL_LZ4=y
|
||||||
|
CONFIG_HAVE_KERNEL_LZMA=y
|
||||||
|
CONFIG_HAVE_KERNEL_LZO=y
|
||||||
|
CONFIG_HAVE_KERNEL_XZ=y
|
||||||
|
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
|
||||||
|
CONFIG_HAVE_MEMBLOCK=y
|
||||||
|
CONFIG_HAVE_NET_DSA=y
|
||||||
|
CONFIG_HAVE_OPROFILE=y
|
||||||
|
CONFIG_HAVE_PERF_EVENTS=y
|
||||||
|
CONFIG_HAVE_PERF_REGS=y
|
||||||
|
CONFIG_HAVE_PERF_USER_STACK_DUMP=y
|
||||||
|
CONFIG_HAVE_PROC_CPU=y
|
||||||
|
CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
|
||||||
|
CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
|
||||||
|
CONFIG_HAVE_UID16=y
|
||||||
|
CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y
|
||||||
|
CONFIG_HW_RANDOM=y
|
||||||
|
CONFIG_HW_RANDOM_MCS814X=y
|
||||||
|
CONFIG_HZ_FIXED=0
|
||||||
|
CONFIG_INITRAMFS_SOURCE=""
|
||||||
|
CONFIG_IOMMU_HELPER=y
|
||||||
|
CONFIG_IRQCHIP=y
|
||||||
|
CONFIG_IRQ_DOMAIN=y
|
||||||
|
CONFIG_IRQ_FORCED_THREADING=y
|
||||||
|
CONFIG_IRQ_WORK=y
|
||||||
|
# CONFIG_ISDN is not set
|
||||||
|
CONFIG_JFFS2_LZO=y
|
||||||
|
CONFIG_JFFS2_RUBIN=y
|
||||||
|
# CONFIG_JFFS2_SUMMARY is not set
|
||||||
|
CONFIG_JFFS2_ZLIB=y
|
||||||
|
CONFIG_KALLSYMS=y
|
||||||
|
CONFIG_LEDS_GPIO=y
|
||||||
|
# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
|
||||||
|
# CONFIG_LEDS_TRIGGER_NETDEV is not set
|
||||||
|
# CONFIG_LEDS_TRIGGER_TIMER is not set
|
||||||
|
CONFIG_LIBCRC32C=y
|
||||||
|
CONFIG_LIBFDT=y
|
||||||
|
CONFIG_LZO_COMPRESS=y
|
||||||
|
CONFIG_LZO_DECOMPRESS=y
|
||||||
|
CONFIG_MACH_DLAN_USB_EXT=y
|
||||||
|
CONFIG_MACH_RBT_832=y
|
||||||
|
CONFIG_MCS8140=y
|
||||||
|
CONFIG_MCS814X_PHY=y
|
||||||
|
# CONFIG_MCS814X_WATCHDOG is not set
|
||||||
|
CONFIG_MDIO_BOARDINFO=y
|
||||||
|
CONFIG_MODULES_USE_ELF_REL=y
|
||||||
|
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
|
||||||
|
# CONFIG_MTD_IMPA7 is not set
|
||||||
|
CONFIG_MTD_JEDECPROBE=y
|
||||||
|
CONFIG_MTD_PHYSMAP=y
|
||||||
|
CONFIG_MULTI_IRQ_HANDLER=y
|
||||||
|
CONFIG_NEED_DMA_MAP_STATE=y
|
||||||
|
CONFIG_NEED_KUSER_HELPERS=y
|
||||||
|
CONFIG_NEED_MACH_MEMORY_H=y
|
||||||
|
CONFIG_NEED_PER_CPU_KM=y
|
||||||
|
CONFIG_NET_KEY=y
|
||||||
|
# CONFIG_NET_VENDOR_BROADCOM is not set
|
||||||
|
# CONFIG_NET_VENDOR_FARADAY is not set
|
||||||
|
# CONFIG_NET_VENDOR_INTEL is not set
|
||||||
|
# CONFIG_NET_VENDOR_MARVELL is not set
|
||||||
|
# CONFIG_NET_VENDOR_MICREL is not set
|
||||||
|
# CONFIG_NET_VENDOR_NATSEMI is not set
|
||||||
|
# CONFIG_NET_VENDOR_SEEQ is not set
|
||||||
|
# CONFIG_NET_VENDOR_SMSC is not set
|
||||||
|
# CONFIG_NET_VENDOR_STMICRO is not set
|
||||||
|
CONFIG_NLS=y
|
||||||
|
CONFIG_NLS_DEFAULT="iso8859-15"
|
||||||
|
CONFIG_NO_BOOTMEM=y
|
||||||
|
CONFIG_NUPORT_ETHERNET_DRIVER=y
|
||||||
|
CONFIG_OF=y
|
||||||
|
CONFIG_OF_ADDRESS=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_RESERVED_MEM=y
|
||||||
|
CONFIG_OLD_SIGACTION=y
|
||||||
|
CONFIG_OLD_SIGSUSPEND3=y
|
||||||
|
CONFIG_PAGEFLAGS_EXTENDED=y
|
||||||
|
CONFIG_PAGE_OFFSET=0xC0000000
|
||||||
|
# CONFIG_PARTITION_ADVANCED is not set
|
||||||
|
# CONFIG_PCI_SYSCALL is not set
|
||||||
|
CONFIG_PERF_USE_VMALLOC=y
|
||||||
|
CONFIG_PHYLIB=y
|
||||||
|
CONFIG_PHYS_OFFSET=0x00000000
|
||||||
|
# CONFIG_PREEMPT_RCU is not set
|
||||||
|
# CONFIG_PREVENT_FIRMWARE_BUILD is not set
|
||||||
|
# CONFIG_RCU_STALL_COMMON is not set
|
||||||
|
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
|
||||||
|
# CONFIG_SCHED_HRTICK is not set
|
||||||
|
# CONFIG_SCSI_DMA is not set
|
||||||
|
CONFIG_SERIAL_OF_PLATFORM=y
|
||||||
|
CONFIG_SPLIT_PTLOCK_CPUS=999999
|
||||||
|
# CONFIG_SWAP is not set
|
||||||
|
CONFIG_SWIOTLB=y
|
||||||
|
# CONFIG_SYN_COOKIES is not set
|
||||||
|
CONFIG_SYSCTL_SYSCALL=y
|
||||||
|
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
|
||||||
|
CONFIG_TICK_CPU_ACCOUNTING=y
|
||||||
|
CONFIG_UID16=y
|
||||||
|
CONFIG_UNCOMPRESS_INCLUDE="mach/uncompress.h"
|
||||||
|
CONFIG_USB_SUPPORT=y
|
||||||
|
CONFIG_USE_OF=y
|
||||||
|
CONFIG_VECTORS_BASE=0xffff0000
|
||||||
|
# CONFIG_VFP is not set
|
||||||
|
# CONFIG_VLAN_8021Q is not set
|
||||||
|
CONFIG_VM_EVENT_COUNTERS=y
|
||||||
|
CONFIG_WATCHDOG_CORE=y
|
||||||
|
CONFIG_WATCHDOG_NOWAYOUT=y
|
||||||
|
# CONFIG_WEXT_PRIV is not set
|
||||||
|
# CONFIG_WEXT_SPY is not set
|
||||||
|
# CONFIG_WIRELESS_EXT is not set
|
||||||
|
CONFIG_XFRM_ALGO=y
|
||||||
|
CONFIG_XZ_DEC_ARM=y
|
||||||
|
CONFIG_XZ_DEC_BCJ=y
|
||||||
|
CONFIG_ZBOOT_ROM_BSS=0
|
||||||
|
CONFIG_ZBOOT_ROM_TEXT=0
|
||||||
|
CONFIG_ZLIB_DEFLATE=y
|
||||||
|
CONFIG_ZLIB_INFLATE=y
|
||||||
|
CONFIG_ZONE_DMA_FLAG=0
|
|
@ -0,0 +1,76 @@
|
||||||
|
/*
|
||||||
|
* dlan-usb-extender.dts - Device Tree file for Devolo dLAN USB Extender
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012, Florian Fainelli <florian@openwrt.org>
|
||||||
|
*
|
||||||
|
* Licensed under GPLv2
|
||||||
|
*/
|
||||||
|
|
||||||
|
/dts-v1/;
|
||||||
|
/include/ "mcs8140.dtsi"
|
||||||
|
|
||||||
|
/ {
|
||||||
|
model = "Devolo dLAN USB Extender";
|
||||||
|
compatible = "devolo,dlan-usb-extender", "moschip,mcs8140", "moschip,mcs814x";
|
||||||
|
|
||||||
|
chosen {
|
||||||
|
bootargs = "mem=16M console=ttyS0,57600 earlyprintk";
|
||||||
|
};
|
||||||
|
|
||||||
|
ahb {
|
||||||
|
vci {
|
||||||
|
eth0: ethernet@40084000 {
|
||||||
|
phy = <&phy0>;
|
||||||
|
phy-mode = "mii";
|
||||||
|
|
||||||
|
phy0: ethernet-phy@0 {
|
||||||
|
reg = <8>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
adc {
|
||||||
|
sdram: memory@0,0 {
|
||||||
|
reg = <0 0 0x1000000>;
|
||||||
|
};
|
||||||
|
|
||||||
|
nor: flash@7,0 {
|
||||||
|
|
||||||
|
partition@0 {
|
||||||
|
label = "ArmBoot";
|
||||||
|
reg = <0 0x30000>;
|
||||||
|
};
|
||||||
|
partition@30000 {
|
||||||
|
label = "Config1";
|
||||||
|
reg = <0x30000 0x10000>;
|
||||||
|
};
|
||||||
|
partition@40000 {
|
||||||
|
label = "Config2";
|
||||||
|
reg = <0x40000 0x10000>;
|
||||||
|
};
|
||||||
|
partition@50000 {
|
||||||
|
label = "kernel";
|
||||||
|
reg = <0x50000 0x100000>;
|
||||||
|
};
|
||||||
|
partition@150000 {
|
||||||
|
label = "rootfs";
|
||||||
|
reg = <0x150000 0x3C0000>;
|
||||||
|
};
|
||||||
|
partition@50001 {
|
||||||
|
label = "linux";
|
||||||
|
reg = <0x50000 0x4C0000>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
leds {
|
||||||
|
compatible = "gpio-leds";
|
||||||
|
|
||||||
|
usb {
|
||||||
|
label = "dlan-usb-extender:green:usb";
|
||||||
|
gpios = <&gpio 19 0>; // gpio 19 active high
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
|
@ -0,0 +1,189 @@
|
||||||
|
/*
|
||||||
|
* mcs8140.dtsi - Device Tree Include file for Moschip MCS8140 family SoC
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012, Florian Fainelli <florian@openwrt.org>
|
||||||
|
*
|
||||||
|
* Licensed under GPLv2.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/include/ "skeleton.dtsi"
|
||||||
|
|
||||||
|
/ {
|
||||||
|
model = "Moschip MCS8140 family SoC";
|
||||||
|
compatible = "moschip,mcs8140";
|
||||||
|
interrupt-parent = <&intc>;
|
||||||
|
|
||||||
|
aliases {
|
||||||
|
serial0 = &uart0;
|
||||||
|
eth0 = ð0;
|
||||||
|
};
|
||||||
|
|
||||||
|
cpus {
|
||||||
|
cpu@0 {
|
||||||
|
compatible = "arm,arm926ejs";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
ahb {
|
||||||
|
compatible = "simple-bus";
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <1>;
|
||||||
|
ranges;
|
||||||
|
|
||||||
|
vci {
|
||||||
|
compatible = "simple-bus";
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <1>;
|
||||||
|
ranges;
|
||||||
|
|
||||||
|
eth0: ethernet@40084000 {
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
|
||||||
|
compatible = "moschip,nuport-mac";
|
||||||
|
reg = <0x40084000 0xd8 // mac
|
||||||
|
0x40080000 0x58>; // dma channels
|
||||||
|
interrupts = <4 5 29>; /* tx, rx, link */
|
||||||
|
nuport-mac,buffer-shifting;
|
||||||
|
nuport-mac,link-activity = <0>;
|
||||||
|
};
|
||||||
|
|
||||||
|
tso@40088000 {
|
||||||
|
reg = <0x40088000 0x1c>;
|
||||||
|
interrupts = <7>;
|
||||||
|
};
|
||||||
|
|
||||||
|
i2s@4008c000 {
|
||||||
|
compatible = "moschip,mcs814x-i2s";
|
||||||
|
reg = <0x4008c000 0x18>;
|
||||||
|
interrupts = <8>;
|
||||||
|
};
|
||||||
|
|
||||||
|
ipsec@40094000 {
|
||||||
|
compatible = "moschip,mcs814x-ipsec";
|
||||||
|
reg = <0x40094000 0x1d8>;
|
||||||
|
interrupts = <16>;
|
||||||
|
};
|
||||||
|
|
||||||
|
rng@4009c000 {
|
||||||
|
compatible = "moschip,mcs814x-rng";
|
||||||
|
reg = <0x4009c000 0x8>;
|
||||||
|
};
|
||||||
|
|
||||||
|
memc@400a8000 {
|
||||||
|
reg = <0x400a8000 0x58>;
|
||||||
|
};
|
||||||
|
|
||||||
|
list-proc@400ac0c0 {
|
||||||
|
reg = <0x400ac0c0 0x38>;
|
||||||
|
interrupts = <19 27>; // done, error
|
||||||
|
};
|
||||||
|
|
||||||
|
gpio: gpio@400d0000 {
|
||||||
|
compatible = "moschip,mcs814x-gpio";
|
||||||
|
reg = <0x400d0000 0x670>;
|
||||||
|
interrupts = <10>;
|
||||||
|
#gpio-cells = <2>;
|
||||||
|
gpio-controller;
|
||||||
|
num-gpios = <20>;
|
||||||
|
};
|
||||||
|
|
||||||
|
eepio: gpio@400d4000 {
|
||||||
|
compatible = "moschip,mcs814x-gpio";
|
||||||
|
reg = <0x400d4000 0x470>;
|
||||||
|
#gpio-cells = <2>;
|
||||||
|
gpio-controller;
|
||||||
|
num-gpios = <4>;
|
||||||
|
};
|
||||||
|
|
||||||
|
uart0: serial@400dc000 {
|
||||||
|
compatible = "ns16550";
|
||||||
|
reg = <0x400dc000 0x20>;
|
||||||
|
clock-frequency = <50000000>;
|
||||||
|
reg-shift = <2>;
|
||||||
|
interrupts = <21>;
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
|
intc: interrupt-controller@400e4000 {
|
||||||
|
#interrupt-cells = <1>;
|
||||||
|
compatible = "moschip,mcs814x-intc";
|
||||||
|
interrupt-controller;
|
||||||
|
interrupt-parent;
|
||||||
|
reg = <0x400e4000 0x48>;
|
||||||
|
};
|
||||||
|
|
||||||
|
m2m@400e8000 {
|
||||||
|
reg = <0x400e8000 0x24>;
|
||||||
|
interrupts = <17>;
|
||||||
|
};
|
||||||
|
|
||||||
|
eth-filters@400ec000 {
|
||||||
|
reg = <0x400ec000 0x80>;
|
||||||
|
};
|
||||||
|
|
||||||
|
timer: timer@400f800c {
|
||||||
|
compatible = "moschip,mcs814x-timer";
|
||||||
|
interrupts = <0>;
|
||||||
|
reg = <0x400f800c 0x8>;
|
||||||
|
};
|
||||||
|
|
||||||
|
watchdog@400f8014 {
|
||||||
|
compatible = "moschip,mcs814x-wdt";
|
||||||
|
reg = <0x400f8014 0x8>;
|
||||||
|
};
|
||||||
|
|
||||||
|
adc {
|
||||||
|
compatible = "simple-bus";
|
||||||
|
#address-cells = <2>;
|
||||||
|
#size-cells = <1>;
|
||||||
|
// 8 64MB chip-selects
|
||||||
|
ranges = <0 0 0x00000000 0x4000000 // sdram
|
||||||
|
1 0 0x04000000 0x4000000 // sdram
|
||||||
|
2 0 0x08000000 0x4000000 // reserved
|
||||||
|
3 0 0x0c000000 0x4000000 // flash/localbus
|
||||||
|
4 0 0x10000000 0x4000000 // flash/localbus
|
||||||
|
5 0 0x14000000 0x4000000 // flash/localbus
|
||||||
|
6 0 0x18000000 0x4000000 // flash/localbus
|
||||||
|
7 0 0x1c000000 0x4000000>; // flash/localbus
|
||||||
|
|
||||||
|
sdram: memory@0,0 {
|
||||||
|
reg = <0 0 0>;
|
||||||
|
};
|
||||||
|
|
||||||
|
nor: flash@7,0 {
|
||||||
|
reg = <7 0 0x4000000>;
|
||||||
|
compatible = "cfi-flash";
|
||||||
|
bank-width = <1>; // 8-bit external flash
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <1>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
usb0: ehci@400fc000 {
|
||||||
|
compatible = "moschip,mcs814x-ehci", "usb-ehci";
|
||||||
|
reg = <0x400fc000 0x74>;
|
||||||
|
interrupts = <2>;
|
||||||
|
};
|
||||||
|
|
||||||
|
usb1: ohci@400fd000 {
|
||||||
|
compatible = "moschip,mcs814x-ohci", "ohci-le";
|
||||||
|
reg = <0x400fd000 0x74>;
|
||||||
|
interrupts = <11>;
|
||||||
|
};
|
||||||
|
|
||||||
|
usb2: ohci@400fe000 {
|
||||||
|
compatible = "moschip,mcs814x-ohci", "ohci-le";
|
||||||
|
reg = <0x400fe000 0x74>;
|
||||||
|
interrupts = <12>;
|
||||||
|
};
|
||||||
|
|
||||||
|
usb3: otg@400ff000 {
|
||||||
|
compatible = "moschip,msc814x-otg", "usb-otg";
|
||||||
|
reg = <0x400ff000 0x1000>;
|
||||||
|
interrupts = <13>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,89 @@
|
||||||
|
/*
|
||||||
|
* rbt-832.dts - Device Tree file for Tigal RBT-832
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012, Florian Fainelli <florian@openwrt.org>
|
||||||
|
*
|
||||||
|
* Licensed under GPLv2
|
||||||
|
*/
|
||||||
|
|
||||||
|
/dts-v1/;
|
||||||
|
/include/ "mcs8140.dtsi"
|
||||||
|
|
||||||
|
/ {
|
||||||
|
model = "Tigal RBT-832";
|
||||||
|
compatible = "tigal,rbt-832", "moschip,mcs8140", "moschip,mcs814x";
|
||||||
|
|
||||||
|
chosen {
|
||||||
|
bootargs = "mem=32M console=ttyS0,115200 earlyprintk";
|
||||||
|
};
|
||||||
|
|
||||||
|
ahb {
|
||||||
|
vci {
|
||||||
|
eth0: ethernet@40084000 {
|
||||||
|
nuport-mac,link-activity = <0x01>;
|
||||||
|
phy = <&phy0>;
|
||||||
|
phy-mode = "mii";
|
||||||
|
|
||||||
|
phy0: ethernet-phy@0 {
|
||||||
|
reg = <1>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
adc {
|
||||||
|
sdram: memory@0,0 {
|
||||||
|
reg = <0 0 0x2000000>;
|
||||||
|
};
|
||||||
|
|
||||||
|
nor: flash@7,0 {
|
||||||
|
|
||||||
|
partition@0 {
|
||||||
|
label = "ArmBoot";
|
||||||
|
reg = <0 0x40000>;
|
||||||
|
};
|
||||||
|
partition@30000 {
|
||||||
|
label = "Enviroment";
|
||||||
|
reg = <0x40000 0x20000>;
|
||||||
|
};
|
||||||
|
partition@50000 {
|
||||||
|
label = "bZimage";
|
||||||
|
reg = <0x60000 0x1a0000>;
|
||||||
|
};
|
||||||
|
partition@150000 {
|
||||||
|
label = "UserFS";
|
||||||
|
reg = <0x200000 0x600000>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
leds {
|
||||||
|
compatible = "gpio-leds";
|
||||||
|
|
||||||
|
ethernet {
|
||||||
|
label = "rbt-832:red:ethernet";
|
||||||
|
gpios = <&gpio 0 0>; // gpio 0 active high
|
||||||
|
};
|
||||||
|
|
||||||
|
usb0 {
|
||||||
|
label = "rbt-832:red:usb0";
|
||||||
|
gpios = <&gpio 4 0>; // gpio 4 active high
|
||||||
|
};
|
||||||
|
|
||||||
|
usb1 {
|
||||||
|
label = "rbt-832:red:usb1";
|
||||||
|
gpios = <&gpio 3 0>; // gpio 3 active high
|
||||||
|
};
|
||||||
|
|
||||||
|
usb2 {
|
||||||
|
label = "rbt-832:red:usb2";
|
||||||
|
gpios = <&gpio 2 0>; // gpio 2 active high
|
||||||
|
};
|
||||||
|
|
||||||
|
usb3 {
|
||||||
|
label = "rbt-832:red:usb3";
|
||||||
|
gpios = <&gpio 1 0>; // gpio 1 active high
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
if ARCH_MCS814X
|
||||||
|
|
||||||
|
config MCS8140
|
||||||
|
bool
|
||||||
|
select CPU_ARM926T
|
||||||
|
|
||||||
|
menu "Moschip MCS8140 boards"
|
||||||
|
|
||||||
|
config MACH_DLAN_USB_EXT
|
||||||
|
bool "Devolo dLAN USB Extender"
|
||||||
|
select MCS8140
|
||||||
|
select NEW_LEDS
|
||||||
|
select LEDS_CLASS
|
||||||
|
select LEDS_GPIO
|
||||||
|
help
|
||||||
|
Machine support for the Devolo dLAN USB Extender
|
||||||
|
|
||||||
|
config MACH_RBT_832
|
||||||
|
bool "Tigal RBT-832"
|
||||||
|
select MCS8140
|
||||||
|
select NEW_LEDS
|
||||||
|
select LEDS_CLASS
|
||||||
|
select LEDS_GPIO
|
||||||
|
help
|
||||||
|
Machine support for the Tigal RBT-832 board
|
||||||
|
|
||||||
|
endmenu
|
||||||
|
|
||||||
|
endif
|
|
@ -0,0 +1,5 @@
|
||||||
|
obj-y += clock.o
|
||||||
|
obj-y += common.o
|
||||||
|
obj-y += irq.o
|
||||||
|
obj-y += timer.o
|
||||||
|
obj-y += board-mcs8140-dt.o
|
|
@ -0,0 +1,4 @@
|
||||||
|
zreladdr-y := 0x00008000
|
||||||
|
|
||||||
|
dtb-$(CONFIG_MACH_DLAN_USB_EXT) += dlan-usb-extender.dtb
|
||||||
|
dtb-$(CONFIG_MACH_RBT_832) += rbt-832.dtb
|
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
* Setup code for Moschip MCS8140-based board using Device Tree
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012, Florian Fainelli <florian@openwrt.org>
|
||||||
|
*
|
||||||
|
* Licensed under GPLv2.
|
||||||
|
*/
|
||||||
|
#include <linux/types.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/gpio.h>
|
||||||
|
#include <linux/irqdomain.h>
|
||||||
|
#include <linux/of_platform.h>
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
#include <asm/setup.h>
|
||||||
|
#include <asm/irq.h>
|
||||||
|
#include <asm/mach/arch.h>
|
||||||
|
#include <asm/mach/map.h>
|
||||||
|
#include <asm/mach/irq.h>
|
||||||
|
|
||||||
|
static void __init mcs814x_dt_device_init(void)
|
||||||
|
{
|
||||||
|
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
|
||||||
|
mcs814x_init_machine();
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *mcs8140_dt_board_compat[] __initdata = {
|
||||||
|
"moschip,mcs8140",
|
||||||
|
NULL, /* sentinel */
|
||||||
|
};
|
||||||
|
|
||||||
|
DT_MACHINE_START(mcs8140_dt, "Moschip MCS8140 board")
|
||||||
|
/* Maintainer: Florian Fainelli <florian@openwrt.org> */
|
||||||
|
.map_io = mcs814x_map_io,
|
||||||
|
.init_early = mcs814x_clk_init,
|
||||||
|
.init_irq = mcs814x_of_irq_init,
|
||||||
|
.init_time = mcs814x_timer_init,
|
||||||
|
.init_machine = mcs814x_dt_device_init,
|
||||||
|
.restart = mcs814x_restart,
|
||||||
|
.dt_compat = mcs8140_dt_board_compat,
|
||||||
|
.handle_irq = mcs814x_handle_irq,
|
||||||
|
MACHINE_END
|
||||||
|
|
|
@ -0,0 +1,271 @@
|
||||||
|
/*
|
||||||
|
* Moschip MCS814x clock routines
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012, Florian Fainelli <florian@openwrt.org>
|
||||||
|
*
|
||||||
|
* Licensed under GPLv2
|
||||||
|
*/
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/export.h>
|
||||||
|
#include <linux/spinlock.h>
|
||||||
|
#include <linux/err.h>
|
||||||
|
#include <linux/io.h>
|
||||||
|
#include <linux/clkdev.h>
|
||||||
|
#include <linux/clk.h>
|
||||||
|
|
||||||
|
#include <mach/mcs814x.h>
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
#define KHZ 1000
|
||||||
|
#define MHZ (KHZ * KHZ)
|
||||||
|
|
||||||
|
struct clk_ops {
|
||||||
|
unsigned long (*get_rate)(struct clk *clk);
|
||||||
|
int (*set_rate)(struct clk *clk, unsigned long rate);
|
||||||
|
struct clk *(*get_parent)(struct clk *clk);
|
||||||
|
int (*enable)(struct clk *clk, int enable);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct clk {
|
||||||
|
struct clk *parent; /* parent clk */
|
||||||
|
unsigned long rate; /* clock rate in Hz */
|
||||||
|
unsigned long divider; /* clock divider */
|
||||||
|
u32 usecount; /* reference count */
|
||||||
|
struct clk_ops *ops; /* clock operation */
|
||||||
|
u32 enable_reg; /* clock enable register */
|
||||||
|
u32 enable_mask; /* clock enable mask */
|
||||||
|
};
|
||||||
|
|
||||||
|
static unsigned long clk_divide_parent(struct clk *clk)
|
||||||
|
{
|
||||||
|
if (clk->parent && clk->divider)
|
||||||
|
return clk_get_rate(clk->parent) / clk->divider;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int clk_local_onoff_enable(struct clk *clk, int enable)
|
||||||
|
{
|
||||||
|
u32 tmp;
|
||||||
|
|
||||||
|
/* no enable_reg means the clock is always enabled */
|
||||||
|
if (!clk->enable_reg)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
tmp = readl_relaxed(mcs814x_sysdbg_base + clk->enable_reg);
|
||||||
|
if (!enable)
|
||||||
|
tmp &= ~clk->enable_mask;
|
||||||
|
else
|
||||||
|
tmp |= clk->enable_mask;
|
||||||
|
|
||||||
|
writel_relaxed(tmp, mcs814x_sysdbg_base + clk->enable_reg);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct clk_ops default_clk_ops = {
|
||||||
|
.get_rate = clk_divide_parent,
|
||||||
|
.enable = clk_local_onoff_enable,
|
||||||
|
};
|
||||||
|
|
||||||
|
static DEFINE_SPINLOCK(clocks_lock);
|
||||||
|
|
||||||
|
static const unsigned long cpu_freq_table[] = {
|
||||||
|
175000,
|
||||||
|
300000,
|
||||||
|
125000,
|
||||||
|
137500,
|
||||||
|
212500,
|
||||||
|
250000,
|
||||||
|
162500,
|
||||||
|
187500,
|
||||||
|
162500,
|
||||||
|
150000,
|
||||||
|
225000,
|
||||||
|
237500,
|
||||||
|
200000,
|
||||||
|
262500,
|
||||||
|
275000,
|
||||||
|
287500
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct clk clk_cpu;
|
||||||
|
|
||||||
|
/* System clock is fixed at 50Mhz */
|
||||||
|
static struct clk clk_sys = {
|
||||||
|
.rate = 50 * MHZ,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct clk clk_sdram;
|
||||||
|
|
||||||
|
static struct clk clk_timer0 = {
|
||||||
|
.parent = &clk_sdram,
|
||||||
|
.divider = 2,
|
||||||
|
.ops = &default_clk_ops,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct clk clk_timer1_2 = {
|
||||||
|
.parent = &clk_sys,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Watchdog clock is system clock / 128 */
|
||||||
|
static struct clk clk_wdt = {
|
||||||
|
.parent = &clk_sys,
|
||||||
|
.divider = 128,
|
||||||
|
.ops = &default_clk_ops,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct clk clk_emac = {
|
||||||
|
.ops = &default_clk_ops,
|
||||||
|
.enable_reg = SYSDBG_SYSCTL,
|
||||||
|
.enable_mask = SYSCTL_EMAC,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct clk clk_ephy = {
|
||||||
|
.ops = &default_clk_ops,
|
||||||
|
.enable_reg = SYSDBG_PLL_CTL,
|
||||||
|
.enable_mask = ~SYSCTL_EPHY, /* active low */
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct clk clk_cipher = {
|
||||||
|
.ops = &default_clk_ops,
|
||||||
|
.enable_reg = SYSDBG_SYSCTL,
|
||||||
|
.enable_mask = SYSCTL_CIPHER,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define CLK(_dev, _con, _clk) \
|
||||||
|
{ .dev_id = (_dev), .con_id = (_con), .clk = (_clk) },
|
||||||
|
|
||||||
|
static struct clk_lookup mcs814x_chip_clks[] = {
|
||||||
|
CLK("cpu", NULL, &clk_cpu)
|
||||||
|
CLK("sys", NULL, &clk_sys)
|
||||||
|
CLK("sdram", NULL, &clk_sdram)
|
||||||
|
/* 32-bits timer0 */
|
||||||
|
CLK("timer0", NULL, &clk_timer0)
|
||||||
|
/* 16-bits timer1 */
|
||||||
|
CLK("timer1", NULL, &clk_timer1_2)
|
||||||
|
/* 64-bits timer2, same as timer 1 */
|
||||||
|
CLK("timer2", NULL, &clk_timer1_2)
|
||||||
|
CLK(NULL, "wdt", &clk_wdt)
|
||||||
|
CLK(NULL, "emac", &clk_emac)
|
||||||
|
CLK(NULL, "ephy", &clk_ephy)
|
||||||
|
CLK(NULL, "cipher", &clk_cipher)
|
||||||
|
};
|
||||||
|
|
||||||
|
static void local_clk_disable(struct clk *clk)
|
||||||
|
{
|
||||||
|
WARN_ON(!clk->usecount);
|
||||||
|
|
||||||
|
if (clk->usecount > 0) {
|
||||||
|
clk->usecount--;
|
||||||
|
|
||||||
|
if ((clk->usecount == 0) && (clk->ops->enable))
|
||||||
|
clk->ops->enable(clk, 0);
|
||||||
|
|
||||||
|
if (clk->parent)
|
||||||
|
local_clk_disable(clk->parent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int local_clk_enable(struct clk *clk)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (clk->parent)
|
||||||
|
ret = local_clk_enable(clk->parent);
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if ((clk->usecount == 0) && (clk->ops->enable))
|
||||||
|
ret = clk->ops->enable(clk, 1);
|
||||||
|
|
||||||
|
if (!ret)
|
||||||
|
clk->usecount++;
|
||||||
|
else if (clk->parent && clk->parent->ops->enable)
|
||||||
|
local_clk_disable(clk->parent);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int clk_enable(struct clk *clk)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&clocks_lock, flags);
|
||||||
|
ret = local_clk_enable(clk);
|
||||||
|
spin_unlock_irqrestore(&clocks_lock, flags);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(clk_enable);
|
||||||
|
|
||||||
|
void clk_disable(struct clk *clk)
|
||||||
|
{
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&clocks_lock, flags);
|
||||||
|
local_clk_disable(clk);
|
||||||
|
spin_unlock_irqrestore(&clocks_lock, flags);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(clk_disable);
|
||||||
|
|
||||||
|
unsigned long clk_get_rate(struct clk *clk)
|
||||||
|
{
|
||||||
|
if (unlikely(IS_ERR_OR_NULL(clk)))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (clk->rate)
|
||||||
|
return clk->rate;
|
||||||
|
|
||||||
|
if (clk->ops && clk->ops->get_rate)
|
||||||
|
return clk->ops->get_rate(clk);
|
||||||
|
|
||||||
|
return clk_get_rate(clk->parent);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(clk_get_rate);
|
||||||
|
|
||||||
|
struct clk *clk_get_parent(struct clk *clk)
|
||||||
|
{
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
if (unlikely(IS_ERR_OR_NULL(clk)))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (!clk->ops || !clk->ops->get_parent)
|
||||||
|
return clk->parent;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&clocks_lock, flags);
|
||||||
|
clk->parent = clk->ops->get_parent(clk);
|
||||||
|
spin_unlock_irqrestore(&clocks_lock, flags);
|
||||||
|
|
||||||
|
return clk->parent;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(clk_get_parent);
|
||||||
|
|
||||||
|
void __init mcs814x_clk_init(void)
|
||||||
|
{
|
||||||
|
u32 bs1;
|
||||||
|
u8 cpu_freq;
|
||||||
|
|
||||||
|
clkdev_add_table(mcs814x_chip_clks, ARRAY_SIZE(mcs814x_chip_clks));
|
||||||
|
|
||||||
|
/* read the bootstrap registers to know the exact clocking scheme */
|
||||||
|
bs1 = readl_relaxed(mcs814x_sysdbg_base + SYSDBG_BS1);
|
||||||
|
cpu_freq = (bs1 >> CPU_FREQ_SHIFT) & CPU_FREQ_MASK;
|
||||||
|
|
||||||
|
pr_info("CPU frequency: %lu (kHz)\n", cpu_freq_table[cpu_freq]);
|
||||||
|
clk_cpu.rate = cpu_freq * KHZ;
|
||||||
|
|
||||||
|
/* read SDRAM frequency */
|
||||||
|
if (bs1 & SDRAM_FREQ_BIT)
|
||||||
|
clk_sdram.rate = 100 * MHZ;
|
||||||
|
else
|
||||||
|
clk_sdram.rate = 133 * MHZ;
|
||||||
|
|
||||||
|
pr_info("SDRAM frequency: %lu (MHz)\n", clk_sdram.rate / MHZ);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,166 @@
|
||||||
|
/*
|
||||||
|
* arch/arm/mach-mcs814x/common.c
|
||||||
|
*
|
||||||
|
* Core functions for Moschip MCS814x SoCs
|
||||||
|
*
|
||||||
|
* This file is licensed under the terms of the GNU General Public
|
||||||
|
* License version 2. This program is licensed "as is" without any
|
||||||
|
* warranty of any kind, whether express or implied.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/io.h>
|
||||||
|
#include <linux/gpio.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
#include <linux/of_address.h>
|
||||||
|
#include <linux/reboot.h>
|
||||||
|
|
||||||
|
#include <asm/setup.h>
|
||||||
|
#include <asm/mach-types.h>
|
||||||
|
#include <asm/mach/arch.h>
|
||||||
|
#include <mach/mcs814x.h>
|
||||||
|
#include <mach/cpu.h>
|
||||||
|
#include <asm/pgtable.h>
|
||||||
|
#include <asm/mach/map.h>
|
||||||
|
|
||||||
|
void __iomem *mcs814x_sysdbg_base;
|
||||||
|
|
||||||
|
static struct map_desc mcs814x_io_desc[] __initdata = {
|
||||||
|
{
|
||||||
|
.virtual = MCS814X_IO_BASE,
|
||||||
|
.pfn = __phys_to_pfn(MCS814X_IO_START),
|
||||||
|
.length = MCS814X_IO_SIZE,
|
||||||
|
.type = MT_DEVICE
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
struct cpu_mode {
|
||||||
|
const char *name;
|
||||||
|
int gpio_start;
|
||||||
|
int gpio_end;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct cpu_mode cpu_modes[] = {
|
||||||
|
{
|
||||||
|
.name = "I2S",
|
||||||
|
.gpio_start = 4,
|
||||||
|
.gpio_end = 8,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "UART",
|
||||||
|
.gpio_start = 4,
|
||||||
|
.gpio_end = 9,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "External MII",
|
||||||
|
.gpio_start = 0,
|
||||||
|
.gpio_end = 16,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "Normal",
|
||||||
|
.gpio_start = -1,
|
||||||
|
.gpio_end = -1,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static void mcs814x_eth_hardware_filter_set(u8 value)
|
||||||
|
{
|
||||||
|
u32 reg;
|
||||||
|
|
||||||
|
reg = readl_relaxed(MCS814X_VIRT_BASE + MCS814X_DBGLED);
|
||||||
|
if (value)
|
||||||
|
reg |= 0x80;
|
||||||
|
else
|
||||||
|
reg &= ~0x80;
|
||||||
|
writel_relaxed(reg, MCS814X_VIRT_BASE + MCS814X_DBGLED);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mcs814x_eth_led_cfg_set(u8 cfg)
|
||||||
|
{
|
||||||
|
u32 reg;
|
||||||
|
|
||||||
|
reg = readl_relaxed(mcs814x_sysdbg_base + SYSDBG_BS2);
|
||||||
|
reg &= ~LED_CFG_MASK;
|
||||||
|
reg |= cfg;
|
||||||
|
writel_relaxed(reg, mcs814x_sysdbg_base + SYSDBG_BS2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mcs814x_eth_buffer_shifting_set(u8 value)
|
||||||
|
{
|
||||||
|
u8 reg;
|
||||||
|
|
||||||
|
reg = readb_relaxed(mcs814x_sysdbg_base + SYSDBG_SYSCTL_MAC);
|
||||||
|
if (value)
|
||||||
|
reg |= BUF_SHIFT_BIT;
|
||||||
|
else
|
||||||
|
reg &= ~BUF_SHIFT_BIT;
|
||||||
|
writeb_relaxed(reg, mcs814x_sysdbg_base + SYSDBG_SYSCTL_MAC);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct of_device_id mcs814x_eth_ids[] __initdata = {
|
||||||
|
{ .compatible = "moschip,nuport-mac", },
|
||||||
|
{ /* sentinel */ },
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Configure platform specific knobs based on ethernet device node
|
||||||
|
* properties */
|
||||||
|
static void mcs814x_eth_init(void)
|
||||||
|
{
|
||||||
|
struct device_node *np;
|
||||||
|
const unsigned int *intspec;
|
||||||
|
|
||||||
|
np = of_find_matching_node(NULL, mcs814x_eth_ids);
|
||||||
|
if (!np)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* hardware filter must always be enabled */
|
||||||
|
mcs814x_eth_hardware_filter_set(1);
|
||||||
|
|
||||||
|
intspec = of_get_property(np, "nuport-mac,buffer-shifting", NULL);
|
||||||
|
if (!intspec)
|
||||||
|
mcs814x_eth_buffer_shifting_set(0);
|
||||||
|
else
|
||||||
|
mcs814x_eth_buffer_shifting_set(1);
|
||||||
|
|
||||||
|
intspec = of_get_property(np, "nuport-mac,link-activity", NULL);
|
||||||
|
if (intspec)
|
||||||
|
mcs814x_eth_led_cfg_set(be32_to_cpup(intspec));
|
||||||
|
|
||||||
|
of_node_put(np);
|
||||||
|
}
|
||||||
|
|
||||||
|
void __init mcs814x_init_machine(void)
|
||||||
|
{
|
||||||
|
u32 bs2, cpu_mode;
|
||||||
|
int gpio;
|
||||||
|
|
||||||
|
bs2 = readl_relaxed(mcs814x_sysdbg_base + SYSDBG_BS2);
|
||||||
|
cpu_mode = (bs2 >> CPU_MODE_SHIFT) & CPU_MODE_MASK;
|
||||||
|
|
||||||
|
pr_info("CPU mode: %s\n", cpu_modes[cpu_mode].name);
|
||||||
|
|
||||||
|
/* request the gpios since the pins are muxed for functionnality */
|
||||||
|
for (gpio = cpu_modes[cpu_mode].gpio_start;
|
||||||
|
gpio == cpu_modes[cpu_mode].gpio_end; gpio++) {
|
||||||
|
if (gpio != -1)
|
||||||
|
gpio_request(gpio, cpu_modes[cpu_mode].name);
|
||||||
|
}
|
||||||
|
|
||||||
|
mcs814x_eth_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
void __init mcs814x_map_io(void)
|
||||||
|
{
|
||||||
|
iotable_init(mcs814x_io_desc, ARRAY_SIZE(mcs814x_io_desc));
|
||||||
|
|
||||||
|
mcs814x_sysdbg_base = ioremap(MCS814X_IO_START + MCS814X_SYSDBG,
|
||||||
|
MCS814X_SYSDBG_SIZE);
|
||||||
|
if (!mcs814x_sysdbg_base)
|
||||||
|
panic("unable to remap sysdbg base");
|
||||||
|
}
|
||||||
|
|
||||||
|
void mcs814x_restart(enum reboot_mode mode, const char *cmd)
|
||||||
|
{
|
||||||
|
writel_relaxed(~(1 << 31), mcs814x_sysdbg_base);
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
#ifndef __ARCH_MCS814X_COMMON_H
|
||||||
|
#define __ARCH_MCS814X_COMMON_H
|
||||||
|
|
||||||
|
#include <linux/reboot.h>
|
||||||
|
#include <asm/mach/time.h>
|
||||||
|
|
||||||
|
void mcs814x_map_io(void);
|
||||||
|
void mcs814x_clk_init(void);
|
||||||
|
void mcs814x_of_irq_init(void);
|
||||||
|
void mcs814x_init_machine(void);
|
||||||
|
void mcs814x_handle_irq(struct pt_regs *regs);
|
||||||
|
void mcs814x_restart(enum reboot_mode mode, const char *cmd);
|
||||||
|
void mcs814x_timer_init(void);
|
||||||
|
extern void __iomem *mcs814x_sysdbg_base;
|
||||||
|
|
||||||
|
#endif /* __ARCH_MCS814X_COMMON_H */
|
|
@ -0,0 +1,16 @@
|
||||||
|
#ifndef __ASM_ARCH_CPU_H__
|
||||||
|
#define __ASM_ARCH_CPU_H__
|
||||||
|
|
||||||
|
#include <asm/cputype.h>
|
||||||
|
|
||||||
|
#define MCS8140_ID 0x41069260 /* ARM926EJ-S */
|
||||||
|
#define MCS814X_MASK 0xff0ffff0
|
||||||
|
|
||||||
|
#ifdef CONFIG_MCS8140
|
||||||
|
/* Moschip MCS8140 is based on an ARM926EJ-S core */
|
||||||
|
#define soc_is_mcs8140() ((read_cpuid_id() & MCS814X_MASK) == MCS8140_ID)
|
||||||
|
#else
|
||||||
|
#define soc_is_mcs8140() (0)
|
||||||
|
#endif /* !CONFIG_MCS8140 */
|
||||||
|
|
||||||
|
#endif /* __ASM_ARCH_CPU_H__ */
|
|
@ -0,0 +1,11 @@
|
||||||
|
#include <mach/mcs814x.h>
|
||||||
|
|
||||||
|
.macro addruart, rp, rv, tmp
|
||||||
|
ldr \rp, =MCS814X_PHYS_BASE
|
||||||
|
ldr \rv, =MCS814X_VIRT_BASE
|
||||||
|
orr \rp, \rp, #MCS814X_UART
|
||||||
|
orr \rv, \rv, #MCS814X_UART
|
||||||
|
.endm
|
||||||
|
|
||||||
|
#define UART_SHIFT 2
|
||||||
|
#include <asm/hardware/debug-8250.S>
|
|
@ -0,0 +1,6 @@
|
||||||
|
#include <mach/mcs814x.h>
|
||||||
|
.macro disable_fiq
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro arch_ret_to_user, tmp1, tmp2
|
||||||
|
.endm
|
|
@ -0,0 +1,21 @@
|
||||||
|
#ifndef __ASM_ARCH_GPIO_H
|
||||||
|
#define __ASM_ARCH_GPIO_H
|
||||||
|
|
||||||
|
/* new generic GPIO API */
|
||||||
|
#include <asm-generic/gpio.h>
|
||||||
|
|
||||||
|
#define gpio_get_value __gpio_get_value
|
||||||
|
#define gpio_set_value __gpio_set_value
|
||||||
|
#define gpio_cansleep __gpio_cansleep
|
||||||
|
|
||||||
|
static inline int gpio_to_irq(unsigned gpio)
|
||||||
|
{
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int irq_to_gpio(unsigned irq)
|
||||||
|
{
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,16 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2003 Artec Design Ltd.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __ASM_ARCH_HARDWARE_H
|
||||||
|
#define __ASM_ARCH_HARDWARE_H
|
||||||
|
|
||||||
|
#include "mcs814x.h"
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2003 Artec Design Ltd.
|
||||||
|
* Copyright (C) 2012, Florian Fainelli <florian@openwrt.org>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __ASM_ARM_ARCH_IO_H
|
||||||
|
#define __ASM_ARM_ARCH_IO_H
|
||||||
|
|
||||||
|
#define IO_SPACE_LIMIT 0xffffffff
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We don't support ins[lb]/outs[lb]. Make them fault.
|
||||||
|
*/
|
||||||
|
#define __raw_readsb(p, d, l) do { *(int *)0 = 0; } while (0)
|
||||||
|
#define __raw_readsl(p, d, l) do { *(int *)0 = 0; } while (0)
|
||||||
|
#define __raw_writesb(p, d, l) do { *(int *)0 = 0; } while (0)
|
||||||
|
#define __raw_writesl(p, d, l) do { *(int *)0 = 0; } while (0)
|
||||||
|
|
||||||
|
#define __io(a) __typesafe_io(a)
|
||||||
|
#define __mem_pci(a) (a)
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,17 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2003 Artec Design Ltd.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __ASM_ARCH_IRQS_H
|
||||||
|
#define __ASM_ARCH_IRQS_H
|
||||||
|
|
||||||
|
#define FIQ_START 0
|
||||||
|
|
||||||
|
#define NR_IRQS 32
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2003 Artec Design Ltd.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __ASM_ARCH_MCS814X_H
|
||||||
|
#define __ASM_ARCH_MCS814X_H
|
||||||
|
|
||||||
|
#define MCS814X_IO_BASE 0xF0000000
|
||||||
|
#define MCS814X_IO_START 0x40000000
|
||||||
|
#define MCS814X_IO_SIZE 0x00100000
|
||||||
|
|
||||||
|
/* IRQ controller register offset */
|
||||||
|
#define MCS814X_IRQ_ICR 0x00
|
||||||
|
#define MCS814X_IRQ_ISR 0x04
|
||||||
|
#define MCS814X_IRQ_MASK 0x20
|
||||||
|
#define MCS814X_IRQ_STS0 0x40
|
||||||
|
|
||||||
|
#define MCS814X_PHYS_BASE 0x40000000
|
||||||
|
#define MCS814X_VIRT_BASE MCS814X_IO_BASE
|
||||||
|
|
||||||
|
#define MCS814X_UART 0x000DC000
|
||||||
|
#define MCS814X_DBGLED 0x000EC000
|
||||||
|
#define MCS814X_SYSDBG 0x000F8000
|
||||||
|
#define MCS814X_SYSDBG_SIZE 0x50
|
||||||
|
|
||||||
|
/* System configuration and bootstrap registers */
|
||||||
|
#define SYSDBG_BS1 0x00
|
||||||
|
#define CPU_FREQ_SHIFT 27
|
||||||
|
#define CPU_FREQ_MASK 0x0F
|
||||||
|
#define SDRAM_FREQ_BIT (1 << 22)
|
||||||
|
|
||||||
|
#define SYSDBG_BS2 0x04
|
||||||
|
#define LED_CFG_MASK 0x03
|
||||||
|
#define CPU_MODE_SHIFT 23
|
||||||
|
#define CPU_MODE_MASK 0x03
|
||||||
|
|
||||||
|
#define SYSDBG_SYSCTL_MAC 0x1d
|
||||||
|
#define BUF_SHIFT_BIT (1 << 0)
|
||||||
|
|
||||||
|
#define SYSDBG_SYSCTL 0x08
|
||||||
|
#define SYSCTL_EMAC (1 << 0)
|
||||||
|
#define SYSCTL_EPHY (1 << 0) /* active low */
|
||||||
|
#define SYSCTL_CIPHER (1 << 16)
|
||||||
|
|
||||||
|
#define SYSDBG_PLL_CTL 0x3C
|
||||||
|
|
||||||
|
#endif /* __ASM_ARCH_MCS814X_H */
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2003 Artec Design Ltd.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __ASM_ARCH_PARAM_H
|
||||||
|
#define __ASM_ARCH_PARAM_H
|
||||||
|
|
||||||
|
#define HZ 100
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,18 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2003 Artec Design Ltd.
|
||||||
|
* Copyright (C) 2012 Florian Fainelli <florian@openwrt.org>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __ASM_ARCH_SYSTEM_H
|
||||||
|
#define __ASM_ARCH_SYSTEM_H
|
||||||
|
|
||||||
|
static inline void arch_idle(void)
|
||||||
|
{
|
||||||
|
cpu_do_idle();
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -0,0 +1,18 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2003 Artec Design Ltd.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __ASM_ARCH_TIMEX_H
|
||||||
|
#define __ASM_ARCH_TIMEX_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Timex specification for MCS814X
|
||||||
|
*/
|
||||||
|
#define CLOCK_TICK_RATE 100
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2012, Florian Fainelli <florian@openwrt.org>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __ASM_ARCH_UNCOMPRESS_H
|
||||||
|
#define __ASM_ARCH_UNCOMPRESS_H
|
||||||
|
|
||||||
|
#include <linux/serial_reg.h>
|
||||||
|
#include <asm/io.h>
|
||||||
|
#include <mach/mcs814x.h>
|
||||||
|
#include <mach/cpu.h>
|
||||||
|
|
||||||
|
#define UART_SHIFT (2)
|
||||||
|
|
||||||
|
/* cannot be static because the code will be inlined */
|
||||||
|
void __iomem *uart_base;
|
||||||
|
|
||||||
|
static inline void putc(int c)
|
||||||
|
{
|
||||||
|
while (!(__raw_readb(uart_base + (UART_LSR << UART_SHIFT)) & UART_LSR_TEMT));
|
||||||
|
__raw_writeb(c, uart_base + (UART_TX << UART_SHIFT));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void flush(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void arch_decomp_setup(void)
|
||||||
|
{
|
||||||
|
if (soc_is_mcs8140())
|
||||||
|
uart_base = (void __iomem *)(MCS814X_PHYS_BASE +MCS814X_UART);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define arch_decomp_wdog()
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,89 @@
|
||||||
|
/*
|
||||||
|
* Moschip MCS814x generic interrupt controller routines
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012, Florian Fainelli <florian@openwrt.org>
|
||||||
|
*
|
||||||
|
* Licensed under the GPLv2
|
||||||
|
*/
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/irq.h>
|
||||||
|
#include <linux/io.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
#include <linux/of_address.h>
|
||||||
|
#include <linux/irqdomain.h>
|
||||||
|
|
||||||
|
#include <asm/exception.h>
|
||||||
|
#include <asm/mach/irq.h>
|
||||||
|
#include <mach/mcs814x.h>
|
||||||
|
|
||||||
|
static void __iomem *mcs814x_intc_base;
|
||||||
|
|
||||||
|
static void __init mcs814x_alloc_gc(void __iomem *base, unsigned int irq_start,
|
||||||
|
unsigned int num)
|
||||||
|
{
|
||||||
|
struct irq_chip_generic *gc;
|
||||||
|
struct irq_chip_type *ct;
|
||||||
|
|
||||||
|
gc = irq_alloc_generic_chip("mcs814x-intc", 1,
|
||||||
|
irq_start, base, handle_level_irq);
|
||||||
|
if (!gc)
|
||||||
|
panic("unable to allocate generic irq chip");
|
||||||
|
|
||||||
|
ct = gc->chip_types;
|
||||||
|
ct->chip.irq_ack = irq_gc_unmask_enable_reg;
|
||||||
|
ct->chip.irq_mask = irq_gc_mask_clr_bit;
|
||||||
|
ct->chip.irq_unmask = irq_gc_mask_set_bit;
|
||||||
|
ct->regs.mask = MCS814X_IRQ_MASK;
|
||||||
|
ct->regs.enable = MCS814X_IRQ_ICR;
|
||||||
|
|
||||||
|
irq_setup_generic_chip(gc, IRQ_MSK(num), IRQ_GC_INIT_MASK_CACHE,
|
||||||
|
IRQ_NOREQUEST, 0);
|
||||||
|
|
||||||
|
/* Clear all interrupts */
|
||||||
|
writel_relaxed(0xffffffff, base + MCS814X_IRQ_ICR);
|
||||||
|
}
|
||||||
|
|
||||||
|
asmlinkage void __exception_irq_entry mcs814x_handle_irq(struct pt_regs *regs)
|
||||||
|
{
|
||||||
|
u32 status, irq;
|
||||||
|
|
||||||
|
do {
|
||||||
|
/* read the status register */
|
||||||
|
status = __raw_readl(mcs814x_intc_base + MCS814X_IRQ_STS0);
|
||||||
|
if (!status)
|
||||||
|
break;
|
||||||
|
|
||||||
|
irq = ffs(status) - 1;
|
||||||
|
status |= (1 << irq);
|
||||||
|
/* clear the interrupt */
|
||||||
|
__raw_writel(status, mcs814x_intc_base + MCS814X_IRQ_STS0);
|
||||||
|
/* call the generic handler */
|
||||||
|
handle_IRQ(irq, regs);
|
||||||
|
|
||||||
|
} while (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct of_device_id mcs814x_intc_ids[] = {
|
||||||
|
{ .compatible = "moschip,mcs814x-intc" },
|
||||||
|
{ /* sentinel */ },
|
||||||
|
};
|
||||||
|
|
||||||
|
void __init mcs814x_of_irq_init(void)
|
||||||
|
{
|
||||||
|
struct device_node *np;
|
||||||
|
|
||||||
|
np = of_find_matching_node(NULL, mcs814x_intc_ids);
|
||||||
|
if (!np)
|
||||||
|
panic("unable to find compatible intc node in dtb\n");
|
||||||
|
|
||||||
|
mcs814x_intc_base = of_iomap(np, 0);
|
||||||
|
if (!mcs814x_intc_base)
|
||||||
|
panic("unable to map intc cpu registers\n");
|
||||||
|
|
||||||
|
irq_domain_add_simple(np, 32, 0, &irq_generic_chip_ops, NULL);
|
||||||
|
|
||||||
|
of_node_put(np);
|
||||||
|
|
||||||
|
mcs814x_alloc_gc(mcs814x_intc_base, 0, 32);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,132 @@
|
||||||
|
/*
|
||||||
|
* Moschip MCS814x timer routines
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012, Florian Fainelli <florian@openwrt.org>
|
||||||
|
*
|
||||||
|
* Licensed under GPLv2
|
||||||
|
*/
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/interrupt.h>
|
||||||
|
#include <linux/time.h>
|
||||||
|
#include <linux/timex.h>
|
||||||
|
#include <linux/irq.h>
|
||||||
|
#include <linux/err.h>
|
||||||
|
#include <linux/clk.h>
|
||||||
|
#include <linux/io.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
#include <linux/of_address.h>
|
||||||
|
|
||||||
|
#include <asm/mach/time.h>
|
||||||
|
#include <mach/mcs814x.h>
|
||||||
|
|
||||||
|
/* Timer block registers */
|
||||||
|
#define TIMER_VAL 0x00
|
||||||
|
#define TIMER_CTL 0x04
|
||||||
|
#define TIMER_CTL_EN 0x01
|
||||||
|
#define TIMER_CTL_DBG 0x02
|
||||||
|
|
||||||
|
static u32 last_reload;
|
||||||
|
static u32 timer_correct;
|
||||||
|
static u32 clock_rate;
|
||||||
|
static u32 timer_reload_value;
|
||||||
|
static void __iomem *mcs814x_timer_base;
|
||||||
|
|
||||||
|
static inline u32 ticks2usecs(u32 x)
|
||||||
|
{
|
||||||
|
return x / (clock_rate / 1000000);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns number of ms since last clock interrupt. Note that interrupts
|
||||||
|
* will have been disabled by do_gettimeoffset()
|
||||||
|
*/
|
||||||
|
static u32 mcs814x_gettimeoffset(void)
|
||||||
|
{
|
||||||
|
u32 ticks = readl_relaxed(mcs814x_timer_base + TIMER_VAL);
|
||||||
|
|
||||||
|
if (ticks < last_reload)
|
||||||
|
return ticks2usecs(ticks + (u32)(0xffffffff - last_reload));
|
||||||
|
else
|
||||||
|
return ticks2usecs(ticks - last_reload);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static irqreturn_t mcs814x_timer_interrupt(int irq, void *dev_id)
|
||||||
|
{
|
||||||
|
u32 count = readl_relaxed(mcs814x_timer_base + TIMER_VAL);
|
||||||
|
|
||||||
|
/* take into account delay up to this moment */
|
||||||
|
last_reload = count + timer_correct + timer_reload_value;
|
||||||
|
|
||||||
|
if (last_reload < timer_reload_value) {
|
||||||
|
last_reload = timer_reload_value;
|
||||||
|
} else {
|
||||||
|
if (timer_correct == 0)
|
||||||
|
timer_correct = readl_relaxed(mcs814x_timer_base + TIMER_VAL) - count;
|
||||||
|
}
|
||||||
|
writel_relaxed(last_reload, mcs814x_timer_base + TIMER_VAL);
|
||||||
|
|
||||||
|
timer_tick();
|
||||||
|
|
||||||
|
return IRQ_HANDLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct irqaction mcs814x_timer_irq = {
|
||||||
|
.name = "mcs814x-timer",
|
||||||
|
.flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
|
||||||
|
.handler = mcs814x_timer_interrupt,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct of_device_id mcs814x_timer_ids[] = {
|
||||||
|
{ .compatible = "moschip,mcs814x-timer" },
|
||||||
|
{ /* sentinel */ },
|
||||||
|
};
|
||||||
|
|
||||||
|
static void __init mcs814x_of_timer_init(void)
|
||||||
|
{
|
||||||
|
struct device_node *np;
|
||||||
|
const unsigned int *intspec;
|
||||||
|
|
||||||
|
np = of_find_matching_node(NULL, mcs814x_timer_ids);
|
||||||
|
if (!np)
|
||||||
|
panic("unable to find compatible timer node in dtb");
|
||||||
|
|
||||||
|
mcs814x_timer_base = of_iomap(np, 0);
|
||||||
|
if (!mcs814x_timer_base)
|
||||||
|
panic("unable to remap timer cpu registers");
|
||||||
|
|
||||||
|
intspec = of_get_property(np, "interrupts", NULL);
|
||||||
|
if (!intspec)
|
||||||
|
panic("no interrupts property for timer");
|
||||||
|
|
||||||
|
mcs814x_timer_irq.irq = be32_to_cpup(intspec);
|
||||||
|
}
|
||||||
|
|
||||||
|
void __init mcs814x_timer_init(void)
|
||||||
|
{
|
||||||
|
struct clk *clk;
|
||||||
|
|
||||||
|
arch_gettimeoffset = mcs814x_gettimeoffset;
|
||||||
|
|
||||||
|
clk = clk_get_sys("timer0", NULL);
|
||||||
|
if (IS_ERR_OR_NULL(clk))
|
||||||
|
panic("unable to get timer0 clock");
|
||||||
|
|
||||||
|
clock_rate = clk_get_rate(clk);
|
||||||
|
|
||||||
|
mcs814x_of_timer_init();
|
||||||
|
|
||||||
|
pr_info("Timer frequency: %d (kHz)\n", clock_rate / 1000);
|
||||||
|
|
||||||
|
timer_reload_value = 0xffffffff - (clock_rate / HZ);
|
||||||
|
|
||||||
|
/* disable timer */
|
||||||
|
writel_relaxed(~TIMER_CTL_EN, mcs814x_timer_base + TIMER_CTL);
|
||||||
|
writel_relaxed(timer_reload_value, mcs814x_timer_base + TIMER_VAL);
|
||||||
|
last_reload = timer_reload_value;
|
||||||
|
|
||||||
|
setup_irq(mcs814x_timer_irq.irq, &mcs814x_timer_irq);
|
||||||
|
/* enable timer, stop timer in debug mode */
|
||||||
|
writel_relaxed(TIMER_CTL_EN | TIMER_CTL_DBG,
|
||||||
|
mcs814x_timer_base + TIMER_CTL);
|
||||||
|
}
|
|
@ -0,0 +1,121 @@
|
||||||
|
/*
|
||||||
|
* RNG driver for Moschip MCS814x SoC
|
||||||
|
*
|
||||||
|
* Copyright 2012 (C), Florian Fainelli <florian@openwrt.org>
|
||||||
|
*
|
||||||
|
* This file is licensed under the terms of the GNU General Public
|
||||||
|
* License version 2. This program is licensed "as is" without any
|
||||||
|
* warranty of any kind, whether express or implied.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/types.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/hw_random.h>
|
||||||
|
#include <linux/io.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
|
||||||
|
#define STAT 0x00
|
||||||
|
#define RND 0x04
|
||||||
|
|
||||||
|
struct mcs814x_rng_priv {
|
||||||
|
void __iomem *regs;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int mcs814x_rng_data_read(struct hwrng *rng, u32 *buffer)
|
||||||
|
{
|
||||||
|
struct mcs814x_rng_priv *priv = (struct mcs814x_rng_priv *)rng->priv;
|
||||||
|
|
||||||
|
*buffer = readl_relaxed(priv->regs + RND);
|
||||||
|
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mcs814x_rng_probe(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct resource *res;
|
||||||
|
struct mcs814x_rng_priv *priv;
|
||||||
|
struct hwrng *rng;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
|
if (!res)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
|
||||||
|
if (!priv) {
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
rng = kzalloc(sizeof(*rng), GFP_KERNEL);
|
||||||
|
if (!rng) {
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto out_priv;
|
||||||
|
}
|
||||||
|
|
||||||
|
platform_set_drvdata(pdev, rng);
|
||||||
|
rng->priv = (unsigned long)priv;
|
||||||
|
rng->name = pdev->name;
|
||||||
|
rng->data_read = mcs814x_rng_data_read;
|
||||||
|
|
||||||
|
priv->regs = devm_ioremap_resource(&pdev->dev, res);
|
||||||
|
if (!priv->regs) {
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto out_rng;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = hwrng_register(rng);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(&pdev->dev, "failed to register hwrng driver\n");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev_info(&pdev->dev, "registered\n");
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
out_rng:
|
||||||
|
platform_set_drvdata(pdev, NULL);
|
||||||
|
kfree(rng);
|
||||||
|
out_priv:
|
||||||
|
kfree(priv);
|
||||||
|
out:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mcs814x_rng_remove(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct hwrng *rng = platform_get_drvdata(pdev);
|
||||||
|
struct mcs814x_rng_priv *priv = (struct mcs814x_rng_priv *)rng->priv;
|
||||||
|
|
||||||
|
hwrng_unregister(rng);
|
||||||
|
kfree(priv);
|
||||||
|
kfree(rng);
|
||||||
|
platform_set_drvdata(pdev, NULL);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct of_device_id mcs814x_rng_ids[] = {
|
||||||
|
{ .compatible = "moschip,mcs814x-rng", },
|
||||||
|
{ /* sentinel */ },
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_driver mcs814x_rng_driver = {
|
||||||
|
.driver = {
|
||||||
|
.name = "mcs814x-rng",
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
.of_match_table = mcs814x_rng_ids,
|
||||||
|
},
|
||||||
|
.probe = mcs814x_rng_probe,
|
||||||
|
.remove = mcs814x_rng_remove,
|
||||||
|
};
|
||||||
|
|
||||||
|
module_platform_driver(mcs814x_rng_driver);
|
||||||
|
|
||||||
|
MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>");
|
||||||
|
MODULE_DESCRIPTION("H/W Random Number Generator (RNG) for Moschip MCS814x");
|
||||||
|
MODULE_LICENSE("GPL");
|
|
@ -0,0 +1,148 @@
|
||||||
|
/*
|
||||||
|
* Moschip MCS814x GPIO support
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012, Florian Fainelli <florian@openwrt.org>
|
||||||
|
*
|
||||||
|
* Licensed under the GPLv2
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/gpio.h>
|
||||||
|
#include <linux/io.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
#include <linux/of_address.h>
|
||||||
|
|
||||||
|
struct mcs814x_gpio_chip {
|
||||||
|
void __iomem *regs;
|
||||||
|
struct gpio_chip chip;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define GPIO_PIN 0x00
|
||||||
|
#define GPIO_DIR 0x04
|
||||||
|
|
||||||
|
#define to_mcs814x_gpio_chip(x) container_of(x, struct mcs814x_gpio_chip, chip)
|
||||||
|
|
||||||
|
static int mcs814x_gpio_get(struct gpio_chip *chip, unsigned offset)
|
||||||
|
{
|
||||||
|
struct mcs814x_gpio_chip *mcs814x = to_mcs814x_gpio_chip(chip);
|
||||||
|
|
||||||
|
return readl_relaxed(mcs814x->regs + GPIO_PIN) & (1 << offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mcs814x_gpio_set(struct gpio_chip *chip,
|
||||||
|
unsigned offset, int value)
|
||||||
|
{
|
||||||
|
struct mcs814x_gpio_chip *mcs814x = to_mcs814x_gpio_chip(chip);
|
||||||
|
u32 mask;
|
||||||
|
|
||||||
|
mask = readl_relaxed(mcs814x->regs + GPIO_PIN);
|
||||||
|
if (value)
|
||||||
|
mask |= (1 << offset);
|
||||||
|
else
|
||||||
|
mask &= ~(1 << offset);
|
||||||
|
writel_relaxed(mask, mcs814x->regs + GPIO_PIN);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mcs814x_gpio_direction_output(struct gpio_chip *chip,
|
||||||
|
unsigned offset, int value)
|
||||||
|
{
|
||||||
|
struct mcs814x_gpio_chip *mcs814x = to_mcs814x_gpio_chip(chip);
|
||||||
|
u32 mask;
|
||||||
|
|
||||||
|
mask = readl_relaxed(mcs814x->regs + GPIO_DIR);
|
||||||
|
mask &= ~(1 << offset);
|
||||||
|
writel_relaxed(mask, mcs814x->regs + GPIO_DIR);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mcs814x_gpio_direction_input(struct gpio_chip *chip,
|
||||||
|
unsigned offset)
|
||||||
|
{
|
||||||
|
struct mcs814x_gpio_chip *mcs814x = to_mcs814x_gpio_chip(chip);
|
||||||
|
u32 mask;
|
||||||
|
|
||||||
|
mask = readl_relaxed(mcs814x->regs + GPIO_DIR);
|
||||||
|
mask |= (1 << offset);
|
||||||
|
writel_relaxed(mask, mcs814x->regs + GPIO_DIR);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mcs814x_gpio_probe(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct resource *res;
|
||||||
|
struct mcs814x_gpio_chip *mcs814x_chip;
|
||||||
|
int ret;
|
||||||
|
const unsigned int *num_gpios;
|
||||||
|
|
||||||
|
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
|
if (!res)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
num_gpios = of_get_property(pdev->dev.of_node, "num-gpios", NULL);
|
||||||
|
if (!num_gpios)
|
||||||
|
dev_err(&pdev->dev, "FIXME: no num-gpios property\n");
|
||||||
|
|
||||||
|
mcs814x_chip = kzalloc(sizeof(*mcs814x_chip), GFP_KERNEL);
|
||||||
|
if (!mcs814x_chip)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
mcs814x_chip->regs = devm_ioremap_resource(&pdev->dev, res);
|
||||||
|
if (!mcs814x_chip->regs) {
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
platform_set_drvdata(pdev, mcs814x_chip);
|
||||||
|
|
||||||
|
#ifdef CONFIG_OF_GPIO
|
||||||
|
mcs814x_chip->chip.of_node = pdev->dev.of_node;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
mcs814x_chip->chip.label = pdev->name;
|
||||||
|
mcs814x_chip->chip.get = mcs814x_gpio_get;
|
||||||
|
mcs814x_chip->chip.set = mcs814x_gpio_set;
|
||||||
|
mcs814x_chip->chip.direction_input = mcs814x_gpio_direction_input;
|
||||||
|
mcs814x_chip->chip.direction_output = mcs814x_gpio_direction_output;
|
||||||
|
mcs814x_chip->chip.ngpio = be32_to_cpup(num_gpios);
|
||||||
|
/* we want dynamic base allocation */
|
||||||
|
mcs814x_chip->chip.base = -1;
|
||||||
|
|
||||||
|
ret = gpiochip_add(&mcs814x_chip->chip);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(&pdev->dev, "failed to register gpiochip\n");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
out:
|
||||||
|
platform_set_drvdata(pdev, NULL);
|
||||||
|
kfree(mcs814x_chip);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct of_device_id mcs814x_gpio_ids[] = {
|
||||||
|
{ .compatible = "moschip,mcs814x-gpio" },
|
||||||
|
{ /* sentinel */ },
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_driver mcs814x_gpio_driver = {
|
||||||
|
.driver = {
|
||||||
|
.name = "mcs814x-gpio",
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
.of_match_table = mcs814x_gpio_ids,
|
||||||
|
},
|
||||||
|
.probe = mcs814x_gpio_probe,
|
||||||
|
};
|
||||||
|
|
||||||
|
int __init mcs814x_gpio_init(void)
|
||||||
|
{
|
||||||
|
return platform_driver_register(&mcs814x_gpio_driver);
|
||||||
|
}
|
||||||
|
postcore_initcall(mcs814x_gpio_init);
|
|
@ -0,0 +1,4 @@
|
||||||
|
config NUPORT_ETHERNET_DRIVER
|
||||||
|
tristate "MCS8140 Ethernet driver"
|
||||||
|
depends on ETHERNET && ARCH_MCS814X
|
||||||
|
help
|
|
@ -0,0 +1,3 @@
|
||||||
|
obj-$(CONFIG_NUPORT_ETHERNET_DRIVER) += mcs8140.o
|
||||||
|
|
||||||
|
mcs8140-objs := nuport_mac.o
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,64 @@
|
||||||
|
/*
|
||||||
|
* Driver for Moschip MCS814x internal PHY
|
||||||
|
*
|
||||||
|
* Copyright (c) 2012 Florian Fainelli <florian@openwrt.org>
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/string.h>
|
||||||
|
#include <linux/errno.h>
|
||||||
|
#include <linux/unistd.h>
|
||||||
|
#include <linux/interrupt.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/delay.h>
|
||||||
|
#include <linux/netdevice.h>
|
||||||
|
#include <linux/etherdevice.h>
|
||||||
|
#include <linux/skbuff.h>
|
||||||
|
#include <linux/spinlock.h>
|
||||||
|
#include <linux/mm.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/mii.h>
|
||||||
|
#include <linux/ethtool.h>
|
||||||
|
#include <linux/phy.h>
|
||||||
|
|
||||||
|
MODULE_DESCRIPTION("Moschip MCS814x PHY driver");
|
||||||
|
MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>");
|
||||||
|
MODULE_LICENSE("GPL");
|
||||||
|
|
||||||
|
/* Nothing special about this PHY but its OUI (O) */
|
||||||
|
static struct phy_driver mcs8140_driver = {
|
||||||
|
.phy_id = 0,
|
||||||
|
.name = "Moschip MCS8140",
|
||||||
|
.phy_id_mask = 0x02,
|
||||||
|
.features = PHY_BASIC_FEATURES,
|
||||||
|
.config_aneg = &genphy_config_aneg,
|
||||||
|
.read_status = &genphy_read_status,
|
||||||
|
.suspend = genphy_suspend,
|
||||||
|
.resume = genphy_resume,
|
||||||
|
.driver = { .owner = THIS_MODULE,},
|
||||||
|
};
|
||||||
|
|
||||||
|
static int __init mcs814x_phy_init(void)
|
||||||
|
{
|
||||||
|
return phy_driver_register(&mcs8140_driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __exit mcs814x_phy_exit(void)
|
||||||
|
{
|
||||||
|
phy_driver_unregister(&mcs8140_driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
module_init(mcs814x_phy_init);
|
||||||
|
module_exit(mcs814x_phy_exit);
|
||||||
|
|
||||||
|
static struct mdio_device_id __maybe_unused mcs814x_phy_tbl[] = {
|
||||||
|
{ 0x0, 0x0ffffff0 },
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
MODULE_DEVICE_TABLE(mdio, mcs814x_phy_tbl);
|
|
@ -0,0 +1,163 @@
|
||||||
|
/*
|
||||||
|
* MCS814X EHCI Host Controller Driver
|
||||||
|
*
|
||||||
|
* Based on "ehci-fsl.c" by Randy Vinson <rvinson@mvista.com>
|
||||||
|
*
|
||||||
|
* 2007 (c) MontaVista Software, Inc. This file is licensed under
|
||||||
|
* the terms of the GNU General Public License version 2. This program
|
||||||
|
* is licensed "as is" without any warranty of any kind, whether express
|
||||||
|
* or implied.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
|
||||||
|
#define MCS814X_EHCI_CAPS_OFFSET 0x68
|
||||||
|
|
||||||
|
static int mcs814x_ehci_init(struct usb_hcd *hcd)
|
||||||
|
{
|
||||||
|
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
|
||||||
|
int retval = 0;
|
||||||
|
|
||||||
|
ehci->caps = hcd->regs + MCS814X_EHCI_CAPS_OFFSET;
|
||||||
|
ehci->regs = hcd->regs
|
||||||
|
+ HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase));
|
||||||
|
ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
|
||||||
|
ehci_reset(ehci);
|
||||||
|
|
||||||
|
retval = ehci_init(hcd);
|
||||||
|
if (retval) {
|
||||||
|
pr_err("ehci_init failed\n");
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct hc_driver mcs814x_ehci_hc_driver = {
|
||||||
|
.description = hcd_name,
|
||||||
|
.product_desc = "MCS814X EHCI Host Controller",
|
||||||
|
.hcd_priv_size = sizeof(struct ehci_hcd),
|
||||||
|
.irq = ehci_irq,
|
||||||
|
.flags = HCD_MEMORY | HCD_USB2,
|
||||||
|
.reset = mcs814x_ehci_init,
|
||||||
|
.start = ehci_run,
|
||||||
|
.stop = ehci_stop,
|
||||||
|
.shutdown = ehci_shutdown,
|
||||||
|
.urb_enqueue = ehci_urb_enqueue,
|
||||||
|
.urb_dequeue = ehci_urb_dequeue,
|
||||||
|
.endpoint_disable = ehci_endpoint_disable,
|
||||||
|
.get_frame_number = ehci_get_frame,
|
||||||
|
.hub_status_data = ehci_hub_status_data,
|
||||||
|
.hub_control = ehci_hub_control,
|
||||||
|
#if defined(CONFIG_PM)
|
||||||
|
.bus_suspend = ehci_bus_suspend,
|
||||||
|
.bus_resume = ehci_bus_resume,
|
||||||
|
#endif
|
||||||
|
.relinquish_port = ehci_relinquish_port,
|
||||||
|
.port_handed_over = ehci_port_handed_over,
|
||||||
|
|
||||||
|
.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int mcs814x_ehci_probe(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct usb_hcd *hcd;
|
||||||
|
const struct hc_driver *driver = &mcs814x_ehci_hc_driver;
|
||||||
|
struct resource *res;
|
||||||
|
int irq;
|
||||||
|
int retval;
|
||||||
|
|
||||||
|
if (usb_disabled())
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
|
||||||
|
if (!res) {
|
||||||
|
dev_err(&pdev->dev,
|
||||||
|
"Found HC with no IRQ. Check %s setup!\n",
|
||||||
|
dev_name(&pdev->dev));
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
irq = res->start;
|
||||||
|
|
||||||
|
pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
|
||||||
|
pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
|
||||||
|
|
||||||
|
hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
|
||||||
|
if (!hcd) {
|
||||||
|
retval = -ENOMEM;
|
||||||
|
goto fail_create_hcd;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
|
if (!res) {
|
||||||
|
dev_err(&pdev->dev,
|
||||||
|
"Found HC with no register addr. Check %s setup!\n",
|
||||||
|
dev_name(&pdev->dev));
|
||||||
|
retval = -ENODEV;
|
||||||
|
goto fail_request_resource;
|
||||||
|
}
|
||||||
|
hcd->rsrc_start = res->start;
|
||||||
|
hcd->rsrc_len = resource_size(res);
|
||||||
|
|
||||||
|
if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
|
||||||
|
driver->description)) {
|
||||||
|
dev_dbg(&pdev->dev, "controller already in use\n");
|
||||||
|
retval = -EBUSY;
|
||||||
|
goto fail_request_resource;
|
||||||
|
}
|
||||||
|
|
||||||
|
hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len);
|
||||||
|
if (hcd->regs == NULL) {
|
||||||
|
dev_dbg(&pdev->dev, "error mapping memory\n");
|
||||||
|
retval = -EFAULT;
|
||||||
|
goto fail_ioremap;
|
||||||
|
}
|
||||||
|
|
||||||
|
retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
|
||||||
|
if (retval)
|
||||||
|
goto fail_add_hcd;
|
||||||
|
|
||||||
|
dev_info(&pdev->dev, "added MCS814X EHCI driver\n");
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
|
||||||
|
fail_add_hcd:
|
||||||
|
iounmap(hcd->regs);
|
||||||
|
fail_ioremap:
|
||||||
|
release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
|
||||||
|
fail_request_resource:
|
||||||
|
usb_put_hcd(hcd);
|
||||||
|
fail_create_hcd:
|
||||||
|
dev_err(&pdev->dev, "init %s fail, %d\n", dev_name(&pdev->dev), retval);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mcs814x_ehci_remove(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct usb_hcd *hcd = platform_get_drvdata(pdev);
|
||||||
|
|
||||||
|
usb_remove_hcd(hcd);
|
||||||
|
iounmap(hcd->regs);
|
||||||
|
release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
|
||||||
|
usb_put_hcd(hcd);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
MODULE_ALIAS("platform:mcs814x-ehci");
|
||||||
|
|
||||||
|
static const struct of_device_id mcs814x_ehci_id[] = {
|
||||||
|
{ .compatible = "moschip,mcs814x-ehci" },
|
||||||
|
{ .compatible = "usb-ehci" },
|
||||||
|
{ /* sentinel */ },
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_driver mcs814x_ehci_driver = {
|
||||||
|
.probe = mcs814x_ehci_probe,
|
||||||
|
.remove = mcs814x_ehci_remove,
|
||||||
|
.driver = {
|
||||||
|
.name = "mcs814x-ehci",
|
||||||
|
.of_match_table = mcs814x_ehci_id,
|
||||||
|
},
|
||||||
|
};
|
|
@ -0,0 +1,202 @@
|
||||||
|
/*
|
||||||
|
* OHCI HCD (Host Controller Driver) for USB.
|
||||||
|
*
|
||||||
|
* (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
|
||||||
|
* (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
|
||||||
|
* (C) Copyright 2002 Hewlett-Packard Company
|
||||||
|
*
|
||||||
|
* Bus Glue for Moschip MCS814x.
|
||||||
|
*
|
||||||
|
* Written by Christopher Hoover <ch@hpl.hp.com>
|
||||||
|
* Based on fragments of previous driver by Russell King et al.
|
||||||
|
*
|
||||||
|
* Modified for LH7A404 from ohci-sa1111.c
|
||||||
|
* by Durgesh Pattamatta <pattamattad@sharpsec.com>
|
||||||
|
*
|
||||||
|
* Modified for pxa27x from ohci-lh7a404.c
|
||||||
|
* by Nick Bane <nick@cecomputing.co.uk> 26-8-2004
|
||||||
|
*
|
||||||
|
* Modified for mcs814x from ohci-mcs814x.c
|
||||||
|
* by Lennert Buytenhek <buytenh@wantstofly.org> 28-2-2006
|
||||||
|
* Based on an earlier driver by Ray Lehtiniemi
|
||||||
|
*
|
||||||
|
* This file is licenced under the GPL.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/device.h>
|
||||||
|
#include <linux/signal.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
|
||||||
|
static int usb_hcd_mcs814x_probe(const struct hc_driver *driver,
|
||||||
|
struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
int retval;
|
||||||
|
struct usb_hcd *hcd;
|
||||||
|
|
||||||
|
if (pdev->resource[1].flags != IORESOURCE_IRQ) {
|
||||||
|
pr_debug("resource[1] is not IORESOURCE_IRQ");
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
|
||||||
|
pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
|
||||||
|
|
||||||
|
hcd = usb_create_hcd(driver, &pdev->dev, "mcs814x");
|
||||||
|
if (hcd == NULL)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
hcd->rsrc_start = pdev->resource[0].start;
|
||||||
|
hcd->rsrc_len = pdev->resource[0].end - pdev->resource[0].start + 1;
|
||||||
|
if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
|
||||||
|
usb_put_hcd(hcd);
|
||||||
|
retval = -EBUSY;
|
||||||
|
goto err1;
|
||||||
|
}
|
||||||
|
|
||||||
|
hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
|
||||||
|
if (hcd->regs == NULL) {
|
||||||
|
pr_debug("ioremap failed");
|
||||||
|
retval = -ENOMEM;
|
||||||
|
goto err2;
|
||||||
|
}
|
||||||
|
|
||||||
|
ohci_hcd_init(hcd_to_ohci(hcd));
|
||||||
|
|
||||||
|
retval = usb_add_hcd(hcd, pdev->resource[1].start, IRQF_DISABLED);
|
||||||
|
if (retval == 0)
|
||||||
|
return retval;
|
||||||
|
|
||||||
|
iounmap(hcd->regs);
|
||||||
|
err2:
|
||||||
|
release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
|
||||||
|
err1:
|
||||||
|
usb_put_hcd(hcd);
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void usb_hcd_mcs814x_remove(struct usb_hcd *hcd,
|
||||||
|
struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
usb_remove_hcd(hcd);
|
||||||
|
iounmap(hcd->regs);
|
||||||
|
release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
|
||||||
|
usb_put_hcd(hcd);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ohci_mcs814x_start(struct usb_hcd *hcd)
|
||||||
|
{
|
||||||
|
struct ohci_hcd *ohci = hcd_to_ohci(hcd);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = ohci_init(ohci);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ret = ohci_run(ohci);
|
||||||
|
if (ret < 0) {
|
||||||
|
ohci_err(ohci, "can't start %s", hcd->self.bus_name);
|
||||||
|
ohci_stop(hcd);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct hc_driver ohci_mcs814x_hc_driver = {
|
||||||
|
.description = hcd_name,
|
||||||
|
.product_desc = "MCS814X OHCI",
|
||||||
|
.hcd_priv_size = sizeof(struct ohci_hcd),
|
||||||
|
.irq = ohci_irq,
|
||||||
|
.flags = HCD_USB11 | HCD_MEMORY,
|
||||||
|
.start = ohci_mcs814x_start,
|
||||||
|
.stop = ohci_stop,
|
||||||
|
.shutdown = ohci_shutdown,
|
||||||
|
.urb_enqueue = ohci_urb_enqueue,
|
||||||
|
.urb_dequeue = ohci_urb_dequeue,
|
||||||
|
.endpoint_disable = ohci_endpoint_disable,
|
||||||
|
.get_frame_number = ohci_get_frame,
|
||||||
|
.hub_status_data = ohci_hub_status_data,
|
||||||
|
.hub_control = ohci_hub_control,
|
||||||
|
#ifdef CONFIG_PM
|
||||||
|
.bus_suspend = ohci_bus_suspend,
|
||||||
|
.bus_resume = ohci_bus_resume,
|
||||||
|
#endif
|
||||||
|
.start_port_reset = ohci_start_port_reset,
|
||||||
|
};
|
||||||
|
|
||||||
|
extern int usb_disabled(void);
|
||||||
|
|
||||||
|
static int ohci_hcd_mcs814x_drv_probe(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = -ENODEV;
|
||||||
|
if (!usb_disabled())
|
||||||
|
ret = usb_hcd_mcs814x_probe(&ohci_mcs814x_hc_driver, pdev);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ohci_hcd_mcs814x_drv_remove(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct usb_hcd *hcd = platform_get_drvdata(pdev);
|
||||||
|
|
||||||
|
usb_hcd_mcs814x_remove(hcd, pdev);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_PM
|
||||||
|
static int ohci_hcd_mcs814x_drv_suspend(struct platform_device *pdev, pm_message_t state)
|
||||||
|
{
|
||||||
|
struct usb_hcd *hcd = platform_get_drvdata(pdev);
|
||||||
|
struct ohci_hcd *ohci = hcd_to_ohci(hcd);
|
||||||
|
|
||||||
|
if (time_before(jiffies, ohci->next_statechange))
|
||||||
|
msleep(5);
|
||||||
|
ohci->next_statechange = jiffies;
|
||||||
|
|
||||||
|
hcd->state = HC_STATE_SUSPENDED;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ohci_hcd_mcs814x_drv_resume(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct usb_hcd *hcd = platform_get_drvdata(pdev);
|
||||||
|
struct ohci_hcd *ohci = hcd_to_ohci(hcd);
|
||||||
|
int status;
|
||||||
|
|
||||||
|
if (time_before(jiffies, ohci->next_statechange))
|
||||||
|
msleep(5);
|
||||||
|
ohci->next_statechange = jiffies;
|
||||||
|
|
||||||
|
ohci_finish_controller_resume(hcd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static const struct of_device_id mcs814x_ohci_id[] = {
|
||||||
|
{ .compatible = "moschip,mcs814x-ohci" },
|
||||||
|
{ .compatible = "ohci-le" },
|
||||||
|
{ /* sentinel */ },
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_driver ohci_hcd_mcs814x_driver = {
|
||||||
|
.probe = ohci_hcd_mcs814x_drv_probe,
|
||||||
|
.remove = ohci_hcd_mcs814x_drv_remove,
|
||||||
|
.shutdown = usb_hcd_platform_shutdown,
|
||||||
|
#ifdef CONFIG_PM
|
||||||
|
.suspend = ohci_hcd_mcs814x_drv_suspend,
|
||||||
|
.resume = ohci_hcd_mcs814x_drv_resume,
|
||||||
|
#endif
|
||||||
|
.driver = {
|
||||||
|
.name = "mcs814x-ohci",
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
.of_match_table = mcs814x_ohci_id,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
MODULE_ALIAS("platform:mcs814x-ohci");
|
|
@ -0,0 +1,207 @@
|
||||||
|
/*
|
||||||
|
* Moschip MCS814x Watchdog driver
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012, Florian Fainelli <florian@openwrt.org>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/miscdevice.h>
|
||||||
|
#include <linux/watchdog.h>
|
||||||
|
#include <linux/io.h>
|
||||||
|
#include <linux/err.h>
|
||||||
|
#include <linux/clk.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
|
||||||
|
#define WDT_COUNT 0x00
|
||||||
|
#define WDT_CTRL 0x04
|
||||||
|
#define WDT_CTRL_EN 0x1
|
||||||
|
|
||||||
|
/* watchdog frequency */
|
||||||
|
#define WDT_MAX_VALUE (0xffffffff)
|
||||||
|
|
||||||
|
struct mcs814x_wdt {
|
||||||
|
void __iomem *regs;
|
||||||
|
spinlock_t lock;
|
||||||
|
struct watchdog_device wdt_dev;
|
||||||
|
struct clk *clk;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int mcs814x_wdt_start(struct watchdog_device *dev)
|
||||||
|
{
|
||||||
|
struct mcs814x_wdt *wdt = watchdog_get_drvdata(dev);
|
||||||
|
u32 reg;
|
||||||
|
|
||||||
|
spin_lock(&wdt->lock);
|
||||||
|
reg = readl_relaxed(wdt->regs + WDT_CTRL);
|
||||||
|
reg |= WDT_CTRL_EN;
|
||||||
|
writel_relaxed(reg, wdt->regs + WDT_CTRL);
|
||||||
|
spin_unlock(&wdt->lock);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mcs814x_wdt_stop(struct watchdog_device *dev)
|
||||||
|
{
|
||||||
|
struct mcs814x_wdt *wdt = watchdog_get_drvdata(dev);
|
||||||
|
u32 reg;
|
||||||
|
|
||||||
|
spin_lock(&wdt->lock);
|
||||||
|
reg = readl_relaxed(wdt->regs + WDT_CTRL);
|
||||||
|
reg &= ~WDT_CTRL_EN;
|
||||||
|
writel_relaxed(reg, wdt->regs + WDT_CTRL);
|
||||||
|
spin_unlock(&wdt->lock);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mcs814x_wdt_set_timeout(struct watchdog_device *dev,
|
||||||
|
unsigned int new_timeout)
|
||||||
|
{
|
||||||
|
struct mcs814x_wdt *wdt = watchdog_get_drvdata(dev);
|
||||||
|
|
||||||
|
spin_lock(&wdt->lock);
|
||||||
|
/* watchdog counts upward and rollover (0xfffffff -> 0)
|
||||||
|
* triggers the reboot
|
||||||
|
*/
|
||||||
|
writel_relaxed(WDT_MAX_VALUE - (new_timeout * clk_get_rate(wdt->clk)),
|
||||||
|
wdt->regs + WDT_COUNT);
|
||||||
|
spin_unlock(&wdt->lock);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mcs814x_wdt_ping(struct watchdog_device *dev)
|
||||||
|
{
|
||||||
|
/* restart the watchdog */
|
||||||
|
mcs814x_wdt_stop(dev);
|
||||||
|
mcs814x_wdt_set_timeout(dev, dev->timeout);
|
||||||
|
mcs814x_wdt_start(dev);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct watchdog_info mcs814x_wdt_ident = {
|
||||||
|
.options = WDIOF_CARDRESET | WDIOF_SETTIMEOUT |
|
||||||
|
WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING,
|
||||||
|
.identity = "MCS814x Watchdog",
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct watchdog_ops mcs814x_wdt_ops = {
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
.start = mcs814x_wdt_start,
|
||||||
|
.stop = mcs814x_wdt_stop,
|
||||||
|
.set_timeout = mcs814x_wdt_set_timeout,
|
||||||
|
.ping = mcs814x_wdt_ping,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int mcs814x_wdt_probe(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct resource *res;
|
||||||
|
struct mcs814x_wdt *wdt;
|
||||||
|
int ret;
|
||||||
|
struct clk *clk;
|
||||||
|
|
||||||
|
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
|
if (!res)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
clk = clk_get(NULL, "wdt");
|
||||||
|
if (IS_ERR_OR_NULL(clk)) {
|
||||||
|
dev_err(&pdev->dev, "failed to get watchdog clock\n");
|
||||||
|
return PTR_ERR(clk);
|
||||||
|
}
|
||||||
|
|
||||||
|
wdt = kzalloc(sizeof(*wdt), GFP_KERNEL);
|
||||||
|
if (!wdt) {
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto out_clk;
|
||||||
|
}
|
||||||
|
|
||||||
|
spin_lock_init(&wdt->lock);
|
||||||
|
wdt->clk = clk;
|
||||||
|
wdt->wdt_dev.info = &mcs814x_wdt_ident;
|
||||||
|
wdt->wdt_dev.ops = &mcs814x_wdt_ops;
|
||||||
|
wdt->wdt_dev.min_timeout = 1;
|
||||||
|
/* approximately 10995 secs */
|
||||||
|
wdt->wdt_dev.max_timeout = (WDT_MAX_VALUE / clk_get_rate(clk));
|
||||||
|
|
||||||
|
platform_set_drvdata(pdev, wdt);
|
||||||
|
|
||||||
|
/* only ioremap registers, because the register is shared */
|
||||||
|
wdt->regs = devm_ioremap(&pdev->dev, res->start, resource_size(res));
|
||||||
|
if (!wdt->regs) {
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
watchdog_set_drvdata(&wdt->wdt_dev, wdt);
|
||||||
|
|
||||||
|
ret = watchdog_register_device(&wdt->wdt_dev);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(&pdev->dev, "cannot register watchdog: %d\n", ret);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev_info(&pdev->dev, "registered\n");
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
out:
|
||||||
|
platform_set_drvdata(pdev, NULL);
|
||||||
|
kfree(wdt);
|
||||||
|
out_clk:
|
||||||
|
clk_put(clk);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mcs814x_wdt_remove(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct mcs814x_wdt *wdt = platform_get_drvdata(pdev);
|
||||||
|
|
||||||
|
clk_put(wdt->clk);
|
||||||
|
watchdog_unregister_device(&wdt->wdt_dev);
|
||||||
|
watchdog_set_drvdata(&wdt->wdt_dev, NULL);
|
||||||
|
kfree(wdt);
|
||||||
|
platform_set_drvdata(pdev, NULL);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct of_device_id mcs814x_wdt_ids[] = {
|
||||||
|
{ .compatible = "moschip,mcs814x-wdt", },
|
||||||
|
{ /* sentinel */ },
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_driver mcs814x_wdt_driver = {
|
||||||
|
.driver = {
|
||||||
|
.name = "mcs814x-wdt",
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
.of_match_table = mcs814x_wdt_ids,
|
||||||
|
},
|
||||||
|
.probe = mcs814x_wdt_probe,
|
||||||
|
.remove = mcs814x_wdt_remove,
|
||||||
|
};
|
||||||
|
|
||||||
|
module_platform_driver(mcs814x_wdt_driver);
|
||||||
|
|
||||||
|
MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>");
|
||||||
|
MODULE_DESCRIPTION("Moschip MCS814x Watchdog driver");
|
||||||
|
MODULE_LICENSE("GPL");
|
||||||
|
MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
|
||||||
|
MODULE_ALIAS("platform:mcs814x-wdt");
|
|
@ -0,0 +1,64 @@
|
||||||
|
--- a/arch/arm/Kconfig
|
||||||
|
+++ b/arch/arm/Kconfig
|
||||||
|
@@ -267,7 +267,8 @@ config PHYS_OFFSET
|
||||||
|
ARCH_INTEGRATOR || \
|
||||||
|
ARCH_IOP13XX || \
|
||||||
|
ARCH_KS8695 || \
|
||||||
|
- (ARCH_REALVIEW && !REALVIEW_HIGH_PHYS_OFFSET)
|
||||||
|
+ (ARCH_REALVIEW && !REALVIEW_HIGH_PHYS_OFFSET) || \
|
||||||
|
+ ARCH_MCS814X
|
||||||
|
default 0x10000000 if ARCH_OMAP1 || ARCH_RPC
|
||||||
|
default 0x20000000 if ARCH_S5PV210
|
||||||
|
default 0x70000000 if REALVIEW_HIGH_PHYS_OFFSET
|
||||||
|
@@ -786,6 +787,21 @@ config ARCH_OMAP1
|
||||||
|
help
|
||||||
|
Support for older TI OMAP1 (omap7xx, omap15xx or omap16xx)
|
||||||
|
|
||||||
|
+config ARCH_MCS814X
|
||||||
|
+ bool "Moschip MCS814x"
|
||||||
|
+ select FIQ
|
||||||
|
+ select GENERIC_IRQ_CHIP
|
||||||
|
+ select GENERIC_GPIO
|
||||||
|
+ select ARCH_REQUIRE_GPIOLIB
|
||||||
|
+ select CLKDEV_LOOKUP
|
||||||
|
+ select ARCH_USES_GETTIMEOFFSET
|
||||||
|
+ select USB_ARCH_HAS_OHCI
|
||||||
|
+ select USB_ARCH_HAS_EHCI
|
||||||
|
+ select MULTI_IRQ_HANDLER
|
||||||
|
+ help
|
||||||
|
+ Support for Moschip MCS814x SoCs (MCS8140).
|
||||||
|
+
|
||||||
|
+
|
||||||
|
endchoice
|
||||||
|
|
||||||
|
menu "Multiple platform selection"
|
||||||
|
@@ -927,6 +944,8 @@ source "arch/arm/mach-picoxcell/Kconfig"
|
||||||
|
source "arch/arm/mach-pxa/Kconfig"
|
||||||
|
source "arch/arm/plat-pxa/Kconfig"
|
||||||
|
|
||||||
|
+source "arch/arm/mach-mcs814x/Kconfig"
|
||||||
|
+
|
||||||
|
source "arch/arm/mach-mmp/Kconfig"
|
||||||
|
|
||||||
|
source "arch/arm/mach-qcom/Kconfig"
|
||||||
|
--- a/arch/arm/Makefile
|
||||||
|
+++ b/arch/arm/Makefile
|
||||||
|
@@ -172,6 +172,7 @@ machine-$(CONFIG_ARCH_IXP4XX) += ixp4xx
|
||||||
|
machine-$(CONFIG_ARCH_KEYSTONE) += keystone
|
||||||
|
machine-$(CONFIG_ARCH_KS8695) += ks8695
|
||||||
|
machine-$(CONFIG_ARCH_LPC32XX) += lpc32xx
|
||||||
|
+machine-$(CONFIG_ARCH_MCS814X) += mcs814x
|
||||||
|
machine-$(CONFIG_ARCH_MESON) += meson
|
||||||
|
machine-$(CONFIG_ARCH_MMP) += mmp
|
||||||
|
machine-$(CONFIG_ARCH_MOXART) += moxart
|
||||||
|
--- a/arch/arm/boot/dts/Makefile
|
||||||
|
+++ b/arch/arm/boot/dts/Makefile
|
||||||
|
@@ -163,6 +163,8 @@ dtb-$(CONFIG_MACH_KIRKWOOD) += kirkwood-
|
||||||
|
kirkwood-ts419-6282.dtb
|
||||||
|
dtb-$(CONFIG_ARCH_LPC32XX) += ea3250.dtb phy3250.dtb
|
||||||
|
dtb-$(CONFIG_ARCH_MARCO) += marco-evb.dtb
|
||||||
|
+dtb-$(CONFIG_ARCH_MCS814X) += dlan-usb-extender.dtb \
|
||||||
|
+ rbt-832.dtb
|
||||||
|
dtb-$(CONFIG_MACH_MESON6) += meson6-atv1200.dtb
|
||||||
|
dtb-$(CONFIG_ARCH_MOXART) += moxart-uc7112lx.dtb
|
||||||
|
dtb-$(CONFIG_ARCH_MXC) += \
|
|
@ -0,0 +1,16 @@
|
||||||
|
--- a/drivers/net/ethernet/Kconfig
|
||||||
|
+++ b/drivers/net/ethernet/Kconfig
|
||||||
|
@@ -186,4 +186,6 @@ source "drivers/net/ethernet/wiznet/Kcon
|
||||||
|
source "drivers/net/ethernet/xilinx/Kconfig"
|
||||||
|
source "drivers/net/ethernet/xircom/Kconfig"
|
||||||
|
|
||||||
|
+source "drivers/net/ethernet/mcs8140/Kconfig"
|
||||||
|
+
|
||||||
|
endif # ETHERNET
|
||||||
|
--- a/drivers/net/ethernet/Makefile
|
||||||
|
+++ b/drivers/net/ethernet/Makefile
|
||||||
|
@@ -84,3 +84,4 @@ obj-$(CONFIG_NET_VENDOR_VIA) += via/
|
||||||
|
obj-$(CONFIG_NET_VENDOR_WIZNET) += wiznet/
|
||||||
|
obj-$(CONFIG_NET_VENDOR_XILINX) += xilinx/
|
||||||
|
obj-$(CONFIG_NET_VENDOR_XIRCOM) += xircom/
|
||||||
|
+obj-$(CONFIG_NUPORT_ETHERNET_DRIVER) += mcs8140/
|
|
@ -0,0 +1,28 @@
|
||||||
|
--- a/drivers/usb/host/ehci-hcd.c
|
||||||
|
+++ b/drivers/usb/host/ehci-hcd.c
|
||||||
|
@@ -1298,6 +1298,11 @@ MODULE_LICENSE ("GPL");
|
||||||
|
#define PLATFORM_DRIVER ehci_hcd_sead3_driver
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+#ifdef CONFIG_ARCH_MCS814X
|
||||||
|
+#include "ehci-mcs814x.c"
|
||||||
|
+#define PLATFORM_DRIVER mcs814x_ehci_driver
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
static int __init ehci_hcd_init(void)
|
||||||
|
{
|
||||||
|
int retval = 0;
|
||||||
|
--- a/drivers/usb/host/ohci-hcd.c
|
||||||
|
+++ b/drivers/usb/host/ohci-hcd.c
|
||||||
|
@@ -1259,6 +1259,11 @@ MODULE_LICENSE ("GPL");
|
||||||
|
#define PLATFORM_DRIVER ohci_hcd_tilegx_driver
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+#ifdef CONFIG_ARCH_MCS814X
|
||||||
|
+#include "ohci-mcs814x.c"
|
||||||
|
+#define PLATFORM_DRIVER ohci_hcd_mcs814x_driver
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
static int __init ohci_hcd_mod_init(void)
|
||||||
|
{
|
||||||
|
int retval = 0;
|
|
@ -0,0 +1,31 @@
|
||||||
|
--- a/drivers/char/hw_random/Kconfig
|
||||||
|
+++ b/drivers/char/hw_random/Kconfig
|
||||||
|
@@ -229,6 +229,18 @@ config HW_RANDOM_TX4939
|
||||||
|
|
||||||
|
If unsure, say Y.
|
||||||
|
|
||||||
|
+config HW_RANDOM_MCS814X
|
||||||
|
+ tristate "Moschip MCS814x Random Number Generator"
|
||||||
|
+ depends on HW_RANDOM && ARCH_MCS814X
|
||||||
|
+ ---help---
|
||||||
|
+ This driver provides kernel-side support for the Random Number
|
||||||
|
+ Generator hardware found on Moschip MCS814x processors.
|
||||||
|
+
|
||||||
|
+ To compile this driver as a module, choose M here: the
|
||||||
|
+ module will be called mcs814x-rng.
|
||||||
|
+
|
||||||
|
+ If unusure, say Y.
|
||||||
|
+
|
||||||
|
config HW_RANDOM_MXC_RNGA
|
||||||
|
tristate "Freescale i.MX RNGA Random Number Generator"
|
||||||
|
depends on ARCH_HAS_RNGA
|
||||||
|
--- a/drivers/char/hw_random/Makefile
|
||||||
|
+++ b/drivers/char/hw_random/Makefile
|
||||||
|
@@ -19,6 +19,7 @@ obj-$(CONFIG_HW_RANDOM_OMAP3_ROM) += oma
|
||||||
|
obj-$(CONFIG_HW_RANDOM_PASEMI) += pasemi-rng.o
|
||||||
|
obj-$(CONFIG_HW_RANDOM_VIRTIO) += virtio-rng.o
|
||||||
|
obj-$(CONFIG_HW_RANDOM_TX4939) += tx4939-rng.o
|
||||||
|
+obj-$(CONFIG_HW_RANDOM_MCS814X) += mcs814x-rng.o
|
||||||
|
obj-$(CONFIG_HW_RANDOM_MXC_RNGA) += mxc-rnga.o
|
||||||
|
obj-$(CONFIG_HW_RANDOM_OCTEON) += octeon-rng.o
|
||||||
|
obj-$(CONFIG_HW_RANDOM_NOMADIK) += nomadik-rng.o
|
|
@ -0,0 +1,25 @@
|
||||||
|
--- a/drivers/watchdog/Kconfig
|
||||||
|
+++ b/drivers/watchdog/Kconfig
|
||||||
|
@@ -505,6 +505,12 @@ config MESON_WATCHDOG
|
||||||
|
To compile this driver as a module, choose M here: the
|
||||||
|
module will be called meson_wdt.
|
||||||
|
|
||||||
|
+config MCS814X_WATCHDOG
|
||||||
|
+ tristate "Moschip MCS814x watchdog"
|
||||||
|
+ depends on WATCHDOG_CORE && ARCH_MCS814X
|
||||||
|
+ help
|
||||||
|
+ Support for the Moschip MCS814x SoCs on-chip watchdog timer.
|
||||||
|
+
|
||||||
|
# AVR32 Architecture
|
||||||
|
|
||||||
|
config AT32AP700X_WDT
|
||||||
|
--- a/drivers/watchdog/Makefile
|
||||||
|
+++ b/drivers/watchdog/Makefile
|
||||||
|
@@ -63,6 +63,7 @@ obj-$(CONFIG_QCOM_WDT) += qcom-wdt.o
|
||||||
|
obj-$(CONFIG_BCM_KONA_WDT) += bcm_kona_wdt.o
|
||||||
|
obj-$(CONFIG_TEGRA_WATCHDOG) += tegra_wdt.o
|
||||||
|
obj-$(CONFIG_MESON_WATCHDOG) += meson_wdt.o
|
||||||
|
+obj-$(CONFIG_MCS814X_WATCHDOG) += mcs814x_wdt.o
|
||||||
|
|
||||||
|
# AVR32 Architecture
|
||||||
|
obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o
|
|
@ -0,0 +1,25 @@
|
||||||
|
--- a/drivers/gpio/Kconfig
|
||||||
|
+++ b/drivers/gpio/Kconfig
|
||||||
|
@@ -819,6 +819,12 @@ config GPIO_MC33880
|
||||||
|
SPI driver for Freescale MC33880 high-side/low-side switch.
|
||||||
|
This provides GPIO interface supporting inputs and outputs.
|
||||||
|
|
||||||
|
+config GPIO_MCS814X
|
||||||
|
+ tristate "Moschip MCS814x GPIO support"
|
||||||
|
+ depends on ARCH_MCS814X
|
||||||
|
+ help
|
||||||
|
+ GPIO driver for Moschip MCS814x SoC gpio controllers.
|
||||||
|
+
|
||||||
|
config GPIO_74X164
|
||||||
|
tristate "74x164 serial-in/parallel-out 8-bits shift register"
|
||||||
|
depends on SPI_MASTER && OF
|
||||||
|
--- a/drivers/gpio/Makefile
|
||||||
|
+++ b/drivers/gpio/Makefile
|
||||||
|
@@ -49,6 +49,7 @@ obj-$(CONFIG_GPIO_MAX732X) += gpio-max73
|
||||||
|
obj-$(CONFIG_GPIO_MC33880) += gpio-mc33880.o
|
||||||
|
obj-$(CONFIG_GPIO_MC9S08DZ60) += gpio-mc9s08dz60.o
|
||||||
|
obj-$(CONFIG_GPIO_MCP23S08) += gpio-mcp23s08.o
|
||||||
|
+obj-$(CONFIG_GPIO_MCS814X) += gpio-mcs814x.o
|
||||||
|
obj-$(CONFIG_GPIO_ML_IOH) += gpio-ml-ioh.o
|
||||||
|
obj-$(CONFIG_GPIO_MM_LANTIQ) += gpio-mm-lantiq.o
|
||||||
|
obj-$(CONFIG_GPIO_MOXART) += gpio-moxart.o
|
|
@ -0,0 +1,20 @@
|
||||||
|
--- a/drivers/net/phy/Kconfig
|
||||||
|
+++ b/drivers/net/phy/Kconfig
|
||||||
|
@@ -164,6 +164,10 @@ config RTL8306_PHY
|
||||||
|
tristate "Driver for Realtek RTL8306S switches"
|
||||||
|
select SWCONFIG
|
||||||
|
|
||||||
|
+config MCS814X_PHY
|
||||||
|
+ tristate "Driver for the Moschip MCS814x internal PHY"
|
||||||
|
+ depends on ARCH_MCS814X
|
||||||
|
+
|
||||||
|
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
|
||||||
|
@@ -51,3 +51,4 @@ obj-$(CONFIG_MDIO_SUN4I) += mdio-sun4i.o
|
||||||
|
obj-$(CONFIG_MDIO_MOXART) += mdio-moxart.o
|
||||||
|
obj-$(CONFIG_AMD_XGBE_PHY) += amd-xgbe-phy.o
|
||||||
|
obj-$(CONFIG_MDIO_BCM_UNIMAC) += mdio-bcm-unimac.o
|
||||||
|
+obj-$(CONFIG_MCS814X_PHY) += mcs814x.o
|
|
@ -0,0 +1,14 @@
|
||||||
|
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
|
||||||
|
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
|
||||||
|
@@ -40,9 +40,9 @@
|
||||||
|
#include <linux/mtd/xip.h>
|
||||||
|
|
||||||
|
#define AMD_BOOTLOC_BUG
|
||||||
|
-#define FORCE_WORD_WRITE 0
|
||||||
|
+#define FORCE_WORD_WRITE 1
|
||||||
|
|
||||||
|
-#define MAX_WORD_RETRIES 3
|
||||||
|
+#define MAX_WORD_RETRIES 10
|
||||||
|
|
||||||
|
#define SST49LF004B 0x0060
|
||||||
|
#define SST49LF040B 0x0050
|
|
@ -0,0 +1,64 @@
|
||||||
|
--- a/drivers/usb/host/ohci.h
|
||||||
|
+++ b/drivers/usb/host/ohci.h
|
||||||
|
@@ -122,7 +122,7 @@ struct td {
|
||||||
|
/* PSW is only for ISO. Only 1 PSW entry is used, but on
|
||||||
|
* big-endian PPC hardware that's the second entry.
|
||||||
|
*/
|
||||||
|
-#define MAXPSW 2
|
||||||
|
+#define MAXPSW 8
|
||||||
|
__hc16 hwPSW [MAXPSW];
|
||||||
|
|
||||||
|
/* rest are purely for the driver's use */
|
||||||
|
--- a/drivers/usb/host/ohci-hcd.c
|
||||||
|
+++ b/drivers/usb/host/ohci-hcd.c
|
||||||
|
@@ -441,6 +441,7 @@ static int ohci_init (struct ohci_hcd *o
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
struct usb_hcd *hcd = ohci_to_hcd(ohci);
|
||||||
|
+ u32 hcca_area;
|
||||||
|
|
||||||
|
/* Accept arbitrarily long scatter-gather lists */
|
||||||
|
hcd->self.sg_tablesize = ~0;
|
||||||
|
@@ -501,11 +502,13 @@ static int ohci_init (struct ohci_hcd *o
|
||||||
|
(unsigned long) ohci);
|
||||||
|
set_timer_slack(&ohci->io_watchdog, msecs_to_jiffies(20));
|
||||||
|
|
||||||
|
- ohci->hcca = dma_alloc_coherent (hcd->self.controller,
|
||||||
|
- sizeof(*ohci->hcca), &ohci->hcca_dma, GFP_KERNEL);
|
||||||
|
+ hcca_area = ohci_readl(ohci, &ohci->regs->hcca);
|
||||||
|
+ ohci->hcca = ioremap_nocache(hcca_area, sizeof *ohci->hcca);
|
||||||
|
if (!ohci->hcca)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
+ ohci->hcca_dma = hcca_area;
|
||||||
|
+
|
||||||
|
if ((ret = ohci_mem_init (ohci)) < 0)
|
||||||
|
ohci_stop (hcd);
|
||||||
|
else {
|
||||||
|
@@ -523,6 +526,7 @@ static int ohci_init (struct ohci_hcd *o
|
||||||
|
*/
|
||||||
|
static int ohci_run (struct ohci_hcd *ohci)
|
||||||
|
{
|
||||||
|
+ int i = 0;
|
||||||
|
u32 mask, val;
|
||||||
|
int first = ohci->fminterval == 0;
|
||||||
|
struct usb_hcd *hcd = ohci_to_hcd(ohci);
|
||||||
|
@@ -573,6 +577,8 @@ static int ohci_run (struct ohci_hcd *oh
|
||||||
|
msleep(val);
|
||||||
|
|
||||||
|
memset (ohci->hcca, 0, sizeof (struct ohci_hcca));
|
||||||
|
+ for (i = 0; i < NUM_INTS; i++)
|
||||||
|
+ ohci->hcca->int_table[i] = 0;
|
||||||
|
|
||||||
|
/* 2msec timelimit here means no irqs/preempt */
|
||||||
|
spin_lock_irq (&ohci->lock);
|
||||||
|
@@ -984,9 +990,6 @@ static void ohci_stop (struct usb_hcd *h
|
||||||
|
remove_debug_files (ohci);
|
||||||
|
ohci_mem_cleanup (ohci);
|
||||||
|
if (ohci->hcca) {
|
||||||
|
- dma_free_coherent (hcd->self.controller,
|
||||||
|
- sizeof *ohci->hcca,
|
||||||
|
- ohci->hcca, ohci->hcca_dma);
|
||||||
|
ohci->hcca = NULL;
|
||||||
|
ohci->hcca_dma = 0;
|
||||||
|
}
|
Loading…
Reference in New Issue