diff options
Diffstat (limited to 'recipes/linux/linux-2.6.30/tx25/linux-2.6.30-rc4-karo.diff')
-rw-r--r-- | recipes/linux/linux-2.6.30/tx25/linux-2.6.30-rc4-karo.diff | 17631 |
1 files changed, 17631 insertions, 0 deletions
diff --git a/recipes/linux/linux-2.6.30/tx25/linux-2.6.30-rc4-karo.diff b/recipes/linux/linux-2.6.30/tx25/linux-2.6.30-rc4-karo.diff new file mode 100644 index 0000000000..6926571c2e --- /dev/null +++ b/recipes/linux/linux-2.6.30/tx25/linux-2.6.30-rc4-karo.diff @@ -0,0 +1,17631 @@ +diff -urNp linux-2.6.30-rc4/.config linux-2.6.30-rc4-karo/.config +--- linux-2.6.30-rc4/.config 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30-rc4-karo/.config 2009-06-02 16:17:34.000000000 +0200 +@@ -0,0 +1,1203 @@ ++# ++# Automatically generated make config: don't edit ++# Linux kernel version: 2.6.30-rc4 ++# Tue Jun 2 15:46:43 2009 ++# ++CONFIG_ARM=y ++CONFIG_SYS_SUPPORTS_APM_EMULATION=y ++CONFIG_GENERIC_GPIO=y ++CONFIG_GENERIC_TIME=y ++CONFIG_GENERIC_CLOCKEVENTS=y ++CONFIG_MMU=y ++# CONFIG_NO_IOPORT is not set ++CONFIG_GENERIC_HARDIRQS=y ++CONFIG_STACKTRACE_SUPPORT=y ++CONFIG_HAVE_LATENCYTOP_SUPPORT=y ++CONFIG_LOCKDEP_SUPPORT=y ++CONFIG_TRACE_IRQFLAGS_SUPPORT=y ++CONFIG_HARDIRQS_SW_RESEND=y ++CONFIG_GENERIC_IRQ_PROBE=y ++CONFIG_RWSEM_GENERIC_SPINLOCK=y ++# CONFIG_ARCH_HAS_ILOG2_U32 is not set ++# CONFIG_ARCH_HAS_ILOG2_U64 is not set ++CONFIG_GENERIC_HWEIGHT=y ++CONFIG_GENERIC_CALIBRATE_DELAY=y ++CONFIG_ARCH_MTD_XIP=y ++CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y ++CONFIG_VECTORS_BASE=0xffff0000 ++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" ++ ++# ++# General setup ++# ++CONFIG_EXPERIMENTAL=y ++CONFIG_BROKEN_ON_SMP=y ++CONFIG_LOCK_KERNEL=y ++CONFIG_INIT_ENV_ARG_LIMIT=32 ++CONFIG_LOCALVERSION="" ++CONFIG_LOCALVERSION_AUTO=y ++# CONFIG_SWAP is not set ++CONFIG_SYSVIPC=y ++CONFIG_SYSVIPC_SYSCTL=y ++CONFIG_POSIX_MQUEUE=y ++CONFIG_POSIX_MQUEUE_SYSCTL=y ++# CONFIG_BSD_PROCESS_ACCT is not set ++# CONFIG_TASKSTATS is not set ++# CONFIG_AUDIT is not set ++ ++# ++# RCU Subsystem ++# ++CONFIG_CLASSIC_RCU=y ++# CONFIG_TREE_RCU is not set ++# CONFIG_PREEMPT_RCU is not set ++# CONFIG_TREE_RCU_TRACE is not set ++# CONFIG_PREEMPT_RCU_TRACE is not set ++# CONFIG_IKCONFIG is not set ++CONFIG_LOG_BUF_SHIFT=17 ++# CONFIG_GROUP_SCHED is not set ++# CONFIG_CGROUPS is not set ++# CONFIG_SYSFS_DEPRECATED_V2 is not set ++# CONFIG_RELAY is not set ++# CONFIG_NAMESPACES is not set ++CONFIG_BLK_DEV_INITRD=y ++CONFIG_INITRAMFS_SOURCE="" ++CONFIG_RD_GZIP=y ++# CONFIG_RD_BZIP2 is not set ++# CONFIG_RD_LZMA is not set ++# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set ++CONFIG_SYSCTL=y ++CONFIG_ANON_INODES=y ++CONFIG_EMBEDDED=y ++CONFIG_UID16=y ++CONFIG_SYSCTL_SYSCALL=y ++CONFIG_KALLSYMS=y ++# CONFIG_KALLSYMS_ALL is not set ++# CONFIG_KALLSYMS_EXTRA_PASS is not set ++# CONFIG_STRIP_ASM_SYMS is not set ++CONFIG_HOTPLUG=y ++CONFIG_PRINTK=y ++CONFIG_BUG=y ++# CONFIG_ELF_CORE is not set ++CONFIG_BASE_FULL=y ++CONFIG_FUTEX=y ++CONFIG_EPOLL=y ++CONFIG_SIGNALFD=y ++CONFIG_TIMERFD=y ++CONFIG_EVENTFD=y ++CONFIG_SHMEM=y ++# CONFIG_AIO is not set ++# CONFIG_VM_EVENT_COUNTERS is not set ++# CONFIG_COMPAT_BRK is not set ++CONFIG_SLAB=y ++# CONFIG_SLUB is not set ++# CONFIG_SLOB is not set ++# CONFIG_PROFILING is not set ++# CONFIG_MARKERS is not set ++CONFIG_HAVE_OPROFILE=y ++# CONFIG_KPROBES is not set ++CONFIG_HAVE_KPROBES=y ++CONFIG_HAVE_KRETPROBES=y ++CONFIG_HAVE_CLK=y ++# CONFIG_SLOW_WORK is not set ++CONFIG_HAVE_GENERIC_DMA_COHERENT=y ++CONFIG_SLABINFO=y ++CONFIG_RT_MUTEXES=y ++CONFIG_BASE_SMALL=0 ++CONFIG_MODULES=y ++# CONFIG_MODULE_FORCE_LOAD is not set ++CONFIG_MODULE_UNLOAD=y ++CONFIG_MODULE_FORCE_UNLOAD=y ++CONFIG_MODVERSIONS=y ++# CONFIG_MODULE_SRCVERSION_ALL is not set ++CONFIG_BLOCK=y ++CONFIG_LBD=y ++# CONFIG_BLK_DEV_BSG is not set ++# CONFIG_BLK_DEV_INTEGRITY is not set ++ ++# ++# IO Schedulers ++# ++CONFIG_IOSCHED_NOOP=y ++CONFIG_IOSCHED_AS=y ++CONFIG_IOSCHED_DEADLINE=y ++CONFIG_IOSCHED_CFQ=y ++CONFIG_DEFAULT_AS=y ++# CONFIG_DEFAULT_DEADLINE is not set ++# CONFIG_DEFAULT_CFQ is not set ++# CONFIG_DEFAULT_NOOP is not set ++CONFIG_DEFAULT_IOSCHED="anticipatory" ++CONFIG_FREEZER=y ++ ++# ++# System Type ++# ++# CONFIG_ARCH_AAEC2000 is not set ++# CONFIG_ARCH_INTEGRATOR is not set ++# CONFIG_ARCH_REALVIEW is not set ++# CONFIG_ARCH_VERSATILE is not set ++# CONFIG_ARCH_AT91 is not set ++# CONFIG_ARCH_CLPS711X is not set ++# CONFIG_ARCH_EBSA110 is not set ++# CONFIG_ARCH_EP93XX is not set ++# CONFIG_ARCH_GEMINI is not set ++# CONFIG_ARCH_FOOTBRIDGE is not set ++# CONFIG_ARCH_NETX is not set ++# CONFIG_ARCH_H720X is not set ++# CONFIG_ARCH_IOP13XX is not set ++# CONFIG_ARCH_IOP32X is not set ++# CONFIG_ARCH_IOP33X is not set ++# CONFIG_ARCH_IXP23XX is not set ++# CONFIG_ARCH_IXP2000 is not set ++# CONFIG_ARCH_IXP4XX is not set ++# CONFIG_ARCH_L7200 is not set ++# CONFIG_ARCH_KIRKWOOD is not set ++# CONFIG_ARCH_KS8695 is not set ++# CONFIG_ARCH_NS9XXX is not set ++# CONFIG_ARCH_LOKI is not set ++# CONFIG_ARCH_MV78XX0 is not set ++CONFIG_ARCH_MXC=y ++# CONFIG_ARCH_ORION5X is not set ++# CONFIG_ARCH_PNX4008 is not set ++# CONFIG_ARCH_PXA is not set ++# CONFIG_ARCH_MMP is not set ++# CONFIG_ARCH_RPC is not set ++# CONFIG_ARCH_SA1100 is not set ++# CONFIG_ARCH_S3C2410 is not set ++# CONFIG_ARCH_S3C64XX is not set ++# CONFIG_ARCH_SHARK is not set ++# CONFIG_ARCH_LH7A40X is not set ++# CONFIG_ARCH_DAVINCI is not set ++# CONFIG_ARCH_OMAP is not set ++# CONFIG_ARCH_MSM is not set ++# CONFIG_ARCH_W90X900 is not set ++ ++# ++# Freescale MXC Implementations ++# ++# CONFIG_ARCH_MX1 is not set ++CONFIG_ARCH_MX2=y ++# CONFIG_ARCH_MX3 is not set ++# CONFIG_MACH_MX21 is not set ++# CONFIG_MACH_MX27 is not set ++CONFIG_MACH_MX25=y ++ ++# ++# MX2 platforms: ++# ++CONFIG_MACH_TX25=y ++# CONFIG_KARO_DEBUG is not set ++CONFIG_MACH_STK5_BASEBOARD=y ++# CONFIG_MXC_IRQ_PRIOR is not set ++# CONFIG_MXC_PWM is not set ++CONFIG_ARCH_MXC_IOMUX_V3=y ++ ++# ++# Processor Type ++# ++CONFIG_CPU_32=y ++CONFIG_CPU_ARM926T=y ++CONFIG_CPU_32v5=y ++CONFIG_CPU_ABRT_EV5TJ=y ++CONFIG_CPU_PABRT_NOIFAR=y ++CONFIG_CPU_CACHE_VIVT=y ++CONFIG_CPU_COPY_V4WB=y ++CONFIG_CPU_TLB_V4WBI=y ++CONFIG_CPU_CP15=y ++CONFIG_CPU_CP15_MMU=y ++ ++# ++# Processor Features ++# ++CONFIG_ARM_THUMB=y ++# CONFIG_CPU_ICACHE_DISABLE is not set ++# CONFIG_CPU_DCACHE_DISABLE is not set ++# CONFIG_CPU_DCACHE_WRITETHROUGH is not set ++# CONFIG_CPU_CACHE_ROUND_ROBIN is not set ++# CONFIG_OUTER_CACHE is not set ++CONFIG_COMMON_CLKDEV=y ++ ++# ++# Bus support ++# ++# CONFIG_PCI_SYSCALL is not set ++# CONFIG_ARCH_SUPPORTS_MSI is not set ++# CONFIG_PCCARD is not set ++ ++# ++# Kernel Features ++# ++CONFIG_TICK_ONESHOT=y ++CONFIG_NO_HZ=y ++# CONFIG_HIGH_RES_TIMERS is not set ++CONFIG_GENERIC_CLOCKEVENTS_BUILD=y ++CONFIG_VMSPLIT_3G=y ++# CONFIG_VMSPLIT_2G is not set ++# CONFIG_VMSPLIT_1G is not set ++CONFIG_PAGE_OFFSET=0xC0000000 ++CONFIG_PREEMPT=y ++CONFIG_HZ=100 ++CONFIG_AEABI=y ++CONFIG_OABI_COMPAT=y ++CONFIG_ARCH_FLATMEM_HAS_HOLES=y ++# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set ++# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set ++# CONFIG_HIGHMEM is not set ++CONFIG_SELECT_MEMORY_MODEL=y ++CONFIG_FLATMEM_MANUAL=y ++# CONFIG_DISCONTIGMEM_MANUAL is not set ++# CONFIG_SPARSEMEM_MANUAL is not set ++CONFIG_FLATMEM=y ++CONFIG_FLAT_NODE_MEM_MAP=y ++CONFIG_PAGEFLAGS_EXTENDED=y ++CONFIG_SPLIT_PTLOCK_CPUS=4096 ++# CONFIG_PHYS_ADDR_T_64BIT is not set ++CONFIG_ZONE_DMA_FLAG=0 ++CONFIG_VIRT_TO_BUS=y ++CONFIG_UNEVICTABLE_LRU=y ++CONFIG_HAVE_MLOCK=y ++CONFIG_HAVE_MLOCKED_PAGE_BIT=y ++CONFIG_ALIGNMENT_TRAP=y ++ ++# ++# Boot options ++# ++CONFIG_ZBOOT_ROM_TEXT=0 ++CONFIG_ZBOOT_ROM_BSS=0 ++CONFIG_CMDLINE="init=/linuxrc root=1f01 rootfstype=jffs2 ro console=ttymxc0,115200 panic=1" ++# CONFIG_XIP_KERNEL is not set ++# CONFIG_KEXEC is not set ++ ++# ++# CPU Power Management ++# ++CONFIG_CPU_IDLE=y ++CONFIG_CPU_IDLE_GOV_LADDER=y ++CONFIG_CPU_IDLE_GOV_MENU=y ++ ++# ++# Floating point emulation ++# ++ ++# ++# At least one emulation must be selected ++# ++CONFIG_FPE_NWFPE=y ++# CONFIG_FPE_NWFPE_XP is not set ++# CONFIG_FPE_FASTFPE is not set ++CONFIG_VFP=y ++ ++# ++# Userspace binary formats ++# ++CONFIG_BINFMT_ELF=y ++CONFIG_HAVE_AOUT=y ++# CONFIG_BINFMT_AOUT is not set ++# CONFIG_BINFMT_MISC is not set ++ ++# ++# Power management options ++# ++CONFIG_PM=y ++CONFIG_PM_DEBUG=y ++CONFIG_PM_VERBOSE=y ++CONFIG_CAN_PM_TRACE=y ++CONFIG_PM_SLEEP=y ++CONFIG_SUSPEND=y ++CONFIG_SUSPEND_FREEZER=y ++CONFIG_APM_EMULATION=y ++CONFIG_ARCH_SUSPEND_POSSIBLE=y ++CONFIG_NET=y ++ ++# ++# Networking options ++# ++CONFIG_PACKET=y ++CONFIG_PACKET_MMAP=y ++CONFIG_UNIX=y ++# CONFIG_NET_KEY is not set ++CONFIG_INET=y ++# CONFIG_IP_MULTICAST is not set ++# CONFIG_IP_ADVANCED_ROUTER is not set ++CONFIG_IP_FIB_HASH=y ++CONFIG_IP_PNP=y ++CONFIG_IP_PNP_DHCP=y ++CONFIG_IP_PNP_BOOTP=y ++# CONFIG_IP_PNP_RARP is not set ++# CONFIG_NET_IPIP is not set ++# CONFIG_NET_IPGRE is not set ++# CONFIG_ARPD is not set ++CONFIG_SYN_COOKIES=y ++# CONFIG_INET_AH is not set ++# CONFIG_INET_ESP is not set ++# CONFIG_INET_IPCOMP is not set ++# CONFIG_INET_XFRM_TUNNEL is not set ++# CONFIG_INET_TUNNEL is not set ++# CONFIG_INET_XFRM_MODE_TRANSPORT is not set ++# CONFIG_INET_XFRM_MODE_TUNNEL is not set ++# CONFIG_INET_XFRM_MODE_BEET is not set ++# CONFIG_INET_LRO is not set ++# CONFIG_INET_DIAG is not set ++# CONFIG_TCP_CONG_ADVANCED is not set ++CONFIG_TCP_CONG_CUBIC=y ++CONFIG_DEFAULT_TCP_CONG="cubic" ++# CONFIG_TCP_MD5SIG is not set ++# CONFIG_IPV6 is not set ++# CONFIG_NETWORK_SECMARK is not set ++# CONFIG_NETFILTER is not set ++# CONFIG_IP_DCCP is not set ++# CONFIG_IP_SCTP is not set ++# CONFIG_TIPC is not set ++# CONFIG_ATM is not set ++# CONFIG_BRIDGE is not set ++# CONFIG_NET_DSA is not set ++# CONFIG_VLAN_8021Q is not set ++# CONFIG_DECNET is not set ++# CONFIG_LLC2 is not set ++# CONFIG_IPX is not set ++# CONFIG_ATALK is not set ++# CONFIG_X25 is not set ++# CONFIG_LAPB is not set ++# CONFIG_ECONET is not set ++# CONFIG_WAN_ROUTER is not set ++# CONFIG_PHONET is not set ++# CONFIG_NET_SCHED is not set ++# CONFIG_DCB is not set ++ ++# ++# Network testing ++# ++# CONFIG_NET_PKTGEN is not set ++# CONFIG_HAMRADIO is not set ++# CONFIG_CAN is not set ++# CONFIG_IRDA is not set ++# CONFIG_BT is not set ++# CONFIG_AF_RXRPC is not set ++# CONFIG_WIRELESS is not set ++# CONFIG_WIMAX is not set ++# CONFIG_RFKILL is not set ++# CONFIG_NET_9P is not set ++ ++# ++# Device Drivers ++# ++ ++# ++# Generic Driver Options ++# ++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" ++CONFIG_STANDALONE=y ++CONFIG_PREVENT_FIRMWARE_BUILD=y ++CONFIG_FW_LOADER=y ++CONFIG_FIRMWARE_IN_KERNEL=y ++CONFIG_EXTRA_FIRMWARE="" ++# CONFIG_DEBUG_DRIVER is not set ++# CONFIG_DEBUG_DEVRES is not set ++# CONFIG_SYS_HYPERVISOR is not set ++# CONFIG_CONNECTOR is not set ++CONFIG_MTD=y ++CONFIG_MTD_DEBUG=y ++CONFIG_MTD_DEBUG_VERBOSE=0 ++CONFIG_MTD_CONCAT=y ++CONFIG_MTD_PARTITIONS=y ++CONFIG_MTD_TESTS=m ++CONFIG_MTD_REDBOOT_PARTS=y ++CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-5 ++# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set ++CONFIG_MTD_REDBOOT_PARTS_READONLY=y ++CONFIG_MTD_CMDLINE_PARTS=y ++# CONFIG_MTD_AFS_PARTS is not set ++# CONFIG_MTD_AR7_PARTS is not set ++ ++# ++# User Modules And Translation Layers ++# ++CONFIG_MTD_CHAR=y ++CONFIG_MTD_BLKDEVS=y ++CONFIG_MTD_BLOCK=y ++# CONFIG_FTL is not set ++# CONFIG_NFTL is not set ++# CONFIG_INFTL is not set ++# CONFIG_RFD_FTL is not set ++# CONFIG_SSFDC is not set ++# CONFIG_MTD_OOPS is not set ++ ++# ++# RAM/ROM/Flash chip drivers ++# ++# CONFIG_MTD_CFI is not set ++# CONFIG_MTD_JEDECPROBE is not set ++CONFIG_MTD_MAP_BANK_WIDTH_1=y ++CONFIG_MTD_MAP_BANK_WIDTH_2=y ++CONFIG_MTD_MAP_BANK_WIDTH_4=y ++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set ++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set ++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set ++CONFIG_MTD_CFI_I1=y ++CONFIG_MTD_CFI_I2=y ++# CONFIG_MTD_CFI_I4 is not set ++# CONFIG_MTD_CFI_I8 is not set ++# CONFIG_MTD_RAM is not set ++# CONFIG_MTD_ROM is not set ++# CONFIG_MTD_ABSENT is not set ++ ++# ++# Mapping drivers for chip access ++# ++# CONFIG_MTD_COMPLEX_MAPPINGS is not set ++# CONFIG_MTD_PLATRAM is not set ++ ++# ++# Self-contained MTD device drivers ++# ++# CONFIG_MTD_SLRAM is not set ++# CONFIG_MTD_PHRAM is not set ++# CONFIG_MTD_MTDRAM is not set ++# CONFIG_MTD_BLOCK2MTD is not set ++ ++# ++# Disk-On-Chip Device Drivers ++# ++# CONFIG_MTD_DOC2000 is not set ++# CONFIG_MTD_DOC2001 is not set ++# CONFIG_MTD_DOC2001PLUS is not set ++CONFIG_MTD_NAND=y ++CONFIG_MTD_NAND_VERIFY_WRITE=y ++# CONFIG_MTD_NAND_ECC_SMC is not set ++# CONFIG_MTD_NAND_MUSEUM_IDS is not set ++# CONFIG_MTD_NAND_GPIO is not set ++CONFIG_MTD_NAND_IDS=y ++# CONFIG_MTD_NAND_DISKONCHIP is not set ++# CONFIG_MTD_NAND_NANDSIM is not set ++# CONFIG_MTD_NAND_PLATFORM is not set ++# CONFIG_MTD_NAND_MXC is not set ++CONFIG_ARCH_MXC_HAS_NFC_V2=y ++CONFIG_ARCH_MXC_HAS_NFC_V2_1=y ++# CONFIG_MTD_ONENAND is not set ++ ++# ++# LPDDR flash memory drivers ++# ++# CONFIG_MTD_LPDDR is not set ++ ++# ++# UBI - Unsorted block images ++# ++# CONFIG_MTD_UBI is not set ++# CONFIG_PARPORT is not set ++CONFIG_BLK_DEV=y ++# CONFIG_BLK_DEV_COW_COMMON is not set ++CONFIG_BLK_DEV_LOOP=m ++# CONFIG_BLK_DEV_CRYPTOLOOP is not set ++# CONFIG_BLK_DEV_NBD is not set ++CONFIG_BLK_DEV_RAM=y ++CONFIG_BLK_DEV_RAM_COUNT=16 ++CONFIG_BLK_DEV_RAM_SIZE=8192 ++# CONFIG_BLK_DEV_XIP is not set ++# CONFIG_CDROM_PKTCDVD is not set ++# CONFIG_ATA_OVER_ETH is not set ++CONFIG_MISC_DEVICES=y ++# CONFIG_ENCLOSURE_SERVICES is not set ++# CONFIG_C2PORT is not set ++ ++# ++# EEPROM support ++# ++# CONFIG_EEPROM_93CX6 is not set ++CONFIG_HAVE_IDE=y ++# CONFIG_IDE is not set ++ ++# ++# SCSI device support ++# ++# CONFIG_RAID_ATTRS is not set ++# CONFIG_SCSI is not set ++# CONFIG_SCSI_DMA is not set ++# CONFIG_SCSI_NETLINK is not set ++# CONFIG_ATA is not set ++# CONFIG_MD is not set ++CONFIG_NETDEVICES=y ++CONFIG_COMPAT_NET_DEV_OPS=y ++# CONFIG_DUMMY is not set ++# CONFIG_BONDING is not set ++# CONFIG_MACVLAN is not set ++# CONFIG_EQUALIZER is not set ++# CONFIG_TUN is not set ++# CONFIG_VETH is not set ++CONFIG_PHYLIB=y ++ ++# ++# MII PHY device drivers ++# ++# CONFIG_MARVELL_PHY is not set ++# CONFIG_DAVICOM_PHY is not set ++# CONFIG_QSEMI_PHY is not set ++# CONFIG_LXT_PHY is not set ++# CONFIG_CICADA_PHY is not set ++# CONFIG_VITESSE_PHY is not set ++CONFIG_SMSC_PHY=y ++# CONFIG_BROADCOM_PHY is not set ++# CONFIG_ICPLUS_PHY is not set ++# CONFIG_REALTEK_PHY is not set ++# CONFIG_NATIONAL_PHY is not set ++# CONFIG_STE10XP is not set ++# CONFIG_LSI_ET1011C_PHY is not set ++# CONFIG_FIXED_PHY is not set ++# CONFIG_MDIO_BITBANG is not set ++CONFIG_NET_ETHERNET=y ++CONFIG_MII=y ++# CONFIG_AX88796 is not set ++# CONFIG_SMC91X is not set ++# CONFIG_DM9000 is not set ++# CONFIG_ETHOC is not set ++# CONFIG_SMC911X is not set ++# CONFIG_SMSC911X is not set ++# CONFIG_DNET is not set ++# CONFIG_IBM_NEW_EMAC_ZMII is not set ++# CONFIG_IBM_NEW_EMAC_RGMII is not set ++# CONFIG_IBM_NEW_EMAC_TAH is not set ++# CONFIG_IBM_NEW_EMAC_EMAC4 is not set ++# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set ++# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set ++# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set ++# CONFIG_B44 is not set ++CONFIG_FEC=y ++# CONFIG_FEC2 is not set ++# CONFIG_NETDEV_1000 is not set ++# CONFIG_NETDEV_10000 is not set ++ ++# ++# Wireless LAN ++# ++# CONFIG_WLAN_PRE80211 is not set ++# CONFIG_WLAN_80211 is not set ++ ++# ++# Enable WiMAX (Networking options) to see the WiMAX drivers ++# ++# CONFIG_WAN is not set ++# CONFIG_PPP is not set ++# CONFIG_SLIP is not set ++CONFIG_NETCONSOLE=y ++CONFIG_NETCONSOLE_DYNAMIC=y ++CONFIG_NETPOLL=y ++# CONFIG_NETPOLL_TRAP is not set ++CONFIG_NET_POLL_CONTROLLER=y ++# CONFIG_ISDN is not set ++ ++# ++# Input device support ++# ++CONFIG_INPUT=y ++# CONFIG_INPUT_FF_MEMLESS is not set ++# CONFIG_INPUT_POLLDEV is not set ++ ++# ++# Userland interfaces ++# ++CONFIG_INPUT_MOUSEDEV=m ++CONFIG_INPUT_MOUSEDEV_PSAUX=y ++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 ++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 ++# CONFIG_INPUT_JOYDEV is not set ++CONFIG_INPUT_EVDEV=m ++CONFIG_INPUT_EVBUG=m ++# CONFIG_INPUT_APMPOWER is not set ++ ++# ++# Input Device Drivers ++# ++CONFIG_INPUT_KEYBOARD=y ++# CONFIG_KEYBOARD_ATKBD is not set ++# CONFIG_KEYBOARD_SUNKBD is not set ++# CONFIG_KEYBOARD_LKKBD is not set ++# CONFIG_KEYBOARD_XTKBD is not set ++# CONFIG_KEYBOARD_NEWTON is not set ++# CONFIG_KEYBOARD_STOWAWAY is not set ++CONFIG_KEYBOARD_GPIO=m ++CONFIG_INPUT_MOUSE=y ++# CONFIG_MOUSE_PS2 is not set ++# CONFIG_MOUSE_SERIAL is not set ++# CONFIG_MOUSE_VSXXXAA is not set ++# CONFIG_MOUSE_GPIO is not set ++# CONFIG_INPUT_JOYSTICK is not set ++# CONFIG_INPUT_TABLET is not set ++# CONFIG_INPUT_TOUCHSCREEN is not set ++# CONFIG_INPUT_MISC is not set ++ ++# ++# Hardware I/O ports ++# ++# CONFIG_SERIO is not set ++# CONFIG_GAMEPORT is not set ++ ++# ++# Character devices ++# ++CONFIG_VT=y ++CONFIG_CONSOLE_TRANSLATIONS=y ++CONFIG_VT_CONSOLE=y ++CONFIG_HW_CONSOLE=y ++CONFIG_VT_HW_CONSOLE_BINDING=y ++CONFIG_DEVKMEM=y ++# CONFIG_SERIAL_NONSTANDARD is not set ++ ++# ++# Serial drivers ++# ++# CONFIG_SERIAL_8250 is not set ++ ++# ++# Non-8250 serial port support ++# ++CONFIG_SERIAL_IMX=y ++CONFIG_SERIAL_IMX_CONSOLE=y ++CONFIG_SERIAL_CORE=y ++CONFIG_SERIAL_CORE_CONSOLE=y ++CONFIG_UNIX98_PTYS=y ++# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set ++CONFIG_LEGACY_PTYS=y ++CONFIG_LEGACY_PTY_COUNT=16 ++# CONFIG_IPMI_HANDLER is not set ++# CONFIG_HW_RANDOM is not set ++# CONFIG_R3964 is not set ++# CONFIG_RAW_DRIVER is not set ++# CONFIG_TCG_TPM is not set ++# CONFIG_I2C is not set ++# CONFIG_SPI is not set ++CONFIG_ARCH_REQUIRE_GPIOLIB=y ++CONFIG_GPIOLIB=y ++CONFIG_DEBUG_GPIO=y ++CONFIG_GPIO_SYSFS=y ++ ++# ++# Memory mapped GPIO expanders: ++# ++ ++# ++# I2C GPIO expanders: ++# ++ ++# ++# PCI GPIO expanders: ++# ++ ++# ++# SPI GPIO expanders: ++# ++# CONFIG_W1 is not set ++# CONFIG_POWER_SUPPLY is not set ++# CONFIG_HWMON is not set ++# CONFIG_THERMAL is not set ++# CONFIG_THERMAL_HWMON is not set ++# CONFIG_WATCHDOG is not set ++CONFIG_SSB_POSSIBLE=y ++ ++# ++# Sonics Silicon Backplane ++# ++# CONFIG_SSB is not set ++ ++# ++# Multifunction device drivers ++# ++# CONFIG_MFD_CORE is not set ++# CONFIG_MFD_SM501 is not set ++# CONFIG_MFD_ASIC3 is not set ++# CONFIG_HTC_EGPIO is not set ++# CONFIG_HTC_PASIC3 is not set ++# CONFIG_MFD_TMIO is not set ++# CONFIG_MFD_T7L66XB is not set ++# CONFIG_MFD_TC6387XB is not set ++# CONFIG_MFD_TC6393XB is not set ++ ++# ++# Multimedia devices ++# ++ ++# ++# Multimedia core support ++# ++# CONFIG_VIDEO_DEV is not set ++# CONFIG_DVB_CORE is not set ++# CONFIG_VIDEO_MEDIA is not set ++ ++# ++# Multimedia drivers ++# ++# CONFIG_DAB is not set ++ ++# ++# Graphics support ++# ++# CONFIG_VGASTATE is not set ++# CONFIG_VIDEO_OUTPUT_CONTROL is not set ++CONFIG_FB=y ++# CONFIG_FIRMWARE_EDID is not set ++# CONFIG_FB_DDC is not set ++# CONFIG_FB_BOOT_VESA_SUPPORT is not set ++CONFIG_FB_CFB_FILLRECT=y ++CONFIG_FB_CFB_COPYAREA=y ++CONFIG_FB_CFB_IMAGEBLIT=y ++# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set ++# CONFIG_FB_SYS_FILLRECT is not set ++# CONFIG_FB_SYS_COPYAREA is not set ++# CONFIG_FB_SYS_IMAGEBLIT is not set ++# CONFIG_FB_FOREIGN_ENDIAN is not set ++# CONFIG_FB_SYS_FOPS is not set ++# CONFIG_FB_SVGALIB is not set ++# CONFIG_FB_MACMODES is not set ++# CONFIG_FB_BACKLIGHT is not set ++CONFIG_FB_MODE_HELPERS=y ++CONFIG_FB_TILEBLITTING=y ++ ++# ++# Frame buffer hardware drivers ++# ++CONFIG_FB_IMX=y ++# CONFIG_FB_S1D13XXX is not set ++# CONFIG_FB_VIRTUAL is not set ++# CONFIG_FB_METRONOME is not set ++# CONFIG_FB_MB862XX is not set ++# CONFIG_FB_BROADSHEET is not set ++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set ++ ++# ++# Display device support ++# ++# CONFIG_DISPLAY_SUPPORT is not set ++ ++# ++# Console display driver support ++# ++# CONFIG_VGA_CONSOLE is not set ++CONFIG_DUMMY_CONSOLE=y ++CONFIG_FRAMEBUFFER_CONSOLE=y ++CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y ++CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y ++# CONFIG_FONTS is not set ++CONFIG_FONT_8x8=y ++CONFIG_FONT_8x16=y ++CONFIG_LOGO=y ++CONFIG_LOGO_LINUX_MONO=y ++CONFIG_LOGO_LINUX_VGA16=y ++CONFIG_LOGO_LINUX_CLUT224=y ++# CONFIG_SOUND is not set ++# CONFIG_HID_SUPPORT is not set ++# CONFIG_USB_SUPPORT is not set ++# CONFIG_MMC is not set ++# CONFIG_MEMSTICK is not set ++# CONFIG_ACCESSIBILITY is not set ++CONFIG_NEW_LEDS=y ++CONFIG_LEDS_CLASS=y ++ ++# ++# LED drivers ++# ++CONFIG_LEDS_GPIO=y ++CONFIG_LEDS_GPIO_PLATFORM=y ++ ++# ++# LED Triggers ++# ++CONFIG_LEDS_TRIGGERS=y ++# CONFIG_LEDS_TRIGGER_TIMER is not set ++CONFIG_LEDS_TRIGGER_HEARTBEAT=y ++# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set ++# CONFIG_LEDS_TRIGGER_GPIO is not set ++# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set ++ ++# ++# iptables trigger is under Netfilter config (LED target) ++# ++CONFIG_RTC_LIB=y ++# CONFIG_RTC_CLASS is not set ++# CONFIG_DMADEVICES is not set ++# CONFIG_AUXDISPLAY is not set ++# CONFIG_REGULATOR is not set ++# CONFIG_UIO is not set ++# CONFIG_STAGING is not set ++ ++# ++# File systems ++# ++CONFIG_EXT2_FS=y ++# CONFIG_EXT2_FS_XATTR is not set ++# CONFIG_EXT2_FS_XIP is not set ++CONFIG_EXT3_FS=m ++# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set ++CONFIG_EXT3_FS_XATTR=y ++CONFIG_EXT3_FS_POSIX_ACL=y ++# CONFIG_EXT3_FS_SECURITY is not set ++# CONFIG_EXT4_FS is not set ++CONFIG_JBD=m ++CONFIG_FS_MBCACHE=m ++# CONFIG_REISERFS_FS is not set ++# CONFIG_JFS_FS is not set ++CONFIG_FS_POSIX_ACL=y ++CONFIG_FILE_LOCKING=y ++# CONFIG_XFS_FS is not set ++# CONFIG_GFS2_FS is not set ++# CONFIG_OCFS2_FS is not set ++# CONFIG_BTRFS_FS is not set ++CONFIG_DNOTIFY=y ++CONFIG_INOTIFY=y ++CONFIG_INOTIFY_USER=y ++# CONFIG_QUOTA is not set ++# CONFIG_AUTOFS_FS is not set ++# CONFIG_AUTOFS4_FS is not set ++# CONFIG_FUSE_FS is not set ++ ++# ++# Caches ++# ++# CONFIG_FSCACHE is not set ++ ++# ++# CD-ROM/DVD Filesystems ++# ++CONFIG_ISO9660_FS=y ++CONFIG_JOLIET=y ++CONFIG_ZISOFS=y ++# CONFIG_UDF_FS is not set ++ ++# ++# DOS/FAT/NT Filesystems ++# ++CONFIG_FAT_FS=m ++CONFIG_MSDOS_FS=m ++CONFIG_VFAT_FS=m ++CONFIG_FAT_DEFAULT_CODEPAGE=437 ++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" ++CONFIG_NTFS_FS=m ++# CONFIG_NTFS_DEBUG is not set ++CONFIG_NTFS_RW=y ++ ++# ++# Pseudo filesystems ++# ++CONFIG_PROC_FS=y ++CONFIG_PROC_SYSCTL=y ++CONFIG_PROC_PAGE_MONITOR=y ++CONFIG_SYSFS=y ++CONFIG_TMPFS=y ++# CONFIG_TMPFS_POSIX_ACL is not set ++# CONFIG_HUGETLB_PAGE is not set ++CONFIG_CONFIGFS_FS=y ++CONFIG_MISC_FILESYSTEMS=y ++# CONFIG_ADFS_FS is not set ++# CONFIG_AFFS_FS is not set ++# CONFIG_HFS_FS is not set ++# CONFIG_HFSPLUS_FS is not set ++# CONFIG_BEFS_FS is not set ++# CONFIG_BFS_FS is not set ++# CONFIG_EFS_FS is not set ++CONFIG_JFFS2_FS=y ++CONFIG_JFFS2_FS_DEBUG=0 ++CONFIG_JFFS2_FS_WRITEBUFFER=y ++# CONFIG_JFFS2_FS_WBUF_VERIFY is not set ++CONFIG_JFFS2_SUMMARY=y ++# CONFIG_JFFS2_FS_XATTR is not set ++# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set ++CONFIG_JFFS2_ZLIB=y ++# CONFIG_JFFS2_LZO is not set ++CONFIG_JFFS2_RTIME=y ++# CONFIG_JFFS2_RUBIN is not set ++CONFIG_CRAMFS=y ++# CONFIG_SQUASHFS is not set ++# CONFIG_VXFS_FS is not set ++# CONFIG_MINIX_FS is not set ++# CONFIG_OMFS_FS is not set ++# CONFIG_HPFS_FS is not set ++# CONFIG_QNX4FS_FS is not set ++# CONFIG_ROMFS_FS is not set ++# CONFIG_SYSV_FS is not set ++# CONFIG_UFS_FS is not set ++# CONFIG_NILFS2_FS is not set ++CONFIG_NETWORK_FILESYSTEMS=y ++CONFIG_NFS_FS=y ++CONFIG_NFS_V3=y ++# CONFIG_NFS_V3_ACL is not set ++CONFIG_NFS_V4=y ++CONFIG_ROOT_NFS=y ++# CONFIG_NFSD is not set ++CONFIG_LOCKD=y ++CONFIG_LOCKD_V4=y ++CONFIG_NFS_COMMON=y ++CONFIG_SUNRPC=y ++CONFIG_SUNRPC_GSS=y ++CONFIG_RPCSEC_GSS_KRB5=y ++# CONFIG_RPCSEC_GSS_SPKM3 is not set ++# CONFIG_SMB_FS is not set ++# CONFIG_CIFS is not set ++# CONFIG_NCP_FS is not set ++# CONFIG_CODA_FS is not set ++# CONFIG_AFS_FS is not set ++ ++# ++# Partition Types ++# ++CONFIG_PARTITION_ADVANCED=y ++# CONFIG_ACORN_PARTITION is not set ++# CONFIG_OSF_PARTITION is not set ++# CONFIG_AMIGA_PARTITION is not set ++# CONFIG_ATARI_PARTITION is not set ++# CONFIG_MAC_PARTITION is not set ++CONFIG_MSDOS_PARTITION=y ++# CONFIG_BSD_DISKLABEL is not set ++# CONFIG_MINIX_SUBPARTITION is not set ++# CONFIG_SOLARIS_X86_PARTITION is not set ++# CONFIG_UNIXWARE_DISKLABEL is not set ++# CONFIG_LDM_PARTITION is not set ++# CONFIG_SGI_PARTITION is not set ++# CONFIG_ULTRIX_PARTITION is not set ++# CONFIG_SUN_PARTITION is not set ++# CONFIG_KARMA_PARTITION is not set ++# CONFIG_EFI_PARTITION is not set ++# CONFIG_SYSV68_PARTITION is not set ++CONFIG_NLS=y ++CONFIG_NLS_DEFAULT="cp437" ++CONFIG_NLS_CODEPAGE_437=y ++# CONFIG_NLS_CODEPAGE_737 is not set ++# CONFIG_NLS_CODEPAGE_775 is not set ++CONFIG_NLS_CODEPAGE_850=y ++# CONFIG_NLS_CODEPAGE_852 is not set ++# CONFIG_NLS_CODEPAGE_855 is not set ++# CONFIG_NLS_CODEPAGE_857 is not set ++# CONFIG_NLS_CODEPAGE_860 is not set ++# CONFIG_NLS_CODEPAGE_861 is not set ++# CONFIG_NLS_CODEPAGE_862 is not set ++# CONFIG_NLS_CODEPAGE_863 is not set ++# CONFIG_NLS_CODEPAGE_864 is not set ++# CONFIG_NLS_CODEPAGE_865 is not set ++# CONFIG_NLS_CODEPAGE_866 is not set ++# CONFIG_NLS_CODEPAGE_869 is not set ++# CONFIG_NLS_CODEPAGE_936 is not set ++# CONFIG_NLS_CODEPAGE_950 is not set ++# CONFIG_NLS_CODEPAGE_932 is not set ++# CONFIG_NLS_CODEPAGE_949 is not set ++# CONFIG_NLS_CODEPAGE_874 is not set ++# CONFIG_NLS_ISO8859_8 is not set ++CONFIG_NLS_CODEPAGE_1250=m ++# CONFIG_NLS_CODEPAGE_1251 is not set ++CONFIG_NLS_ASCII=m ++CONFIG_NLS_ISO8859_1=m ++# CONFIG_NLS_ISO8859_2 is not set ++# CONFIG_NLS_ISO8859_3 is not set ++# CONFIG_NLS_ISO8859_4 is not set ++# CONFIG_NLS_ISO8859_5 is not set ++# CONFIG_NLS_ISO8859_6 is not set ++# CONFIG_NLS_ISO8859_7 is not set ++# CONFIG_NLS_ISO8859_9 is not set ++# CONFIG_NLS_ISO8859_13 is not set ++# CONFIG_NLS_ISO8859_14 is not set ++CONFIG_NLS_ISO8859_15=y ++# CONFIG_NLS_KOI8_R is not set ++# CONFIG_NLS_KOI8_U is not set ++CONFIG_NLS_UTF8=y ++# CONFIG_DLM is not set ++ ++# ++# Kernel hacking ++# ++# CONFIG_PRINTK_TIME is not set ++CONFIG_ENABLE_WARN_DEPRECATED=y ++CONFIG_ENABLE_MUST_CHECK=y ++CONFIG_FRAME_WARN=1024 ++CONFIG_MAGIC_SYSRQ=y ++# CONFIG_UNUSED_SYMBOLS is not set ++# CONFIG_DEBUG_FS is not set ++# CONFIG_HEADERS_CHECK is not set ++CONFIG_DEBUG_KERNEL=y ++# CONFIG_DEBUG_SHIRQ is not set ++CONFIG_DETECT_SOFTLOCKUP=y ++CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y ++CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=1 ++CONFIG_DETECT_HUNG_TASK=y ++CONFIG_BOOTPARAM_HUNG_TASK_PANIC=y ++CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=1 ++# CONFIG_SCHED_DEBUG is not set ++# CONFIG_SCHEDSTATS is not set ++# CONFIG_TIMER_STATS is not set ++# CONFIG_DEBUG_OBJECTS is not set ++CONFIG_DEBUG_SLAB=y ++CONFIG_DEBUG_SLAB_LEAK=y ++# CONFIG_DEBUG_PREEMPT is not set ++# CONFIG_DEBUG_RT_MUTEXES is not set ++# CONFIG_RT_MUTEX_TESTER is not set ++# CONFIG_DEBUG_SPINLOCK is not set ++# CONFIG_DEBUG_MUTEXES is not set ++# CONFIG_DEBUG_LOCK_ALLOC is not set ++# CONFIG_PROVE_LOCKING is not set ++# CONFIG_LOCK_STAT is not set ++# CONFIG_DEBUG_SPINLOCK_SLEEP is not set ++# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set ++# CONFIG_DEBUG_KOBJECT is not set ++CONFIG_DEBUG_BUGVERBOSE=y ++# CONFIG_DEBUG_INFO is not set ++# CONFIG_DEBUG_VM is not set ++# CONFIG_DEBUG_WRITECOUNT is not set ++# CONFIG_DEBUG_MEMORY_INIT is not set ++# CONFIG_DEBUG_LIST is not set ++# CONFIG_DEBUG_SG is not set ++# CONFIG_DEBUG_NOTIFIERS is not set ++# CONFIG_BOOT_PRINTK_DELAY is not set ++# CONFIG_RCU_TORTURE_TEST is not set ++# CONFIG_RCU_CPU_STALL_DETECTOR is not set ++# CONFIG_BACKTRACE_SELF_TEST is not set ++# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set ++# CONFIG_FAULT_INJECTION is not set ++# CONFIG_LATENCYTOP is not set ++# CONFIG_SYSCTL_SYSCALL_CHECK is not set ++# CONFIG_PAGE_POISONING is not set ++CONFIG_HAVE_FUNCTION_TRACER=y ++CONFIG_TRACING_SUPPORT=y ++ ++# ++# Tracers ++# ++# CONFIG_FUNCTION_TRACER is not set ++# CONFIG_IRQSOFF_TRACER is not set ++# CONFIG_PREEMPT_TRACER is not set ++# CONFIG_SCHED_TRACER is not set ++# CONFIG_CONTEXT_SWITCH_TRACER is not set ++# CONFIG_EVENT_TRACER is not set ++# CONFIG_BOOT_TRACER is not set ++# CONFIG_TRACE_BRANCH_PROFILING is not set ++# CONFIG_STACK_TRACER is not set ++# CONFIG_KMEMTRACE is not set ++# CONFIG_WORKQUEUE_TRACER is not set ++# CONFIG_BLK_DEV_IO_TRACE is not set ++# CONFIG_SAMPLES is not set ++CONFIG_HAVE_ARCH_KGDB=y ++# CONFIG_KGDB is not set ++CONFIG_ARM_UNWIND=y ++CONFIG_DEBUG_USER=y ++CONFIG_DEBUG_ERRORS=y ++# CONFIG_DEBUG_STACK_USAGE is not set ++# CONFIG_DEBUG_LL is not set ++ ++# ++# Security options ++# ++# CONFIG_KEYS is not set ++# CONFIG_SECURITY is not set ++# CONFIG_SECURITYFS is not set ++# CONFIG_SECURITY_FILE_CAPABILITIES is not set ++CONFIG_CRYPTO=y ++ ++# ++# Crypto core or helper ++# ++# CONFIG_CRYPTO_FIPS is not set ++CONFIG_CRYPTO_ALGAPI=y ++CONFIG_CRYPTO_ALGAPI2=y ++CONFIG_CRYPTO_AEAD2=y ++CONFIG_CRYPTO_BLKCIPHER=y ++CONFIG_CRYPTO_BLKCIPHER2=y ++CONFIG_CRYPTO_HASH=y ++CONFIG_CRYPTO_HASH2=y ++CONFIG_CRYPTO_RNG2=y ++CONFIG_CRYPTO_PCOMP=y ++CONFIG_CRYPTO_MANAGER=y ++CONFIG_CRYPTO_MANAGER2=y ++# CONFIG_CRYPTO_GF128MUL is not set ++# CONFIG_CRYPTO_NULL is not set ++CONFIG_CRYPTO_WORKQUEUE=y ++# CONFIG_CRYPTO_CRYPTD is not set ++# CONFIG_CRYPTO_AUTHENC is not set ++# CONFIG_CRYPTO_TEST is not set ++ ++# ++# Authenticated Encryption with Associated Data ++# ++# CONFIG_CRYPTO_CCM is not set ++# CONFIG_CRYPTO_GCM is not set ++# CONFIG_CRYPTO_SEQIV is not set ++ ++# ++# Block modes ++# ++CONFIG_CRYPTO_CBC=y ++# CONFIG_CRYPTO_CTR is not set ++# CONFIG_CRYPTO_CTS is not set ++CONFIG_CRYPTO_ECB=y ++# CONFIG_CRYPTO_LRW is not set ++# CONFIG_CRYPTO_PCBC is not set ++# CONFIG_CRYPTO_XTS is not set ++ ++# ++# Hash modes ++# ++CONFIG_CRYPTO_HMAC=y ++# CONFIG_CRYPTO_XCBC is not set ++ ++# ++# Digest ++# ++# CONFIG_CRYPTO_CRC32C is not set ++# CONFIG_CRYPTO_MD4 is not set ++CONFIG_CRYPTO_MD5=y ++# CONFIG_CRYPTO_MICHAEL_MIC is not set ++# CONFIG_CRYPTO_RMD128 is not set ++# CONFIG_CRYPTO_RMD160 is not set ++# CONFIG_CRYPTO_RMD256 is not set ++# CONFIG_CRYPTO_RMD320 is not set ++# CONFIG_CRYPTO_SHA1 is not set ++# CONFIG_CRYPTO_SHA256 is not set ++# CONFIG_CRYPTO_SHA512 is not set ++# CONFIG_CRYPTO_TGR192 is not set ++# CONFIG_CRYPTO_WP512 is not set ++ ++# ++# Ciphers ++# ++CONFIG_CRYPTO_AES=y ++# CONFIG_CRYPTO_ANUBIS is not set ++CONFIG_CRYPTO_ARC4=y ++# CONFIG_CRYPTO_BLOWFISH is not set ++# CONFIG_CRYPTO_CAMELLIA is not set ++# CONFIG_CRYPTO_CAST5 is not set ++# CONFIG_CRYPTO_CAST6 is not set ++CONFIG_CRYPTO_DES=y ++# CONFIG_CRYPTO_FCRYPT is not set ++# CONFIG_CRYPTO_KHAZAD is not set ++# CONFIG_CRYPTO_SALSA20 is not set ++# CONFIG_CRYPTO_SEED is not set ++# CONFIG_CRYPTO_SERPENT is not set ++# CONFIG_CRYPTO_TEA is not set ++# CONFIG_CRYPTO_TWOFISH is not set ++ ++# ++# Compression ++# ++# CONFIG_CRYPTO_DEFLATE is not set ++# CONFIG_CRYPTO_ZLIB is not set ++# CONFIG_CRYPTO_LZO is not set ++ ++# ++# Random Number Generation ++# ++# CONFIG_CRYPTO_ANSI_CPRNG is not set ++CONFIG_CRYPTO_HW=y ++# CONFIG_BINARY_PRINTF is not set ++ ++# ++# Library routines ++# ++CONFIG_BITREVERSE=y ++CONFIG_GENERIC_FIND_LAST_BIT=y ++# CONFIG_CRC_CCITT is not set ++# CONFIG_CRC16 is not set ++# CONFIG_CRC_T10DIF is not set ++# CONFIG_CRC_ITU_T is not set ++CONFIG_CRC32=y ++# CONFIG_CRC7 is not set ++# CONFIG_LIBCRC32C is not set ++CONFIG_ZLIB_INFLATE=y ++CONFIG_ZLIB_DEFLATE=y ++CONFIG_DECOMPRESS_GZIP=y ++CONFIG_HAS_IOMEM=y ++CONFIG_HAS_IOPORT=y ++CONFIG_HAS_DMA=y ++CONFIG_NLATTR=y +diff -urNp linux-2.6.30-rc4/arch/arm/configs/karo_tx25_defconfig linux-2.6.30-rc4-karo/arch/arm/configs/karo_tx25_defconfig +--- linux-2.6.30-rc4/arch/arm/configs/karo_tx25_defconfig 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30-rc4-karo/arch/arm/configs/karo_tx25_defconfig 2009-06-02 17:05:27.000000000 +0200 +@@ -0,0 +1,1203 @@ ++# ++# Automatically generated make config: don't edit ++# Linux kernel version: 2.6.30-rc4 ++# Tue Jun 2 15:46:43 2009 ++# ++CONFIG_ARM=y ++CONFIG_SYS_SUPPORTS_APM_EMULATION=y ++CONFIG_GENERIC_GPIO=y ++CONFIG_GENERIC_TIME=y ++CONFIG_GENERIC_CLOCKEVENTS=y ++CONFIG_MMU=y ++# CONFIG_NO_IOPORT is not set ++CONFIG_GENERIC_HARDIRQS=y ++CONFIG_STACKTRACE_SUPPORT=y ++CONFIG_HAVE_LATENCYTOP_SUPPORT=y ++CONFIG_LOCKDEP_SUPPORT=y ++CONFIG_TRACE_IRQFLAGS_SUPPORT=y ++CONFIG_HARDIRQS_SW_RESEND=y ++CONFIG_GENERIC_IRQ_PROBE=y ++CONFIG_RWSEM_GENERIC_SPINLOCK=y ++# CONFIG_ARCH_HAS_ILOG2_U32 is not set ++# CONFIG_ARCH_HAS_ILOG2_U64 is not set ++CONFIG_GENERIC_HWEIGHT=y ++CONFIG_GENERIC_CALIBRATE_DELAY=y ++CONFIG_ARCH_MTD_XIP=y ++CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y ++CONFIG_VECTORS_BASE=0xffff0000 ++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" ++ ++# ++# General setup ++# ++CONFIG_EXPERIMENTAL=y ++CONFIG_BROKEN_ON_SMP=y ++CONFIG_LOCK_KERNEL=y ++CONFIG_INIT_ENV_ARG_LIMIT=32 ++CONFIG_LOCALVERSION="" ++CONFIG_LOCALVERSION_AUTO=y ++# CONFIG_SWAP is not set ++CONFIG_SYSVIPC=y ++CONFIG_SYSVIPC_SYSCTL=y ++CONFIG_POSIX_MQUEUE=y ++CONFIG_POSIX_MQUEUE_SYSCTL=y ++# CONFIG_BSD_PROCESS_ACCT is not set ++# CONFIG_TASKSTATS is not set ++# CONFIG_AUDIT is not set ++ ++# ++# RCU Subsystem ++# ++CONFIG_CLASSIC_RCU=y ++# CONFIG_TREE_RCU is not set ++# CONFIG_PREEMPT_RCU is not set ++# CONFIG_TREE_RCU_TRACE is not set ++# CONFIG_PREEMPT_RCU_TRACE is not set ++# CONFIG_IKCONFIG is not set ++CONFIG_LOG_BUF_SHIFT=17 ++# CONFIG_GROUP_SCHED is not set ++# CONFIG_CGROUPS is not set ++# CONFIG_SYSFS_DEPRECATED_V2 is not set ++# CONFIG_RELAY is not set ++# CONFIG_NAMESPACES is not set ++CONFIG_BLK_DEV_INITRD=y ++CONFIG_INITRAMFS_SOURCE="" ++CONFIG_RD_GZIP=y ++# CONFIG_RD_BZIP2 is not set ++# CONFIG_RD_LZMA is not set ++# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set ++CONFIG_SYSCTL=y ++CONFIG_ANON_INODES=y ++CONFIG_EMBEDDED=y ++CONFIG_UID16=y ++CONFIG_SYSCTL_SYSCALL=y ++CONFIG_KALLSYMS=y ++# CONFIG_KALLSYMS_ALL is not set ++# CONFIG_KALLSYMS_EXTRA_PASS is not set ++# CONFIG_STRIP_ASM_SYMS is not set ++CONFIG_HOTPLUG=y ++CONFIG_PRINTK=y ++CONFIG_BUG=y ++# CONFIG_ELF_CORE is not set ++CONFIG_BASE_FULL=y ++CONFIG_FUTEX=y ++CONFIG_EPOLL=y ++CONFIG_SIGNALFD=y ++CONFIG_TIMERFD=y ++CONFIG_EVENTFD=y ++CONFIG_SHMEM=y ++# CONFIG_AIO is not set ++# CONFIG_VM_EVENT_COUNTERS is not set ++# CONFIG_COMPAT_BRK is not set ++CONFIG_SLAB=y ++# CONFIG_SLUB is not set ++# CONFIG_SLOB is not set ++# CONFIG_PROFILING is not set ++# CONFIG_MARKERS is not set ++CONFIG_HAVE_OPROFILE=y ++# CONFIG_KPROBES is not set ++CONFIG_HAVE_KPROBES=y ++CONFIG_HAVE_KRETPROBES=y ++CONFIG_HAVE_CLK=y ++# CONFIG_SLOW_WORK is not set ++CONFIG_HAVE_GENERIC_DMA_COHERENT=y ++CONFIG_SLABINFO=y ++CONFIG_RT_MUTEXES=y ++CONFIG_BASE_SMALL=0 ++CONFIG_MODULES=y ++# CONFIG_MODULE_FORCE_LOAD is not set ++CONFIG_MODULE_UNLOAD=y ++CONFIG_MODULE_FORCE_UNLOAD=y ++CONFIG_MODVERSIONS=y ++# CONFIG_MODULE_SRCVERSION_ALL is not set ++CONFIG_BLOCK=y ++CONFIG_LBD=y ++# CONFIG_BLK_DEV_BSG is not set ++# CONFIG_BLK_DEV_INTEGRITY is not set ++ ++# ++# IO Schedulers ++# ++CONFIG_IOSCHED_NOOP=y ++CONFIG_IOSCHED_AS=y ++CONFIG_IOSCHED_DEADLINE=y ++CONFIG_IOSCHED_CFQ=y ++CONFIG_DEFAULT_AS=y ++# CONFIG_DEFAULT_DEADLINE is not set ++# CONFIG_DEFAULT_CFQ is not set ++# CONFIG_DEFAULT_NOOP is not set ++CONFIG_DEFAULT_IOSCHED="anticipatory" ++CONFIG_FREEZER=y ++ ++# ++# System Type ++# ++# CONFIG_ARCH_AAEC2000 is not set ++# CONFIG_ARCH_INTEGRATOR is not set ++# CONFIG_ARCH_REALVIEW is not set ++# CONFIG_ARCH_VERSATILE is not set ++# CONFIG_ARCH_AT91 is not set ++# CONFIG_ARCH_CLPS711X is not set ++# CONFIG_ARCH_EBSA110 is not set ++# CONFIG_ARCH_EP93XX is not set ++# CONFIG_ARCH_GEMINI is not set ++# CONFIG_ARCH_FOOTBRIDGE is not set ++# CONFIG_ARCH_NETX is not set ++# CONFIG_ARCH_H720X is not set ++# CONFIG_ARCH_IOP13XX is not set ++# CONFIG_ARCH_IOP32X is not set ++# CONFIG_ARCH_IOP33X is not set ++# CONFIG_ARCH_IXP23XX is not set ++# CONFIG_ARCH_IXP2000 is not set ++# CONFIG_ARCH_IXP4XX is not set ++# CONFIG_ARCH_L7200 is not set ++# CONFIG_ARCH_KIRKWOOD is not set ++# CONFIG_ARCH_KS8695 is not set ++# CONFIG_ARCH_NS9XXX is not set ++# CONFIG_ARCH_LOKI is not set ++# CONFIG_ARCH_MV78XX0 is not set ++CONFIG_ARCH_MXC=y ++# CONFIG_ARCH_ORION5X is not set ++# CONFIG_ARCH_PNX4008 is not set ++# CONFIG_ARCH_PXA is not set ++# CONFIG_ARCH_MMP is not set ++# CONFIG_ARCH_RPC is not set ++# CONFIG_ARCH_SA1100 is not set ++# CONFIG_ARCH_S3C2410 is not set ++# CONFIG_ARCH_S3C64XX is not set ++# CONFIG_ARCH_SHARK is not set ++# CONFIG_ARCH_LH7A40X is not set ++# CONFIG_ARCH_DAVINCI is not set ++# CONFIG_ARCH_OMAP is not set ++# CONFIG_ARCH_MSM is not set ++# CONFIG_ARCH_W90X900 is not set ++ ++# ++# Freescale MXC Implementations ++# ++# CONFIG_ARCH_MX1 is not set ++CONFIG_ARCH_MX2=y ++# CONFIG_ARCH_MX3 is not set ++# CONFIG_MACH_MX21 is not set ++# CONFIG_MACH_MX27 is not set ++CONFIG_MACH_MX25=y ++ ++# ++# MX2 platforms: ++# ++CONFIG_MACH_TX25=y ++# CONFIG_KARO_DEBUG is not set ++CONFIG_MACH_STK5_BASEBOARD=y ++# CONFIG_MXC_IRQ_PRIOR is not set ++# CONFIG_MXC_PWM is not set ++CONFIG_ARCH_MXC_IOMUX_V3=y ++ ++# ++# Processor Type ++# ++CONFIG_CPU_32=y ++CONFIG_CPU_ARM926T=y ++CONFIG_CPU_32v5=y ++CONFIG_CPU_ABRT_EV5TJ=y ++CONFIG_CPU_PABRT_NOIFAR=y ++CONFIG_CPU_CACHE_VIVT=y ++CONFIG_CPU_COPY_V4WB=y ++CONFIG_CPU_TLB_V4WBI=y ++CONFIG_CPU_CP15=y ++CONFIG_CPU_CP15_MMU=y ++ ++# ++# Processor Features ++# ++CONFIG_ARM_THUMB=y ++# CONFIG_CPU_ICACHE_DISABLE is not set ++# CONFIG_CPU_DCACHE_DISABLE is not set ++# CONFIG_CPU_DCACHE_WRITETHROUGH is not set ++# CONFIG_CPU_CACHE_ROUND_ROBIN is not set ++# CONFIG_OUTER_CACHE is not set ++CONFIG_COMMON_CLKDEV=y ++ ++# ++# Bus support ++# ++# CONFIG_PCI_SYSCALL is not set ++# CONFIG_ARCH_SUPPORTS_MSI is not set ++# CONFIG_PCCARD is not set ++ ++# ++# Kernel Features ++# ++CONFIG_TICK_ONESHOT=y ++CONFIG_NO_HZ=y ++# CONFIG_HIGH_RES_TIMERS is not set ++CONFIG_GENERIC_CLOCKEVENTS_BUILD=y ++CONFIG_VMSPLIT_3G=y ++# CONFIG_VMSPLIT_2G is not set ++# CONFIG_VMSPLIT_1G is not set ++CONFIG_PAGE_OFFSET=0xC0000000 ++CONFIG_PREEMPT=y ++CONFIG_HZ=100 ++CONFIG_AEABI=y ++CONFIG_OABI_COMPAT=y ++CONFIG_ARCH_FLATMEM_HAS_HOLES=y ++# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set ++# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set ++# CONFIG_HIGHMEM is not set ++CONFIG_SELECT_MEMORY_MODEL=y ++CONFIG_FLATMEM_MANUAL=y ++# CONFIG_DISCONTIGMEM_MANUAL is not set ++# CONFIG_SPARSEMEM_MANUAL is not set ++CONFIG_FLATMEM=y ++CONFIG_FLAT_NODE_MEM_MAP=y ++CONFIG_PAGEFLAGS_EXTENDED=y ++CONFIG_SPLIT_PTLOCK_CPUS=4096 ++# CONFIG_PHYS_ADDR_T_64BIT is not set ++CONFIG_ZONE_DMA_FLAG=0 ++CONFIG_VIRT_TO_BUS=y ++CONFIG_UNEVICTABLE_LRU=y ++CONFIG_HAVE_MLOCK=y ++CONFIG_HAVE_MLOCKED_PAGE_BIT=y ++CONFIG_ALIGNMENT_TRAP=y ++ ++# ++# Boot options ++# ++CONFIG_ZBOOT_ROM_TEXT=0 ++CONFIG_ZBOOT_ROM_BSS=0 ++CONFIG_CMDLINE="init=/linuxrc root=1f01 rootfstype=jffs2 ro console=ttymxc0,115200 panic=1" ++# CONFIG_XIP_KERNEL is not set ++# CONFIG_KEXEC is not set ++ ++# ++# CPU Power Management ++# ++CONFIG_CPU_IDLE=y ++CONFIG_CPU_IDLE_GOV_LADDER=y ++CONFIG_CPU_IDLE_GOV_MENU=y ++ ++# ++# Floating point emulation ++# ++ ++# ++# At least one emulation must be selected ++# ++CONFIG_FPE_NWFPE=y ++# CONFIG_FPE_NWFPE_XP is not set ++# CONFIG_FPE_FASTFPE is not set ++CONFIG_VFP=y ++ ++# ++# Userspace binary formats ++# ++CONFIG_BINFMT_ELF=y ++CONFIG_HAVE_AOUT=y ++# CONFIG_BINFMT_AOUT is not set ++# CONFIG_BINFMT_MISC is not set ++ ++# ++# Power management options ++# ++CONFIG_PM=y ++CONFIG_PM_DEBUG=y ++CONFIG_PM_VERBOSE=y ++CONFIG_CAN_PM_TRACE=y ++CONFIG_PM_SLEEP=y ++CONFIG_SUSPEND=y ++CONFIG_SUSPEND_FREEZER=y ++CONFIG_APM_EMULATION=y ++CONFIG_ARCH_SUSPEND_POSSIBLE=y ++CONFIG_NET=y ++ ++# ++# Networking options ++# ++CONFIG_PACKET=y ++CONFIG_PACKET_MMAP=y ++CONFIG_UNIX=y ++# CONFIG_NET_KEY is not set ++CONFIG_INET=y ++# CONFIG_IP_MULTICAST is not set ++# CONFIG_IP_ADVANCED_ROUTER is not set ++CONFIG_IP_FIB_HASH=y ++CONFIG_IP_PNP=y ++CONFIG_IP_PNP_DHCP=y ++CONFIG_IP_PNP_BOOTP=y ++# CONFIG_IP_PNP_RARP is not set ++# CONFIG_NET_IPIP is not set ++# CONFIG_NET_IPGRE is not set ++# CONFIG_ARPD is not set ++CONFIG_SYN_COOKIES=y ++# CONFIG_INET_AH is not set ++# CONFIG_INET_ESP is not set ++# CONFIG_INET_IPCOMP is not set ++# CONFIG_INET_XFRM_TUNNEL is not set ++# CONFIG_INET_TUNNEL is not set ++# CONFIG_INET_XFRM_MODE_TRANSPORT is not set ++# CONFIG_INET_XFRM_MODE_TUNNEL is not set ++# CONFIG_INET_XFRM_MODE_BEET is not set ++# CONFIG_INET_LRO is not set ++# CONFIG_INET_DIAG is not set ++# CONFIG_TCP_CONG_ADVANCED is not set ++CONFIG_TCP_CONG_CUBIC=y ++CONFIG_DEFAULT_TCP_CONG="cubic" ++# CONFIG_TCP_MD5SIG is not set ++# CONFIG_IPV6 is not set ++# CONFIG_NETWORK_SECMARK is not set ++# CONFIG_NETFILTER is not set ++# CONFIG_IP_DCCP is not set ++# CONFIG_IP_SCTP is not set ++# CONFIG_TIPC is not set ++# CONFIG_ATM is not set ++# CONFIG_BRIDGE is not set ++# CONFIG_NET_DSA is not set ++# CONFIG_VLAN_8021Q is not set ++# CONFIG_DECNET is not set ++# CONFIG_LLC2 is not set ++# CONFIG_IPX is not set ++# CONFIG_ATALK is not set ++# CONFIG_X25 is not set ++# CONFIG_LAPB is not set ++# CONFIG_ECONET is not set ++# CONFIG_WAN_ROUTER is not set ++# CONFIG_PHONET is not set ++# CONFIG_NET_SCHED is not set ++# CONFIG_DCB is not set ++ ++# ++# Network testing ++# ++# CONFIG_NET_PKTGEN is not set ++# CONFIG_HAMRADIO is not set ++# CONFIG_CAN is not set ++# CONFIG_IRDA is not set ++# CONFIG_BT is not set ++# CONFIG_AF_RXRPC is not set ++# CONFIG_WIRELESS is not set ++# CONFIG_WIMAX is not set ++# CONFIG_RFKILL is not set ++# CONFIG_NET_9P is not set ++ ++# ++# Device Drivers ++# ++ ++# ++# Generic Driver Options ++# ++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" ++CONFIG_STANDALONE=y ++CONFIG_PREVENT_FIRMWARE_BUILD=y ++CONFIG_FW_LOADER=y ++CONFIG_FIRMWARE_IN_KERNEL=y ++CONFIG_EXTRA_FIRMWARE="" ++# CONFIG_DEBUG_DRIVER is not set ++# CONFIG_DEBUG_DEVRES is not set ++# CONFIG_SYS_HYPERVISOR is not set ++# CONFIG_CONNECTOR is not set ++CONFIG_MTD=y ++CONFIG_MTD_DEBUG=y ++CONFIG_MTD_DEBUG_VERBOSE=0 ++CONFIG_MTD_CONCAT=y ++CONFIG_MTD_PARTITIONS=y ++CONFIG_MTD_TESTS=m ++CONFIG_MTD_REDBOOT_PARTS=y ++CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-5 ++# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set ++CONFIG_MTD_REDBOOT_PARTS_READONLY=y ++CONFIG_MTD_CMDLINE_PARTS=y ++# CONFIG_MTD_AFS_PARTS is not set ++# CONFIG_MTD_AR7_PARTS is not set ++ ++# ++# User Modules And Translation Layers ++# ++CONFIG_MTD_CHAR=y ++CONFIG_MTD_BLKDEVS=y ++CONFIG_MTD_BLOCK=y ++# CONFIG_FTL is not set ++# CONFIG_NFTL is not set ++# CONFIG_INFTL is not set ++# CONFIG_RFD_FTL is not set ++# CONFIG_SSFDC is not set ++# CONFIG_MTD_OOPS is not set ++ ++# ++# RAM/ROM/Flash chip drivers ++# ++# CONFIG_MTD_CFI is not set ++# CONFIG_MTD_JEDECPROBE is not set ++CONFIG_MTD_MAP_BANK_WIDTH_1=y ++CONFIG_MTD_MAP_BANK_WIDTH_2=y ++CONFIG_MTD_MAP_BANK_WIDTH_4=y ++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set ++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set ++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set ++CONFIG_MTD_CFI_I1=y ++CONFIG_MTD_CFI_I2=y ++# CONFIG_MTD_CFI_I4 is not set ++# CONFIG_MTD_CFI_I8 is not set ++# CONFIG_MTD_RAM is not set ++# CONFIG_MTD_ROM is not set ++# CONFIG_MTD_ABSENT is not set ++ ++# ++# Mapping drivers for chip access ++# ++# CONFIG_MTD_COMPLEX_MAPPINGS is not set ++# CONFIG_MTD_PLATRAM is not set ++ ++# ++# Self-contained MTD device drivers ++# ++# CONFIG_MTD_SLRAM is not set ++# CONFIG_MTD_PHRAM is not set ++# CONFIG_MTD_MTDRAM is not set ++# CONFIG_MTD_BLOCK2MTD is not set ++ ++# ++# Disk-On-Chip Device Drivers ++# ++# CONFIG_MTD_DOC2000 is not set ++# CONFIG_MTD_DOC2001 is not set ++# CONFIG_MTD_DOC2001PLUS is not set ++CONFIG_MTD_NAND=y ++CONFIG_MTD_NAND_VERIFY_WRITE=y ++# CONFIG_MTD_NAND_ECC_SMC is not set ++# CONFIG_MTD_NAND_MUSEUM_IDS is not set ++# CONFIG_MTD_NAND_GPIO is not set ++CONFIG_MTD_NAND_IDS=y ++# CONFIG_MTD_NAND_DISKONCHIP is not set ++# CONFIG_MTD_NAND_NANDSIM is not set ++# CONFIG_MTD_NAND_PLATFORM is not set ++# CONFIG_MTD_NAND_MXC is not set ++CONFIG_ARCH_MXC_HAS_NFC_V2=y ++CONFIG_ARCH_MXC_HAS_NFC_V2_1=y ++# CONFIG_MTD_ONENAND is not set ++ ++# ++# LPDDR flash memory drivers ++# ++# CONFIG_MTD_LPDDR is not set ++ ++# ++# UBI - Unsorted block images ++# ++# CONFIG_MTD_UBI is not set ++# CONFIG_PARPORT is not set ++CONFIG_BLK_DEV=y ++# CONFIG_BLK_DEV_COW_COMMON is not set ++CONFIG_BLK_DEV_LOOP=m ++# CONFIG_BLK_DEV_CRYPTOLOOP is not set ++# CONFIG_BLK_DEV_NBD is not set ++CONFIG_BLK_DEV_RAM=y ++CONFIG_BLK_DEV_RAM_COUNT=16 ++CONFIG_BLK_DEV_RAM_SIZE=8192 ++# CONFIG_BLK_DEV_XIP is not set ++# CONFIG_CDROM_PKTCDVD is not set ++# CONFIG_ATA_OVER_ETH is not set ++CONFIG_MISC_DEVICES=y ++# CONFIG_ENCLOSURE_SERVICES is not set ++# CONFIG_C2PORT is not set ++ ++# ++# EEPROM support ++# ++# CONFIG_EEPROM_93CX6 is not set ++CONFIG_HAVE_IDE=y ++# CONFIG_IDE is not set ++ ++# ++# SCSI device support ++# ++# CONFIG_RAID_ATTRS is not set ++# CONFIG_SCSI is not set ++# CONFIG_SCSI_DMA is not set ++# CONFIG_SCSI_NETLINK is not set ++# CONFIG_ATA is not set ++# CONFIG_MD is not set ++CONFIG_NETDEVICES=y ++CONFIG_COMPAT_NET_DEV_OPS=y ++# CONFIG_DUMMY is not set ++# CONFIG_BONDING is not set ++# CONFIG_MACVLAN is not set ++# CONFIG_EQUALIZER is not set ++# CONFIG_TUN is not set ++# CONFIG_VETH is not set ++CONFIG_PHYLIB=y ++ ++# ++# MII PHY device drivers ++# ++# CONFIG_MARVELL_PHY is not set ++# CONFIG_DAVICOM_PHY is not set ++# CONFIG_QSEMI_PHY is not set ++# CONFIG_LXT_PHY is not set ++# CONFIG_CICADA_PHY is not set ++# CONFIG_VITESSE_PHY is not set ++CONFIG_SMSC_PHY=y ++# CONFIG_BROADCOM_PHY is not set ++# CONFIG_ICPLUS_PHY is not set ++# CONFIG_REALTEK_PHY is not set ++# CONFIG_NATIONAL_PHY is not set ++# CONFIG_STE10XP is not set ++# CONFIG_LSI_ET1011C_PHY is not set ++# CONFIG_FIXED_PHY is not set ++# CONFIG_MDIO_BITBANG is not set ++CONFIG_NET_ETHERNET=y ++CONFIG_MII=y ++# CONFIG_AX88796 is not set ++# CONFIG_SMC91X is not set ++# CONFIG_DM9000 is not set ++# CONFIG_ETHOC is not set ++# CONFIG_SMC911X is not set ++# CONFIG_SMSC911X is not set ++# CONFIG_DNET is not set ++# CONFIG_IBM_NEW_EMAC_ZMII is not set ++# CONFIG_IBM_NEW_EMAC_RGMII is not set ++# CONFIG_IBM_NEW_EMAC_TAH is not set ++# CONFIG_IBM_NEW_EMAC_EMAC4 is not set ++# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set ++# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set ++# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set ++# CONFIG_B44 is not set ++CONFIG_FEC=y ++# CONFIG_FEC2 is not set ++# CONFIG_NETDEV_1000 is not set ++# CONFIG_NETDEV_10000 is not set ++ ++# ++# Wireless LAN ++# ++# CONFIG_WLAN_PRE80211 is not set ++# CONFIG_WLAN_80211 is not set ++ ++# ++# Enable WiMAX (Networking options) to see the WiMAX drivers ++# ++# CONFIG_WAN is not set ++# CONFIG_PPP is not set ++# CONFIG_SLIP is not set ++CONFIG_NETCONSOLE=y ++CONFIG_NETCONSOLE_DYNAMIC=y ++CONFIG_NETPOLL=y ++# CONFIG_NETPOLL_TRAP is not set ++CONFIG_NET_POLL_CONTROLLER=y ++# CONFIG_ISDN is not set ++ ++# ++# Input device support ++# ++CONFIG_INPUT=y ++# CONFIG_INPUT_FF_MEMLESS is not set ++# CONFIG_INPUT_POLLDEV is not set ++ ++# ++# Userland interfaces ++# ++CONFIG_INPUT_MOUSEDEV=m ++CONFIG_INPUT_MOUSEDEV_PSAUX=y ++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 ++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 ++# CONFIG_INPUT_JOYDEV is not set ++CONFIG_INPUT_EVDEV=m ++CONFIG_INPUT_EVBUG=m ++# CONFIG_INPUT_APMPOWER is not set ++ ++# ++# Input Device Drivers ++# ++CONFIG_INPUT_KEYBOARD=y ++# CONFIG_KEYBOARD_ATKBD is not set ++# CONFIG_KEYBOARD_SUNKBD is not set ++# CONFIG_KEYBOARD_LKKBD is not set ++# CONFIG_KEYBOARD_XTKBD is not set ++# CONFIG_KEYBOARD_NEWTON is not set ++# CONFIG_KEYBOARD_STOWAWAY is not set ++CONFIG_KEYBOARD_GPIO=m ++CONFIG_INPUT_MOUSE=y ++# CONFIG_MOUSE_PS2 is not set ++# CONFIG_MOUSE_SERIAL is not set ++# CONFIG_MOUSE_VSXXXAA is not set ++# CONFIG_MOUSE_GPIO is not set ++# CONFIG_INPUT_JOYSTICK is not set ++# CONFIG_INPUT_TABLET is not set ++# CONFIG_INPUT_TOUCHSCREEN is not set ++# CONFIG_INPUT_MISC is not set ++ ++# ++# Hardware I/O ports ++# ++# CONFIG_SERIO is not set ++# CONFIG_GAMEPORT is not set ++ ++# ++# Character devices ++# ++CONFIG_VT=y ++CONFIG_CONSOLE_TRANSLATIONS=y ++CONFIG_VT_CONSOLE=y ++CONFIG_HW_CONSOLE=y ++CONFIG_VT_HW_CONSOLE_BINDING=y ++CONFIG_DEVKMEM=y ++# CONFIG_SERIAL_NONSTANDARD is not set ++ ++# ++# Serial drivers ++# ++# CONFIG_SERIAL_8250 is not set ++ ++# ++# Non-8250 serial port support ++# ++CONFIG_SERIAL_IMX=y ++CONFIG_SERIAL_IMX_CONSOLE=y ++CONFIG_SERIAL_CORE=y ++CONFIG_SERIAL_CORE_CONSOLE=y ++CONFIG_UNIX98_PTYS=y ++# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set ++CONFIG_LEGACY_PTYS=y ++CONFIG_LEGACY_PTY_COUNT=16 ++# CONFIG_IPMI_HANDLER is not set ++# CONFIG_HW_RANDOM is not set ++# CONFIG_R3964 is not set ++# CONFIG_RAW_DRIVER is not set ++# CONFIG_TCG_TPM is not set ++# CONFIG_I2C is not set ++# CONFIG_SPI is not set ++CONFIG_ARCH_REQUIRE_GPIOLIB=y ++CONFIG_GPIOLIB=y ++CONFIG_DEBUG_GPIO=y ++CONFIG_GPIO_SYSFS=y ++ ++# ++# Memory mapped GPIO expanders: ++# ++ ++# ++# I2C GPIO expanders: ++# ++ ++# ++# PCI GPIO expanders: ++# ++ ++# ++# SPI GPIO expanders: ++# ++# CONFIG_W1 is not set ++# CONFIG_POWER_SUPPLY is not set ++# CONFIG_HWMON is not set ++# CONFIG_THERMAL is not set ++# CONFIG_THERMAL_HWMON is not set ++# CONFIG_WATCHDOG is not set ++CONFIG_SSB_POSSIBLE=y ++ ++# ++# Sonics Silicon Backplane ++# ++# CONFIG_SSB is not set ++ ++# ++# Multifunction device drivers ++# ++# CONFIG_MFD_CORE is not set ++# CONFIG_MFD_SM501 is not set ++# CONFIG_MFD_ASIC3 is not set ++# CONFIG_HTC_EGPIO is not set ++# CONFIG_HTC_PASIC3 is not set ++# CONFIG_MFD_TMIO is not set ++# CONFIG_MFD_T7L66XB is not set ++# CONFIG_MFD_TC6387XB is not set ++# CONFIG_MFD_TC6393XB is not set ++ ++# ++# Multimedia devices ++# ++ ++# ++# Multimedia core support ++# ++# CONFIG_VIDEO_DEV is not set ++# CONFIG_DVB_CORE is not set ++# CONFIG_VIDEO_MEDIA is not set ++ ++# ++# Multimedia drivers ++# ++# CONFIG_DAB is not set ++ ++# ++# Graphics support ++# ++# CONFIG_VGASTATE is not set ++# CONFIG_VIDEO_OUTPUT_CONTROL is not set ++CONFIG_FB=y ++# CONFIG_FIRMWARE_EDID is not set ++# CONFIG_FB_DDC is not set ++# CONFIG_FB_BOOT_VESA_SUPPORT is not set ++CONFIG_FB_CFB_FILLRECT=y ++CONFIG_FB_CFB_COPYAREA=y ++CONFIG_FB_CFB_IMAGEBLIT=y ++# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set ++# CONFIG_FB_SYS_FILLRECT is not set ++# CONFIG_FB_SYS_COPYAREA is not set ++# CONFIG_FB_SYS_IMAGEBLIT is not set ++# CONFIG_FB_FOREIGN_ENDIAN is not set ++# CONFIG_FB_SYS_FOPS is not set ++# CONFIG_FB_SVGALIB is not set ++# CONFIG_FB_MACMODES is not set ++# CONFIG_FB_BACKLIGHT is not set ++CONFIG_FB_MODE_HELPERS=y ++CONFIG_FB_TILEBLITTING=y ++ ++# ++# Frame buffer hardware drivers ++# ++CONFIG_FB_IMX=y ++# CONFIG_FB_S1D13XXX is not set ++# CONFIG_FB_VIRTUAL is not set ++# CONFIG_FB_METRONOME is not set ++# CONFIG_FB_MB862XX is not set ++# CONFIG_FB_BROADSHEET is not set ++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set ++ ++# ++# Display device support ++# ++# CONFIG_DISPLAY_SUPPORT is not set ++ ++# ++# Console display driver support ++# ++# CONFIG_VGA_CONSOLE is not set ++CONFIG_DUMMY_CONSOLE=y ++CONFIG_FRAMEBUFFER_CONSOLE=y ++CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y ++CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y ++# CONFIG_FONTS is not set ++CONFIG_FONT_8x8=y ++CONFIG_FONT_8x16=y ++CONFIG_LOGO=y ++CONFIG_LOGO_LINUX_MONO=y ++CONFIG_LOGO_LINUX_VGA16=y ++CONFIG_LOGO_LINUX_CLUT224=y ++# CONFIG_SOUND is not set ++# CONFIG_HID_SUPPORT is not set ++# CONFIG_USB_SUPPORT is not set ++# CONFIG_MMC is not set ++# CONFIG_MEMSTICK is not set ++# CONFIG_ACCESSIBILITY is not set ++CONFIG_NEW_LEDS=y ++CONFIG_LEDS_CLASS=y ++ ++# ++# LED drivers ++# ++CONFIG_LEDS_GPIO=y ++CONFIG_LEDS_GPIO_PLATFORM=y ++ ++# ++# LED Triggers ++# ++CONFIG_LEDS_TRIGGERS=y ++# CONFIG_LEDS_TRIGGER_TIMER is not set ++CONFIG_LEDS_TRIGGER_HEARTBEAT=y ++# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set ++# CONFIG_LEDS_TRIGGER_GPIO is not set ++# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set ++ ++# ++# iptables trigger is under Netfilter config (LED target) ++# ++CONFIG_RTC_LIB=y ++# CONFIG_RTC_CLASS is not set ++# CONFIG_DMADEVICES is not set ++# CONFIG_AUXDISPLAY is not set ++# CONFIG_REGULATOR is not set ++# CONFIG_UIO is not set ++# CONFIG_STAGING is not set ++ ++# ++# File systems ++# ++CONFIG_EXT2_FS=y ++# CONFIG_EXT2_FS_XATTR is not set ++# CONFIG_EXT2_FS_XIP is not set ++CONFIG_EXT3_FS=m ++# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set ++CONFIG_EXT3_FS_XATTR=y ++CONFIG_EXT3_FS_POSIX_ACL=y ++# CONFIG_EXT3_FS_SECURITY is not set ++# CONFIG_EXT4_FS is not set ++CONFIG_JBD=m ++CONFIG_FS_MBCACHE=m ++# CONFIG_REISERFS_FS is not set ++# CONFIG_JFS_FS is not set ++CONFIG_FS_POSIX_ACL=y ++CONFIG_FILE_LOCKING=y ++# CONFIG_XFS_FS is not set ++# CONFIG_GFS2_FS is not set ++# CONFIG_OCFS2_FS is not set ++# CONFIG_BTRFS_FS is not set ++CONFIG_DNOTIFY=y ++CONFIG_INOTIFY=y ++CONFIG_INOTIFY_USER=y ++# CONFIG_QUOTA is not set ++# CONFIG_AUTOFS_FS is not set ++# CONFIG_AUTOFS4_FS is not set ++# CONFIG_FUSE_FS is not set ++ ++# ++# Caches ++# ++# CONFIG_FSCACHE is not set ++ ++# ++# CD-ROM/DVD Filesystems ++# ++CONFIG_ISO9660_FS=y ++CONFIG_JOLIET=y ++CONFIG_ZISOFS=y ++# CONFIG_UDF_FS is not set ++ ++# ++# DOS/FAT/NT Filesystems ++# ++CONFIG_FAT_FS=m ++CONFIG_MSDOS_FS=m ++CONFIG_VFAT_FS=m ++CONFIG_FAT_DEFAULT_CODEPAGE=437 ++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" ++CONFIG_NTFS_FS=m ++# CONFIG_NTFS_DEBUG is not set ++CONFIG_NTFS_RW=y ++ ++# ++# Pseudo filesystems ++# ++CONFIG_PROC_FS=y ++CONFIG_PROC_SYSCTL=y ++CONFIG_PROC_PAGE_MONITOR=y ++CONFIG_SYSFS=y ++CONFIG_TMPFS=y ++# CONFIG_TMPFS_POSIX_ACL is not set ++# CONFIG_HUGETLB_PAGE is not set ++CONFIG_CONFIGFS_FS=y ++CONFIG_MISC_FILESYSTEMS=y ++# CONFIG_ADFS_FS is not set ++# CONFIG_AFFS_FS is not set ++# CONFIG_HFS_FS is not set ++# CONFIG_HFSPLUS_FS is not set ++# CONFIG_BEFS_FS is not set ++# CONFIG_BFS_FS is not set ++# CONFIG_EFS_FS is not set ++CONFIG_JFFS2_FS=y ++CONFIG_JFFS2_FS_DEBUG=0 ++CONFIG_JFFS2_FS_WRITEBUFFER=y ++# CONFIG_JFFS2_FS_WBUF_VERIFY is not set ++CONFIG_JFFS2_SUMMARY=y ++# CONFIG_JFFS2_FS_XATTR is not set ++# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set ++CONFIG_JFFS2_ZLIB=y ++# CONFIG_JFFS2_LZO is not set ++CONFIG_JFFS2_RTIME=y ++# CONFIG_JFFS2_RUBIN is not set ++CONFIG_CRAMFS=y ++# CONFIG_SQUASHFS is not set ++# CONFIG_VXFS_FS is not set ++# CONFIG_MINIX_FS is not set ++# CONFIG_OMFS_FS is not set ++# CONFIG_HPFS_FS is not set ++# CONFIG_QNX4FS_FS is not set ++# CONFIG_ROMFS_FS is not set ++# CONFIG_SYSV_FS is not set ++# CONFIG_UFS_FS is not set ++# CONFIG_NILFS2_FS is not set ++CONFIG_NETWORK_FILESYSTEMS=y ++CONFIG_NFS_FS=y ++CONFIG_NFS_V3=y ++# CONFIG_NFS_V3_ACL is not set ++CONFIG_NFS_V4=y ++CONFIG_ROOT_NFS=y ++# CONFIG_NFSD is not set ++CONFIG_LOCKD=y ++CONFIG_LOCKD_V4=y ++CONFIG_NFS_COMMON=y ++CONFIG_SUNRPC=y ++CONFIG_SUNRPC_GSS=y ++CONFIG_RPCSEC_GSS_KRB5=y ++# CONFIG_RPCSEC_GSS_SPKM3 is not set ++# CONFIG_SMB_FS is not set ++# CONFIG_CIFS is not set ++# CONFIG_NCP_FS is not set ++# CONFIG_CODA_FS is not set ++# CONFIG_AFS_FS is not set ++ ++# ++# Partition Types ++# ++CONFIG_PARTITION_ADVANCED=y ++# CONFIG_ACORN_PARTITION is not set ++# CONFIG_OSF_PARTITION is not set ++# CONFIG_AMIGA_PARTITION is not set ++# CONFIG_ATARI_PARTITION is not set ++# CONFIG_MAC_PARTITION is not set ++CONFIG_MSDOS_PARTITION=y ++# CONFIG_BSD_DISKLABEL is not set ++# CONFIG_MINIX_SUBPARTITION is not set ++# CONFIG_SOLARIS_X86_PARTITION is not set ++# CONFIG_UNIXWARE_DISKLABEL is not set ++# CONFIG_LDM_PARTITION is not set ++# CONFIG_SGI_PARTITION is not set ++# CONFIG_ULTRIX_PARTITION is not set ++# CONFIG_SUN_PARTITION is not set ++# CONFIG_KARMA_PARTITION is not set ++# CONFIG_EFI_PARTITION is not set ++# CONFIG_SYSV68_PARTITION is not set ++CONFIG_NLS=y ++CONFIG_NLS_DEFAULT="cp437" ++CONFIG_NLS_CODEPAGE_437=y ++# CONFIG_NLS_CODEPAGE_737 is not set ++# CONFIG_NLS_CODEPAGE_775 is not set ++CONFIG_NLS_CODEPAGE_850=y ++# CONFIG_NLS_CODEPAGE_852 is not set ++# CONFIG_NLS_CODEPAGE_855 is not set ++# CONFIG_NLS_CODEPAGE_857 is not set ++# CONFIG_NLS_CODEPAGE_860 is not set ++# CONFIG_NLS_CODEPAGE_861 is not set ++# CONFIG_NLS_CODEPAGE_862 is not set ++# CONFIG_NLS_CODEPAGE_863 is not set ++# CONFIG_NLS_CODEPAGE_864 is not set ++# CONFIG_NLS_CODEPAGE_865 is not set ++# CONFIG_NLS_CODEPAGE_866 is not set ++# CONFIG_NLS_CODEPAGE_869 is not set ++# CONFIG_NLS_CODEPAGE_936 is not set ++# CONFIG_NLS_CODEPAGE_950 is not set ++# CONFIG_NLS_CODEPAGE_932 is not set ++# CONFIG_NLS_CODEPAGE_949 is not set ++# CONFIG_NLS_CODEPAGE_874 is not set ++# CONFIG_NLS_ISO8859_8 is not set ++CONFIG_NLS_CODEPAGE_1250=m ++# CONFIG_NLS_CODEPAGE_1251 is not set ++CONFIG_NLS_ASCII=m ++CONFIG_NLS_ISO8859_1=m ++# CONFIG_NLS_ISO8859_2 is not set ++# CONFIG_NLS_ISO8859_3 is not set ++# CONFIG_NLS_ISO8859_4 is not set ++# CONFIG_NLS_ISO8859_5 is not set ++# CONFIG_NLS_ISO8859_6 is not set ++# CONFIG_NLS_ISO8859_7 is not set ++# CONFIG_NLS_ISO8859_9 is not set ++# CONFIG_NLS_ISO8859_13 is not set ++# CONFIG_NLS_ISO8859_14 is not set ++CONFIG_NLS_ISO8859_15=y ++# CONFIG_NLS_KOI8_R is not set ++# CONFIG_NLS_KOI8_U is not set ++CONFIG_NLS_UTF8=y ++# CONFIG_DLM is not set ++ ++# ++# Kernel hacking ++# ++# CONFIG_PRINTK_TIME is not set ++CONFIG_ENABLE_WARN_DEPRECATED=y ++CONFIG_ENABLE_MUST_CHECK=y ++CONFIG_FRAME_WARN=1024 ++CONFIG_MAGIC_SYSRQ=y ++# CONFIG_UNUSED_SYMBOLS is not set ++# CONFIG_DEBUG_FS is not set ++# CONFIG_HEADERS_CHECK is not set ++CONFIG_DEBUG_KERNEL=y ++# CONFIG_DEBUG_SHIRQ is not set ++CONFIG_DETECT_SOFTLOCKUP=y ++CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y ++CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=1 ++CONFIG_DETECT_HUNG_TASK=y ++CONFIG_BOOTPARAM_HUNG_TASK_PANIC=y ++CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=1 ++# CONFIG_SCHED_DEBUG is not set ++# CONFIG_SCHEDSTATS is not set ++# CONFIG_TIMER_STATS is not set ++# CONFIG_DEBUG_OBJECTS is not set ++CONFIG_DEBUG_SLAB=y ++CONFIG_DEBUG_SLAB_LEAK=y ++# CONFIG_DEBUG_PREEMPT is not set ++# CONFIG_DEBUG_RT_MUTEXES is not set ++# CONFIG_RT_MUTEX_TESTER is not set ++# CONFIG_DEBUG_SPINLOCK is not set ++# CONFIG_DEBUG_MUTEXES is not set ++# CONFIG_DEBUG_LOCK_ALLOC is not set ++# CONFIG_PROVE_LOCKING is not set ++# CONFIG_LOCK_STAT is not set ++# CONFIG_DEBUG_SPINLOCK_SLEEP is not set ++# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set ++# CONFIG_DEBUG_KOBJECT is not set ++CONFIG_DEBUG_BUGVERBOSE=y ++# CONFIG_DEBUG_INFO is not set ++# CONFIG_DEBUG_VM is not set ++# CONFIG_DEBUG_WRITECOUNT is not set ++# CONFIG_DEBUG_MEMORY_INIT is not set ++# CONFIG_DEBUG_LIST is not set ++# CONFIG_DEBUG_SG is not set ++# CONFIG_DEBUG_NOTIFIERS is not set ++# CONFIG_BOOT_PRINTK_DELAY is not set ++# CONFIG_RCU_TORTURE_TEST is not set ++# CONFIG_RCU_CPU_STALL_DETECTOR is not set ++# CONFIG_BACKTRACE_SELF_TEST is not set ++# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set ++# CONFIG_FAULT_INJECTION is not set ++# CONFIG_LATENCYTOP is not set ++# CONFIG_SYSCTL_SYSCALL_CHECK is not set ++# CONFIG_PAGE_POISONING is not set ++CONFIG_HAVE_FUNCTION_TRACER=y ++CONFIG_TRACING_SUPPORT=y ++ ++# ++# Tracers ++# ++# CONFIG_FUNCTION_TRACER is not set ++# CONFIG_IRQSOFF_TRACER is not set ++# CONFIG_PREEMPT_TRACER is not set ++# CONFIG_SCHED_TRACER is not set ++# CONFIG_CONTEXT_SWITCH_TRACER is not set ++# CONFIG_EVENT_TRACER is not set ++# CONFIG_BOOT_TRACER is not set ++# CONFIG_TRACE_BRANCH_PROFILING is not set ++# CONFIG_STACK_TRACER is not set ++# CONFIG_KMEMTRACE is not set ++# CONFIG_WORKQUEUE_TRACER is not set ++# CONFIG_BLK_DEV_IO_TRACE is not set ++# CONFIG_SAMPLES is not set ++CONFIG_HAVE_ARCH_KGDB=y ++# CONFIG_KGDB is not set ++CONFIG_ARM_UNWIND=y ++CONFIG_DEBUG_USER=y ++CONFIG_DEBUG_ERRORS=y ++# CONFIG_DEBUG_STACK_USAGE is not set ++# CONFIG_DEBUG_LL is not set ++ ++# ++# Security options ++# ++# CONFIG_KEYS is not set ++# CONFIG_SECURITY is not set ++# CONFIG_SECURITYFS is not set ++# CONFIG_SECURITY_FILE_CAPABILITIES is not set ++CONFIG_CRYPTO=y ++ ++# ++# Crypto core or helper ++# ++# CONFIG_CRYPTO_FIPS is not set ++CONFIG_CRYPTO_ALGAPI=y ++CONFIG_CRYPTO_ALGAPI2=y ++CONFIG_CRYPTO_AEAD2=y ++CONFIG_CRYPTO_BLKCIPHER=y ++CONFIG_CRYPTO_BLKCIPHER2=y ++CONFIG_CRYPTO_HASH=y ++CONFIG_CRYPTO_HASH2=y ++CONFIG_CRYPTO_RNG2=y ++CONFIG_CRYPTO_PCOMP=y ++CONFIG_CRYPTO_MANAGER=y ++CONFIG_CRYPTO_MANAGER2=y ++# CONFIG_CRYPTO_GF128MUL is not set ++# CONFIG_CRYPTO_NULL is not set ++CONFIG_CRYPTO_WORKQUEUE=y ++# CONFIG_CRYPTO_CRYPTD is not set ++# CONFIG_CRYPTO_AUTHENC is not set ++# CONFIG_CRYPTO_TEST is not set ++ ++# ++# Authenticated Encryption with Associated Data ++# ++# CONFIG_CRYPTO_CCM is not set ++# CONFIG_CRYPTO_GCM is not set ++# CONFIG_CRYPTO_SEQIV is not set ++ ++# ++# Block modes ++# ++CONFIG_CRYPTO_CBC=y ++# CONFIG_CRYPTO_CTR is not set ++# CONFIG_CRYPTO_CTS is not set ++CONFIG_CRYPTO_ECB=y ++# CONFIG_CRYPTO_LRW is not set ++# CONFIG_CRYPTO_PCBC is not set ++# CONFIG_CRYPTO_XTS is not set ++ ++# ++# Hash modes ++# ++CONFIG_CRYPTO_HMAC=y ++# CONFIG_CRYPTO_XCBC is not set ++ ++# ++# Digest ++# ++# CONFIG_CRYPTO_CRC32C is not set ++# CONFIG_CRYPTO_MD4 is not set ++CONFIG_CRYPTO_MD5=y ++# CONFIG_CRYPTO_MICHAEL_MIC is not set ++# CONFIG_CRYPTO_RMD128 is not set ++# CONFIG_CRYPTO_RMD160 is not set ++# CONFIG_CRYPTO_RMD256 is not set ++# CONFIG_CRYPTO_RMD320 is not set ++# CONFIG_CRYPTO_SHA1 is not set ++# CONFIG_CRYPTO_SHA256 is not set ++# CONFIG_CRYPTO_SHA512 is not set ++# CONFIG_CRYPTO_TGR192 is not set ++# CONFIG_CRYPTO_WP512 is not set ++ ++# ++# Ciphers ++# ++CONFIG_CRYPTO_AES=y ++# CONFIG_CRYPTO_ANUBIS is not set ++CONFIG_CRYPTO_ARC4=y ++# CONFIG_CRYPTO_BLOWFISH is not set ++# CONFIG_CRYPTO_CAMELLIA is not set ++# CONFIG_CRYPTO_CAST5 is not set ++# CONFIG_CRYPTO_CAST6 is not set ++CONFIG_CRYPTO_DES=y ++# CONFIG_CRYPTO_FCRYPT is not set ++# CONFIG_CRYPTO_KHAZAD is not set ++# CONFIG_CRYPTO_SALSA20 is not set ++# CONFIG_CRYPTO_SEED is not set ++# CONFIG_CRYPTO_SERPENT is not set ++# CONFIG_CRYPTO_TEA is not set ++# CONFIG_CRYPTO_TWOFISH is not set ++ ++# ++# Compression ++# ++# CONFIG_CRYPTO_DEFLATE is not set ++# CONFIG_CRYPTO_ZLIB is not set ++# CONFIG_CRYPTO_LZO is not set ++ ++# ++# Random Number Generation ++# ++# CONFIG_CRYPTO_ANSI_CPRNG is not set ++CONFIG_CRYPTO_HW=y ++# CONFIG_BINARY_PRINTF is not set ++ ++# ++# Library routines ++# ++CONFIG_BITREVERSE=y ++CONFIG_GENERIC_FIND_LAST_BIT=y ++# CONFIG_CRC_CCITT is not set ++# CONFIG_CRC16 is not set ++# CONFIG_CRC_T10DIF is not set ++# CONFIG_CRC_ITU_T is not set ++CONFIG_CRC32=y ++# CONFIG_CRC7 is not set ++# CONFIG_LIBCRC32C is not set ++CONFIG_ZLIB_INFLATE=y ++CONFIG_ZLIB_DEFLATE=y ++CONFIG_DECOMPRESS_GZIP=y ++CONFIG_HAS_IOMEM=y ++CONFIG_HAS_IOPORT=y ++CONFIG_HAS_DMA=y ++CONFIG_NLATTR=y +diff -urNp linux-2.6.30-rc4/arch/arm/mach-mx2/Kconfig linux-2.6.30-rc4-karo/arch/arm/mach-mx2/Kconfig +--- linux-2.6.30-rc4/arch/arm/mach-mx2/Kconfig 2009-05-13 09:46:19.000000000 +0200 ++++ linux-2.6.30-rc4-karo/arch/arm/mach-mx2/Kconfig 2009-06-02 17:05:27.000000000 +0200 +@@ -6,14 +6,26 @@ choice + + config MACH_MX21 + bool "i.MX21 support" ++ select ARCH_MXC_IOMUX_V2 ++ select ARCH_MXC_HAS_NFC_V1 + help + This enables support for Freescale's MX2 based i.MX21 processor. + + config MACH_MX27 + bool "i.MX27 support" ++ select ARCH_MXC_IOMUX_V2 ++ select ARCH_MXC_HAS_NFC_V1 + help + This enables support for Freescale's MX2 based i.MX27 processor. + ++config MACH_MX25 ++ bool "i.MX25 support" ++ select ARCH_MXC_IOMUX_V3 ++ select ARCH_MXC_HAS_NFC_V2_1 ++ select PHYLIB if FEC ++ help ++ This enables support for Freescale's MX2 based i.MX25 processor. ++ + endchoice + + comment "MX2 platforms:" +@@ -39,6 +51,26 @@ config MACH_PCM038 + Include support for phyCORE-i.MX27 (aka pcm038) platform. This + includes specific configurations for the module and its peripherals. + ++config MACH_TX25 ++ bool "Support Ka-Ro electronics TX25 module" ++ depends on MACH_MX25 ++ help ++ Include support for Ka-Ro TX25 processor module ++ ++config KARO_DEBUG ++ bool "Enable Ka-Ro specific debug messages" ++ depends on MACH_TX25 || MACH_TX27 ++ help ++ Compile the architecture specific files with -DDEBUG to enable ++ additional debug messages ++ ++config MACH_STK5_BASEBOARD ++ bool "Ka-Ro Starterkit-5 (STK5) development board" ++ depends on MACH_TX27 || MACH_TX25 ++ help ++ This adds board specific devices that can be found on Ka-Ro's ++ STK5 evaluation board. ++ + choice + prompt "Baseboard" + depends on MACH_PCM038 +@@ -60,3 +92,4 @@ config MACH_MX27_3DS + Include support for MX27PDK platform. This includes specific + configurations for the board and its peripherals. + endif ++ +diff -urNp linux-2.6.30-rc4/arch/arm/mach-mx2/Makefile linux-2.6.30-rc4-karo/arch/arm/mach-mx2/Makefile +--- linux-2.6.30-rc4/arch/arm/mach-mx2/Makefile 2009-05-13 09:46:19.000000000 +0200 ++++ linux-2.6.30-rc4-karo/arch/arm/mach-mx2/Makefile 2009-06-02 17:05:27.000000000 +0200 +@@ -2,17 +2,31 @@ + # Makefile for the linux kernel. + # + ++ifeq ($(CONFIG_KARO_DEBUG),y) ++ EXTRA_CFLAGS += -DDEBUG ++endif ++ + # Object file lists. + +-obj-y := generic.o devices.o serial.o ++obj-y := generic.o serial.o ++obj-$(CONFIG_MACH_MX25) += devices_mx25.o ++ifeq ($(CONFIG_MACH_MX25),) ++obj-y += devices.o ++endif ++ ++obj-$(CONFIG_MACH_MX21) += clock_imx21.o + +-obj-$(CONFIG_MACH_MX21) += clock_imx21.o ++obj-$(CONFIG_MACH_MX25) += clock_imx25.o ++obj-$(CONFIG_MACH_MX25) += cpu_imx25.o + +-obj-$(CONFIG_MACH_MX27) += cpu_imx27.o +-obj-$(CONFIG_MACH_MX27) += clock_imx27.o ++obj-$(CONFIG_MACH_MX27) += cpu_imx27.o ++obj-$(CONFIG_MACH_MX27) += clock_imx27.o + +-obj-$(CONFIG_MACH_MX21ADS) += mx21ads.o +-obj-$(CONFIG_MACH_MX27ADS) += mx27ads.o +-obj-$(CONFIG_MACH_PCM038) += pcm038.o +-obj-$(CONFIG_MACH_PCM970_BASEBOARD) += pcm970-baseboard.o +-obj-$(CONFIG_MACH_MX27_3DS) += mx27pdk.o ++obj-$(CONFIG_MACH_MX21ADS) += mx21ads.o ++obj-$(CONFIG_MACH_MX27ADS) += mx27ads.o ++obj-$(CONFIG_MACH_PCM038) += pcm038.o ++obj-$(CONFIG_MACH_PCM970_BASEBOARD) += pcm970-baseboard.o ++obj-$(CONFIG_MACH_MX27_3DS) += mx27pdk.o ++obj-$(CONFIG_MACH_TX27) += karo-tx27.o tx27_gpio.o ++obj-$(CONFIG_MACH_TX25) += karo-tx25.o ++obj-$(CONFIG_MACH_STK5_BASEBOARD) += stk5-baseboard.o +diff -urNp linux-2.6.30-rc4/arch/arm/mach-mx2/Makefile.boot linux-2.6.30-rc4-karo/arch/arm/mach-mx2/Makefile.boot +--- linux-2.6.30-rc4/arch/arm/mach-mx2/Makefile.boot 2009-05-13 09:46:19.000000000 +0200 ++++ linux-2.6.30-rc4-karo/arch/arm/mach-mx2/Makefile.boot 2009-06-02 17:05:27.000000000 +0200 +@@ -5,3 +5,7 @@ initrd_phys-$(CONFIG_MACH_MX21) := 0xC08 + zreladdr-$(CONFIG_MACH_MX27) := 0xA0008000 + params_phys-$(CONFIG_MACH_MX27) := 0xA0000100 + initrd_phys-$(CONFIG_MACH_MX27) := 0xA0800000 ++ ++zreladdr-$(CONFIG_MACH_MX25) := 0x80008000 ++params_phys-$(CONFIG_MACH_MX25) := 0x80000100 ++initrd_phys-$(CONFIG_MACH_MX25) := 0x80800000 +diff -urNp linux-2.6.30-rc4/arch/arm/mach-mx2/clock_imx21.c linux-2.6.30-rc4-karo/arch/arm/mach-mx2/clock_imx21.c +--- linux-2.6.30-rc4/arch/arm/mach-mx2/clock_imx21.c 2009-05-13 09:46:19.000000000 +0200 ++++ linux-2.6.30-rc4-karo/arch/arm/mach-mx2/clock_imx21.c 2009-06-02 17:05:26.000000000 +0200 +@@ -890,7 +890,7 @@ static struct clk clko_clk = { + .con_id = n, \ + .clk = &c, \ + }, +-static struct clk_lookup lookups[] __initdata = { ++static struct clk_lookup lookups[] = { + /* It's unlikely that any driver wants one of them directly: + _REGISTER_CLOCK(NULL, "ckih", ckih_clk) + _REGISTER_CLOCK(NULL, "ckil", ckil_clk) +diff -urNp linux-2.6.30-rc4/arch/arm/mach-mx2/clock_imx25.c linux-2.6.30-rc4-karo/arch/arm/mach-mx2/clock_imx25.c +--- linux-2.6.30-rc4/arch/arm/mach-mx2/clock_imx25.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30-rc4-karo/arch/arm/mach-mx2/clock_imx25.c 2009-06-02 17:05:26.000000000 +0200 +@@ -0,0 +1,1967 @@ ++/* ++ * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved. ++ */ ++ ++/* ++ * The code contained herein is licensed under the GNU General Public ++ * License. You may obtain a copy of the GNU General Public License ++ * Version 2 or later at the following locations: ++ * ++ * http://www.opensource.org/licenses/gpl-license.html ++ * http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++/* based on mach-mx27/clock.c */ ++ ++#include <linux/clk.h> ++#include <linux/io.h> ++#include <linux/module.h> ++//#include <linux/spinlock.h> ++ ++#include <asm/clkdev.h> ++//#include <asm/div64.h> ++ ++#include <mach/clock.h> ++#include <mach/common.h> ++#include <mach/hardware.h> ++ ++/* Register offsets */ ++#define MXC_CCM_MPCTL (IO_ADDRESS(CCM_BASE_ADDR) + 0x00) ++#define MXC_CCM_UPCTL (IO_ADDRESS(CCM_BASE_ADDR) + 0x04) ++#define MXC_CCM_CCTL (IO_ADDRESS(CCM_BASE_ADDR) + 0x08) ++#define MXC_CCM_CGCR0 (IO_ADDRESS(CCM_BASE_ADDR) + 0x0C) ++#define MXC_CCM_CGCR1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x10) ++#define MXC_CCM_CGCR2 (IO_ADDRESS(CCM_BASE_ADDR) + 0x14) ++#define MXC_CCM_PCDR0 (IO_ADDRESS(CCM_BASE_ADDR) + 0x18) ++#define MXC_CCM_PCDR1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x1C) ++#define MXC_CCM_PCDR2 (IO_ADDRESS(CCM_BASE_ADDR) + 0x20) ++#define MXC_CCM_PCDR3 (IO_ADDRESS(CCM_BASE_ADDR) + 0x24) ++#define MXC_CCM_RCSR (IO_ADDRESS(CCM_BASE_ADDR) + 0x28) ++#define MXC_CCM_CRDR (IO_ADDRESS(CCM_BASE_ADDR) + 0x2C) ++#define MXC_CCM_DCVR0 (IO_ADDRESS(CCM_BASE_ADDR) + 0x30) ++#define MXC_CCM_DCVR1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x34) ++#define MXC_CCM_DCVR2 (IO_ADDRESS(CCM_BASE_ADDR) + 0x38) ++#define MXC_CCM_DCVR3 (IO_ADDRESS(CCM_BASE_ADDR) + 0x3C) ++#define MXC_CCM_LTR0 (IO_ADDRESS(CCM_BASE_ADDR) + 0x40) ++#define MXC_CCM_LTR1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x44) ++#define MXC_CCM_LTR2 (IO_ADDRESS(CCM_BASE_ADDR) + 0x48) ++#define MXC_CCM_LTR3 (IO_ADDRESS(CCM_BASE_ADDR) + 0x4C) ++#define MXC_CCM_LTBR0 (IO_ADDRESS(CCM_BASE_ADDR) + 0x50) ++#define MXC_CCM_LTBR1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x54) ++#define MXC_CCM_PMCR0 (IO_ADDRESS(CCM_BASE_ADDR) + 0x58) ++#define MXC_CCM_PMCR1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x5C) ++#define MXC_CCM_PMCR2 (IO_ADDRESS(CCM_BASE_ADDR) + 0x60) ++#define MXC_CCM_MCR (IO_ADDRESS(CCM_BASE_ADDR) + 0x64) ++ ++#define MXC_CCM_MPCTL_BRMO (1 << 31) ++#define MXC_CCM_MPCTL_PD_OFFSET 26 ++#define MXC_CCM_MPCTL_PD_MASK (0xf << 26) ++#define MXC_CCM_MPCTL_MFD_OFFSET 16 ++#define MXC_CCM_MPCTL_MFD_MASK (0x3ff << 16) ++#define MXC_CCM_MPCTL_MFI_OFFSET 10 ++#define MXC_CCM_MPCTL_MFI_MASK (0xf << 10) ++#define MXC_CCM_MPCTL_MFN_OFFSET 0 ++#define MXC_CCM_MPCTL_MFN_MASK 0x3ff ++#define MXC_CCM_MPCTL_LF (1 << 15) ++ ++#define MXC_CCM_UPCTL_BRMO (1 << 31) ++#define MXC_CCM_UPCTL_PD_OFFSET 26 ++#define MXC_CCM_UPCTL_PD_MASK (0xf << 26) ++#define MXC_CCM_UPCTL_MFD_OFFSET 16 ++#define MXC_CCM_UPCTL_MFD_MASK (0x3ff << 16) ++#define MXC_CCM_UPCTL_MFI_OFFSET 10 ++#define MXC_CCM_UPCTL_MFI_MASK (0xf << 10) ++#define MXC_CCM_UPCTL_MFN_OFFSET 0 ++#define MXC_CCM_UPCTL_MFN_MASK 0x3ff ++#define MXC_CCM_UPCTL_LF (1 << 15) ++ ++#define MXC_CCM_CCTL_ARM_OFFSET 30 ++#define MXC_CCM_CCTL_ARM_MASK (0x3 << 30) ++#define MXC_CCM_CCTL_AHB_OFFSET 28 ++#define MXC_CCM_CCTL_AHB_MASK (0x3 << 28) ++#define MXC_CCM_CCTL_MPLL_RST (1 << 27) ++#define MXC_CCM_CCTL_UPLL_RST (1 << 26) ++#define MXC_CCM_CCTL_LP_CTL_OFFSET 24 ++#define MXC_CCM_CCTL_LP_CTL_MASK (0x3 << 24) ++#define MXC_CCM_CCTL_LP_MODE_RUN (0x0 << 24) ++#define MXC_CCM_CCTL_LP_MODE_WAIT (0x1 << 24) ++#define MXC_CCM_CCTL_LP_MODE_DOZE (0x2 << 24) ++#define MXC_CCM_CCTL_LP_MODE_STOP (0x3 << 24) ++#define MXC_CCM_CCTL_UPLL_DISABLE (1 << 23) ++#define MXC_CCM_CCTL_MPLL_BYPASS (1 << 22) ++#define MXC_CCM_CCTL_USB_DIV_OFFSET 16 ++#define MXC_CCM_CCTL_USB_DIV_MASK (0x3 << 16) ++#define MXC_CCM_CCTL_CG_CTRL (1 << 15) ++#define MXC_CCM_CCTL_ARM_SRC (1 << 14) ++ ++#define MXC_CCM_CGCR0_HCLK_ATA_OFFSET (16 + 0) ++#define MXC_CCM_CGCR0_HCLK_BROM_OFFSET (16 + 1) ++#define MXC_CCM_CGCR0_HCLK_CSI_OFFSET (16 + 2) ++#define MXC_CCM_CGCR0_HCLK_EMI_OFFSET (16 + 3) ++#define MXC_CCM_CGCR0_HCLK_ESAI_OFFSET (16 + 4) ++#define MXC_CCM_CGCR0_HCLK_ESDHC1_OFFSET (16 + 5) ++#define MXC_CCM_CGCR0_HCLK_ESDHC2_OFFSET (16 + 6) ++#define MXC_CCM_CGCR0_HCLK_FEC_OFFSET (16 + 7) ++#define MXC_CCM_CGCR0_HCLK_LCDC_OFFSET (16 + 8) ++#define MXC_CCM_CGCR0_HCLK_RTIC_OFFSET (16 + 9) ++#define MXC_CCM_CGCR0_HCLK_SDMA_OFFSET (16 + 10) ++#define MXC_CCM_CGCR0_HCLK_SLCDC_OFFSET (16 + 11) ++#define MXC_CCM_CGCR0_HCLK_USBOTG_OFFSET (16 + 12) ++ ++#define MXC_CCM_CGCR0_PER_CSI_OFFSET 0 ++#define MXC_CCM_CGCR0_PER_EPIT_OFFSET 1 ++#define MXC_CCM_CGCR0_PER_ESAI_OFFSET 2 ++#define MXC_CCM_CGCR0_PER_ESDHC1_OFFSET 3 ++#define MXC_CCM_CGCR0_PER_ESDHC2_OFFSET 4 ++#define MXC_CCM_CGCR0_PER_GPT_OFFSET 5 ++#define MXC_CCM_CGCR0_PER_I2C_OFFSET 6 ++#define MXC_CCM_CGCR0_PER_LCDC_OFFSET 7 ++#define MXC_CCM_CGCR0_PER_NFC_OFFSET 8 ++#define MXC_CCM_CGCR0_PER_OWIRE_OFFSET 9 ++#define MXC_CCM_CGCR0_PER_PWM_OFFSET 10 ++#define MXC_CCM_CGCR0_PER_SIM1_OFFSET 11 ++#define MXC_CCM_CGCR0_PER_SIM2_OFFSET 12 ++#define MXC_CCM_CGCR0_PER_SSI1_OFFSET 13 ++#define MXC_CCM_CGCR0_PER_SSI2_OFFSET 14 ++#define MXC_CCM_CGCR0_PER_UART_OFFSET 15 ++ ++#define MXC_CCM_CGCR1_AUDMUX_OFFSET 0 ++#define MXC_CCM_CGCR1_ATA_OFFSET 1 ++#define MXC_CCM_CGCR1_CAN1_OFFSET 2 ++#define MXC_CCM_CGCR1_CAN2_OFFSET 3 ++#define MXC_CCM_CGCR1_CSI_OFFSET 4 ++#define MXC_CCM_CGCR1_CSPI1_OFFSET 5 ++#define MXC_CCM_CGCR1_CSPI2_OFFSET 6 ++#define MXC_CCM_CGCR1_CSPI3_OFFSET 7 ++#define MXC_CCM_CGCR1_DRYICE_OFFSET 8 ++#define MXC_CCM_CGCR1_ECT_OFFSET 9 ++#define MXC_CCM_CGCR1_EPIT1_OFFSET 10 ++#define MXC_CCM_CGCR1_EPIT2_OFFSET 11 ++#define MXC_CCM_CGCR1_ESAI_OFFSET 12 ++#define MXC_CCM_CGCR1_ESDHC1_OFFSET 13 ++#define MXC_CCM_CGCR1_ESDHC2_OFFSET 14 ++#define MXC_CCM_CGCR1_FEC_OFFSET 15 ++#define MXC_CCM_CGCR1_GPIO1_OFFSET 16 ++#define MXC_CCM_CGCR1_GPIO2_OFFSET 17 ++#define MXC_CCM_CGCR1_GPIO3_OFFSET 18 ++#define MXC_CCM_CGCR1_GPT1_OFFSET 19 ++#define MXC_CCM_CGCR1_GPT2_OFFSET 20 ++#define MXC_CCM_CGCR1_GPT3_OFFSET 21 ++#define MXC_CCM_CGCR1_GPT4_OFFSET 22 ++#define MXC_CCM_CGCR1_I2C1_OFFSET 23 ++#define MXC_CCM_CGCR1_I2C2_OFFSET 24 ++#define MXC_CCM_CGCR1_I2C3_OFFSET 25 ++#define MXC_CCM_CGCR1_IIM_OFFSET 26 ++#define MXC_CCM_CGCR1_IOMUXC_OFFSET 27 ++#define MXC_CCM_CGCR1_KPP_OFFSET 28 ++#define MXC_CCM_CGCR1_LCDC_OFFSET 29 ++#define MXC_CCM_CGCR1_OWIRE_OFFSET 30 ++#define MXC_CCM_CGCR1_PWM1_OFFSET 31 ++ ++#define MXC_CCM_CGCR2_PWM2_OFFSET (32 - 32) ++#define MXC_CCM_CGCR2_PWM3_OFFSET (33 - 32) ++#define MXC_CCM_CGCR2_PWM4_OFFSET (34 - 32) ++#define MXC_CCM_CGCR2_RNGB_OFFSET (35 - 32) ++#define MXC_CCM_CGCR2_RTIC_OFFSET (36 - 32) ++#define MXC_CCM_CGCR2_SCC_OFFSET (37 - 32) ++#define MXC_CCM_CGCR2_SDMA_OFFSET (38 - 32) ++#define MXC_CCM_CGCR2_SIM1_OFFSET (39 - 32) ++#define MXC_CCM_CGCR2_SIM2_OFFSET (40 - 32) ++#define MXC_CCM_CGCR2_SLCDC_OFFSET (41 - 32) ++#define MXC_CCM_CGCR2_SPBA_OFFSET (42 - 32) ++#define MXC_CCM_CGCR2_SSI1_OFFSET (43 - 32) ++#define MXC_CCM_CGCR2_SSI2_OFFSET (44 - 32) ++#define MXC_CCM_CGCR2_TCHSCRN_OFFSET (45 - 32) ++#define MXC_CCM_CGCR2_UART1_OFFSET (46 - 32) ++#define MXC_CCM_CGCR2_UART2_OFFSET (47 - 32) ++#define MXC_CCM_CGCR2_UART3_OFFSET (48 - 32) ++#define MXC_CCM_CGCR2_UART4_OFFSET (49 - 32) ++#define MXC_CCM_CGCR2_UART5_OFFSET (50 - 32) ++#define MXC_CCM_CGCR2_WDOG_OFFSET (51 - 32) ++ ++#define MXC_CCM_PCDR1_PERDIV1_MASK 0x3f ++ ++#define MXC_CCM_MCR_USB_XTAL_MUX_OFFSET 31 ++#define MXC_CCM_MCR_CLKO_EN_OFFSET 30 ++#define MXC_CCM_MCR_CLKO_DIV_OFFSET 24 ++#define MXC_CCM_MCR_CLKO_DIV_MASK (0x3F << 24) ++#define MXC_CCM_MCR_CLKO_SEL_OFFSET 20 ++#define MXC_CCM_MCR_CLKO_SEL_MASK (0xF << 20) ++#define MXC_CCM_MCR_ESAI_CLK_MUX_OFFSET 19 ++#define MXC_CCM_MCR_SSI2_CLK_MUX_OFFSET 18 ++#define MXC_CCM_MCR_SSI1_CLK_MUX_OFFSET 17 ++#define MXC_CCM_MCR_USB_CLK_MUX_OFFSET 16 ++ ++#define MXC_CCM_MCR_PER_CLK_MUX_MASK (0xFFFF << 0) ++ ++#define OSC24M_CLK_FREQ 24000000 /* 24MHz reference clk */ ++#define OSC32K_CLK_FREQ 32768 /* 32.768kHz oscillator in */ ++ ++static struct clk mpll_clk; ++static struct clk upll_clk; ++static struct clk ahb_clk; ++static struct clk upll_24610k_clk; ++ ++static int _clk_enable(struct clk *clk) ++{ ++ unsigned long reg; ++ ++ if (!clk->enable_reg) ++ return 0; ++ ++ reg = __raw_readl(clk->enable_reg); ++ reg |= 1 << clk->enable_shift; ++ __raw_writel(reg, clk->enable_reg); ++ ++ return 0; ++} ++ ++static void _clk_disable(struct clk *clk) ++{ ++ unsigned long reg; ++ ++ if (!clk->enable_reg) ++ return; ++ ++ reg = __raw_readl(clk->enable_reg); ++ reg &= ~(1 << clk->enable_shift); ++ __raw_writel(reg, clk->enable_reg); ++} ++ ++static int _clk_upll_enable(struct clk *clk) ++{ ++ unsigned long reg; ++ ++ reg = __raw_readl(MXC_CCM_CCTL); ++ reg &= ~MXC_CCM_CCTL_UPLL_DISABLE; ++ __raw_writel(reg, MXC_CCM_CCTL); ++ ++ while (!(__raw_readl(MXC_CCM_UPCTL) & MXC_CCM_UPCTL_LF)) ++ cpu_relax(); ++ ++ return 0; ++} ++ ++static void _clk_upll_disable(struct clk *clk) ++{ ++ unsigned long reg; ++ ++ reg = __raw_readl(MXC_CCM_CCTL); ++ reg |= MXC_CCM_CCTL_UPLL_DISABLE; ++ __raw_writel(reg, MXC_CCM_CCTL); ++} ++ ++static int _perclk_enable(struct clk *clk) ++{ ++ unsigned long reg; ++ ++ reg = __raw_readl(MXC_CCM_CGCR0); ++ reg |= 1 << clk->id; ++ __raw_writel(reg, MXC_CCM_CGCR0); ++ ++ return 0; ++} ++ ++static void _perclk_disable(struct clk *clk) ++{ ++ unsigned long reg; ++ ++ reg = __raw_readl(MXC_CCM_CGCR0); ++ reg &= ~(1 << clk->id); ++ __raw_writel(reg, MXC_CCM_CGCR0); ++} ++ ++static int _clk_pll_set_rate(struct clk *clk, unsigned long rate) ++{ ++ unsigned long reg; ++ signed long pd = 1; /* Pre-divider */ ++ signed long mfi; /* Multiplication Factor (Integer part) */ ++ signed long mfn; /* Multiplication Factor (Integer part) */ ++ signed long mfd; /* Multiplication Factor (Denominator Part) */ ++ signed long tmp; ++ unsigned long ref_freq = clk_get_rate(clk->parent); ++ ++ while (((ref_freq / pd) * 10) > rate) ++ pd++; ++ ++ /* the ref_freq/2 in the following is to round up */ ++ mfi = (((rate / 2) * pd) + (ref_freq / 2)) / ref_freq; ++ if (mfi < 5 || mfi > 15) ++ return -EINVAL; ++ ++ /* pick a mfd value that will work ++ * then solve for mfn */ ++ mfd = ref_freq / 50000; ++ ++ /* ++ * pll_freq * pd * mfd ++ * mfn = -------------------- - (mfi * mfd) ++ * 2 * ref_freq ++ */ ++ /* the tmp/2 is for rounding */ ++ tmp = ref_freq / 10000; ++ mfn = ((((((rate / 2) + (tmp / 2)) / tmp) * pd) * mfd) / 10000) - ++ (mfi * mfd); ++ ++ printk(KERN_DEBUG "pll freq: %lu PD=%ld MFI=%ld MFD=%ld MFN=%ld (0x%03lx)\n", ++ rate, pd, mfi, mfd, mfn, (mfn + ((mfn < 0) ? 1024 : 0)) & 0x3ff); ++ ++ mfn = (mfn + ((mfn < 0) ? 1024 : 0)) & 0x3ff; ++ pd--; ++ mfd--; ++ ++ /* Change the Pll value */ ++ reg = (mfi << MXC_CCM_MPCTL_MFI_OFFSET) | ++ (mfn << MXC_CCM_MPCTL_MFN_OFFSET) | ++ (mfd << MXC_CCM_MPCTL_MFD_OFFSET) | ++ (pd << MXC_CCM_MPCTL_PD_OFFSET); ++ ++ if (clk == &mpll_clk) { ++ printk(KERN_DEBUG "Changing MPCTL from %08x to %08lx\n", ++ __raw_readl(MXC_CCM_MPCTL), reg); ++ } else if (clk == &upll_clk) { ++ printk(KERN_DEBUG "Changing UPCTL from %08x to %08lx\n", ++ __raw_readl(MXC_CCM_UPCTL), reg); ++ } ++ if (clk == &mpll_clk) ++ __raw_writel(reg, MXC_CCM_MPCTL); ++ else if (clk == &upll_clk) ++ __raw_writel(reg, MXC_CCM_UPCTL); ++ return 0; ++} ++ ++static unsigned long _clk_pll_getrate(struct clk *clk) ++{ ++ unsigned long rate; ++ signed long mfi, mfn, mfd, pdf; ++ unsigned long ref_clk; ++ unsigned long reg; ++ ++ ref_clk = clk_get_rate(clk->parent); ++ ++ if (clk == &mpll_clk) { ++ reg = __raw_readl(MXC_CCM_MPCTL); ++ pdf = (reg & MXC_CCM_MPCTL_PD_MASK) >> MXC_CCM_MPCTL_PD_OFFSET; ++ mfd = (reg & MXC_CCM_MPCTL_MFD_MASK) >> MXC_CCM_MPCTL_MFD_OFFSET; ++ mfi = (reg & MXC_CCM_MPCTL_MFI_MASK) >> MXC_CCM_MPCTL_MFI_OFFSET; ++ mfn = (reg & MXC_CCM_MPCTL_MFN_MASK) >> MXC_CCM_MPCTL_MFN_OFFSET; ++ } else if (clk == &upll_clk) { ++ reg = __raw_readl(MXC_CCM_UPCTL); ++ pdf = (reg & MXC_CCM_UPCTL_PD_MASK) >> MXC_CCM_UPCTL_PD_OFFSET; ++ mfd = (reg & MXC_CCM_UPCTL_MFD_MASK) >> MXC_CCM_UPCTL_MFD_OFFSET; ++ mfi = (reg & MXC_CCM_UPCTL_MFI_MASK) >> MXC_CCM_UPCTL_MFI_OFFSET; ++ mfn = (reg & MXC_CCM_UPCTL_MFN_MASK) >> MXC_CCM_UPCTL_MFN_OFFSET; ++ } else { ++ BUG(); /* oops */ ++ } ++ ++ mfi = (mfi < 5) ? 5 : mfi; ++ rate = 2LL * ref_clk * mfn; ++ do_div(rate, mfd + 1); ++ rate = 2LL * ref_clk * mfi + rate; ++ do_div(rate, pdf + 1); ++ ++ return rate; ++} ++ ++static unsigned long _clk_cpu_round_rate(struct clk *clk, unsigned long rate) ++{ ++ int div = clk_get_rate(clk->parent) / rate; ++ ++ if (clk_get_rate(clk->parent) % rate) ++ div++; ++ ++ if (div > 4) ++ div = 4; ++ ++ return clk_get_rate(clk->parent) / div; ++} ++ ++static int _clk_cpu_set_rate(struct clk *clk, unsigned long rate) ++{ ++ int div, reg; ++ unsigned long cctl = __raw_readl(MXC_CCM_CCTL); ++ ++ div = clk_get_rate(clk->parent) / rate; ++ ++ if (div > 4 || div < 1 || ((clk_get_rate(clk->parent) / div) != rate)) ++ return -EINVAL; ++ div--; ++ ++ reg = (cctl & ~MXC_CCM_CCTL_ARM_MASK) | ++ (div << MXC_CCM_CCTL_ARM_OFFSET); ++ __raw_writel(reg, MXC_CCM_CCTL); ++ ++ return 0; ++} ++ ++static unsigned long _clk_cpu_getrate(struct clk *clk) ++{ ++ unsigned long div; ++ unsigned long cctl = __raw_readl(MXC_CCM_CCTL); ++ unsigned long rate; ++ ++ div = (cctl & MXC_CCM_CCTL_ARM_MASK) >> MXC_CCM_CCTL_ARM_OFFSET; ++ ++ rate = clk_get_rate(clk->parent) / (div + 1); ++ ++ if (cctl & MXC_CCM_CCTL_ARM_SRC) { ++ rate *= 3; ++ rate /= 4; ++ } ++ return rate; ++} ++ ++static unsigned long _clk_ahb_getrate(struct clk *clk) ++{ ++ unsigned long div; ++ unsigned long cctl = __raw_readl(MXC_CCM_CCTL); ++ ++ div = (cctl & MXC_CCM_CCTL_AHB_MASK) >> MXC_CCM_CCTL_AHB_OFFSET; ++ ++ return clk_get_rate(clk->parent) / (div + 1); ++} ++ ++static void __iomem *pcdr_a[4] = { ++ MXC_CCM_PCDR0, MXC_CCM_PCDR1, MXC_CCM_PCDR2, MXC_CCM_PCDR3 ++}; ++ ++static unsigned long _clk_perclkx_getrate(struct clk *clk) ++{ ++ unsigned long perclk_pdf; ++ unsigned long pcdr; ++ ++ if (clk->id < 0 || clk->id > 15) ++ return 0; ++ ++ pcdr = __raw_readl(pcdr_a[clk->id >> 2]); ++ ++ perclk_pdf = ++ (pcdr >> ((clk->id & 3) << 3)) & MXC_CCM_PCDR1_PERDIV1_MASK; ++ ++ return clk_get_rate(clk->parent) / (perclk_pdf + 1); ++} ++ ++static unsigned long _clk_perclkx_round_rate(struct clk *clk, ++ unsigned long rate) ++{ ++ unsigned long div; ++ ++ div = clk_get_rate(clk->parent) / rate; ++ if (clk_get_rate(clk->parent) % rate) ++ div++; ++ ++ if (div > 64) ++ div = 64; ++ ++ return clk_get_rate(clk->parent) / div; ++} ++ ++static int _clk_perclkx_set_rate(struct clk *clk, unsigned long rate) ++{ ++ unsigned long reg; ++ unsigned long div; ++ ++ if (clk->id < 0 || clk->id > 15) ++ return -EINVAL; ++ ++ div = clk_get_rate(clk->parent) / rate; ++ printk(KERN_DEBUG "%s: perclk[%d] parent_rate=%lu rate=%lu div=%lu\n", ++ __FUNCTION__, clk->id, clk_get_rate(clk->parent), rate, div); ++ if (div > 64 || div < 1 || ((clk_get_rate(clk->parent) / div) != rate)) ++ return -EINVAL; ++ div--; ++ ++ reg = ++ __raw_readl(pcdr_a[clk->id >> 2]) & ~(MXC_CCM_PCDR1_PERDIV1_MASK << ++ ((clk->id & 3) << 3)); ++ reg |= div << ((clk->id & 3) << 3); ++ __raw_writel(reg, pcdr_a[clk->id >> 2]); ++ ++ return 0; ++} ++ ++static int _clk_perclkx_set_parent(struct clk *clk, struct clk *parent) ++{ ++ unsigned long mcr; ++ ++ if (clk->parent == parent) ++ return 0; ++ if (parent != &upll_clk && parent != &ahb_clk) ++ return -EINVAL; ++ ++ clk->parent = parent; ++ mcr = __raw_readl(MXC_CCM_MCR); ++ if (parent == &upll_clk) ++ mcr |= (1 << clk->id); ++ else ++ mcr &= ~(1 << clk->id); ++ ++ __raw_writel(mcr, MXC_CCM_MCR); ++ ++ return 0; ++} ++ ++static int _clk_perclkx_set_parent3(struct clk *clk, struct clk *parent) ++{ ++ unsigned long mcr = __raw_readl(MXC_CCM_MCR); ++ int bit; ++ ++ if (clk->parent == parent) ++ return 0; ++ if (parent != &upll_clk && parent != &ahb_clk && ++ parent != &upll_24610k_clk) ++ return -EINVAL; ++ ++ switch (clk->id) { ++ case 2: ++ bit = MXC_CCM_MCR_ESAI_CLK_MUX_OFFSET; ++ break; ++ case 13: ++ bit = MXC_CCM_MCR_SSI1_CLK_MUX_OFFSET; ++ break; ++ case 14: ++ bit = MXC_CCM_MCR_SSI2_CLK_MUX_OFFSET; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ if (parent == &upll_24610k_clk) { ++ mcr |= bit; ++ __raw_writel(mcr, MXC_CCM_MCR); ++ clk->parent = parent; ++ } else { ++ mcr &= ~bit; ++ __raw_writel(mcr, MXC_CCM_MCR); ++ return _clk_perclkx_set_parent(clk, parent); ++ } ++ ++ return 0; ++} ++ ++static unsigned long _clk_ipg_getrate(struct clk *clk) ++{ ++ return clk_get_rate(clk->parent) / 2; /* Always AHB / 2 */ ++} ++ ++/* Top-level clocks */ ++static unsigned long ckih_rate = OSC24M_CLK_FREQ; ++ ++static unsigned long clk_ckih_get_rate(struct clk *clk) ++{ ++ return ckih_rate; ++} ++ ++static unsigned long clk_ckil_get_rate(struct clk *clk) ++{ ++ return OSC32K_CLK_FREQ; ++} ++ ++static struct clk osc24m_clk = { ++ .get_rate = clk_ckih_get_rate, ++}; ++ ++static struct clk osc32k_clk = { ++ .get_rate = clk_ckil_get_rate, ++}; ++ ++static struct clk mpll_clk = { ++ .parent = &osc24m_clk, ++ .get_rate = _clk_pll_getrate, ++ .set_rate = _clk_pll_set_rate, ++}; ++ ++static struct clk upll_clk = { ++ .parent = &osc24m_clk, ++ .get_rate = _clk_pll_getrate, ++ .set_rate = _clk_pll_set_rate, ++ .enable = _clk_upll_enable, ++ .disable = _clk_upll_disable, ++}; ++ ++static unsigned long _clk_24610k_getrate(struct clk *clk) ++{ ++ long long rate = clk_get_rate(clk->parent) * 2461LL; ++ ++ do_div(rate, 24000); ++ ++ return rate; /* Always (UPLL * 24.61 / 240) */ ++} ++ ++static struct clk upll_24610k_clk = { ++ .parent = &upll_clk, ++ .get_rate = _clk_24610k_getrate, ++}; ++ ++/* Mid-level clocks */ ++ ++static struct clk cpu_clk = { /* ARM clock */ ++ .parent = &mpll_clk, ++ .set_rate = _clk_cpu_set_rate, ++ .get_rate = _clk_cpu_getrate, ++ .round_rate = _clk_cpu_round_rate, ++}; ++ ++static struct clk ahb_clk = { /* a.k.a. HCLK */ ++ .parent = &cpu_clk, ++ .get_rate = _clk_ahb_getrate, ++}; ++ ++static struct clk ipg_clk = { ++ .parent = &ahb_clk, ++ .get_rate = _clk_ipg_getrate, ++}; ++ ++/* Bottom-level clocks */ ++ ++struct clk usbotg_clk = { ++ .id = 0, ++ .parent = &ahb_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR0, ++ .enable_shift = MXC_CCM_CGCR0_HCLK_USBOTG_OFFSET, ++ .disable = _clk_disable, ++}; ++ ++struct clk rtic_clk = { ++ .id = 0, ++ .parent = &ahb_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR0, ++ .enable_shift = MXC_CCM_CGCR0_HCLK_RTIC_OFFSET, ++ .disable = _clk_disable, ++}; ++ ++struct clk emi_clk = { ++ .id = 0, ++ .parent = &ahb_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR0, ++ .enable_shift = MXC_CCM_CGCR0_HCLK_EMI_OFFSET, ++ .disable = _clk_disable, ++}; ++ ++struct clk brom_clk = { ++ .id = 0, ++ .parent = &ahb_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR0, ++ .enable_shift = MXC_CCM_CGCR0_HCLK_BROM_OFFSET, ++ .disable = _clk_disable, ++}; ++ ++static struct clk per_clk[] = { ++ { ++ .id = 0, ++ .parent = &ahb_clk, /* can be AHB or UPLL */ ++ .round_rate = _clk_perclkx_round_rate, ++ .set_rate = _clk_perclkx_set_rate, ++ .set_parent = _clk_perclkx_set_parent, ++ .get_rate = _clk_perclkx_getrate, ++ .enable = _perclk_enable, ++ .disable = _perclk_disable, ++ }, ++ { ++ .id = 1, ++ .parent = &ahb_clk, /* can be AHB or UPLL */ ++ .round_rate = _clk_perclkx_round_rate, ++ .set_rate = _clk_perclkx_set_rate, ++ .set_parent = _clk_perclkx_set_parent, ++ .get_rate = _clk_perclkx_getrate, ++ .enable = _perclk_enable, ++ .disable = _perclk_disable, ++ }, ++ { ++ .id = 2, ++ .parent = &ahb_clk, /* can be AHB or UPLL or 24.61MHz */ ++ .round_rate = _clk_perclkx_round_rate, ++ .set_rate = _clk_perclkx_set_rate, ++ .set_parent = _clk_perclkx_set_parent3, ++ .get_rate = _clk_perclkx_getrate, ++ .enable = _perclk_enable, ++ .disable = _perclk_disable, ++ }, ++ { ++ .id = 3, ++ .parent = &ahb_clk, /* can be AHB or UPLL */ ++ .round_rate = _clk_perclkx_round_rate, ++ .set_rate = _clk_perclkx_set_rate, ++ .set_parent = _clk_perclkx_set_parent, ++ .get_rate = _clk_perclkx_getrate, ++ .enable = _perclk_enable, ++ }, ++ { ++ .id = 4, ++ .parent = &ahb_clk, /* can be AHB or UPLL */ ++ .round_rate = _clk_perclkx_round_rate, ++ .set_rate = _clk_perclkx_set_rate, ++ .set_parent = _clk_perclkx_set_parent, ++ .get_rate = _clk_perclkx_getrate, ++ .enable = _perclk_enable, ++ .disable = _perclk_disable, ++ }, ++ { ++ .id = 5, ++ .parent = &upll_clk, /* can be AHB or UPLL */ ++ .round_rate = _clk_perclkx_round_rate, ++ .set_rate = _clk_perclkx_set_rate, ++ .set_parent = _clk_perclkx_set_parent, ++ .get_rate = _clk_perclkx_getrate, ++ .enable = _perclk_enable, ++ .disable = _perclk_disable, ++ }, ++ { ++ .id = 6, ++ .parent = &ahb_clk, /* can be AHB or UPLL */ ++ .round_rate = _clk_perclkx_round_rate, ++ .set_rate = _clk_perclkx_set_rate, ++ .set_parent = _clk_perclkx_set_parent, ++ .get_rate = _clk_perclkx_getrate, ++ .enable = _perclk_enable, ++ .disable = _perclk_disable, ++ }, ++ { ++ .id = 7, ++ .parent = &ahb_clk, /* can be AHB or UPLL */ ++ .round_rate = _clk_perclkx_round_rate, ++ .set_rate = _clk_perclkx_set_rate, ++ .set_parent = _clk_perclkx_set_parent, ++ .get_rate = _clk_perclkx_getrate, ++ .enable = _perclk_enable, ++ .disable = _perclk_disable, ++ }, ++ { ++ .id = 8, ++ .parent = &ahb_clk, /* can be AHB or UPLL */ ++ .round_rate = _clk_perclkx_round_rate, ++ .set_rate = _clk_perclkx_set_rate, ++ .set_parent = _clk_perclkx_set_parent, ++ .get_rate = _clk_perclkx_getrate, ++ .enable = _perclk_enable, ++ .disable = _perclk_disable, ++ }, ++ { ++ .id = 9, ++ .parent = &ahb_clk, /* can be AHB or UPLL */ ++ .round_rate = _clk_perclkx_round_rate, ++ .set_rate = _clk_perclkx_set_rate, ++ .set_parent = _clk_perclkx_set_parent, ++ .get_rate = _clk_perclkx_getrate, ++ .enable = _perclk_enable, ++ .disable = _perclk_disable, ++ }, ++ { ++ .id = 10, ++ .parent = &ahb_clk, /* can be AHB or UPLL */ ++ .round_rate = _clk_perclkx_round_rate, ++ .set_rate = _clk_perclkx_set_rate, ++ .set_parent = _clk_perclkx_set_parent, ++ .get_rate = _clk_perclkx_getrate, ++ .enable = _perclk_enable, ++ .disable = _perclk_disable, ++ }, ++ { ++ .id = 11, ++ .parent = &ahb_clk, /* can be AHB or UPLL */ ++ .round_rate = _clk_perclkx_round_rate, ++ .set_rate = _clk_perclkx_set_rate, ++ .set_parent = _clk_perclkx_set_parent, ++ .get_rate = _clk_perclkx_getrate, ++ .enable = _perclk_enable, ++ .disable = _perclk_disable, ++ }, ++ { ++ .id = 12, ++ .parent = &ahb_clk, /* can be AHB or UPLL */ ++ .round_rate = _clk_perclkx_round_rate, ++ .set_rate = _clk_perclkx_set_rate, ++ .set_parent = _clk_perclkx_set_parent, ++ .get_rate = _clk_perclkx_getrate, ++ .enable = _perclk_enable, ++ .disable = _perclk_disable, ++ }, ++ { ++ .id = 13, ++ .parent = &ahb_clk, /* can be AHB or UPLL or 24.61MHz */ ++ .round_rate = _clk_perclkx_round_rate, ++ .set_rate = _clk_perclkx_set_rate, ++ .set_parent = _clk_perclkx_set_parent3, ++ .get_rate = _clk_perclkx_getrate, ++ .enable = _perclk_enable, ++ .disable = _perclk_disable, ++ }, ++ { ++ .id = 14, ++ .parent = &ahb_clk, /* can be AHB or UPLL or 24.61MHz */ ++ .round_rate = _clk_perclkx_round_rate, ++ .set_rate = _clk_perclkx_set_rate, ++ .set_parent = _clk_perclkx_set_parent3, ++ .get_rate = _clk_perclkx_getrate, ++ .enable = _perclk_enable, ++ .disable = _perclk_disable, ++ }, ++ { ++ .id = 15, ++ .parent = &ahb_clk, /* can be AHB or UPLL */ ++ .round_rate = _clk_perclkx_round_rate, ++ .set_rate = _clk_perclkx_set_rate, ++ .set_parent = _clk_perclkx_set_parent, ++ .get_rate = _clk_perclkx_getrate, ++ .enable = _perclk_enable, ++ .disable = _perclk_disable, ++ }, ++}; ++ ++struct clk nfc_clk = { ++ .id = 0, ++ .parent = &per_clk[8], ++}; ++ ++struct clk audmux_clk = { ++ .id = 0, ++ .parent = &ipg_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR1, ++ .enable_shift = MXC_CCM_CGCR1_AUDMUX_OFFSET, ++ .disable = _clk_disable, ++}; ++ ++struct clk ata_clk[] = { ++ { ++ .id = 0, ++ .parent = &ipg_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR1, ++ .enable_shift = MXC_CCM_CGCR1_ATA_OFFSET, ++ .disable = _clk_disable, ++ .secondary = &ata_clk[1], ++ }, ++ { ++ .id = 0, ++ .parent = &ahb_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR0, ++ .enable_shift = MXC_CCM_CGCR0_HCLK_ATA_OFFSET, ++ .disable = _clk_disable, ++ }, ++}; ++ ++struct clk can_clk[] = { ++ { ++ .id = 0, ++ .parent = &ipg_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR1, ++ .enable_shift = MXC_CCM_CGCR1_CAN1_OFFSET, ++ .disable = _clk_disable, ++ }, ++ { ++ .id = 1, ++ .parent = &ipg_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR1, ++ .enable_shift = MXC_CCM_CGCR1_CAN2_OFFSET, ++ .disable = _clk_disable, ++ }, ++}; ++ ++struct clk csi_clk[] = { ++ { ++ .id = 0, ++ .parent = &per_clk[0], ++ .secondary = &csi_clk[1], ++ }, ++ { ++ .id = 0, ++ .parent = &ipg_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR1, ++ .enable_shift = MXC_CCM_CGCR1_CSI_OFFSET, ++ .disable = _clk_disable, ++ .secondary = &csi_clk[2], ++ }, ++ { ++ .id = 0, ++ .parent = &ahb_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR0, ++ .enable_shift = MXC_CCM_CGCR0_HCLK_CSI_OFFSET, ++ .disable = _clk_disable, ++ }, ++}; ++ ++struct clk cspi_clk[] = { ++ { ++ .id = 0, ++ .parent = &ipg_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR1, ++ .enable_shift = MXC_CCM_CGCR1_CSPI1_OFFSET, ++ .disable = _clk_disable, ++ }, ++ { ++ .id = 1, ++ .parent = &ipg_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR1, ++ .enable_shift = MXC_CCM_CGCR1_CSPI2_OFFSET, ++ .disable = _clk_disable, ++ }, ++ { ++ .id = 2, ++ .parent = &ipg_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR1, ++ .enable_shift = MXC_CCM_CGCR1_CSPI3_OFFSET, ++ .disable = _clk_disable, ++ }, ++}; ++ ++struct clk dryice_clk = { ++ .id = 0, ++ .parent = &ipg_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR1, ++ .enable_shift = MXC_CCM_CGCR1_DRYICE_OFFSET, ++ .disable = _clk_disable, ++}; ++ ++struct clk ect_clk = { ++ .id = 0, ++ .parent = &ipg_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR1, ++ .enable_shift = MXC_CCM_CGCR1_ECT_OFFSET, ++ .disable = _clk_disable, ++}; ++ ++struct clk epit1_clk[] = { ++ { ++ .id = 0, ++ .parent = &per_clk[1], ++ .secondary = &epit1_clk[1], ++ }, ++ { ++ .id = 0, ++ .parent = &ipg_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR1, ++ .enable_shift = MXC_CCM_CGCR1_EPIT1_OFFSET, ++ .disable = _clk_disable, ++ }, ++}; ++ ++struct clk epit2_clk[] = { ++ { ++ .id = 1, ++ .parent = &per_clk[1], ++ .secondary = &epit2_clk[1], ++ }, ++ { ++ .id = 1, ++ .parent = &ipg_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR1, ++ .enable_shift = MXC_CCM_CGCR1_EPIT2_OFFSET, ++ .disable = _clk_disable, ++ }, ++}; ++ ++struct clk esai_clk[] = { ++ { ++ .id = 0, ++ .parent = &per_clk[2], ++ .secondary = &esai_clk[1], ++ }, ++ { ++ .id = 0, ++ .parent = &ipg_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR1, ++ .enable_shift = MXC_CCM_CGCR1_ESAI_OFFSET, ++ .disable = _clk_disable, ++ .secondary = &esai_clk[2], ++ }, ++ { ++ .id = 0, ++ .parent = &ahb_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR0, ++ .enable_shift = MXC_CCM_CGCR0_HCLK_ESAI_OFFSET, ++ .disable = _clk_disable, ++ }, ++}; ++ ++struct clk esdhc1_clk[] = { ++ { ++ .id = 0, ++ .parent = &per_clk[3], ++ .secondary = &esdhc1_clk[1], ++ }, ++ { ++ .id = 0, ++ .parent = &ipg_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR1, ++ .enable_shift = MXC_CCM_CGCR1_ESDHC1_OFFSET, ++ .disable = _clk_disable, ++ .secondary = &esdhc1_clk[2], ++ }, ++ { ++ .id = 0, ++ .parent = &ahb_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR0, ++ .enable_shift = MXC_CCM_CGCR0_HCLK_ESDHC1_OFFSET, ++ .disable = _clk_disable, ++ }, ++}; ++ ++struct clk esdhc2_clk[] = { ++ { ++ .id = 1, ++ .parent = &per_clk[4], ++ .secondary = &esdhc2_clk[1], ++ }, ++ { ++ .id = 1, ++ .parent = &ipg_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR1, ++ .enable_shift = MXC_CCM_CGCR1_ESDHC2_OFFSET, ++ .disable = _clk_disable, ++ .secondary = &esdhc2_clk[2], ++ }, ++ { ++ .id = 1, ++ .parent = &ahb_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR0, ++ .enable_shift = MXC_CCM_CGCR0_HCLK_ESDHC2_OFFSET, ++ .disable = _clk_disable, ++ }, ++}; ++ ++struct clk fec_clk[] = { ++ { ++ .id = 0, ++ .parent = &ipg_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR1, ++ .enable_shift = MXC_CCM_CGCR1_FEC_OFFSET, ++ .disable = _clk_disable, ++ .secondary = &fec_clk[1], ++ }, ++ { ++ .id = 0, ++ .parent = &ahb_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR0, ++ .enable_shift = MXC_CCM_CGCR0_HCLK_FEC_OFFSET, ++ .disable = _clk_disable, ++ }, ++}; ++ ++struct clk gpio_clk[] = { ++ { ++ .id = 0, ++ .parent = &ipg_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR1, ++ .enable_shift = MXC_CCM_CGCR1_GPIO1_OFFSET, ++ .disable = _clk_disable, ++ }, ++ { ++ .id = 1, ++ .parent = &ipg_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR1, ++ .enable_shift = MXC_CCM_CGCR1_GPIO2_OFFSET, ++ .disable = _clk_disable, ++ }, ++ { ++ .id = 2, ++ .parent = &ipg_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR1, ++ .enable_shift = MXC_CCM_CGCR1_GPIO3_OFFSET, ++ .disable = _clk_disable, ++ }, ++}; ++ ++static struct clk gpt1_clk[] = { ++ { ++ .id = 0, ++ .parent = &per_clk[5], ++ .secondary = &gpt1_clk[1], ++ }, ++ { ++ .id = 0, ++ .parent = &ipg_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR1, ++ .enable_shift = MXC_CCM_CGCR1_GPT1_OFFSET, ++ .disable = _clk_disable, ++ }, ++}; ++ ++static struct clk gpt2_clk[] = { ++ { ++ .id = 1, ++ .parent = &per_clk[5], ++ .secondary = &gpt1_clk[1], ++ }, ++ { ++ .id = 1, ++ .parent = &ipg_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR1, ++ .enable_shift = MXC_CCM_CGCR1_GPT2_OFFSET, ++ .disable = _clk_disable, ++ }, ++}; ++ ++static struct clk gpt3_clk[] = { ++ { ++ .id = 2, ++ .parent = &per_clk[5], ++ .secondary = &gpt1_clk[1], ++ }, ++ { ++ .id = 2, ++ .parent = &ipg_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR1, ++ .enable_shift = MXC_CCM_CGCR1_GPT3_OFFSET, ++ .disable = _clk_disable, ++ }, ++}; ++ ++static struct clk gpt4_clk[] = { ++ { ++ .id = 3, ++ .parent = &per_clk[5], ++ .secondary = &gpt1_clk[1], ++ }, ++ { ++ .id = 3, ++ .parent = &ipg_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR1, ++ .enable_shift = MXC_CCM_CGCR1_GPT4_OFFSET, ++ .disable = _clk_disable, ++ }, ++}; ++ ++struct clk i2c_clk[] = { ++ { ++ .id = 0, ++ .parent = &per_clk[6], ++ }, ++ { ++ .id = 1, ++ .parent = &per_clk[6], ++ }, ++ { ++ .id = 2, ++ .parent = &per_clk[6], ++ }, ++}; ++ ++struct clk iim_clk = { ++ .id = 0, ++ .parent = &ipg_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR1, ++ .enable_shift = MXC_CCM_CGCR1_IIM_OFFSET, ++ .disable = _clk_disable, ++}; ++ ++struct clk iomuxc_clk = { ++ .id = 0, ++ .parent = &ipg_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR1, ++ .enable_shift = MXC_CCM_CGCR1_IOMUXC_OFFSET, ++ .disable = _clk_disable, ++}; ++ ++struct clk kpp_clk = { ++ .id = 0, ++ .parent = &ipg_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR1, ++ .enable_shift = MXC_CCM_CGCR1_KPP_OFFSET, ++ .disable = _clk_disable, ++}; ++ ++struct clk lcdc_clk[] = { ++ { ++ .id = 0, ++ .parent = &per_clk[7], ++ .secondary = &lcdc_clk[1], ++ }, ++ { ++ .id = 0, ++ .parent = &ipg_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR1, ++ .enable_shift = MXC_CCM_CGCR1_LCDC_OFFSET, ++ .disable = _clk_disable, ++ .secondary = &lcdc_clk[2], ++ }, ++ { ++ .id = 0, ++ .parent = &ahb_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR0, ++ .enable_shift = MXC_CCM_CGCR0_HCLK_LCDC_OFFSET, ++ .disable = _clk_disable, ++ }, ++}; ++ ++struct clk owire_clk[] = { ++ { ++ .id = 0, ++ .parent = &per_clk[9], ++ .secondary = &owire_clk[1], ++ }, ++ { ++ .id = 0, ++ .parent = &ipg_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR1, ++ .enable_shift = MXC_CCM_CGCR1_OWIRE_OFFSET, ++ .disable = _clk_disable, ++ }, ++}; ++ ++struct clk pwm1_clk[] = { ++ { ++ .id = 0, ++ .parent = &per_clk[10], ++ .secondary = &pwm1_clk[1], ++ }, ++ { ++ .id = 0, ++ .parent = &ipg_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR1, ++ .enable_shift = MXC_CCM_CGCR1_PWM1_OFFSET, ++ .disable = _clk_disable, ++ }, ++}; ++ ++struct clk pwm2_clk[] = { ++ { ++ .id = 1, ++ .parent = &per_clk[10], ++ .secondary = &pwm2_clk[1], ++ }, ++ { ++ .id = 1, ++ .parent = &ipg_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR2, ++ .enable_shift = MXC_CCM_CGCR2_PWM2_OFFSET, ++ .disable = _clk_disable, ++ }, ++}; ++ ++struct clk pwm3_clk[] = { ++ { ++ .id = 2, ++ .parent = &per_clk[10], ++ .secondary = &pwm3_clk[1], ++ }, ++ { ++ .id = 2, ++ .parent = &ipg_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR2, ++ .enable_shift = MXC_CCM_CGCR2_PWM3_OFFSET, ++ .disable = _clk_disable, ++ }, ++}; ++ ++struct clk pwm4_clk[] = { ++ { ++ .id = 3, ++ .parent = &per_clk[10], ++ .secondary = &pwm4_clk[1], ++ }, ++ { ++ .id = 3, ++ .parent = &ipg_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR2, ++ .enable_shift = MXC_CCM_CGCR2_PWM3_OFFSET, ++ .disable = _clk_disable, ++ }, ++}; ++ ++struct clk rngb_clk = { ++ .id = 0, ++ .parent = &ipg_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR2, ++ .enable_shift = MXC_CCM_CGCR2_RNGB_OFFSET, ++ .disable = _clk_disable, ++}; ++ ++struct clk scc_clk = { ++ .id = 0, ++ .parent = &ipg_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR2, ++ .enable_shift = MXC_CCM_CGCR2_SCC_OFFSET, ++ .disable = _clk_disable, ++}; ++ ++struct clk sdma_clk[] = { ++ { ++ .id = 0, ++ .parent = &ipg_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR2, ++ .enable_shift = MXC_CCM_CGCR2_SDMA_OFFSET, ++ .disable = _clk_disable, ++ .secondary = &sdma_clk[1], ++ }, ++ { ++ .id = 0, ++ .parent = &ahb_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR0, ++ .enable_shift = MXC_CCM_CGCR0_HCLK_SDMA_OFFSET, ++ .disable = _clk_disable, ++ }, ++}; ++ ++struct clk sim1_clk[] = { ++ { ++ .id = 0, ++ .parent = &per_clk[11], ++ .secondary = &sim1_clk[1], ++ }, ++ { ++ .id = 0, ++ .parent = &ipg_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR2, ++ .enable_shift = MXC_CCM_CGCR2_SIM1_OFFSET, ++ .disable = _clk_disable, ++ }, ++}; ++ ++struct clk sim2_clk[] = { ++ { ++ .id = 1, ++ .parent = &per_clk[12], ++ .secondary = &sim2_clk[1], ++ }, ++ { ++ .id = 1, ++ .parent = &ipg_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR2, ++ .enable_shift = MXC_CCM_CGCR2_SIM2_OFFSET, ++ .disable = _clk_disable, ++ }, ++}; ++ ++struct clk slcdc_clk[] = { ++ { ++ .id = 0, ++ .parent = &ipg_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR2, ++ .enable_shift = MXC_CCM_CGCR2_SLCDC_OFFSET, ++ .disable = _clk_disable, ++ .secondary = &slcdc_clk[1], ++ }, ++ { ++ .id = 0, ++ .parent = &ahb_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR0, ++ .enable_shift = MXC_CCM_CGCR0_HCLK_SLCDC_OFFSET, ++ .disable = _clk_disable, ++ }, ++}; ++ ++struct clk spba_clk = { ++ .id = 0, ++ .parent = &ipg_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR2, ++ .enable_shift = MXC_CCM_CGCR2_SPBA_OFFSET, ++ .disable = _clk_disable, ++}; ++ ++struct clk ssi1_clk[] = { ++ { ++ .id = 0, ++ .parent = &per_clk[13], ++ .secondary = &ssi1_clk[1], ++ }, ++ { ++ .id = 0, ++ .parent = &ipg_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR2, ++ .enable_shift = MXC_CCM_CGCR2_SSI1_OFFSET, ++ .disable = _clk_disable, ++ }, ++}; ++ ++struct clk ssi2_clk[] = { ++ { ++ .id = 1, ++ .parent = &per_clk[14], ++ .secondary = &ssi2_clk[1], ++ }, ++ { ++ .id = 1, ++ .parent = &ipg_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR2, ++ .enable_shift = MXC_CCM_CGCR2_SSI2_OFFSET, ++ .disable = _clk_disable, ++ }, ++}; ++ ++struct clk tchscrn_clk = { ++ .id = 0, ++ .parent = &ipg_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR2, ++ .enable_shift = MXC_CCM_CGCR2_TCHSCRN_OFFSET, ++ .disable = _clk_disable, ++}; ++ ++struct clk uart1_clk[] = { ++ { ++ .id = 0, ++ .parent = &per_clk[15], ++ .secondary = &uart1_clk[1], ++ }, ++ { ++ .id = 0, ++ .parent = &ipg_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR2, ++ .enable_shift = MXC_CCM_CGCR2_UART1_OFFSET, ++ .disable = _clk_disable, ++ }, ++}; ++ ++struct clk uart2_clk[] = { ++ { ++ .id = 1, ++ .parent = &per_clk[15], ++ .secondary = &uart2_clk[1], ++ }, ++ { ++ .id = 1, ++ .parent = &ipg_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR2, ++ .enable_shift = MXC_CCM_CGCR2_UART2_OFFSET, ++ .disable = _clk_disable, ++ }, ++}; ++ ++struct clk uart3_clk[] = { ++ { ++ .id = 2, ++ .parent = &per_clk[15], ++ .secondary = &uart3_clk[1], ++ }, ++ { ++ .id = 2, ++ .parent = &ipg_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR2, ++ .enable_shift = MXC_CCM_CGCR2_UART3_OFFSET, ++ .disable = _clk_disable, ++ }, ++}; ++ ++struct clk uart4_clk[] = { ++ { ++ .id = 3, ++ .parent = &per_clk[15], ++ .secondary = &uart4_clk[1], ++ }, ++ { ++ .id = 3, ++ .parent = &ipg_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR2, ++ .enable_shift = MXC_CCM_CGCR2_UART4_OFFSET, ++ .disable = _clk_disable, ++ }, ++}; ++ ++struct clk uart5_clk[] = { ++ { ++ .id = 4, ++ .parent = &per_clk[15], ++ .secondary = &uart5_clk[1], ++ }, ++ { ++ .id = 4, ++ .parent = &ipg_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR2, ++ .enable_shift = MXC_CCM_CGCR2_UART5_OFFSET, ++ .disable = _clk_disable, ++ }, ++}; ++ ++struct clk wdog_clk = { ++ .id = 0, ++ .parent = &ipg_clk, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_CGCR2, ++ .enable_shift = MXC_CCM_CGCR2_WDOG_OFFSET, ++ .disable = _clk_disable, ++}; ++ ++static unsigned long _clk_usb_round_rate(struct clk *clk, unsigned long rate) ++{ ++ unsigned long div; ++ ++ div = clk_get_rate(clk->parent) / rate; ++ if (clk_get_rate(clk->parent) % rate) ++ div++; ++ ++ if (div > 64) ++ return -EINVAL; ++ ++ return clk_get_rate(clk->parent) / div; ++} ++ ++static int _clk_usb_set_rate(struct clk *clk, unsigned long rate) ++{ ++ unsigned long reg; ++ unsigned long div; ++ ++ div = clk_get_rate(clk->parent) / rate; ++ ++ if (clk_get_rate(clk->parent) / div != rate) ++ return -EINVAL; ++ if (div > 64) ++ return -EINVAL; ++ ++ reg = __raw_readl(MXC_CCM_CCTL) & ~MXC_CCM_CCTL_USB_DIV_MASK; ++ reg |= (div - 1) << MXC_CCM_CCTL_USB_DIV_OFFSET; ++ __raw_writel(reg, MXC_CCM_MCR); ++ ++ return 0; ++} ++ ++static unsigned long _clk_usb_getrate(struct clk *clk) ++{ ++ unsigned long div = ++ __raw_readl(MXC_CCM_MCR) & MXC_CCM_CCTL_USB_DIV_MASK; ++ ++ div >>= MXC_CCM_CCTL_USB_DIV_OFFSET; ++ ++ return clk_get_rate(clk->parent) / (div + 1); ++} ++ ++static int _clk_usb_set_parent(struct clk *clk, struct clk *parent) ++{ ++ unsigned long mcr; ++ ++ if (clk->parent == parent) ++ return 0; ++ if (parent != &upll_clk && parent != &ahb_clk) ++ return -EINVAL; ++ ++ clk->parent = parent; ++ mcr = __raw_readl(MXC_CCM_MCR); ++ if (parent == &ahb_clk) ++ mcr |= (1 << MXC_CCM_MCR_USB_CLK_MUX_OFFSET); ++ else ++ mcr &= ~(1 << MXC_CCM_MCR_USB_CLK_MUX_OFFSET); ++ ++ __raw_writel(mcr, MXC_CCM_MCR); ++ ++ return 0; ++} ++ ++static struct clk usb_clk = { ++ .parent = &upll_clk, ++ .get_rate = _clk_usb_getrate, ++ .set_rate = _clk_usb_set_rate, ++ .round_rate = _clk_usb_round_rate, ++ .set_parent = _clk_usb_set_parent, ++}; ++ ++/* CLKO */ ++ ++static unsigned long _clk_clko_round_rate(struct clk *clk, unsigned long rate) ++{ ++ unsigned long div; ++ ++ div = clk_get_rate(clk->parent) / rate; ++ if (clk_get_rate(clk->parent) % rate) ++ div++; ++ ++ if (div > 64) ++ return -EINVAL; ++ ++ return clk_get_rate(clk->parent) / div; ++} ++ ++static int _clk_clko_set_rate(struct clk *clk, unsigned long rate) ++{ ++ unsigned long reg; ++ unsigned long div; ++ ++ div = clk_get_rate(clk->parent) / rate; ++ ++ if ((clk_get_rate(clk->parent) / div) != rate) ++ return -EINVAL; ++ if (div > 64) ++ return -EINVAL; ++ ++ reg = __raw_readl(MXC_CCM_MCR) & ~MXC_CCM_MCR_CLKO_DIV_MASK; ++ reg |= (div - 1) << MXC_CCM_MCR_CLKO_DIV_OFFSET; ++ __raw_writel(reg, MXC_CCM_MCR); ++ ++ return 0; ++} ++ ++static unsigned long _clk_clko_getrate(struct clk *clk) ++{ ++ unsigned long div = __raw_readl(MXC_CCM_MCR); ++ ++ div &= MXC_CCM_MCR_CLKO_DIV_MASK; ++ div >>= MXC_CCM_MCR_CLKO_DIV_OFFSET; ++ ++ return clk_get_rate(clk->parent) / (div + 1); ++} ++ ++static struct clk *clko_sources[] = { ++ &osc32k_clk, /* 0x0 */ ++ &osc24m_clk, /* 0x1 */ ++ &cpu_clk, /* 0x2 */ ++ &ahb_clk, /* 0x3 */ ++ &ipg_clk, /* 0x4 */ ++ NULL, /* 0x5 */ ++ NULL, /* 0x6 */ ++ NULL, /* 0x7 */ ++ NULL, /* 0x8 */ ++ NULL, /* 0x9 */ ++ &per_clk[0], /* 0xA */ ++ &per_clk[2], /* 0xB */ ++ &per_clk[13], /* 0xC */ ++ &per_clk[14], /* 0xD */ ++ &usb_clk, /* 0xE */ ++ NULL, /* 0xF */ ++}; ++ ++#define NR_CLKO_SOURCES (sizeof(clko_sources) / sizeof(struct clk *)) ++ ++static int _clk_clko_set_parent(struct clk *clk, struct clk *parent) ++{ ++ unsigned long reg; ++ struct clk **src; ++ int i; ++ ++ if (clk->parent == parent) ++ return 0; ++ for (i = 0, src = clko_sources; i < NR_CLKO_SOURCES; i++, src++) ++ if (*src == parent) ++ break; ++ ++ if (i == NR_CLKO_SOURCES) ++ return -EINVAL; ++ ++ clk->parent = parent; ++ ++ reg = __raw_readl(MXC_CCM_MCR) & ~MXC_CCM_MCR_CLKO_SEL_MASK; ++ reg |= i << MXC_CCM_MCR_CLKO_SEL_OFFSET; ++ __raw_writel(reg, MXC_CCM_MCR); ++ ++ return 0; ++} ++ ++static struct clk clko_clk = { ++ .set_rate = _clk_clko_set_rate, ++ .round_rate = _clk_clko_round_rate, ++ .set_parent = _clk_clko_set_parent, ++ .get_rate = _clk_clko_getrate, ++ .enable = _clk_enable, ++ .enable_reg = MXC_CCM_MCR, ++ .enable_shift = MXC_CCM_MCR_CLKO_EN_OFFSET, ++ .disable = _clk_disable, ++}; ++ ++#ifdef CONFIG_COMMON_CLKDEV ++#define _REGISTER_CLOCK(d, n, c) \ ++ { \ ++ .dev_id = d, \ ++ .con_id = n, \ ++ .clk = &c, \ ++ }, ++ ++static struct clk_lookup lookups[] = { ++ _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk) ++ _REGISTER_CLOCK(NULL, "audmux", audmux_clk) ++ _REGISTER_CLOCK(NULL, "ata", ata_clk[0]) ++ _REGISTER_CLOCK(NULL, "can", can_clk[0]) ++ _REGISTER_CLOCK(NULL, "csi", csi_clk[0]) ++ _REGISTER_CLOCK(NULL, "cspi.0", cspi_clk[0]) ++ _REGISTER_CLOCK(NULL, "cspi.1", cspi_clk[1]) ++ _REGISTER_CLOCK(NULL, "cspi.2", cspi_clk[2]) ++ _REGISTER_CLOCK(NULL, "dryice", dryice_clk) ++ _REGISTER_CLOCK(NULL, "ect", ect_clk) ++ _REGISTER_CLOCK(NULL, "epit1", epit1_clk[0]) ++ _REGISTER_CLOCK(NULL, "epit2", epit2_clk[0]) ++ _REGISTER_CLOCK(NULL, "esai", esai_clk[0]) ++ _REGISTER_CLOCK("mxc-mmc.0", NULL, esdhc1_clk[0]) ++ _REGISTER_CLOCK("mxc-mmc.1", NULL, esdhc2_clk[0]) ++ _REGISTER_CLOCK("fec.0", NULL, fec_clk[0]) ++ _REGISTER_CLOCK(NULL, "gpio0", gpio_clk[0]) ++ _REGISTER_CLOCK(NULL, "gpio1", gpio_clk[1]) ++ _REGISTER_CLOCK(NULL, "gpio2", gpio_clk[2]) ++ _REGISTER_CLOCK(NULL, "gpt1", gpt1_clk[0]) ++ _REGISTER_CLOCK(NULL, "gpt2", gpt2_clk[0]) ++ _REGISTER_CLOCK(NULL, "gpt3", gpt3_clk[0]) ++ _REGISTER_CLOCK(NULL, "gpt4", gpt4_clk[0]) ++ _REGISTER_CLOCK("imx-i2c.0", NULL, i2c_clk[0]) ++ _REGISTER_CLOCK("imx-i2c.1", NULL, i2c_clk[1]) ++ _REGISTER_CLOCK("imx-i2c.2", NULL, i2c_clk[2]) ++ _REGISTER_CLOCK(NULL, "iim", iim_clk) ++ _REGISTER_CLOCK(NULL, "iomuxc", iomuxc_clk) ++ _REGISTER_CLOCK(NULL, "kpp", kpp_clk) ++ _REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk[0]) ++ _REGISTER_CLOCK(NULL, "owire", owire_clk[0]) ++ _REGISTER_CLOCK("mxc_pwm.0", NULL, pwm1_clk[0]) ++ _REGISTER_CLOCK("mxc_pwm.1", NULL, pwm2_clk[0]) ++ _REGISTER_CLOCK("mxc_pwm.2", NULL, pwm3_clk[0]) ++ _REGISTER_CLOCK("mxc_pwm.3", NULL, pwm4_clk[0]) ++ _REGISTER_CLOCK(NULL, "rngb", rngb_clk) ++ _REGISTER_CLOCK(NULL, "scc", scc_clk) ++ _REGISTER_CLOCK(NULL, "sdma", sdma_clk[0]) ++ _REGISTER_CLOCK(NULL, "sim1", sim1_clk[0]) ++ _REGISTER_CLOCK(NULL, "sim2", sim2_clk[0]) ++ _REGISTER_CLOCK(NULL, "slcdc", slcdc_clk[0]) ++ _REGISTER_CLOCK(NULL, "spba", spba_clk) ++ _REGISTER_CLOCK(NULL, "ssi1", ssi1_clk[0]) ++ _REGISTER_CLOCK(NULL, "ssi2", ssi2_clk[0]) ++ _REGISTER_CLOCK(NULL, "tchscrn", tchscrn_clk) ++ _REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk[0]) ++ _REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk[0]) ++ _REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk[0]) ++ _REGISTER_CLOCK("imx-uart.3", NULL, uart4_clk[0]) ++ _REGISTER_CLOCK("imx-uart.4", NULL, uart5_clk[0]) ++ _REGISTER_CLOCK(NULL, "wdog", wdog_clk) ++ _REGISTER_CLOCK(NULL, "usb", usb_clk) ++ _REGISTER_CLOCK(NULL, "clko", clko_clk) ++ _REGISTER_CLOCK(NULL, "brom", brom_clk) ++}; ++#else ++static struct clk *mxc_clks[] = { ++ &osc24m_clk, ++ &osc32k_clk, ++ &mpll_clk, ++ &upll_clk, ++ &cpu_clk, ++ &ahb_clk, ++ &ipg_clk, ++ &per_clk[0], ++ &per_clk[1], ++ &per_clk[2], ++ &per_clk[3], ++ &per_clk[4], ++ &per_clk[5], ++ &per_clk[6], ++ &per_clk[7], ++ &per_clk[8], ++ &per_clk[9], ++ &per_clk[10], ++ &per_clk[11], ++ &per_clk[12], ++ &per_clk[13], ++ &per_clk[14], ++ &per_clk[15], ++ &nfc_clk, ++ &audmux_clk, ++ &ata_clk[0], ++ &ata_clk[1], ++ &can_clk[0], ++ &can_clk[1], ++ &csi_clk[0], ++ &csi_clk[1], ++ &csi_clk[2], ++ &cspi_clk[0], ++ &cspi_clk[1], ++ &cspi_clk[2], ++ &dryice_clk, ++ &ect_clk, ++ &epit1_clk[0], ++ &epit1_clk[1], ++ &epit2_clk[0], ++ &epit2_clk[1], ++ &esai_clk[0], ++ &esai_clk[1], ++ &esai_clk[2], ++ &esdhc1_clk[0], ++ &esdhc1_clk[1], ++ &esdhc1_clk[2], ++ &esdhc2_clk[0], ++ &esdhc2_clk[1], ++ &esdhc2_clk[2], ++ &fec_clk[0], ++ &fec_clk[1], ++ &gpio_clk[0], ++ &gpio_clk[1], ++ &gpio_clk[2], ++ &gpt1_clk[0], ++ &gpt1_clk[1], ++ &gpt2_clk[0], ++ &gpt2_clk[1], ++ &gpt3_clk[0], ++ &gpt3_clk[1], ++ &gpt4_clk[0], ++ &gpt4_clk[1], ++ &i2c_clk[0], ++ &i2c_clk[1], ++ &i2c_clk[2], ++ &iim_clk, ++ &iomuxc_clk, ++ &kpp_clk, ++ &lcdc_clk[0], ++ &lcdc_clk[1], ++ &lcdc_clk[2], ++ &owire_clk[0], ++ &owire_clk[1], ++ &pwm1_clk[0], ++ &pwm1_clk[1], ++ &pwm2_clk[0], ++ &pwm2_clk[1], ++ &pwm3_clk[0], ++ &pwm3_clk[1], ++ &pwm4_clk[0], ++ &pwm4_clk[1], ++ &rngb_clk, ++ &scc_clk, ++ &sdma_clk[0], ++ &sdma_clk[1], ++ &sim1_clk[0], ++ &sim1_clk[1], ++ &sim2_clk[0], ++ &sim2_clk[1], ++ &slcdc_clk[0], ++ &slcdc_clk[1], ++ &spba_clk, ++ &ssi1_clk[0], ++ &ssi1_clk[1], ++ &ssi2_clk[0], ++ &ssi2_clk[1], ++ &tchscrn_clk, ++ &uart1_clk[0], ++ &uart1_clk[1], ++ &uart2_clk[0], ++ &uart2_clk[1], ++ &uart3_clk[0], ++ &uart3_clk[1], ++ &uart4_clk[0], ++ &uart4_clk[1], ++ &uart5_clk[0], ++ &uart5_clk[1], ++ &wdog_clk, ++ &usb_clk, ++ &clko_clk, ++}; ++#endif ++ ++int __init mx25_clocks_init(unsigned long fref) ++{ ++ int i; ++ ++#ifdef CONFIG_COMMON_CLKDEV ++ for (i = 0; i < ARRAY_SIZE(lookups); i++) { ++ printk(KERN_DEBUG "Registering clock '%s' '%s'\n", ++ lookups[i].dev_id ? lookups[i].dev_id : "", ++ lookups[i].con_id ? lookups[i].con_id : ""); ++ clkdev_add(&lookups[i]); ++ } ++#else ++ struct clk **clkp; ++ for (clkp = mxc_clks; clkp < mxc_clks + ARRAY_SIZE(mxc_clks); clkp++) ++ clk_register(*clkp); ++#endif ++ ckih_rate = fref; ++#ifndef CONFIG_DEBUG_LL ++ /* Turn off all possible clocks */ ++ __raw_writel((1 << MXC_CCM_CGCR0_HCLK_EMI_OFFSET), MXC_CCM_CGCR0); ++ ++ __raw_writel((1 << MXC_CCM_CGCR1_GPT1_OFFSET) | ++ (1 << MXC_CCM_CGCR1_IIM_OFFSET), MXC_CCM_CGCR1); ++ __raw_writel(1 << MXC_CCM_CGCR2_SCC_OFFSET, MXC_CCM_CGCR2); ++#endif ++#if 1 ++ /* Set all perclk sources to upll */ ++ for (i = 0; i < ARRAY_SIZE(per_clk); i++) { ++ int ret; ++ unsigned long rate = per_clk[i].get_rate(&per_clk[i]); ++ ++#ifdef CONFIG_DEBUG_LL ++ if (i == 15) { ++ printk(KERN_DEBUG "skipping per_clk[%d] rate=%lu\n", i, rate); ++ continue; ++ } ++#endif ++ { ++ unsigned long new_rate; ++ ++ per_clk[i].set_parent(&per_clk[i], &upll_clk); ++ new_rate = per_clk[i].round_rate(&per_clk[i], rate); ++ if ((ret = per_clk[i].set_rate(&per_clk[i], new_rate)) < 0) { ++ printk(KERN_ERR "Error %d setting clk[%d] rate to %lu\n", ++ ret, i, new_rate); ++ } ++ } ++ } ++#endif ++ /* the NFC clock must be derived from AHB clock */ ++ clk_set_parent(&per_clk[8], &ahb_clk); ++ clk_set_rate(&per_clk[8], clk_get_rate(&ahb_clk) / 6); ++ ++ /* This will propagate to all children and init all the clock rates */ ++#if 1 ++ clk_enable(&uart1_clk[0]); ++#endif ++ clk_enable(&emi_clk); ++ clk_enable(&gpio_clk[0]); ++ clk_enable(&gpio_clk[1]); ++ clk_enable(&gpio_clk[2]); ++ clk_enable(&iim_clk); ++ clk_enable(&gpt1_clk[0]); ++ clk_enable(&iomuxc_clk); ++ clk_enable(&scc_clk); ++ ++ pr_info("Clock input source is %ld\n", clk_get_rate(&osc24m_clk)); ++ ++ pr_info("CPU: %lu.%03luMHz\n", ++ clk_get_rate(&cpu_clk) / 1000000, clk_get_rate(&cpu_clk) / 1000 % 1000); ++ pr_info("AHB: %lu.%03luMHz\n", ++ clk_get_rate(&ahb_clk) / 1000000, clk_get_rate(&ahb_clk) / 1000 % 1000); ++ pr_info("MPLL: %lu.%03luMHz\n", ++ clk_get_rate(&mpll_clk) / 1000000, clk_get_rate(&mpll_clk) / 1000 % 1000); ++ pr_info("UPLL: %lu.%03luMHz\n", ++ clk_get_rate(&upll_clk) / 1000000, clk_get_rate(&upll_clk) / 1000 % 1000); ++ clk_set_rate(&mpll_clk, clk_get_rate(&mpll_clk)); ++ clk_set_rate(&upll_clk, clk_get_rate(&upll_clk)); ++ ++ mxc_timer_init(&gpt1_clk[0]); ++ return 0; ++} +diff -urNp linux-2.6.30-rc4/arch/arm/mach-mx2/clock_imx27.c linux-2.6.30-rc4-karo/arch/arm/mach-mx2/clock_imx27.c +--- linux-2.6.30-rc4/arch/arm/mach-mx2/clock_imx27.c 2009-05-13 09:46:19.000000000 +0200 ++++ linux-2.6.30-rc4-karo/arch/arm/mach-mx2/clock_imx27.c 2009-06-02 17:05:26.000000000 +0200 +@@ -621,7 +621,7 @@ DEFINE_CLOCK1(csi_clk, 0, 0, 0, + .clk = &c, \ + }, + +-static struct clk_lookup lookups[] __initdata = { ++static struct clk_lookup lookups[] = { + _REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk) + _REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk) + _REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk) +diff -urNp linux-2.6.30-rc4/arch/arm/mach-mx2/cpu_imx25.c linux-2.6.30-rc4-karo/arch/arm/mach-mx2/cpu_imx25.c +--- linux-2.6.30-rc4/arch/arm/mach-mx2/cpu_imx25.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30-rc4-karo/arch/arm/mach-mx2/cpu_imx25.c 2009-06-02 17:05:27.000000000 +0200 +@@ -0,0 +1,65 @@ ++/* ++ * arch/arm/mach-mx2/cpu_mx25.c ++ * ++ * Copyright 2009 Lothar Wassmann <LW@KARO-electronics.de> ++ * derived from: cpu_mx27.c ++ * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved. ++ * ++ * 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., 51 Franklin Street, Fifth Floor, Boston, ++ * MA 02110-1301, USA. ++ */ ++ ++/* ++ * i.MX25 specific CPU detection code ++ */ ++ ++#include <linux/io.h> ++#include <linux/module.h> ++ ++#include <mach/hardware.h> ++ ++static int cpu_silicon_rev = -1; ++static int cpu_partnumber; ++ ++#define IIM_PREV_REG IO_ADDRESS(IIM_BASE_ADDR + 0x20) ++#define IIM_SREV_REG IO_ADDRESS(IIM_BASE_ADDR + 0x24) ++ ++static void query_silicon_parameter(void) ++{ ++ cpu_partnumber = __raw_readl(IIM_PREV_REG) >> 3; ++ cpu_silicon_rev = __raw_readl(IIM_SREV_REG); ++ ++ printk(KERN_DEBUG "CPU rev: 0x%02x chip_rev: 0x%02x\n", ++ cpu_partnumber, cpu_silicon_rev); ++ if (WARN_ON(cpu_partnumber != 0x1f)) { ++ printk(KERN_WARNING "Unsupported CPU rev: 0x%02x\n", cpu_partnumber); ++ } ++} ++ ++/* ++ * Returns: ++ * the silicon revision of the cpu ++ * -EINVAL - not a mx25 ++ */ ++int mx25_revision(void) ++{ ++ if (cpu_silicon_rev == -1) ++ query_silicon_parameter(); ++ ++ if (cpu_partnumber != 0x1f) ++ return -EINVAL; ++ ++ return cpu_silicon_rev; ++} ++EXPORT_SYMBOL(mx25_revision); +diff -urNp linux-2.6.30-rc4/arch/arm/mach-mx2/crm_regs_mx25.h linux-2.6.30-rc4-karo/arch/arm/mach-mx2/crm_regs_mx25.h +--- linux-2.6.30-rc4/arch/arm/mach-mx2/crm_regs_mx25.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30-rc4-karo/arch/arm/mach-mx2/crm_regs_mx25.h 2009-06-02 17:05:27.000000000 +0200 +@@ -0,0 +1,190 @@ ++/* ++ * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved. ++ */ ++ ++/* ++ * The code contained herein is licensed under the GNU General Public ++ * License. You may obtain a copy of the GNU General Public License ++ * Version 2 or later at the following locations: ++ * ++ * http://www.opensource.org/licenses/gpl-license.html ++ * http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++#ifndef __ARCH_ARM_MACH_MX25_CRM_REGS_H__ ++#define __ARCH_ARM_MACH_MX25_CRM_REGS_H__ ++ ++#include <mach/hardware.h> ++ ++/* Register offsets */ ++#define MXC_CCM_MPCTL (IO_ADDRESS(CCM_BASE_ADDR) + 0x00) ++#define MXC_CCM_UPCTL (IO_ADDRESS(CCM_BASE_ADDR) + 0x04) ++#define MXC_CCM_CCTL (IO_ADDRESS(CCM_BASE_ADDR) + 0x08) ++#define MXC_CCM_CGCR0 (IO_ADDRESS(CCM_BASE_ADDR) + 0x0C) ++#define MXC_CCM_CGCR1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x10) ++#define MXC_CCM_CGCR2 (IO_ADDRESS(CCM_BASE_ADDR) + 0x14) ++#define MXC_CCM_PCDR0 (IO_ADDRESS(CCM_BASE_ADDR) + 0x18) ++#define MXC_CCM_PCDR1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x1C) ++#define MXC_CCM_PCDR2 (IO_ADDRESS(CCM_BASE_ADDR) + 0x20) ++#define MXC_CCM_PCDR3 (IO_ADDRESS(CCM_BASE_ADDR) + 0x24) ++#define MXC_CCM_RCSR (IO_ADDRESS(CCM_BASE_ADDR) + 0x28) ++#define MXC_CCM_CRDR (IO_ADDRESS(CCM_BASE_ADDR) + 0x2C) ++#define MXC_CCM_DCVR0 (IO_ADDRESS(CCM_BASE_ADDR) + 0x30) ++#define MXC_CCM_DCVR1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x34) ++#define MXC_CCM_DCVR2 (IO_ADDRESS(CCM_BASE_ADDR) + 0x38) ++#define MXC_CCM_DCVR3 (IO_ADDRESS(CCM_BASE_ADDR) + 0x3C) ++#define MXC_CCM_LTR0 (IO_ADDRESS(CCM_BASE_ADDR) + 0x40) ++#define MXC_CCM_LTR1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x44) ++#define MXC_CCM_LTR2 (IO_ADDRESS(CCM_BASE_ADDR) + 0x48) ++#define MXC_CCM_LTR3 (IO_ADDRESS(CCM_BASE_ADDR) + 0x4C) ++#define MXC_CCM_LTBR0 (IO_ADDRESS(CCM_BASE_ADDR) + 0x50) ++#define MXC_CCM_LTBR1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x54) ++#define MXC_CCM_PMCR0 (IO_ADDRESS(CCM_BASE_ADDR) + 0x58) ++#define MXC_CCM_PMCR1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x5C) ++#define MXC_CCM_PMCR2 (IO_ADDRESS(CCM_BASE_ADDR) + 0x60) ++#define MXC_CCM_MCR (IO_ADDRESS(CCM_BASE_ADDR) + 0x64) ++ ++#define MXC_CCM_MPCTL_BRMO (1 << 31) ++#define MXC_CCM_MPCTL_PD_OFFSET 26 ++#define MXC_CCM_MPCTL_PD_MASK (0xf << 26) ++#define MXC_CCM_MPCTL_MFD_OFFSET 16 ++#define MXC_CCM_MPCTL_MFD_MASK (0x3ff << 16) ++#define MXC_CCM_MPCTL_MFI_OFFSET 10 ++#define MXC_CCM_MPCTL_MFI_MASK (0xf << 10) ++#define MXC_CCM_MPCTL_MFN_OFFSET 0 ++#define MXC_CCM_MPCTL_MFN_MASK 0x3ff ++#define MXC_CCM_MPCTL_LF (1 << 15) ++ ++#define MXC_CCM_UPCTL_BRMO (1 << 31) ++#define MXC_CCM_UPCTL_PD_OFFSET 26 ++#define MXC_CCM_UPCTL_PD_MASK (0xf << 26) ++#define MXC_CCM_UPCTL_MFD_OFFSET 16 ++#define MXC_CCM_UPCTL_MFD_MASK (0x3ff << 16) ++#define MXC_CCM_UPCTL_MFI_OFFSET 10 ++#define MXC_CCM_UPCTL_MFI_MASK (0xf << 10) ++#define MXC_CCM_UPCTL_MFN_OFFSET 0 ++#define MXC_CCM_UPCTL_MFN_MASK 0x3ff ++#define MXC_CCM_UPCTL_LF (1 << 15) ++ ++#define MXC_CCM_CCTL_ARM_OFFSET 30 ++#define MXC_CCM_CCTL_ARM_MASK (0x3 << 30) ++#define MXC_CCM_CCTL_AHB_OFFSET 28 ++#define MXC_CCM_CCTL_AHB_MASK (0x3 << 28) ++#define MXC_CCM_CCTL_MPLL_RST (1 << 27) ++#define MXC_CCM_CCTL_UPLL_RST (1 << 26) ++#define MXC_CCM_CCTL_LP_CTL_OFFSET 24 ++#define MXC_CCM_CCTL_LP_CTL_MASK (0x3 << 24) ++#define MXC_CCM_CCTL_LP_MODE_RUN (0x0 << 24) ++#define MXC_CCM_CCTL_LP_MODE_WAIT (0x1 << 24) ++#define MXC_CCM_CCTL_LP_MODE_DOZE (0x2 << 24) ++#define MXC_CCM_CCTL_LP_MODE_STOP (0x3 << 24) ++#define MXC_CCM_CCTL_UPLL_DISABLE (1 << 23) ++#define MXC_CCM_CCTL_MPLL_BYPASS (1 << 22) ++#define MXC_CCM_CCTL_USB_DIV_OFFSET 16 ++#define MXC_CCM_CCTL_USB_DIV_MASK (0x3 << 16) ++#define MXC_CCM_CCTL_CG_CTRL (1 << 15) ++#define MXC_CCM_CCTL_ARM_SRC (1 << 14) ++ ++#define MXC_CCM_CGCR0_HCLK_ATA_OFFSET 16 ++#define MXC_CCM_CGCR0_HCLK_BROM_OFFSET 17 ++#define MXC_CCM_CGCR0_HCLK_CSI_OFFSET 18 ++#define MXC_CCM_CGCR0_HCLK_EMI_OFFSET 19 ++#define MXC_CCM_CGCR0_HCLK_ESAI_OFFSET 20 ++#define MXC_CCM_CGCR0_HCLK_ESDHC1_OFFSET 21 ++#define MXC_CCM_CGCR0_HCLK_ESDHC2_OFFSET 22 ++#define MXC_CCM_CGCR0_HCLK_FEC_OFFSET 23 ++#define MXC_CCM_CGCR0_HCLK_LCDC_OFFSET 24 ++#define MXC_CCM_CGCR0_HCLK_RTIC_OFFSET 25 ++#define MXC_CCM_CGCR0_HCLK_SDMA_OFFSET 26 ++#define MXC_CCM_CGCR0_HCLK_SLCDC_OFFSET 27 ++#define MXC_CCM_CGCR0_HCLK_USBOTG_OFFSET 28 ++ ++#define MXC_CCM_CGCR0_PER_CSI_OFFSET 0 ++#define MXC_CCM_CGCR0_PER_EPIT_OFFSET 1 ++#define MXC_CCM_CGCR0_PER_ESAI_OFFSET 2 ++#define MXC_CCM_CGCR0_PER_ESDHC1_OFFSET 3 ++#define MXC_CCM_CGCR0_PER_ESDHC2_OFFSET 4 ++#define MXC_CCM_CGCR0_PER_GPT_OFFSET 5 ++#define MXC_CCM_CGCR0_PER_I2C_OFFSET 6 ++#define MXC_CCM_CGCR0_PER_LCDC_OFFSET 7 ++#define MXC_CCM_CGCR0_PER_NFC_OFFSET 8 ++#define MXC_CCM_CGCR0_PER_OWIRE_OFFSET 9 ++#define MXC_CCM_CGCR0_PER_PWM_OFFSET 10 ++#define MXC_CCM_CGCR0_PER_SIM1_OFFSET 11 ++#define MXC_CCM_CGCR0_PER_SIM2_OFFSET 12 ++#define MXC_CCM_CGCR0_PER_SSI1_OFFSET 13 ++#define MXC_CCM_CGCR0_PER_SSI2_OFFSET 14 ++#define MXC_CCM_CGCR0_PER_UART_OFFSET 15 ++ ++#define MXC_CCM_CGCR1_AUDMUX_OFFSET 0 ++#define MXC_CCM_CGCR1_ATA_OFFSET 1 ++#define MXC_CCM_CGCR1_CAN1_OFFSET 2 ++#define MXC_CCM_CGCR1_CAN2_OFFSET 3 ++#define MXC_CCM_CGCR1_CSI_OFFSET 4 ++#define MXC_CCM_CGCR1_CSPI1_OFFSET 5 ++#define MXC_CCM_CGCR1_CSPI2_OFFSET 6 ++#define MXC_CCM_CGCR1_CSPI3_OFFSET 7 ++#define MXC_CCM_CGCR1_DRYICE_OFFSET 8 ++#define MXC_CCM_CGCR1_ECT_OFFSET 9 ++#define MXC_CCM_CGCR1_EPIT1_OFFSET 10 ++#define MXC_CCM_CGCR1_EPIT2_OFFSET 11 ++#define MXC_CCM_CGCR1_ESAI_OFFSET 12 ++#define MXC_CCM_CGCR1_ESDHC1_OFFSET 13 ++#define MXC_CCM_CGCR1_ESDHC2_OFFSET 14 ++#define MXC_CCM_CGCR1_FEC_OFFSET 15 ++#define MXC_CCM_CGCR1_GPIO1_OFFSET 16 ++#define MXC_CCM_CGCR1_GPIO2_OFFSET 17 ++#define MXC_CCM_CGCR1_GPIO3_OFFSET 18 ++#define MXC_CCM_CGCR1_GPT1_OFFSET 19 ++#define MXC_CCM_CGCR1_GPT2_OFFSET 20 ++#define MXC_CCM_CGCR1_GPT3_OFFSET 21 ++#define MXC_CCM_CGCR1_GPT4_OFFSET 22 ++#define MXC_CCM_CGCR1_I2C1_OFFSET 23 ++#define MXC_CCM_CGCR1_I2C2_OFFSET 24 ++#define MXC_CCM_CGCR1_I2C3_OFFSET 25 ++#define MXC_CCM_CGCR1_IIM_OFFSET 26 ++#define MXC_CCM_CGCR1_IOMUXC_OFFSET 27 ++#define MXC_CCM_CGCR1_KPP_OFFSET 28 ++#define MXC_CCM_CGCR1_LCDC_OFFSET 29 ++#define MXC_CCM_CGCR1_OWIRE_OFFSET 30 ++#define MXC_CCM_CGCR1_PWM1_OFFSET 31 ++ ++#define MXC_CCM_CGCR2_PWM2_OFFSET (32-32) ++#define MXC_CCM_CGCR2_PWM3_OFFSET (33-32) ++#define MXC_CCM_CGCR2_PWM4_OFFSET (34-32) ++#define MXC_CCM_CGCR2_RNGB_OFFSET (35-32) ++#define MXC_CCM_CGCR2_RTIC_OFFSET (36-32) ++#define MXC_CCM_CGCR2_SCC_OFFSET (37-32) ++#define MXC_CCM_CGCR2_SDMA_OFFSET (38-32) ++#define MXC_CCM_CGCR2_SIM1_OFFSET (39-32) ++#define MXC_CCM_CGCR2_SIM2_OFFSET (40-32) ++#define MXC_CCM_CGCR2_SLCDC_OFFSET (41-32) ++#define MXC_CCM_CGCR2_SPBA_OFFSET (42-32) ++#define MXC_CCM_CGCR2_SSI1_OFFSET (43-32) ++#define MXC_CCM_CGCR2_SSI2_OFFSET (44-32) ++#define MXC_CCM_CGCR2_TCHSCRN_OFFSET (45-32) ++#define MXC_CCM_CGCR2_UART1_OFFSET (46-32) ++#define MXC_CCM_CGCR2_UART2_OFFSET (47-32) ++#define MXC_CCM_CGCR2_UART3_OFFSET (48-32) ++#define MXC_CCM_CGCR2_UART4_OFFSET (49-32) ++#define MXC_CCM_CGCR2_UART5_OFFSET (50-32) ++#define MXC_CCM_CGCR2_WDOG_OFFSET (51-32) ++ ++#define MXC_CCM_PCDR1_PERDIV1_MASK 0x3f ++ ++#define MXC_CCM_RCSR_NF16B (1 << 14) ++ ++#define MXC_CCM_MCR_USB_XTAL_MUX_OFFSET 31 ++#define MXC_CCM_MCR_CLKO_EN_OFFSET 30 ++#define MXC_CCM_MCR_CLKO_DIV_OFFSET 24 ++#define MXC_CCM_MCR_CLKO_DIV_MASK (0x3F << 24) ++#define MXC_CCM_MCR_CLKO_SEL_OFFSET 20 ++#define MXC_CCM_MCR_CLKO_SEL_MASK (0xF << 20) ++#define MXC_CCM_MCR_ESAI_CLK_MUX_OFFSET 19 ++#define MXC_CCM_MCR_SSI2_CLK_MUX_OFFSET 18 ++#define MXC_CCM_MCR_SSI1_CLK_MUX_OFFSET 17 ++#define MXC_CCM_MCR_USB_CLK_MUX_OFFSET 16 ++ ++#define MXC_CCM_MCR_PER_CLK_MUX_MASK (0xFFFF << 0) ++ ++#endif /* __ARCH_ARM_MACH_MX25_CRM_REGS_H__ */ +diff -urNp linux-2.6.30-rc4/arch/arm/mach-mx2/devices.h linux-2.6.30-rc4-karo/arch/arm/mach-mx2/devices.h +--- linux-2.6.30-rc4/arch/arm/mach-mx2/devices.h 2009-05-13 09:46:19.000000000 +0200 ++++ linux-2.6.30-rc4-karo/arch/arm/mach-mx2/devices.h 2009-06-02 17:05:27.000000000 +0200 +@@ -20,3 +20,9 @@ extern struct platform_device mxc_i2c_de + extern struct platform_device mxc_i2c_device1; + extern struct platform_device mxc_sdhc_device0; + extern struct platform_device mxc_sdhc_device1; ++#ifdef CONFIG_MACH_MX25 ++extern struct platform_device mx25_i2c_device0; ++extern struct platform_device mx25_i2c_device1; ++extern struct platform_device mx25_i2c_device2; ++extern struct platform_device mxc_sdhc_device2; ++#endif +diff -urNp linux-2.6.30-rc4/arch/arm/mach-mx2/devices_mx25.c linux-2.6.30-rc4-karo/arch/arm/mach-mx2/devices_mx25.c +--- linux-2.6.30-rc4/arch/arm/mach-mx2/devices_mx25.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30-rc4-karo/arch/arm/mach-mx2/devices_mx25.c 2009-06-02 17:05:27.000000000 +0200 +@@ -0,0 +1,402 @@ ++/* ++ * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved. ++ */ ++ ++/* ++ * The code contained herein is licensed under the GNU General Public ++ * License. You may obtain a copy of the GNU General Public License ++ * Version 2 or later at the following locations: ++ * ++ * http://www.opensource.org/licenses/gpl-license.html ++ * http://www.gnu.org/copyleft/gpl.html ++ */ ++#include <linux/module.h> ++#include <linux/kernel.h> ++#include <linux/init.h> ++#include <linux/platform_device.h> ++#include <linux/clk.h> ++#include <linux/gpio.h> ++#include <linux/spi/spi.h> ++ ++#include <mach/hardware.h> ++#include <mach/mmc.h> ++#include <mach/spba.h> ++#include <mach/sdma.h> ++#include <mach/iomux.h> ++ ++#include "sdma_script_code.h" ++ ++#include "karo.h" ++ ++void mx25_sdma_get_script_info(sdma_script_start_addrs * sdma_script_addr) ++{ ++ sdma_script_addr->mxc_sdma_ap_2_ap_addr = ap_2_ap_ADDR; ++ sdma_script_addr->mxc_sdma_ap_2_bp_addr = -1; ++ sdma_script_addr->mxc_sdma_bp_2_ap_addr = -1; ++ sdma_script_addr->mxc_sdma_loopback_on_dsp_side_addr = -1; ++ sdma_script_addr->mxc_sdma_mcu_interrupt_only_addr = -1; ++ ++ sdma_script_addr->mxc_sdma_firi_2_per_addr = -1; ++ sdma_script_addr->mxc_sdma_firi_2_mcu_addr = -1; ++ sdma_script_addr->mxc_sdma_per_2_firi_addr = -1; ++ sdma_script_addr->mxc_sdma_mcu_2_firi_addr = -1; ++ ++ sdma_script_addr->mxc_sdma_uart_2_per_addr = uart_2_per_ADDR; ++ sdma_script_addr->mxc_sdma_uart_2_mcu_addr = uart_2_mcu_ADDR; ++ sdma_script_addr->mxc_sdma_per_2_app_addr = per_2_app_ADDR; ++ sdma_script_addr->mxc_sdma_mcu_2_app_addr = mcu_2_app_ADDR; ++ ++ sdma_script_addr->mxc_sdma_per_2_per_addr = -1; ++ ++ sdma_script_addr->mxc_sdma_uartsh_2_per_addr = uartsh_2_per_ADDR; ++ sdma_script_addr->mxc_sdma_uartsh_2_mcu_addr = uartsh_2_mcu_ADDR; ++ sdma_script_addr->mxc_sdma_per_2_shp_addr = per_2_shp_ADDR; ++ sdma_script_addr->mxc_sdma_mcu_2_shp_addr = mcu_2_shp_ADDR; ++ ++ sdma_script_addr->mxc_sdma_ata_2_mcu_addr = ata_2_mcu_ADDR; ++ sdma_script_addr->mxc_sdma_mcu_2_ata_addr = mcu_2_ata_ADDR; ++ ++ sdma_script_addr->mxc_sdma_app_2_per_addr = app_2_per_ADDR; ++ sdma_script_addr->mxc_sdma_app_2_mcu_addr = app_2_mcu_ADDR; ++ sdma_script_addr->mxc_sdma_shp_2_per_addr = shp_2_per_ADDR; ++ sdma_script_addr->mxc_sdma_shp_2_mcu_addr = shp_2_mcu_ADDR; ++ ++ sdma_script_addr->mxc_sdma_mshc_2_mcu_addr = -1; ++ sdma_script_addr->mxc_sdma_mcu_2_mshc_addr = -1; ++ ++ sdma_script_addr->mxc_sdma_spdif_2_mcu_addr = -1; ++ sdma_script_addr->mxc_sdma_mcu_2_spdif_addr = -1; ++ ++ sdma_script_addr->mxc_sdma_asrc_2_mcu_addr = -1; ++ ++ sdma_script_addr->mxc_sdma_dptc_dvfs_addr = -1; ++ sdma_script_addr->mxc_sdma_ext_mem_2_ipu_addr = ext_mem__ipu_ram_ADDR; ++ sdma_script_addr->mxc_sdma_descrambler_addr = -1; ++ ++ sdma_script_addr->mxc_sdma_start_addr = (unsigned short *)sdma_code; ++ sdma_script_addr->mxc_sdma_ram_code_size = RAM_CODE_SIZE; ++ sdma_script_addr->mxc_sdma_ram_code_start_addr = RAM_CODE_START_ADDR; ++} ++ ++#if defined(CONFIG_MXC_WATCHDOG) || defined(CONFIG_MXC_WATCHDOG_MODULE) ++static struct resource wdt_resources[] = { ++ { ++ .start = WDOG_BASE_ADDR, ++ .end = WDOG_BASE_ADDR + 0x2f, ++ .flags = IORESOURCE_MEM, ++ }, ++}; ++ ++static struct platform_device mx25_wdt_device = { ++ .name = "mxc_wdt", ++ .id = 0, ++ .num_resources = ARRAY_SIZE(wdt_resources), ++ .resource = wdt_resources, ++}; ++ ++static void mx25_init_wdt(void) ++{ ++ (void)platform_device_register(&mx25_wdt_device); ++} ++#else ++static inline void mx25_init_wdt(void) ++{ ++} ++#endif ++ ++/* ++ * lcdc: ++ * - i.MX1: the basic controller ++ * - i.MX21: to be checked ++ * - i.MX27: like i.MX1, with slightly variations ++ */ ++static struct resource mxc_fb[] = { ++ { ++ .start = LCDC_BASE_ADDR, ++ .end = LCDC_BASE_ADDR + 0xFFF, ++ .flags = IORESOURCE_MEM, ++ }, ++ { ++ .start = MXC_INT_LCDC, ++ .end = MXC_INT_LCDC, ++ .flags = IORESOURCE_IRQ, ++ } ++}; ++ ++/* mxc lcd driver */ ++struct platform_device mxc_fb_device = { ++ .name = "imx-fb", ++ .id = 0, ++ .num_resources = ARRAY_SIZE(mxc_fb), ++ .resource = mxc_fb, ++ .dev = { ++ .coherent_dma_mask = 0xFFFFFFFF, ++ }, ++}; ++ ++/* SPI controller and device data */ ++#if defined(CONFIG_SPI_MXC) || defined(CONFIG_SPI_MXC_MODULE) ++ ++#ifdef CONFIG_SPI_MXC_SELECT1 ++/*! ++ * Resource definition for the CSPI1 ++ */ ++static struct resource mx25_spi1_resources[] = { ++ [0] = { ++ .start = CSPI1_BASE_ADDR, ++ .end = CSPI1_BASE_ADDR + SZ_4K - 1, ++ .flags = IORESOURCE_MEM, ++ }, ++ [1] = { ++ .start = MXC_INT_CSPI1, ++ .end = MXC_INT_CSPI1, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++/*! Platform Data for MXC CSPI1 */ ++static struct mxc_spi_master mx25_spi1_data = { ++ .maxchipselect = 4, ++ .spi_version = 7, ++}; ++ ++/*! Device Definition for MXC CSPI1 */ ++static struct platform_device mx25_spi1_device = { ++ .name = "mxc_spi", ++ .id = 0, ++ .dev = { ++ .platform_data = &mx25_spi1_data, ++ }, ++ .num_resources = ARRAY_SIZE(mx25_spi1_resources), ++ .resource = mx25_spi1_resources, ++}; ++ ++#endif /* CONFIG_SPI_MXC_SELECT1 */ ++ ++#ifdef CONFIG_SPI_MXC_SELECT2 ++/*! ++ * Resource definition for the CSPI2 ++ */ ++static struct resource mx25_spi2_resources[] = { ++ [0] = { ++ .start = CSPI2_BASE_ADDR, ++ .end = CSPI2_BASE_ADDR + SZ_4K - 1, ++ .flags = IORESOURCE_MEM, ++ }, ++ [1] = { ++ .start = MXC_INT_CSPI2, ++ .end = MXC_INT_CSPI2, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++/*! Platform Data for MXC CSPI2 */ ++static struct mxc_spi_master mx25_spi2_data = { ++ .maxchipselect = 4, ++ .spi_version = 7, ++}; ++ ++/*! Device Definition for MXC CSPI2 */ ++static struct platform_device mx25_spi2_device = { ++ .name = "mxc_spi", ++ .id = 1, ++ .dev = { ++ .platform_data = &mx25_spi2_data, ++ }, ++ .num_resources = ARRAY_SIZE(mx25_spi2_resources), ++ .resource = mx25_spi2_resources, ++}; ++#endif /* CONFIG_SPI_MXC_SELECT2 */ ++ ++#ifdef CONFIG_SPI_MXC_SELECT3 ++/*! ++ * Resource definition for the CSPI3 ++ */ ++static struct resource mx25_spi3_resources[] = { ++ [0] = { ++ .start = CSPI3_BASE_ADDR, ++ .end = CSPI3_BASE_ADDR + SZ_4K - 1, ++ .flags = IORESOURCE_MEM, ++ }, ++ [1] = { ++ .start = MXC_INT_CSPI3, ++ .end = MXC_INT_CSPI3, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++/*! Platform Data for MXC CSPI3 */ ++static struct mxc_spi_master mx25_spi3_data = { ++ .maxchipselect = 4, ++ .spi_version = 7, ++}; ++ ++/*! Device Definition for MXC CSPI3 */ ++static struct platform_device mx25_spi3_device = { ++ .name = "mxc_spi", ++ .id = 2, ++ .dev = { ++ .platform_data = &mx25_spi3_data, ++ }, ++ .num_resources = ARRAY_SIZE(mx25_spi3_resources), ++ .resource = mx25_spi3_resources, ++}; ++#endif /* CONFIG_SPI_MXC_SELECT3 */ ++ ++static inline void mx25_init_spi(void) ++{ ++ spba_take_ownership(SPBA_CSPI2, SPBA_MASTER_A); ++ spba_take_ownership(SPBA_CSPI3, SPBA_MASTER_A); ++ ++#ifdef CONFIG_SPI_MXC_SELECT1 ++ if (platform_device_register(&mx25_spi1_device) < 0) ++ printk(KERN_ERR "Error: Registering the SPI Controller_1\n"); ++#endif /* CONFIG_SPI_MXC_SELECT1 */ ++#ifdef CONFIG_SPI_MXC_SELECT2 ++ if (platform_device_register(&mx25_spi2_device) < 0) ++ printk(KERN_ERR "Error: Registering the SPI Controller_2\n"); ++#endif /* CONFIG_SPI_MXC_SELECT2 */ ++#ifdef CONFIG_SPI_MXC_SELECT3 ++ if (platform_device_register(&mx25_spi3_device) < 0) ++ printk(KERN_ERR "Error: Registering the SPI Controller_3\n"); ++#endif /* CONFIG_SPI_MXC_SELECT3 */ ++} ++#else ++static inline void mx25_init_spi(void) ++{ ++} ++#endif ++ ++/* I2C controller and device data */ ++#if defined(CONFIG_I2C_IMX) || defined(CONFIG_I2C_IMX_MODULE) ++ ++/*! ++ * Resource definition for the I2C1 ++ */ ++static struct resource mx25_i2c1_resources[] = { ++ [0] = { ++ .start = I2C_BASE_ADDR, ++ .end = I2C_BASE_ADDR + SZ_4K - 1, ++ .flags = IORESOURCE_MEM, ++ }, ++ [1] = { ++ .start = MXC_INT_I2C, ++ .end = MXC_INT_I2C, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++/*! ++ * Resource definition for the I2C2 ++ */ ++static struct resource mx25_i2c2_resources[] = { ++ [0] = { ++ .start = I2C2_BASE_ADDR, ++ .end = I2C2_BASE_ADDR + SZ_4K - 1, ++ .flags = IORESOURCE_MEM, ++ }, ++ [1] = { ++ .start = MXC_INT_I2C2, ++ .end = MXC_INT_I2C2, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++/*! ++ * Resource definition for the I2C3 ++ */ ++static struct resource mx25_i2c3_resources[] = { ++ [0] = { ++ .start = I2C3_BASE_ADDR, ++ .end = I2C3_BASE_ADDR + SZ_4K - 1, ++ .flags = IORESOURCE_MEM, ++ }, ++ [1] = { ++ .start = MXC_INT_I2C3, ++ .end = MXC_INT_I2C3, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++/*! Device Definition for MXC I2C1 */ ++struct platform_device mx25_i2c_device0 = { ++ .name = "imx-i2c", ++ .id = 0, ++ .num_resources = ARRAY_SIZE(mx25_i2c1_resources), ++ .resource = mx25_i2c1_resources, ++}; ++ ++struct platform_device mx25_i2c_device1 = { ++ .name = "imx-i2c", ++ .id = 1, ++ .num_resources = ARRAY_SIZE(mx25_i2c2_resources), ++ .resource = mx25_i2c2_resources, ++}; ++ ++struct platform_device mx25_i2c_device2 = { ++ .name = "imx-i2c", ++ .id = 2, ++ .num_resources = ARRAY_SIZE(mx25_i2c3_resources), ++ .resource = mx25_i2c3_resources, ++}; ++#endif ++ ++static struct mxc_gpio_port mx25_gpio_ports[] = { ++ { ++ .chip.label = "gpio-1", ++ .base = IO_ADDRESS(GPIO1_BASE_ADDR), ++ .irq = MXC_INT_GPIO1, ++ .virtual_irq_start = MXC_GPIO_IRQ_START, ++ }, ++ { ++ .chip.label = "gpio-2", ++ .base = IO_ADDRESS(GPIO2_BASE_ADDR), ++ .irq = MXC_INT_GPIO2, ++ .virtual_irq_start = MXC_GPIO_IRQ_START + 1 * 32, ++ }, ++ { ++ .chip.label = "gpio-3", ++ .base = IO_ADDRESS(GPIO3_BASE_ADDR), ++ .irq = MXC_INT_GPIO3, ++ .virtual_irq_start = MXC_GPIO_IRQ_START + 2 * 32, ++ }, ++ { ++ .chip.label = "gpio-4", ++ .base = IO_ADDRESS(GPIO4_BASE_ADDR), ++ .irq = MXC_INT_GPIO4, ++ .virtual_irq_start = MXC_GPIO_IRQ_START + 3 * 32, ++ }, ++}; ++ ++static inline void mx25_init_ssi(void) ++{ ++ /* SPBA configuration for SSI - SDMA and MCU are set */ ++ spba_take_ownership(SPBA_SSI1, SPBA_MASTER_A | SPBA_MASTER_C); ++ spba_take_ownership(SPBA_SSI2, SPBA_MASTER_A | SPBA_MASTER_C); ++} ++ ++static struct platform_device mx25_dma_device = { ++ .name = "mxc_dma", ++ .id = 0, ++}; ++ ++static inline void mx25_init_dma(void) ++{ ++ (void)platform_device_register(&mx25_dma_device); ++} ++ ++static int __init mx25_init_devices(void) ++{ ++ mx25_init_wdt(); ++ mx25_init_spi(); ++ mx25_init_dma(); ++ mx25_init_ssi(); ++ ++ return 0; ++} ++arch_initcall(mx25_init_devices); ++ ++int __init mxc_register_gpios(void) ++{ ++ return mxc_gpio_init(mx25_gpio_ports, ARRAY_SIZE(mx25_gpio_ports)); ++} +diff -urNp linux-2.6.30-rc4/arch/arm/mach-mx2/generic.c linux-2.6.30-rc4-karo/arch/arm/mach-mx2/generic.c +--- linux-2.6.30-rc4/arch/arm/mach-mx2/generic.c 2009-05-13 09:46:19.000000000 +0200 ++++ linux-2.6.30-rc4-karo/arch/arm/mach-mx2/generic.c 2009-06-02 17:05:27.000000000 +0200 +@@ -26,6 +26,7 @@ + #include <asm/mach/map.h> + + /* MX27 memory map definition */ ++#if defined(CONFIG_MACH_MX27) || defined(CONFIG_MACH_MX21) + static struct map_desc mxc_io_desc[] __initdata = { + /* + * this fixed mapping covers: +@@ -61,7 +62,7 @@ static struct map_desc mxc_io_desc[] __i + .pfn = __phys_to_pfn(X_MEMC_BASE_ADDR), + .length = X_MEMC_SIZE, + .type = MT_DEVICE +- } ++ }, + }; + + /* +@@ -82,4 +83,46 @@ void __init mx27_map_io(void) + + iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc)); + } ++#endif ++ ++#ifdef CONFIG_MACH_MX25 ++static struct map_desc mx25_io_desc[] __initdata = { ++ { ++ .virtual = (unsigned long)X_MEMC_BASE_ADDR_VIRT, ++ .pfn = __phys_to_pfn(X_MEMC_BASE_ADDR), ++ .length = X_MEMC_SIZE, ++ .type = MT_DEVICE ++ }, ++ { ++ .virtual = (unsigned long)ASIC_BASE_ADDR_VIRT, ++ .pfn = __phys_to_pfn(ASIC_BASE_ADDR), ++ .length = ASIC_SIZE, ++ .type = MT_DEVICE_NONSHARED ++ }, ++ { ++ .virtual = (unsigned long)AIPS1_BASE_ADDR_VIRT, ++ .pfn = __phys_to_pfn(AIPS1_BASE_ADDR), ++ .length = AIPS1_SIZE, ++ .type = MT_DEVICE_NONSHARED ++ }, ++ { ++ .virtual = (unsigned long)AIPS2_BASE_ADDR_VIRT, ++ .pfn = __phys_to_pfn(AIPS2_BASE_ADDR), ++ .length = AIPS2_SIZE, ++ .type = MT_DEVICE_NONSHARED ++ }, ++ { ++ .virtual = (unsigned long)SPBA0_BASE_ADDR_VIRT, ++ .pfn = __phys_to_pfn(SPBA0_BASE_ADDR), ++ .length = SPBA0_SIZE, ++ .type = MT_DEVICE_NONSHARED ++ }, ++}; ++ ++void __init mx25_map_io(void) ++{ ++ mxc_set_cpu_type(MXC_CPU_MX25); + ++ iotable_init(mx25_io_desc, ARRAY_SIZE(mx25_io_desc)); ++} ++#endif +diff -urNp linux-2.6.30-rc4/arch/arm/mach-mx2/karo-tx25.c linux-2.6.30-rc4-karo/arch/arm/mach-mx2/karo-tx25.c +--- linux-2.6.30-rc4/arch/arm/mach-mx2/karo-tx25.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30-rc4-karo/arch/arm/mach-mx2/karo-tx25.c 2009-06-02 17:05:27.000000000 +0200 +@@ -0,0 +1,1115 @@ ++/* ++ * arch/arm/mach-mx2/karo-tx25.c ++ * ++ * Copyright (C) 2008 Lothar Wassmann <LW@KARO-electronics.de> ++ * ++ * based on: arch/arm/mach-mx27ads.c (C) Freescale Semiconductor, Inc. ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 as published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the: ++ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 ++ * ++ * This file adds support for the Ka-Ro electronics TX25 processor modules ++ */ ++ ++#include <linux/types.h> ++#include <linux/sched.h> ++#include <linux/interrupt.h> ++#include <linux/init.h> ++#include <linux/ioport.h> ++#include <linux/platform_device.h> ++#include <linux/input.h> ++#include <linux/clk.h> ++#include <linux/delay.h> ++#include <linux/fb.h> ++//#include <linux/i2c.h> ++//#include <linux/i2c/at24.h> ++#include <linux/spi/spi.h> ++#include <linux/serial_8250.h> ++#include <linux/fec_enet.h> ++#if defined(CONFIG_MTD) || defined(CONFIG_MTD_MODULE) ++#include <mtd/mtd-abi.h> ++#include <linux/mtd/map.h> ++#include <linux/mtd/partitions.h> ++#include <asm/mach/flash.h> ++#endif ++ ++#include <linux/serial.h> ++#include <linux/fsl_devices.h> ++#include <linux/irq.h> ++#include <linux/mmc/host.h> ++#include <linux/leds.h> ++ ++#include <asm/setup.h> ++#include <asm/irq.h> ++#include <asm/mach-types.h> ++#include <asm/mach/arch.h> ++#include <asm/mach/time.h> ++#include <mach/common.h> ++#include <mach/hardware.h> ++#include <mach/gpio.h> ++#include <mach/iomux.h> ++#include <mach/irqs.h> ++#include <mach/clock.h> ++#include <mach/imxfb.h> ++//#include <mach/imx_spi.h> ++//#include <mach/i2c.h> ++#include <mach/mmc.h> ++#include <mach/imx-uart.h> ++#include <mach/mxc_nand.h> ++//#include <mach/ulpi.h> ++//#include <mach/mxc_ehci.h> ++//#include <mach/board-tx25.h> ++ ++#include "crm_regs.h" ++#include "devices.h" ++#include "karo.h" ++ ++#ifdef DEBUG ++int tx25_debug = 1; ++module_param(tx25_debug, int, S_IRUGO | S_IWUSR); ++#else ++static int tx25_debug; ++module_param(tx25_debug, int, 0); ++#endif ++ ++//#include "karo.h" ++ ++int karo_board_type = 0; ++int karo_mod_type = -1; ++ ++ ++#ifdef CONFIG_USB_EHCI_MXC ++ ++#define SMSC_VENDOR_ID 0x0424 ++#define USB3317_PROD_ID 0x0006 ++#define ULPI_FCTL 7 ++ ++static inline const char *ulpi_name(void __iomem *view) ++{ ++ if ((unsigned long)view & 0x400) { ++ return "USBH2"; ++ } else { ++ return "USBOTG"; ++ } ++} ++ ++static int usb3317_init(void __iomem *view) ++{ ++ int vid, pid, ret; ++#if 1 ++ /* This is a kludge until we know why we sometimes read a wrong ++ * vendor or product ID! ++ */ ++ int retries = 3; ++ ++ retry: ++#endif ++ ret = ulpi_read(ISP1504_VID_HIGH, view); ++ if (ret < 0) { ++ goto err; ++ } ++ vid = ret << 8; ++ ++ ret = ulpi_read(ISP1504_VID_LOW, view); ++ if (ret < 0) { ++ goto err; ++ } ++ vid |= ret; ++ ++ ret = ulpi_read(ISP1504_PID_HIGH, view); ++ if (ret < 0) { ++ goto err; ++ } ++ pid = ret << 8; ++ ++ ret = ulpi_read(ISP1504_PID_LOW, view); ++ if (ret < 0) { ++ goto err; ++ } ++ pid |= ret; ++ ++ pr_info("ULPI on %s port Vendor ID 0x%x Product ID 0x%x\n", ++ ulpi_name(view), vid, pid); ++ if (vid != SMSC_VENDOR_ID || pid != USB3317_PROD_ID) { ++ if (retries-- < 0) { ++ pr_err("No USB3317 found\n"); ++ return -ENODEV; ++ } ++ goto retry; ++ } ++ err: ++ if (ret < 0) { ++ printk(KERN_ERR "ULPI read on %s port failed with error %d\n", ++ ulpi_name(view), ret); ++ return ret; ++ } ++ return 0; ++} ++ ++static int usb3317_set_vbus_power(void __iomem *view, int on) ++{ ++ int ret; ++ ++ DBG(0, "%s: Switching %s port VBUS power %s\n", __FUNCTION__, ++ ulpi_name(view), on ? "on" : "off"); ++ ++ if (on) { ++ ret = ulpi_set(DRV_VBUS_EXT | /* enable external Vbus */ ++ DRV_VBUS | /* enable internal Vbus */ ++ CHRG_VBUS, /* charge Vbus */ ++ ISP1504_OTGCTL, view); ++ } else { ++ ret = ulpi_clear(DRV_VBUS_EXT | /* disable external Vbus */ ++ DRV_VBUS, /* disable internal Vbus */ ++ ISP1504_OTGCTL, view); ++ if (ret == 0) { ++ ret = ulpi_set(DISCHRG_VBUS, /* discharge Vbus */ ++ ISP1504_OTGCTL, view); ++ } ++ } ++ if (ret < 0) { ++ printk(KERN_ERR "ULPI read on %s port failed with error %d\n", ++ ulpi_name(view), ret); ++ return ret; ++ } ++ return 0; ++} ++ ++static int tx25_usbh2_init(struct platform_device *pdev) ++{ ++ int ret; ++ u32 temp; ++ unsigned long flags; ++ void __iomem *view = IO_ADDRESS(OTG_BASE_ADDR + 0x570); ++ ++ local_irq_save(flags); ++ temp = readl(IO_ADDRESS(OTG_BASE_ADDR) + 0x600); ++ temp &= ~((3 << 21) | (1 << 0)); ++ temp |= (1 << 5) | (1 << 16) | (1 << 19) | (1 << 20); ++ writel(temp, IO_ADDRESS(OTG_BASE_ADDR) + 0x600); ++ local_irq_restore(flags); ++ ++ /* select ULPI transceiver */ ++ /* this must be done _before_ setting up the GPIOs! */ ++ temp = readl(view + 0x14); ++ DBG(0, "%s: Changing USBH2_PORTSC1 from %08x to %08x\n", __FUNCTION__, ++ temp, (temp & ~(3 << 30)) | (2 << 30)); ++ temp &= ~(3 << 30); ++ temp |= 2 << 30; ++ writel(temp, view + 0x14); ++ ++ /* Set to Host mode */ ++ temp = readl(view + 0x38); ++ DBG(0, "%s: Changing USBH2_USBMODE from %08x to %08x\n", __FUNCTION__, ++ temp, temp | 3); ++ writel(temp | 0x3, view + 0x38); ++ ++ ret = gpio_usbh2_active(); ++ if (ret != 0) { ++ return ret; ++ } ++ ++ ret = usb3317_init(view); ++ if (ret != 0) { ++ goto err; ++ } ++ ret = usb3317_set_vbus_power(view, 1); ++ if (ret != 0) { ++ goto err; ++ } ++ return 0; ++ ++ err: ++ gpio_usbh2_inactive(); ++ return ret; ++} ++ ++static int tx25_usbh2_exit(struct platform_device *pdev) ++{ ++ gpio_usbh2_inactive(); ++ return 0; ++} ++ ++static struct mxc_usbh_platform_data tx25_usbh2_data = { ++ .init = tx25_usbh2_init, ++ .exit = tx25_usbh2_exit, ++}; ++ ++int tx25_usbh2_register(void) ++{ ++ int ret; ++ ++ ret = mxc_register_device(&mxc_ehci2, &tx25_usbh2_data); ++ return ret; ++} ++device_initcall(tx25_usbh2_register); ++#endif // CONFIG_USB_EHCI_MXC ++ ++//#define FEC_MII_IRQ IRQ_GPIOD(8) ++ ++#if defined(CONFIG_FEC) || defined(CONFIG_FEC_MODULE) ++static struct resource fec_resources[] = { ++ { ++ .start = FEC_BASE_ADDR, ++ .end = FEC_BASE_ADDR + 0x18f, ++ .flags = IORESOURCE_MEM, ++ }, { ++ .start = FEC_BASE_ADDR + 0x200, ++ .end = FEC_BASE_ADDR + 0x30b, ++ .flags = IORESOURCE_MEM, ++ }, { ++ .start = MXC_INT_FEC, ++ .end = MXC_INT_FEC, ++ .flags = IORESOURCE_IRQ, ++#ifdef FEC_MII_IRQ ++ }, { ++ .start = FEC_MII_IRQ, ++ .end = FEC_MII_IRQ, ++ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, ++#endif ++ }, ++}; ++ ++/* ++ * Setup GPIO for FEC device to be active ++ * ++ */ ++static struct pad_desc karo_tx25_fec_gpios_off[] = { ++ MX25_PAD_FEC_MDC__GPIO_3_5, ++ MX25_PAD_FEC_MDIO__GPIO_3_6, ++ MX25_PAD_FEC_TDATA0__GPIO_3_7, ++ MX25_PAD_FEC_TDATA1__GPIO_3_8, ++ MX25_PAD_FEC_TX_EN__GPIO_3_9, ++ MX25_PAD_FEC_RDATA0__GPIO_3_10, ++ MX25_PAD_FEC_RDATA1__GPIO_3_11, ++ MX25_PAD_FEC_RX_DV__GPIO_3_12, ++ MX25_PAD_FEC_TX_CLK__GPIO_3_13, ++ MX25_PAD_D12__GPIO_4_8, ++ MX25_PAD_D10__GPIO_4_10, ++}; ++ ++static struct pad_desc karo_tx25_fec_pwr_gpios[] = { ++ MX25_PAD_D11__GPIO_4_9, /* FEC PHY power on pin */ ++ MX25_PAD_D13__GPIO_4_7, /* FEC reset */ ++}; ++ ++static struct pad_desc karo_tx25_fec_gpios_on[] = { ++ MX25_PAD_FEC_MDC__FEC_MDC, ++ MX25_PAD_FEC_MDIO__FEC_MDIO, ++ MX25_PAD_FEC_TDATA0__FEC_TDATA0, ++ MX25_PAD_FEC_TDATA1__FEC_TDATA1, ++ MX25_PAD_FEC_TX_EN__FEC_TX_EN, ++ MX25_PAD_FEC_RDATA0__FEC_RDATA0, ++ MX25_PAD_FEC_RDATA1__FEC_RDATA1, ++ MX25_PAD_FEC_RX_DV__FEC_RX_DV, ++ MX25_PAD_FEC_TX_CLK__FEC_TX_CLK, ++ MX25_PAD_D12__GPIO_4_8, ++ MX25_PAD_D10__GPIO_4_10, ++}; ++ ++static struct gpio_desc { ++ unsigned int gpio:7; ++ unsigned int dir:1; ++ unsigned int level:1; ++} karo_tx25_fec_strap_gpios[] = { ++ /* configure the PHY strap pins to the correct values */ ++ { GPIO_PORTC | 5, 1, 0, }, ++ { GPIO_PORTC | 6, 1, 0, }, ++ { GPIO_PORTC | 7, 1, 0, }, ++ { GPIO_PORTC | 8, 1, 0, }, ++ { GPIO_PORTC | 9, 1, 0, }, ++ { GPIO_PORTC | 10, 1, 1, }, ++ { GPIO_PORTC | 11, 1, 1, }, ++ { GPIO_PORTC | 12, 0, 1, }, ++ { GPIO_PORTC | 13, 1, 0, }, ++ ++ { GPIO_PORTD | 8, 0, 0, }, ++ { GPIO_PORTD | 10, 0, 0, }, ++ { GPIO_PORTD | 9, 1, 1, }, ++ { GPIO_PORTD | 7, 1, 0, }, ++}; ++ ++#define TX25_FEC_PWR_GPIO (GPIO_PORTD | 9) ++#define TX25_FEC_RST_GPIO (GPIO_PORTD | 7) ++ ++static int gpio_fec_active(void) ++{ ++ int ret; ++ int i; ++ ++#ifdef FEC_MII_IRQ ++ DBG(0, "%s: Using IRQ %d (GPIO %d) for MII\n", __FUNCTION__, ++ FEC_MII_IRQ, irq_to_gpio(FEC_MII_IRQ)); ++ ++ set_irq_type(FEC_MII_IRQ, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING); ++#endif ++ ret = mxc_iomux_v3_setup_multiple_pads(karo_tx25_fec_pwr_gpios, ++ ARRAY_SIZE(karo_tx25_fec_pwr_gpios)); ++ if (ret) { ++ return ret; ++ } ++ /* ++ * If the PHY is already powered on, assume it has been ++ * correctly configured (by the boot loader) ++ */ ++ if (0 && gpio_get_value(TX25_FEC_PWR_GPIO) && ++ gpio_get_value(TX25_FEC_RST_GPIO)) { ++ ret = mxc_iomux_v3_setup_multiple_pads(karo_tx25_fec_gpios_on, ++ ARRAY_SIZE(karo_tx25_fec_gpios_on)); ++ if (ret) { ++ mxc_iomux_v3_release_multiple_pads(karo_tx25_fec_pwr_gpios, ++ ARRAY_SIZE(karo_tx25_fec_pwr_gpios)); ++ return ret; ++ } ++ } else { ++ /* switch PHY strap pins into required state */ ++ ret = mxc_iomux_v3_setup_multiple_pads(karo_tx25_fec_gpios_off, ++ ARRAY_SIZE(karo_tx25_fec_gpios_off)); ++ if (ret) { ++ mxc_iomux_v3_release_multiple_pads(karo_tx25_fec_pwr_gpios, ++ ARRAY_SIZE(karo_tx25_fec_pwr_gpios)); ++ return ret; ++ } ++ DBG(0, "%s: Switching FEC PHY power on\n", __FUNCTION__); ++ //gpio_set_value(TX25_FEC_PWR_GPIO, 1); ++#if 0 ++ while (1) { ++ gpio_set_value(TX25_FEC_PWR_GPIO, 1); ++ mdelay(1000); ++ gpio_set_value(TX25_FEC_PWR_GPIO, 0); ++ mdelay(1000); ++ } ++#endif ++ DBG(0, "%s: Asserting FEC PHY reset\n", __FUNCTION__); ++// gpio_set_value(TX25_FEC_RST_GPIO, 0); ++ for (i = 0; i < ARRAY_SIZE(karo_tx25_fec_strap_gpios); i++) { ++ struct gpio_desc *pd = &karo_tx25_fec_strap_gpios[i]; ++ ++ ret = gpio_request(pd->gpio, "FEC"); ++ if (ret < 0) { ++ DBG(0, "%s: Failed to request GPIO%d_%d: %d\n", ++ __FUNCTION__, pd->gpio / 32 + 1, pd->gpio % 32, ret); ++ goto rel_mux; ++ } ++ if (pd->dir) { ++ gpio_direction_output(pd->gpio, ++ pd->level); ++ } else { ++ gpio_direction_input(pd->gpio); ++ } ++ } ++#ifdef DEBUG ++ for (i = 0; i < ARRAY_SIZE(karo_tx25_fec_strap_gpios); i++) { ++ struct gpio_desc *pd = &karo_tx25_fec_strap_gpios[i]; ++ int grp = pd->gpio / 32 + 1; ++ int ofs = pd->gpio % 32; ++ ++ if (pd->dir && pd->level != gpio_get_value(pd->gpio)) { ++ DBG(0, "%s: GPIO%d_%d is %d instead of %d\n", __FUNCTION__, ++ grp, ofs, gpio_get_value(pd->gpio), ++ pd->level); ++ } ++ } ++#endif ++ DBG(0, "%s: Delaying for 22ms\n", __FUNCTION__); ++ mdelay(22); ++ DBG(0, "%s: Deasserting FEC PHY reset\n", __FUNCTION__); ++ gpio_set_value(TX25_FEC_RST_GPIO, 1); ++#ifdef DEBUG ++ for (i = 0; i < ARRAY_SIZE(karo_tx25_fec_strap_gpios); i++) { ++ struct gpio_desc *pd = &karo_tx25_fec_strap_gpios[i]; ++ int grp = pd->gpio / 32 + 1; ++ int ofs = pd->gpio % 32; ++ ++ DBG(0, "%s: GPIO%d_%d is %d\n", __FUNCTION__, ++ grp, ofs, gpio_get_value(pd->gpio)); ++ } ++#endif ++ mxc_iomux_v3_release_multiple_pads(karo_tx25_fec_gpios_off, ++ ARRAY_SIZE(karo_tx25_fec_gpios_off)); ++ ret = mxc_iomux_v3_setup_multiple_pads(karo_tx25_fec_gpios_on, ++ ARRAY_SIZE(karo_tx25_fec_gpios_on)); ++ if (ret) { ++ goto rel_gpio; ++ } ++#ifdef DEBUG ++ for (i = 0; i < ARRAY_SIZE(karo_tx25_fec_strap_gpios); i++) { ++ struct gpio_desc *pd = &karo_tx25_fec_strap_gpios[i]; ++ int grp = pd->gpio / 32 + 1; ++ int ofs = pd->gpio % 32; ++ ++ DBG(0, "%s: GPIO%d_%d is %d\n", __FUNCTION__, ++ grp, ofs, gpio_get_value(pd->gpio)); ++ } ++#endif ++ } ++ return ret; ++ ++ rel_mux: ++ mxc_iomux_v3_release_multiple_pads(karo_tx25_fec_gpios_off, ++ ARRAY_SIZE(karo_tx25_fec_gpios_off)); ++ rel_gpio: ++ while (--i >= 0) { ++ struct gpio_desc *pd = &karo_tx25_fec_strap_gpios[i]; ++#ifdef DEBUG ++ int grp = pd->gpio / 32 + 1; ++ int ofs = pd->gpio % 32; ++ ++ DBG(0, "%s: Freeing GPIO%d_%d\n", __FUNCTION__, ++ grp, ofs); ++#endif ++ gpio_free(pd->gpio); ++ } ++ mxc_iomux_v3_release_multiple_pads(karo_tx25_fec_pwr_gpios, ++ ARRAY_SIZE(karo_tx25_fec_pwr_gpios)); ++ return ret; ++} ++ ++/* ++ * Setup GPIO for FEC device to be inactive ++ * ++ */ ++static void gpio_fec_inactive(void) ++{ ++ int i; ++ ++ mxc_iomux_v3_release_multiple_pads(karo_tx25_fec_gpios_on, ++ ARRAY_SIZE(karo_tx25_fec_gpios_on)); ++ mxc_iomux_v3_setup_multiple_pads(karo_tx25_fec_gpios_off, ++ ARRAY_SIZE(karo_tx25_fec_gpios_off)); ++ DBG(0, "%s: Asserting FEC PHY reset\n", __FUNCTION__); ++ gpio_set_value(TX25_FEC_RST_GPIO, 0); ++ DBG(0, "%s: Switching FEC PHY power off\n", __FUNCTION__); ++ gpio_set_value(TX25_FEC_PWR_GPIO, 0); ++ ++ mxc_iomux_v3_release_multiple_pads(karo_tx25_fec_gpios_off, ++ ARRAY_SIZE(karo_tx25_fec_gpios_off)); ++ mxc_iomux_v3_release_multiple_pads(karo_tx25_fec_pwr_gpios, ++ ARRAY_SIZE(karo_tx25_fec_pwr_gpios)); ++ for (i = 0; i < ARRAY_SIZE(karo_tx25_fec_strap_gpios); i++) { ++ struct gpio_desc *pd = &karo_tx25_fec_strap_gpios[i]; ++#ifdef DEBUG ++ int grp = pd->gpio / 32 + 1; ++ int ofs = pd->gpio % 32; ++ ++ DBG(0, "%s: Freeing GPIO%d_%d\n", __FUNCTION__, ++ grp, ofs); ++#endif ++ gpio_free(pd->gpio); ++ } ++} ++ ++static struct clk *tx25_fec_clk; ++ ++static int tx25_fec_suspend(struct platform_device *pdev) ++{ ++ BUG_ON(tx25_fec_clk == NULL); ++ DBG(1, "%s: Switching FEC PHY off\n", __FUNCTION__); ++ gpio_fec_inactive(); ++ clk_disable(tx25_fec_clk); ++ return 0; ++} ++ ++static int tx25_fec_resume(struct platform_device *pdev) ++{ ++ BUG_ON(tx25_fec_clk == NULL); ++ DBG(1, "%s: Switching FEC PHY on\n", __FUNCTION__); ++ clk_enable(tx25_fec_clk); ++ gpio_fec_active(); ++ return 0; ++} ++ ++#if 0 ++/* ++ * i.MX25 allows RMII mode to be configured via a gasket ++ */ ++#define FEC_MIIGSK_CFGR_FRCONT (1 << 6) ++#define FEC_MIIGSK_CFGR_LBMODE (1 << 4) ++#define FEC_MIIGSK_CFGR_EMODE (1 << 3) ++#define FEC_MIIGSK_CFGR_IF_MODE_MASK (3 << 0) ++#define FEC_MIIGSK_CFGR_IF_MODE_MII (0 << 0) ++#define FEC_MIIGSK_CFGR_IF_MODE_RMII (1 << 0) ++ ++#define FEC_MIIGSK_ENR_READY (1 << 2) ++#define FEC_MIIGSK_ENR_EN (1 << 1) ++ ++#include "../arch/arm/mach-mx25/crm_regs.h" ++static void __inline__ fec_localhw_setup(struct net_device *dev) ++{ ++ struct fec_enet_private *fep = netdev_priv(dev); ++ ++ /* ++ * Set up the MII gasket for RMII mode ++ */ ++ printk("%s: enable RMII gasket\n", dev->name); ++ ++ /* disable the gasket and wait */ ++ fec_reg_write16(fep, FEC_MIIGSK_ENR, 0); ++ while (fec_reg_read16(fep, FEC_MIIGSK_ENR) & FEC_MIIGSK_ENR_READY) ++ udelay(1); ++ ++ /* configure the gasket for RMII, 50 MHz, no loopback, no echo */ ++ fec_reg_write16(fep, FEC_MIIGSK_CFGR, FEC_MIIGSK_CFGR_IF_MODE_RMII); ++ ++ /* re-enable the gasket */ ++ fec_reg_write16(fep, FEC_MIIGSK_ENR, FEC_MIIGSK_ENR_EN); ++ fec_reg_read16(fep, FEC_MIIGSK_CFGR); ++ fec_reg_read16(fep, FEC_MIIGSK_ENR); ++} ++#endif ++ ++static int fec_arch_init(struct platform_device *pdev) ++{ ++ int ret; ++ ++ DBG(0, "%s: Activating FEC GPIOs\n", __FUNCTION__); ++ dump_regs(); ++ ++ ret = gpio_fec_active(); ++ if (ret) { ++ printk(KERN_ERR "%s: could not enable FEC gpios: %d\n", __FUNCTION__, ret); ++ return ret; ++ } ++ ++ BUG_ON(tx25_fec_clk != NULL); ++ tx25_fec_clk = clk_get(&pdev->dev, NULL); ++ if (unlikely(IS_ERR(tx25_fec_clk))) { ++ printk(KERN_ERR "Failed to get fec_clk\n"); ++ return PTR_ERR(tx25_fec_clk); ++ } ++ DBG(0, "%s: Enabling FEC clock\n", __FUNCTION__); ++ clk_enable(tx25_fec_clk); ++ dump_regs(); ++ return 0; ++} ++ ++static void fec_arch_exit(struct platform_device *pdev) ++{ ++ BUG_ON(tx25_fec_clk == NULL); ++ if (unlikely(IS_ERR(tx25_fec_clk))) { ++ printk(KERN_ERR "Failed to get fec_clk\n"); ++ return; ++ } ++ DBG(0, "%s: Disabling FEC clock\n", __FUNCTION__); ++ clk_disable(tx25_fec_clk); ++ clk_put(tx25_fec_clk); ++ tx25_fec_clk = NULL; ++ DBG(0, "%s: Deactivating FEC GPIOs\n", __FUNCTION__); ++ gpio_fec_inactive(); ++} ++ ++static struct fec_enet_platform_data fec_data = { ++ .arch_init = fec_arch_init, ++ .arch_exit = fec_arch_exit, ++ .suspend = tx25_fec_suspend, ++ .resume = tx25_fec_resume, ++}; ++ ++static struct platform_device fec_device = { ++ .name = "fec", ++ .id = 0, ++ .num_resources = ARRAY_SIZE(fec_resources), ++ .resource = fec_resources, ++ .dev = { ++ .platform_data = &fec_data, ++ .coherent_dma_mask = 0xFFFFFFFF, ++ }, ++}; ++#endif ++ ++/* MTD NAND flash */ ++#if defined(CONFIG_MTD_NAND_MXC) || defined(CONFIG_MTD_NAND_MXC_MODULE) ++#ifdef CONFIG_ARCH_MXC_HAS_NFC_V2 ++static struct mtd_partition tx25_nand_partitions[] = { ++ { ++ .name = "RedBoot", ++ .offset = 0, ++ .size = 0x00040000, ++ }, { ++ .name = "kernel", ++ .offset = MTDPART_OFS_APPEND, ++ .size = 0x001A0000, ++ }, { ++ .name = "rootfs", ++ .offset = MTDPART_OFS_APPEND, ++ .size = 0x07E000000, ++ }, { ++ .name = "FIS directory", ++ .offset = MTDPART_OFS_APPEND, ++ .size = 0x00003000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "RedBoot config", ++ .offset = MTDPART_OFS_APPEND, ++ .size = 0x00001000, ++ .mask_flags = MTD_WRITEABLE, ++ }, ++}; ++ ++static struct pad_desc karo_tx25_nand_pads[] = { ++ MX25_PAD_NF_CE0__NF_CE0, ++ MX25_PAD_NFWE_B__NFWE_B, ++ MX25_PAD_NFRE_B__NFRE_B, ++ MX25_PAD_NFALE__NFALE, ++ MX25_PAD_NFCLE__NFCLE, ++ MX25_PAD_NFWP_B__NFWP_B, ++ MX25_PAD_NFRB__NFRB, ++ MX25_PAD_D7__D7, ++ MX25_PAD_D6__D6, ++ MX25_PAD_D5__D5, ++ MX25_PAD_D4__D4, ++ MX25_PAD_D3__D3, ++ MX25_PAD_D2__D2, ++ MX25_PAD_D1__D1, ++ MX25_PAD_D0__D0, ++}; ++ ++static int tx25_nand_init(void) ++{ ++ int ret; ++ ++ DBG(0, "%s: Configuring NAND pins\n", __FUNCTION__); ++ ret = mxc_iomux_v3_setup_multiple_pads(karo_tx25_nand_pads, ++ ARRAY_SIZE(karo_tx25_nand_pads)); ++ if (ret) { ++ return ret; ++ } ++ return 0; ++} ++ ++static void tx25_nand_exit(void) ++{ ++ mxc_iomux_v3_release_multiple_pads(karo_tx25_nand_pads, ++ ARRAY_SIZE(karo_tx25_nand_pads)); ++} ++ ++static struct flash_platform_data tx25_nand_data = { ++ .map_name = "nand_probe", ++ .name = "tx25-nand", ++ .parts = tx25_nand_partitions, ++ .nr_parts = ARRAY_SIZE(tx25_nand_partitions), ++ .width = 1, ++ .init = tx25_nand_init, ++ .exit = tx25_nand_exit, ++}; ++#else ++static struct mxc_nand_platform_data tx25_nand_data = { ++ .hw_ecc = 1, ++ .width = 1, ++}; ++#endif ++ ++static struct resource tx25_nand_resources[] = { ++#ifdef CONFIG_ARCH_MXC_HAS_NFC_V1_1 ++ { ++ .start = NFC_BASE_ADDR + 0x1e00, ++ .end = NFC_BASE_ADDR + 0x1e2f, ++ .flags = IORESOURCE_MEM, ++ }, { ++ .start = NFC_BASE_ADDR, ++ .end = NFC_BASE_ADDR + 0x11ff, ++ .flags = IORESOURCE_MEM, ++#else ++ { ++ .start = NFC_BASE_ADDR, ++ .end = NFC_BASE_ADDR + 0x1e2f, ++ .flags = IORESOURCE_MEM, ++#endif ++ }, { ++ .start = MXC_INT_NANDFC, ++ .end = MXC_INT_NANDFC, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++static struct platform_device tx25_nand_mtd_device = { ++ .name = "mxc_nand", ++ .id = 0, ++ .num_resources = ARRAY_SIZE(tx25_nand_resources), ++ .resource = tx25_nand_resources, ++ .dev = { ++ .platform_data = &tx25_nand_data, ++ }, ++}; ++#endif ++ ++#if defined(CONFIG_VIDEO_MXC_EMMA_OUTPUT) || defined(CONFIG_VIDEO_MXC_EMMA_OUTPUT_MODULE) ++static u64 mxc_emma_dmamask = 0xffffffffUL; ++ ++static struct platform_device tx25_v4l2out_device = { ++ .name = "MXC Video Output", ++ .id = 0, ++ .dev = { ++ .dma_mask = &mxc_emma_dmamask, ++ .coherent_dma_mask = ~0UL, ++ }, ++}; ++#endif ++ ++#if 0 ++#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) ++static struct pad_desc mxc_i2c0_pins[] = { ++ /* ++ * it seems the data line misses a pullup, so we must enable ++ * the internal pullup as a local workaround ++ */ ++ MX25_PAD_I2C1_CLK__I2C1_CLK, ++ MX25_PAD_I2C1_DAT__I2C1_DAT, ++}; ++ ++static int karo_tx25_i2c_0_init(struct device *dev) ++{ ++ DBG(-1, "%s: \n", __FUNCTION__); ++ return mxc_iomux_v3_setup_multiple_pads(mxc_i2c0_pins, ++ ARRAY_SIZE(mxc_i2c0_pins)); ++} ++ ++static void karo_tx25_i2c_0_exit(struct device *dev) ++{ ++ DBG(-1, "%s: \n", __FUNCTION__); ++ mxc_iomux_v3_release_multiple_pads(mxc_i2c0_pins, ++ ARRAY_SIZE(mxc_i2c0_pins)); ++} ++ ++static struct imxi2c_platform_data karo_tx25_i2c_0_data = { ++ .bitrate = 100000, ++ .init = karo_tx25_i2c_0_init, ++ .exit = karo_tx25_i2c_0_exit, ++}; ++ ++static struct at24_platform_data karo_tx25_eeprom = { ++ .byte_len = 2048, ++ .page_size = 32, ++ .flags = AT24_FLAG_ADDR16 | AT24_FLAG_TAKE8ADDR, ++}; ++ ++static struct i2c_board_info karo_i2c_0_boardinfo[] __initdata = { ++ { ++ I2C_BOARD_INFO("24c16", 0x50), ++ .platform_data = &karo_tx25_eeprom, ++ .type = "24c16", ++ }, ++}; ++ ++int __init karo_i2c_init(void) ++{ ++ int ret; ++ ++ DBG(0, "%s: Registering I2C bus 0\n", __FUNCTION__); ++ ret = mxc_register_device(&mx25_i2c_device0, &karo_tx25_i2c_0_data); ++ if (ret != 0) { ++ printk(KERN_ERR "Failed to register I2C device: %d\n", ret); ++ return ret; ++ } ++ ret = i2c_register_board_info(0, karo_i2c_0_boardinfo, ++ ARRAY_SIZE(karo_i2c_0_boardinfo)); ++ if (ret != 0) { ++ printk(KERN_ERR "Failed to register I2C board info: %d\n", ret); ++ } ++ return ret; ++} ++device_initcall(karo_i2c_init); ++#endif ++#endif ++ ++struct platform_dev_list { ++ struct platform_device *pdev; ++ int flag; ++} tx25_devices[] __initdata = { ++#if defined(CONFIG_RTC_MXC) || defined(CONFIG_RTC_MXC_MODULE) ++ { .pdev = &mxc_rtc_device, .flag = -1, }, ++#endif ++#if defined(CONFIG_MTD_NAND_MXC) || defined(CONFIG_MTD_NAND_MXC_MODULE) ++ { .pdev = &tx25_nand_mtd_device, .flag = 1, }, ++#endif ++#if defined(CONFIG_FEC) || defined(CONFIG_FEC_MODULE) ++ { .pdev = &fec_device, .flag = 1, }, ++#endif ++#if defined(CONFIG_SPI_MXC) || defined(CONFIG_SPI_MXC_MODULE) ++ { .pdev = &mxcspi1_device, .flag = 1, }, ++#endif ++#if defined(CONFIG_VIDEO_MXC_EMMA_OUTPUT) || defined(CONFIG_VIDEO_MXC_EMMA_OUTPUT_MODULE) ++ { .pdev = &tx25_v4l2out_device, .flag = 1, }, ++#endif ++#if defined(CONFIG_MXC_VPU) || defined(CONFIG_MXC_VPU_MODULE) ++ { .pdev = &mxc_vpu_device, .flag = 1, }, ++#endif ++}; ++#define TX25_NUM_DEVICES ARRAY_SIZE(tx25_devices) ++ ++static __init void karo_tx25_board_init(void) ++{ ++ int i; ++ ++ DBG(0, "%s: \n", __FUNCTION__); ++ ++ dump_regs(); ++ ++ for (i = 0; i < TX25_NUM_DEVICES; i++) { ++ int ret; ++ ++ if (tx25_devices[i].pdev == NULL) continue; ++ if (!tx25_devices[i].flag) { ++ DBG(0, "%s: Skipping platform device[%d] @ %p dev %p: %s\n", ++ __FUNCTION__, i, tx25_devices[i].pdev, &tx25_devices[i].pdev->dev, ++ tx25_devices[i].pdev->name); ++ continue; ++ } ++ DBG(0, "%s: Registering platform device[%d] @ %p dev %p: %s\n", ++ __FUNCTION__, i, tx25_devices[i].pdev, &tx25_devices[i].pdev->dev, ++ tx25_devices[i].pdev->name); ++ ret = platform_device_register(tx25_devices[i].pdev); ++ if (ret) { ++ printk(KERN_WARNING "%s: Failed to register platform_device[%d]: %s: %d\n", ++ __FUNCTION__, i, tx25_devices[i].pdev->name, ret); ++ } ++ } ++ DBG(0, "%s: Done\n", __FUNCTION__); ++} ++ ++static struct pad_desc karo_tx25_gpios[] __initdata = { ++ MX25_PAD_GPIO_A__GPIO_A, ++ MX25_PAD_GPIO_B__GPIO_B, ++ MX25_PAD_GPIO_C__GPIO_C, ++ MX25_PAD_GPIO_D__GPIO_D, ++ MX25_PAD_GPIO_E__GPIO_E, ++ MX25_PAD_GPIO_F__GPIO_F, ++ MX25_PAD_CSI_D7__GPIO_1_6, ++ MX25_PAD_CSI_D8__GPIO_1_7, ++ MX25_PAD_CSI_MCLK__GPIO_1_8, ++ MX25_PAD_CSI_VSYNC__GPIO_1_9, ++ MX25_PAD_CSI_HSYNC__GPIO_1_10, ++ MX25_PAD_CSI_PIXCLK__GPIO_1_11, ++ MX25_PAD_I2C1_CLK__GPIO_1_12, ++ MX25_PAD_I2C1_DAT__GPIO_1_13, ++ MX25_PAD_CSPI1_MOSI__GPIO_1_14, ++ MX25_PAD_CSPI1_MISO__GPIO_1_15, ++ MX25_PAD_CSPI1_SS0__GPIO_1_16, ++ MX25_PAD_CSPI1_SS1__GPIO_1_17, ++ MX25_PAD_CSPI1_SCLK__GPIO_1_18, ++ MX25_PAD_LD5__GPIO_1_19, ++ MX25_PAD_LD6__GPIO_1_20, ++ MX25_PAD_LD7__GPIO_1_21, ++ MX25_PAD_HSYNC__GPIO_1_22, ++ MX25_PAD_VSYNC__GPIO_1_23, ++ MX25_PAD_LSCLK__GPIO_1_24, ++ MX25_PAD_OE_ACD__GPIO_1_25, ++ MX25_PAD_PWM__GPIO_1_26, ++ MX25_PAD_CSI_D2__GPIO_1_27, ++ MX25_PAD_CSI_D3__GPIO_1_28, ++ MX25_PAD_CSI_D4__GPIO_1_29, ++ MX25_PAD_CSI_D5__GPIO_1_30, ++ MX25_PAD_CSI_D6__GPIO_1_31, ++ ++ MX25_PAD_A14__GPIO_2_0, ++ MX25_PAD_A15__GPIO_2_1, ++ MX25_PAD_A16__GPIO_2_2, ++ MX25_PAD_A17__GPIO_2_3, ++ MX25_PAD_A18__GPIO_2_4, ++ MX25_PAD_A19__GPIO_2_5, ++ MX25_PAD_A20__GPIO_2_6, ++ MX25_PAD_A21__GPIO_2_7, ++ MX25_PAD_A22__GPIO_2_8, ++ MX25_PAD_A23__GPIO_2_9, ++ MX25_PAD_A24__GPIO_2_10, ++ MX25_PAD_A25__GPIO_2_11, ++ MX25_PAD_EB0__GPIO_2_12, ++ MX25_PAD_EB1__GPIO_2_13, ++ MX25_PAD_OE__GPIO_2_14, ++ MX25_PAD_LD0__GPIO_2_15, ++ MX25_PAD_LD1__GPIO_2_16, ++ MX25_PAD_LD2__GPIO_2_17, ++ MX25_PAD_LD3__GPIO_2_18, ++ MX25_PAD_LD4__GPIO_2_19, ++ MX25_PAD_DE_B__GPIO_2_20, ++ MX25_PAD_CLKO__GPIO_2_21, ++ MX25_PAD_CSPI1_RDY__GPIO_2_22, ++ MX25_PAD_SD1_CMD__GPIO_2_23, ++ MX25_PAD_SD1_CLK__GPIO_2_24, ++ MX25_PAD_SD1_DATA0__GPIO_2_25, ++ MX25_PAD_SD1_DATA1__GPIO_2_26, ++ MX25_PAD_SD1_DATA2__GPIO_2_27, ++ MX25_PAD_SD1_DATA3__GPIO_2_28, ++ MX25_PAD_KPP_ROW0__GPIO_2_29, ++ MX25_PAD_KPP_ROW1__GPIO_2_30, ++ MX25_PAD_KPP_ROW2__GPIO_2_31, ++ ++ MX25_PAD_KPP_ROW3__GPIO_3_0, ++ MX25_PAD_KPP_COL0__GPIO_3_1, ++ MX25_PAD_KPP_COL1__GPIO_3_2, ++ MX25_PAD_KPP_COL2__GPIO_3_3, ++ MX25_PAD_KPP_COL3__GPIO_3_4, ++ MX25_PAD_FEC_MDC__GPIO_3_5, ++ MX25_PAD_FEC_MDIO__GPIO_3_6, ++ MX25_PAD_FEC_TDATA0__GPIO_3_7, ++ MX25_PAD_FEC_TDATA1__GPIO_3_8, ++ MX25_PAD_FEC_TX_EN__GPIO_3_9, ++ MX25_PAD_FEC_RDATA0__GPIO_3_10, ++ MX25_PAD_FEC_RDATA1__GPIO_3_11, ++ MX25_PAD_FEC_RX_DV__GPIO_3_12, ++ MX25_PAD_FEC_TX_CLK__GPIO_3_13, ++ MX25_PAD_RTCK__GPIO_3_14, ++ MX25_PAD_EXT_ARMCLK__GPIO_3_15, ++ MX25_PAD_UPLL_BYPCLK__GPIO_3_16, ++ MX25_PAD_VSTBY_REQ__GPIO_3_17, ++ MX25_PAD_VSTBY_ACK__GPIO_3_18, ++ MX25_PAD_POWER_FAIL__GPIO_3_19, ++ MX25_PAD_CS4__GPIO_3_20, ++ MX25_PAD_CS5__GPIO_3_21, ++ MX25_PAD_NF_CE0__GPIO_3_22, ++ MX25_PAD_ECB__GPIO_3_23, ++ MX25_PAD_LBA__GPIO_3_24, ++ MX25_PAD_RW__GPIO_3_25, ++ MX25_PAD_NFWE_B__GPIO_3_26, ++ MX25_PAD_NFRE_B__GPIO_3_27, ++ MX25_PAD_NFALE__GPIO_3_28, ++ MX25_PAD_NFCLE__GPIO_3_29, ++ MX25_PAD_NFWP_B__GPIO_3_30, ++ MX25_PAD_NFRB__GPIO_3_31, ++ ++ MX25_PAD_A10__GPIO_4_0, ++ MX25_PAD_A13__GPIO_4_1, ++ MX25_PAD_CS0__GPIO_4_2, ++ MX25_PAD_CS1__GPIO_4_3, ++ MX25_PAD_BCLK__GPIO_4_4, ++ MX25_PAD_D15__GPIO_4_5, ++ MX25_PAD_D14__GPIO_4_6, ++ MX25_PAD_D13__GPIO_4_7, ++ MX25_PAD_D12__GPIO_4_8, ++ MX25_PAD_D11__GPIO_4_9, ++ MX25_PAD_D10__GPIO_4_10, ++ MX25_PAD_D9__GPIO_4_11, ++ MX25_PAD_D8__GPIO_4_12, ++ MX25_PAD_D7__GPIO_4_13, ++ MX25_PAD_D6__GPIO_4_14, ++ MX25_PAD_D5__GPIO_4_15, ++ MX25_PAD_D4__GPIO_4_16, ++ MX25_PAD_D3__GPIO_4_17, ++ MX25_PAD_D2__GPIO_4_18, ++ MX25_PAD_D1__GPIO_4_19, ++ MX25_PAD_D0__GPIO_4_20, ++ MX25_PAD_CSI_D9__GPIO_4_21, ++ MX25_PAD_UART1_RXD__GPIO_4_22, ++ MX25_PAD_UART1_TXD__GPIO_4_23, ++ MX25_PAD_UART1_RTS__GPIO_4_24, ++ MX25_PAD_UART1_CTS__GPIO_4_25, ++ MX25_PAD_UART2_RXD__GPIO_4_26, ++ MX25_PAD_UART2_TXD__GPIO_4_27, ++ MX25_PAD_UART2_RTS__GPIO_4_28, ++ MX25_PAD_UART2_CTS__GPIO_4_29, ++ MX25_PAD_BOOT_MODE0__GPIO_4_30, ++ MX25_PAD_BOOT_MODE1__GPIO_4_31, ++}; ++ ++static int __init karo_tx25_setup_gpios(void) ++{ ++ int i; ++ int ret; ++ int count = 0; ++ ++ for (i = 0; i < ARRAY_SIZE(karo_tx25_gpios); i++) { ++ struct pad_desc *pd = &karo_tx25_gpios[i]; ++#if 0 ++ if (i - 64 >= 16 && i - 64 < 32) { ++ continue; ++ } ++#endif ++ ret = mxc_iomux_v3_setup_pad(pd); ++ if (ret == 0) { ++#ifdef IOMUX_DEBUG ++ DBG(0, "%s: PAD[%d] %s set up as GPIO\n", __FUNCTION__, i, pd->name); ++#else ++ DBG(0, "%s: PAD[%d] set up as GPIO\n", __FUNCTION__, i); ++#endif ++ count++; ++ mxc_iomux_v3_release_pad(pd); ++ } else { ++#ifdef IOMUX_DEBUG ++ DBG(0, "%s: PAD[%d] %s skipped\n", __FUNCTION__, i, pd->name); ++#else ++ DBG(0, "%s: PAD[%d] skipped\n", __FUNCTION__, i); ++#endif ++ } ++ } ++ DBG(0, "%s: %d out of %d pins set up as GPIO\n", __FUNCTION__, count, i); ++#if 0 ++ if (gpio_request(42, "TEST") == 0) { ++ gpio_direction_output(42, 1); ++ while (1) { ++ gpio_set_value(42, 0); ++ if (gpio_get_value(42)) { ++ DBG(0, "%s: GPIO 42 is HIGH instead of LOW\n", __FUNCTION__); ++ } ++ msleep(1000); ++ gpio_set_value(42, 1); ++ if (!gpio_get_value(42)) { ++ DBG(0, "%s: GPIO 42 is LOW instead of HIGH\n", __FUNCTION__); ++ } ++ msleep(1000); ++ } ++ } ++ gpio_free(42); ++#endif ++ return 0; ++} ++late_initcall(karo_tx25_setup_gpios); ++ ++static void __init karo_tx25_map_io(void) ++{ ++ mx25_map_io(); ++} ++ ++static void __init karo_tx25_fixup(struct machine_desc *desc, struct tag *tags, ++ char **cmdline, struct meminfo *mi) ++{ ++} ++ ++static void __init karo_tx25_timer_init(void) ++{ ++ DBG(0, "%s: \n", __FUNCTION__); ++ mx25_clocks_init(24000000); ++ DBG(0, "%s: Done\n", __FUNCTION__); ++} ++ ++struct sys_timer karo_tx25_timer = { ++ .init = karo_tx25_timer_init, ++}; ++ ++static int __init karo_mod_type_setup(char *line) ++{ ++ get_option(&line, &karo_mod_type); ++ DBG(0, "%s: Module type set to 0x%02x by kernel cmd line\n", __FUNCTION__, karo_mod_type); ++ ++ return 1; ++} ++__setup("module_type=", karo_mod_type_setup); ++ ++static int __init karo_board_type_setup(char *line) ++{ ++ get_option(&line, &karo_board_type); ++ DBG(0, "%s: Board type set to 0x%02x by kernel cmd line\n", __FUNCTION__, karo_board_type); ++ ++ return 1; ++} ++__setup("board_type=", karo_board_type_setup); ++ ++MACHINE_START(TX25, "Ka-Ro electronics TX25 module (Freescale i.MX25)") ++ /* Maintainer: <LW@KARO-electronics.de> */ ++ .phys_io = AIPS1_BASE_ADDR, ++ .io_pg_offst = ((unsigned long)AIPS1_BASE_ADDR_VIRT >> 18) & 0xfffc, ++ .fixup = karo_tx25_fixup, ++ .map_io = karo_tx25_map_io, ++ .init_irq = mxc_init_irq, ++ .init_machine = karo_tx25_board_init, ++ .timer = &karo_tx25_timer, ++MACHINE_END +diff -urNp linux-2.6.30-rc4/arch/arm/mach-mx2/karo.h linux-2.6.30-rc4-karo/arch/arm/mach-mx2/karo.h +--- linux-2.6.30-rc4/arch/arm/mach-mx2/karo.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30-rc4-karo/arch/arm/mach-mx2/karo.h 2009-06-02 17:05:27.000000000 +0200 +@@ -0,0 +1,99 @@ ++/* ++ * arch/arm/mach-mx2/karo.h ++ * ++ * Copyright (C) 2009 Lothar Wassmann <LW@KARO-electronics.de> ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 as published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the: ++ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 ++ * ++ * This file provides platform specific definitions for the ++ * Ka-Ro electronics TX25 processor modules ++ */ ++ ++#include <linux/io.h> ++#include "crm_regs_mx25.h" ++ ++enum { ++ BOARD_KARO_STK5, ++}; ++ ++extern int karo_board_type; ++extern int karo_mod_type; ++ ++#ifdef DEBUG ++extern int tx25_debug; ++#define dbg_lvl(n) ((n) < tx25_debug) ++#define DBG(lvl, fmt...) do { if (dbg_lvl(lvl)) printk(KERN_DEBUG fmt); } while (0) ++#else ++#define dbg_lvl(n) 0 ++#define DBG(lvl, fmt...) do { } while (0) ++#endif ++ ++static inline int karo_get_board_type(void) ++{ ++ return karo_board_type; ++} ++ ++static inline int karo_get_module_type(void) ++{ ++ return karo_mod_type; ++} ++ ++#define SHOW_REG(reg) DBG(0, "%s[%08lx]=%08x\n", #reg, MXC_PHYS_ADDRESS(reg), __raw_readl(reg)) ++ ++#define SHOW_GPIO_REG(port, reg) \ ++ DBG(0, "GPIO%d_%s[%08lx]=%08x\n", port, #reg, \ ++ GPIO_BASE_ADDR(port) + GPIO_##reg, \ ++ __raw_readl(IO_ADDRESS(GPIO_BASE_ADDR(port) + GPIO_##reg))) ++ ++static inline void dump_regs(void) ++{ ++ int i; ++ ++ SHOW_REG(MXC_CCM_MPCTL); ++ SHOW_REG(MXC_CCM_UPCTL); ++ SHOW_REG(MXC_CCM_CCTL); ++ SHOW_REG(MXC_CCM_RCSR); ++ SHOW_REG(MXC_CCM_CRDR); ++ SHOW_REG(MXC_CCM_PCDR0); ++ SHOW_REG(MXC_CCM_PCDR1); ++ SHOW_REG(MXC_CCM_PCDR2); ++ SHOW_REG(MXC_CCM_PCDR3); ++ SHOW_REG(MXC_CCM_CGCR0); ++ SHOW_REG(MXC_CCM_CGCR1); ++ SHOW_REG(MXC_CCM_CGCR2); ++ SHOW_REG(MXC_CCM_MCR); ++ SHOW_REG(MXC_CCM_PMCR0); ++ SHOW_REG(MXC_CCM_PMCR1); ++ SHOW_REG(MXC_CCM_PMCR2); ++ SHOW_REG(MXC_CCM_LTBR0); ++ SHOW_REG(MXC_CCM_LTBR1); ++ SHOW_REG(MXC_CCM_LTR0); ++ SHOW_REG(MXC_CCM_LTR1); ++ SHOW_REG(MXC_CCM_LTR2); ++ SHOW_REG(MXC_CCM_LTR3); ++ SHOW_REG(MXC_CCM_DCVR0); ++ SHOW_REG(MXC_CCM_DCVR1); ++ SHOW_REG(MXC_CCM_DCVR2); ++ SHOW_REG(MXC_CCM_DCVR3); ++ ++ for (i = 1; i <= 4; i++) { ++ SHOW_GPIO_REG(i, DR); ++ SHOW_GPIO_REG(i, GDIR); ++ SHOW_GPIO_REG(i, PSR); ++ SHOW_GPIO_REG(i, ICR1); ++ SHOW_GPIO_REG(i, ICR2); ++ SHOW_GPIO_REG(i, IMR); ++ SHOW_GPIO_REG(i, ISR); ++ } ++} +diff -urNp linux-2.6.30-rc4/arch/arm/mach-mx2/sdma_script_code.h linux-2.6.30-rc4-karo/arch/arm/mach-mx2/sdma_script_code.h +--- linux-2.6.30-rc4/arch/arm/mach-mx2/sdma_script_code.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30-rc4-karo/arch/arm/mach-mx2/sdma_script_code.h 2009-06-02 17:05:27.000000000 +0200 +@@ -0,0 +1,159 @@ ++ ++/* ++ * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved. ++ */ ++ ++/* ++ * 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 ++ */ ++ ++/*! ++ * @file sdma_script_code.h ++ * @brief This file contains functions of SDMA scripts code initialization ++ * ++ * The file was generated automatically. Based on sdma scripts library. ++ * ++ * @ingroup SDMA ++ */ ++/************************************************************************ ++ ++ SDMA RELEASE LABEL: "SS15_SENNA" ++ ++************************************************************************/ ++ ++#ifndef SDMA_SCRIPT_CODE_H ++#define SDMA_SCRIPT_CODE_H ++ ++/*! ++ * SDMA ROM scripts start addresses and sizes ++ */ ++#define start_ADDR 0 ++#define start_SIZE 22 ++ ++#define core_ADDR 80 ++#define core_SIZE 233 ++ ++#define common_ADDR 313 ++#define common_SIZE 416 ++ ++#define ap_2_ap_ADDR 729 ++#define ap_2_ap_SIZE 41 ++ ++#define app_2_mcu_ADDR 770 ++#define app_2_mcu_SIZE 64 ++ ++#define mcu_2_app_ADDR 834 ++#define mcu_2_app_SIZE 70 ++ ++#define uart_2_mcu_ADDR 904 ++#define uart_2_mcu_SIZE 75 ++ ++#define shp_2_mcu_ADDR 979 ++#define shp_2_mcu_SIZE 69 ++ ++#define mcu_2_shp_ADDR 1048 ++#define mcu_2_shp_SIZE 72 ++ ++#define uartsh_2_mcu_ADDR 1120 ++#define uartsh_2_mcu_SIZE 69 ++ ++#define app_2_per_ADDR 1189 ++#define app_2_per_SIZE 66 ++ ++#define per_2_app_ADDR 1255 ++#define per_2_app_SIZE 74 ++ ++#define per_2_shp_ADDR 1329 ++#define per_2_shp_SIZE 78 ++ ++#define shp_2_per_ADDR 1407 ++#define shp_2_per_SIZE 72 ++ ++#define mcu_2_ata_ADDR 1479 ++#define mcu_2_ata_SIZE 81 ++ ++#define ata_2_mcu_ADDR 1560 ++#define ata_2_mcu_SIZE 96 ++ ++#define loop_DMAs_routines_ADDR 1656 ++#define loop_DMAs_routines_SIZE 227 ++ ++#define test_ADDR 1883 ++#define test_SIZE 63 ++ ++#define signature_ADDR 1022 ++#define signature_SIZE 1 ++ ++/*! ++ * SDMA RAM scripts start addresses and sizes ++ */ ++#define ext_mem__ipu_ram_ADDR 6144 ++#define ext_mem__ipu_ram_SIZE 123 ++ ++#define uart_2_per_ADDR 6267 ++#define uart_2_per_SIZE 73 ++ ++#define uartsh_2_per_ADDR 6340 ++#define uartsh_2_per_SIZE 67 ++ ++/*! ++ * SDMA RAM image start address and size ++ */ ++#define RAM_CODE_START_ADDR 6144 ++#define RAM_CODE_SIZE 263 ++ ++/*! ++ * Buffer that holds the SDMA RAM image ++ */ ++__attribute__ ((__aligned__(4))) ++#ifndef CONFIG_XIP_KERNEL ++const ++#endif ++static const short sdma_code[] = { ++ 0x0e70, 0x0611, 0x5616, 0xc18a, 0x7d2a, 0x5ade, 0x008e, 0xc19c, ++ 0x7c26, 0x5be0, 0x5ef0, 0x5ce8, 0x0688, 0x08ff, 0x0011, 0x28ff, ++ 0x00bc, 0x53f6, 0x05df, 0x7d0b, 0x6dc5, 0x03df, 0x7d03, 0x6bd5, ++ 0xd84f, 0x982b, 0x6b05, 0xc6d8, 0x7e27, 0x7f29, 0x982b, 0x6d01, ++ 0x03df, 0x7d05, 0x6bd5, 0xc702, 0x7e18, 0x7f1a, 0x982b, 0x6b05, ++ 0xc678, 0x7e07, 0x7f06, 0x52de, 0x53e6, 0xc1a8, 0x7dd7, 0x0200, ++ 0x9803, 0x0007, 0x6004, 0x680c, 0x53f6, 0x028e, 0x00a3, 0xc2ad, ++ 0x048b, 0x0498, 0x0454, 0x068a, 0x982b, 0x0207, 0x680c, 0x6ddf, ++ 0x0107, 0x68ff, 0x60d0, 0x9834, 0x0207, 0x68ff, 0x6d28, 0x0107, ++ 0x6004, 0x680c, 0x9834, 0x0007, 0x68ff, 0x60d0, 0x9834, 0x0288, ++ 0x03a5, 0x3b03, 0x3d03, 0x4d00, 0x7d0a, 0x0804, 0x00a5, 0x00da, ++ 0x7d1a, 0x02a0, 0x7b01, 0x65d8, 0x7eee, 0x65ff, 0x7eec, 0x0804, ++ 0x02d0, 0x7d11, 0x4b00, 0x7c0f, 0x008a, 0x3003, 0x6dcf, 0x6bdf, ++ 0x0015, 0x0015, 0x7b02, 0x65d8, 0x0000, 0x7edd, 0x63ff, 0x7edb, ++ 0x3a03, 0x6dcd, 0x6bdd, 0x008a, 0x7b02, 0x65d8, 0x0000, 0x7ed3, ++ 0x65ff, 0x7ed1, 0x0006, 0xc23a, 0x57db, 0x52f3, 0x6ad5, 0x56fb, ++ 0x028e, 0x1a94, 0x6ac3, 0x62c8, 0x0269, 0x7d1e, 0x1e94, 0x6ee3, ++ 0x62d0, 0x5aeb, 0x62c8, 0x0248, 0x6ed3, 0x6ac8, 0x2694, 0x52eb, ++ 0x6ad5, 0x6ee3, 0x62c8, 0x026e, 0x7d27, 0x6ac8, 0x7f23, 0x2501, ++ 0x4d00, 0x7d26, 0x028e, 0x1a98, 0x6ac3, 0x62c8, 0x6ec3, 0x0260, ++ 0x7df1, 0x62d0, 0xc2d1, 0x98c0, 0x6ee3, 0x008f, 0x2001, 0x00d5, ++ 0x7d01, 0x008d, 0x05a0, 0x62c8, 0x026e, 0x7d0e, 0x6ac8, 0x7f0a, ++ 0x2001, 0x7cf9, 0x6add, 0x7f06, 0x0000, 0x4d00, 0x7d09, 0xc251, ++ 0x57db, 0x987f, 0x0007, 0x6aff, 0x62d0, 0xc2d1, 0x0458, 0x0454, ++ 0x6add, 0x7ff8, 0xc261, 0x987c, 0xc230, 0xc23a, 0x57db, 0x52f3, ++ 0x6ad5, 0x56fb, 0x028e, 0x1a94, 0x5202, 0x0269, 0x7d17, 0x1e94, ++ 0x5206, 0x0248, 0x5a06, 0x2694, 0x5206, 0x026e, 0x7d26, 0x6ac8, ++ 0x7f22, 0x2501, 0x4d00, 0x7d27, 0x028e, 0x1a98, 0x5202, 0x0260, ++ 0x7df3, 0x6add, 0x7f18, 0x62d0, 0xc2d1, 0x9903, 0x008f, 0x2001, ++ 0x00d5, 0x7d01, 0x008d, 0x05a0, 0x5206, 0x026e, 0x7d0e, 0x6ac8, ++ 0x7f0a, 0x2001, 0x7cf9, 0x6add, 0x7f06, 0x0000, 0x4d00, 0x7d0b, ++ 0xc251, 0x57db, 0x98c9, 0x0007, 0x6aff, 0x6add, 0x7ffc, 0x62d0, ++ 0xc2d1, 0x0458, 0x0454, 0x6add, 0x7ff6, 0xc261, 0x98c6 ++}; ++#endif +diff -urNp linux-2.6.30-rc4/arch/arm/mach-mx2/stk5-baseboard.c linux-2.6.30-rc4-karo/arch/arm/mach-mx2/stk5-baseboard.c +--- linux-2.6.30-rc4/arch/arm/mach-mx2/stk5-baseboard.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30-rc4-karo/arch/arm/mach-mx2/stk5-baseboard.c 2009-06-02 17:05:27.000000000 +0200 +@@ -0,0 +1,1003 @@ ++/* ++ * arch/arm/mach-mx2/stk5-baseboard.c ++ * ++ * Copyright (C) 2009 Lothar Wassmann <LW@KARO-electronics.de> ++ * ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 as published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the: ++ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 ++ * ++ * This file adds support for devices found on Ka-Ro electronics ++ * Starterkit-5 (STK5) baseboard ++ */ ++ ++#include <linux/types.h> ++#include <linux/sched.h> ++#include <linux/interrupt.h> ++#include <linux/init.h> ++#include <linux/ioport.h> ++#include <linux/platform_device.h> ++#include <linux/input.h> ++#include <linux/clk.h> ++#include <linux/delay.h> ++#include <linux/fb.h> ++#include <linux/i2c.h> ++#include <linux/i2c/at24.h> ++#include <linux/spi/spi.h> ++//#include <linux/serial_8250.h> ++ ++#include <linux/serial.h> ++#include <linux/fsl_devices.h> ++#include <linux/irq.h> ++#include <linux/mmc/host.h> ++#include <linux/gpio_keys.h> ++#include <linux/leds.h> ++ ++#include <asm/setup.h> ++#include <asm/irq.h> ++#include <asm/mach-types.h> ++#include <asm/mach/arch.h> ++#include <asm/mach/time.h> ++#include <mach/common.h> ++#include <mach/hardware.h> ++#include <mach/gpio.h> ++#include <mach/iomux.h> ++#include <mach/irqs.h> ++#include <mach/clock.h> ++#include <mach/imxfb.h> ++//#include <mach/imx_spi.h> ++#include <mach/i2c.h> ++#include <mach/mmc.h> ++#include <mach/imx-uart.h> ++//#include <mach/ulpi.h> ++//#include <mach/mxc_ehci.h> ++#include <mach/board-stk5.h> ++ ++#include "crm_regs.h" ++#include "devices.h" ++#include "karo.h" ++ ++#if defined(CONFIG_SERIAL_IMX) || defined(CONFIG_SERIAL_IMX_MODULE) ++static struct pad_desc stk5_uart_pads[][4] = { ++ { ++ MX25_PAD_UART1_TXD__UART1_TXD, ++ MX25_PAD_UART1_RXD__UART1_RXD, ++ MX25_PAD_UART1_CTS__UART1_CTS, ++ MX25_PAD_UART1_RTS__UART1_RTS, ++ }, { ++ MX25_PAD_UART2_TXD__UART2_TXD, ++ MX25_PAD_UART2_RXD__UART2_RXD, ++ MX25_PAD_UART2_CTS__UART2_CTS, ++ MX25_PAD_UART2_RTS__UART2_RTS, ++ }, { ++ MX25_PAD_ECB__UART5_TXD_MUX, ++ MX25_PAD_LBA__UART5_RXD_MUX, ++ MX25_PAD_CS4__UART5_CTS, ++ MX25_PAD_CS5__UART5_RTS, ++#if 0 ++ }, { ++ MX25_PAD_UART4_TXD__UART4_TXD, ++ MX25_PAD_UART4_RXD__UART4_RXD, ++ MX25_PAD_UART4_CTS__UART4_CTS, ++ MX25_PAD_UART4_RTS__UART4_RTS, ++ }, { ++ MX25_PAD_UART5_TXD__UART5_TXD, ++ MX25_PAD_UART5_RXD__UART5_RXD, ++ MX25_PAD_UART5_CTS__UART5_CTS, ++ MX25_PAD_UART5_RTS__UART5_RTS, ++#endif ++ }, ++}; ++ ++static int stk5_uart_init(struct platform_device *pdev) ++{ ++ DBG(0, "%s: \n", __FUNCTION__); ++ return mxc_iomux_v3_setup_multiple_pads(stk5_uart_pads[pdev->id], ++ ARRAY_SIZE(stk5_uart_pads[pdev->id])); ++} ++ ++static void stk5_uart_exit(struct platform_device *pdev) ++{ ++ DBG(0, "%s: \n", __FUNCTION__); ++ mxc_iomux_v3_release_multiple_pads(stk5_uart_pads[pdev->id], ++ ARRAY_SIZE(stk5_uart_pads[pdev->id])); ++} ++ ++static struct imxuart_platform_data stk5_uart_ports[] = { ++ { ++ .init = stk5_uart_init, ++ .exit = stk5_uart_exit, ++ .flags = IMXUART_HAVE_RTSCTS, ++ }, { ++ .init = stk5_uart_init, ++ .exit = stk5_uart_exit, ++ .flags = IMXUART_HAVE_RTSCTS, ++ }, { ++ .init = stk5_uart_init, ++ .exit = stk5_uart_exit, ++ .flags = IMXUART_HAVE_RTSCTS, ++ }, { ++ .init = stk5_uart_init, ++ .exit = stk5_uart_exit, ++ .flags = IMXUART_HAVE_RTSCTS, ++ }, { ++ .init = stk5_uart_init, ++ .exit = stk5_uart_exit, ++ .flags = IMXUART_HAVE_RTSCTS, ++ }, { ++ .init = stk5_uart_init, ++ .exit = stk5_uart_exit, ++ .flags = IMXUART_HAVE_RTSCTS, ++ }, ++}; ++ ++static struct platform_device *stk5_uart_devices[] = { ++#if UART1_ENABLED ++ &mxc_uart_device0, ++#endif ++#if UART2_ENABLED ++ &mxc_uart_device1, ++#endif ++#if UART3_ENABLED ++ &mxc_uart_device2, ++#endif ++#if UART4_ENABLED ++ &mxc_uart_device3, ++#endif ++#if UART5_ENABLED ++ &mxc_uart_device4, ++#endif ++}; ++ ++static void __init karo_stk5_serial_init(void) ++{ ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(stk5_uart_devices); i++) { ++ int ret; ++ int port = stk5_uart_devices[i]->id; ++ ++ DBG(0, "%s: Registering platform device[%d] @ %p dev %p: %s\n", ++ __FUNCTION__, i, stk5_uart_devices[i], ++ &stk5_uart_devices[i]->dev, stk5_uart_devices[i]->name); ++ ret = mxc_register_device(stk5_uart_devices[i], ++ &stk5_uart_ports[port]); ++ if (ret != 0) { ++ printk(KERN_WARNING "%s: Failed to register platform_device[%d]: %s: %d\n", ++ __FUNCTION__, i, stk5_uart_devices[i]->name, ret); ++ } ++ } ++} ++#else ++static void __init karo_stk5_serial_init(void) ++{ ++} ++#endif ++ ++#ifdef CONFIG_USB_EHCI_MXC ++ ++#define SMSC_VENDOR_ID 0x0424 ++#define USB3317_PROD_ID 0x0006 ++#define ULPI_FCTL 7 ++ ++static inline const char *ulpi_name(void __iomem *view) ++{ ++ if ((unsigned long)view & 0x400) { ++ return "USBH2"; ++ } else { ++ return "USBOTG"; ++ } ++} ++ ++static int usb3317_init(void __iomem *view) ++{ ++ int vid, pid, ret; ++ ++ ret = ulpi_read(ISP1504_VID_HIGH, view); ++ if (ret < 0) { ++ goto err; ++ } ++ vid = ret << 8; ++ ++ ret = ulpi_read(ISP1504_VID_LOW, view); ++ if (ret < 0) { ++ goto err; ++ } ++ vid |= ret; ++ ++ ret = ulpi_read(ISP1504_PID_HIGH, view); ++ if (ret < 0) { ++ goto err; ++ } ++ pid = ret << 8; ++ ++ ret = ulpi_read(ISP1504_PID_LOW, view); ++ if (ret < 0) { ++ goto err; ++ } ++ pid |= ret; ++ ++ pr_info("ULPI on %s port Vendor ID 0x%x Product ID 0x%x\n", ++ ulpi_name(view), vid, pid); ++ if (vid != SMSC_VENDOR_ID || pid != USB3317_PROD_ID) { ++ pr_err("No USB3317 found\n"); ++ return -ENODEV; ++ } ++ err: ++ if (ret < 0) { ++ printk(KERN_ERR "ULPI read on %s port failed with error %d\n", ++ ulpi_name(view), ret); ++ return ret; ++ } ++ return 0; ++} ++ ++static int usb3317_set_vbus_power(void __iomem *view, int on) ++{ ++ int ret; ++ ++ DBG(0, "%s: Switching %s port VBUS power %s\n", __FUNCTION__, ++ ulpi_name(view), on ? "on" : "off"); ++ ++ if (on) { ++ ret = ulpi_set(DRV_VBUS_EXT | /* enable external Vbus */ ++ DRV_VBUS | /* enable internal Vbus */ ++ CHRG_VBUS, /* charge Vbus */ ++ ISP1504_OTGCTL, view); ++ } else { ++ ret = ulpi_clear(DRV_VBUS_EXT | /* disable external Vbus */ ++ DRV_VBUS, /* disable internal Vbus */ ++ ISP1504_OTGCTL, view); ++ if (ret == 0) { ++ ret = ulpi_set(DISCHRG_VBUS, /* discharge Vbus */ ++ ISP1504_OTGCTL, view); ++ } ++ } ++ if (ret < 0) { ++ printk(KERN_ERR "ULPI read on %s port failed with error %d\n", ++ ulpi_name(view), ret); ++ return ret; ++ } ++ return 0; ++} ++ ++static int stk5_usbh2_init(struct platform_device *pdev) ++{ ++ int ret; ++ u32 temp; ++ unsigned long flags; ++ void __iomem *view = IO_ADDRESS(OTG_BASE_ADDR + 0x570); ++ ++ local_irq_save(flags); ++ temp = readl(IO_ADDRESS(OTG_BASE_ADDR) + 0x600); ++ temp &= ~((3 << 21) | (1 << 0)); ++ temp |= (1 << 5) | (1 << 16) | (1 << 19) | (1 << 20); ++ writel(temp, IO_ADDRESS(OTG_BASE_ADDR) + 0x600); ++ local_irq_restore(flags); ++ ++ /* select ULPI transceiver */ ++ /* this must be done _before_ setting up the GPIOs! */ ++ temp = readl(view + 0x14); ++ DBG(0, "%s: Changing USBH2_PORTSC1 from %08x to %08x\n", __FUNCTION__, ++ temp, (temp & ~(3 << 30)) | (2 << 30)); ++ temp &= ~(3 << 30); ++ temp |= 2 << 30; ++ writel(temp, view + 0x14); ++ ++ /* Set to Host mode */ ++ temp = readl(view + 0x38); ++ DBG(0, "%s: Changing USBH2_USBMODE from %08x to %08x\n", __FUNCTION__, ++ temp, temp | 3); ++ writel(temp | 0x3, view + 0x38); ++ ++ ret = gpio_usbh2_active(); ++ if (ret != 0) { ++ return ret; ++ } ++ ++ ret = usb3317_init(view); ++ if (ret != 0) { ++ goto err; ++ } ++ ret = usb3317_set_vbus_power(view, 1); ++ if (ret != 0) { ++ goto err; ++ } ++ return 0; ++ ++ err: ++ gpio_usbh2_inactive(); ++ return ret; ++} ++ ++static int stk5_usbh2_exit(struct platform_device *pdev) ++{ ++ gpio_usbh2_inactive(); ++ return 0; ++} ++ ++static struct mxc_usbh_platform_data stk5_usbh2_data = { ++ .init = stk5_usbh2_init, ++ .exit = stk5_usbh2_exit, ++}; ++ ++static int __init karo_stk5_usbh2_register(void) ++{ ++ int ret; ++ ++ ret = mxc_register_device(&mxc_ehci2, &stk5_usbh2_data); ++ return ret; ++} ++#else ++static inline int karo_stk5_usbh2_register(void) ++{ ++ return 0; ++} ++#endif // CONFIG_USB_EHCI_MXC ++ ++#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE) ++static struct gpio_led stk5_leds[] = { ++ { ++ .name = "GPIO-LED", ++ .default_trigger = "heartbeat", ++ .gpio = GPIO_PORTB | 7, ++ }, ++}; ++ ++static struct gpio_led_platform_data stk5_led_data = { ++ .leds = stk5_leds, ++ .num_leds = ARRAY_SIZE(stk5_leds), ++}; ++ ++static struct platform_device stk5_led_device = { ++ .name = "leds-gpio", ++ .id = -1, ++ .dev = { ++ .platform_data = &stk5_led_data, ++ }, ++}; ++#endif ++ ++#if defined(CONFIG_KEYBOARD_MXC) || defined(CONFIG_KEYBOARD_MXC_MODULE) ++/*! ++ * This array is used for mapping mx25 ADS keypad scancodes to input keyboard ++ * keycodes. ++ */ ++static u16 stk5_kpd_keycodes[] = { ++ KEY_POWER, ++}; ++ ++static struct keypad_data stk5_keypad = { ++ .rowmax = 1, ++ .colmax = 1, ++ .irq = MXC_INT_KPP, ++ .learning = 0, ++ //.delay = 2, /* unused in the driver! */ ++ .matrix = stk5_kpd_keycodes, ++}; ++ ++static struct resource stk5_kpp_resources[] = { ++ { ++ .start = MXC_INT_KPP, ++ .end = MXC_INT_KPP, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++/* stk5 keypad driver */ ++static struct platform_device stk5_keypad_device = { ++ .name = "mxc_keypad", ++ .id = 0, ++ .num_resources = ARRAY_SIZE(stk5_kpp_resources), ++ .resource = stk5_kpp_resources, ++ .dev = { ++ .platform_data = &stk5_keypad, ++ }, ++}; ++#endif ++ ++#if defined(CONFIG_FB_IMX) || defined(CONFIG_FB_IMX_MODULE) ++/* ++ * Setup GPIO for LCDC device to be active ++ * ++ */ ++static struct pad_desc mx25_lcdc_gpios[] = { ++#if 0 ++ MXC_PIN(A, 30, GPIO, GPIO_OUT | GPIO_DFLT_LOW), /* PA30 */ ++ MXC_PIN(A, 25, GPIO, GPIO_OUT | GPIO_DFLT_LOW), /* PA25 */ ++ MXC_PIN(A, 26, GPIO, GPIO_OUT | GPIO_DFLT_LOW), /* PA26 */ ++ MXC_PIN(A, 24, GPIO, GPIO_OUT | GPIO_DFLT_LOW), /* PA24 */ ++ MXC_PIN(A, 27, GPIO, GPIO_OUT | GPIO_DFLT_LOW), /* PA27 */ ++#endif ++ MX25_PAD_LSCLK__LSCLK, ++ MX25_PAD_LD0__LD0, ++ MX25_PAD_LD1__LD1, ++ MX25_PAD_LD2__LD2, ++ MX25_PAD_LD3__LD3, ++ MX25_PAD_LD4__LD4, ++ MX25_PAD_LD5__LD5, ++ MX25_PAD_LD6__LD6, ++ MX25_PAD_LD7__LD7, ++ MX25_PAD_LD8__LD8, ++ MX25_PAD_LD9__LD9, ++ MX25_PAD_LD10__LD10, ++ MX25_PAD_LD11__LD11, ++ MX25_PAD_LD12__LD12, ++ MX25_PAD_LD13__LD13, ++ MX25_PAD_LD14__LD14, ++ MX25_PAD_LD15__LD15, ++ MX25_PAD_D15__LD16, ++ MX25_PAD_D14__LD17, ++ MX25_PAD_HSYNC__HSYNC, ++ MX25_PAD_VSYNC__VSYNC, ++ MX25_PAD_OE_ACD__OE_ACD, ++}; ++ ++static int stk5_gpio_lcdc_active(struct platform_device *dev) ++{ ++ int ret; ++ ++ DBG(0, "%s: Setting up GPIO pins for LCD\n", __FUNCTION__); ++ ret = mxc_iomux_v3_setup_multiple_pads(mx25_lcdc_gpios, ++ ARRAY_SIZE(mx25_lcdc_gpios)); ++ if (ret) { ++ DBG(0, "%s: Failed to setup GPIO pins for LCD: %d\n", ++ __FUNCTION__, ret); ++ return ret; ++ } ++ return 0; ++} ++ ++/* ++ * Setup GPIO for LCDC device to be inactive ++ * ++ */ ++static void stk5_gpio_lcdc_inactive(struct platform_device *dev) ++{ ++ mxc_iomux_v3_release_multiple_pads(mx25_lcdc_gpios, ++ ARRAY_SIZE(mx25_lcdc_gpios)); ++} ++ ++static struct imx_fb_platform_data stk5_fb_data[] __initdata = { ++ { ++ //.fb_mode = "Xenarc_700_Y-18", ++ .init = stk5_gpio_lcdc_active, ++ .exit = stk5_gpio_lcdc_inactive, ++ .lcd_power = NULL, ++ .backlight_power = NULL, ++ ++ .pixclock = 34576, ++ .xres = 640, ++ .yres = 480, ++ ++ .bpp = 32, ++ ++ .hsync_len = 64, ++ .right_margin = 60 + 1, ++ .left_margin = 80 + 3, ++ ++ .vsync_len = 2, ++ .upper_margin = 54, ++ .lower_margin = 54, ++#if 0 ++ /* currently not used by driver! */ ++ .sync = ((0*FB_SYNC_HOR_HIGH_ACT) | ++ (0*FB_SYNC_VERT_HIGH_ACT) | ++ (1*FB_SYNC_OE_ACT_HIGH)), ++#else ++ .pcr = PCR_TFT | PCR_COLOR | PCR_PBSIZ_8 | ++ PCR_BPIX_18 | PCR_END_SEL | PCR_FLMPOL | PCR_LPPOL | PCR_SCLK_SEL, ++ .dmacr = 0x800a0078, ++#endif ++ .cmap_greyscale = 0, ++ .cmap_inverse = 0, ++ .cmap_static = 0, ++ ++ .fixed_screen_cpu = NULL, ++ }, { ++ //.fb_mode = "Xenarc_700_Y-16", ++ .init = stk5_gpio_lcdc_active, ++ .exit = stk5_gpio_lcdc_inactive, ++ .lcd_power = NULL, ++ .backlight_power = NULL, ++ ++ .pixclock = 34576, ++ .xres = 640, ++ .yres = 480, ++ ++ .bpp = 16, ++ ++ .hsync_len = 64, ++ .right_margin = 138 + 1, ++ .left_margin = 118 + 3, ++ ++ .vsync_len = 7, ++ .upper_margin = 44, ++ .lower_margin = 44, ++#if 0 ++ /* currently not used by driver! */ ++ .sync = ((0*FB_SYNC_HOR_HIGH_ACT) | ++ (0*FB_SYNC_VERT_HIGH_ACT) | ++ (1*FB_SYNC_OE_ACT_HIGH)), ++#else ++ .pcr = PCR_TFT | PCR_COLOR | PCR_PBSIZ_8 | ++ PCR_BPIX_16 | PCR_FLMPOL | PCR_LPPOL | PCR_SCLK_SEL, ++ .dmacr = 0x80040060, ++#endif ++ .cmap_greyscale = 0, ++ .cmap_inverse = 0, ++ .cmap_static = 0, ++ ++ .fixed_screen_cpu = NULL, ++ }, { ++ //.fb_mode = "SHARP LQ10D42-16", ++ .init = stk5_gpio_lcdc_active, ++ .exit = stk5_gpio_lcdc_inactive, ++ .lcd_power = NULL, ++ .backlight_power = NULL, ++ ++ .pixclock = 34576, ++ .xres = 640, ++ .yres = 480, ++ ++#ifdef USE_18BPP ++ .bpp = 32, ++#else ++ .bpp = 16, ++#endif ++ .hsync_len = 64, ++ .right_margin = 138 + 1, ++ .left_margin = 118 + 3, ++ ++ .vsync_len = 7, ++ .upper_margin = 28, ++ .lower_margin = 60, ++#if 0 ++ /* currently not used by driver! */ ++ .sync = ((0*FB_SYNC_HOR_HIGH_ACT) | ++ (0*FB_SYNC_VERT_HIGH_ACT) | ++ (1*FB_SYNC_OE_ACT_HIGH)), ++#else ++ .pcr = PCR_TFT | PCR_COLOR | PCR_PBSIZ_8 | ++#ifdef USE_18BPP ++ PCR_BPIX_18 | PCR_END_SEL | PCR_FLMPOL | PCR_LPPOL | PCR_SCLK_SEL, ++#else ++ PCR_BPIX_16 | PCR_FLMPOL | PCR_LPPOL | PCR_SCLK_SEL, ++#endif ++ .dmacr = 0x80040060, ++#endif ++ .cmap_greyscale = 0, ++ .cmap_inverse = 0, ++ .cmap_static = 0, ++ ++ .fixed_screen_cpu = NULL, ++ }, { ++ //.fb_mode = "SHARP LQ104V1DG61-16", ++ .init = stk5_gpio_lcdc_active, ++ .exit = stk5_gpio_lcdc_inactive, ++ .lcd_power = NULL, ++ .backlight_power = NULL, ++ ++ .pixclock = 40000, ++ .xres = 640, ++ .yres = 480, ++ ++#ifdef USE_18BPP ++ .bpp = 32, ++#else ++ .bpp = 16, ++#endif ++ .hsync_len = 32, ++ .right_margin = 32 + 1, ++ .left_margin = 0 + 3, ++ ++ .vsync_len = 35, ++ .upper_margin = 0, ++ .lower_margin = 0, ++#if 0 ++ /* currently not used by driver! */ ++ .sync = ((0*FB_SYNC_HOR_HIGH_ACT) | ++ (0*FB_SYNC_VERT_HIGH_ACT) | ++ (1*FB_SYNC_OE_ACT_HIGH)), ++#else ++ .pcr = PCR_TFT | PCR_COLOR | PCR_PBSIZ_8 | ++#ifdef USE_18BPP ++ PCR_BPIX_18 | PCR_END_SEL | PCR_FLMPOL | PCR_LPPOL | PCR_SCLK_SEL, ++#else ++ PCR_BPIX_16 | PCR_FLMPOL | PCR_LPPOL | PCR_CLKPOL | PCR_SCLK_SEL, ++#endif ++ .dmacr = 0x80040060, ++#endif ++ .cmap_greyscale = 0, ++ .cmap_inverse = 0, ++ .cmap_static = 0, ++ ++ .fixed_screen_cpu = NULL, ++ }, ++}; ++ ++static int __init karo_stk5_fb_register(void) ++{ ++ int ret; ++ ++ ret = mxc_register_device(&mxc_fb_device, &stk5_fb_data[0]); ++ if (ret != 0) { ++ DBG(0, "%s: Failed to register FB device: %d\n", __FUNCTION__, ret); ++ } ++ return ret; ++} ++#else ++static inline int karo_stk5_fb_register(void) ++{ ++ return 0; ++} ++#endif ++ ++#if defined(CONFIG_MMC_MXC) || defined(CONFIG_MMC_MXC_MODULE) ++/*! ++ * Resource definition for the SDHC1 ++ */ ++static struct resource stk5_sdhc1_resources[] = { ++ { ++ .start = MMC_SDHC1_BASE_ADDR, ++ .end = MMC_SDHC1_BASE_ADDR + SZ_4K - 1, ++ .flags = IORESOURCE_MEM, ++ }, { ++ .start = MXC_INT_SDHC1, ++ .end = MXC_INT_SDHC1, ++ .flags = IORESOURCE_IRQ, ++ }, { ++ .start = gpio_to_irq(4 * 32 + 4), ++ .end = gpio_to_irq(4 * 32 + 4), ++ .flags = IORESOURCE_IRQ, ++#if 0 ++ }, { ++ .name = "sdhc1", ++ .start = DMA_REQ_SDHC1, ++ .end = DMA_REQ_SDHC1, ++ .flags = IORESOURCE_DMA ++#endif ++ }, ++}; ++ ++static inline int stk5_mmc_get_irq(int id) ++{ ++ int irq; ++ ++ switch (id) { ++ case 0: ++ irq = stk5_sdhc1_resources[2].start; ++ break; ++ default: ++ BUG(); ++ } ++ return irq; ++} ++ ++static const char *stk5_mmc_irqdesc[] = { ++ "MMC card 0 detect", ++}; ++ ++static struct pad_desc stk5_sdhc_pads[] = { ++}; ++ ++static int stk5_mmc_init(struct device *dev, irqreturn_t (*mmc_detect_irq)(int, void *), ++ void *data) ++{ ++ int err; ++ int id = to_platform_device(dev)->id; ++ struct mmc_host *host = data; ++ int irq = stk5_mmc_get_irq(id); ++ ++ err = mxc_iomux_v3_setup_multiple_pads(stk5_sdhc_pads, ++ ARRAY_SIZE(stk5_sdhc_pads)); ++ if (err) { ++ return err; ++ } ++ ++ host->caps |= MMC_CAP_4_BIT_DATA; ++ ++ err = request_irq(irq, mmc_detect_irq, ++ IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, ++ stk5_mmc_irqdesc[id], data); ++ if (err) { ++ printk(KERN_ERR "%s: MMC/SD: can't request MMC card detect IRQ %d\n", ++ __FUNCTION__, irq); ++ return err; ++ } ++ device_set_wakeup_capable(dev, 1); ++ ++ return 0; ++} ++ ++static void stk5_mmc_exit(struct device *dev, void *data) ++{ ++ int id = to_platform_device(dev)->id; ++ int irq = stk5_mmc_get_irq(id); ++ ++ free_irq(irq, data); ++ mxc_iomux_v3_release_multiple_pads(stk5_sdhc_pads, ++ ARRAY_SIZE(stk5_sdhc_pads)); ++} ++ ++#if 0 ++static int stk5_mmc_suspend(struct device *dev, pm_message_t state) ++{ ++ int id = to_platform_device(dev)->id; ++ int irq = stk5_mmc_get_irq(id); ++ ++ if (device_may_wakeup(dev)) { ++ DBG(0, "%s: Enabling IRQ %d wakeup\n", __FUNCTION__, irq); ++ return enable_irq_wake(irq); ++ } ++ return 0; ++} ++ ++static int stk5_mmc_resume(struct device *dev) ++{ ++ int id = to_platform_device(dev)->id; ++ int irq = stk5_mmc_get_irq(id); ++ ++ if (device_may_wakeup(dev)) { ++ DBG(0, "%s: Disabling IRQ %d wakeup\n", __FUNCTION__, irq); ++ return disable_irq_wake(irq); ++ } ++ return 0; ++} ++#endif ++ ++static struct imxmmc_platform_data stk5_sdhc1_data = { ++ //.ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, ++ //.min_clk = 150000, ++ //.max_clk = 25000000, ++ //.detect_delay = 20, ++ .init = stk5_mmc_init, ++ .exit = stk5_mmc_exit, ++// .suspend = stk5_mmc_suspend, ++// .resume = stk5_mmc_resume, ++}; ++ ++static struct platform_device stk5_sdhc1_device = { ++ .name = "imx-mmc", ++ .id = 0, ++ .dev = { ++ .platform_data = &stk5_sdhc1_data, ++ }, ++ .num_resources = ARRAY_SIZE(stk5_sdhc1_resources), ++ .resource = stk5_sdhc1_resources, ++}; ++#endif ++ ++#if defined(CONFIG_SPI_MXC) || defined(CONFIG_SPI_MXC_MODULE) ++static struct resource mxcspi1_resources[] = { ++ { ++ .start = CSPI1_BASE_ADDR, ++ .end = CSPI1_BASE_ADDR + SZ_4K - 1, ++ .flags = IORESOURCE_MEM, ++ }, { ++ .start = MXC_INT_CSPI1, ++ .end = MXC_INT_CSPI1, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++static struct mxc_spi_master mxcspi1_data = { ++ .maxchipselect = 2, ++ .spi_version = 0, ++}; ++ ++static struct platform_device mxcspi1_device = { ++ .name = "mxc_spi", ++ .id = 0, ++ .dev = { ++ .platform_data = &mxcspi1_data, ++ }, ++ .num_resources = ARRAY_SIZE(mxcspi1_resources), ++ .resource = mxcspi1_resources, ++}; ++#endif // defined(CONFIG_SPI_MXC) || defined(CONFIG_SPI_MXC_MODULE) ++ ++#if defined(CONFIG_AC97_BUS) || defined(CONFIG_AC97_BUS_MODULE) ++static u64 stk5_dma_mask = ~0UL; ++ ++static struct pad_desc stk5_ac97_pads_on[] = { ++ MX25_PAD_VSTBY_ACK__GPIO_3_18, /* UCB1400 Reset */ ++ MX25_PAD_RW__AUD4_TXFS, ++ MX25_PAD_EB0__AUD4_TXD, ++ MX25_PAD_EB1__AUD4_RXD, ++ MX25_PAD_OE__AUD4_TXC, ++}; ++ ++static struct pad_desc stk5_ac97_pads_off[] = { ++ MX25_PAD_VSTBY_ACK__GPIO_3_18, /* UCB1400 Reset */ ++ MX25_PAD_RW__GPIO_3_25, ++ MX25_PAD_EB0__GPIO_2_12, ++ MX25_PAD_EB1__AUD4_RXD, ++ MX25_PAD_OE__AUD4_TXC, ++}; ++ ++static struct gpio_desc { ++ unsigned int gpio:7; ++ unsigned int dir:1; ++ unsigned int level:1; ++} stk5_ac97_gpios[] = { ++ /* configure the PHY strap pins to the correct values */ ++ { GPIO_PORTC | 18, 1, 0, }, ++ { GPIO_PORTC | 25, 1, 0, }, ++ { GPIO_PORTB | 12, 1, 0, }, ++}; ++ ++static int stk5_ac97_init(struct platform_device *dev) ++{ ++ int ret; ++ int i; ++ ++ DBG(0, "%s: \n", __FUNCTION__); ++ ++ ret = mxc_iomux_v3_setup_multiple_pads(stk5_ac97_pads_off, ++ ARRAY_SIZE(stk5_ac97_pads_off)); ++ if (ret == 0) { ++ for (i = 0; i < ARRAY_SIZE(stk5_ac97_gpios); i++) { ++ struct gpio_desc *pd = &stk5_ac97_gpios[i]; ++ ++ ret = gpio_request(pd->gpio, "AC97"); ++ if (ret < 0) { ++ DBG(0, "%s: Failed to request GPIO%d_%d: %d\n", ++ __FUNCTION__, pd->gpio / 32 + 1, pd->gpio % 32, ret); ++ goto rel_mux; ++ } ++ if (pd->dir) { ++ gpio_direction_output(pd->gpio, ++ pd->level); ++ } else { ++ gpio_direction_input(pd->gpio); ++ } ++ } ++ ++ ret = mxc_iomux_v3_setup_multiple_pads(stk5_ac97_pads_on, ++ ARRAY_SIZE(stk5_ac97_pads_on)); ++ if (ret != 0) { ++ goto rel_gpio; ++ } ++ udelay(1); ++ gpio_set_value(stk5_ac97_gpios[0].gpio, !stk5_ac97_gpios[0].level); ++ } ++ return ret; ++ ++ rel_mux: ++ mxc_iomux_v3_release_multiple_pads(stk5_ac97_gpios_off, ++ ARRAY_SIZE(stk5_ac97_gpios_off)); ++ rel_gpio: ++ while (--i >= 0) { ++ struct gpio_desc *pd = &stk5_ac97_gpios[i]; ++ int grp = pd->gpio / 32 + 1; ++ int ofs = pd->gpio % 32; ++ ++ DBG(0, "%s: Freeing GPIO%d_%d\n", __FUNCTION__, ++ grp, ofs); ++ gpio_free(pd->gpio); ++ } ++ return ret; ++} ++ ++static void stk5_ac97_exit(struct platform_device *dev) ++{ ++ int i; ++ ++ DBG(0, "%s: Releasing AC97 GPIO pins\n", __FUNCTION__); ++ ++ mxc_iomux_v3_release_multiple_pads(stk5_ac97_pads_on, ++ ARRAY_SIZE(stk5_ac97_pads_on)); ++ for (i = 0; i < ARRAY_SIZE(stk5_ac97_gpios); i++) { ++ struct gpio_desc *pd = &stk5_ac97_gpios[i]; ++ int grp = pd->gpio / 32 + 1; ++ int ofs = pd->gpio % 32; ++ ++ DBG(0, "%s: Freeing GPIO%d_%d\n", __FUNCTION__, ++ grp, ofs); ++ gpio_free(pd->gpio); ++ } ++} ++ ++static struct mxc_ac97_audio_ops stk5_ac97_ops = { ++ .init = stk5_ac97_init, ++ .exit = stk5_ac97_exit, ++ .startup = NULL, ++ .shutdown = NULL, ++ .suspend = NULL, ++ .resume = NULL, ++ .priv = NULL, ++}; ++ ++static struct platform_device ac97_device = { ++ .name = "mx25-ac97", ++ .id = -1, ++ .dev = { ++ .dma_mask = &stk5_dma_mask, ++ .coherent_dma_mask = ~0UL, ++ .platform_data = &stk5_ac97_ops, ++ }, ++}; ++#endif ++ ++static struct platform_dev_list { ++ struct platform_device *pdev; ++ int flag; ++} stk5_devices[] __initdata = { ++#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE) ++ { .pdev = &stk5_led_device, .flag = -1, }, ++#endif ++#if defined(CONFIG_KEYBOARD_MXC) || defined(CONFIG_KEYBOARD_MXC_MODULE) ++ { .pdev = &stk5_keypad_device, .flag = 1, }, ++#endif ++#if defined(CONFIG_SPI_MXC) || defined(CONFIG_SPI_MXC_MODULE) ++ { .pdev = &mxcspi1_device, .flag = 1, }, ++#endif ++#if defined(CONFIG_AC97_BUS) || defined(CONFIG_AC97_BUS_MODULE) ++ { .pdev = &ac97_device, .flag = 1, }, ++#endif ++#if defined(CONFIG_MMC_MXC) || defined(CONFIG_MMC_MXC_MODULE) ++ { .pdev = &stk5_sdhc1_device, .flag = 1, }, ++#endif ++}; ++#define STK5_NUM_DEVICES ARRAY_SIZE(stk5_devices) ++ ++static __init int karo_stk5_board_init(void) ++{ ++ int ret; ++ int i; ++ ++ if (karo_get_board_type() != BOARD_KARO_STK5) { ++ return -ENODEV; ++ } ++ DBG(0, "%s: \n", __FUNCTION__); ++ ++ karo_stk5_serial_init(); ++ ++ dump_regs(); ++ ++ /* enable SSI1_INT (GPIO_3_15) for IRQ probing */ ++ set_irq_flags(gpio_to_irq(GPIO_PORTC | 15), IRQF_VALID | IRQF_PROBE); ++ ++ ret = karo_stk5_fb_register(); ++ if (ret) { ++ printk(KERN_WARNING "%s: karo_stk5_fb_register() failed: %d\n", ++ __FUNCTION__, ret); ++ } ++ ret = karo_stk5_usbh2_register(); ++ if (ret) { ++ printk(KERN_WARNING "%s: karo_stk5_usbh2_register() failed: %d\n", ++ __FUNCTION__, ret); ++ } ++ ++ for (i = 0; i < STK5_NUM_DEVICES; i++) { ++ if (stk5_devices[i].pdev == NULL) continue; ++ if (!stk5_devices[i].flag) { ++ DBG(0, "%s: Skipping platform device[%d] @ %p dev %p: %s\n", ++ __FUNCTION__, i, stk5_devices[i].pdev, &stk5_devices[i].pdev->dev, ++ stk5_devices[i].pdev->name); ++ continue; ++ } ++ DBG(0, "%s: Registering platform device[%d] @ %p dev %p: %s\n", ++ __FUNCTION__, i, stk5_devices[i].pdev, &stk5_devices[i].pdev->dev, ++ stk5_devices[i].pdev->name); ++ ret = platform_device_register(stk5_devices[i].pdev); ++ if (ret) { ++ printk(KERN_WARNING "%s: Failed to register platform_device[%d]: %s: %d\n", ++ __FUNCTION__, i, stk5_devices[i].pdev->name, ret); ++ } ++ } ++ DBG(0, "%s: Done\n", __FUNCTION__); ++ return 0; ++} ++subsys_initcall(karo_stk5_board_init); +diff -urNp linux-2.6.30-rc4/arch/arm/mach-mx3/clock-imx35.c linux-2.6.30-rc4-karo/arch/arm/mach-mx3/clock-imx35.c +--- linux-2.6.30-rc4/arch/arm/mach-mx3/clock-imx35.c 2009-05-13 09:46:19.000000000 +0200 ++++ linux-2.6.30-rc4-karo/arch/arm/mach-mx3/clock-imx35.c 2009-06-02 17:05:26.000000000 +0200 +@@ -381,7 +381,7 @@ DEFINE_CLOCK(gpu2d_clk, 0, CCM_CGR3, 4 + .clk = &c, \ + }, + +-static struct clk_lookup lookups[] __initdata = { ++static struct clk_lookup lookups[] = { + _REGISTER_CLOCK(NULL, "asrc", asrc_clk) + _REGISTER_CLOCK(NULL, "ata", ata_clk) + _REGISTER_CLOCK(NULL, "audmux", audmux_clk) +diff -urNp linux-2.6.30-rc4/arch/arm/mach-mx3/clock.c linux-2.6.30-rc4-karo/arch/arm/mach-mx3/clock.c +--- linux-2.6.30-rc4/arch/arm/mach-mx3/clock.c 2009-05-13 09:46:19.000000000 +0200 ++++ linux-2.6.30-rc4-karo/arch/arm/mach-mx3/clock.c 2009-06-02 17:05:26.000000000 +0200 +@@ -516,7 +516,7 @@ DEFINE_CLOCK(ipg_clk, 0, NULL, + .clk = &c, \ + }, + +-static struct clk_lookup lookups[] __initdata = { ++static struct clk_lookup lookups[] = { + _REGISTER_CLOCK(NULL, "emi", emi_clk) + _REGISTER_CLOCK(NULL, "cspi", cspi1_clk) + _REGISTER_CLOCK(NULL, "cspi", cspi2_clk) +diff -urNp linux-2.6.30-rc4/arch/arm/plat-mxc/Kconfig linux-2.6.30-rc4-karo/arch/arm/plat-mxc/Kconfig +--- linux-2.6.30-rc4/arch/arm/plat-mxc/Kconfig 2009-05-13 09:46:19.000000000 +0200 ++++ linux-2.6.30-rc4-karo/arch/arm/plat-mxc/Kconfig 2009-06-02 17:05:27.000000000 +0200 +@@ -56,6 +56,9 @@ config ARCH_HAS_RNGA + bool + depends on ARCH_MXC + ++config ARCH_MXC_IOMUX_V2 ++ bool ++ + config ARCH_MXC_IOMUX_V3 + bool + endif +diff -urNp linux-2.6.30-rc4/arch/arm/plat-mxc/Makefile linux-2.6.30-rc4-karo/arch/arm/plat-mxc/Makefile +--- linux-2.6.30-rc4/arch/arm/plat-mxc/Makefile 2009-05-13 09:46:19.000000000 +0200 ++++ linux-2.6.30-rc4-karo/arch/arm/plat-mxc/Makefile 2009-06-02 17:05:27.000000000 +0200 +@@ -5,7 +5,7 @@ + # Common support + obj-y := irq.o clock.o gpio.o time.o devices.o cpu.o system.o + +-obj-$(CONFIG_ARCH_MX1) += iomux-mx1-mx2.o dma-mx1-mx2.o +-obj-$(CONFIG_ARCH_MX2) += iomux-mx1-mx2.o dma-mx1-mx2.o +-obj-$(CONFIG_ARCH_MXC_IOMUX_V3) += iomux-v3.o +-obj-$(CONFIG_MXC_PWM) += pwm.o ++obj-$(CONFIG_ARCH_MXC_IOMUX_V2) += iomux-mx1-mx2.o dma-mx1-mx2.o ++obj-$(CONFIG_ARCH_MXC_IOMUX_V3) += iomux-v3.o ++obj-$(CONFIG_MXC_PWM) += pwm.o ++obj-$(CONFIG_MACH_MX25) += spba.o +diff -urNp linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/board-stk5.h linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/board-stk5.h +--- linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/board-stk5.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/board-stk5.h 2009-06-02 17:05:27.000000000 +0200 +@@ -0,0 +1,17 @@ ++/* ++ * Copyright 2009 <LW@KARO-electronics.de> ++ * ++ * The code contained herein is licensed under the GNU General Public ++ * License. You may obtain a copy of the GNU General Public License ++ * Version 2 or later at the following locations: ++ * ++ * http://www.opensource.org/licenses/gpl-license.html ++ * http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++#define UART1_ENABLED 1 ++#define UART2_ENABLED 1 ++#define UART3_ENABLED 1 ++/* Not available on TX25 */ ++#define UART4_ENABLED 0 ++#define UART5_ENABLED 0 +diff -urNp linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/board-tx25.h linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/board-tx25.h +--- linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/board-tx25.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/board-tx25.h 2009-06-02 17:05:27.000000000 +0200 +@@ -0,0 +1,13 @@ ++/* ++ * Copyright 2009 <LW@KARO-electronics.de> ++ * ++ * The code contained herein is licensed under the GNU General Public ++ * License. You may obtain a copy of the GNU General Public License ++ * Version 2 or later at the following locations: ++ * ++ * http://www.opensource.org/licenses/gpl-license.html ++ * http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++#define MXC_LL_UART_PADDR UART1_BASE_ADDR ++#define MXC_LL_UART_VADDR AIPS1_IO_ADDRESS(UART1_BASE_ADDR) +diff -urNp linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/common.h linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/common.h +--- linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/common.h 2009-05-13 09:46:19.000000000 +0200 ++++ linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/common.h 2009-06-02 17:05:27.000000000 +0200 +@@ -17,6 +17,7 @@ struct clk; + extern void mx1_map_io(void); + extern void mx21_map_io(void); + extern void mx27_map_io(void); ++extern void mx25_map_io(void); + extern void mx31_map_io(void); + extern void mx35_map_io(void); + extern void mxc_init_irq(void); +@@ -24,6 +25,7 @@ extern void mxc_timer_init(struct clk *t + extern int mx1_clocks_init(unsigned long fref); + extern int mx21_clocks_init(unsigned long lref, unsigned long fref); + extern int mx27_clocks_init(unsigned long fref); ++extern int mx25_clocks_init(unsigned long fref); + extern int mx31_clocks_init(unsigned long fref); + extern int mx35_clocks_init(void); + extern int mxc_register_gpios(void); +diff -urNp linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/dma.h linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/dma.h +--- linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/dma.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/dma.h 2009-06-02 17:05:27.000000000 +0200 +@@ -0,0 +1,259 @@ ++/* ++ * Copyright 2004-2008 Freescale Semiconductor, Inc. All Rights Reserved. ++ */ ++ ++/* ++ * 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_MXC_DMA_H__ ++#define __ASM_ARCH_MXC_DMA_H__ ++ ++#include <mach/sdma.h> ++ ++#define MXC_DMA_DYNAMIC_CHANNEL 255 ++ ++#define MXC_DMA_DONE 0x0 ++#define MXC_DMA_REQUEST_TIMEOUT 0x1 ++#define MXC_DMA_TRANSFER_ERROR 0x2 ++ ++/*! This defines the list of device ID's for DMA */ ++typedef enum mxc_dma_device { ++ MXC_DMA_UART1_RX, ++ MXC_DMA_UART1_TX, ++ MXC_DMA_UART2_RX, ++ MXC_DMA_UART2_TX, ++ MXC_DMA_UART3_RX, ++ MXC_DMA_UART3_TX, ++ MXC_DMA_UART4_RX, ++ MXC_DMA_UART4_TX, ++ MXC_DMA_UART5_RX, ++ MXC_DMA_UART5_TX, ++ MXC_DMA_UART6_RX, ++ MXC_DMA_UART6_TX, ++ MXC_DMA_MMC1_WIDTH_1, ++ MXC_DMA_MMC1_WIDTH_4, ++ MXC_DMA_MMC2_WIDTH_1, ++ MXC_DMA_MMC2_WIDTH_4, ++ MXC_DMA_SSI1_8BIT_RX0, ++ MXC_DMA_SSI1_8BIT_TX0, ++ MXC_DMA_SSI1_16BIT_RX0, ++ MXC_DMA_SSI1_16BIT_TX0, ++ MXC_DMA_SSI1_24BIT_RX0, ++ MXC_DMA_SSI1_24BIT_TX0, ++ MXC_DMA_SSI1_8BIT_RX1, ++ MXC_DMA_SSI1_8BIT_TX1, ++ MXC_DMA_SSI1_16BIT_RX1, ++ MXC_DMA_SSI1_16BIT_TX1, ++ MXC_DMA_SSI1_24BIT_RX1, ++ MXC_DMA_SSI1_24BIT_TX1, ++ MXC_DMA_SSI2_8BIT_RX0, ++ MXC_DMA_SSI2_8BIT_TX0, ++ MXC_DMA_SSI2_16BIT_RX0, ++ MXC_DMA_SSI2_16BIT_TX0, ++ MXC_DMA_SSI2_24BIT_RX0, ++ MXC_DMA_SSI2_24BIT_TX0, ++ MXC_DMA_SSI2_8BIT_RX1, ++ MXC_DMA_SSI2_8BIT_TX1, ++ MXC_DMA_SSI2_16BIT_RX1, ++ MXC_DMA_SSI2_16BIT_TX1, ++ MXC_DMA_SSI2_24BIT_RX1, ++ MXC_DMA_SSI2_24BIT_TX1, ++ MXC_DMA_FIR_RX, ++ MXC_DMA_FIR_TX, ++ MXC_DMA_CSPI1_RX, ++ MXC_DMA_CSPI1_TX, ++ MXC_DMA_CSPI2_RX, ++ MXC_DMA_CSPI2_TX, ++ MXC_DMA_CSPI3_RX, ++ MXC_DMA_CSPI3_TX, ++ MXC_DMA_ATA_RX, ++ MXC_DMA_ATA_TX, ++ MXC_DMA_MEMORY, ++ MXC_DMA_FIFO_MEMORY, ++ MXC_DMA_DSP_PACKET_DATA0_RD, ++ MXC_DMA_DSP_PACKET_DATA0_WR, ++ MXC_DMA_DSP_PACKET_DATA1_RD, ++ MXC_DMA_DSP_PACKET_DATA1_WR, ++ MXC_DMA_DSP_LOG0_CHNL, ++ MXC_DMA_DSP_LOG1_CHNL, ++ MXC_DMA_DSP_LOG2_CHNL, ++ MXC_DMA_DSP_LOG3_CHNL, ++ MXC_DMA_CSI_RX, ++ MXC_DMA_SPDIF_16BIT_TX, ++ MXC_DMA_SPDIF_16BIT_RX, ++ MXC_DMA_SPDIF_32BIT_TX, ++ MXC_DMA_SPDIF_32BIT_RX, ++ MXC_DMA_ASRC_A_RX, ++ MXC_DMA_ASRC_A_TX, ++ MXC_DMA_ASRC_B_RX, ++ MXC_DMA_ASRC_B_TX, ++ MXC_DMA_ASRC_C_RX, ++ MXC_DMA_ASRC_C_TX, ++ MXC_DMA_ESAI_16BIT_RX, ++ MXC_DMA_ESAI_16BIT_TX, ++ MXC_DMA_ESAI_24BIT_RX, ++ MXC_DMA_ESAI_24BIT_TX, ++ MXC_DMA_TEST_RAM2D2RAM, ++ MXC_DMA_TEST_RAM2RAM2D, ++ MXC_DMA_TEST_RAM2D2RAM2D, ++ MXC_DMA_TEST_RAM2RAM, ++ MXC_DMA_TEST_HW_CHAINING, ++ MXC_DMA_TEST_SW_CHAINING ++} mxc_dma_device_t; ++ ++/*! This defines the prototype of callback funtion registered by the drivers */ ++typedef void (*mxc_dma_callback_t) (void *arg, int error_status, ++ unsigned int count); ++ ++/*! This defines the type of DMA transfer requested */ ++typedef enum mxc_dma_mode { ++ MXC_DMA_MODE_READ, ++ MXC_DMA_MODE_WRITE, ++} mxc_dma_mode_t; ++ ++/*! This defines the DMA channel parameters */ ++typedef struct mxc_dma_channel { ++ unsigned int active:1; /*!< When there has a active tranfer, it is set to 1 */ ++ unsigned int lock; /*!< Defines the channel is allocated or not */ ++ int curr_buf; /*!< Current buffer */ ++ mxc_dma_mode_t mode; /*!< Read or Write */ ++ unsigned int channel; /*!< Channel info */ ++ unsigned int dynamic:1; /*!< Channel not statically allocated when 1 */ ++ char *dev_name; /*!< Device name */ ++ void *private; /*!< Private structure for platform */ ++ mxc_dma_callback_t cb_fn; /*!< The callback function */ ++ void *cb_args; /*!< The argument of callback function */ ++} mxc_dma_channel_t; ++ ++/*! This structure contains the information about a dma transfer */ ++typedef struct mxc_dma_requestbuf { ++ dma_addr_t src_addr; /*!< source address */ ++ dma_addr_t dst_addr; /*!< destination address */ ++ int num_of_bytes; /*!< the length of this transfer : bytes */ ++} mxc_dma_requestbuf_t; ++ ++/*! ++ * This function is generally called by the driver at open time. ++ * The DMA driver would do any initialization steps that is required ++ * to get the channel ready for data transfer. ++ * ++ * @param channel_id a pre-defined id. The peripheral driver would specify ++ * the id associated with its peripheral. This would be ++ * used by the DMA driver to identify the peripheral ++ * requesting DMA and do the necessary setup on the ++ * channel associated with the particular peripheral. ++ * The DMA driver could use static or dynamic DMA channel ++ * allocation. ++ * @param dev_name module name or device name ++ * @return returns a negative number on error if request for a DMA channel did not ++ * succeed, returns the channel number to be used on success. ++ */ ++extern int mxc_dma_request(mxc_dma_device_t channel_id, char *dev_name); ++ ++/*! ++ * This function is generally called by the driver at close time. The DMA ++ * driver would do any cleanup associated with this channel. ++ * ++ * @param channel_num the channel number returned at request time. This ++ * would be used by the DMA driver to identify the calling ++ * driver and do the necessary cleanup on the channel ++ * associated with the particular peripheral ++ * @return returns a negative number on error or 0 on success ++ */ ++extern int mxc_dma_free(int channel_num); ++ ++/*! ++ * This function would just configure the buffers specified by the user into ++ * dma channel. The caller must call mxc_dma_enable to start this transfer. ++ * ++ * @param channel_num the channel number returned at request time. This ++ * would be used by the DMA driver to identify the calling ++ * driver and do the necessary cleanup on the channel ++ * associated with the particular peripheral ++ * @param dma_buf an array of physical addresses to the user defined ++ * buffers. The caller must guarantee the dma_buf is ++ * available until the transfer is completed. ++ * @param num_buf number of buffers in the array ++ * @param mode specifies whether this is READ or WRITE operation ++ * @return This function returns a negative number on error if buffer could not be ++ * added with DMA for transfer. On Success, it returns 0 ++ */ ++extern int mxc_dma_config(int channel_num, mxc_dma_requestbuf_t * dma_buf, ++ int num_buf, mxc_dma_mode_t mode); ++ ++/*! ++ * This function would just configure the scatterlist specified by the ++ * user into dma channel. This is a slight variation of mxc_dma_config(), ++ * it is provided for the convenience of drivers that have a scatterlist ++ * passed into them. It is the calling driver's responsibility to have the ++ * correct physical address filled in the "dma_address" field of the ++ * scatterlist. ++ * ++ * @param channel_num the channel number returned at request time. This ++ * would be used by the DMA driver to identify the calling ++ * driver and do the necessary cleanup on the channel ++ * associated with the particular peripheral ++ * @param sg a scatterlist of buffers. The caller must guarantee ++ * the dma_buf is available until the transfer is ++ * completed. ++ * @param num_buf number of buffers in the array ++ * @param num_of_bytes total number of bytes to transfer. If set to 0, this ++ * would imply to use the length field of the scatterlist ++ * for each DMA transfer. Else it would calculate the size ++ * for each DMA transfer. ++ * @param mode specifies whether this is READ or WRITE operation ++ * @return This function returns a negative number on error if buffer could not ++ * be added with DMA for transfer. On Success, it returns 0 ++ */ ++extern int mxc_dma_sg_config(int channel_num, struct scatterlist *sg, ++ int num_buf, int num_of_bytes, ++ mxc_dma_mode_t mode); ++ ++/*! ++ * This function is provided if the driver would like to set/change its ++ * callback function. ++ * ++ * @param channel_num the channel number returned at request time. This ++ * would be used by the DMA driver to identify the calling ++ * driver and do the necessary cleanup on the channel ++ * associated with the particular peripheral ++ * @param callback a callback function to provide notification on transfer ++ * completion, user could specify NULL if he does not wish ++ * to be notified ++ * @param arg an argument that gets passed in to the callback ++ * function, used by the user to do any driver specific ++ * operations. ++ * @return this function returns a negative number on error if the callback ++ * could not be set for the channel or 0 on success ++ */ ++extern int mxc_dma_callback_set(int channel_num, mxc_dma_callback_t callback, ++ void *arg); ++ ++/*! ++ * This stops the DMA channel and any ongoing transfers. Subsequent use of ++ * mxc_dma_enable() will restart the channel and restart the transfer. ++ * ++ * @param channel_num the channel number returned at request time. This ++ * would be used by the DMA driver to identify the calling ++ * driver and do the necessary cleanup on the channel ++ * associated with the particular peripheral ++ * @return returns a negative number on error or 0 on success ++ */ ++extern int mxc_dma_disable(int channel_num); ++ ++/*! ++ * This starts DMA transfer. Or it restarts DMA on a stopped channel ++ * previously stopped with mxc_dma_disable(). ++ * ++ * @param channel_num the channel number returned at request time. This ++ * would be used by the DMA driver to identify the calling ++ * driver and do the necessary cleanup on the channel ++ * associated with the particular peripheral ++ * @return returns a negative number on error or 0 on success ++ */ ++extern int mxc_dma_enable(int channel_num); ++ ++#endif +diff -urNp linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/hardware.h linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/hardware.h +--- linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/hardware.h 2009-05-13 09:46:19.000000000 +0200 ++++ linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/hardware.h 2009-06-02 17:05:27.000000000 +0200 +@@ -29,13 +29,18 @@ + #endif + + #ifdef CONFIG_ARCH_MX2 ++#ifndef CONFIG_MACH_MX25 + # include <mach/mx2x.h> ++#endif + # ifdef CONFIG_MACH_MX21 + # include <mach/mx21.h> + # endif + # ifdef CONFIG_MACH_MX27 + # include <mach/mx27.h> + # endif ++# ifdef CONFIG_MACH_MX25 ++# include <mach/mx25.h> ++# endif + #endif + + #ifdef CONFIG_ARCH_MX1 +diff -urNp linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/imxfb.h linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/imxfb.h +--- linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/imxfb.h 2009-05-13 09:46:19.000000000 +0200 ++++ linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/imxfb.h 2009-06-02 17:05:26.000000000 +0200 +@@ -13,7 +13,8 @@ + #define PCR_BPIX_4 (2 << 25) + #define PCR_BPIX_8 (3 << 25) + #define PCR_BPIX_12 (4 << 25) +-#define PCR_BPIX_16 (4 << 25) ++#define PCR_BPIX_16 (5 << 25) ++#define PCR_BPIX_18 (6 << 25) + #define PCR_PIXPOL (1 << 24) + #define PCR_FLMPOL (1 << 23) + #define PCR_LPPOL (1 << 22) +diff -urNp linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/iomux-mx25.h linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/iomux-mx25.h +--- linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/iomux-mx25.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/iomux-mx25.h 2009-06-02 17:05:27.000000000 +0200 +@@ -0,0 +1,905 @@ ++/* ++ * arch/arm/plat-mxc/include/mach/iomux-mx25.h ++ * ++ * Copyright (C) 2009 by Lothar Wassmann <LW@KARO-electronics.de> ++ * ++ * based on arch/arm/mach-mx25/mx25_pins.h ++ * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved. ++ * and ++ * arch/arm/plat-mxc/include/mach/iomux-mx35.h ++ * Copyright (C, NO_PAD_CTRL) 2009 by Jan Weitzel Phytec Messtechnik GmbH <armlinux@phytec.de> ++ * ++ * The code contained herein is licensed under the GNU General Public ++ * License. You may obtain a copy of the GNU General Public License ++ * Version 2 or later at the following locations: ++ * ++ * http://www.opensource.org/licenses/gpl-license.html ++ * http://www.gnu.org/copyleft/gpl.html ++ */ ++#ifndef __IOMUX_MX25_H__ ++#define __IOMUX_MX25_H__ ++ ++#include <mach/iomux-v3.h> ++ ++/* ++ * ++ * @brief MX25 I/O Pin List ++ * ++ * @ingroup GPIO_MX25 ++ */ ++ ++#ifndef __ASSEMBLY__ ++ ++/* ++ * IOMUX/PAD Bit field definitions ++ */ ++ ++#define MX25_PAD_A10__A10 IOMUX_PAD(A10, A10, 0x000, 0x008, 0x00, 0, 0, NO_PAD_CTRL) ++#define MX25_PAD_A10__GPIO_4_0 IOMUX_PAD(A10, GPIO_4_0, 0x000, 0x008, 0x05, 0, 0, NO_PAD_CTRL) ++#define MX25_PAD_A13__A13 IOMUX_PAD(A13, A13, 0x22C, 0x00c, 0x00, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_A13__GPIO_4_1 IOMUX_PAD(A13, GPIO_4_1, 0x22C, 0x00c, 0x05, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_A14__A14 IOMUX_PAD(A14, A14, 0x230, 0x010, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_A14__GPIO_2_0 IOMUX_PAD(A14, GPIO_2_0, 0x230, 0x010, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_A15__A15 IOMUX_PAD(A15, A15, 0x234, 0x014, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_A15__GPIO_2_1 IOMUX_PAD(A15, GPIO_2_1, 0x234, 0x014, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_A16__A16 IOMUX_PAD(A16, A16, 0x000, 0x018, 0x10, 0, 0, NO_PAD_CTRL) ++#define MX25_PAD_A16__GPIO_2_2 IOMUX_PAD(A16, GPIO_2_2, 0x000, 0x018, 0x15, 0, 0, NO_PAD_CTRL) ++#define MX25_PAD_A17__A17 IOMUX_PAD(A17, A17, 0x238, 0x01c, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_A17__GPIO_2_3 IOMUX_PAD(A17, GPIO_2_3, 0x238, 0x01c, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_A18__A18 IOMUX_PAD(A18, A18, 0x23c, 0x020, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_A18__GPIO_2_4 IOMUX_PAD(A18, GPIO_2_4, 0x23c, 0x020, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_A18__FEC_COL IOMUX_PAD(A18, FEC_COL, 0x23c, 0x020, 0x17, 0x504, 0, PAD_CTL_SLEW_RATE_FAST) ++#define MX25_PAD_A19__A19 IOMUX_PAD(A19, A19, 0x240, 0x024, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_A19__FEC_RX_ER IOMUX_PAD(A19, FEC_RX_ER, 0x240, 0x024, 0x17, 0x518, 0, PAD_CTL_SLEW_RATE_FAST) ++#define MX25_PAD_A19__GPIO_2_5 IOMUX_PAD(A19, GPIO_2_5, 0x240, 0x024, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_A20__A20 IOMUX_PAD(A20, A20, 0x244, 0x028, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_A20__GPIO_2_6 IOMUX_PAD(A20, GPIO_2_6, 0x244, 0x028, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_A20__FEC_RDATA2 IOMUX_PAD(A20, FEC_RDATA2, 0x244, 0x028, 0x17, 0x50c, 0, PAD_CTL_SLEW_RATE_FAST) ++#define MX25_PAD_A21__A21 IOMUX_PAD(A21, A21, 0x248, 0x02c, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_A21__GPIO_2_7 IOMUX_PAD(A21, GPIO_2_7, 0x248, 0x02c, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_A21__FEC_RDATA3 IOMUX_PAD(A21, FEC_RDATA3, 0x248, 0x02c, 0x17, 0x510, 0, PAD_CTL_SLEW_RATE_FAST) ++#define MX25_PAD_A22__A22 IOMUX_PAD(A22, A22, 0x000, 0x030, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_A22__GPIO_2_8 IOMUX_PAD(A22, GPIO_2_8, 0x000, 0x030, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_A23__A23 IOMUX_PAD(A23, A23, 0x24c, 0x034, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_A23__GPIO_2_9 IOMUX_PAD(A23, GPIO_2_9, 0x24c, 0x034, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_A24__A24 IOMUX_PAD(A24, A24, 0x250, 0x038, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_A24__GPIO_2_10 IOMUX_PAD(A24, GPIO_2_10, 0x250, 0x038, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_A24__FEC_RX_CLK IOMUX_PAD(A24, FEC_RX_CLK, 0x250, 0x038, 0x17, 0x514, 0, PAD_CTL_SLEW_RATE_FAST) ++#define MX25_PAD_A25__A25 IOMUX_PAD(A25, A25, 0x254, 0x03c, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_A25__GPIO_2_11 IOMUX_PAD(A25, GPIO_2_11, 0x254, 0x03c, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_A25__FEC_CRS IOMUX_PAD(A25, FEC_CRS, 0x254, 0x03c, 0x17, 0x508, 0, PAD_CTL_SLEW_RATE_FAST) ++#define MX25_PAD_EB0__EB0 IOMUX_PAD(EB0, EB0, 0x258, 0x040, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_EB0__AUD4_TXD IOMUX_PAD(EB0, AUD4_TXD, 0x258, 0x040, 0x14, 0x464, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_EB0__GPIO_2_12 IOMUX_PAD(EB0, GPIO_2_12, 0x258, 0x040, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_EB1__EB1 IOMUX_PAD(EB1, EB1, 0x25c, 0x044, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_EB1__AUD4_RXD IOMUX_PAD(EB1, AUD4_RXD, 0x25c, 0x044, 0x14, 0x460, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_EB1__GPIO_2_13 IOMUX_PAD(EB1, GPIO_2_13, 0x25c, 0x044, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_OE__OE IOMUX_PAD(OE, OE, 0x260, 0x048, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_OE__AUD4_TXC IOMUX_PAD(OE, AUD4_TXC, 0x260, 0x048, 0x14, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_OE__GPIO_2_14 IOMUX_PAD(OE, GPIO_2_14, 0x260, 0x048, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_CS0__CS0 IOMUX_PAD(CS0, CS0, 0x000, 0x04c, 0x00, 0, 0, NO_PAD_CTRL) ++#define MX25_PAD_CS0__GPIO_4_2 IOMUX_PAD(CS0, GPIO_4_2, 0x000, 0x04c, 0x05, 0, 0, NO_PAD_CTRL) ++#define MX25_PAD_CS1__CS1 IOMUX_PAD(CS1, CS1, 0x000, 0x050, 0x00, 0, 0, NO_PAD_CTRL) ++#define MX25_PAD_CS1__GPIO_4_3 IOMUX_PAD(CS1, GPIO_4_3, 0x000, 0x050, 0x05, 0, 0, NO_PAD_CTRL) ++#define MX25_PAD_CS4__CS4 IOMUX_PAD(CS4, CS4, 0x264, 0x054, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_CS4__UART5_CTS IOMUX_PAD(CS4, UART5_CTS, 0x264, 0x054, 0x13, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_CS4__GPIO_3_20 IOMUX_PAD(CS4, GPIO_3_20, 0x264, 0x054, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_CS5__CS5 IOMUX_PAD(CS5, CS5, 0x268, 0x058, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_CS5__UART5_RTS IOMUX_PAD(CS5, UART5_RTS, 0x268, 0x058, 0x13, 0x574, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_CS5__GPIO_3_21 IOMUX_PAD(CS5, GPIO_3_21, 0x268, 0x058, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_NF_CE0__NF_CE0 IOMUX_PAD(NF_CE0, NF_CE0, 0x26c, 0x05c, 0x10, 0, 0, PAD_CTL_SLEW_RATE_FAST) ++#define MX25_PAD_NF_CE0__GPIO_3_22 IOMUX_PAD(NF_CE0, GPIO_3_22, 0x26c, 0x05c, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_ECB__ECB IOMUX_PAD(ECB, ECB, 0x270, 0x060, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_ECB__UART5_TXD_MUX IOMUX_PAD(ECB, UART5_TXD_MUX, 0x270, 0x060, 0x13, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_ECB__GPIO_3_23 IOMUX_PAD(ECB, GPIO_3_23, 0x270, 0x060, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_LBA__LBA IOMUX_PAD(LBA, LBA, 0x274, 0x064, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_LBA__UART5_RXD_MUX IOMUX_PAD(LBA, UART5_RXD_MUX, 0x274, 0x064, 0x13, 0x578, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_LBA__GPIO_3_24 IOMUX_PAD(LBA, GPIO_3_24, 0x274, 0x064, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_BCLK__BCLK IOMUX_PAD(BCLK, BCLK, 0x000, 0x068, 0x00, 0, 0, NO_PAD_CTRL) ++#define MX25_PAD_BCLK__GPIO_4_4 IOMUX_PAD(BCLK, GPIO_4_4, 0x000, 0x068, 0x05, 0, 0, NO_PAD_CTRL) ++#define MX25_PAD_RW__RW IOMUX_PAD(RW, RW, 0x278, 0x06c, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_RW__AUD4_TXFS IOMUX_PAD(RW, AUD4_TXFS, 0x278, 0x06c, 0x14, 0x474, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_RW__GPIO_3_25 IOMUX_PAD(RW, GPIO_3_25, 0x278, 0x06c, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_NFWE_B__NFWE_B IOMUX_PAD(NFWE_B, NFWE_B, 0x000, 0x070, 0x10, 0, 0, NO_PAD_CTRL) ++#define MX25_PAD_NFWE_B__GPIO_3_26 IOMUX_PAD(NFWE_B, GPIO_3_26, 0x000, 0x070, 0x15, 0, 0, NO_PAD_CTRL) ++#define MX25_PAD_NFRE_B__NFRE_B IOMUX_PAD(NFRE_B, NFRE_B, 0x000, 0x074, 0x10, 0, 0, NO_PAD_CTRL) ++#define MX25_PAD_NFRE_B__GPIO_3_27 IOMUX_PAD(NFRE_B, GPIO_3_27, 0x000, 0x074, 0x15, 0, 0, NO_PAD_CTRL) ++#define MX25_PAD_NFALE__NFALE IOMUX_PAD(NFALE, NFALE, 0x000, 0x078, 0x10, 0, 0, NO_PAD_CTRL) ++#define MX25_PAD_NFALE__GPIO_3_28 IOMUX_PAD(NFALE, GPIO_3_28, 0x000, 0x078, 0x15, 0, 0, NO_PAD_CTRL) ++#define MX25_PAD_NFCLE__NFCLE IOMUX_PAD(NFCLE, NFCLE, 0x000, 0x07c, 0x10, 0, 0, NO_PAD_CTRL) ++#define MX25_PAD_NFCLE__GPIO_3_29 IOMUX_PAD(NFCLE, GPIO_3_29, 0x000, 0x07c, 0x15, 0, 0, NO_PAD_CTRL) ++#define MX25_PAD_NFWP_B__NFWP_B IOMUX_PAD(NFWP_B, NFWP_B, 0x000, 0x080, 0x10, 0, 0, NO_PAD_CTRL) ++#define MX25_PAD_NFWP_B__GPIO_3_30 IOMUX_PAD(NFWP_B, GPIO_3_30, 0x000, 0x080, 0x15, 0, 0, NO_PAD_CTRL) ++#define MX25_PAD_NFRB__NFRB IOMUX_PAD(NFRB, NFRB, 0x27c, 0x084, 0x10, 0, 0, PAD_CTL_PULL_KEEPER) ++#define MX25_PAD_NFRB__GPIO_3_31 IOMUX_PAD(NFRB, GPIO_3_31, 0x27c, 0x084, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_D15__D15 IOMUX_PAD(D15, D15, 0x280, 0x088, 0x00, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_D15__LD16 IOMUX_PAD(D15, LD16, 0x280, 0x088, 0x01, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_D15__GPIO_4_5 IOMUX_PAD(D15, GPIO_4_5, 0x280, 0x088, 0x05, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_D14__D14 IOMUX_PAD(D14, D14, 0x284, 0x08c, 0x00, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_D14__LD17 IOMUX_PAD(D14, LD17, 0x284, 0x08c, 0x01, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_D14__GPIO_4_6 IOMUX_PAD(D14, GPIO_4_6, 0x284, 0x08c, 0x05, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_D13__D13 IOMUX_PAD(D13, D13, 0x288, 0x090, 0x00, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_D13__LD18 IOMUX_PAD(D13, LD18, 0x288, 0x090, 0x01, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_D13__GPIO_4_7 IOMUX_PAD(D13, GPIO_4_7, 0x288, 0x090, 0x05, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_D12__D12 IOMUX_PAD(D12, D12, 0x28c, 0x094, 0x00, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_D12__GPIO_4_8 IOMUX_PAD(D12, GPIO_4_8, 0x28c, 0x094, 0x05, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_D11__D11 IOMUX_PAD(D11, D11, 0x290, 0x098, 0x00, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_D11__GPIO_4_9 IOMUX_PAD(D11, GPIO_4_9, 0x290, 0x098, 0x05, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_D10__D10 IOMUX_PAD(D10, D10, 0x294, 0x09c, 0x00, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_D10__GPIO_4_10 IOMUX_PAD(D10, GPIO_4_10, 0x294, 0x09c, 0x05, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_D10__USBOTG_OC IOMUX_PAD(D10, USBOTG_OC, 0x294, 0x09c, 0x06, 0x57c, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_D9__D9 IOMUX_PAD(D9, D9, 0x298, 0x0a0, 0x00, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_D9__GPIO_4_11 IOMUX_PAD(D9, GPIO_4_11, 0x298, 0x0a0, 0x05, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_D9__USBH2_PWR IOMUX_PAD(D9, USBH2_PWR, 0x298, 0x0a0, 0x06, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_D8__D8 IOMUX_PAD(D8, D8, 0x29c, 0x0a4, 0x00, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_D8__GPIO_4_12 IOMUX_PAD(D8, GPIO_4_12, 0x29c, 0x0a4, 0x05, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_D8__USBH2_OC IOMUX_PAD(D8, USBH2_OC, 0x29c, 0x0a4, 0x06, 0x580, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_D7__D7 IOMUX_PAD(D7, D7, 0x2a0, 0x0a8, 0x00, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_D7__GPIO_4_13 IOMUX_PAD(D7, GPIO_4_13, 0x2a0, 0x0a8, 0x05, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_D6__D6 IOMUX_PAD(D6, D6, 0x2a4, 0x0ac, 0x00, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_D6__GPIO_4_14 IOMUX_PAD(D6, GPIO_4_14, 0x2a4, 0x0ac, 0x05, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_D5__D5 IOMUX_PAD(D5, D5, 0x2a8, 0x0b0, 0x00, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_D5__GPIO_4_15 IOMUX_PAD(D5, GPIO_4_15, 0x2a8, 0x0b0, 0x05, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_D4__D4 IOMUX_PAD(D4, D4, 0x2ac, 0x0b4, 0x00, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_D4__GPIO_4_16 IOMUX_PAD(D4, GPIO_4_16, 0x2ac, 0x0b4, 0x05, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_D3__D3 IOMUX_PAD(D3, D3, 0x2b0, 0x0b8, 0x00, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_D3__GPIO_4_17 IOMUX_PAD(D3, GPIO_4_17, 0x2b0, 0x0b8, 0x05, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_D2__D2 IOMUX_PAD(D2, D2, 0x2b4, 0x0bc, 0x00, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_D2__GPIO_4_18 IOMUX_PAD(D2, GPIO_4_18, 0x2b4, 0x0bc, 0x05, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_D1__D1 IOMUX_PAD(D1, D1, 0x2b8, 0x0c0, 0x00, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_D1__GPIO_4_19 IOMUX_PAD(D1, GPIO_4_19, 0x2b8, 0x0c0, 0x05, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_D0__D0 IOMUX_PAD(D0, D0, 0x2bc, 0x0c4, 0x00, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_D0__GPIO_4_20 IOMUX_PAD(D0, GPIO_4_20, 0x2bc, 0x0c4, 0x05, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_LD0__LD0 IOMUX_PAD(LD0, LD0, 0x2c0, 0x0c8, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_LD0__CSI_D0 IOMUX_PAD(LD0, CSI_D0, 0x2c0, 0x0c8, 0x12, 0x488, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_LD0__GPIO_2_15 IOMUX_PAD(LD0, GPIO_2_15, 0x2c0, 0x0c8, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_LD1__LD1 IOMUX_PAD(LD1, LD1, 0x2c4, 0x0cc, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_LD1__CSI_D1 IOMUX_PAD(LD1, CSI_D1, 0x2c4, 0x0cc, 0x12, 0x48c, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_LD1__GPIO_2_16 IOMUX_PAD(LD1, GPIO_2_16, 0x2c4, 0x0cc, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_LD2__LD2 IOMUX_PAD(LD2, LD2, 0x2c8, 0x0d0, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_LD2__GPIO_2_17 IOMUX_PAD(LD2, GPIO_2_17, 0x2c8, 0x0d0, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_LD3__LD3 IOMUX_PAD(LD3, LD3, 0x2cc, 0x0d4, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_LD3__GPIO_2_18 IOMUX_PAD(LD3, GPIO_2_18, 0x2cc, 0x0d4, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_LD4__LD4 IOMUX_PAD(LD4, LD4, 0x2d0, 0x0d8, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_LD4__GPIO_2_19 IOMUX_PAD(LD4, GPIO_2_19, 0x2d0, 0x0d8, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_LD5__LD5 IOMUX_PAD(LD5, LD5, 0x2d4, 0x0dc, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_LD5__GPIO_1_19 IOMUX_PAD(LD5, GPIO_1_19, 0x2d4, 0x0dc, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_LD6__LD6 IOMUX_PAD(LD6, LD6, 0x2d8, 0x0e0, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_LD6__GPIO_1_20 IOMUX_PAD(LD6, GPIO_1_20, 0x2d8, 0x0e0, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_LD7__LD7 IOMUX_PAD(LD7, LD7, 0x2dc, 0x0e4, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_LD7__GPIO_1_21 IOMUX_PAD(LD7, GPIO_1_21, 0x2dc, 0x0e4, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_LD8__LD8 IOMUX_PAD(LD8, LD8, 0x2e0, 0x0e8, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_LD8__FEC_TX_ERR IOMUX_PAD(LD8, FEC_TX_ERR, 0x2e0, 0x0e8, 0x15, 0, 0, PAD_CTL_SLEW_RATE_FAST) ++#define MX25_PAD_LD9__LD9 IOMUX_PAD(LD9, LD9, 0x2e4, 0x0ec, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_LD9__FEC_COL IOMUX_PAD(LD9, FEC_COL, 0x2e4, 0x0ec, 0x15, 0x504, 1, PAD_CTL_SLEW_RATE_FAST) ++#define MX25_PAD_LD10__LD10 IOMUX_PAD(LD10, LD10, 0x2e8, 0x0f0, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_LD10__FEC_RX_ER IOMUX_PAD(LD10, FEC_RX_ER, 0x2e8, 0x0f0, 0x15, 0x518, 1, PAD_CTL_SLEW_RATE_FAST) ++#define MX25_PAD_LD11__LD11 IOMUX_PAD(LD11, LD11, 0x2ec, 0x0f4, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_LD11__FEC_RDATA2 IOMUX_PAD(LD11, FEC_RDATA2, 0x2ec, 0x0f4, 0x15, 0x50c, 1, PAD_CTL_SLEW_RATE_FAST) ++#define MX25_PAD_LD12__LD12 IOMUX_PAD(LD12, LD12, 0x2f0, 0x0f8, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_LD12__FEC_RDATA3 IOMUX_PAD(LD12, FEC_RDATA3, 0x2f0, 0x0f8, 0x15, 0x510, 1, PAD_CTL_SLEW_RATE_FAST) ++#define MX25_PAD_LD13__LD13 IOMUX_PAD(LD13, LD13, 0x2f4, 0x0fc, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_LD13__FEC_TDATA2 IOMUX_PAD(LD13, FEC_TDATA2, 0x2f4, 0x0fc, 0x15, 0, 0, PAD_CTL_SLEW_RATE_FAST) ++#define MX25_PAD_LD14__LD14 IOMUX_PAD(LD14, LD14, 0x2f8, 0x100, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_LD14__FEC_TDATA3 IOMUX_PAD(LD14, FEC_TDATA3, 0x2f8, 0x100, 0x15, 0, 0, PAD_CTL_SLEW_RATE_FAST) ++#define MX25_PAD_LD15__LD15 IOMUX_PAD(LD15, LD15, 0x2fc, 0x104, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_LD15__FEC_RX_CLK IOMUX_PAD(LD15, FEC_RX_CLK, 0x2fc, 0x104, 0x15, 0x514, 1, PAD_CTL_SLEW_RATE_FAST) ++#define MX25_PAD_HSYNC__HSYNC IOMUX_PAD(HSYNC, HSYNC, 0x300, 0x108, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_HSYNC__GPIO_1_22 IOMUX_PAD(HSYNC, GPIO_1_22, 0x300, 0x108, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_VSYNC__VSYNC IOMUX_PAD(VSYNC, VSYNC, 0x304, 0x10c, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_VSYNC__GPIO_1_23 IOMUX_PAD(VSYNC, GPIO_1_23, 0x304, 0x10c, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_LSCLK__LSCLK IOMUX_PAD(LSCLK, LSCLK, 0x308, 0x110, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_LSCLK__GPIO_1_24 IOMUX_PAD(LSCLK, GPIO_1_24, 0x308, 0x110, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_OE_ACD__OE_ACD IOMUX_PAD(OE_ACD, OE_ACD, 0x30c, 0x114, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_OE_ACD__GPIO_1_25 IOMUX_PAD(OE_ACD, GPIO_1_25, 0x30c, 0x114, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_CONTRAST__CONTRAST IOMUX_PAD(CONTRAST, CONTRAST, 0x310, 0x118, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_CONTRAST__FEC_CRS IOMUX_PAD(CONTRAST, FEC_CRS, 0x310, 0x118, 0x15, 0x508, 1, PAD_CTL_SLEW_RATE_FAST) ++#define MX25_PAD_PWM__PWM IOMUX_PAD(PWM, PWM, 0x314, 0x11c, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_PWM__GPIO_1_26 IOMUX_PAD(PWM, GPIO_1_26, 0x314, 0x11c, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_PWM__USBH2_OC IOMUX_PAD(PWM, USBH2_OC, 0x314, 0x11c, 0x16, 0x580, 1, 0 | NO_PAD_CTRL) ++#define MX25_PAD_CSI_D2__CSI_D2 IOMUX_PAD(CSI_D2, CSI_D2, 0x318, 0x120, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_CSI_D2__UART5_RXD_MUX IOMUX_PAD(CSI_D2, UART5_RXD_MUX, 0x318, 0x120, 0x11, 0x578, 1, 0 | NO_PAD_CTRL) ++#define MX25_PAD_CSI_D2__GPIO_1_27 IOMUX_PAD(CSI_D2, GPIO_1_27, 0x318, 0x120, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_CSI_D3__CSI_D3 IOMUX_PAD(CSI_D3, CSI_D3, 0x31c, 0x124, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_CSI_D3__GPIO_1_28 IOMUX_PAD(CSI_D3, GPIO_1_28, 0x31c, 0x124, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_CSI_D4__CSI_D4 IOMUX_PAD(CSI_D4, CSI_D4, 0x320, 0x128, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_CSI_D4__UART5_RTS IOMUX_PAD(CSI_D4, UART5_RTS, 0x320, 0x128, 0x11, 0x574, 1, 0 | NO_PAD_CTRL) ++#define MX25_PAD_CSI_D4__GPIO_1_29 IOMUX_PAD(CSI_D4, GPIO_1_29, 0x320, 0x128, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_CSI_D5__CSI_D5 IOMUX_PAD(CSI_D5, CSI_D5, 0x324, 0x12c, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_CSI_D5__GPIO_1_30 IOMUX_PAD(CSI_D5, GPIO_1_30, 0x324, 0x12c, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_CSI_D6__CSI_D6 IOMUX_PAD(CSI_D6, CSI_D6, 0x328, 0x130, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_CSI_D6__GPIO_1_31 IOMUX_PAD(CSI_D6, GPIO_1_31, 0x328, 0x130, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_CSI_D7__CSI_D7 IOMUX_PAD(CSI_D7, CSI_D7, 0x32c, 0x134, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_CSI_D7__GPIO_1_6 IOMUX_PAD(CSI_D7, GPIO_1_6, 0x32c, 0x134, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_CSI_D8__CSI_D8 IOMUX_PAD(CSI_D8, CSI_D8, 0x330, 0x138, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_CSI_D8__GPIO_1_7 IOMUX_PAD(CSI_D8, GPIO_1_7, 0x330, 0x138, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_CSI_D9__CSI_D9 IOMUX_PAD(CSI_D9, CSI_D9, 0x334, 0x13c, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_CSI_D9__GPIO_4_21 IOMUX_PAD(CSI_D9, GPIO_4_21, 0x334, 0x13c, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_CSI_MCLK__CSI_MCLK IOMUX_PAD(CSI_MCLK, CSI_MCLK, 0x338, 0x140, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_CSI_MCLK__GPIO_1_8 IOMUX_PAD(CSI_MCLK, GPIO_1_8, 0x338, 0x140, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_CSI_VSYNC__CSI_VSYNC IOMUX_PAD(CSI_VSYNC, CSI_VSYNC, 0x33c, 0x144, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_CSI_VSYNC__GPIO_1_9 IOMUX_PAD(CSI_VSYNC, GPIO_1_9, 0x33c, 0x144, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_CSI_HSYNC__CSI_HSYNC IOMUX_PAD(CSI_HSYNC, CSI_HSYNC, 0x340, 0x148, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_CSI_HSYNC__GPIO_1_10 IOMUX_PAD(CSI_HSYNC, GPIO_1_10, 0x340, 0x148, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_CSI_PIXCLK__CSI_PIXCLK IOMUX_PAD(CSI_PIXCLK, CSI_PIXCLK, 0x344, 0x14c, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_CSI_PIXCLK__GPIO_1_11 IOMUX_PAD(CSI_PIXCLK, GPIO_1_11, 0x344, 0x14c, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_I2C1_CLK__I2C1_CLK IOMUX_PAD(I2C1_CLK, I2C1_CLK, 0x348, 0x150, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_I2C1_CLK__GPIO_1_12 IOMUX_PAD(I2C1_CLK, GPIO_1_12, 0x348, 0x150, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_I2C1_DAT__I2C1_DAT IOMUX_PAD(I2C1_DAT, I2C1_DAT, 0x34c, 0x154, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_I2C1_DAT__GPIO_1_13 IOMUX_PAD(I2C1_DAT, GPIO_1_13, 0x34c, 0x154, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_CSPI1_MOSI__CSPI1_MOSI IOMUX_PAD(CSPI1_MOSI, CSPI1_MOSI, 0x350, 0x158, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_CSPI1_MOSI__GPIO_1_14 IOMUX_PAD(CSPI1_MOSI, GPIO_1_14, 0x350, 0x158, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_CSPI1_MISO__CSPI1_MISO IOMUX_PAD(CSPI1_MISO, CSPI1_MISO, 0x354, 0x15c, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_CSPI1_MISO__GPIO_1_15 IOMUX_PAD(CSPI1_MISO, GPIO_1_15, 0x354, 0x15c, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_CSPI1_SS0__CSPI1_SS0 IOMUX_PAD(CSPI1_SS0, CSPI1_SS0, 0x358, 0x160, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_CSPI1_SS0__GPIO_1_16 IOMUX_PAD(CSPI1_SS0, GPIO_1_16, 0x358, 0x160, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_CSPI1_SS1__CSPI1_SS1 IOMUX_PAD(CSPI1_SS1, CSPI1_SS1, 0x35c, 0x164, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_CSPI1_SS1__GPIO_1_17 IOMUX_PAD(CSPI1_SS1, GPIO_1_17, 0x35c, 0x164, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_CSPI1_SCLK__CSPI1_SCLK IOMUX_PAD(CSPI1_SCLK, CSPI1_SCLK, 0x360, 0x168, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_CSPI1_SCLK__GPIO_1_18 IOMUX_PAD(CSPI1_SCLK, GPIO_1_18, 0x360, 0x168, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_CSPI1_RDY__CSPI1_RDY IOMUX_PAD(CSPI1_RDY, CSPI1_RDY, 0x364, 0x16c, 0x10, 0, 0, PAD_CTL_PULL_KEEPER) ++#define MX25_PAD_CSPI1_RDY__GPIO_2_22 IOMUX_PAD(CSPI1_RDY, GPIO_2_22, 0x364, 0x16c, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_UART1_RXD__UART1_RXD IOMUX_PAD(UART1_RXD, UART1_RXD, 0x368, 0x170, 0x10, 0, 0, PAD_CTL_PULL_DOWN_100K) ++#define MX25_PAD_UART1_RXD__GPIO_4_22 IOMUX_PAD(UART1_RXD, GPIO_4_22, 0x368, 0x170, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_UART1_TXD__UART1_TXD IOMUX_PAD(UART1_TXD, UART1_TXD, 0x36c, 0x174, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_UART1_TXD__GPIO_4_23 IOMUX_PAD(UART1_TXD, GPIO_4_23, 0x36c, 0x174, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_UART1_RTS__UART1_RTS IOMUX_PAD(UART1_RTS, UART1_RTS, 0x370, 0x178, 0x10, 0, 0, PAD_CTL_PULL_UP_100K) ++#define MX25_PAD_UART1_RTS__CSI_D0 IOMUX_PAD(UART1_RTS, CSI_D0, 0x370, 0x178, 0x11, 0x488, 1, 0 | NO_PAD_CTRL) ++#define MX25_PAD_UART1_RTS__GPIO_4_24 IOMUX_PAD(UART1_RTS, GPIO_4_24, 0x370, 0x178, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_UART1_CTS__UART1_CTS IOMUX_PAD(UART1_CTS, UART1_CTS, 0x374, 0x17c, 0x10, 0, 0, PAD_CTL_PULL_UP_100K) ++#define MX25_PAD_UART1_CTS__CSI_D1 IOMUX_PAD(UART1_CTS, CSI_D1, 0x374, 0x17c, 0x11, 0x48c, 1, 0 | NO_PAD_CTRL) ++#define MX25_PAD_UART1_CTS__GPIO_4_25 IOMUX_PAD(UART1_CTS, GPIO_4_25, 0x374, 0x17c, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_UART2_RXD__UART2_RXD IOMUX_PAD(UART2_RXD, UART2_RXD, 0x378, 0x180, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_UART2_RXD__GPIO_4_26 IOMUX_PAD(UART2_RXD, GPIO_4_26, 0x378, 0x180, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_UART2_TXD__UART2_TXD IOMUX_PAD(UART2_TXD, UART2_TXD, 0x37c, 0x184, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_UART2_TXD__GPIO_4_27 IOMUX_PAD(UART2_TXD, GPIO_4_27, 0x37c, 0x184, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_UART2_RTS__UART2_RTS IOMUX_PAD(UART2_RTS, UART2_RTS, 0x380, 0x188, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_UART2_RTS__FEC_COL IOMUX_PAD(UART2_RTS, FEC_COL, 0x380, 0x188, 0x12, 0x504, 2, PAD_CTL_SLEW_RATE_FAST) ++#define MX25_PAD_UART2_RTS__GPIO_4_28 IOMUX_PAD(UART2_RTS, GPIO_4_28, 0x380, 0x188, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_UART2_CTS__FEC_RX_ER IOMUX_PAD(UART2_CTS, FEC_RX_ER, 0x384, 0x18c, 0x12, 0x518, 2, PAD_CTL_SLEW_RATE_FAST) ++#define MX25_PAD_UART2_CTS__UART2_CTS IOMUX_PAD(UART2_CTS, UART2_CTS, 0x384, 0x18c, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_UART2_CTS__GPIO_4_29 IOMUX_PAD(UART2_CTS, GPIO_4_29, 0x384, 0x18c, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_SD1_CMD__SD1_CMD IOMUX_PAD(SD1_CMD, SD1_CMD, 0x388, 0x190, 0x10, 0, 0, PAD_CTL_PULL_UP_47K | PAD_CTL_SLEW_RATE_FAST) ++#define MX25_PAD_SD1_CMD__FEC_RDATA2 IOMUX_PAD(SD1_CMD, FEC_RDATA2, 0x388, 0x190, 0x12, 0x50c, 2, PAD_CTL_SLEW_RATE_FAST) ++#define MX25_PAD_SD1_CMD__GPIO_2_23 IOMUX_PAD(SD1_CMD, GPIO_2_23, 0x388, 0x190, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_SD1_CLK__SD1_CLK IOMUX_PAD(SD1_CLK, SD1_CLK, 0x38c, 0x194, 0x10, 0, 0, PAD_CTL_PULL_UP_47K | PAD_CTL_SLEW_RATE_FAST) ++#define MX25_PAD_SD1_CLK__FEC_RDATA3 IOMUX_PAD(SD1_CLK, FEC_RDATA3, 0x38c, 0x194, 0x12, 0x510, 2, PAD_CTL_SLEW_RATE_FAST) ++#define MX25_PAD_SD1_CLK__GPIO_2_24 IOMUX_PAD(SD1_CLK, GPIO_2_24, 0x38c, 0x194, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_SD1_DATA0__SD1_DATA0 IOMUX_PAD(SD1_DATA0, SD1_DATA0, 0x390, 0x198, 0x10, 0, 0, PAD_CTL_PULL_UP_47K | PAD_CTL_SLEW_RATE_FAST) ++#define MX25_PAD_SD1_DATA0__GPIO_2_25 IOMUX_PAD(SD1_DATA0, GPIO_2_25, 0x390, 0x198, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_SD1_DATA1__SD1_DATA1 IOMUX_PAD(SD1_DATA1, SD1_DATA1, 0x394, 0x19c, 0x10, 0, 0, PAD_CTL_PULL_UP_47K | PAD_CTL_SLEW_RATE_FAST) ++#define MX25_PAD_SD1_DATA1__AUD7_RXD IOMUX_PAD(SD1_DATA1, AUD7_RXD, 0x394, 0x19c, 0x13, 0x478, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_SD1_DATA1__GPIO_2_26 IOMUX_PAD(SD1_DATA1, GPIO_2_26, 0x394, 0x19c, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_SD1_DATA2__SD1_DATA2 IOMUX_PAD(SD1_DATA2, SD1_DATA2, 0x398, 0x1a0, 0x10, 0, 0, PAD_CTL_PULL_UP_47K | PAD_CTL_SLEW_RATE_FAST) ++#define MX25_PAD_SD1_DATA2__FEC_RX_CLK IOMUX_PAD(SD1_DATA2, FEC_RX_CLK, 0x398, 0x1a0, 0x15, 0x514, 2, PAD_CTL_SLEW_RATE_FAST) ++#define MX25_PAD_SD1_DATA2__GPIO_2_27 IOMUX_PAD(SD1_DATA2, GPIO_2_27, 0x398, 0x1a0, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_SD1_DATA3__SD1_DATA3 IOMUX_PAD(SD1_DATA3, SD1_DATA3, 0x39c, 0x1a4, 0x10, 0, 0, PAD_CTL_PULL_UP_47K | PAD_CTL_SLEW_RATE_FAST) ++#define MX25_PAD_SD1_DATA3__FEC_CRS IOMUX_PAD(SD1_DATA3, FEC_CRS, 0x39c, 0x1a4, 0x10, 0x508, 2, PAD_CTL_SLEW_RATE_FAST) ++#define MX25_PAD_SD1_DATA3__GPIO_2_28 IOMUX_PAD(SD1_DATA3, GPIO_2_28, 0x39c, 0x1a4, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_KPP_ROW0__KPP_ROW0 IOMUX_PAD(KPP_ROW0, KPP_ROW0, 0x3a0, 0x1a8, 0x10, 0, 0, PAD_CTL_PULL_KEEPER) ++#define MX25_PAD_KPP_ROW0__GPIO_2_29 IOMUX_PAD(KPP_ROW0, GPIO_2_29, 0x3a0, 0x1a8, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_KPP_ROW1__KPP_ROW1 IOMUX_PAD(KPP_ROW1, KPP_ROW1, 0x3a4, 0x1ac, 0x10, 0, 0, PAD_CTL_PULL_KEEPER) ++#define MX25_PAD_KPP_ROW1__GPIO_2_30 IOMUX_PAD(KPP_ROW1, GPIO_2_30, 0x3a4, 0x1ac, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_KPP_ROW2__KPP_ROW2 IOMUX_PAD(KPP_ROW2, KPP_ROW2, 0x3a8, 0x1b0, 0x10, 0, 0, PAD_CTL_PULL_KEEPER) ++#define MX25_PAD_KPP_ROW2__CSI_D0 IOMUX_PAD(KPP_ROW2, CSI_D0, 0x3a8, 0x1b0, 0x13, 0x488, 2, 0 | NO_PAD_CTRL) ++#define MX25_PAD_KPP_ROW2__GPIO_2_31 IOMUX_PAD(KPP_ROW2, GPIO_2_31, 0x3a8, 0x1b0, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_KPP_ROW3__KPP_ROW3 IOMUX_PAD(KPP_ROW3, KPP_ROW3, 0x3ac, 0x1b4, 0x10, 0, 0, PAD_CTL_PULL_KEEPER) ++#define MX25_PAD_KPP_ROW3__CSI_LD1 IOMUX_PAD(KPP_ROW3, CSI_LD1, 0x3ac, 0x1b4, 0x13, 0x48c, 2, 0 | NO_PAD_CTRL) ++#define MX25_PAD_KPP_ROW3__GPIO_3_0 IOMUX_PAD(KPP_ROW3, GPIO_3_0, 0x3ac, 0x1b4, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_KPP_COL0__KPP_COL0 IOMUX_PAD(KPP_COL0, KPP_COL0, 0x3b0, 0x1b8, 0x10, 0, 0, PAD_CTL_PULL_KEEPER | PAD_CTL_OUTPUT_OPEN_DRAIN) ++#define MX25_PAD_KPP_COL0__GPIO_3_1 IOMUX_PAD(KPP_COL0, GPIO_3_1, 0x3b0, 0x1b8, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_KPP_COL1__KPP_COL1 IOMUX_PAD(KPP_COL1, KPP_COL1, 0x3b4, 0x1bc, 0x10, 0, 0, PAD_CTL_PULL_KEEPER | PAD_CTL_OUTPUT_OPEN_DRAIN) ++#define MX25_PAD_KPP_COL1__GPIO_3_2 IOMUX_PAD(KPP_COL1, GPIO_3_2, 0x3b4, 0x1bc, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_KPP_COL2__KPP_COL2 IOMUX_PAD(KPP_COL2, KPP_COL2, 0x3b8, 0x1c0, 0x10, 0, 0, PAD_CTL_PULL_KEEPER | PAD_CTL_OUTPUT_OPEN_DRAIN) ++#define MX25_PAD_KPP_COL2__GPIO_3_3 IOMUX_PAD(KPP_COL2, GPIO_3_3, 0x3b8, 0x1c0, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_KPP_COL3__KPP_COL3 IOMUX_PAD(KPP_COL3, KPP_COL3, 0x3bc, 0x1c4, 0x10, 0, 0, PAD_CTL_PULL_KEEPER | PAD_CTL_OUTPUT_OPEN_DRAIN) ++#define MX25_PAD_KPP_COL3__GPIO_3_4 IOMUX_PAD(KPP_COL3, GPIO_3_4, 0x3bc, 0x1c4, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_FEC_MDC__FEC_MDC IOMUX_PAD(FEC_MDC, FEC_MDC, 0x3c0, 0x1c8, 0x10, 0, 0, PAD_CTL_SLEW_RATE_FAST) ++#define MX25_PAD_FEC_MDC__AUD4_TXD IOMUX_PAD(FEC_MDC, AUD4_TXD, 0x3c0, 0x1c8, 0x12, 0x464, 1, 0 | NO_PAD_CTRL) ++#define MX25_PAD_FEC_MDC__GPIO_3_5 IOMUX_PAD(FEC_MDC, GPIO_3_5, 0x3c0, 0x1c8, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_FEC_MDIO__FEC_MDIO IOMUX_PAD(FEC_MDIO, FEC_MDIO, 0x3c4, 0x1cc, 0x10, 0, 0, PAD_CTL_HYSTERESIS | PAD_CTL_PULL_UP_22K | PAD_CTL_SLEW_RATE_FAST) ++#define MX25_PAD_FEC_MDIO__AUD4_RXD IOMUX_PAD(FEC_MDIO, AUD4_RXD, 0x3c4, 0x1cc, 0x12, 0x460, 1, 0 | NO_PAD_CTRL) ++#define MX25_PAD_FEC_MDIO__GPIO_3_6 IOMUX_PAD(FEC_MDIO, GPIO_3_6, 0x3c4, 0x1cc, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_FEC_TDATA0__FEC_TDATA0 IOMUX_PAD(FEC_TDATA0, FEC_TDATA0, 0x3c8, 0x1d0, 0x10, 0, 0, PAD_CTL_SLEW_RATE_FAST) ++#define MX25_PAD_FEC_TDATA0__GPIO_3_7 IOMUX_PAD(FEC_TDATA0, GPIO_3_7, 0x3c8, 0x1d0, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_FEC_TDATA1__FEC_TDATA1 IOMUX_PAD(FEC_TDATA1, FEC_TDATA1, 0x3cc, 0x1d4, 0x10, 0, 0, PAD_CTL_SLEW_RATE_FAST) ++#define MX25_PAD_FEC_TDATA1__AUD4_TXFS IOMUX_PAD(FEC_TDATA1, AUD4_TXFS, 0x3cc, 0x1d4, 0x12, 0x474, 1, 0 | NO_PAD_CTRL) ++#define MX25_PAD_FEC_TDATA1__GPIO_3_8 IOMUX_PAD(FEC_TDATA1, GPIO_3_8, 0x3cc, 0x1d4, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_FEC_TX_EN__FEC_TX_EN IOMUX_PAD(FEC_TX_EN, FEC_TX_EN, 0x3d0, 0x1d8, 0x10, 0, 0, PAD_CTL_SLEW_RATE_FAST) ++#define MX25_PAD_FEC_TX_EN__GPIO_3_9 IOMUX_PAD(FEC_TX_EN, GPIO_3_9 , 0x3d0, 0x1d8, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_FEC_RDATA0__FEC_RDATA0 IOMUX_PAD(FEC_RDATA0, FEC_RDATA0, 0x3d4, 0x1dc, 0x10, 0, 0, PAD_CTL_PULL_DOWN_100K | PAD_CTL_SLEW_RATE_FAST) ++#define MX25_PAD_FEC_RDATA0__GPIO_3_10 IOMUX_PAD(FEC_RDATA0, GPIO_3_10, 0x3d4, 0x1dc, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_FEC_RDATA1__FEC_RDATA1 IOMUX_PAD(FEC_RDATA1, FEC_RDATA1, 0x3d8, 0x1e0, 0x10, 0, 0, PAD_CTL_PULL_DOWN_100K | PAD_CTL_SLEW_RATE_FAST) ++#define MX25_PAD_FEC_RDATA1__GPIO_3_11 IOMUX_PAD(FEC_RDATA1, GPIO_3_11, 0x3d8, 0x1e0, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_FEC_RX_DV__FEC_RX_DV IOMUX_PAD(FEC_RX_DV, FEC_RX_DV, 0x3dc, 0x1e4, 0x10, 0, 0, PAD_CTL_PULL_DOWN_100K | PAD_CTL_SLEW_RATE_FAST) ++#define MX25_PAD_FEC_RX_DV__CAN2_RX IOMUX_PAD(FEC_RX_DV, CAN2_RX, 0x3dc, 0x1e4, 0x14, 0x484, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_FEC_RX_DV__GPIO_3_12 IOMUX_PAD(FEC_RX_DV, GPIO_3_12, 0x3dc, 0x1e4, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_FEC_TX_CLK__FEC_TX_CLK IOMUX_PAD(FEC_TX_CLK, FEC_TX_CLK, 0x3e0, 0x1e8, 0x10, 0, 0, PAD_CTL_HYSTERESIS | PAD_CTL_PULL_DOWN_100K | PAD_CTL_SLEW_RATE_FAST) ++#define MX25_PAD_FEC_TX_CLK__GPIO_3_13 IOMUX_PAD(FEC_TX_CLK, GPIO_3_13, 0x3e0, 0x1e8, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_RTCK__RTCK IOMUX_PAD(RTCK, RTCK, 0x3e4, 0x1ec, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_RTCK__OWIRE IOMUX_PAD(RTCK, OWIRE, 0x3e4, 0x1ec, 0x11, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_RTCK__GPIO_3_14 IOMUX_PAD(RTCK, GPIO_3_14, 0x3e4, 0x1ec, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_DE_B__DE_B IOMUX_PAD(DE_B, DE_B, 0x3ec, 0x1f0, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_DE_B__GPIO_2_20 IOMUX_PAD(DE_B, GPIO_2_20, 0x3ec, 0x1f0, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_TDO__TDO IOMUX_PAD(TDO, TDO, 0x3e8, 0x000, 0x00, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_GPIO_A__GPIO_A IOMUX_PAD(GPIO_A, GPIO_A, 0x3f0, 0x1f4, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_GPIO_A__USBOTG_PWR IOMUX_PAD(GPIO_A, USBOTG_PWR, 0x3f0, 0x1f4, 0x12, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_GPIO_B__GPIO_B IOMUX_PAD(GPIO_B, GPIO_B, 0x3f4, 0x1f8, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_GPIO_B__USBOTG_OC IOMUX_PAD(GPIO_B, USBOTG_OC, 0x3f4, 0x1f8, 0x12, 0x57c, 1, 0 | NO_PAD_CTRL) ++#define MX25_PAD_GPIO_C__GPIO_C IOMUX_PAD(GPIO_C, GPIO_C, 0x3f8, 0x1fc, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_GPIO_C__CAN2_TX IOMUX_PAD(GPIO_C, CAN2_TX, 0x3f8, 0x1fc, 0x16, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_GPIO_D__GPIO_D IOMUX_PAD(GPIO_D, GPIO_D, 0x3fc, 0x200, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_GPIO_D__CAN2_RX IOMUX_PAD(GPIO_D, CAN2_RX, 0x3fc, 0x200, 0x16, 0x484, 1, 0 | NO_PAD_CTRL) ++#define MX25_PAD_GPIO_E__GPIO_E IOMUX_PAD(GPIO_E, GPIO_E, 0x400, 0x204, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_GPIO_E__AUD7_TXD IOMUX_PAD(GPIO_E, AUD7_TXD, 0x400, 0x204, 0x14, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_GPIO_F__GPIO_F IOMUX_PAD(GPIO_F, GPIO_F, 0x404, 0x208, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_GPIO_F__AUD7_TXC IOMUX_PAD(GPIO_F, AUD7_TXC, 0x404, 0x208, 0x14, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_EXT_ARMCLK__EXT_ARMCLK IOMUX_PAD(EXT_ARMCLK, EXT_ARMCLK, 0x000, 0x20c, 0x10, 0, 0, NO_PAD_CTRL) ++#define MX25_PAD_EXT_ARMCLK__GPIO_3_15 IOMUX_PAD(EXT_ARMCLK, GPIO_3_15, 0x000, 0x20c, 0x15, 0, 0, NO_PAD_CTRL) ++#define MX25_PAD_UPLL_BYPCLK__UPLL_BYPCLK IOMUX_PAD(UPLL_BYPCLK, UPLL_BYPCLK, 0x000, 0x210, 0x10, 0, 0, NO_PAD_CTRL) ++#define MX25_PAD_UPLL_BYPCLK__GPIO_3_16 IOMUX_PAD(UPLL_BYPCLK, GPIO_3_16, 0x000, 0x210, 0x15, 0, 0, NO_PAD_CTRL) ++#define MX25_PAD_VSTBY_REQ__VSTBY_REQ IOMUX_PAD(VSTBY_REQ, VSTBY_REQ, 0x408, 0x214, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_VSTBY_REQ__AUD7_TXFS IOMUX_PAD(VSTBY_REQ, AUD7_TXFS, 0x408, 0x214, 0x14, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_VSTBY_REQ__GPIO_3_17 IOMUX_PAD(VSTBY_REQ, GPIO_3_17, 0x408, 0x214, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_VSTBY_ACK__VSTBY_ACK IOMUX_PAD(VSTBY_ACK, VSTBY_ACK, 0x40c, 0x218, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_VSTBY_ACK__GPIO_3_18 IOMUX_PAD(VSTBY_ACK, GPIO_3_18, 0x40c, 0x218, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_POWER_FAIL__POWER_FAIL IOMUX_PAD(POWER_FAIL, POWER_FAIL, 0x410, 0x21c, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_POWER_FAIL__AUD7_RXD IOMUX_PAD(POWER_FAIL, AUD7_RXD, 0x410, 0x21c, 0x14, 0x478, 1, 0 | NO_PAD_CTRL) ++#define MX25_PAD_POWER_FAIL__GPIO_3_19 IOMUX_PAD(POWER_FAIL, GPIO_3_19, 0x410, 0x21c, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_CLKO__CLKO IOMUX_PAD(CLKO, CLKO, 0x414, 0x220, 0x10, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_CLKO__GPIO_2_21 IOMUX_PAD(CLKO, GPIO_2_21, 0x414, 0x220, 0x15, 0, 0, 0 | NO_PAD_CTRL) ++#define MX25_PAD_BOOT_MODE0__BOOT_MODE0 IOMUX_PAD(BOOT_MODE0, BOOT_MODE0, 0x000, 0x224, 0x00, 0, 0, NO_PAD_CTRL) ++#define MX25_PAD_BOOT_MODE0__GPIO_4_30 IOMUX_PAD(BOOT_MODE0, GPIO_4_30, 0x000, 0x224, 0x05, 0, 0, NO_PAD_CTRL) ++#define MX25_PAD_BOOT_MODE1__BOOT_MODE1 IOMUX_PAD(BOOT_MODE1, BOOT_MODE1, 0x000, 0x228, 0x00, 0, 0, NO_PAD_CTRL) ++#define MX25_PAD_BOOT_MODE1__GPIO_4_31 IOMUX_PAD(BOOT_MODE1, GPIO_4_31, 0x000, 0x228, 0x05, 0, 0, NO_PAD_CTRL) ++ ++#define MX25_PAD_CTL_GRP_DVS_MISC IOMUX_PAD(0x418, 0x000, 0, 0, 0, NO_PAD_CTRL) ++#define MX25_PAD_CTL_GRP_DSE_FEC IOMUX_PAD(0x41c, 0x000, 0, 0, 0, NO_PAD_CTRL) ++#define MX25_PAD_CTL_GRP_DVS_JTAG IOMUX_PAD(0x420, 0x000, 0, 0, 0, NO_PAD_CTRL) ++#define MX25_PAD_CTL_GRP_DSE_NFC IOMUX_PAD(0x424, 0x000, 0, 0, 0, NO_PAD_CTRL) ++#define MX25_PAD_CTL_GRP_DSE_CSI IOMUX_PAD(0x428, 0x000, 0, 0, 0, NO_PAD_CTRL) ++#define MX25_PAD_CTL_GRP_DSE_WEIM IOMUX_PAD(0x42c, 0x000, 0, 0, 0, NO_PAD_CTRL) ++#define MX25_PAD_CTL_GRP_DSE_DDR IOMUX_PAD(0x430, 0x000, 0, 0, 0, NO_PAD_CTRL) ++#define MX25_PAD_CTL_GRP_DVS_CRM IOMUX_PAD(0x434, 0x000, 0, 0, 0, NO_PAD_CTRL) ++#define MX25_PAD_CTL_GRP_DSE_KPP IOMUX_PAD(0x438, 0x000, 0, 0, 0, NO_PAD_CTRL) ++#define MX25_PAD_CTL_GRP_DSE_SDHC1 IOMUX_PAD(0x43c, 0x000, 0, 0, 0, NO_PAD_CTRL) ++#define MX25_PAD_CTL_GRP_DSE_LCD IOMUX_PAD(0x440, 0x000, 0, 0, 0, NO_PAD_CTRL) ++#define MX25_PAD_CTL_GRP_DSE_UART IOMUX_PAD(0x444, 0x000, 0, 0, 0, NO_PAD_CTRL) ++#define MX25_PAD_CTL_GRP_DVS_NFC IOMUX_PAD(0x448, 0x000, 0, 0, 0, NO_PAD_CTRL) ++#define MX25_PAD_CTL_GRP_DVS_CSI IOMUX_PAD(0x44c, 0x000, 0, 0, 0, NO_PAD_CTRL) ++#define MX25_PAD_CTL_GRP_DSE_CSPI1 IOMUX_PAD(0x450, 0x000, 0, 0, 0, NO_PAD_CTRL) ++#define MX25_PAD_CTL_GRP_DDRTYPE IOMUX_PAD(0x454, 0x000, 0, 0, 0, NO_PAD_CTRL) ++#define MX25_PAD_CTL_GRP_DVS_SDHC1 IOMUX_PAD(0x458, 0x000, 0, 0, 0, NO_PAD_CTRL) ++#define MX25_PAD_CTL_GRP_DVS_LCD IOMUX_PAD(0x45c, 0x000, 0, 0, 0, NO_PAD_CTRL) ++ ++#if 0 ++enum { ++ GPIO_A, ++ GPIO_B, ++ GPIO_C, ++ GPIO_D, ++ GPIO_E, ++ GPIO_F, ++ GPIO_1_6, ++ GPIO_1_7, ++ GPIO_1_8, ++ GPIO_1_9, ++ GPIO_1_10, ++ GPIO_1_11, ++ GPIO_1_12, ++ GPIO_1_13, ++ GPIO_1_14, ++ GPIO_1_15, ++ GPIO_1_16, ++ GPIO_1_17, ++ GPIO_1_18, ++ GPIO_1_19, ++ GPIO_1_20, ++ GPIO_1_21, ++ GPIO_1_22, ++ GPIO_1_23, ++ GPIO_1_24, ++ GPIO_1_25, ++ GPIO_1_26, ++ GPIO_1_27, ++ GPIO_1_28, ++ GPIO_1_29, ++ GPIO_1_30, ++ GPIO_1_31, ++ GPIO_2_0, ++ GPIO_2_1, ++ GPIO_2_2, ++ GPIO_2_3, ++ GPIO_2_4, ++ GPIO_2_5, ++ GPIO_2_6, ++ GPIO_2_7, ++ GPIO_2_8, ++ GPIO_2_9, ++ GPIO_2_10, ++ GPIO_2_11, ++ GPIO_2_12, ++ GPIO_2_13, ++ GPIO_2_14, ++ GPIO_2_15, ++ GPIO_2_16, ++ GPIO_2_17, ++ GPIO_2_18, ++ GPIO_2_19, ++ GPIO_2_20, ++ GPIO_2_21, ++ GPIO_2_22, ++ GPIO_2_23, ++ GPIO_2_24, ++ GPIO_2_25, ++ GPIO_2_26, ++ GPIO_2_27, ++ GPIO_2_28, ++ GPIO_2_29, ++ GPIO_2_30, ++ GPIO_2_31, ++ GPIO_3_0, ++ GPIO_3_1, ++ GPIO_3_2, ++ GPIO_3_3, ++ GPIO_3_4, ++ GPIO_3_5, ++ GPIO_3_6, ++ GPIO_3_7, ++ GPIO_3_8, ++ GPIO_3_9, ++ GPIO_3_10, ++ GPIO_3_11, ++ GPIO_3_12, ++ GPIO_3_13, ++ GPIO_3_14, ++ GPIO_3_15, ++ GPIO_3_16, ++ GPIO_3_17, ++ GPIO_3_18, ++ GPIO_3_19, ++ GPIO_3_20, ++ GPIO_3_21, ++ GPIO_3_22, ++ GPIO_3_23, ++ GPIO_3_24, ++ GPIO_3_25, ++ GPIO_3_26, ++ GPIO_3_27, ++ GPIO_3_28, ++ GPIO_3_29, ++ GPIO_3_30, ++ GPIO_3_31, ++ GPIO_4_0, ++ GPIO_4_1, ++ GPIO_4_2, ++ GPIO_4_3, ++ GPIO_4_4, ++ GPIO_4_5, ++ GPIO_4_6, ++ GPIO_4_7, ++ GPIO_4_8, ++ GPIO_4_9, ++ GPIO_4_10, ++ GPIO_4_11, ++ GPIO_4_12, ++ GPIO_4_13, ++ GPIO_4_14, ++ GPIO_4_15, ++ GPIO_4_16, ++ GPIO_4_17, ++ GPIO_4_18, ++ GPIO_4_19, ++ GPIO_4_20, ++ GPIO_4_21, ++ GPIO_4_22, ++ GPIO_4_23, ++ GPIO_4_24, ++ GPIO_4_25, ++ GPIO_4_26, ++ GPIO_4_27, ++ GPIO_4_28, ++ GPIO_4_29, ++ GPIO_4_30, ++ GPIO_4_31, ++}; ++ ++#define IOMUX_TO_GPIO(__pad_desc) ({ \ ++ int __gpio = -1; \ ++ struct pad_desc *__pd = __pad_desc; \ ++ \ ++ switch (__pd->mux_ctrl_ofs) { \ ++ case MX25_PAD_GPIO_A__GPIO_A: \ ++ __gpio = GPIO_A; \ ++ break; \ ++ case MX25_PAD_GPIO_B__GPIO_B: \ ++ __gpio = GPIO_B; \ ++ break; \ ++ case MX25_PAD_GPIO_C__GPIO_C: \ ++ __gpio = GPIO_C; \ ++ break; \ ++ case MX25_PAD_GPIO_D__GPIO_D: \ ++ __gpio = GPIO_D; \ ++ break; \ ++ case MX25_PAD_GPIO_E__GPIO_E: \ ++ __gpio = GPIO_E; \ ++ break; \ ++ case MX25_PAD_GPIO_F__GPIO_F: \ ++ __gpio = GPIO_F; \ ++ break; \ ++ case MX25_PAD_CSI_D7__GPIO_1_6: \ ++ __gpio = GPIO_1_6; \ ++ break; \ ++ case MX25_PAD_CSI_D8__GPIO_1_7: \ ++ __gpio = GPIO_1_7; \ ++ break; \ ++ case MX25_PAD_CSI_MCLK__GPIO_1_8: \ ++ __gpio = GPIO_1_8; \ ++ break; \ ++ case MX25_PAD_CSI_VSYNC__GPIO_1_9: \ ++ __gpio = GPIO_1_9; \ ++ break; \ ++ case MX25_PAD_CSI_HSYNC__GPIO_1_10: \ ++ __gpio = GPIO_1_10; \ ++ break; \ ++ case MX25_PAD_CSI_PIXCLK__GPIO_1_11: \ ++ __gpio = GPIO_1_11; \ ++ break; \ ++ case MX25_PAD_I2C1_CLK__GPIO_1_12: \ ++ __gpio = GPIO_1_12; \ ++ break; \ ++ case MX25_PAD_I2C1_DAT__GPIO_1_13: \ ++ __gpio = GPIO_1_13; \ ++ break; \ ++ case MX25_PAD_CSPI1_MOSI__GPIO_1_14: \ ++ __gpio = GPIO_1_14; \ ++ break; \ ++ case MX25_PAD_CSPI1_MISO__GPIO_1_15: \ ++ __gpio = GPIO_1_15; \ ++ break; \ ++ case MX25_PAD_CSPI1_SS0__GPIO_1_16: \ ++ __gpio = GPIO_1_16; \ ++ break; \ ++ case MX25_PAD_CSPI1_SS1__GPIO_1_17: \ ++ __gpio = GPIO_1_17; \ ++ break; \ ++ case MX25_PAD_CSPI1_SCLK__GPIO_1_18: \ ++ __gpio = GPIO_1_18; \ ++ break; \ ++ case MX25_PAD_LD5__GPIO_1_19: \ ++ __gpio = GPIO_1_19; \ ++ break; \ ++ case MX25_PAD_LD6__GPIO_1_20: \ ++ __gpio = GPIO_1_20; \ ++ break; \ ++ case MX25_PAD_LD7__GPIO_1_21: \ ++ __gpio = GPIO_1_21; \ ++ break; \ ++ case MX25_PAD_HSYNC__GPIO_1_22: \ ++ __gpio = GPIO_1_22; \ ++ break; \ ++ case MX25_PAD_VSYNC__GPIO_1_23: \ ++ __gpio = GPIO_1_23; \ ++ break; \ ++ case MX25_PAD_LSCLK__GPIO_1_24: \ ++ __gpio = GPIO_1_24; \ ++ break; \ ++ case MX25_PAD_OE_ACD__GPIO_1_25: \ ++ __gpio = GPIO_1_25; \ ++ break; \ ++ case MX25_PAD_PWM__GPIO_1_26: \ ++ __gpio = GPIO_1_26; \ ++ break; \ ++ case MX25_PAD_CSI_D2__GPIO_1_27: \ ++ __gpio = GPIO_1_27; \ ++ break; \ ++ case MX25_PAD_CSI_D3__GPIO_1_28: \ ++ __gpio = GPIO_1_28; \ ++ break; \ ++ case MX25_PAD_CSI_D4__GPIO_1_29: \ ++ __gpio = GPIO_1_29; \ ++ break; \ ++ case MX25_PAD_CSI_D5__GPIO_1_30: \ ++ __gpio = GPIO_1_30; \ ++ break; \ ++ case MX25_PAD_CSI_D6__GPIO_1_31: \ ++ __gpio = GPIO_1_31; \ ++ break; \ ++ \ ++ case MX25_PAD_A14__GPIO_2_0: \ ++ __gpio = GPIO_2_0; \ ++ break; \ ++ case MX25_PAD_A15__GPIO_2_1: \ ++ __gpio = GPIO_2_1; \ ++ break; \ ++ case MX25_PAD_A16__GPIO_2_2: \ ++ __gpio = GPIO_2_2; \ ++ break; \ ++ case MX25_PAD_A17__GPIO_2_3: \ ++ __gpio = GPIO_2_3; \ ++ break; \ ++ case MX25_PAD_A18__GPIO_2_4: \ ++ __gpio = GPIO_2_4; \ ++ break; \ ++ case MX25_PAD_A19__GPIO_2_5: \ ++ __gpio = GPIO_2_5; \ ++ break; \ ++ case MX25_PAD_A20__GPIO_2_6: \ ++ __gpio = GPIO_2_6; \ ++ break; \ ++ case MX25_PAD_A21__GPIO_2_7: \ ++ __gpio = GPIO_2_7; \ ++ break; \ ++ case MX25_PAD_A22__GPIO_2_8: \ ++ __gpio = GPIO_2_8; \ ++ break; \ ++ case MX25_PAD_A23__GPIO_2_9: \ ++ __gpio = GPIO_2_9; \ ++ break; \ ++ case MX25_PAD_A24__GPIO_2_10: \ ++ __gpio = GPIO_2_10; \ ++ break; \ ++ case MX25_PAD_A25__GPIO_2_11: \ ++ __gpio = GPIO_2_11; \ ++ break; \ ++ case MX25_PAD_EB0__GPIO_2_12: \ ++ __gpio = GPIO_2_12; \ ++ break; \ ++ case MX25_PAD_EB1__GPIO_2_13: \ ++ __gpio = GPIO_2_13; \ ++ break; \ ++ case MX25_PAD_OE__GPIO_2_14: \ ++ __gpio = GPIO_2_14; \ ++ break; \ ++ case MX25_PAD_LD0__GPIO_2_15: \ ++ __gpio = GPIO_2_15; \ ++ break; \ ++ case MX25_PAD_LD1__GPIO_2_16: \ ++ __gpio = GPIO_2_16; \ ++ break; \ ++ case MX25_PAD_LD2__GPIO_2_17: \ ++ __gpio = GPIO_2_17; \ ++ break; \ ++ case MX25_PAD_LD3__GPIO_2_18: \ ++ __gpio = GPIO_2_18; \ ++ break; \ ++ case MX25_PAD_LD4__GPIO_2_19: \ ++ __gpio = GPIO_2_19; \ ++ break; \ ++ case MX25_PAD_DE_B__GPIO_2_20: \ ++ __gpio = GPIO_2_20; \ ++ break; \ ++ case MX25_PAD_CLKO__GPIO_2_21: \ ++ __gpio = GPIO_2_21; \ ++ break; \ ++ case MX25_PAD_CSPI1_RDY__GPIO_2_22: \ ++ __gpio = GPIO_2_22; \ ++ break; \ ++ case MX25_PAD_SD1_CMD__GPIO_2_23: \ ++ __gpio = GPIO_2_23; \ ++ break; \ ++ case MX25_PAD_SD1_CLK__GPIO_2_24: \ ++ __gpio = GPIO_2_24; \ ++ break; \ ++ case MX25_PAD_SD1_DATA0__GPIO_2_25: \ ++ __gpio = GPIO_2_25; \ ++ break; \ ++ case MX25_PAD_SD1_DATA1__GPIO_2_26: \ ++ __gpio = GPIO_2_26; \ ++ break; \ ++ case MX25_PAD_SD1_DATA2__GPIO_2_27: \ ++ __gpio = GPIO_2_27; \ ++ break; \ ++ case MX25_PAD_SD1_DATA3__GPIO_2_28: \ ++ __gpio = GPIO_2_28; \ ++ break; \ ++ case MX25_PAD_KPP_ROW0__GPIO_2_29: \ ++ __gpio = GPIO_2_29; \ ++ break; \ ++ case MX25_PAD_KPP_ROW1__GPIO_2_30: \ ++ __gpio = GPIO_2_30; \ ++ break; \ ++ case MX25_PAD_KPP_ROW2__GPIO_2_31: \ ++ __gpio = GPIO_2_31; \ ++ break; \ ++ \ ++ case MX25_PAD_KPP_ROW3__GPIO_3_0: \ ++ __gpio = GPIO_3_0; \ ++ break; \ ++ case MX25_PAD_KPP_COL0__GPIO_3_1: \ ++ __gpio = GPIO_3_1; \ ++ break; \ ++ case MX25_PAD_KPP_COL1__GPIO_3_2: \ ++ __gpio = GPIO_3_2; \ ++ break; \ ++ case MX25_PAD_KPP_COL2__GPIO_3_3: \ ++ __gpio = GPIO_3_3; \ ++ break; \ ++ case MX25_PAD_KPP_COL3__GPIO_3_4: \ ++ __gpio = GPIO_3_4; \ ++ break; \ ++ case MX25_PAD_FEC_MDC__GPIO_3_5: \ ++ __gpio = GPIO_3_5; \ ++ break; \ ++ case MX25_PAD_FEC_MDIO__GPIO_3_6: \ ++ __gpio = GPIO_3_6; \ ++ break; \ ++ case MX25_PAD_FEC_TDATA0__GPIO_3_7: \ ++ __gpio = GPIO_3_7; \ ++ break; \ ++ case MX25_PAD_FEC_TDATA1__GPIO_3_8: \ ++ __gpio = GPIO_3_8; \ ++ break; \ ++ case MX25_PAD_FEC_TX_EN__GPIO_3_9: \ ++ __gpio = GPIO_3_9; \ ++ break; \ ++ case MX25_PAD_FEC_RDATA0__GPIO_3_10: \ ++ __gpio = GPIO_3_10; \ ++ break; \ ++ case MX25_PAD_FEC_RDATA1__GPIO_3_11: \ ++ __gpio = GPIO_3_11; \ ++ break; \ ++ case MX25_PAD_FEC_RX_DV__GPIO_3_12: \ ++ __gpio = GPIO_3_12; \ ++ break; \ ++ case MX25_PAD_FEC_TX_CLK__GPIO_3_13: \ ++ __gpio = GPIO_3_13; \ ++ break; \ ++ case MX25_PAD_RTCK__GPIO_3_14: \ ++ __gpio = GPIO_3_14; \ ++ break; \ ++ case MX25_PAD_EXT_ARMCLK__GPIO_3_15: \ ++ __gpio = GPIO_3_15; \ ++ break; \ ++ case MX25_PAD_UPLL_BYPCLK__GPIO_3_16: \ ++ __gpio = GPIO_3_16; \ ++ break; \ ++ case MX25_PAD_VSTBY_REQ__GPIO_3_17: \ ++ __gpio = GPIO_3_17; \ ++ break; \ ++ case MX25_PAD_VSTBY_ACK__GPIO_3_18: \ ++ __gpio = GPIO_3_18; \ ++ break; \ ++ case MX25_PAD_POWER_FAIL__GPIO_3_19: \ ++ __gpio = GPIO_3_19; \ ++ break; \ ++ case MX25_PAD_CS4__GPIO_3_20: \ ++ __gpio = GPIO_3_20; \ ++ break; \ ++ case MX25_PAD_CS5__GPIO_3_21: \ ++ __gpio = GPIO_3_21; \ ++ break; \ ++ case MX25_PAD_NF_CE0__GPIO_3_22: \ ++ __gpio = GPIO_3_22; \ ++ break; \ ++ case MX25_PAD_ECB__GPIO_3_23: \ ++ __gpio = GPIO_3_23; \ ++ break; \ ++ case MX25_PAD_LBA__GPIO_3_24: \ ++ __gpio = GPIO_3_24; \ ++ break; \ ++ case MX25_PAD_RW__GPIO_3_25: \ ++ __gpio = GPIO_3_25; \ ++ break; \ ++ case MX25_PAD_NFWE_B__GPIO_3_26: \ ++ __gpio = GPIO_3_26; \ ++ break; \ ++ case MX25_PAD_NFRE_B__GPIO_3_27: \ ++ __gpio = GPIO_3_27; \ ++ break; \ ++ case MX25_PAD_NFALE__GPIO_3_28: \ ++ __gpio = GPIO_3_28; \ ++ break; \ ++ case MX25_PAD_NFCLE__GPIO_3_29: \ ++ __gpio = GPIO_3_29; \ ++ break; \ ++ case MX25_PAD_NFWP_B__GPIO_3_30: \ ++ __gpio = GPIO_3_30; \ ++ break; \ ++ case MX25_PAD_NFRB__GPIO_3_31: \ ++ __gpio = GPIO_3_31; \ ++ break; \ ++ \ ++ case MX25_PAD_A10__GPIO_4_0: \ ++ __gpio = GPIO_4_0; \ ++ break; \ ++ case MX25_PAD_A13__GPIO_4_1: \ ++ __gpio = GPIO_4_1; \ ++ break; \ ++ case MX25_PAD_CS0__GPIO_4_2: \ ++ __gpio = GPIO_4_2; \ ++ break; \ ++ case MX25_PAD_CS1__GPIO_4_3: \ ++ __gpio = GPIO_4_3; \ ++ break; \ ++ case MX25_PAD_BCLK__GPIO_4_4: \ ++ __gpio = GPIO_4_4; \ ++ break; \ ++ case MX25_PAD_D15__GPIO_4_5: \ ++ __gpio = GPIO_4_5; \ ++ break; \ ++ case MX25_PAD_D14__GPIO_4_6: \ ++ __gpio = GPIO_4_6; \ ++ break; \ ++ case MX25_PAD_D13__GPIO_4_7: \ ++ __gpio = GPIO_4_7; \ ++ break; \ ++ case MX25_PAD_D12__GPIO_4_8: \ ++ __gpio = GPIO_4_8; \ ++ break; \ ++ case MX25_PAD_D11__GPIO_4_9: \ ++ __gpio = GPIO_4_9; \ ++ break; \ ++ case MX25_PAD_D10__GPIO_4_10: \ ++ __gpio = GPIO_4_10; \ ++ break; \ ++ case MX25_PAD_D9__GPIO_4_11: \ ++ __gpio = GPIO_4_11; \ ++ break; \ ++ case MX25_PAD_D8__GPIO_4_12: \ ++ __gpio = GPIO_4_12; \ ++ break; \ ++ case MX25_PAD_D7__GPIO_4_13: \ ++ __gpio = GPIO_4_13; \ ++ break; \ ++ case MX25_PAD_D6__GPIO_4_14: \ ++ __gpio = GPIO_4_14; \ ++ break; \ ++ case MX25_PAD_D5__GPIO_4_15: \ ++ __gpio = GPIO_4_15; \ ++ break; \ ++ case MX25_PAD_D4__GPIO_4_16: \ ++ __gpio = GPIO_4_16; \ ++ break; \ ++ case MX25_PAD_D3__GPIO_4_17: \ ++ __gpio = GPIO_4_17; \ ++ break; \ ++ case MX25_PAD_D2__GPIO_4_18: \ ++ __gpio = GPIO_4_18; \ ++ break; \ ++ case MX25_PAD_D1__GPIO_4_19: \ ++ __gpio = GPIO_4_19; \ ++ break; \ ++ case MX25_PAD_D0__GPIO_4_20: \ ++ __gpio = GPIO_4_20; \ ++ break; \ ++ case MX25_PAD_CSI_D9__GPIO_4_21: \ ++ __gpio = GPIO_4_21; \ ++ break; \ ++ case MX25_PAD_UART1_RXD__GPIO_4_22: \ ++ __gpio = GPIO_4_22; \ ++ break; \ ++ case MX25_PAD_UART1_TXD__GPIO_4_23: \ ++ __gpio = GPIO_4_23; \ ++ break; \ ++ case MX25_PAD_UART1_RTS__GPIO_4_24: \ ++ __gpio = GPIO_4_24; \ ++ break; \ ++ case MX25_PAD_UART1_CTS__GPIO_4_25: \ ++ __gpio = GPIO_4_25; \ ++ break; \ ++ case MX25_PAD_UART2_RXD__GPIO_4_26: \ ++ __gpio = GPIO_4_26; \ ++ break; \ ++ case MX25_PAD_UART2_TXD__GPIO_4_27: \ ++ __gpio = GPIO_4_27; \ ++ break; \ ++ case MX25_PAD_UART2_RTS__GPIO_4_28: \ ++ __gpio = GPIO_4_28; \ ++ break; \ ++ case MX25_PAD_UART2_CTS__GPIO_4_29: \ ++ __gpio = GPIO_4_29; \ ++ break; \ ++ case MX25_PAD_BOOT_MODE0__GPIO_4_30: \ ++ __gpio = GPIO_4_30; \ ++ break; \ ++ case MX25_PAD_BOOT_MODE1__GPIO_4_31: \ ++ __gpio = GPIO_4_31; \ ++ break; \ ++ } \ ++ __gpio; \ ++}) ++#endif ++ ++#endif // __ASSEMBLY__ ++#endif // __IOMUX_MX25_H__ +diff -urNp linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/iomux-v3.h linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/iomux-v3.h +--- linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/iomux-v3.h 2009-05-13 09:46:19.000000000 +0200 ++++ linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/iomux-v3.h 2009-06-02 17:05:27.000000000 +0200 +@@ -54,7 +54,7 @@ struct pad_desc { + unsigned select_input:3; + }; + +-#define IOMUX_PAD(_pad_ctrl_ofs, _mux_ctrl_ofs, _mux_mode, _select_input_ofs, \ ++#define IOMUX_PAD(_pad, _func, _pad_ctrl_ofs, _mux_ctrl_ofs, _mux_mode, _select_input_ofs, \ + _select_input, _pad_ctrl) \ + { \ + .mux_ctrl_ofs = _mux_ctrl_ofs, \ +@@ -68,28 +68,28 @@ struct pad_desc { + /* + * Use to set PAD control + */ +-#define PAD_CTL_DRIVE_VOLTAGE_3_3_V 0 +-#define PAD_CTL_DRIVE_VOLTAGE_1_8_V 1 ++#define PAD_CTL_DRIVE_VOLTAGE_3_3_V (0 << 13) ++#define PAD_CTL_DRIVE_VOLTAGE_1_8_V (1 << 13) + +-#define PAD_CTL_NO_HYSTERESIS 0 +-#define PAD_CTL_HYSTERESIS 1 ++#define PAD_CTL_NO_HYSTERESIS (0 << 8) ++#define PAD_CTL_HYSTERESIS (1 << 8) + +-#define PAD_CTL_PULL_DISABLED 0x0 +-#define PAD_CTL_PULL_KEEPER 0xa +-#define PAD_CTL_PULL_DOWN_100K 0xc +-#define PAD_CTL_PULL_UP_47K 0xd +-#define PAD_CTL_PULL_UP_100K 0xe +-#define PAD_CTL_PULL_UP_22K 0xf +- +-#define PAD_CTL_OUTPUT_CMOS 0 +-#define PAD_CTL_OUTPUT_OPEN_DRAIN 1 +- +-#define PAD_CTL_DRIVE_STRENGTH_NORM 0 +-#define PAD_CTL_DRIVE_STRENGTH_HIGH 1 +-#define PAD_CTL_DRIVE_STRENGTH_MAX 2 ++#define PAD_CTL_PULL_DISABLED (0x0 << 4) ++#define PAD_CTL_PULL_KEEPER (0x8 << 4) ++#define PAD_CTL_PULL_DOWN_100K (0xc << 4) ++#define PAD_CTL_PULL_UP_47K (0xd << 4) ++#define PAD_CTL_PULL_UP_100K (0xe << 4) ++#define PAD_CTL_PULL_UP_22K (0xf << 4) ++ ++#define PAD_CTL_OUTPUT_CMOS (0 << 3) ++#define PAD_CTL_OUTPUT_OPEN_DRAIN (1 << 3) ++ ++#define PAD_CTL_DRIVE_STRENGTH_NORM (0 << 1) ++#define PAD_CTL_DRIVE_STRENGTH_HIGH (1 << 1) ++#define PAD_CTL_DRIVE_STRENGTH_MAX (2 << 1) + +-#define PAD_CTL_SLEW_RATE_SLOW 0 +-#define PAD_CTL_SLEW_RATE_FAST 1 ++#define PAD_CTL_SLEW_RATE_SLOW (0 << 0) ++#define PAD_CTL_SLEW_RATE_FAST (1 << 0) + + /* + * setups a single pad: +diff -urNp linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/iomux.h linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/iomux.h +--- linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/iomux.h 2009-05-13 09:46:19.000000000 +0200 ++++ linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/iomux.h 2009-06-02 17:05:27.000000000 +0200 +@@ -24,10 +24,14 @@ + * GPIO Module and I/O Multiplexer + * x = 0..3 for reg_A, reg_B, reg_C, reg_D + */ ++#ifndef CONFIG_MACH_MX25 + #define VA_GPIO_BASE IO_ADDRESS(GPIO_BASE_ADDR) ++#endif + #define MXC_DDIR(x) (0x00 + ((x) << 8)) ++#ifndef CONFIG_MACH_MX25 + #define MXC_OCR1(x) (0x04 + ((x) << 8)) + #define MXC_OCR2(x) (0x08 + ((x) << 8)) ++#endif + #define MXC_ICONFA1(x) (0x0c + ((x) << 8)) + #define MXC_ICONFA2(x) (0x10 + ((x) << 8)) + #define MXC_ICONFB1(x) (0x14 + ((x) << 8)) +@@ -96,16 +100,20 @@ + + + #ifdef CONFIG_ARCH_MX1 +-#include <mach/iomux-mx1.h> ++# include <mach/iomux-mx1.h> + #endif + #ifdef CONFIG_ARCH_MX2 +-#include <mach/iomux-mx2x.h> +-#ifdef CONFIG_MACH_MX21 +-#include <mach/iomux-mx21.h> +-#endif +-#ifdef CONFIG_MACH_MX27 +-#include <mach/iomux-mx27.h> +-#endif ++# ifndef CONFIG_MACH_MX25 ++# include <mach/iomux-mx2x.h> ++# ifdef CONFIG_MACH_MX21 ++# include <mach/iomux-mx21.h> ++# endif ++# endif ++# ifdef CONFIG_MACH_MX27 ++# include <mach/iomux-mx27.h> ++# else ++# include <mach/iomux-mx25.h> ++# endif + #endif + + +diff -urNp linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/irqs.h linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/irqs.h +--- linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/irqs.h 2009-05-13 09:46:19.000000000 +0200 ++++ linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/irqs.h 2009-06-02 17:05:27.000000000 +0200 +@@ -21,7 +21,11 @@ + #if defined CONFIG_ARCH_MX1 + #define MXC_GPIO_IRQS (32 * 4) + #elif defined CONFIG_ARCH_MX2 ++#ifndef CONFIG_MACH_MX25 + #define MXC_GPIO_IRQS (32 * 6) ++#else ++#define MXC_GPIO_IRQS (32 * 4) ++#endif + #elif defined CONFIG_ARCH_MX3 + #define MXC_GPIO_IRQS (32 * 3) + #endif +diff -urNp linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/memory.h linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/memory.h +--- linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/memory.h 2009-05-13 09:46:19.000000000 +0200 ++++ linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/memory.h 2009-06-02 17:05:27.000000000 +0200 +@@ -14,12 +14,13 @@ + #if defined CONFIG_ARCH_MX1 + #define PHYS_OFFSET UL(0x08000000) + #elif defined CONFIG_ARCH_MX2 +-#ifdef CONFIG_MACH_MX21 ++# if defined(CONFIG_MACH_MX21) + #define PHYS_OFFSET UL(0xC0000000) +-#endif +-#ifdef CONFIG_MACH_MX27 ++# elif defined(CONFIG_MACH_MX27) + #define PHYS_OFFSET UL(0xA0000000) +-#endif ++# elif defined(CONFIG_MACH_MX25) ++#define PHYS_OFFSET UL(0x80000000) ++# endif + #elif defined CONFIG_ARCH_MX3 + #define PHYS_OFFSET UL(0x80000000) + #endif +diff -urNp linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/mx25.h linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/mx25.h +--- linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/mx25.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/mx25.h 2009-06-02 17:05:27.000000000 +0200 +@@ -0,0 +1,482 @@ ++/* ++ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved. ++ */ ++ ++/* ++ * The code contained herein is licensed under the GNU General Public ++ * License. You may obtain a copy of the GNU General Public License ++ * Version 2 or later at the following locations: ++ * ++ * http://www.opensource.org/licenses/gpl-license.html ++ * http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++/*! ++ * @file arch-mxc/mx25.h ++ * @brief This file contains register definitions. ++ * ++ * @ingroup MSL_MX25 ++ */ ++ ++#ifndef __ASM_ARCH_MXC_MX25_H__ ++#define __ASM_ARCH_MXC_MX25_H__ ++ ++#ifndef __ASM_ARCH_MXC_HARDWARE_H__ ++#error "Do not include directly." ++#endif ++ ++#ifdef CONFIG_DEBUG_LL ++#ifdef CONFIG_MACH_TX25 ++#include <mach/board-tx25.h> ++#endif ++#endif // CONFIG_DEBUG_LL ++ ++/* ++ * MX25 memory map: ++ * ++ * Virt Phys Size What ++ * --------------------------------------------------------------------------- ++ * FC000000 43F00000 1M AIPS 1 ++ * FC100000 50000000 1M SPBA ++ * FC200000 53F00000 1M AIPS 2 ++ * FC300000 60000000 1M ROMPATCH (128M) ++ * FC400000 68000000 1M ASIC (128M) ++ * FC500000 78000000 128K FBC RAM (IRAM) ++ * 80000000 256M SDRAM0 ++ * 90000000 256M SDRAM1 ++ * A0000000 128M CS0 Flash ++ * A8000000 128M CS1 Flash ++ * B0000000 32M CS2 SRAM ++ * B2000000 32M CS3 ++ * B4000000 32M CS4 ++ * B6000000 32M CS5 ++ * FC520000 B8000000 64K SDRAM, WEIM, M3IF, EMI controllers ++ * FC530000 BB000000 8K NFC ++ */ ++ ++#include <asm/memory.h> ++#define VA(x) _AT(void __force __iomem *,x) ++ ++/* ++ * IRAM ++ */ ++#define IRAM_BASE_ADDR UL(0x78000000) /* internal ram */ ++#define IRAM_BASE_ADDR_VIRT VA(0xFC500000) ++#define IRAM_SIZE SZ_128K ++ ++/* ++ * AIPS 1 ++ */ ++#define AIPS1_BASE_ADDR UL(0x43F00000) ++#define AIPS1_BASE_ADDR_VIRT VA(0xFC000000) ++#define AIPS1_SIZE SZ_1M ++ ++#define MAX_BASE_ADDR (AIPS1_BASE_ADDR + 0x00004000) ++#define CLKCTL_BASE_ADDR (AIPS1_BASE_ADDR + 0x00008000) ++#define ETB_SLOT4_BASE_ADDR (AIPS1_BASE_ADDR + 0x0000C000) ++#define ETB_SLOT5_BASE_ADDR (AIPS1_BASE_ADDR + 0x00010000) ++#define AAPE_BASE_ADDR (AIPS1_BASE_ADDR + 0x00014000) ++#define I2C_BASE_ADDR (AIPS1_BASE_ADDR + 0x00080000) ++#define I2C3_BASE_ADDR (AIPS1_BASE_ADDR + 0x00084000) ++#define CAN1_BASE_ADDR (AIPS1_BASE_ADDR + 0x00088000) ++#define CAN3_BASE_ADDR (AIPS1_BASE_ADDR + 0x0008C000) ++#define UART1_BASE_ADDR (AIPS1_BASE_ADDR + 0x00090000) ++#define UART2_BASE_ADDR (AIPS1_BASE_ADDR + 0x00094000) ++#define I2C2_BASE_ADDR (AIPS1_BASE_ADDR + 0x00098000) ++#define OWIRE_BASE_ADDR (AIPS1_BASE_ADDR + 0x0009C000) ++#define ATA_BASE_ADDR (AIPS1_BASE_ADDR + 0x000A0000) ++#define CSPI1_BASE_ADDR (AIPS1_BASE_ADDR + 0x000A4000) ++#define KPP_BASE_ADDR (AIPS1_BASE_ADDR + 0x000A8000) ++#define IOMUXC_BASE_ADDR (AIPS1_BASE_ADDR + 0x000AC000) ++#define AUDMUX_BASE_ADDR (AIPS1_BASE_ADDR + 0x000B0000) ++#define ECT_A_BASE_ADDR (AIPS1_BASE_ADDR + 0x000B8000) ++#define ECT_B_BASE_ADDR (AIPS1_BASE_ADDR + 0x000BC000) ++ ++/* ++ * SPBA global module enabled #0 ++ */ ++#define SPBA0_BASE_ADDR UL(0x50000000) ++#define SPBA0_BASE_ADDR_VIRT VA(0xFC100000) ++#define SPBA0_SIZE SZ_1M ++ ++#define CSPI3_BASE_ADDR (SPBA0_BASE_ADDR + 0x00004000) ++#define UART4_BASE_ADDR (SPBA0_BASE_ADDR + 0x00008000) ++#define UART3_BASE_ADDR (SPBA0_BASE_ADDR + 0x0000C000) ++#define CSPI2_BASE_ADDR (SPBA0_BASE_ADDR + 0x00010000) ++#define SSI2_BASE_ADDR (SPBA0_BASE_ADDR + 0x00014000) ++#define ESAI_BASE_ADDR (SPBA0_BASE_ADDR + 0x00018000) ++#define ATA_DMA_BASE_ADDR (SPBA0_BASE_ADDR + 0x00020000) ++#define SIM1_BASE_ADDR (SPBA0_BASE_ADDR + 0x00024000) ++#define SIM2_BASE_ADDR (SPBA0_BASE_ADDR + 0x00028000) ++#define UART5_BASE_ADDR (SPBA0_BASE_ADDR + 0x0002C000) ++#define TSC_BASE_ADDR (SPBA0_BASE_ADDR + 0x00030000) ++#define SSI1_BASE_ADDR (SPBA0_BASE_ADDR + 0x00034000) ++#define FEC_BASE_ADDR (SPBA0_BASE_ADDR + 0x00038000) ++#define SPBA_CTRL_BASE_ADDR (SPBA0_BASE_ADDR + 0x0003C000) ++ ++/*! ++ * defines for SPBA modules ++ */ ++#define SPBA_CSPI3 (0x1 << 2) ++#define SPBA_UART4 (0x2 << 2) ++#define SPBA_UART3 (0x3 << 2) ++#define SPBA_CSPI2 (0x4 << 2) ++#define SPBA_SSI2 (0x5 << 2) ++#define SPBA_ESAI (0x6 << 2) ++#define SPBA_ATA (0x8 << 2) ++#define SPBA_SIM1 (0x9 << 2) ++#define SPBA_SIM2 (0xA << 2) ++#define SPBA_UART5 (0xB << 2) ++#define SPBA_ANALOG (0xC << 2) ++#define SPBA_SSI1 (0xD << 2) ++#define SPBA_FEC (0xE << 2) ++ ++/*! ++ * Defines for modules using static and dynamic DMA channels ++ */ ++#define MXC_DMA_CHANNEL_IRAM 30 ++#define MXC_DMA_CHANNEL_UART1_RX MXC_DMA_DYNAMIC_CHANNEL ++#define MXC_DMA_CHANNEL_UART1_TX MXC_DMA_DYNAMIC_CHANNEL ++#define MXC_DMA_CHANNEL_UART2_RX MXC_DMA_DYNAMIC_CHANNEL ++#define MXC_DMA_CHANNEL_UART2_TX MXC_DMA_DYNAMIC_CHANNEL ++#define MXC_DMA_CHANNEL_UART3_RX MXC_DMA_DYNAMIC_CHANNEL ++#define MXC_DMA_CHANNEL_UART3_TX MXC_DMA_DYNAMIC_CHANNEL ++#define MXC_DMA_CHANNEL_UART4_RX MXC_DMA_DYNAMIC_CHANNEL ++#define MXC_DMA_CHANNEL_UART4_TX MXC_DMA_DYNAMIC_CHANNEL ++#define MXC_DMA_CHANNEL_UART5_RX MXC_DMA_DYNAMIC_CHANNEL ++#define MXC_DMA_CHANNEL_UART5_TX MXC_DMA_DYNAMIC_CHANNEL ++#define MXC_DMA_CHANNEL_MMC1 MXC_DMA_DYNAMIC_CHANNEL ++#define MXC_DMA_CHANNEL_SSI1_RX MXC_DMA_DYNAMIC_CHANNEL ++#ifdef CONFIG_SDMA_IRAM ++#define MXC_DMA_CHANNEL_SSI1_TX (MXC_DMA_CHANNEL_IRAM + 1) ++#else ++#define MXC_DMA_CHANNEL_SSI1_TX MXC_DMA_DYNAMIC_CHANNEL ++#endif ++#define MXC_DMA_CHANNEL_SSI2_RX MXC_DMA_DYNAMIC_CHANNEL ++#define MXC_DMA_CHANNEL_SSI2_TX MXC_DMA_DYNAMIC_CHANNEL ++#define MXC_DMA_CHANNEL_CSPI1_RX MXC_DMA_DYNAMIC_CHANNEL ++#define MXC_DMA_CHANNEL_CSPI1_TX MXC_DMA_DYNAMIC_CHANNEL ++#define MXC_DMA_CHANNEL_CSPI2_RX MXC_DMA_DYNAMIC_CHANNEL ++#define MXC_DMA_CHANNEL_CSPI2_TX MXC_DMA_DYNAMIC_CHANNEL ++#define MXC_DMA_CHANNEL_CSPI3_RX MXC_DMA_DYNAMIC_CHANNEL ++#define MXC_DMA_CHANNEL_CSPI3_TX MXC_DMA_DYNAMIC_CHANNEL ++#define MXC_DMA_CHANNEL_ATA_RX MXC_DMA_DYNAMIC_CHANNEL ++#define MXC_DMA_CHANNEL_ATA_TX MXC_DMA_DYNAMIC_CHANNEL ++#define MXC_DMA_CHANNEL_MEMORY MXC_DMA_DYNAMIC_CHANNEL ++#define MXC_DMA_CHANNEL_ESAI_RX MXC_DMA_DYNAMIC_CHANNEL ++#define MXC_DMA_CHANNEL_ESAI_TX MXC_DMA_DYNAMIC_CHANNEL ++ ++/* ++ * AIPS 2 ++ */ ++#define AIPS2_BASE_ADDR UL(0x53F00000) ++#define AIPS2_BASE_ADDR_VIRT VA(0xFC200000) ++#define AIPS2_SIZE SZ_1M ++ ++#define CCM_BASE_ADDR (AIPS2_BASE_ADDR + 0x00080000) ++#define GPT4_BASE_ADDR (AIPS2_BASE_ADDR + 0x00084000) ++#define GPT3_BASE_ADDR (AIPS2_BASE_ADDR + 0x00088000) ++#define GPT2_BASE_ADDR (AIPS2_BASE_ADDR + 0x0008C000) ++#define GPT1_BASE_ADDR (AIPS2_BASE_ADDR + 0x00090000) ++#define EPIT1_BASE_ADDR (AIPS2_BASE_ADDR + 0x00094000) ++#define EPIT2_BASE_ADDR (AIPS2_BASE_ADDR + 0x00098000) ++#define GPIO4_BASE_ADDR (AIPS2_BASE_ADDR + 0x0009C000) ++#define PWM2_BASE_ADDR (AIPS2_BASE_ADDR + 0x000A0000) ++#define GPIO3_BASE_ADDR (AIPS2_BASE_ADDR + 0x000A4000) ++#define PWM3_BASE_ADDR (AIPS2_BASE_ADDR + 0x000A8000) ++#define SCC_BASE_ADDR (AIPS2_BASE_ADDR + 0x000AC000) ++#define RNGD_BASE_ADDR (AIPS2_BASE_ADDR + 0x000B0000) ++#define MMC_SDHC1_BASE_ADDR (AIPS2_BASE_ADDR + 0x000B4000) ++#define MMC_SDHC2_BASE_ADDR (AIPS2_BASE_ADDR + 0x000B8000) ++#define LCDC_BASE_ADDR (AIPS2_BASE_ADDR + 0x000BC000) ++#define SLCDC_BASE_ADDR (AIPS2_BASE_ADDR + 0x000C0000) ++#define PWM4_BASE_ADDR (AIPS2_BASE_ADDR + 0x000C8000) ++#define GPIO1_BASE_ADDR (AIPS2_BASE_ADDR + 0x000CC000) ++#define GPIO2_BASE_ADDR (AIPS2_BASE_ADDR + 0x000D0000) ++#define SDMA_BASE_ADDR (AIPS2_BASE_ADDR + 0x000D4000) ++#define WDOG_BASE_ADDR (AIPS2_BASE_ADDR + 0x000DC000) ++#define PWM1_BASE_ADDR (AIPS2_BASE_ADDR + 0x000E0000) ++#define RTIC_BASE_ADDR (AIPS2_BASE_ADDR + 0x000EC000) ++#define IIM_BASE_ADDR (AIPS2_BASE_ADDR + 0x000F0000) ++#define USBOTG_BASE_ADDR (AIPS2_BASE_ADDR + 0x000F4000) ++#define OTG_BASE_ADDR USBOTG_BASE_ADDR ++#define CSI_BASE_ADDR (AIPS2_BASE_ADDR + 0x000F8000) ++#define DRYICE_BASE_ADDR (AIPS2_BASE_ADDR + 0x000FC000) ++ ++/* ++ * ROMP and ASIC ++ */ ++#define ROMP_BASE_ADDR UL(0x60000000) ++#define ROMP_BASE_ADDR_VIRT VA(0xFC300000) ++#define ROMP_SIZE SZ_1M ++ ++#define ASIC_BASE_ADDR UL(0x68000000) ++#define ASIC_BASE_ADDR_VIRT VA(0xFC400000) ++#define ASIC_SIZE SZ_1M ++#define AVIC_BASE_ADDR ASIC_BASE_ADDR ++#define AVIC_BASE_ADDR_VIRT ASIC_BASE_ADDR_VIRT ++#define AVIC_SIZE ASIC_SIZE ++ ++/* ++ * SDRAM, WEIM, M3IF, EMI controllers ++ */ ++#define X_MEMC_BASE_ADDR UL(0xB8000000) ++#define X_MEMC_BASE_ADDR_VIRT VA(0xFC520000) ++#define X_MEMC_SIZE SZ_64K ++ ++#define SDRAMC_BASE_ADDR (X_MEMC_BASE_ADDR + 0x1000) ++#define WEIM_BASE_ADDR (X_MEMC_BASE_ADDR + 0x2000) ++#define M3IF_BASE_ADDR (X_MEMC_BASE_ADDR + 0x3000) ++#define EMI_CTL_BASE_ADDR (X_MEMC_BASE_ADDR + 0x4000) ++ ++/* ++ * NFC controller ++ */ ++#define NFC_BASE_ADDR UL(0xBB000000) ++#define NFC_BASE_ADDR_VIRT VA(0xFC530000) ++#define NFC_SIZE SZ_8K ++ ++/* ++ * Memory regions and CS ++ */ ++#define CSD0_BASE_ADDR UL(0x80000000) ++#define CSD1_BASE_ADDR UL(0x90000000) ++ ++#define SDRAM_BASE_ADDR CSD0_BASE_ADDR ++ ++#define CS0_BASE_ADDR UL(0xA0000000) ++#define CS1_BASE_ADDR UL(0xA8000000) ++#define CS2_BASE_ADDR UL(0xB0000000) ++#define CS3_BASE_ADDR UL(0xB2000000) ++#define CS4_BASE_ADDR UL(0xB4000000) ++#define CS4_SIZE SZ_32M ++#define CS5_BASE_ADDR UL(0xB6000000) ++#define CS5_SIZE SZ_32M ++ ++/*! ++ * This macro defines the physical to virtual address mapping for all the ++ * peripheral modules. It is used by passing in the physical address as x ++ * and returning the virtual address. If the physical address is not mapped, ++ * it returns 0 ++ */ ++#define IO_ADDRESS(x) \ ++ VA((((x) >= AIPS1_BASE_ADDR) && ((x) < (AIPS1_BASE_ADDR + AIPS1_SIZE))) ? AIPS1_IO_ADDRESS(x): \ ++ (((x) >= SPBA0_BASE_ADDR) && ((x) < (SPBA0_BASE_ADDR + SPBA0_SIZE))) ? SPBA0_IO_ADDRESS(x): \ ++ (((x) >= AIPS2_BASE_ADDR) && ((x) < (AIPS2_BASE_ADDR + AIPS2_SIZE))) ? AIPS2_IO_ADDRESS(x): \ ++ (((x) >= ROMP_BASE_ADDR) && ((x) < (ROMP_BASE_ADDR + ROMP_SIZE))) ? ROMP_IO_ADDRESS(x): \ ++ (((x) >= ASIC_BASE_ADDR) && ((x) < (ASIC_BASE_ADDR + AVIC_SIZE))) ? ASIC_IO_ADDRESS(x): \ ++ (((x) >= IRAM_BASE_ADDR) && ((x) < (IRAM_BASE_ADDR + IRAM_SIZE))) ? IRAM_IO_ADDRESS(x): \ ++ (((x) >= X_MEMC_BASE_ADDR) && ((x) < (X_MEMC_BASE_ADDR + X_MEMC_SIZE))) ? X_MEMC_IO_ADDRESS(x): \ ++ (((x) >= NFC_BASE_ADDR) && ((x) < (NFC_BASE_ADDR + NFC_SIZE))) ? NFC_IO_ADDRESS(x): \ ++ 0) ++ ++#define MXC_VADDR_RANGE(v,n) \ ++ (((v)) >= n##_BASE_ADDR_VIRT) && \ ++ (((v)) < n##_BASE_ADDR_VIRT + n##_SIZE) ? \ ++ ((v)-n##_BASE_ADDR_VIRT + n##_BASE_ADDR) : ++ ++#define MXC_PHYS_ADDRESS(v) \ ++ UL(MXC_VADDR_RANGE(v,AIPS1) \ ++ MXC_VADDR_RANGE(v,AIPS2) \ ++ MXC_VADDR_RANGE(v,SPBA0) \ ++ MXC_VADDR_RANGE(v,ROMP) \ ++ MXC_VADDR_RANGE(v,ASIC) \ ++ MXC_VADDR_RANGE(v,IRAM) \ ++ MXC_VADDR_RANGE(v,X_MEMC) \ ++ MXC_VADDR_RANGE(v,NFC) \ ++ 0) ++ ++#define GPIO_BASE_ADDR(port) \ ++ ((port == 1 ? GPIO1_BASE_ADDR : \ ++ (port == 2 ? GPIO2_BASE_ADDR : \ ++ (port == 3 ? GPIO3_BASE_ADDR : \ ++ (port == 4 ? GPIO4_BASE_ADDR : 0))))) ++ ++/* ++ * define the address mapping macros: in physical address order ++ */ ++ ++#define AIPS1_IO_ADDRESS(x) \ ++ (((x) - AIPS1_BASE_ADDR) + AIPS1_BASE_ADDR_VIRT) ++ ++#define SPBA0_IO_ADDRESS(x) \ ++ (((x) - SPBA0_BASE_ADDR) + SPBA0_BASE_ADDR_VIRT) ++ ++#define AIPS2_IO_ADDRESS(x) \ ++ (((x) - AIPS2_BASE_ADDR) + AIPS2_BASE_ADDR_VIRT) ++ ++#define ROMP_IO_ADDRESS(x) \ ++ (((x) - ROMP_BASE_ADDR) + ROMP_BASE_ADDR_VIRT) ++ ++#define ASIC_IO_ADDRESS(x) \ ++ (((x) - ASIC_BASE_ADDR) + ASIC_BASE_ADDR_VIRT) ++ ++/* for entry-macro.S */ ++#define AVIC_IO_ADDRESS(x) ASIC_IO_ADDRESS(x) ++ ++#define IRAM_IO_ADDRESS(x) \ ++ (((x) - IRAM_BASE_ADDR) + IRAM_BASE_ADDR_VIRT) ++ ++#define X_MEMC_IO_ADDRESS(x) \ ++ (((x) - X_MEMC_BASE_ADDR) + X_MEMC_BASE_ADDR_VIRT) ++ ++#define NFC_IO_ADDRESS(x) \ ++ (((x) - NFC_BASE_ADDR) + NFC_BASE_ADDR_VIRT) ++ ++/* ++ * DMA request assignments ++ */ ++#define DMA_REQ_EXTREQ0 0 ++#define DMA_REQ_CCM 1 ++#define DMA_REQ_ATA_TX_END 2 ++#define DMA_REQ_ATA_TX 3 ++#define DMA_REQ_ATA_RX 4 ++#define DMA_REQ_CSPI2_RX 6 ++#define DMA_REQ_CSPI2_TX 7 ++#define DMA_REQ_CSPI1_RX 8 ++#define DMA_REQ_CSPI1_TX 9 ++#define DMA_REQ_UART3_RX 10 ++#define DMA_REQ_UART3_TX 11 ++#define DMA_REQ_UART4_RX 12 ++#define DMA_REQ_UART4_TX 13 ++#define DMA_REQ_EXTREQ1 14 ++#define DMA_REQ_EXTREQ2 15 ++#define DMA_REQ_UART2_RX 16 ++#define DMA_REQ_UART2_TX 17 ++#define DMA_REQ_UART1_RX 18 ++#define DMA_REQ_UART1_TX 19 ++#define DMA_REQ_SSI2_RX1 22 ++#define DMA_REQ_SSI2_TX1 23 ++#define DMA_REQ_SSI2_RX0 24 ++#define DMA_REQ_SSI2_TX0 25 ++#define DMA_REQ_SSI1_RX1 26 ++#define DMA_REQ_SSI1_TX1 27 ++#define DMA_REQ_SSI1_RX0 28 ++#define DMA_REQ_SSI1_TX0 29 ++#define DMA_REQ_NFC 30 ++#define DMA_REQ_ECT 31 ++#define DMA_REQ_ESAI_RX 32 ++#define DMA_REQ_ESAI_TX 33 ++#define DMA_REQ_CSPI3_RX 34 ++#define DMA_REQ_CSPI3_TX 35 ++#define DMA_REQ_SIM2_RX 36 ++#define DMA_REQ_SIM2_TX 37 ++#define DMA_REQ_SIM1_RX 38 ++#define DMA_REQ_SIM1_TX 39 ++#define DMA_REQ_TSC_GCQ 44 ++#define DMA_REQ_TSC_TCQ 45 ++#define DMA_REQ_UART5_RX 46 ++#define DMA_REQ_UART5_TX 47 ++ ++/* ++ * Interrupt numbers ++ */ ++#define MXC_INT_CSPI3 0 ++#define MXC_INT_GPT4 1 ++#define MXC_INT_OWIRE 2 ++#define MXC_INT_I2C 3 ++#define MXC_INT_I2C2 4 ++#define MXC_INT_UART4 5 ++#define MXC_INT_RTIC 6 ++#define MXC_INT_ESAI 7 ++#define MXC_INT_SDHC2 8 ++#define MXC_INT_SDHC1 9 ++#define MXC_INT_I2C3 10 ++#define MXC_INT_SSI2 11 ++#define MXC_INT_SSI1 12 ++#define MXC_INT_CSPI2 13 ++#define MXC_INT_CSPI1 14 ++#define MXC_INT_ATA 15 ++#define MXC_INT_GPIO3 16 ++#define MXC_INT_CSI 17 ++#define MXC_INT_UART3 18 ++#define MXC_INT_IIM 19 ++#define MXC_INT_SIM1 20 ++#define MXC_INT_SIM2 21 ++#define MXC_INT_RNGD 22 ++#define MXC_INT_GPIO4 23 ++#define MXC_INT_KPP 24 ++#define MXC_INT_DRYICE_RTC 25 ++#define MXC_INT_PWM 26 ++#define MXC_INT_EPIT2 27 ++#define MXC_INT_EPIT1 28 ++#define MXC_INT_GPT3 29 ++#define MXC_INT_POWER_FAIL 30 ++#define MXC_INT_CRM 31 ++#define MXC_INT_UART2 32 ++#define MXC_INT_NANDFC 33 ++#define MXC_INT_SDMA 34 ++#define MXC_INT_USB_HTG 35 ++#define MXC_INT_PWM2 36 ++#define MXC_INT_USB_OTG 37 ++#define MXC_INT_SLCDC 38 ++#define MXC_INT_LCDC 39 ++#define MXC_INT_UART5 40 ++#define MXC_INT_PWM3 41 ++#define MXC_INT_PWM4 42 ++#define MXC_INT_CAN1 43 ++#define MXC_INT_CAN2 44 ++#define MXC_INT_UART1 45 ++#define MXC_INT_TSC 46 ++#define MXC_INT_ECT 48 ++#define MXC_INT_SCC_SCM 49 ++#define MXC_INT_SCC_SMN 50 ++#define MXC_INT_GPIO2 51 ++#define MXC_INT_GPIO1 52 ++#define MXC_INT_GPT2 53 ++#define MXC_INT_GPT1 54 ++#define MXC_INT_WDOG 55 ++#define MXC_INT_DRYICE 56 ++#define MXC_INT_FEC 57 ++#define MXC_INT_EXT_INT5 58 ++#define MXC_INT_EXT_INT4 59 ++#define MXC_INT_EXT_INT3 60 ++#define MXC_INT_EXT_INT2 61 ++#define MXC_INT_EXT_INT1 62 ++#define MXC_INT_EXT_INT0 63 ++ ++#define MXC_INT_GPT MXC_INT_GPT1 ++ ++/* silicon revisions specific to i.MX25 */ ++#define CHIP_REV_1_0 0x00 ++#define CHIP_REV_1_1 0x01 ++ ++/* gpio and gpio based interrupt handling */ ++#define GPIO_DR 0x00 ++#define GPIO_GDIR 0x04 ++#define GPIO_PSR 0x08 ++#define GPIO_ICR1 0x0C ++#define GPIO_ICR2 0x10 ++#define GPIO_IMR 0x14 ++#define GPIO_ISR 0x18 ++#define GPIO_INT_LOW_LEV 0x0 ++#define GPIO_INT_HIGH_LEV 0x1 ++#define GPIO_INT_RISE_EDGE 0x2 ++#define GPIO_INT_FALL_EDGE 0x3 ++#define GPIO_INT_NONE 0x4 ++ ++/* Mandatory defines used globally */ ++ ++/* this CPU supports up to 96 GPIOs */ ++#define ARCH_NR_GPIOS 128 ++ ++#define MXC_TIMER_GPT1 1 ++#define MXC_TIMER_GPT2 2 ++#define MXC_TIMER_GPT3 3 ++#define MXC_TIMER_GPT4 4 ++ ++/*! ++ * NFMS bit in RCSR register for pagesize of nandflash ++ */ ++#define NFMS_REG IO_ADDRESS(CCM_BASE_ADDR + 0x28) ++#define NFMS_NF_DWIDTH 14 ++#define NFMS_NF_PG_SZ 8 ++ ++#if !defined(__ASSEMBLY__) && !defined(__MXC_BOOT_UNCOMPRESS) ++#include <linux/io.h> ++ ++extern int mx25_revision(void); ++ ++#endif ++ ++#endif /* __ASM_ARCH_MXC_MX25_H__ */ +diff -urNp linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/mx2x.h linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/mx2x.h +--- linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/mx2x.h 2009-05-13 09:46:19.000000000 +0200 ++++ linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/mx2x.h 2009-06-02 17:05:27.000000000 +0200 +@@ -79,7 +79,7 @@ + * This macro defines the physical to virtual address mapping for all the + * peripheral modules. It is used by passing in the physical address as x + * and returning the virtual address. If the physical address is not mapped, +- * it returns 0xDEADBEEF ++ * it returns 0 + */ + #define IO_ADDRESS(x) \ + (void __force __iomem *) \ +@@ -88,7 +88,7 @@ + ((x >= SAHB1_BASE_ADDR) && (x < (SAHB1_BASE_ADDR + SAHB1_SIZE))) ? \ + SAHB1_IO_ADDRESS(x) : \ + ((x >= X_MEMC_BASE_ADDR) && (x < (X_MEMC_BASE_ADDR + X_MEMC_SIZE))) ? \ +- X_MEMC_IO_ADDRESS(x) : 0xDEADBEEF) ++ X_MEMC_IO_ADDRESS(x) : 0) + + /* define the address mapping macros: in physical address order */ + #define AIPI_IO_ADDRESS(x) \ +diff -urNp linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/mxc.h linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/mxc.h +--- linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/mxc.h 2009-05-13 09:46:19.000000000 +0200 ++++ linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/mxc.h 2009-06-02 17:05:27.000000000 +0200 +@@ -27,6 +27,7 @@ + #define MXC_CPU_MX1 1 + #define MXC_CPU_MX21 21 + #define MXC_CPU_MX27 27 ++#define MXC_CPU_MX25 25 + #define MXC_CPU_MX31 31 + #define MXC_CPU_MX35 35 + +@@ -70,6 +71,18 @@ extern unsigned int __mxc_cpu_type; + # define cpu_is_mx27() (0) + #endif + ++#ifdef CONFIG_MACH_MX25 ++# ifdef mxc_cpu_type ++# undef mxc_cpu_type ++# define mxc_cpu_type __mxc_cpu_type ++# else ++# define mxc_cpu_type MXC_CPU_MX25 ++# endif ++# define cpu_is_mx25() (mxc_cpu_type == MXC_CPU_MX25) ++#else ++# define cpu_is_mx25() (0) ++#endif ++ + #ifdef CONFIG_ARCH_MX31 + # ifdef mxc_cpu_type + # undef mxc_cpu_type +@@ -101,6 +114,6 @@ extern unsigned int __mxc_cpu_type; + #endif + + #define cpu_is_mx3() (cpu_is_mx31() || cpu_is_mx35()) +-#define cpu_is_mx2() (cpu_is_mx21() || cpu_is_mx27()) ++#define cpu_is_mx2() (cpu_is_mx21() || cpu_is_mx25() || cpu_is_mx27()) + + #endif /* __ASM_ARCH_MXC_H__ */ +diff -urNp linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/sdma.h linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/sdma.h +--- linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/sdma.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/sdma.h 2009-06-02 17:05:27.000000000 +0200 +@@ -0,0 +1,504 @@ ++ ++/* ++ * Copyright 2004-2008 Freescale Semiconductor, Inc. All Rights Reserved. ++ */ ++ ++/* ++ * The code contained herein is licensed under the GNU General Public ++ * License. You may obtain a copy of the GNU General Public License ++ * Version 2 or later at the following locations: ++ * ++ * http://www.opensource.org/licenses/gpl-license.html ++ * http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++#ifndef __ASM_ARCH_MXC_SDMA_H__ ++#define __ASM_ARCH_MXC_SDMA_H__ ++ ++/*! ++ * @defgroup SDMA Smart Direct Memory Access (SDMA) Driver ++ */ ++ ++/*! ++ * @file arch-mxc/sdma.h ++ * ++ * @brief This file contains the SDMA API declarations. ++ * ++ * SDMA is responsible on moving data between peripherals and memories (MCU, EMI and DSP). ++ * ++ * @ingroup SDMA ++ */ ++ ++#include <stdarg.h> ++#include <linux/interrupt.h> ++#include <mach/dma.h> ++#include <mach/hardware.h> ++ ++/*! ++ * This defines maximum DMA address ++ */ ++#define MAX_DMA_ADDRESS 0xffffffff ++ ++/*! ++ * This defines maximum number of DMA channels ++ */ ++#ifdef CONFIG_MXC_SDMA_API ++#define MAX_DMA_CHANNELS 32 ++#define MAX_BD_NUMBER 16 ++#define MXC_SDMA_DEFAULT_PRIORITY 1 ++#define MXC_SDMA_MIN_PRIORITY 1 ++#define MXC_SDMA_MAX_PRIORITY 7 ++#else ++#define MAX_DMA_CHANNELS 0 ++#endif ++ ++#define MXC_FIFO_MEM_DEST_FIXED 0x1 ++#define MXC_FIFO_MEM_SRC_FIXED 0x2 ++/*! ++ * This enumerates transfer types ++ */ ++typedef enum { ++ emi_2_per = 0, /*!< EMI memory to peripheral */ ++ emi_2_int, /*!< EMI memory to internal RAM */ ++ emi_2_emi, /*!< EMI memory to EMI memory */ ++ emi_2_dsp, /*!< EMI memory to DSP memory */ ++ per_2_int, /*!< Peripheral to internal RAM */ ++ per_2_emi, /*!< Peripheral to internal EMI memory */ ++ per_2_dsp, /*!< Peripheral to DSP memory */ ++ per_2_per, /*!< Peripheral to Peripheral */ ++ int_2_per, /*!< Internal RAM to peripheral */ ++ int_2_int, /*!< Internal RAM to Internal RAM */ ++ int_2_emi, /*!< Internal RAM to EMI memory */ ++ int_2_dsp, /*!< Internal RAM to DSP memory */ ++ dsp_2_per, /*!< DSP memory to peripheral */ ++ dsp_2_int, /*!< DSP memory to internal RAM */ ++ dsp_2_emi, /*!< DSP memory to EMI memory */ ++ dsp_2_dsp, /*!< DSP memory to DSP memory */ ++ emi_2_dsp_loop, /*!< EMI memory to DSP memory loopback */ ++ dsp_2_emi_loop, /*!< DSP memory to EMI memory loopback */ ++ dvfs_pll, /*!< DVFS script with PLL change */ ++ dvfs_pdr /*!< DVFS script without PLL change */ ++} sdma_transferT; ++ ++/*! ++ * This enumerates peripheral types ++ */ ++typedef enum { ++ SSI, /*!< MCU domain SSI */ ++ SSI_SP, /*!< Shared SSI */ ++ MMC, /*!< MMC */ ++ SDHC, /*!< SDHC */ ++ UART, /*!< MCU domain UART */ ++ UART_SP, /*!< Shared UART */ ++ FIRI, /*!< FIRI */ ++ CSPI, /*!< MCU domain CSPI */ ++ CSPI_SP, /*!< Shared CSPI */ ++ SIM, /*!< SIM */ ++ ATA, /*!< ATA */ ++ CCM, /*!< CCM */ ++ EXT, /*!< External peripheral */ ++ MSHC, /*!< Memory Stick Host Controller */ ++ MSHC_SP, /*!< Shared Memory Stick Host Controller */ ++ DSP, /*!< DSP */ ++ MEMORY, /*!< Memory */ ++ FIFO_MEMORY, /*!< FIFO type Memory */ ++ SPDIF, /*!< SPDIF */ ++ IPU_MEMORY, /*!< IPU Memory */ ++ ASRC, /*!< ASRC */ ++ ESAI, /*!< ESAI */ ++} sdma_periphT; ++ ++#ifndef TRANSFER_32BIT ++/*! ++ * This defines SDMA access data size ++ */ ++#define TRANSFER_32BIT 0x00 ++#define TRANSFER_8BIT 0x01 ++#define TRANSFER_16BIT 0x02 ++#define TRANSFER_24BIT 0x03 ++ ++#endif ++ ++/*! ++ * This defines maximum device name length passed during mxc_request_dma(). ++ */ ++#define MAX_DEVNAME_LENGTH 32 ++ ++/*! ++ * This defines SDMA interrupt callback function prototype. ++ */ ++typedef void (*dma_callback_t) (void *arg); ++ ++/*! ++ * Structure containing sdma channel parameters. ++ */ ++typedef struct { ++ __u32 watermark_level; /*!< Lower/upper threshold that ++ * triggers SDMA event ++ */ ++ __u32 per_address; /*!< Peripheral source/destination ++ * physical address ++ */ ++ sdma_periphT peripheral_type; /*!< Peripheral type */ ++ sdma_transferT transfer_type; /*!< Transfer type */ ++ int event_id; /*!< Event number, ++ * needed by all channels ++ * that started by peripherals dma ++ * request (per_2_*,*_2_per) ++ * Not used for memory and DSP ++ * transfers. ++ */ ++ int event_id2; /*!< Second event number, ++ * used in ATA scripts only. ++ */ ++ int bd_number; /*!< Buffer descriptors number. ++ * If not set, single buffer ++ * descriptor will be used. ++ */ ++ dma_callback_t callback; /*! callback function */ ++ void *arg; /*! callback argument */ ++ unsigned long word_size:8; /*!< SDMA data access word size */ ++} dma_channel_params; ++ ++/*! ++ * Structure containing sdma request parameters. ++ */ ++typedef struct { ++ /*! physical source memory address */ ++ __u8 *sourceAddr; ++ /*! physical destination memory address */ ++ __u8 *destAddr; ++ /*! amount of data to transfer, ++ * updated during mxc_dma_get_config ++ */ ++ __u16 count; ++ /*!< DONE bit of the buffer descriptor, ++ * updated during mxc_dma_get_config ++ * 0 - means the BD is done and closed by SDMA ++ * 1 - means the BD is still being processed by SDMA ++ */ ++ int bd_done; ++ /*!< CONT bit of the buffer descriptor, ++ * set it if full multi-buffer descriptor mechanism ++ * required. ++ */ ++ int bd_cont; ++ /*!< ERROR bit of the buffer descriptor, ++ * updated during mxc_dma_get_config. ++ * If it is set - there was an error during BD processing. ++ */ ++ int bd_error; ++} dma_request_t; ++ ++/*! ++ * Structure containing sdma request parameters. ++ */ ++typedef struct { ++ /*! address of ap_2_ap script */ ++ int mxc_sdma_ap_2_ap_addr; ++ /*! address of ap_2_bp script */ ++ int mxc_sdma_ap_2_bp_addr; ++ /*! address of ap_2_ap_fixed script */ ++ int mxc_sdma_ap_2_ap_fixed_addr; ++ /*! address of bp_2_ap script */ ++ int mxc_sdma_bp_2_ap_addr; ++ /*! address of loopback_on_dsp_side script */ ++ int mxc_sdma_loopback_on_dsp_side_addr; ++ /*! address of mcu_interrupt_only script */ ++ int mxc_sdma_mcu_interrupt_only_addr; ++ ++ /*! address of firi_2_per script */ ++ int mxc_sdma_firi_2_per_addr; ++ /*! address of firi_2_mcu script */ ++ int mxc_sdma_firi_2_mcu_addr; ++ /*! address of per_2_firi script */ ++ int mxc_sdma_per_2_firi_addr; ++ /*! address of mcu_2_firi script */ ++ int mxc_sdma_mcu_2_firi_addr; ++ ++ /*! address of uart_2_per script */ ++ int mxc_sdma_uart_2_per_addr; ++ /*! address of uart_2_mcu script */ ++ int mxc_sdma_uart_2_mcu_addr; ++ /*! address of per_2_app script */ ++ int mxc_sdma_per_2_app_addr; ++ /*! address of mcu_2_app script */ ++ int mxc_sdma_mcu_2_app_addr; ++ /*! address of per_2_per script */ ++ int mxc_sdma_per_2_per_addr; ++ ++ /*! address of uartsh_2_per script */ ++ int mxc_sdma_uartsh_2_per_addr; ++ /*! address of uartsh_2_mcu script */ ++ int mxc_sdma_uartsh_2_mcu_addr; ++ /*! address of per_2_shp script */ ++ int mxc_sdma_per_2_shp_addr; ++ /*! address of mcu_2_shp script */ ++ int mxc_sdma_mcu_2_shp_addr; ++ ++ /*! address of ata_2_mcu script */ ++ int mxc_sdma_ata_2_mcu_addr; ++ /*! address of mcu_2_ata script */ ++ int mxc_sdma_mcu_2_ata_addr; ++ ++ /*! address of app_2_per script */ ++ int mxc_sdma_app_2_per_addr; ++ /*! address of app_2_mcu script */ ++ int mxc_sdma_app_2_mcu_addr; ++ /*! address of shp_2_per script */ ++ int mxc_sdma_shp_2_per_addr; ++ /*! address of shp_2_mcu script */ ++ int mxc_sdma_shp_2_mcu_addr; ++ ++ /*! address of mshc_2_mcu script */ ++ int mxc_sdma_mshc_2_mcu_addr; ++ /*! address of mcu_2_mshc script */ ++ int mxc_sdma_mcu_2_mshc_addr; ++ ++ /*! address of spdif_2_mcu script */ ++ int mxc_sdma_spdif_2_mcu_addr; ++ /*! address of mcu_2_spdif script */ ++ int mxc_sdma_mcu_2_spdif_addr; ++ ++ /*! address of asrc_2_mcu script */ ++ int mxc_sdma_asrc_2_mcu_addr; ++ ++ /*! address of ext_mem_2_ipu script */ ++ int mxc_sdma_ext_mem_2_ipu_addr; ++ ++ /*! address of descrambler script */ ++ int mxc_sdma_descrambler_addr; ++ ++ /*! address of dptc_dvfs script */ ++ int mxc_sdma_dptc_dvfs_addr; ++ ++ int mxc_sdma_utra_addr; ++ ++ /*! address where ram code starts */ ++ int mxc_sdma_ram_code_start_addr; ++ /*! size of the ram code */ ++ int mxc_sdma_ram_code_size; ++ /*! RAM image address */ ++ unsigned short *mxc_sdma_start_addr; ++} sdma_script_start_addrs; ++ ++/*! Structure to store the initialized dma_channel parameters */ ++typedef struct mxc_sdma_channel_params { ++ /*! Channel params */ ++ dma_channel_params chnl_params; ++ /*! Channel type (static channel number or dynamic channel) */ ++ unsigned int channel_num; ++ /*! Channel priority [0x1(lowest) - 0x7(highest)] */ ++ unsigned int chnl_priority; ++} mxc_sdma_channel_params_t; ++ ++/*! Private SDMA data structure */ ++typedef struct mxc_dma_channel_private { ++ /*! ID of the buffer that was processed */ ++ unsigned int buf_tail; ++ /*! Tasklet for the channel */ ++ struct tasklet_struct chnl_tasklet; ++ /*! Flag indicates if interrupt is required after every BD transfer */ ++ int intr_after_every_bd; ++} mxc_dma_channel_private_t; ++ ++/*! ++ * Setup channel according to parameters. ++ * Must be called once after mxc_request_dma() ++ * ++ * @param channel channel number ++ * @param p channel parameters pointer ++ * @return 0 on success, error code on fail ++ */ ++int mxc_dma_setup_channel(int channel, dma_channel_params * p); ++ ++/*! ++ * Setup the channel priority. This can be used to change the default priority ++ * for the channel. ++ * ++ * @param channel channel number ++ * @param priority priority to be set for the channel ++ * ++ * @return 0 on success, error code on failure ++ */ ++int mxc_dma_set_channel_priority(unsigned int channel, unsigned int priority); ++ ++/*! ++ * Allocates dma channel. ++ * If channel's value is 0, then the function allocates a free channel ++ * dynamically and sets its value to channel. ++ * Else allocates requested channel if it is free. ++ * If the channel is busy or no free channels (in dynamic allocation) -EBUSY returned. ++ * ++ * @param channel pointer to channel number ++ * @param devicename device name ++ * @return 0 on success, error code on fail ++ */ ++int mxc_request_dma(int *channel, const char *devicename); ++ ++/*! ++ * Configures request parameters. Can be called multiple times after ++ * mxc_request_dma() and mxc_dma_setup_channel(). ++ * ++ * ++ * @param channel channel number ++ * @param p request parameters pointer ++ * @param bd_index index of buffer descriptor to set ++ * @return 0 on success, error code on fail ++ */ ++/* int mxc_dma_set_config(int channel, dma_request_t *p, int bd_index); */ ++int mxc_dma_set_config(int channel, dma_request_t * p, int bd_index); ++ ++/*! ++ * Returns request parameters. ++ * ++ * @param channel channel number ++ * @param p request parameters pointer ++ * @param bd_index index of buffer descriptor to get ++ * @return 0 on success, error code on fail ++ */ ++/* int mxc_dma_get_config(int channel, dma_request_t *p, int bd_index); */ ++int mxc_dma_get_config(int channel, dma_request_t * p, int bd_index); ++ ++/*! ++ * This function is used by MXC IPC's write_ex2. It passes the a pointer to the ++ * data control structure to iapi_write_ipcv2() ++ * ++ * @param channel SDMA channel number ++ * @param ctrl_ptr Data Control structure pointer ++ */ ++int mxc_sdma_write_ipcv2(int channel, void *ctrl_ptr); ++ ++/*! ++ * This function is used by MXC IPC's read_ex2. It passes the a pointer to the ++ * data control structure to iapi_read_ipcv2() ++ * ++ * @param channel SDMA channel number ++ * @param ctrl_ptr Data Control structure pointer ++ */ ++int mxc_sdma_read_ipcv2(int channel, void *ctrl_ptr); ++ ++/*! ++ * Starts dma channel. ++ * ++ * @param channel channel number ++ */ ++int mxc_dma_start(int channel); ++ ++/*! ++ * Stops dma channel. ++ * ++ * @param channel channel number ++ */ ++int mxc_dma_stop(int channel); ++ ++/*! ++ * Frees dma channel. ++ * ++ * @param channel channel number ++ */ ++void mxc_free_dma(int channel); ++ ++/*! ++ * Sets callback function. Used with standard dma api ++ * for supporting interrupts ++ * ++ * @param channel channel number ++ * @param callback callback function pointer ++ * @param arg argument for callback function ++ */ ++void mxc_dma_set_callback(int channel, dma_callback_t callback, void *arg); ++ ++/*! ++ * Allocates uncachable buffer. Uses hash table. ++ * ++ * @param size size of allocated buffer ++ * @return pointer to buffer ++ */ ++void *sdma_malloc(size_t size); ++ ++#ifdef CONFIG_SDMA_IRAM ++/*! ++ * Allocates uncachable buffer from IRAM.. ++ * ++ * @param size size of allocated buffer ++ * @return pointer to buffer ++ */ ++void *sdma_iram_malloc(size_t size); ++#endif /*CONFIG_SDMA_IRAM */ ++ ++/*! ++ * Frees uncachable buffer. Uses hash table. ++ */ ++void sdma_free(void *buf); ++ ++/*! ++ * Converts virtual to physical address. Uses hash table. ++ * ++ * @param buf virtual address pointer ++ * @return physical address value ++ */ ++unsigned long sdma_virt_to_phys(void *buf); ++ ++/*! ++ * Converts physical to virtual address. Uses hash table. ++ * ++ * @param buf physical address value ++ * @return virtual address pointer ++ */ ++void *sdma_phys_to_virt(unsigned long buf); ++ ++/*! ++ * Configures the BD_INTR bit on a buffer descriptor parameters. ++ * ++ * ++ * @param channel channel number ++ * @param bd_index index of buffer descriptor to set ++ * @param bd_intr flag to set or clear the BD_INTR bit ++ */ ++void mxc_dma_set_bd_intr(int channel, int bd_index, int bd_intr); ++ ++/*! ++ * Gets the BD_INTR bit on a buffer descriptor. ++ * ++ * ++ * @param channel channel number ++ * @param bd_index index of buffer descriptor to set ++ * ++ * @return returns the BD_INTR bit status ++ */ ++int mxc_dma_get_bd_intr(int channel, int bd_index); ++ ++/*! ++ * Stop the current transfer ++ * ++ * @param channel channel number ++ * @param buffer_number number of buffers (beginning with 0), ++ * whose done bits should be reset to 0 ++ */ ++int mxc_dma_reset(int channel, int buffer_number); ++ ++/*! ++ * This functions Returns the SDMA paramaters associated for a module ++ * ++ * @param channel_id the ID of the module requesting DMA ++ * @return returns the sdma parameters structure for the device ++ */ ++mxc_sdma_channel_params_t *mxc_sdma_get_channel_params(mxc_dma_device_t ++ channel_id); ++ ++/*! ++ * This functions marks the SDMA channels that are statically allocated ++ * ++ * @param chnl the channel array used to store channel information ++ */ ++void mxc_get_static_channels(mxc_dma_channel_t * chnl); ++ ++/*! ++ * Initializes SDMA driver ++ */ ++int __init sdma_init(void); ++ ++#define DEFAULT_ERR 1 ++ ++#endif +diff -urNp linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/spba.h linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/spba.h +--- linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/spba.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/spba.h 2009-06-02 17:05:27.000000000 +0200 +@@ -0,0 +1,66 @@ ++ ++/* ++ * Copyright 2004-2008 Freescale Semiconductor, Inc. All Rights Reserved. ++ */ ++ ++/* ++ * The code contained herein is licensed under the GNU General Public ++ * License. You may obtain a copy of the GNU General Public License ++ * Version 2 or later at the following locations: ++ * ++ * http://www.opensource.org/licenses/gpl-license.html ++ * http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++/*! ++ * @defgroup SPBA Shared Peripheral Bus Arbiter (SPBA) ++ * @ingroup MSL_MX31 MSL_MX35 MSL_MX37 MSL_MX51 MSL_MXC91321 ++ */ ++ ++/*! ++ * @file arch-mxc/spba.h ++ * @brief This file contains the Shared Peripheral Bus Arbiter (spba) API. ++ * ++ * @ingroup SPBA ++ */ ++ ++#ifndef __ASM_ARCH_MXC_SPBA_H__ ++#define __ASM_ARCH_MXC_SPBA_H__ ++ ++#ifdef __KERNEL__ ++ ++#define MXC_SPBA_RAR_MASK 0x7 ++ ++/*! ++ * Defines three SPBA masters: A - ARM, C - SDMA (no master B for MX31) ++ */ ++enum spba_masters { ++ SPBA_MASTER_A = 1, ++ SPBA_MASTER_B = 2, ++ SPBA_MASTER_C = 4, ++}; ++ ++/*! ++ * This function allows the three masters (A, B, C) to take ownership of a ++ * shared peripheral. ++ * ++ * @param mod specified module as defined in \b enum \b #spba_module ++ * @param master one of more (or-ed together) masters as defined in \b enum \b #spba_masters ++ * ++ * @return 0 if successful; -1 otherwise. ++ */ ++int spba_take_ownership(int mod, int master); ++ ++/*! ++ * This function releases the ownership for a shared peripheral. ++ * ++ * @param mod specified module as defined in \b enum \b #spba_module ++ * @param master one of more (or-ed together) masters as defined in \b enum \b #spba_masters ++ * ++ * @return 0 if successful; -1 otherwise. ++ */ ++int spba_rel_ownership(int mod, int master); ++ ++#endif /* __KERNEL__ */ ++ ++#endif /* __ASM_ARCH_MXC_SPBA_H__ */ +diff -urNp linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/timex.h linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/timex.h +--- linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/timex.h 2009-05-13 09:46:19.000000000 +0200 ++++ linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/timex.h 2009-06-02 17:05:27.000000000 +0200 +@@ -23,7 +23,11 @@ + #if defined CONFIG_ARCH_MX1 + #define CLOCK_TICK_RATE 16000000 + #elif defined CONFIG_ARCH_MX2 ++#ifndef CONFIG_MACH_MX25 + #define CLOCK_TICK_RATE 13300000 ++#else ++#define CLOCK_TICK_RATE 12000000 ++#endif + #elif defined CONFIG_ARCH_MX3 + #define CLOCK_TICK_RATE 16625000 + #endif +diff -urNp linux-2.6.30-rc4/arch/arm/plat-mxc/iomux-mx1-mx2.c linux-2.6.30-rc4-karo/arch/arm/plat-mxc/iomux-mx1-mx2.c +--- linux-2.6.30-rc4/arch/arm/plat-mxc/iomux-mx1-mx2.c 2009-05-13 09:46:19.000000000 +0200 ++++ linux-2.6.30-rc4-karo/arch/arm/plat-mxc/iomux-mx1-mx2.c 2009-06-02 17:05:27.000000000 +0200 +@@ -74,11 +74,12 @@ void mxc_gpio_mode(int gpio_mode) + __raw_writel(tmp, VA_GPIO_BASE + MXC_GIUS(port)); + + if (pin < 16) { ++#ifndef CONFIG_MACH_MX25 + tmp = __raw_readl(VA_GPIO_BASE + MXC_OCR1(port)); + tmp &= ~(3 << (pin * 2)); + tmp |= (ocr << (pin * 2)); + __raw_writel(tmp, VA_GPIO_BASE + MXC_OCR1(port)); +- ++#endif + tmp = __raw_readl(VA_GPIO_BASE + MXC_ICONFA1(port)); + tmp &= ~(3 << (pin * 2)); + tmp |= ((gpio_mode >> GPIO_AOUT_SHIFT) & 3) << (pin * 2); +@@ -90,12 +91,12 @@ void mxc_gpio_mode(int gpio_mode) + __raw_writel(tmp, VA_GPIO_BASE + MXC_ICONFB1(port)); + } else { + pin -= 16; +- ++#ifndef CONFIG_MACH_MX25 + tmp = __raw_readl(VA_GPIO_BASE + MXC_OCR2(port)); + tmp &= ~(3 << (pin * 2)); + tmp |= (ocr << (pin * 2)); + __raw_writel(tmp, VA_GPIO_BASE + MXC_OCR2(port)); +- ++#endif + tmp = __raw_readl(VA_GPIO_BASE + MXC_ICONFA2(port)); + tmp &= ~(3 << (pin * 2)); + tmp |= ((gpio_mode >> GPIO_AOUT_SHIFT) & 3) << (pin * 2); +diff -urNp linux-2.6.30-rc4/arch/arm/plat-mxc/iomux-v3.c linux-2.6.30-rc4-karo/arch/arm/plat-mxc/iomux-v3.c +--- linux-2.6.30-rc4/arch/arm/plat-mxc/iomux-v3.c 2009-05-13 09:46:19.000000000 +0200 ++++ linux-2.6.30-rc4-karo/arch/arm/plat-mxc/iomux-v3.c 2009-06-02 17:05:27.000000000 +0200 +@@ -31,7 +31,24 @@ + + #define IOMUX_BASE IO_ADDRESS(IOMUXC_BASE_ADDR) + +-static unsigned long iomux_v3_pad_alloc_map[0x200 / BITS_PER_LONG]; ++#ifdef CONFIG_MACH_MX25 ++#define NUM_PADS 0x228 ++#else ++#define NUM_PADS 0x200 ++#endif ++ ++static unsigned long iomux_v3_pad_alloc_map[NUM_PADS / BITS_PER_LONG]; ++ ++static inline int mxc_iomux_v3_pad_offset(struct pad_desc *pad) ++{ ++ int pad_ofs; ++ if (cpu_is_mx25()) ++ pad_ofs = pad->mux_ctrl_ofs; ++ else ++ pad_ofs = pad->pad_ctrl_ofs; ++ BUG_ON((pad_ofs >> 7) >= ARRAY_SIZE(iomux_v3_pad_alloc_map)); ++ return pad_ofs; ++} + + /* + * setups a single pin: +@@ -40,7 +57,7 @@ static unsigned long iomux_v3_pad_alloc_ + */ + int mxc_iomux_v3_setup_pad(struct pad_desc *pad) + { +- unsigned int pad_ofs = pad->pad_ctrl_ofs; ++ unsigned int pad_ofs = mxc_iomux_v3_pad_offset(pad); + + if (test_and_set_bit(pad_ofs >> 2, iomux_v3_pad_alloc_map)) + return -EBUSY; +@@ -65,8 +82,10 @@ int mxc_iomux_v3_setup_multiple_pads(str + + for (i = 0; i < count; i++) { + ret = mxc_iomux_v3_setup_pad(p); +- if (ret) ++ if (ret) { ++ printk(KERN_ERR "Failed to setup PAD[%d]: %d\n", i, ret); + goto setup_error; ++ } + p++; + } + return 0; +@@ -79,7 +98,7 @@ EXPORT_SYMBOL(mxc_iomux_v3_setup_multipl + + void mxc_iomux_v3_release_pad(struct pad_desc *pad) + { +- unsigned int pad_ofs = pad->pad_ctrl_ofs; ++ unsigned int pad_ofs = mxc_iomux_v3_pad_offset(pad); + + clear_bit(pad_ofs >> 2, iomux_v3_pad_alloc_map); + } +diff -urNp linux-2.6.30-rc4/arch/arm/plat-mxc/pwm.c linux-2.6.30-rc4-karo/arch/arm/plat-mxc/pwm.c +--- linux-2.6.30-rc4/arch/arm/plat-mxc/pwm.c 2009-05-13 09:46:19.000000000 +0200 ++++ linux-2.6.30-rc4-karo/arch/arm/plat-mxc/pwm.c 2009-06-02 17:05:27.000000000 +0200 +@@ -55,7 +55,7 @@ int pwm_config(struct pwm_device *pwm, i + if (pwm == NULL || period_ns == 0 || duty_ns > period_ns) + return -EINVAL; + +- if (cpu_is_mx27() || cpu_is_mx3()) { ++ if (cpu_is_mx27() || cpu_is_mx3() || cpu_is_mx25()) { + unsigned long long c; + unsigned long period_cycles, duty_cycles, prescale; + c = clk_get_rate(pwm->clk); +diff -urNp linux-2.6.30-rc4/arch/arm/plat-mxc/spba.c linux-2.6.30-rc4-karo/arch/arm/plat-mxc/spba.c +--- linux-2.6.30-rc4/arch/arm/plat-mxc/spba.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30-rc4-karo/arch/arm/plat-mxc/spba.c 2009-06-02 17:05:27.000000000 +0200 +@@ -0,0 +1,143 @@ ++/* ++ * Copyright 2004-2008 Freescale Semiconductor, Inc. All Rights Reserved. ++ */ ++ ++/* ++ * The code contained herein is licensed under the GNU General Public ++ * License. You may obtain a copy of the GNU General Public License ++ * Version 2 or later at the following locations: ++ * ++ * http://www.opensource.org/licenses/gpl-license.html ++ * http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++#include <linux/types.h> ++#include <linux/module.h> ++#include <linux/clk.h> ++#include <linux/err.h> ++#include <asm/io.h> ++#include <mach/hardware.h> ++#include <mach/spba.h> ++ ++/*! ++ * @file plat-mxc/spba.c ++ * ++ * @brief This file contains the SPBA API implementation details. ++ * ++ * @ingroup SPBA ++ */ ++ ++static DEFINE_SPINLOCK(spba_lock); ++ ++#define SPBA_MASTER_MIN 1 ++#define SPBA_MASTER_MAX 7 ++ ++/*! ++ * the base addresses for the SPBA modules ++ */ ++static unsigned long spba_base = (unsigned long)IO_ADDRESS(SPBA_CTRL_BASE_ADDR); ++ ++/*! ++ * SPBA clock ++ */ ++static struct clk *spba_clk; ++/*! ++ * This function allows the three masters (A, B, C) to take ownership of a ++ * shared peripheral. ++ * ++ * @param mod specified module as defined in \b enum \b #spba_module ++ * @param master one of more (or-ed together) masters as defined in \b enum \b #spba_masters ++ * ++ * @return 0 if successful; a negative errno value otherwise. ++ */ ++int spba_take_ownership(int mod, int master) ++{ ++ unsigned long spba_flags; ++ int rtn_val = -EIO; ++ ++ if (master < SPBA_MASTER_MIN || master > SPBA_MASTER_MAX) { ++ printk("%s() invalid master %d\n", __FUNCTION__, master); ++ return -EINVAL; ++ } ++ ++ if (spba_clk == NULL) { ++ spba_clk = clk_get(NULL, "spba"); ++ if (IS_ERR(spba_clk)) { ++ int ret = PTR_ERR(spba_clk); ++ ++ spba_clk = NULL; ++ return ret; ++ } ++ } ++ clk_enable(spba_clk); ++ ++ spin_lock_irqsave(&spba_lock, spba_flags); ++ __raw_writel(master, spba_base + mod); ++ ++ if ((__raw_readl(spba_base + mod) & MXC_SPBA_RAR_MASK) == master) { ++ rtn_val = 0; ++ } ++ ++ spin_unlock_irqrestore(&spba_lock, spba_flags); ++ ++ clk_disable(spba_clk); ++ return rtn_val; ++} ++ ++/*! ++ * This function releases the ownership for a shared peripheral. ++ * ++ * @param mod specified module as defined in \b enum \b #spba_module ++ * @param master one of more (or-ed together) masters as defined in \b enum \b #spba_masters ++ * ++ * @return 0 if successful; a negativ errno value otherwise. ++ */ ++int spba_rel_ownership(int mod, int master) ++{ ++ unsigned long spba_flags; ++ volatile unsigned long rar; ++ ++ if (master < SPBA_MASTER_MIN || master > SPBA_MASTER_MAX) { ++ printk("%s() invalid master %d\n", __FUNCTION__, master); ++ return -EINVAL; ++ } ++ ++ if (spba_clk == NULL) { ++ spba_clk = clk_get(NULL, "spba"); ++ if (IS_ERR(spba_clk)) { ++ int ret = PTR_ERR(spba_clk); ++ spba_clk = NULL; ++ return ret; ++ } ++ } ++ clk_enable(spba_clk); ++ ++ if ((__raw_readl(spba_base + mod) & master) == 0) { ++ clk_disable(spba_clk); ++ return -EBUSY; /* does not own it */ ++ } ++ ++ spin_lock_irqsave(&spba_lock, spba_flags); ++ ++ /* Since only the last 3 bits are writeable, doesn't need to mask off ++ bits 31-3 */ ++ rar = __raw_readl(spba_base + mod) & (~master); ++ __raw_writel(rar, spba_base + mod); ++ ++ if ((__raw_readl(spba_base + mod) & master) != 0) { ++ spin_unlock_irqrestore(&spba_lock, spba_flags); ++ clk_disable(spba_clk); ++ return -EIO; ++ } ++ spin_unlock_irqrestore(&spba_lock, spba_flags); ++ ++ clk_disable(spba_clk); ++ return 0; ++} ++ ++EXPORT_SYMBOL(spba_take_ownership); ++EXPORT_SYMBOL(spba_rel_ownership); ++ ++MODULE_AUTHOR("Freescale Semiconductor, Inc."); ++MODULE_DESCRIPTION("SPBA"); ++MODULE_LICENSE("GPL"); +diff -urNp linux-2.6.30-rc4/arch/arm/plat-mxc/time.c linux-2.6.30-rc4-karo/arch/arm/plat-mxc/time.c +--- linux-2.6.30-rc4/arch/arm/plat-mxc/time.c 2009-05-13 09:46:19.000000000 +0200 ++++ linux-2.6.30-rc4-karo/arch/arm/plat-mxc/time.c 2009-06-02 17:05:27.000000000 +0200 +@@ -66,7 +66,7 @@ static inline void gpt_irq_disable(void) + { + unsigned int tmp; + +- if (cpu_is_mx3()) ++ if (cpu_is_mx3() || cpu_is_mx25()) + __raw_writel(0, timer_base + MX3_IR); + else { + tmp = __raw_readl(timer_base + MXC_TCTL); +@@ -76,7 +76,7 @@ static inline void gpt_irq_disable(void) + + static inline void gpt_irq_enable(void) + { +- if (cpu_is_mx3()) ++ if (cpu_is_mx3() || cpu_is_mx25()) + __raw_writel(1<<0, timer_base + MX3_IR); + else { + __raw_writel(__raw_readl(timer_base + MXC_TCTL) | MX1_2_TCTL_IRQEN, +@@ -88,9 +88,9 @@ static void gpt_irq_acknowledge(void) + { + if (cpu_is_mx1()) + __raw_writel(0, timer_base + MX1_2_TSTAT); +- if (cpu_is_mx2()) ++ if (cpu_is_mx2() && !cpu_is_mx25()) + __raw_writel(MX2_TSTAT_CAPT | MX2_TSTAT_COMP, timer_base + MX1_2_TSTAT); +- if (cpu_is_mx3()) ++ if (cpu_is_mx3() || cpu_is_mx25()) + __raw_writel(MX3_TSTAT_OF1, timer_base + MX3_TSTAT); + } + +@@ -117,7 +117,7 @@ static int __init mxc_clocksource_init(s + { + unsigned int c = clk_get_rate(timer_clk); + +- if (cpu_is_mx3()) ++ if (cpu_is_mx3() || cpu_is_mx25()) + clocksource_mxc.read = mx3_get_cycles; + + clocksource_mxc.mult = clocksource_hz2mult(c, +@@ -180,7 +180,7 @@ static void mxc_set_mode(enum clock_even + + if (mode != clockevent_mode) { + /* Set event time into far-far future */ +- if (cpu_is_mx3()) ++ if (cpu_is_mx3() || cpu_is_mx25()) + __raw_writel(__raw_readl(timer_base + MX3_TCN) - 3, + timer_base + MX3_TCMP); + else +@@ -233,7 +233,7 @@ static irqreturn_t mxc_timer_interrupt(i + struct clock_event_device *evt = &clockevent_mxc; + uint32_t tstat; + +- if (cpu_is_mx3()) ++ if (cpu_is_mx3() || cpu_is_mx25()) + tstat = __raw_readl(timer_base + MX3_TSTAT); + else + tstat = __raw_readl(timer_base + MX1_2_TSTAT); +@@ -264,7 +264,7 @@ static int __init mxc_clockevent_init(st + { + unsigned int c = clk_get_rate(timer_clk); + +- if (cpu_is_mx3()) ++ if (cpu_is_mx3() || cpu_is_mx25()) + clockevent_mxc.set_next_event = mx3_set_next_event; + + clockevent_mxc.mult = div_sc(c, NSEC_PER_SEC, +@@ -287,6 +287,7 @@ void __init mxc_timer_init(struct clk *t + int irq; + + clk_enable(timer_clk); ++printk(KERN_DEBUG "%s: \n", __FUNCTION__); + + if (cpu_is_mx1()) { + #ifdef CONFIG_ARCH_MX1 +@@ -306,6 +307,7 @@ void __init mxc_timer_init(struct clk *t + } else + BUG(); + ++printk(KERN_DEBUG "%s: timer_base=%p IRQ=%d\n", __FUNCTION__, timer_base, irq); + /* + * Initialise to a known state (all timers off, and timing reset) + */ +@@ -313,7 +315,7 @@ void __init mxc_timer_init(struct clk *t + __raw_writel(0, timer_base + MXC_TCTL); + __raw_writel(0, timer_base + MXC_TPRER); /* see datasheet note */ + +- if (cpu_is_mx3()) ++ if (cpu_is_mx3() || cpu_is_mx25()) + tctl_val = MX3_TCTL_CLK_IPG | MX3_TCTL_FRR | MX3_TCTL_WAITEN | MXC_TCTL_TEN; + else + tctl_val = MX1_2_TCTL_FRR | MX1_2_TCTL_CLK_PCLK1 | MXC_TCTL_TEN; +diff -urNp linux-2.6.30-rc4/arch/arm/tools/mach-types linux-2.6.30-rc4-karo/arch/arm/tools/mach-types +--- linux-2.6.30-rc4/arch/arm/tools/mach-types 2009-05-13 09:46:19.000000000 +0200 ++++ linux-2.6.30-rc4-karo/arch/arm/tools/mach-types 2009-06-02 17:05:27.000000000 +0200 +@@ -12,7 +12,7 @@ + # + # http://www.arm.linux.org.uk/developer/machines/?action=new + # +-# Last update: Mon Mar 23 20:09:01 2009 ++# Last update: Mon Apr 20 10:31:38 2009 + # + # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number + # +@@ -1721,7 +1721,7 @@ sapphire MACH_SAPPHIRE SAPPHIRE 1729 + csb637xo MACH_CSB637XO CSB637XO 1730 + evisiong MACH_EVISIONG EVISIONG 1731 + stmp37xx MACH_STMP37XX STMP37XX 1732 +-stmp378x MACH_STMP38XX STMP38XX 1733 ++stmp378x MACH_STMP378X STMP378X 1733 + tnt MACH_TNT TNT 1734 + tbxt MACH_TBXT TBXT 1735 + playmate MACH_PLAYMATE PLAYMATE 1736 +@@ -2132,3 +2132,41 @@ apollo MACH_APOLLO APOLLO 2141 + at91cap9stk MACH_AT91CAP9STK AT91CAP9STK 2142 + spc300 MACH_SPC300 SPC300 2143 + eko MACH_EKO EKO 2144 ++ccw9m2443 MACH_CCW9M2443 CCW9M2443 2145 ++ccw9m2443js MACH_CCW9M2443JS CCW9M2443JS 2146 ++m2m_router_device MACH_M2M_ROUTER_DEVICE M2M_ROUTER_DEVICE 2147 ++str9104nas MACH_STAR9104NAS STAR9104NAS 2148 ++pca100 MACH_PCA100 PCA100 2149 ++z3_dm365_mod_01 MACH_Z3_DM365_MOD_01 Z3_DM365_MOD_01 2150 ++hipox MACH_HIPOX HIPOX 2151 ++omap3_piteds MACH_OMAP3_PITEDS OMAP3_PITEDS 2152 ++bm150r MACH_BM150R BM150R 2153 ++tbone MACH_TBONE TBONE 2154 ++merlin MACH_MERLIN MERLIN 2155 ++falcon MACH_FALCON FALCON 2156 ++davinci_da850_evm MACH_DAVINCI_DA850_EVM DAVINCI_DA850_EVM 2157 ++s5p6440 MACH_S5P6440 S5P6440 2158 ++at91sam9g10ek MACH_AT91SAM9G10EK AT91SAM9G10EK 2159 ++omap_4430sdp MACH_OMAP_4430SDP OMAP_4430SDP 2160 ++lpc313x MACH_LPC313X LPC313X 2161 ++magx_zn5 MACH_MAGX_ZN5 MAGX_ZN5 2162 ++magx_em30 MACH_MAGX_EM30 MAGX_EM30 2163 ++magx_ve66 MACH_MAGX_VE66 MAGX_VE66 2164 ++meesc MACH_MEESC MEESC 2165 ++otc570 MACH_OTC570 OTC570 2166 ++bcu2412 MACH_BCU2412 BCU2412 2167 ++beacon MACH_BEACON BEACON 2168 ++actia_tgw MACH_ACTIA_TGW ACTIA_TGW 2169 ++e4430 MACH_E4430 E4430 2170 ++ql300 MACH_QL300 QL300 2171 ++btmavb101 MACH_BTMAVB101 BTMAVB101 2172 ++btmawb101 MACH_BTMAWB101 BTMAWB101 2173 ++sq201 MACH_SQ201 SQ201 2174 ++quatro45xx MACH_QUATRO45XX QUATRO45XX 2175 ++openpad MACH_OPENPAD OPENPAD 2176 ++tx25 MACH_TX25 TX25 2177 ++omap3_torpedo MACH_OMAP3_TORPEDO OMAP3_TORPEDO 2178 ++htcraphael_k MACH_HTCRAPHAEL_K HTCRAPHAEL_K 2179 ++pxa255 MACH_PXA255 PXA255 2180 ++lal43 MACH_LAL43 LAL43 2181 ++htcraphael_cdma500 MACH_HTCRAPHAEL_CDMA500 HTCRAPHAEL_CDMA500 2182 +diff -urNp linux-2.6.30-rc4/drivers/leds/leds-gpio.c linux-2.6.30-rc4-karo/drivers/leds/leds-gpio.c +--- linux-2.6.30-rc4/drivers/leds/leds-gpio.c 2009-05-13 09:46:19.000000000 +0200 ++++ linux-2.6.30-rc4-karo/drivers/leds/leds-gpio.c 2009-06-02 17:05:27.000000000 +0200 +@@ -82,7 +82,7 @@ static int __devinit create_gpio_led(con + if (!gpio_is_valid(template->gpio)) { + printk(KERN_INFO "Skipping unavilable LED gpio %d (%s)\n", + template->gpio, template->name); +- return 0; ++ return -EINVAL; + } + + ret = gpio_request(template->gpio, template->name); +diff -urNp linux-2.6.30-rc4/drivers/mtd/nand/Kconfig linux-2.6.30-rc4-karo/drivers/mtd/nand/Kconfig +--- linux-2.6.30-rc4/drivers/mtd/nand/Kconfig 2009-05-13 09:46:19.000000000 +0200 ++++ linux-2.6.30-rc4-karo/drivers/mtd/nand/Kconfig 2009-06-02 17:05:27.000000000 +0200 +@@ -420,6 +420,27 @@ config MTD_NAND_MXC + This enables the driver for the NAND flash controller on the + MXC processors. + ++config MTD_NAND_MXC_FLASH_BBT ++ bool "Support a flash based bad block table" ++ depends on MTD_NAND_MXC ++ ++config ARCH_MXC_HAS_NFC_V1 ++ bool ++ ++config ARCH_MXC_HAS_NFC_V1_1 ++ select ARCH_MXC_HAS_NFC_V1 ++ bool ++ ++config ARCH_MXC_HAS_NFC_V2 ++ bool ++ ++config ARCH_MXC_HAS_NFC_V2_1 ++ bool ++ select ARCH_MXC_HAS_NFC_V2 ++ ++config ARCH_MXC_HAS_NFC_V3 ++ bool ++ + config MTD_NAND_SH_FLCTL + tristate "Support for NAND on Renesas SuperH FLCTL" + depends on MTD_NAND && SUPERH && CPU_SUBTYPE_SH7723 +diff -urNp linux-2.6.30-rc4/drivers/mtd/nand/Makefile linux-2.6.30-rc4-karo/drivers/mtd/nand/Makefile +--- linux-2.6.30-rc4/drivers/mtd/nand/Makefile 2009-05-13 09:46:19.000000000 +0200 ++++ linux-2.6.30-rc4-karo/drivers/mtd/nand/Makefile 2009-06-02 17:05:27.000000000 +0200 +@@ -36,7 +36,13 @@ obj-$(CONFIG_MTD_NAND_ORION) += orion_n + obj-$(CONFIG_MTD_NAND_FSL_ELBC) += fsl_elbc_nand.o + obj-$(CONFIG_MTD_NAND_FSL_UPM) += fsl_upm.o + obj-$(CONFIG_MTD_NAND_SH_FLCTL) += sh_flctl.o ++ifneq ($(CONFIG_ARCH_MXC_HAS_NFC_V1),) + obj-$(CONFIG_MTD_NAND_MXC) += mxc_nand.o ++else ++ifneq ($(CONFIG_ARCH_MXC_HAS_NFC_V2),) ++obj-$(CONFIG_MTD_NAND_MXC) += mxc_nd2.o ++endif ++endif + obj-$(CONFIG_MTD_NAND_SOCRATES) += socrates_nand.o + obj-$(CONFIG_MTD_NAND_TXX9NDFMC) += txx9ndfmc.o + +diff -urNp linux-2.6.30-rc4/drivers/mtd/nand/mxc_nand.c linux-2.6.30-rc4-karo/drivers/mtd/nand/mxc_nand.c +--- linux-2.6.30-rc4/drivers/mtd/nand/mxc_nand.c 2009-05-13 09:46:19.000000000 +0200 ++++ linux-2.6.30-rc4-karo/drivers/mtd/nand/mxc_nand.c 2009-06-02 17:05:27.000000000 +0200 +@@ -34,23 +34,52 @@ + #include <asm/mach/flash.h> + #include <mach/mxc_nand.h> + ++#ifdef CONFIG_MTD_DEBUG ++static int debug = 3; ++module_param(debug, int, S_IRUGO | S_IWUSR); ++ ++#define dbg_lvl(n) ((n) < debug) ++#define DBG(lvl, fmt...) do { if (dbg_lvl(lvl)) printk(KERN_DEBUG fmt); } while (0) ++#undef DEBUG ++#define DEBUG(l, fmt...) DBG(l, fmt) ++#else ++static int debug; ++module_param(debug, int, 0); ++ ++#define dbg_lvl(n) 0 ++#define DBG(lvl, fmt...) do { } while (0) ++#endif ++ ++ + #define DRIVER_NAME "mxc_nand" + + /* Addresses for NFC registers */ +-#define NFC_BUF_SIZE 0xE00 +-#define NFC_BUF_ADDR 0xE04 +-#define NFC_FLASH_ADDR 0xE06 +-#define NFC_FLASH_CMD 0xE08 +-#define NFC_CONFIG 0xE0A +-#define NFC_ECC_STATUS_RESULT 0xE0C +-#define NFC_RSLTMAIN_AREA 0xE0E +-#define NFC_RSLTSPARE_AREA 0xE10 +-#define NFC_WRPROT 0xE12 +-#define NFC_UNLOCKSTART_BLKADDR 0xE14 +-#define NFC_UNLOCKEND_BLKADDR 0xE16 +-#define NFC_NF_WRPRST 0xE18 +-#define NFC_CONFIG1 0xE1A +-#define NFC_CONFIG2 0xE1C ++#define NFC_BUF_SIZE 0x000 ++#define NFC_BUF_ADDR 0x004 ++#define NFC_FLASH_ADDR 0x006 ++#define NFC_FLASH_CMD 0x008 ++#define NFC_CONFIG 0x00A ++#define NFC_ECC_STATUS_RESULT 0x00C ++#define NFC_RSLTMAIN_AREA 0x00E ++#define NFC_RSLTSPARE_AREA 0x010 ++#define NFC_WRPROT 0x012 ++#ifndef CONFIG_ARCH_MXC_HAS_NFC_V1_1 ++#define NFC_UNLOCKSTART_BLKADDR 0x014 ++#define NFC_UNLOCKEND_BLKADDR 0x016 ++#endif ++#define NFC_NF_WRPRST 0x018 ++#define NFC_CONFIG1 0x01A ++#define NFC_CONFIG2 0x01C ++#ifdef CONFIG_ARCH_MXC_HAS_NFC_V1_1 ++#define NFC_UNLOCKSTART_BLKADDR 0x020 ++#define NFC_UNLOCKEND_BLKADDR 0x022 ++#define NFC_UNLOCKSTART_BLKADDR1 0x024 ++#define NFC_UNLOCKEND_BLKADDR1 0x026 ++#define NFC_UNLOCKSTART_BLKADDR2 0x028 ++#define NFC_UNLOCKEND_BLKADDR2 0x02a ++#define NFC_UNLOCKSTART_BLKADDR3 0x02c ++#define NFC_UNLOCKEND_BLKADDR3 0x02e ++#endif + + /* Addresses for NFC RAM BUFFER Main area 0 */ + #define MAIN_AREA0 0x000 +@@ -59,10 +88,27 @@ + #define MAIN_AREA3 0x600 + + /* Addresses for NFC SPARE BUFFER Spare area 0 */ ++#ifndef CONFIG_ARCH_MXC_HAS_NFC_V1_1 ++#define SPARE_AREA_SIZE 16 + #define SPARE_AREA0 0x800 + #define SPARE_AREA1 0x810 + #define SPARE_AREA2 0x820 + #define SPARE_AREA3 0x830 ++#else ++#define SPARE_AREA_SIZE 64 ++#define MAIN_AREA4 0x800 ++#define MAIN_AREA5 0xa00 ++#define MAIN_AREA6 0xc00 ++#define MAIN_AREA7 0xe00 ++#define SPARE_AREA0 0x1000 ++#define SPARE_AREA1 0x1040 ++#define SPARE_AREA2 0x1080 ++#define SPARE_AREA3 0x10c0 ++#define SPARE_AREA4 0x1100 ++#define SPARE_AREA5 0x1140 ++#define SPARE_AREA6 0x1180 ++#define SPARE_AREA7 0x11c0 ++#endif + + /* Set INT to 0, FCMD to 1, rest to 0 in NFC_CONFIG2 Register + * for Command operation */ +@@ -107,6 +153,7 @@ struct mxc_nand_host { + struct device *dev; + + void __iomem *regs; ++ void __iomem *nfc_buf; + int spare_only; + int status_request; + int pagesize_2k; +@@ -128,32 +175,149 @@ struct mxc_nand_host { + #define MAIN_SINGLEBIT_ERROR 0x4 + #define SPARE_SINGLEBIT_ERROR 0x1 + ++#ifndef CONFIG_ARCH_MXC_HAS_NFC_V1_1 + /* OOB placement block for use with hardware ecc generation */ ++static struct nand_ecclayout nand_hw_eccoob2k_8 = { ++ .eccbytes = 5, ++ .eccpos = {6, 7, 8, 9, 10}, ++ .oobfree = {{0, 5}, {11, 11}, {27, 11}, {43, 5}} ++}; ++ + static struct nand_ecclayout nand_hw_eccoob_8 = { + .eccbytes = 5, + .eccpos = {6, 7, 8, 9, 10}, +- .oobfree = {{0, 5}, {11, 5}, } ++ .oobfree = {{0, 5}, {11, 5}} ++}; ++ ++static struct nand_ecclayout nand_hw_eccoob2k_16 = { ++ .eccbytes = 5, ++ .eccpos = {6, 7, 8, 9, 10}, ++ .oobfree = {{0, 6}, {12, 10}, {28, 10}, {44, 4}} + }; + + static struct nand_ecclayout nand_hw_eccoob_16 = { + .eccbytes = 5, + .eccpos = {6, 7, 8, 9, 10}, +- .oobfree = {{0, 6}, {12, 4}, } ++ .oobfree = {{0, 6}, {12, 4}} ++}; ++ ++#ifdef CONFIG_MTD_NAND_MXC_FLASH_BBT ++static u8 bbt_pattern[] = {'B', 'b', 't', '0' }; ++static u8 mirror_pattern[] = {'1', 't', 'b', 'B' }; ++ ++static struct nand_bbt_descr bbt_main_descr = { ++ .options = (NAND_BBT_LASTBLOCK | NAND_BBT_WRITE | ++ NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP), ++ .offs = 12, ++ .len = 4, ++ .veroffs = 11, ++ .maxblocks = 4, ++ .pattern = bbt_pattern, ++}; ++ ++static struct nand_bbt_descr bbt_mirror_descr = { ++ .options = (NAND_BBT_LASTBLOCK | NAND_BBT_WRITE | ++ NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP), ++ .offs = 12, ++ .len = 4, ++ .veroffs = 11, ++ .maxblocks = 4, ++ .pattern = mirror_pattern, ++}; ++#endif ++#else ++/* ++ * OOB placement block for use with hardware ecc generation ++ */ ++static struct nand_ecclayout nand_hw_eccoob2k_8 = { ++ .eccbytes = 9, ++ .eccpos = {7, 8, 9, 10, 11, 12, 13, 14, 15}, ++ .oobfree = {{0, 7}, {16, 7}, {32, 7}, {48, 7}}, ++}; ++ ++static struct nand_ecclayout nand_hw_eccoob_8 = { ++ .eccbytes = 9, ++ .eccpos = {7, 8, 9, 10, 11, 12, 13, 14, 15}, ++ .oobfree = {{0, 4}}, ++}; ++ ++static struct nand_ecclayout nand_hw_eccoob2k_16 = { ++ .eccbytes = 9, ++ .eccpos = {6, 7, 8, 9, 10, 11, 12, 13, 14}, ++ .oobfree = {{0, 6}, {17, 6}, {33, 6}, {47, 6}}, + }; + ++static struct nand_ecclayout nand_hw_eccoob_16 = { ++ .eccbytes = 9, ++ .eccpos = {6, 7, 8, 9, 10, 11, 12, 13, 14}, ++ .oobfree = {{0, 3}} ++}; ++ ++#ifdef CONFIG_MTD_NAND_MXC_FLASH_BBT ++/* Generic flash bbt decriptors ++*/ ++static u8 bbt_pattern[] = { 'B', 'b', 't', '0' }; ++static u8 mirror_pattern[] = { '1', 't', 'b', 'B' }; ++ ++static struct nand_bbt_descr bbt_main_descr = { ++ .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE | ++ NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP, ++ .offs = 0, ++ .len = 4, ++ .veroffs = 4, ++ .maxblocks = 4, ++ .pattern = bbt_pattern ++}; ++ ++static struct nand_bbt_descr bbt_mirror_descr = { ++ .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE | ++ NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP, ++ .offs = 0, ++ .len = 4, ++ .veroffs = 4, ++ .maxblocks = 4, ++ .pattern = mirror_pattern ++}; ++#endif ++#endif ++ + #ifdef CONFIG_MTD_PARTITIONS + static const char *part_probes[] = { "RedBoot", "cmdlinepart", NULL }; + #endif + ++#ifdef CONFIG_MTD_DEBUG ++#define nfc_read_reg(b, r) __nfc_read_reg(b, r, #r, __FUNCTION__) ++static inline u16 __nfc_read_reg(void __iomem *base, unsigned int reg, ++ const char *name, const char *fn) ++{ ++ u16 val = readw(base + reg); ++ DBG(3, "%s: Read %04x from %s[%02x]\n", fn, val, name, reg); ++ return val; ++} ++ ++#define nfc_write_reg(v, b, r) __nfc_write_reg(v, b, r, #r, __FUNCTION__) ++static inline void __nfc_write_reg(u16 val, void __iomem *base, unsigned int reg, ++ const char *name, const char *fn) ++{ ++ DBG(3, "%s: Writing %04x to %s[%02x]\n", fn, val, name, reg); ++ writew(val, base + reg); ++} ++#else ++#define nfc_read_reg(b, r) readw(b + r) ++#define nfc_write_reg(v, b, r) writew(v, b + r) ++#endif ++ + static irqreturn_t mxc_nfc_irq(int irq, void *dev_id) + { + struct mxc_nand_host *host = dev_id; + + uint16_t tmp; + +- tmp = readw(host->regs + NFC_CONFIG1); ++ DEBUG(MTD_DEBUG_LEVEL0, "%s(%d)\n", __FUNCTION__, irq); ++ ++ tmp = nfc_read_reg(host->regs, NFC_CONFIG1); + tmp |= NFC_INT_MSK; /* Disable interrupt */ +- writew(tmp, host->regs + NFC_CONFIG1); ++ nfc_write_reg(tmp, host->regs, NFC_CONFIG1); + + wake_up(&host->irq_waitq); + +@@ -166,36 +330,31 @@ static irqreturn_t mxc_nfc_irq(int irq, + static void wait_op_done(struct mxc_nand_host *host, int max_retries, + uint16_t param, int useirq) + { +- uint32_t tmp; ++ uint32_t nfc_stat; + ++ nfc_stat = nfc_read_reg(host->regs, NFC_CONFIG2); + if (useirq) { +- if ((readw(host->regs + NFC_CONFIG2) & NFC_INT) == 0) { +- +- tmp = readw(host->regs + NFC_CONFIG1); +- tmp &= ~NFC_INT_MSK; /* Enable interrupt */ +- writew(tmp, host->regs + NFC_CONFIG1); +- +- wait_event(host->irq_waitq, +- readw(host->regs + NFC_CONFIG2) & NFC_INT); +- +- tmp = readw(host->regs + NFC_CONFIG2); +- tmp &= ~NFC_INT; +- writew(tmp, host->regs + NFC_CONFIG2); ++ if (!(nfc_stat & NFC_INT)) { ++ uint32_t cfg1; ++ const unsigned long timeout = 10; ++ ++ cfg1 = nfc_read_reg(host->regs, NFC_CONFIG1); ++ cfg1 &= ~NFC_INT_MSK; /* Enable interrupt */ ++ nfc_write_reg(cfg1, host->regs, NFC_CONFIG1); ++ ++ max_retries = wait_event_timeout(host->irq_waitq, ++ (nfc_stat = nfc_read_reg(host->regs, ++ NFC_CONFIG2)) & NFC_INT, ++ timeout); + } + } else { +- while (max_retries-- > 0) { +- if (readw(host->regs + NFC_CONFIG2) & NFC_INT) { +- tmp = readw(host->regs + NFC_CONFIG2); +- tmp &= ~NFC_INT; +- writew(tmp, host->regs + NFC_CONFIG2); +- break; +- } ++ while (!(nfc_stat & NFC_INT) && max_retries-- > 0) { ++ nfc_stat = nfc_read_reg(host->regs, NFC_CONFIG2); + udelay(1); + } +- if (max_retries <= 0) +- DEBUG(MTD_DEBUG_LEVEL0, "%s(%d): INT not set\n", +- __func__, param); + } ++ nfc_write_reg(nfc_stat & ~NFC_INT, host->regs, NFC_CONFIG2); ++ WARN_ONCE(max_retries <= 0, "%s(%d): INT not set\n", __func__, param); + } + + /* This function issues the specified command to the NAND device and +@@ -204,8 +363,8 @@ static void send_cmd(struct mxc_nand_hos + { + DEBUG(MTD_DEBUG_LEVEL3, "send_cmd(host, 0x%x, %d)\n", cmd, useirq); + +- writew(cmd, host->regs + NFC_FLASH_CMD); +- writew(NFC_CMD, host->regs + NFC_CONFIG2); ++ nfc_write_reg(cmd, host->regs, NFC_FLASH_CMD); ++ nfc_write_reg(NFC_CMD, host->regs, NFC_CONFIG2); + + /* Wait for operation to complete */ + wait_op_done(host, TROP_US_DELAY, cmd, useirq); +@@ -218,8 +377,8 @@ static void send_addr(struct mxc_nand_ho + { + DEBUG(MTD_DEBUG_LEVEL3, "send_addr(host, 0x%x %d)\n", addr, islast); + +- writew(addr, host->regs + NFC_FLASH_ADDR); +- writew(NFC_ADDR, host->regs + NFC_CONFIG2); ++ nfc_write_reg(addr, host->regs, NFC_FLASH_ADDR); ++ nfc_write_reg(NFC_ADDR, host->regs, NFC_CONFIG2); + + /* Wait for operation to complete */ + wait_op_done(host, TROP_US_DELAY, addr, islast); +@@ -233,19 +392,19 @@ static void send_prog_page(struct mxc_na + DEBUG(MTD_DEBUG_LEVEL3, "send_prog_page (%d)\n", spare_only); + + /* NANDFC buffer 0 is used for page read/write */ +- writew(buf_id, host->regs + NFC_BUF_ADDR); ++ nfc_write_reg(buf_id, host->regs, NFC_BUF_ADDR); + + /* Configure spare or page+spare access */ + if (!host->pagesize_2k) { +- uint16_t config1 = readw(host->regs + NFC_CONFIG1); ++ uint16_t config1 = nfc_read_reg(host->regs, NFC_CONFIG1); + if (spare_only) + config1 |= NFC_SP_EN; + else + config1 &= ~(NFC_SP_EN); +- writew(config1, host->regs + NFC_CONFIG1); ++ nfc_write_reg(config1, host->regs, NFC_CONFIG1); + } + +- writew(NFC_INPUT, host->regs + NFC_CONFIG2); ++ nfc_write_reg(NFC_INPUT, host->regs, NFC_CONFIG2); + + /* Wait for operation to complete */ + wait_op_done(host, TROP_US_DELAY, spare_only, true); +@@ -259,19 +418,19 @@ static void send_read_page(struct mxc_na + DEBUG(MTD_DEBUG_LEVEL3, "send_read_page (%d)\n", spare_only); + + /* NANDFC buffer 0 is used for page read/write */ +- writew(buf_id, host->regs + NFC_BUF_ADDR); ++ nfc_write_reg(buf_id, host->regs, NFC_BUF_ADDR); + + /* Configure spare or page+spare access */ + if (!host->pagesize_2k) { +- uint32_t config1 = readw(host->regs + NFC_CONFIG1); ++ uint32_t config1 = nfc_read_reg(host->regs, NFC_CONFIG1); + if (spare_only) + config1 |= NFC_SP_EN; + else + config1 &= ~NFC_SP_EN; +- writew(config1, host->regs + NFC_CONFIG1); ++ nfc_write_reg(config1, host->regs, NFC_CONFIG1); + } + +- writew(NFC_OUTPUT, host->regs + NFC_CONFIG2); ++ nfc_write_reg(NFC_OUTPUT, host->regs, NFC_CONFIG2); + + /* Wait for operation to complete */ + wait_op_done(host, TROP_US_DELAY, spare_only, true); +@@ -284,20 +443,20 @@ static void send_read_id(struct mxc_nand + uint16_t tmp; + + /* NANDFC buffer 0 is used for device ID output */ +- writew(0x0, host->regs + NFC_BUF_ADDR); ++ nfc_write_reg(0x0, host->regs, NFC_BUF_ADDR); + + /* Read ID into main buffer */ +- tmp = readw(host->regs + NFC_CONFIG1); ++ tmp = nfc_read_reg(host->regs, NFC_CONFIG1); + tmp &= ~NFC_SP_EN; +- writew(tmp, host->regs + NFC_CONFIG1); ++ nfc_write_reg(tmp, host->regs, NFC_CONFIG1); + +- writew(NFC_ID, host->regs + NFC_CONFIG2); ++ nfc_write_reg(NFC_ID, host->regs, NFC_CONFIG2); + + /* Wait for operation to complete */ + wait_op_done(host, TROP_US_DELAY, 0, true); + + if (this->options & NAND_BUSWIDTH_16) { +- void __iomem *main_buf = host->regs + MAIN_AREA0; ++ void __iomem *main_buf = host->nfc_buf + MAIN_AREA0; + /* compress the ID info */ + writeb(readb(main_buf + 2), main_buf + 1); + writeb(readb(main_buf + 4), main_buf + 2); +@@ -311,29 +470,29 @@ static void send_read_id(struct mxc_nand + * NAND device status and returns the current status. */ + static uint16_t get_dev_status(struct mxc_nand_host *host) + { +- void __iomem *main_buf = host->regs + MAIN_AREA1; ++ void __iomem *main_buf = host->nfc_buf + MAIN_AREA0; + uint32_t store; + uint16_t ret, tmp; + /* Issue status request to NAND device */ + +- /* store the main area1 first word, later do recovery */ ++ /* store the main area first word, later do recovery */ + store = readl(main_buf); +- /* NANDFC buffer 1 is used for device status to prevent ++ /* NANDFC buffer 0 is used for device status to prevent + * corruption of read/write buffer on status requests. */ +- writew(1, host->regs + NFC_BUF_ADDR); ++ nfc_write_reg(0, host->regs, NFC_BUF_ADDR); + + /* Read status into main buffer */ +- tmp = readw(host->regs + NFC_CONFIG1); ++ tmp = nfc_read_reg(host->regs, NFC_CONFIG1); + tmp &= ~NFC_SP_EN; +- writew(tmp, host->regs + NFC_CONFIG1); ++ nfc_write_reg(tmp, host->regs, NFC_CONFIG1); + +- writew(NFC_STATUS, host->regs + NFC_CONFIG2); ++ nfc_write_reg(NFC_STATUS, host->regs, NFC_CONFIG2); + + /* Wait for operation to complete */ + wait_op_done(host, TROP_US_DELAY, 0, true); + + /* Status is placed in first word of main buffer */ +- /* get status, then recovery area 1 data */ ++ /* get status, then recover area 0 data */ + ret = readw(main_buf); + writel(store, main_buf); + +@@ -369,7 +528,7 @@ static int mxc_nand_correct_data(struct + * additional correction. 2-Bit errors cannot be corrected by + * HW ECC, so we need to return failure + */ +- uint16_t ecc_status = readw(host->regs + NFC_ECC_STATUS_RESULT); ++ uint16_t ecc_status = nfc_read_reg(host->regs, NFC_ECC_STATUS_RESULT); + + if (((ecc_status & 0x3) == 2) || ((ecc_status >> 2) == 2)) { + DEBUG(MTD_DEBUG_LEVEL0, +@@ -392,8 +551,8 @@ static u_char mxc_nand_read_byte(struct + struct mxc_nand_host *host = nand_chip->priv; + uint8_t ret = 0; + uint16_t col, rd_word; +- uint16_t __iomem *main_buf = host->regs + MAIN_AREA0; +- uint16_t __iomem *spare_buf = host->regs + SPARE_AREA0; ++ uint16_t __iomem *main_buf = host->nfc_buf + MAIN_AREA0; ++ uint16_t __iomem *spare_buf = host->nfc_buf + SPARE_AREA0; + + /* Check for status request */ + if (host->status_request) +@@ -436,9 +595,9 @@ static uint16_t mxc_nand_read_word(struc + col += mtd->writesize; + + if (col < mtd->writesize) +- p = (host->regs + MAIN_AREA0) + (col >> 1); ++ p = (host->nfc_buf + MAIN_AREA0) + (col >> 1); + else +- p = (host->regs + SPARE_AREA0) + ((col - mtd->writesize) >> 1); ++ p = (host->nfc_buf + SPARE_AREA0) + ((col - mtd->writesize) >> 1); + + if (col & 1) { + rd_word = readw(p); +@@ -464,6 +623,7 @@ static void mxc_nand_write_buf(struct mt + struct nand_chip *nand_chip = mtd->priv; + struct mxc_nand_host *host = nand_chip->priv; + int n, col, i = 0; ++ int ss = mtd->oobsize / (mtd->writesize >> 9); + + DEBUG(MTD_DEBUG_LEVEL3, + "mxc_nand_write_buf(col = %d, len = %d)\n", host->col_addr, +@@ -474,21 +634,27 @@ static void mxc_nand_write_buf(struct mt + /* Adjust saved column address */ + if (col < mtd->writesize && host->spare_only) + col += mtd->writesize; +- ++#if 0 + n = mtd->writesize + mtd->oobsize - col; + n = min(len, n); ++#else ++ BUG_ON(len > mtd->writesize + mtd->oobsize - col); ++ n = len; ++#endif + + DEBUG(MTD_DEBUG_LEVEL3, + "%s:%d: col = %d, n = %d\n", __func__, __LINE__, col, n); + + while (n) { + void __iomem *p; ++ int si = (col - mtd->writesize) / 16; + + if (col < mtd->writesize) +- p = host->regs + MAIN_AREA0 + (col & ~3); ++ p = host->nfc_buf + MAIN_AREA0 + (col & ~3); + else +- p = host->regs + SPARE_AREA0 - +- mtd->writesize + (col & ~3); ++ p = host->nfc_buf + SPARE_AREA0 + ++ si * SPARE_AREA_SIZE + ++ (col - mtd->writesize) % ss; + + DEBUG(MTD_DEBUG_LEVEL3, "%s:%d: p = %p\n", __func__, + __LINE__, p); +@@ -542,6 +708,7 @@ static void mxc_nand_write_buf(struct mt + DEBUG(MTD_DEBUG_LEVEL3, + "%s:%d: n = %d, m = %d, i = %d, col = %d\n", + __func__, __LINE__, n, m, i, col); ++ BUG_ON(m == 0); + + memcpy(p, &buf[i], m); + col += m; +@@ -562,27 +729,50 @@ static void mxc_nand_read_buf(struct mtd + struct nand_chip *nand_chip = mtd->priv; + struct mxc_nand_host *host = nand_chip->priv; + int n, col, i = 0; ++ int ss = mtd->oobsize / (mtd->writesize >> 9); + + DEBUG(MTD_DEBUG_LEVEL3, + "mxc_nand_read_buf(col = %d, len = %d)\n", host->col_addr, len); + + col = host->col_addr; ++ if (dbg_lvl(2)) { ++ int si = col / 512; ++ print_hex_dump(KERN_DEBUG, "main: ", DUMP_PREFIX_ADDRESS, ++ 16, 2, host->nfc_buf + MAIN_AREA0, 64, 0); ++ print_hex_dump(KERN_DEBUG, "spare: ", DUMP_PREFIX_ADDRESS, ++ 16, 2, host->nfc_buf + SPARE_AREA0 + ++ si * SPARE_AREA_SIZE, 16, 0); ++ } + + /* Adjust saved column address */ + if (col < mtd->writesize && host->spare_only) + col += mtd->writesize; +- ++#if 0 + n = mtd->writesize + mtd->oobsize - col; + n = min(len, n); +- ++#else ++ /* If more data is requested to be read than is available in ++ * the flash buffer this is clearly a BUG! */ ++ BUG_ON(len > mtd->writesize + mtd->oobsize - col); ++ n = len; ++#endif + while (n) { + void __iomem *p; ++ int si = (col - mtd->writesize) / ss; + + if (col < mtd->writesize) +- p = host->regs + MAIN_AREA0 + (col & ~3); ++ p = host->nfc_buf + MAIN_AREA0 + (col & ~3); + else +- p = host->regs + SPARE_AREA0 - +- mtd->writesize + (col & ~3); ++ p = host->nfc_buf + SPARE_AREA0 + ++ si * SPARE_AREA_SIZE + ++ (col - mtd->writesize) % ss; ++ ++ DBG(1, "p=%p col=%03x ss=%d si=%d\n", p, col, ss, si); ++ ++ if (dbg_lvl(3)) { ++ print_hex_dump(KERN_DEBUG, "spare: ", DUMP_PREFIX_ADDRESS, ++ 16, 2, p, 64, 0); ++ } + + if (((col | (int)&buf[i]) & 3) || n < 16) { + uint32_t data; +@@ -618,18 +808,23 @@ static void mxc_nand_read_buf(struct mtd + int m = mtd->writesize - col; + + if (col >= mtd->writesize) +- m += mtd->oobsize; ++ m = ss; + + m = min(n, m) & ~3; ++ DBG(1, "Copying %u byte from offset %03x[%p]\n", ++ m + (col & 3), col, p); ++ BUG_ON(m == 0); + memcpy(&buf[i], p, m); + col += m; + i += m; + n -= m; + } + } ++ if (dbg_lvl(1)) { ++ print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, buf, len); ++ } + /* Update saved column address */ + host->col_addr = col; +- + } + + /* Used by the upper layer to verify the data in NAND Flash +@@ -655,13 +850,15 @@ static void mxc_nand_select_chip(struct + } + + if (chip == -1) { +- writew(readw(host->regs + NFC_CONFIG1) & ~NFC_CE, +- host->regs + NFC_CONFIG1); ++ nfc_write_reg(host->regs, ++ nfc_read_reg(host->regs, NFC_CONFIG1) & ~NFC_CE, ++ NFC_CONFIG1); + return; + } + +- writew(readw(host->regs + NFC_CONFIG1) | NFC_CE, +- host->regs + NFC_CONFIG1); ++ nfc_write_reg(host->regs, ++ nfc_read_reg(host->regs, NFC_CONFIG1) | NFC_CE, ++ NFC_CONFIG1); + #endif + + switch (chip) { +@@ -831,6 +1028,7 @@ static void mxc_nand_command(struct mtd_ + break; + + case NAND_CMD_READID: ++ host->col_addr = 0; + send_read_id(host); + break; + +@@ -851,9 +1049,12 @@ static int __init mxcnd_probe(struct pla + struct mtd_info *mtd; + struct mxc_nand_platform_data *pdata = pdev->dev.platform_data; + struct mxc_nand_host *host; +- struct resource *res; ++ struct resource *res1, *res2; + uint16_t tmp; +- int err = 0, nr_parts = 0; ++ int err, nr_parts; ++ ++ DBG(0, "%s: pdata=%p hw_ecc=%d width=%d\n", __FUNCTION__, ++ pdata, pdata->hw_ecc, pdata->width); + + /* Allocate memory for MTD device structure and private data */ + host = kzalloc(sizeof(struct mxc_nand_host), GFP_KERNEL); +@@ -868,9 +1069,6 @@ static int __init mxcnd_probe(struct pla + mtd->owner = THIS_MODULE; + mtd->dev.parent = &pdev->dev; + +- /* 50 us command delay time */ +- this->chip_delay = 5; +- + this->priv = host; + this->dev_ready = mxc_nand_dev_ready; + this->cmdfunc = mxc_nand_command; +@@ -880,29 +1078,61 @@ static int __init mxcnd_probe(struct pla + this->write_buf = mxc_nand_write_buf; + this->read_buf = mxc_nand_read_buf; + this->verify_buf = mxc_nand_verify_buf; ++#ifdef CONFIG_MTD_NAND_MXC_FLASH_BBT ++ this->bbt_td = &bbt_main_descr; ++ this->bbt_md = &bbt_mirror_descr; ++ this->options |= NAND_USE_FLASH_BBT; ++#endif + +- host->clk = clk_get(&pdev->dev, "nfc"); +- if (IS_ERR(host->clk)) ++ host->clk = clk_get(&pdev->dev, "nfc_clk"); ++ if (IS_ERR(host->clk)) { ++ err = PTR_ERR(host->clk); + goto eclk; ++ } ++ printk(KERN_DEBUG "NFC clk rate: %lu\n", clk_get_rate(host->clk)); ++ clk_set_rate(host->clk, 11000000); ++ printk(KERN_DEBUG "NFC clk rate: %lu\n", clk_get_rate(host->clk)); + + clk_enable(host->clk); + host->clk_act = 1; + +- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +- if (!res) { ++ res1 = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (!res1) { + err = -ENODEV; + goto eres; + } ++ if (!request_mem_region(res1->start, resource_size(res1), "mxc_nand")) { ++ err = -EBUSY; ++ goto ereq1; ++ } + +- host->regs = ioremap(res->start, res->end - res->start + 1); ++ res2 = platform_get_resource(pdev, IORESOURCE_MEM, 1); ++ if (res2) { ++ if (!request_mem_region(res2->start, resource_size(res2), "mxc_nand")) { ++ err = -EBUSY; ++ goto ereq2; ++ } ++ } ++ ++ host->regs = ioremap(res1->start, resource_size(res1)); + if (!host->regs) { +- err = -EIO; +- goto eres; ++ err = -ENOMEM; ++ goto eunmap1; + } + +- tmp = readw(host->regs + NFC_CONFIG1); ++ if (!res2) { ++ host->nfc_buf = host->regs; ++ host->regs += 0xe00; ++ } else { ++ host->nfc_buf = ioremap(res2->start, resource_size(res2)); ++ if (!host->regs) { ++ err = -ENOMEM; ++ goto eunmap2; ++ } ++ } ++ tmp = nfc_read_reg(host->regs, NFC_CONFIG1); + tmp |= NFC_INT_MSK; +- writew(tmp, host->regs + NFC_CONFIG1); ++ nfc_write_reg(tmp, host->regs, NFC_CONFIG1); + + init_waitqueue_head(&host->irq_waitq); + +@@ -911,7 +1141,7 @@ static int __init mxcnd_probe(struct pla + err = request_irq(host->irq, mxc_nfc_irq, 0, "mxc_nd", host); + if (err) + goto eirq; +- ++#if 0 + if (pdata->hw_ecc) { + this->ecc.calculate = mxc_nand_calculate_ecc; + this->ecc.hwctl = mxc_nand_enable_hwecc; +@@ -919,50 +1149,90 @@ static int __init mxcnd_probe(struct pla + this->ecc.mode = NAND_ECC_HW; + this->ecc.size = 512; + this->ecc.bytes = 3; ++ if ( + this->ecc.layout = &nand_hw_eccoob_8; +- tmp = readw(host->regs + NFC_CONFIG1); ++ tmp = nfc_read_reg(host->regs, NFC_CONFIG1); + tmp |= NFC_ECC_EN; +- writew(tmp, host->regs + NFC_CONFIG1); ++ nfc_write_reg(tmp, host->regs, NFC_CONFIG1); + } else { + this->ecc.size = 512; + this->ecc.bytes = 3; + this->ecc.layout = &nand_hw_eccoob_8; + this->ecc.mode = NAND_ECC_SOFT; +- tmp = readw(host->regs + NFC_CONFIG1); ++ tmp = nfc_read_reg(host->regs, NFC_CONFIG1); + tmp &= ~NFC_ECC_EN; +- writew(tmp, host->regs + NFC_CONFIG1); ++ nfc_write_reg(tmp, host->regs, NFC_CONFIG1); + } +- ++#endif + /* Reset NAND */ + this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1); + + /* preset operation */ + /* Unlock the internal RAM Buffer */ +- writew(0x2, host->regs + NFC_CONFIG); ++ nfc_write_reg(0x2, host->regs, NFC_CONFIG); + + /* Blocks to be unlocked */ +- writew(0x0, host->regs + NFC_UNLOCKSTART_BLKADDR); +- writew(0x4000, host->regs + NFC_UNLOCKEND_BLKADDR); ++ nfc_write_reg(0x0, host->regs, NFC_UNLOCKSTART_BLKADDR); ++ nfc_write_reg(0x4000, host->regs, NFC_UNLOCKEND_BLKADDR); + + /* Unlock Block Command for given address range */ +- writew(0x4, host->regs + NFC_WRPROT); ++ nfc_write_reg(0x4, host->regs, NFC_WRPROT); + + /* NAND bus width determines access funtions used by upper layer */ + if (pdata->width == 2) { + this->options |= NAND_BUSWIDTH_16; +- this->ecc.layout = &nand_hw_eccoob_16; + } + +- host->pagesize_2k = 0; +- + /* Scan to find existence of the device */ +- if (nand_scan(mtd, 1)) { ++ err = nand_scan_ident(mtd, 1); ++ if (err) { + DEBUG(MTD_DEBUG_LEVEL0, + "MXC_ND: Unable to find any NAND device.\n"); +- err = -ENXIO; ++ goto escan; ++ } ++ /* this is required before completing the scan */ ++ host->pagesize_2k = (mtd->writesize == 2048); ++ ++ if (pdata->width == 2) { ++ if (host->pagesize_2k) { ++ this->ecc.layout = &nand_hw_eccoob2k_16; ++ } else { ++ this->ecc.layout = &nand_hw_eccoob_16; ++ } ++ } else { ++ if (host->pagesize_2k) { ++ this->ecc.layout = &nand_hw_eccoob2k_8; ++ } else { ++ this->ecc.layout = &nand_hw_eccoob_8; ++ } ++ } ++ if (pdata->hw_ecc) { ++ this->ecc.calculate = mxc_nand_calculate_ecc; ++ this->ecc.hwctl = mxc_nand_enable_hwecc; ++ this->ecc.correct = mxc_nand_correct_data; ++ this->ecc.mode = NAND_ECC_HW; ++ this->ecc.size = 512; ++ this->ecc.bytes = 3; ++ tmp = nfc_read_reg(host->regs, NFC_CONFIG1); ++ tmp |= NFC_ECC_EN; ++ nfc_write_reg(tmp, host->regs, NFC_CONFIG1); ++ } else { ++ this->ecc.size = 512; ++ this->ecc.bytes = 3; ++ this->ecc.mode = NAND_ECC_SOFT; ++ tmp = nfc_read_reg(host->regs, NFC_CONFIG1); ++ tmp &= ~NFC_ECC_EN; ++ nfc_write_reg(tmp, host->regs, NFC_CONFIG1); ++ } ++ ++ err = nand_scan_tail(mtd); ++ if (err) { + goto escan; + } + ++ pr_info("MXC MTD nand Driver IRQ %d bus width: %u bit %s ECC IO: %08lx\n", ++ host->irq, pdata->width * 8, pdata->hw_ecc ? "HW" : "SW", ++ (unsigned long)res1->start); + /* Register the partitions */ + #ifdef CONFIG_MTD_PARTITIONS + nr_parts = +@@ -981,10 +1251,19 @@ static int __init mxcnd_probe(struct pla + return 0; + + escan: +- free_irq(host->irq, NULL); ++ free_irq(host->irq, host); + eirq: ++ if (host->regs != host->nfc_buf) ++ iounmap(host->nfc_buf); ++eunmap2: + iounmap(host->regs); ++eunmap1: ++ release_mem_region(res2->start, resource_size(res2)); ++ereq2: ++ release_mem_region(res1->start, resource_size(res1)); ++ereq1: + eres: ++ clk_disable(host->clk); + clk_put(host->clk); + eclk: + kfree(host); +@@ -995,46 +1274,63 @@ eclk: + static int __devexit mxcnd_remove(struct platform_device *pdev) + { + struct mxc_nand_host *host = platform_get_drvdata(pdev); ++ struct resource *res; + ++ if (host->clk_act) ++ clk_disable(host->clk); + clk_put(host->clk); + +- platform_set_drvdata(pdev, NULL); +- + nand_release(&host->mtd); +- free_irq(host->irq, NULL); ++ free_irq(host->irq, host); + iounmap(host->regs); + kfree(host); + ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (res) { ++ release_mem_region(res->start, resource_size(res)); ++ } ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 1); ++ if (res) { ++ release_mem_region(res->start, resource_size(res)); ++ } + return 0; + } + + #ifdef CONFIG_PM + static int mxcnd_suspend(struct platform_device *pdev, pm_message_t state) + { +- struct mtd_info *info = platform_get_drvdata(pdev); ++ struct mtd_info *mtd = platform_get_drvdata(pdev); ++ struct nand_chip *nand_chip = mtd->priv; ++ struct mxc_nand_host *host = nand_chip->priv; + int ret = 0; + + DEBUG(MTD_DEBUG_LEVEL0, "MXC_ND : NAND suspend\n"); +- if (info) +- ret = info->suspend(info); ++ if (mtd) ++ ret = mtd->suspend(mtd); + ++ if (host->clk_act) { + /* Disable the NFC clock */ +- clk_disable(nfc_clk); /* FIXME */ ++ clk_disable(host->clk); ++ } + + return ret; + } + + static int mxcnd_resume(struct platform_device *pdev) + { +- struct mtd_info *info = platform_get_drvdata(pdev); ++ struct mtd_info *mtd = platform_get_drvdata(pdev); ++ struct nand_chip *nand_chip = mtd->priv; ++ struct mxc_nand_host *host = nand_chip->priv; + int ret = 0; + + DEBUG(MTD_DEBUG_LEVEL0, "MXC_ND : NAND resume\n"); +- /* Enable the NFC clock */ +- clk_enable(nfc_clk); /* FIXME */ + +- if (info) +- info->resume(info); ++ if (host->clk_act) { ++ /* Enable the NFC clock */ ++ clk_enable(host->clk); ++ } ++ if (mtd) ++ mtd->resume(mtd); + + return ret; + } +@@ -1047,7 +1343,7 @@ static int mxcnd_resume(struct platform_ + static struct platform_driver mxcnd_driver = { + .driver = { + .name = DRIVER_NAME, +- }, ++ }, + .remove = __exit_p(mxcnd_remove), + .suspend = mxcnd_suspend, + .resume = mxcnd_resume, +@@ -1055,13 +1351,14 @@ static struct platform_driver mxcnd_driv + + static int __init mxc_nd_init(void) + { ++ int ret; ++ + /* Register the device driver structure. */ +- pr_info("MXC MTD nand Driver\n"); +- if (platform_driver_probe(&mxcnd_driver, mxcnd_probe) != 0) { ++ ret = platform_driver_probe(&mxcnd_driver, mxcnd_probe); ++ if (ret != 0) { + printk(KERN_ERR "Driver register failed for mxcnd_driver\n"); +- return -ENODEV; + } +- return 0; ++ return ret; + } + + static void __exit mxc_nd_cleanup(void) +diff -urNp linux-2.6.30-rc4/drivers/mtd/nand/mxc_nd2.c linux-2.6.30-rc4-karo/drivers/mtd/nand/mxc_nd2.c +--- linux-2.6.30-rc4/drivers/mtd/nand/mxc_nd2.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30-rc4-karo/drivers/mtd/nand/mxc_nd2.c 2009-06-02 17:05:27.000000000 +0200 +@@ -0,0 +1,1651 @@ ++/* ++ * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved. ++ */ ++ ++/* ++ * The code contained herein is licensed under the GNU General Public ++ * License. You may obtain a copy of the GNU General Public License ++ * Version 2 or later at the following locations: ++ * ++ * http://www.opensource.org/licenses/gpl-license.html ++ * http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++#include <linux/delay.h> ++#include <linux/slab.h> ++#include <linux/init.h> ++#include <linux/module.h> ++#include <linux/mtd/mtd.h> ++#include <linux/mtd/nand.h> ++#include <linux/interrupt.h> ++#include <linux/device.h> ++#include <linux/platform_device.h> ++#include <linux/clk.h> ++#include <linux/err.h> ++#include <linux/mtd/partitions.h> ++#include <asm/mach/flash.h> ++#include <asm/io.h> ++ ++#ifdef CONFIG_MTD_DEBUG ++static int debug = 0; ++module_param(debug, int, S_IRUGO | S_IWUSR); ++ ++#define dbg_lvl(n) ((n) < debug) ++#define DBG(lvl, fmt...) do { if (dbg_lvl(lvl)) printk(KERN_DEBUG fmt); } while (0) ++#undef DEBUG ++#define DEBUG DBG ++#else ++static int debug; ++module_param(debug, int, 0); ++ ++#define dbg_lvl(n) 0 ++#define DBG(lvl, fmt...) do { } while (0) ++#endif ++ ++#include "mxc_nd2.h" ++ ++#define DRV_NAME "mxc_nand" ++ ++ ++/* Global address Variables */ ++/* ++static void __iomem *nfc_axi_base; ++static void __iomem *nfc_ip_base; ++*/ ++ ++struct mxc_mtd_s { ++ struct mtd_info mtd; ++ struct nand_chip nand; ++ struct mtd_partition *parts; ++ struct device *dev; ++ wait_queue_head_t irq_waitq; ++ int irq; ++ ++ u8 *data_buf; ++ u8 *oob_buf; ++ struct clk *clk; ++ int clk_act; ++ ++ struct resource *res_ip; ++ struct resource *res_axi; ++ void __iomem *reg_base; ++ void __iomem *axi_base; ++ u16 __iomem *main_buf; ++ u16 __iomem *spare_buf; ++ ++ bool status_req; ++ u16 col_addr; ++}; ++ ++/* ++ * Define delays in microsec for NAND device operations ++ */ ++#define TROP_US_DELAY 2000 ++ ++#ifdef CONFIG_MTD_NAND_MXC_SWECC ++static int hardware_ecc = 0; ++#else ++static int hardware_ecc = 1; ++#endif ++ ++static u8 num_of_interleave = 1; ++ ++/* ++ * OOB placement block for use with hardware ecc generation ++ */ ++static struct nand_ecclayout nand_hw_eccoob_512 = { ++ .eccbytes = 9, ++ .eccpos = {7, 8, 9, 10, 11, 12, 13, 14, 15}, ++ .oobfree = {{0, 4}}, ++}; ++ ++static struct nand_ecclayout nand_hw_eccoob_2k = { ++ .eccbytes = 9, ++ .eccpos = {7, 8, 9, 10, 11, 12, 13, 14, 15}, ++ .oobfree = {{2, 5}, {16, 7}, {32, 7}, {48,7}}, ++}; ++ ++static struct nand_ecclayout nand_hw_eccoob_4k = { ++ .eccbytes = 9, ++ .eccpos = {7, 8, 9, 10, 11, 12, 13, 14, 15}, ++ .oobfree = {{2, 5}, {16, 218 - 16}}, ++}; ++ ++/*! ++ * @defgroup NAND_MTD NAND Flash MTD Driver for MXC processors ++ */ ++ ++/*! ++ * @file mxc_nd2.c ++ * ++ * @brief This file contains the hardware specific layer for NAND Flash on ++ * MXC processor ++ * ++ * @ingroup NAND_MTD ++ */ ++ ++#ifdef CONFIG_MTD_PARTITIONS ++static const char *part_probes[] = { "RedBoot", "cmdlinepart", NULL }; ++#endif ++ ++static irqreturn_t mxc_nfc_irq(int irq, void *dev_id) ++{ ++ struct mxc_mtd_s *mxc_nand_data = dev_id; ++ ++ /* Disable Interrupt */ ++ nfc_write_reg(mxc_nand_data, ++ nfc_read_reg(mxc_nand_data, REG_NFC_INTERRUPT) | ++ NFC_INT_MSK, REG_NFC_INTERRUPT); ++ wake_up(&mxc_nand_data->irq_waitq); ++ ++ return IRQ_HANDLED; ++} ++ ++/* ++ * Functions to transfer data to/from spare erea. ++ */ ++static void ++copy_spare(struct mtd_info *mtd, void *pbuf, void *pspare, int len, bool bfrom) ++{ ++ u16 i, j; ++ u16 m = mtd->oobsize; ++ u16 n = mtd->writesize >> 9; ++ u8 *d = (u8 *) pbuf; ++ u8 *s = (u8 *) pspare; ++ u16 t = SPARE_LEN; ++ ++ m /= num_of_interleave; ++ n /= num_of_interleave; ++ ++ j = (m / n >> 1) << 1; ++ ++ if (bfrom) { ++ for (i = 0; i < n - 1; i++) ++ memcpy(&d[i * j], &s[i * t], j); ++ ++ /* the last section */ ++ memcpy(&d[i * j], &s[i * t], len - i * j); ++ } else { ++ for (i = 0; i < n - 1; i++) ++ memcpy(&s[i * t], &d[i * j], j); ++ ++ /* the last section */ ++ memcpy(&s[i * t], &d[i * j], len - i * j); ++ } ++} ++ ++/*! ++ * This function polls the NFC to wait for the basic operation to complete by ++ * checking the INT bit of config2 register. ++ * ++ * @param retries number of retry attempts (separated by 1 us) ++ * @param useirq True if IRQ should be used rather than polling ++ */ ++static void wait_op_done(struct mxc_mtd_s *mxc_nand_data, int retries, bool useirq) ++{ ++ u32 nfc_stat; ++ static unsigned long max_wait[2]; ++ unsigned long timeout = msecs_to_jiffies(retries); ++ int op; ++ ++ nfc_stat = nfc_read_reg(mxc_nand_data, REG_NFC_OPS_STAT); ++ op = nfc_stat & 0xff; ++ DBG(2, "%s: cmd: 0x%02x op: 0x%02x irq: %d\n", __FUNCTION__, ++ __raw_readw(mxc_nand_data->reg_base + REG_NFC_FLASH_CMD), ++ op, useirq); ++ if (useirq) { ++ if (!(nfc_stat & NFC_OPS_STAT)) { ++ /* Enable Interrupt */ ++ nfc_write_reg(mxc_nand_data, ++ nfc_read_reg(mxc_nand_data, ++ REG_NFC_INTERRUPT) & ~NFC_INT_MSK, ++ REG_NFC_INTERRUPT); ++ retries = wait_event_timeout(mxc_nand_data->irq_waitq, ++ (nfc_stat = nfc_read_reg(mxc_nand_data, ++ REG_NFC_OPS_STAT)) & NFC_OPS_STAT, ++ timeout); ++ } ++ } else { ++ while (!(nfc_stat & NFC_OPS_STAT) && retries-- > 0) { ++ udelay(1); ++ nfc_stat = nfc_read_reg(mxc_nand_data, REG_NFC_OPS_STAT); ++ } ++ } ++ if (!(nfc_stat & NFC_OPS_STAT) && retries <= 0) { ++ printk(KERN_ERR "%s: timeout waiting for NFC INT for cmd: 0x%02x op 0x%02x: %d\n", ++ __FUNCTION__, __raw_readw(mxc_nand_data->reg_base + ++ REG_NFC_FLASH_CMD), op, useirq); ++ BUG(); ++ } else { ++ unsigned long wait = (useirq ? timeout : TROP_US_DELAY) - retries; ++ if (wait > max_wait[useirq]) { ++ max_wait[useirq] = wait; ++ DBG(2, "%s: ready(%d) after %lu ticks\n", __FUNCTION__, ++ useirq, max_wait[useirq]); ++ } ++ } ++ WRITE_NFC_IP_REG(nfc_stat & ~NFC_OPS_STAT, REG_NFC_OPS_STAT); ++ if (nfc_stat & NFC_OPS_STAT) { ++ DBG(2, "%s: Done: irq: %d ticks: %d\n", __FUNCTION__, useirq, retries); ++ } else { ++ DBG(0, "%s: Failed: irq: %d\n", __FUNCTION__, useirq); ++ } ++} ++ ++static inline void send_atomic_cmd(struct mxc_mtd_s *mxc_nand_data, u16 cmd, bool useirq) ++{ ++ /* fill command */ ++ nfc_write_reg(mxc_nand_data, cmd, REG_NFC_FLASH_CMD); ++ ++ /* clear status */ ++ ACK_OPS; ++ ++ /* send out command */ ++ nfc_write_reg(mxc_nand_data, NFC_CMD, REG_NFC_OPS); ++ ++ /* Wait for operation to complete */ ++ wait_op_done(mxc_nand_data, TROP_US_DELAY, useirq); ++} ++ ++static void mxc_do_addr_cycle(struct mtd_info *mtd, int column, int page_addr); ++static int mxc_check_ecc_status(struct mtd_info *mtd); ++ ++#ifdef NFC_AUTO_MODE_ENABLE ++/*! ++ * This function handle the interleave related work ++ * @param mtd mtd info ++ * @param cmd command ++ */ ++static void auto_cmd_interleave(struct mtd_info *mtd, u16 cmd) ++{ ++ u32 i; ++ u32 j = num_of_interleave; ++ struct nand_chip *this = mtd->priv; ++ struct mxc_mtd_s *mxc_nand_data = nand_chip->priv; ++ u32 addr_low = nfc_read_reg(mxc_nand_data, NFC_FLASH_ADDR0); ++ u32 addr_high = nfc_read_reg(mxc_nand_data, NFC_FLASH_ADDR8); ++ u32 page_addr = addr_low >> 16 | addr_high << 16; ++ u8 *dbuf = mxc_nand_data->data_buf; ++ u8 *obuf = mxc_nand_data->oob_buf; ++ u32 dlen = mtd->writesize / j; ++ u32 olen = mtd->oobsize / j; ++ ++ /* adjust the addr value ++ * since ADD_OP mode is 01 ++ */ ++ if (j > 1) ++ page_addr *= j; ++ else ++ page_addr *= this->numchips; ++ ++ switch (cmd) { ++ case NAND_CMD_PAGEPROG: ++ for (i = 0; i < j; i++) { ++ /* reset addr cycle */ ++ if (j > 1) ++ mxc_do_addr_cycle(mtd, 0, page_addr++); ++ ++ /* data transfer */ ++ memcpy(mxc_nand_data->main_buf, dbuf, dlen); ++ copy_spare(mtd, obuf, mxc_nand_data->spare_buf, olen, false); ++ ++ /* update the value */ ++ dbuf += dlen; ++ obuf += olen; ++ ++ NFC_SET_RBA(0); ++ ACK_OPS; ++ nfc_write_reg(mxc_nand_data, NFC_AUTO_PROG, REG_NFC_OPS); ++ ++ /* wait auto_prog_done bit set */ ++ while (!(raw_read(REG_NFC_OPS_STAT) & NFC_OP_DONE)) ; ++ } ++ ++ wait_op_done(TROP_US_DELAY, false); ++ while (!(raw_read(REG_NFC_OPS_STAT) & NFC_RB)) ; ++ ++ break; ++ case NAND_CMD_READSTART: ++ for (i = 0; i < j; i++) { ++ /* reset addr cycle */ ++ if (j > 1) ++ mxc_do_addr_cycle(mtd, 0, page_addr++); ++ ++ NFC_SET_RBA(0); ++ ACK_OPS; ++ nfc_write_reg(mxc_nand_data, NFC_AUTO_READ, REG_NFC_OPS); ++ wait_op_done(mxc_nand_data, TROP_US_DELAY, true); ++ ++ /* check ecc error */ ++ mxc_check_ecc_status(mtd); ++ ++ /* data transfer */ ++ memcpy(dbuf, mxc_nand_data->main_buf, dlen); ++ copy_spare(mtd, obuf, mxc_nand_data->spare_buf, olen, true); ++ ++ /* update the value */ ++ dbuf += dlen; ++ obuf += olen; ++ } ++ break; ++ case NAND_CMD_ERASE2: ++ for (i = 0; i < j; i++) { ++ if (!i) { ++ page_addr = addr_low; ++ page_addr *= (j > 1 ? j : this->numchips); ++ } ++ mxc_do_addr_cycle(mtd, -1, page_addr++); ++ ACK_OPS; ++ nfc_write_reg(NFC_AUTO_ERASE, REG_NFC_OPS); ++ wait_op_done(TROP_US_DELAY, true); ++ } ++ break; ++ case NAND_CMD_RESET: ++ for (i = 0; i < j; i++) { ++ if (j > 1) ++ NFC_SET_NFC_ACTIVE_CS(i); ++ send_atomic_cmd(cmd, false); ++ } ++ break; ++ } ++} ++#endif ++ ++static void send_addr(struct mxc_mtd_s *mxc_nand_data, u16 addr, bool useirq); ++ ++/*! ++ * This function issues the specified command to the NAND device and ++ * waits for completion. ++ * ++ * @param cmd command for NAND Flash ++ * @param useirq True if IRQ should be used rather than polling ++ */ ++static void send_cmd(struct mtd_info *mtd, u16 cmd, bool useirq) ++{ ++ struct nand_chip *nand_chip = mtd->priv; ++ struct mxc_mtd_s *mxc_nand_data = nand_chip->priv; ++ ++ DEBUG(MTD_DEBUG_LEVEL3, "send_cmd(0x%x, %d)\n", cmd, useirq); ++ ++#ifdef NFC_AUTO_MODE_ENABLE ++ switch (cmd) { ++ case NAND_CMD_READ0: ++ case NAND_CMD_READOOB: ++ nfc_write_reg(mxc_nand_data, NAND_CMD_READ0, REG_NFC_FLASH_CMD); ++ break; ++ case NAND_CMD_SEQIN: ++ case NAND_CMD_ERASE1: ++ nfc_write_reg(mxc_nand_data, cmd, REG_NFC_FLASH_CMD); ++ break; ++ case NAND_CMD_PAGEPROG: ++ case NAND_CMD_ERASE2: ++ case NAND_CMD_READSTART: ++ nfc_write_reg(mxc_nand_data, ++ nfc_read_reg(mxc_nand_data, REG_NFC_FLASH_CMD) | ++ cmd << NFC_CMD_1_SHIFT, ++ REG_NFC_FLASH_CMD); ++ auto_cmd_interleave(mtd, cmd); ++ break; ++ case NAND_CMD_READID: ++ send_atomic_cmd(mxc_nand_data, cmd, useirq); ++ send_addr(mxc_nand_data, 0, false); ++ break; ++ case NAND_CMD_RESET: ++ auto_cmd_interleave(mtd, cmd); ++ case NAND_CMD_STATUS: ++ break; ++ } ++#else ++ send_atomic_cmd(mxc_nand_data, cmd, useirq); ++#endif ++} ++ ++/*! ++ * This function sends an address (or partial address) to the ++ * NAND device. The address is used to select the source/destination for ++ * a NAND command. ++ * ++ * @param addr address to be written to NFC. ++ * @param useirq True if IRQ should be used rather than polling ++ */ ++static void send_addr(struct mxc_mtd_s *mxc_nand_data, u16 addr, bool useirq) ++{ ++ DEBUG(MTD_DEBUG_LEVEL3, "send_addr(0x%x %d)\n", addr, useirq); ++ ++ /* fill address */ ++ nfc_write_reg(mxc_nand_data, (addr << NFC_FLASH_ADDR_SHIFT), ++ REG_NFC_FLASH_ADDR); ++ ++ /* clear status */ ++ ACK_OPS; ++ ++ /* send out address */ ++ nfc_write_reg(mxc_nand_data, NFC_ADDR, REG_NFC_OPS); ++ ++ /* Wait for operation to complete */ ++ wait_op_done(mxc_nand_data, TROP_US_DELAY, useirq); ++} ++ ++/*! ++ * This function requests the NFC to initate the transfer ++ * of data currently in the NFC RAM buffer to the NAND device. ++ * ++ * @param buf_id Specify Internal RAM Buffer number ++ */ ++static void send_prog_page(struct mxc_mtd_s *mxc_nand_data, u8 buf_id) ++{ ++#ifndef NFC_AUTO_MODE_ENABLE ++ DEBUG(MTD_DEBUG_LEVEL0, "%s\n", __FUNCTION__); ++ ++ /* set ram buffer id */ ++ NFC_SET_RBA(buf_id); ++ ++ /* clear status */ ++ ACK_OPS; ++ ++ /* transfer data from NFC ram to nand */ ++ nfc_write_reg(mxc_nand_data, NFC_INPUT, REG_NFC_OPS); ++ ++ /* Wait for operation to complete */ ++ wait_op_done(mxc_nand_data, TROP_US_DELAY, true); ++#endif ++} ++ ++/*! ++ * This function requests the NFC to initated the transfer ++ * of data from the NAND device into in the NFC ram buffer. ++ * ++ * @param buf_id Specify Internal RAM Buffer number ++ */ ++static void send_read_page(struct mxc_mtd_s *mxc_nand_data, u8 buf_id) ++{ ++#ifndef NFC_AUTO_MODE_ENABLE ++ DEBUG(MTD_DEBUG_LEVEL2, "%s(%d)\n", __FUNCTION__, buf_id); ++ ++ /* set ram buffer id */ ++ NFC_SET_RBA(buf_id); ++ ++ /* clear status */ ++ ACK_OPS; ++ ++ /* transfer data from nand to NFC ram */ ++ nfc_write_reg(mxc_nand_data, NFC_OUTPUT, REG_NFC_OPS); ++ ++ /* Wait for operation to complete */ ++ wait_op_done(mxc_nand_data, TROP_US_DELAY, true); ++#endif ++} ++ ++/*! ++ * This function requests the NFC to perform a read of the ++ * NAND device ID. ++ */ ++static void send_read_id(struct mxc_mtd_s *mxc_nand_data) ++{ ++ DBG(2, "%s: \n", __FUNCTION__); ++ ++ /* Set RBA bits for BUFFER0 */ ++ NFC_SET_RBA(0); ++ ++ /* clear status */ ++ ACK_OPS; ++ ++ /* Read ID into main buffer */ ++ nfc_write_reg(mxc_nand_data, NFC_ID, REG_NFC_OPS); ++ ++ /* Wait for operation to complete */ ++ wait_op_done(mxc_nand_data, TROP_US_DELAY, true); ++} ++ ++#ifdef NFC_AUTO_MODE_ENABLE ++static inline void read_dev_status(u16 *status) ++{ ++ u32 mask = 0xFF << 16; ++ ++ /* clear status */ ++ ACK_OPS; ++ ++ do { ++ /* send auto read status command */ ++ nfc_write_reg(NFC_AUTO_STATE, REG_NFC_OPS); ++ if (cpu_is_mx51_rev(CHIP_REV_2_0) == 1) ++ wait_op_done(TROP_US_DELAY, false); ++ *status = (raw_read(NFC_CONFIG1) & mask) >> 16; ++ } while ((*status & NAND_STATUS_READY) == 0); ++} ++#endif ++ ++/*! ++ * This function requests the NFC to perform a read of the ++ * NAND device status and returns the current status. ++ * ++ * @return device status ++ */ ++static u16 get_dev_status(struct mxc_mtd_s *mxc_nand_data) ++{ ++#ifdef NFC_AUTO_MODE_ENABLE ++ int i; ++ u16 status = 0; ++ for (i = 0; i < num_of_interleave; i++) { ++ ++ /* set ative cs */ ++ NFC_SET_NFC_ACTIVE_CS(i); ++ ++ /* FIXME, NFC Auto erase may have ++ * problem, have to poll it until ++ * the nand get idle, otherwise ++ * it may get error ++ */ ++ read_dev_status(&status); ++ if (status & NAND_STATUS_FAIL) ++ break; ++ } ++ ++ return status; ++#else ++ u8 val = 1; ++ u16 *main_buf = mxc_nand_data->main_buf + val * (0x200 >> 1); ++ u16 ret; ++ u16 save = *main_buf; ++ ++ /* Set ram buffer id */ ++ NFC_SET_RBA(val); ++ ++ /* clear status */ ++ ACK_OPS; ++ ++ if (dbg_lvl(3)) { ++ for (val = 0; val < 8; val++) { ++ u16 *main_buf = mxc_nand_data->main_buf + val * (0x200 >> 1); ++ print_hex_dump(KERN_DEBUG, "mainbuf0: ", ++ DUMP_PREFIX_ADDRESS, ++ 16, 2, main_buf, 16, 0); ++ } ++ } ++ ++ /* Read status into main buffer */ ++ nfc_write_reg(mxc_nand_data, NFC_STATUS, REG_NFC_OPS); ++ ++ /* Wait for operation to complete */ ++ wait_op_done(mxc_nand_data, TROP_US_DELAY, true); ++ ++ if (dbg_lvl(3)) { ++ for (val = 0; val < 8; val++) { ++ u16 *main_buf = mxc_nand_data->main_buf + val * (0x200 >> 1); ++ print_hex_dump(KERN_DEBUG, "mainbuf1: ", ++ DUMP_PREFIX_ADDRESS, ++ 16, 2, main_buf, 16, 0); ++ } ++ } ++ ++ /* Status is placed in first word of main buffer */ ++ /* get status, then recover area 1 data */ ++ ret = *main_buf; ++ *main_buf = save; ++ ++ return ret; ++#endif ++} ++ ++static void mxc_nand_enable_hwecc(struct mtd_info *mtd, int mode) ++{ ++ struct nand_chip *nand_chip = mtd->priv; ++ struct mxc_mtd_s *mxc_nand_data = nand_chip->priv; ++ ++ nfc_write_reg(mxc_nand_data, ++ (nfc_read_reg(mxc_nand_data, REG_NFC_ECC_EN) | NFC_ECC_EN), ++ REG_NFC_ECC_EN); ++ return; ++} ++ ++/* ++ * Function to record the ECC corrected/uncorrected errors resulted ++ * after a page read. This NFC detects and corrects upto to 4 symbols ++ * of 9-bits each. ++ */ ++static int mxc_check_ecc_status(struct mtd_info *mtd) ++{ ++ struct nand_chip *nand_chip = mtd->priv; ++ struct mxc_mtd_s *mxc_nand_data = nand_chip->priv; ++ int no_subpages = (mtd->writesize >> 9) / num_of_interleave; ++ int ret = 0; ++ u8 ecc_bit_mask = (IS_4BIT_ECC ? 0x7 : 0xf); ++ u8 err_limit = (IS_4BIT_ECC ? 0x4 : 0x8); ++ u32 ecc_stat; ++ ++ ecc_stat = GET_NFC_ECC_STATUS(); ++ do { ++ u32 err = ecc_stat & ecc_bit_mask; ++ if (err > err_limit) { ++ mtd->ecc_stats.failed++; ++ printk(KERN_WARNING "UnCorrectable RS-ECC Error\n"); ++ return -EILSEQ; ++ } else { ++ ret += err; ++ } ++ ecc_stat >>= 4; ++ } while (--no_subpages); ++ ++ mtd->ecc_stats.corrected += ret; ++ pr_debug("%d Symbol Correctable RS-ECC Error\n", ret); ++ ++ return ret; ++} ++ ++/* ++ * Function to correct the detected errors. This NFC corrects all the errors ++ * detected. So this function just return 0. ++ */ ++static int mxc_nand_correct_data(struct mtd_info *mtd, u_char *dat, ++ u_char *read_ecc, u_char *calc_ecc) ++{ ++ return 0; ++} ++ ++/* ++ * Function to calculate the ECC for the data to be stored in the Nand device. ++ * This NFC has a hardware RS(511,503) ECC engine together with the RS ECC ++ * CONTROL blocks are responsible for detection and correction of up to ++ * 8 symbols of 9 bits each in 528 byte page. ++ * So this function is just return 0. ++ */ ++ ++static int mxc_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, ++ u_char *ecc_code) ++{ ++ return 0; ++} ++ ++/*! ++ * This function id is used to read the data buffer from the NAND Flash. To ++ * read the data from NAND Flash first the data output cycle is initiated by ++ * the NFC, which copies the data to RAMbuffer. This data of length \b len is ++ * then copied to buffer \b buf. ++ * ++ * @param mtd MTD structure for the NAND Flash ++ * @param buf data to be read from NAND Flash ++ * @param len number of bytes to be read ++ */ ++static void mxc_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) ++{ ++ struct nand_chip *nand_chip = mtd->priv; ++ struct mxc_mtd_s *mxc_nand_data = nand_chip->priv; ++ u16 col = mxc_nand_data->col_addr; ++ ++ if (mtd->writesize) { ++ int j = mtd->writesize - col; ++ int n = min((int)mtd->oobsize + j, len); ++ ++ if (j > 0) { ++ if (WARN_ON(n > j)) { ++ memcpy(buf, &mxc_nand_data->data_buf[col], j); ++ memcpy(buf + j, &mxc_nand_data->oob_buf[0], n - j); ++ } else { ++ memcpy(buf, &mxc_nand_data->data_buf[col], n); ++ } ++ } else { ++ col -= mtd->writesize; ++ memcpy(buf, &mxc_nand_data->oob_buf[col], len); ++ } ++ ++ /* update */ ++ mxc_nand_data->col_addr += n; ++ } else { ++ /* At flash identify phase, ++ * mtd->writesize has not been ++ * set correctly, it should ++ * be zero. And len will less 2 ++ */ ++ memcpy(buf, &mxc_nand_data->data_buf[col], len); ++ ++ /* update */ ++ mxc_nand_data->col_addr += len; ++ } ++} ++ ++/*! ++ * This function reads byte from the NAND Flash ++ * ++ * @param mtd MTD structure for the NAND Flash ++ * ++ * @return data read from the NAND Flash ++ */ ++static u8 mxc_nand_read_byte(struct mtd_info *mtd) ++{ ++ struct nand_chip *nand_chip = mtd->priv; ++ struct mxc_mtd_s *mxc_nand_data = nand_chip->priv; ++ u8 ret; ++ ++ /* Check for status request */ ++ if (mxc_nand_data->status_req) { ++ ret = get_dev_status(mxc_nand_data) & 0xFF; ++ DBG(1, "%s: NAND status=%02x\n", __FUNCTION__, ret); ++ return ret; ++ } ++ ++ mxc_nand_read_buf(mtd, &ret, 1); ++ return ret; ++} ++ ++/*! ++ * This function reads word from the NAND Flash ++ * ++ * @param mtd MTD structure for the NAND Flash ++ * ++ * @return data read from the NAND Flash ++ */ ++static u16 mxc_nand_read_word(struct mtd_info *mtd) ++{ ++ u16 ret; ++ ++ mxc_nand_read_buf(mtd, (u8 *)&ret, sizeof(u16)); ++ return ret; ++} ++ ++/*! ++ * This function reads byte from the NAND Flash ++ * ++ * @param mtd MTD structure for the NAND Flash ++ * ++ * @return data read from the NAND Flash ++ */ ++static u_char mxc_nand_read_byte16(struct mtd_info *mtd) ++{ ++ struct nand_chip *nand_chip = mtd->priv; ++ struct mxc_mtd_s *mxc_nand_data = nand_chip->priv; ++ ++ /* Check for status request */ ++ if (mxc_nand_data->status_req) { ++ return get_dev_status(mxc_nand_data) & 0xFF; ++ } ++ ++ return mxc_nand_read_word(mtd) & 0xFF; ++} ++ ++/*! ++ * This function writes data of length \b len from buffer \b buf to the NAND ++ * internal RAM buffer's MAIN area 0. ++ * ++ * @param mtd MTD structure for the NAND Flash ++ * @param buf data to be written to NAND Flash ++ * @param len number of bytes to be written ++ */ ++static void mxc_nand_write_buf(struct mtd_info *mtd, ++ const u_char *buf, int len) ++{ ++ struct nand_chip *nand_chip = mtd->priv; ++ struct mxc_mtd_s *mxc_nand_data = nand_chip->priv; ++ u16 col = mxc_nand_data->col_addr; ++ int j = mtd->writesize - col; ++ int n = mtd->oobsize + j; ++ ++ n = min(n, len); ++ ++ if (j > 0) { ++ if (n > j) { ++ memcpy(&mxc_nand_data->data_buf[col], buf, j); ++ memcpy(&mxc_nand_data->oob_buf[0], buf + j, n - j); ++ } else { ++ memcpy(&mxc_nand_data->data_buf[col], buf, n); ++ } ++ } else { ++ col -= mtd->writesize; ++ memcpy(&mxc_nand_data->oob_buf[col], buf, len); ++ } ++ ++ /* update */ ++ mxc_nand_data->col_addr += n; ++} ++ ++/*! ++ * This function is used by the upper layer to verify the data in NAND Flash ++ * with the data in the \b buf. ++ * ++ * @param mtd MTD structure for the NAND Flash ++ * @param buf data to be verified ++ * @param len length of the data to be verified ++ * ++ * @return -EFAULT if error else 0 ++ * ++ */ ++static int mxc_nand_verify_buf(struct mtd_info *mtd, const u_char *buf, ++ int len) ++{ ++ struct nand_chip *nand_chip = mtd->priv; ++ struct mxc_mtd_s *mxc_nand_data = nand_chip->priv; ++ u_char *s = mxc_nand_data->data_buf; ++ const u_char *p = buf; ++ ++ for (; len > 0; len--) { ++ if (*p++ != *s++) ++ return -EFAULT; ++ } ++ ++ return 0; ++} ++ ++/*! ++ * This function is used by upper layer for select and deselect of the NAND ++ * chip ++ * ++ * @param mtd MTD structure for the NAND Flash ++ * @param chip val indicating select or deselect ++ */ ++static void mxc_nand_select_chip(struct mtd_info *mtd, int chip) ++{ ++ struct nand_chip *nand_chip = mtd->priv; ++ struct mxc_mtd_s *mxc_nand_data = nand_chip->priv; ++ ++ switch (chip) { ++ case -1: ++ if (mxc_nand_data->clk_act) { ++ /* Disable the NFC clock */ ++ clk_disable(mxc_nand_data->clk); ++ mxc_nand_data->clk_act = 0; ++ } ++ break; ++ case 0 ... 7: ++ /* Enable the NFC clock */ ++ if (!mxc_nand_data->clk_act) { ++ clk_enable(mxc_nand_data->clk); ++ mxc_nand_data->clk_act = 1; ++ } ++ NFC_SET_NFC_ACTIVE_CS(chip); ++ break; ++ default: ++ BUG(); ++ } ++} ++ ++/* ++ * Function to perform the address cycles. ++ */ ++static void mxc_do_addr_cycle(struct mtd_info *mtd, int column, int page_addr) ++{ ++ struct nand_chip *nand_chip = mtd->priv; ++ struct mxc_mtd_s *mxc_nand_data = nand_chip->priv; ++#ifdef NFC_AUTO_MODE_ENABLE ++ if (page_addr != -1 && column != -1) { ++ u32 mask = 0xFFFF; ++ /* the column address */ ++ nfc_write_reg(mxc_nand_data, column & mask, NFC_FLASH_ADDR0); ++ nfc_write_reg(mxc_nand_data, ++ (nfc_read_reg(mxc_nand_data, NFC_FLASH_ADDR0) | ++ ((page_addr & mask) << 16)), NFC_FLASH_ADDR0); ++ /* the row address */ ++ nfc_write_reg(mxc_nand_data, ++ ((nfc_read_reg(mxc_nand_data, NFC_FLASH_ADDR8) & ++ (mask << 16)) | ++ ((page_addr & (mask << 16)) >> 16)), ++ NFC_FLASH_ADDR8); ++ } else if (page_addr != -1) { ++ nfc_write_reg(mxc_nand_data, page_addr, NFC_FLASH_ADDR0); ++ } ++ ++ DEBUG(MTD_DEBUG_LEVEL3, ++ "AutoMode:the ADDR REGS value is (0x%x, 0x%x)\n", ++ nfc_read_reg(mxc_nand_data, NFC_FLASH_ADDR0), ++ nfc_read_reg(mxc_nand_data, NFC_FLASH_ADDR8)); ++#else ++ ++ u32 page_mask = nand_chip->pagemask; ++ ++ if (column != -1) { ++ send_addr(mxc_nand_data, column & 0xFF, false); ++ if (IS_2K_PAGE_NAND) { ++ /* another col addr cycle for 2k page */ ++ send_addr(mxc_nand_data, (column >> 8) & 0xF, false); ++ } else if (IS_4K_PAGE_NAND) { ++ /* another col addr cycle for 4k page */ ++ send_addr(mxc_nand_data, (column >> 8) & 0x1F, false); ++ } ++ } ++ if (page_addr != -1) { ++ do { ++ send_addr(mxc_nand_data, (page_addr & 0xff), false); ++ page_mask >>= 8; ++ page_addr >>= 8; ++ } while (page_mask != 0); ++ } ++#endif ++} ++ ++/*! ++ * This function is used by the upper layer to write command to NAND Flash for ++ * different operations to be carried out on NAND Flash ++ * ++ * @param mtd MTD structure for the NAND Flash ++ * @param command command for NAND Flash ++ * @param column column offset for the page read ++ * @param page_addr page to be read from NAND Flash ++ */ ++static void mxc_nand_command(struct mtd_info *mtd, unsigned command, ++ int column, int page_addr) ++{ ++ struct nand_chip *nand_chip = mtd->priv; ++ struct mxc_mtd_s *mxc_nand_data = nand_chip->priv; ++ bool useirq = false; ++ ++ DEBUG(MTD_DEBUG_LEVEL2, ++ "mxc_nand_command (cmd = 0x%x, col = 0x%x, page = 0x%x)\n", ++ command, column, page_addr); ++ /* ++ * Reset command state information ++ */ ++ mxc_nand_data->status_req = false; ++ ++ /* ++ * Command pre-processing step ++ */ ++ switch (command) { ++ case NAND_CMD_STATUS: ++ mxc_nand_data->col_addr = 0; ++ mxc_nand_data->status_req = true; ++ break; ++ ++ case NAND_CMD_READ0: ++ mxc_nand_data->col_addr = column; ++ break; ++ ++ case NAND_CMD_READOOB: ++ mxc_nand_data->col_addr = column; ++ command = NAND_CMD_READ0; ++ break; ++ ++ case NAND_CMD_SEQIN: ++ if (column != 0) { ++ /* Before sending SEQIN command for partial ++ * write, we need to read one page out. ++ * FSL NFC does not support partial write ++ * for large page devices. It alway sends out ++ * 512+ecc+512+ecc.... ++ * For small page nand flash, it would support ++ * SPARE ONLY operation. But to simplify the driver, ++ * we take the same approach for small page and ++ * large page devices: ++ * read out the whole page and update. ++ * As for MLC nand NOP(num of operation) = 1. ++ * Partial writing to one programmed page is ++ * not allowed! We can't limit it in the driver, ++ * the upper layer application needs to take care of it. ++ */ ++ mxc_nand_command(mtd, NAND_CMD_READ0, 0, page_addr); ++ } ++ ++ mxc_nand_data->col_addr = column; ++ break; ++ ++ case NAND_CMD_PAGEPROG: ++#ifndef NFC_AUTO_MODE_ENABLE ++ /* The NFC internal buffer access ++ * has some limitation, it does not ++ * allow byte access. To make the code ++ * simple and easy to use, do not check ++ * the address alignment each time. ++ * Use the temp buffer to accomodate ++ * the data alignment. ++ * We know data_buf will be at least 4 ++ * byte aligned, so we can use ++ * memcpy safely. ++ */ ++ memcpy(mxc_nand_data->main_buf, mxc_nand_data->data_buf, mtd->writesize); ++ copy_spare(mtd, mxc_nand_data->oob_buf, mxc_nand_data->spare_buf, ++ mtd->oobsize, false); ++#endif ++ ++ if (IS_LARGE_PAGE_NAND) ++ PROG_PAGE(mxc_nand_data); ++ else ++ send_prog_page(mxc_nand_data, 0); ++ useirq = true; ++ break; ++ ++ case NAND_CMD_ERASE1: ++ break; ++ case NAND_CMD_ERASE2: ++ useirq = true; ++ ++ break; ++ } ++ ++ /* ++ * Write out the command to the device. ++ */ ++ send_cmd(mtd, command, useirq); ++ ++ mxc_do_addr_cycle(mtd, column, page_addr); ++ ++ /* ++ * Command post-processing step ++ */ ++ switch (command) { ++ ++ case NAND_CMD_READOOB: ++ case NAND_CMD_READ0: ++ if (IS_LARGE_PAGE_NAND) { ++ /* send read confirm command */ ++ send_cmd(mtd, NAND_CMD_READSTART, true); ++ /* read for each AREA */ ++ READ_PAGE(mxc_nand_data); ++ } else { ++ send_read_page(mxc_nand_data, 0); ++ } ++ ++#ifndef NFC_AUTO_MODE_ENABLE ++ /* FIXME, the NFC interal buffer ++ * access has some limitation, it ++ * does not allow byte access. To ++ * make the code simple and ease use ++ * do not check the address alignment ++ * on each access. Use the temp buffer ++ * to accomodate the data. Since we ++ * know data_buf will be at least 4 ++ * byte alignment, so we can use ++ * memcpy safely ++ */ ++ memcpy(mxc_nand_data->data_buf, mxc_nand_data->main_buf, mtd->writesize); ++ copy_spare(mtd, mxc_nand_data->oob_buf, ++ mxc_nand_data->spare_buf, mtd->oobsize, true); ++#endif ++ ++ break; ++ ++ case NAND_CMD_READID: ++ send_read_id(mxc_nand_data); ++ mxc_nand_data->col_addr = column; ++ memcpy(mxc_nand_data->data_buf, mxc_nand_data->main_buf, 2048); ++ break; ++ } ++} ++ ++static int mxc_nand_read_oob(struct mtd_info *mtd, ++ struct nand_chip *chip, int page, int sndcmd) ++{ ++ struct nand_chip *nand_chip = mtd->priv; ++ struct mxc_mtd_s *mxc_nand_data = nand_chip->priv; ++ ++ if (sndcmd) { ++ chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page); ++ sndcmd = 0; ++ } ++ ++ memcpy(chip->oob_poi, mxc_nand_data->oob_buf, mtd->oobsize); ++ ++ return sndcmd; ++} ++ ++static int mxc_nand_read_page(struct mtd_info *mtd, struct nand_chip *chip, ++ u8 *buf) ++{ ++ struct nand_chip *nand_chip = mtd->priv; ++ struct mxc_mtd_s *mxc_nand_data = nand_chip->priv; ++ ++#ifndef NFC_AUTO_MODE_ENABLE ++ if (mxc_check_ecc_status(mtd) < 0) { ++ //printk(KERN_ERR "ECC error in block %u page %u\n",); ++ } ++#endif ++ ++ memcpy(buf, mxc_nand_data->data_buf, mtd->writesize); ++ memcpy(chip->oob_poi, mxc_nand_data->oob_buf, mtd->oobsize); ++ ++ return 0; ++} ++ ++static void mxc_nand_write_page(struct mtd_info *mtd, struct nand_chip *chip, ++ const u8 *buf) ++{ ++ struct nand_chip *nand_chip = mtd->priv; ++ struct mxc_mtd_s *mxc_nand_data = nand_chip->priv; ++ ++ memcpy(mxc_nand_data->data_buf, buf, mtd->writesize); ++ memcpy(mxc_nand_data->oob_buf, chip->oob_poi, mtd->oobsize); ++} ++ ++/* Define some generic bad / good block scan pattern which are used ++ * while scanning a device for factory marked good / bad blocks. */ ++static u8 scan_ff_pattern[] = { 0xff, 0xff }; ++ ++static struct nand_bbt_descr smallpage_memorybased = { ++ .options = NAND_BBT_SCAN2NDPAGE, ++ .offs = 5, ++ .len = 1, ++ .pattern = scan_ff_pattern ++}; ++ ++static struct nand_bbt_descr largepage_memorybased = { ++ .options = 0, ++ .offs = 0, ++ .len = 2, ++ .pattern = scan_ff_pattern ++}; ++ ++/* Generic flash bbt decriptors ++*/ ++static u8 bbt_pattern[] = { 'B', 'b', 't', '0' }; ++static u8 mirror_pattern[] = { '1', 't', 'b', 'B' }; ++ ++static struct nand_bbt_descr bbt_main_descr = { ++ .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE | ++ NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP, ++ .offs = 0, ++ .len = 4, ++ .veroffs = 4, ++ .maxblocks = 4, ++ .pattern = bbt_pattern ++}; ++ ++static struct nand_bbt_descr bbt_mirror_descr = { ++ .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE | ++ NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP, ++ .offs = 0, ++ .len = 4, ++ .veroffs = 4, ++ .maxblocks = 4, ++ .pattern = mirror_pattern ++}; ++ ++static int mxc_nand_scan_bbt(struct mtd_info *mtd) ++{ ++ struct nand_chip *nand_chip = mtd->priv; ++ struct mxc_mtd_s *mxc_nand_data = nand_chip->priv; ++ ++ if (IS_2K_PAGE_NAND) { ++ NFC_SET_NFMS(1 << NFMS_NF_PG_SZ); ++ } else if (IS_4K_PAGE_NAND) { ++ NFC_SET_NFMS(1 << NFMS_NF_PG_SZ); ++ } else { ++ } ++ ++ /* reconfig for interleave mode */ ++#ifdef NFC_AUTO_MODE_ENABLE ++ if (nand_chip->numchips > 1) { ++ num_of_interleave = nand_chip->numchips; ++ nand_chip->numchips = 1; ++ ++ /* FIXEME:need remove it ++ * when kernel support ++ * 4G larger space ++ */ ++ mtd->size = nand_chip->chipsize; ++ mtd->erasesize *= num_of_interleave; ++ mtd->writesize *= num_of_interleave; ++ mtd->oobsize *= num_of_interleave; ++ nand_chip->page_shift = ffs(mtd->writesize) - 1; ++ nand_chip->bbt_erase_shift = ++ nand_chip->phys_erase_shift = ffs(mtd->erasesize) - 1; ++ nand_chip->chip_shift = ffs(nand_chip->chipsize) - 1; ++ nand_chip->oob_poi = nand_chip->buffers->databuf + mtd->writesize; ++ } ++#endif ++ /* jffs2 not write oob */ ++ //mtd->flags |= MTD_OOB_READONLY; ++ ++ /* use flash based bbt */ ++ nand_chip->bbt_td = &bbt_main_descr; ++ nand_chip->bbt_md = &bbt_mirror_descr; ++ ++ /* update flash based bbt */ ++ nand_chip->options |= NAND_USE_FLASH_BBT; ++ ++ if (!nand_chip->badblock_pattern) { ++ nand_chip->badblock_pattern = (mtd->writesize > 512) ? ++ &largepage_memorybased : &smallpage_memorybased; ++ } ++ ++ /* Build bad block table */ ++ return nand_scan_bbt(mtd, nand_chip->badblock_pattern); ++} ++ ++static void mxc_nfc_init(struct mxc_mtd_s *mxc_nand_data) ++{ ++ /* Disable interrupt */ ++ nfc_write_reg(mxc_nand_data, ++ nfc_read_reg(mxc_nand_data, REG_NFC_INTERRUPT) | ++ NFC_INT_MSK, REG_NFC_INTERRUPT); ++ ++ /* disable spare enable */ ++ nfc_write_reg(mxc_nand_data, ++ nfc_read_reg(mxc_nand_data, REG_NFC_SP_EN) & ++ ~NFC_SP_EN, REG_NFC_SP_EN); ++ ++ /* Unlock the internal RAM Buffer */ ++ nfc_write_reg(mxc_nand_data, NFC_SET_BLS(NFC_BLS_UNLOCKED), ++ REG_NFC_BLS); ++ ++ /* Blocks to be unlocked */ ++ UNLOCK_ADDR(0x0, 0xFFFF); ++ ++ /* Unlock Block Command for given address range */ ++ nfc_write_reg(mxc_nand_data, NFC_SET_WPC(NFC_WPC_UNLOCK), REG_NFC_WPC); ++ ++ /* Enable symmetric mode by default except mx37TO1.0 */ ++ if (!cpu_is_mx25()) { ++ nfc_write_reg(mxc_nand_data, ++ nfc_read_reg(mxc_nand_data, REG_NFC_ONE_CYCLE) | ++ NFC_ONE_CYCLE, REG_NFC_ONE_CYCLE); ++ } else { ++ nfc_write_reg(mxc_nand_data, ++ nfc_read_reg(mxc_nand_data, REG_NFC_ONE_CYCLE) & ++ ~NFC_ONE_CYCLE, REG_NFC_ONE_CYCLE); ++ } ++} ++ ++static int mxc_alloc_buf(struct mxc_mtd_s *mxc_nand_data) ++{ ++ u8 *buf; ++ ++ buf = kzalloc(NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE, GFP_KERNEL); ++ if (!buf) { ++ printk(KERN_ERR "%s: failed to allocate data_buf\n", __func__); ++ return -ENOMEM; ++ } ++ mxc_nand_data->data_buf = buf; ++ mxc_nand_data->oob_buf = &buf[NAND_MAX_PAGESIZE]; ++ return 0; ++} ++ ++static void mxc_free_buf(struct mxc_mtd_s *mxc_nand_data) ++{ ++ kfree(mxc_nand_data->data_buf); ++} ++ ++/*! ++ * This function is called during the driver binding process. ++ * ++ * @param pdev the device structure used to store device specific ++ * information that is used by the suspend, resume and ++ * remove functions ++ * ++ * @return The function always returns 0. ++ */ ++#define SPLIT_SCAN ++ ++static int __init mxcnd_probe(struct platform_device *pdev) ++{ ++ int err; ++ struct nand_chip *this; ++ struct mtd_info *mtd; ++ struct flash_platform_data *pdata = pdev->dev.platform_data; ++ int nr_parts; ++ struct resource *res; ++ struct mxc_mtd_s *mxc_nand_data; ++ struct clk *clk; ++ void __iomem *nfc_axi_base; ++ void __iomem *nfc_ip_base; ++ ++ if (!pdata) { ++ dev_err(&pdev->dev, "No platform_data\n"); ++ return -ENODEV; ++ } ++ ++ /* Allocate memory for MTD device structure and private data */ ++ mxc_nand_data = kzalloc(sizeof(struct mxc_mtd_s), GFP_KERNEL); ++ if (!mxc_nand_data) { ++ printk(KERN_ERR "%s: failed to allocate mtd_info\n", ++ __FUNCTION__); ++ return -ENOMEM; ++ } ++ ++ /* allocate data buffer */ ++ if (mxc_alloc_buf(mxc_nand_data)) { ++ err = -ENOMEM; ++ goto out; ++ } ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (!res) { ++ dev_err(&pdev->dev, "no memory resource\n"); ++ err = -ENODEV; ++ goto out1; ++ } ++ if (!request_mem_region(res->start, resource_size(res), DRV_NAME)) { ++ err = -EBUSY; ++ goto out1; ++ } ++ mxc_nand_data->res_ip = res; ++ ++ nfc_ip_base = ioremap(res->start, resource_size(res)); ++ if (nfc_ip_base == NULL) { ++ dev_err(&pdev->dev, "Failed to ioremap %08lx..%08lx\n", ++ (unsigned long)res->start, (unsigned long)res->end); ++ err = -ENOMEM; ++ goto out2; ++ } ++ DBG(0, "%s: %08lx..%08lx remapped to %p\n", __FUNCTION__, ++ (unsigned long)res->start, (unsigned long)res->end, ++ nfc_ip_base); ++ ++ mxc_nand_data->reg_base = nfc_ip_base; ++ mxc_nand_data->main_buf = mxc_nand_data->reg_base + MAIN_AREA0; ++ mxc_nand_data->spare_buf = mxc_nand_data->reg_base + SPARE_AREA0; ++ ++ DBG(1, "%s: reg_base=%p\n", __FUNCTION__, mxc_nand_data->reg_base); ++ DBG(1, "%s: main_buf=%p\n", __FUNCTION__, mxc_nand_data->main_buf); ++ DBG(1, "%s: spare_buf=%p\n", __FUNCTION__, mxc_nand_data->spare_buf); ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 1); ++ if (res) { ++ if (!request_mem_region(res->start, resource_size(res), DRV_NAME)) { ++ err = -EBUSY; ++ goto out3; ++ } ++ nfc_axi_base = ioremap(res->start, resource_size(res)); ++ if (nfc_axi_base == NULL) { ++ dev_err(&pdev->dev, "Failed to ioremap %08lx..%08lx\n", ++ (unsigned long)res->start, (unsigned long)res->end); ++ err = -ENOMEM; ++ goto out4; ++ } ++ mxc_nand_data->res_axi = res; ++ DBG(0, "%s: %08lx..%08lx remapped to %p\n", __FUNCTION__, ++ (unsigned long)res->start, (unsigned long)res->end, ++ nfc_axi_base); ++ mxc_nand_data->axi_base = nfc_axi_base; ++ } ++ ++ err = platform_get_irq(pdev, 0); ++ if (err < 0) { ++ dev_err(&pdev->dev, "Failed to get IRQ\n"); ++ goto out5; ++ } ++ mxc_nand_data->irq = err; ++ DBG(0, "%s: IRQ=%d\n", __FUNCTION__, mxc_nand_data->irq); ++ ++ /* init the nfc */ ++ mxc_nfc_init(mxc_nand_data); ++ ++ mxc_nand_data->dev = &pdev->dev; ++ /* structures must be linked */ ++ this = &mxc_nand_data->nand; ++ mtd = &mxc_nand_data->mtd; ++ mtd->priv = this; ++ mtd->owner = THIS_MODULE; ++ ++ this->priv = mxc_nand_data; ++ this->cmdfunc = mxc_nand_command; ++ this->select_chip = mxc_nand_select_chip; ++ this->read_byte = mxc_nand_read_byte; ++ this->read_word = mxc_nand_read_word; ++ this->write_buf = mxc_nand_write_buf; ++ this->read_buf = mxc_nand_read_buf; ++ this->verify_buf = mxc_nand_verify_buf; ++ this->scan_bbt = mxc_nand_scan_bbt; ++ ++ /* NAND bus width determines access funtions used by upper layer */ ++ if (pdata->width == 2) { ++ this->read_byte = mxc_nand_read_byte16; ++ this->options |= NAND_BUSWIDTH_16; ++ NFC_SET_NFMS(1 << NFMS_NF_DWIDTH); ++ } else { ++ NFC_SET_NFMS(0); ++ } ++ ++ clk = clk_get(&pdev->dev, "nfc_clk"); ++ if (IS_ERR(clk)) { ++ dev_err(&pdev->dev, "Failed to get nfc_clk: %ld\n", ++ PTR_ERR(clk)); ++ err = PTR_ERR(clk); ++ goto out6; ++ } ++ mxc_nand_data->clk = clk; ++ clk_enable(clk); ++ mxc_nand_data->clk_act = 1; ++ ++ init_waitqueue_head(&mxc_nand_data->irq_waitq); ++ err = request_irq(mxc_nand_data->irq, mxc_nfc_irq, 0, "mxc_nd", ++ mxc_nand_data); ++ if (err) { ++ goto out7; ++ } ++ ++ DBG(0, "%s: Init GPIOs\n", __FUNCTION__); ++ /* config the gpio */ ++ if (pdata->init) { ++ err = pdata->init(); ++ if (err) { ++ printk(KERN_ERR "%s: Failed to init GPIOs: %d\n", ++ __FUNCTION__, err); ++ goto out8; ++ } ++ } ++ ++ DBG(0, "%s: Resetting NAND chip\n", __FUNCTION__); ++ /* Reset NAND */ ++ this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1); ++ ++ /* Scan to find existence of the device */ ++ err = nand_scan_ident(mtd, 1); ++ if (err) { ++ DEBUG(MTD_DEBUG_LEVEL0, ++ "MXC_ND: Unable to find any NAND device.\n"); ++ goto out9; ++ } ++ ++ if (IS_2K_PAGE_NAND) { ++ DBG(0, "%s: Using 2k ecc layout\n", __FUNCTION__); ++ this->ecc.layout = &nand_hw_eccoob_2k; ++ } else if (IS_4K_PAGE_NAND) { ++ DBG(0, "%s: Using 4k ecc layout\n", __FUNCTION__); ++ this->ecc.layout = &nand_hw_eccoob_4k; ++ } else { ++ DBG(0, "%s: Using 512b ecc layout\n", __FUNCTION__); ++ this->ecc.layout = &nand_hw_eccoob_512; ++ } ++ if (hardware_ecc) { ++ this->ecc.read_page = mxc_nand_read_page; ++ this->ecc.write_page = mxc_nand_write_page; ++ this->ecc.read_oob = mxc_nand_read_oob; ++ this->ecc.calculate = mxc_nand_calculate_ecc; ++ this->ecc.hwctl = mxc_nand_enable_hwecc; ++ this->ecc.correct = mxc_nand_correct_data; ++ this->ecc.mode = NAND_ECC_HW; ++ this->ecc.size = 512; ++ this->ecc.bytes = 9; ++ nfc_write_reg(mxc_nand_data, ++ (nfc_read_reg(mxc_nand_data, REG_NFC_ECC_EN) | NFC_ECC_EN), ++ REG_NFC_ECC_EN); ++ } else { ++ this->ecc.mode = NAND_ECC_SOFT; ++ nfc_write_reg(mxc_nand_data, ++ (nfc_read_reg(mxc_nand_data, REG_NFC_ECC_EN) & ~NFC_ECC_EN), ++ REG_NFC_ECC_EN); ++ } ++ ++ DBG(0, "%s: Scanning for NAND devices\n", __FUNCTION__); ++ err = nand_scan_tail(mtd); ++ if (err) { ++ goto out9; ++ } ++ ++ printk(KERN_INFO "MXC NAND V2 driver %d bit bus width %s ECC with %u/%u byte\n", ++ pdata->width * 8, hardware_ecc ? "HW" : "SW", ++ this->ecc.bytes, this->ecc.size); ++ ++ /* Register the partitions */ ++#ifdef CONFIG_MTD_PARTITIONS ++ nr_parts = ++ parse_mtd_partitions(mtd, part_probes, &mxc_nand_data->parts, 0); ++ if (nr_parts > 0) ++ add_mtd_partitions(mtd, mxc_nand_data->parts, nr_parts); ++ else if (pdata->parts) ++ add_mtd_partitions(mtd, pdata->parts, pdata->nr_parts); ++ else ++#endif ++ { ++ pr_info("Registering %s as whole device\n", mtd->name); ++ add_mtd_device(mtd); ++ } ++ ++ platform_set_drvdata(pdev, mtd); ++ return 0; ++ ++ out9: ++ if (pdata->exit) ++ pdata->exit(); ++ out8: ++ free_irq(mxc_nand_data->irq, mxc_nand_data); ++ out7: ++ clk_disable(clk); ++ clk_put(clk); ++ out6: ++ mxc_free_buf(mxc_nand_data); ++ out5: ++ if (mxc_nand_data->axi_base) ++ iounmap(mxc_nand_data->axi_base); ++ out4: ++ if (mxc_nand_data->res_axi) ++ release_mem_region(mxc_nand_data->res_axi->start, ++ resource_size(mxc_nand_data->res_axi)); ++ out3: ++ iounmap(mxc_nand_data->reg_base); ++ out2: ++ release_mem_region(mxc_nand_data->res_ip->start, ++ resource_size(mxc_nand_data->res_ip)); ++ out1: ++ mxc_free_buf(mxc_nand_data); ++ out: ++ kfree(mxc_nand_data); ++ return err; ++} ++ ++ /*! ++ * Dissociates the driver from the device. ++ * ++ * @param pdev the device structure used to give information on which ++ * ++ * @return The function always returns 0. ++ */ ++ ++static int __exit mxcnd_remove(struct platform_device *pdev) ++{ ++ struct mtd_info *mtd = platform_get_drvdata(pdev); ++ struct nand_chip *nand_chip = mtd->priv; ++ struct mxc_mtd_s *mxc_nand_data = nand_chip->priv; ++ struct flash_platform_data *pdata = pdev->dev.platform_data; ++ ++ if (pdata->exit) ++ pdata->exit(); ++ ++ nand_release(mtd); ++ ++ free_irq(mxc_nand_data->irq, mxc_nand_data); ++ clk_disable(mxc_nand_data->clk); ++ clk_put(mxc_nand_data->clk); ++ ++ iounmap(mxc_nand_data->reg_base); ++ release_mem_region(mxc_nand_data->res_ip->start, ++ resource_size(mxc_nand_data->res_ip)); ++ if (mxc_nand_data->res_axi) { ++ iounmap(mxc_nand_data->axi_base); ++ release_mem_region(mxc_nand_data->res_axi->start, ++ resource_size(mxc_nand_data->res_axi)); ++ } ++ mxc_free_buf(mxc_nand_data); ++ kfree(mxc_nand_data); ++ return 0; ++} ++ ++#ifdef CONFIG_PM ++/*! ++ * This function is called to put the NAND in a low power state. Refer to the ++ * document driver-model/driver.txt in the kernel source tree for more ++ * information. ++ * ++ * @param pdev the device information structure ++ * ++ * @param state the power state the device is entering ++ * ++ * @return The function returns 0 on success and a negative errno value on failure ++ */ ++ ++static int mxcnd_suspend(struct platform_device *pdev, pm_message_t state) ++{ ++ int ret; ++ struct mtd_info *mtd = platform_get_drvdata(pdev); ++ struct nand_chip *nand_chip = mtd->priv; ++ struct mxc_mtd_s *mxc_nand_data = nand_chip->priv; ++ ++ DEBUG(MTD_DEBUG_LEVEL0, "MXC_ND2 : NAND suspend\n"); ++ ret = mtd->suspend(mtd); ++ if (ret == 0) { ++ /* Disable the NFC clock */ ++ clk_disable(mxc_nand_data->clk); ++ } ++ return ret; ++} ++ ++/*! ++ * This function is called to bring the NAND back from a low power state. Refer ++ * to the document driver-model/driver.txt in the kernel source tree for more ++ * information. ++ * ++ * @param pdev the device information structure ++ * ++ * @return The function returns 0 on success and a negative errno value on failure ++ */ ++static int mxcnd_resume(struct platform_device *pdev) ++{ ++ struct mtd_info *mtd = platform_get_drvdata(pdev); ++ struct nand_chip *nand_chip = mtd->priv; ++ struct mxc_mtd_s *mxc_nand_data = nand_chip->priv; ++ int ret = 0; ++ ++ DEBUG(MTD_DEBUG_LEVEL0, "MXC_ND2 : NAND resume\n"); ++ /* Enable the NFC clock */ ++ clk_enable(mxc_nand_data->clk); ++ ++ mtd->resume(mtd); ++ ++ return ret; ++} ++ ++#else ++#define mxcnd_suspend NULL ++#define mxcnd_resume NULL ++#endif /* CONFIG_PM */ ++ ++/*! ++ * This structure contains pointers to the power management callback functions. ++ */ ++static struct platform_driver mxcnd_driver = { ++ .driver = { ++ .name = DRV_NAME, ++ }, ++ .probe = mxcnd_probe, ++ .remove = __exit_p(mxcnd_remove), ++ .suspend = mxcnd_suspend, ++ .resume = mxcnd_resume, ++}; ++ ++/*! ++ * Main initialization routine ++ * @return 0 if successful; non-zero otherwise ++ */ ++static int __init mxc_nd_init(void) ++{ ++ int ret; ++ ++ /* Register the device driver structure. */ ++ ret = platform_driver_register(&mxcnd_driver); ++ if (ret != 0) { ++ printk(KERN_ERR "Driver register failed for mxcnd_driver\n"); ++ } ++ return ret; ++} ++ ++/*! ++ * Clean up routine ++ */ ++static void __exit mxc_nd_cleanup(void) ++{ ++ /* Unregister the device structure */ ++ platform_driver_unregister(&mxcnd_driver); ++} ++ ++module_init(mxc_nd_init); ++module_exit(mxc_nd_cleanup); ++ ++MODULE_AUTHOR("Freescale Semiconductor, Inc."); ++MODULE_DESCRIPTION("MXC NAND MTD driver Version 2-5"); ++MODULE_LICENSE("GPL"); +diff -urNp linux-2.6.30-rc4/drivers/mtd/nand/mxc_nd2.h linux-2.6.30-rc4-karo/drivers/mtd/nand/mxc_nd2.h +--- linux-2.6.30-rc4/drivers/mtd/nand/mxc_nd2.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30-rc4-karo/drivers/mtd/nand/mxc_nd2.h 2009-06-02 17:05:27.000000000 +0200 +@@ -0,0 +1,699 @@ ++/* ++ * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved. ++ */ ++ ++/* ++ * The code contained herein is licensed under the GNU General Public ++ * License. You may obtain a copy of the GNU General Public License ++ * Version 2 or later at the following locations: ++ * ++ * http://www.opensource.org/licenses/gpl-license.html ++ * http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++/*! ++ * @file mxc_nd2.h ++ * ++ * @brief This file contains the NAND Flash Controller register information. ++ * ++ * ++ * @ingroup NAND_MTD ++ */ ++ ++#ifndef __MXC_ND2_H__ ++#define __MXC_ND2_H__ ++ ++#include <mach/hardware.h> ++ ++#define IS_2K_PAGE_NAND ((mtd->writesize / num_of_interleave) \ ++ == NAND_PAGESIZE_2KB) ++#define IS_4K_PAGE_NAND ((mtd->writesize / num_of_interleave) \ ++ == NAND_PAGESIZE_4KB) ++#define IS_LARGE_PAGE_NAND ((mtd->writesize / num_of_interleave) > 512) ++ ++#define GET_NAND_OOB_SIZE (mtd->oobsize / num_of_interleave) ++ ++#define NAND_PAGESIZE_2KB 2048 ++#define NAND_PAGESIZE_4KB 4096 ++ ++#ifdef CONFIG_ARCH_MXC_HAS_NFC_V3 ++/* ++ * For V3 NFC registers Definition ++ */ ++/* AXI Bus Mapped */ ++#define NFC_AXI_BASE_ADDR NFC_BASE_ADDR_AXI ++ ++#if defined(CONFIG_ARCH_MXC_HAS_NFC_V3_1) /* mx37 */ ++#define MXC_INT_NANDFC MXC_INT_EMI ++#define NFC_FLASH_ADDR_CMD (nfc_axi_base + 0x1E00) ++#define NFC_CONFIG1 (nfc_axi_base + 0x1E04) ++#define NFC_ECC_STATUS_RESULT (nfc_axi_base + 0x1E08) ++#define LAUNCH_NFC (nfc_axi_base + 0x1E0c) ++#define NFC_WRPROT 0x00 ++#define NFC_WRPROT_UNLOCK_BLK_ADD0 0x04 ++#define NFC_CONFIG2 0x14 ++#define NFC_IPC 0x18 ++#elif defined(CONFIG_ARCH_MXC_HAS_NFC_V3_2) /* mx51 */ ++#define MXC_INT_NANDFC MXC_INT_NFC ++#define NFC_AUTO_MODE_ENABLE ++#define NFC_FLASH_CMD (nfc_axi_base + 0x1E00) ++#define NFC_FLASH_ADDR0 (nfc_axi_base + 0x1E04) ++#define NFC_FLASH_ADDR8 (nfc_axi_base + 0x1E24) ++#define NFC_CONFIG1 (nfc_axi_base + 0x1E34) ++#define NFC_ECC_STATUS_RESULT (nfc_axi_base + 0x1E38) ++#define NFC_ECC_STATUS_SUM (nfc_axi_base + 0x1E3C) ++#define LAUNCH_NFC (nfc_axi_base + 0x1E40) ++#define NFC_WRPROT 0x00 ++#define NFC_WRPROT_UNLOCK_BLK_ADD0 0x04 ++#define NFC_CONFIG2 0x24 ++#define NFC_CONFIG3 0x28 ++#define NFC_IPC 0x2C ++#else /* skye */ ++#define NFC_FLASH_ADDR_CMD (nfc_axi_base + 0xE00) ++#define NFC_CONFIG1 (nfc_axi_base + 0xE04) ++#define NFC_ECC_STATUS_RESULT (nfc_axi_base + 0xE08) ++#define LAUNCH_NFC (nfc_axi_base + 0xE0C) ++#define NFC_WRPROT 0x00 ++#define NFC_WRPROT_UNLOCK_BLK_ADD0 0x04 ++#define NFC_CONFIG2 0x14 ++#define NFC_IPC 0x18 ++#endif /* CONFIG_ARCH_MXC_HAS_NFC_V3_1 */ ++/*! ++ * Addresses for NFC RAM BUFFER Main area 0 ++ */ ++#define MAIN_AREA0 ((u16 *)(nfc_axi_base + 0x000)) ++#define MAIN_AREA1 ((u16 *)(nfc_axi_base + 0x200)) ++ ++/*! ++ * Addresses for NFC SPARE BUFFER Spare area 0 ++ */ ++#if defined(CONFIG_ARCH_MXC_HAS_NFC_V3_1) || \ ++ defined(CONFIG_ARCH_MXC_HAS_NFC_V3_2) ++#define SPARE_AREA0 ((u16 *)(nfc_axi_base + 0x1000)) ++#define SPARE_LEN 64 ++#define SPARE_COUNT 8 ++#define SPARE_SIZE (SPARE_LEN * SPARE_COUNT) ++#else ++#define SPARE_AREA0 ((u16 *)(nfc_axi_base + 0x800)) ++#define SPARE_LEN 16 ++#define SPARE_COUNT 4 ++#define SPARE_SIZE (SPARE_LEN * SPARE_COUNT) ++#endif /* CONFIG_ARCH_MXC_HAS_NFC_V3_1 */ ++ ++#if defined(CONFIG_ARCH_MXC_HAS_NFC_V3_1) || \ ++ defined(CONFIG_ARCH_MXC_HAS_NFC_V3_2) ++#define NFC_SPAS_WIDTH 8 ++#define NFC_SPAS_SHIFT 16 ++ ++#define IS_4BIT_ECC \ ++( \ ++ cpu_is_mx51_rev(CHIP_REV_2_0) == 1 ? \ ++ !((raw_read(NFC_CONFIG2) & NFC_ECC_MODE_4) >> 6) : \ ++ ((raw_read(NFC_CONFIG2) & NFC_ECC_MODE_4) >> 6) \ ++) ++ ++#define NFC_SET_SPAS(v) \ ++ raw_write((((raw_read(NFC_CONFIG2) & \ ++ NFC_FIELD_RESET(NFC_SPAS_WIDTH, NFC_SPAS_SHIFT)) | ((v) << 16))), \ ++ NFC_CONFIG2) ++ ++#define NFC_SET_ECC_MODE(v) \ ++do { \ ++ if (cpu_is_mx51_rev(CHIP_REV_2_0) == 1) { \ ++ if ((v) == NFC_SPAS_218 || (v) == NFC_SPAS_112) \ ++ raw_write(((raw_read(NFC_CONFIG2) & \ ++ NFC_ECC_MODE_MASK) | \ ++ NFC_ECC_MODE_4), NFC_CONFIG2); \ ++ else \ ++ raw_write(((raw_read(NFC_CONFIG2) & \ ++ NFC_ECC_MODE_MASK) & \ ++ ~NFC_ECC_MODE_4), NFC_CONFIG2); \ ++ } else { \ ++ if ((v) == NFC_SPAS_218 || (v) == NFC_SPAS_112) \ ++ raw_write(((raw_read(NFC_CONFIG2) & \ ++ NFC_ECC_MODE_MASK) & \ ++ ~NFC_ECC_MODE_4), NFC_CONFIG2); \ ++ else \ ++ raw_write(((raw_read(NFC_CONFIG2) & \ ++ NFC_ECC_MODE_MASK) | \ ++ NFC_ECC_MODE_4), NFC_CONFIG2); \ ++ } \ ++} while (0) ++ ++#define WRITE_NFC_IP_REG(val,reg) \ ++ do { \ ++ nfc_write_reg(mxc_nand_data, NFC_IPC_CREQ, NFC_IPC); \ ++ while (!(nfc_read_reg(mxc_nand_data, NFC_IPC) & NFC_IPC_ACK)); \ ++ nfc_write_reg(mxc_nand_data, val, reg); \ ++ nfc_write_reg(mxc_nand_data, 0, NFC_IPC); \ ++ } while(0) ++#else ++#define IS_4BIT_ECC 1 ++#define NFC_SET_SPAS(v) ++#define NFC_SET_ECC_MODE(v) ++#define NFC_SET_NFMS(v) (NFMS |= (v)) ++ ++#define WRITE_NFC_IP_REG(val,reg) \ ++ nfc_write_reg(mxc_nand_data, val, REG_NFC_OPS_STAT) ++#endif /* CONFIG_ARCH_MXC_HAS_NFC_V3_1 */ ++ ++#define GET_NFC_ECC_STATUS() nfc_read_reg(mxc_nand_data, REG_NFC_ECC_STATUS_RESULT); ++ ++/*! ++ * Set 1 to specific operation bit, rest to 0 in LAUNCH_NFC Register for ++ * Specific operation ++ */ ++#define NFC_CMD 0x1 ++#define NFC_ADDR 0x2 ++#define NFC_INPUT 0x4 ++#define NFC_OUTPUT 0x8 ++#define NFC_ID 0x10 ++#define NFC_STATUS 0x20 ++ ++#ifdef CONFIG_ARCH_MXC_HAS_NFC_V3_2 /* mx51 */ ++#define NFC_AUTO_PROG 0x40 ++#define NFC_AUTO_READ 0x80 ++#define NFC_AUTO_ERASE 0x200 ++#define NFC_COPY_BACK_0 0x400 ++#define NFC_COPY_BACK_1 0x800 ++#define NFC_AUTO_STATE 0x1000 ++#endif /* CONFIG_ARCH_MXC_HAS_NFC_V3_2 */ ++ ++/* Bit Definitions for NFC_IPC*/ ++#define NFC_OPS_STAT (1 << 31) ++ ++#ifdef CONFIG_ARCH_MXC_HAS_NFC_V3_2 /* mx51 */ ++#define NFC_OP_DONE (1 << 30) ++#define NFC_RB (1 << 28) ++#define NFC_PS_WIDTH 2 ++#define NFC_PS_SHIFT 0 ++#define NFC_PS_512 0 ++#define NFC_PS_2K 1 ++#define NFC_PS_4K 2 ++#else ++#define NFC_RB (1 << 29) ++#endif /* CONFIG_ARCH_MXC_HAS_NFC_V3_2 */ ++ ++#define NFC_ONE_CYCLE (1 << 2) ++ ++#ifdef CONFIG_ARCH_MXC_HAS_NFC_V3_2 /* mx51 */ ++#define NFC_INT_MSK (1 << 15) ++#define NFC_AUTO_PROG_DONE_MSK (1 << 14) ++#define NFC_NUM_ADDR_PHASE1_WIDTH 2 ++#define NFC_NUM_ADDR_PHASE1_SHIFT 12 ++ ++#define NFC_NUM_ADDR_PHASE0_WIDTH 1 ++#define NFC_NUM_ADDR_PHASE0_SHIFT 5 ++ ++#define NFC_ONE_LESS_PHASE1 0 ++#define NFC_TWO_LESS_PHASE1 1 ++ ++#define NFC_FLASH_ADDR_SHIFT 0 ++#else ++#define NFC_INT_MSK (1 << 4) ++#define NFC_BIG (1 << 5) ++#define NFC_FLASH_ADDR_SHIFT 16 ++#endif /* CONFIG_ARCH_MXC_HAS_NFC_V3_2 */ ++ ++#define NFC_UNLOCK_END_ADDR_SHIFT 16 ++ ++/* Bit definition for NFC_CONFIGRATION_1 */ ++#define NFC_SP_EN (1 << 0) ++#define NFC_CE (1 << 1) ++#define NFC_RST (1 << 2) ++#define NFC_ECC_EN (1 << 3) ++ ++#define NFC_FIELD_RESET(width, shift) ~(((1 << (width)) - 1) << (shift)) ++ ++#define NFC_RBA_SHIFT 4 ++ ++#if defined(CONFIG_ARCH_MXC_HAS_NFC_V3_1) || \ ++ defined(CONFIG_ARCH_MXC_HAS_NFC_V3_2) /* mx51 */ ++#define NFC_RBA_WIDTH 3 ++#else ++#define NFC_RBA_WIDTH 2 ++#endif /* CONFIG_ARCH_MXC_HAS_NFC_V3_1 */ ++ ++#if defined(CONFIG_ARCH_MXC_HAS_NFC_V3_2) /* mx51 */ ++#define NFC_ITERATION_SHIFT 8 ++#define NFC_ITERATION_WIDTH 4 ++#define NFC_ACTIVE_CS_SHIFT 12 ++#define NFC_ACTIVE_CS_WIDTH 3 ++/* bit definition for CONFIGRATION3 */ ++#define NFC_NO_SDMA (1 << 20) ++#define NFC_FMP_SHIFT 16 ++#define NFC_FMP_WIDTH 4 ++#define NFC_RBB_MODE (1 << 15) ++#define NFC_NUM_OF_DEVICES_SHIFT 12 ++#define NFC_NUM_OF_DEVICES_WIDTH 4 ++#define NFC_DMA_MODE_SHIFT 11 ++#define NFC_DMA_MODE_WIDTH 1 ++#define NFC_SBB_SHIFT 8 ++#define NFC_SBB_WIDTH 3 ++#define NFC_BIG (1 << 7) ++#define NFC_SB2R_SHIFT 4 ++#define NFC_SB2R_WIDTH 3 ++#define NFC_FW_SHIFT 3 ++#define NFC_FW_WIDTH 1 ++#define NFC_TOO (1 << 2) ++#define NFC_ADD_OP_SHIFT 0 ++#define NFC_ADD_OP_WIDTH 2 ++#define NFC_FW_8 1 ++#define NFC_FW_16 0 ++#define NFC_ST_CMD_SHITF 24 ++#define NFC_ST_CMD_WIDTH 8 ++#endif /* CONFIG_ARCH_MXC_HAS_NFC_V3_2 */ ++ ++#define NFC_PPB_32 (0 << 7) ++#define NFC_PPB_64 (1 << 7) ++#define NFC_PPB_128 (2 << 7) ++#define NFC_PPB_256 (3 << 7) ++#define NFC_PPB_RESET ~(3 << 7) ++ ++#define NFC_BLS_LOCKED (0 << 16) ++#define NFC_BLS_LOCKED_DEFAULT (1 << 16) ++#define NFC_BLS_UNLOCKED (2 << 16) ++#define NFC_BLS_RESET ~(3 << 16) ++#define NFC_WPC_LOCK_TIGHT 1 ++#define NFC_WPC_LOCK (1 << 1) ++#define NFC_WPC_UNLOCK (1 << 2) ++#define NFC_WPC_RESET ~7 ++#if defined(CONFIG_ARCH_MXC_HAS_NFC_V3_1) || \ ++ defined(CONFIG_ARCH_MXC_HAS_NFC_V3_2) ++#define NFC_ECC_MODE_4 (1 << 6) ++#define NFC_ECC_MODE_MASK ~(1 << 6) ++#define NFC_SPAS_16 8 ++#define NFC_SPAS_64 32 ++#define NFC_SPAS_128 64 ++#define NFC_SPAS_112 56 ++#define NFC_SPAS_218 109 ++#define NFC_IPC_CREQ (1 << 0) ++#define NFC_IPC_ACK (1 << 1) ++#endif /* CONFIG_ARCH_MXC_HAS_NFC_V3_1 */ ++ ++#define REG_NFC_OPS_STAT NFC_IPC ++#define REG_NFC_INTERRUPT NFC_CONFIG2 ++#ifdef CONFIG_ARCH_MXC_HAS_NFC_V3_2 ++#define REG_NFC_FLASH_ADDR NFC_FLASH_ADDR0 ++#define REG_NFC_FLASH_CMD NFC_FLASH_CMD ++#else ++#define REG_NFC_FLASH_ADDR NFC_FLASH_ADDR_CMD ++#define REG_NFC_FLASH_CMD NFC_FLASH_ADDR_CMD ++#endif /* CONFIG_ARCH_MXC_HAS_NFC_V3_2 */ ++#define REG_NFC_OPS LAUNCH_NFC ++#define REG_NFC_SET_RBA NFC_CONFIG1 ++#define REG_NFC_RB NFC_IPC ++#define REG_NFC_ECC_EN NFC_CONFIG2 ++#define REG_NFC_ECC_STATUS_RESULT NFC_ECC_STATUS_RESULT ++#define REG_NFC_CE NFC_CONFIG1 ++#define REG_NFC_RST NFC_CONFIG1 ++#define REG_NFC_PPB NFC_CONFIG2 ++#define REG_NFC_SP_EN NFC_CONFIG1 ++#define REG_NFC_BLS NFC_WRPROT ++#define REG_UNLOCK_BLK_ADD0 NFC_WRPROT_UNLOCK_BLK_ADD0 ++#define REG_UNLOCK_BLK_ADD1 NFC_WRPROT_UNLOCK_BLK_ADD1 ++#define REG_UNLOCK_BLK_ADD2 NFC_WRPROT_UNLOCK_BLK_ADD2 ++#define REG_UNLOCK_BLK_ADD3 NFC_WRPROT_UNLOCK_BLK_ADD3 ++#define REG_NFC_WPC NFC_WRPROT ++#define REG_NFC_ONE_CYCLE NFC_CONFIG2 ++ ++/* NFC V3 Specific MACRO function definitions */ ++#define raw_write(v,a) __raw_writel(v,a) ++#define raw_read(a) __raw_readl(a) ++ ++/* Explicitly ack ops status (if any), before issuing any command */ ++#define ACK_OPS \ ++ nfc_write_reg(mxc_nand_data, \ ++ (nfc_read_reg(mxc_nand_data, REG_NFC_OPS_STAT) & ~NFC_OPS_STAT), \ ++ REG_NFC_OPS_STAT) ++ ++/* Set RBA buffer id*/ ++#define NFC_SET_RBA(val) \ ++ nfc_write_reg(mxc_nand_data, \ ++ (nfc_read_reg(mxc_nand_data, REG_NFC_SET_RBA) & \ ++ (NFC_FIELD_RESET(NFC_RBA_WIDTH, NFC_RBA_SHIFT))) | \ ++ ((val) << NFC_RBA_SHIFT), REG_NFC_SET_RBA) ++ ++#define NFC_SET_PS(val) \ ++ nfc_write_reg(mxc_nand_data, \ ++ (nfc_read_reg(mxc_nand_data, NFC_CONFIG2) & \ ++ (NFC_FIELD_RESET(NFC_PS_WIDTH, NFC_PS_SHIFT))) | \ ++ ((val) << NFC_PS_SHIFT), NFC_CONFIG2) ++ ++#ifdef CONFIG_ARCH_MXC_HAS_NFC_V3_2 ++#define UNLOCK_ADDR(start_addr,end_addr) \ ++{ \ ++ int i = 0; \ ++ for (; i < NAND_MAX_CHIPS; i++) \ ++ nfc_write_reg(mxc_nand_data, start_addr | \ ++ (end_addr << NFC_UNLOCK_END_ADDR_SHIFT), \ ++ REG_UNLOCK_BLK_ADD0 + (i << 2)); \ ++} ++ ++#define NFC_SET_NFC_ACTIVE_CS(val) \ ++ nfc_write_reg(mxc_nand_data, (nfc_read_reg(mxc_nand_data, NFC_CONFIG1) & \ ++ (NFC_FIELD_RESET(NFC_ACTIVE_CS_WIDTH, NFC_ACTIVE_CS_SHIFT))) | \ ++ ((val) << NFC_ACTIVE_CS_SHIFT), NFC_CONFIG1) ++ ++#define NFC_GET_MAXCHIP_SP() 8 ++ ++#else ++#define UNLOCK_ADDR(start_addr,end_addr) \ ++ nfc_write_reg(mxc_nand_data, start_addr | \ ++ (end_addr << NFC_UNLOCK_END_ADDR_SHIFT), REG_UNLOCK_BLK_ADD0) ++ ++#define NFC_SET_NFC_ACTIVE_CS(val) ++#define NFC_GET_MAXCHIP_SP() 1 ++#endif /* CONFIG_ARCH_MXC_HAS_NFC_V3_2 */ ++ ++#define NFC_SET_BLS(val) ((nfc_read_reg(mxc_nand_data, REG_NFC_BLS) & NFC_BLS_RESET) | val) ++#define NFC_SET_WPC(val) ((nfc_read_reg(mxc_nand_data, REG_NFC_WPC) & NFC_WPC_RESET) | val) ++#define CHECK_NFC_RB nfc_read_reg(mxc_nand_data, REG_NFC_RB) & NFC_RB ++ ++#if defined(CONFIG_ARCH_MXC_HAS_NFC_V3_2) ++#define NFC_SET_NFC_NUM_ADDR_PHASE1(val) \ ++ nfc_write_reg(mxc_nand_data, (nfc_read_reg(mxc_nand_data, NFC_CONFIG2) & \ ++ (NFC_FIELD_RESET(NFC_NUM_ADDR_PHASE1_WIDTH, \ ++ NFC_NUM_ADDR_PHASE1_SHIFT))) | \ ++ ((val) << NFC_NUM_ADDR_PHASE1_SHIFT), NFC_CONFIG2); ++ ++#define NFC_SET_NFC_NUM_ADDR_PHASE0(val) \ ++ nfc_write_reg(mxc_nand_data, (nfc_read_reg(mxc_nand_data, NFC_CONFIG2) & \ ++ (NFC_FIELD_RESET(NFC_NUM_ADDR_PHASE0_WIDTH, \ ++ NFC_NUM_ADDR_PHASE0_SHIFT))) | \ ++ ((val) << NFC_NUM_ADDR_PHASE0_SHIFT), NFC_CONFIG2); ++ ++#define NFC_SET_NFC_ITERATION(val) \ ++ nfc_write_reg(mxc_nand_data, (nfc_read_reg(mxc_nand_data, NFC_CONFIG1) & \ ++ (NFC_FIELD_RESET(NFC_ITERATION_WIDTH, NFC_ITERATION_SHIFT))) | \ ++ ((val) << NFC_ITERATION_SHIFT), NFC_CONFIG1); ++ ++#define NFC_SET_FW(val) \ ++ nfc_write_reg(mxc_nand_data, (nfc_read_reg(mxc_nand_data, NFC_CONFIG3) & \ ++ (NFC_FIELD_RESET(NFC_FW_WIDTH, NFC_FW_SHIFT))) | \ ++ ((val) << NFC_FW_SHIFT), NFC_CONFIG3); ++ ++#define NFC_SET_NUM_OF_DEVICE(val) \ ++ nfc_write_reg(mxc_nand_data, (nfc_read_reg(mxc_nand_data, NFC_CONFIG3) & \ ++ (NFC_FIELD_RESET(NFC_NUM_OF_DEVICES_WIDTH, \ ++ NFC_NUM_OF_DEVICES_SHIFT))) | \ ++ ((val) << NFC_NUM_OF_DEVICES_SHIFT), NFC_CONFIG3); ++ ++#define NFC_SET_ADD_OP_MODE(val) \ ++ nfc_write_reg(mxc_nand_data, (nfc_read_reg(mxc_nand_data, NFC_CONFIG3) & \ ++ (NFC_FIELD_RESET(NFC_ADD_OP_WIDTH, NFC_ADD_OP_SHIFT))) | \ ++ ((val) << NFC_ADD_OP_SHIFT), NFC_CONFIG3); ++ ++#define NFC_SET_ADD_CS_MODE(val) \ ++{ \ ++ NFC_SET_ADD_OP_MODE(val); \ ++ NFC_SET_NUM_OF_DEVICE(this->numchips - 1); \ ++} ++ ++#define NFC_SET_ST_CMD(val) \ ++ nfc_write_reg((raw_read(NFC_CONFIG2) & \ ++ (NFC_FIELD_RESET(NFC_ST_CMD_WIDTH, \ ++ NFC_ST_CMD_SHITF))) | \ ++ ((val) << NFC_ST_CMD_SHITF), NFC_CONFIG2); ++ ++#define NFMS_NF_DWIDTH 0 ++#define NFMS_NF_PG_SZ 1 ++#define NFC_CMD_1_SHIFT 8 ++ ++#define NUM_OF_ADDR_CYCLE (fls(g_page_mask) >> 3) ++ ++/*should set the fw,ps,spas,ppb*/ ++#define NFC_SET_NFMS(v) \ ++do { \ ++ NFC_SET_FW(NFC_FW_8); \ ++ if (((v) & (1 << NFMS_NF_DWIDTH))) \ ++ NFC_SET_FW(NFC_FW_16); \ ++ if (((v) & (1 << NFMS_NF_PG_SZ))) { \ ++ if (IS_2K_PAGE_NAND) { \ ++ NFC_SET_PS(NFC_PS_2K); \ ++ NFC_SET_NFC_NUM_ADDR_PHASE1(NUM_OF_ADDR_CYCLE); \ ++ NFC_SET_NFC_NUM_ADDR_PHASE0(NFC_TWO_LESS_PHASE1); \ ++ } else if (IS_4K_PAGE_NAND) { \ ++ NFC_SET_PS(NFC_PS_4K); \ ++ NFC_SET_NFC_NUM_ADDR_PHASE1(NUM_OF_ADDR_CYCLE); \ ++ NFC_SET_NFC_NUM_ADDR_PHASE0(NFC_TWO_LESS_PHASE1); \ ++ } else { \ ++ NFC_SET_PS(NFC_PS_512); \ ++ NFC_SET_NFC_NUM_ADDR_PHASE1(NUM_OF_ADDR_CYCLE - 1); \ ++ NFC_SET_NFC_NUM_ADDR_PHASE0(NFC_ONE_LESS_PHASE1); \ ++ } \ ++ NFC_SET_ADD_CS_MODE(1); \ ++ NFC_SET_SPAS(GET_NAND_OOB_SIZE >> 1); \ ++ NFC_SET_ECC_MODE(GET_NAND_OOB_SIZE >> 1); \ ++ NFC_SET_ST_CMD(0x70); \ ++ nfc_write_reg(raw_read(NFC_CONFIG3) | 1 << 20, NFC_CONFIG3); \ ++ } \ ++} while (0) ++#endif /* CONFIG_ARCH_MXC_HAS_NFC_V3_2 */ ++ ++#ifdef CONFIG_ARCH_MXC_HAS_NFC_V3_1 ++#define NFC_SET_NFMS(v) ++#endif /* CONFIG_ARCH_MXC_HAS_NFC_V3_1 */ ++ ++#define READ_PAGE(c) send_read_page(c,0) ++#define PROG_PAGE(c) send_prog_page(c,0) ++ ++#elif CONFIG_ARCH_MXC_HAS_NFC_V2 ++ ++/* ++ * For V1/V2 NFC registers Definition ++ */ ++ ++#define NFC_AXI_BASE_ADDR 0x00 ++/* ++ * Addresses for NFC registers ++ */ ++#ifdef CONFIG_ARCH_MXC_HAS_NFC_V2_1 ++#define NFC_REG_BASE 0x1000 ++#else ++#define NFC_REG_BASE 0x0000 ++#endif /* CONFIG_ARCH_MXC_HAS_NFC_V2_1 */ ++#define NFC_BUF_SIZE (NFC_REG_BASE + 0xE00) ++#define NFC_BUF_ADDR (NFC_REG_BASE + 0xE04) ++#define NFC_FLASH_ADDR (NFC_REG_BASE + 0xE06) ++#define NFC_FLASH_CMD (NFC_REG_BASE + 0xE08) ++#define NFC_CONFIG (NFC_REG_BASE + 0xE0A) ++#ifdef CONFIG_ARCH_MXC_HAS_NFC_V2_1 ++#define NFC_ECC_STATUS_RESULT (NFC_REG_BASE + 0xE0C) ++#define NFC_ECC_STATUS_RESULT_1 (NFC_REG_BASE + 0xE0C) ++#define NFC_ECC_STATUS_RESULT_2 (NFC_REG_BASE + 0xE0E) ++#define NFC_SPAS (NFC_REG_BASE + 0xE10) ++#else ++#define NFC_ECC_STATUS_RESULT (NFC_REG_BASE + 0xE0C) ++#define NFC_RSLTMAIN_AREA (NFC_REG_BASE + 0xE0E) ++#define NFC_RSLTSPARE_AREA (NFC_REG_BASE + 0xE10) ++#endif /* CONFIG_ARCH_MXC_HAS_NFC_V2_1 */ ++#define NFC_WRPROT (NFC_REG_BASE + 0xE12) ++#ifdef CONFIG_ARCH_MXC_HAS_NFC_V2_1 ++#define NFC_UNLOCKSTART_BLKADDR (NFC_REG_BASE + 0xE20) ++#define NFC_UNLOCKEND_BLKADDR (NFC_REG_BASE + 0xE22) ++#define NFC_UNLOCKSTART_BLKADDR1 (NFC_REG_BASE + 0xE24) ++#define NFC_UNLOCKEND_BLKADDR1 (NFC_REG_BASE + 0xE26) ++#define NFC_UNLOCKSTART_BLKADDR2 (NFC_REG_BASE + 0xE28) ++#define NFC_UNLOCKEND_BLKADDR2 (NFC_REG_BASE + 0xE2A) ++#define NFC_UNLOCKSTART_BLKADDR3 (NFC_REG_BASE + 0xE2C) ++#define NFC_UNLOCKEND_BLKADDR3 (NFC_REG_BASE + 0xE2E) ++#else ++#define NFC_UNLOCKSTART_BLKADDR (NFC_REG_BASE + 0xE14) ++#define NFC_UNLOCKEND_BLKADDR (NFC_REG_BASE + 0xE16) ++#endif /* CONFIG_ARCH_MXC_HAS_NFC_V2_1 */ ++#define NFC_NF_WRPRST (NFC_REG_BASE + 0xE18) ++#define NFC_CONFIG1 (NFC_REG_BASE + 0xE1A) ++#define NFC_CONFIG2 (NFC_REG_BASE + 0xE1C) ++ ++/*! ++ * Addresses for NFC RAM BUFFER Main area 0 ++ */ ++#define MAIN_AREA0 0x000 ++#define MAIN_AREA1 0x200 ++ ++/*! ++ * Addresses for NFC SPARE BUFFER Spare area 0 ++ */ ++#ifdef CONFIG_ARCH_MXC_HAS_NFC_V2_1 ++#define SPARE_AREA0 0x1000 ++#define SPARE_LEN 64 ++#define SPARE_COUNT 8 ++#else ++#define SPARE_AREA0 0x800 ++#define SPARE_LEN 16 ++#define SPARE_COUNT 4 ++#endif /* CONFIG_ARCH_MXC_HAS_NFC_V2_1 */ ++#define SPARE_SIZE (SPARE_LEN * SPARE_COUNT) ++ ++#ifdef CONFIG_ARCH_MXC_HAS_NFC_V2_1 ++#define REG_NFC_ECC_MODE NFC_CONFIG1 ++#define SPAS_SHIFT 0 ++#define REG_NFC_SPAS NFC_SPAS ++#define SPAS_MASK 0xFF00 ++#define IS_4BIT_ECC \ ++ (!!(nfc_read_reg(mxc_nand_data, REG_NFC_ECC_MODE) & NFC_ECC_MODE_4)) ++ ++#define NFC_SET_SPAS(v) \ ++ nfc_write_reg(mxc_nand_data, \ ++ ((nfc_read_reg(mxc_nand_data, REG_NFC_SPAS) & SPAS_MASK) | \ ++ (((v) << SPAS_SHIFT))), \ ++ REG_NFC_SPAS) ++ ++#define NFC_SET_ECC_MODE(v) \ ++do { \ ++ if ((v) == NFC_SPAS_218) { \ ++ nfc_write_reg(mxc_nand_data, \ ++ (nfc_read_reg(mxc_nand_data, REG_NFC_ECC_MODE) & ~NFC_ECC_MODE_4),\ ++ REG_NFC_ECC_MODE); \ ++ } else { \ ++ nfc_write_reg(mxc_nand_data, \ ++ (nfc_read_reg(mxc_nand_data, REG_NFC_ECC_MODE) | NFC_ECC_MODE_4), \ ++ REG_NFC_ECC_MODE); \ ++ } \ ++} while (0) ++ ++#define NFC_SET_NFMS(v) \ ++do { \ ++ DBG(0, "Setting NFMS[%p:%08lx] to %08x | %08x\n", NFMS_REG, \ ++ MXC_PHYS_ADDRESS(NFMS_REG), __raw_readl(NFMS_REG), v); \ ++ __raw_writel(__raw_readl(NFMS_REG) | (v), NFMS_REG); \ ++ if (((v) & (1 << NFMS_NF_PG_SZ))) { \ ++ NFC_SET_SPAS(GET_NAND_OOB_SIZE >> 1); \ ++ NFC_SET_ECC_MODE(GET_NAND_OOB_SIZE >> 1); \ ++ } \ ++} while (0) ++#else ++#define IS_4BIT_ECC 1 ++#define NFC_SET_SPAS(v) ++#define NFC_SET_ECC_MODE(v) ++#define NFC_SET_NFMS(v) (NFMS |= (v)) ++#endif /* CONFIG_ARCH_MXC_HAS_NFC_V2_1 */ ++ ++#define WRITE_NFC_IP_REG(val,reg) \ ++ nfc_write_reg(mxc_nand_data, val, REG_NFC_OPS_STAT) ++ ++#define GET_NFC_ECC_STATUS() nfc_read_reg(mxc_nand_data, REG_NFC_ECC_STATUS_RESULT) ++ ++/*! ++ * Set INT to 0, Set 1 to specific operation bit, rest to 0 in NFC_CONFIG2 Register for ++ * Specific operation ++ */ ++#define NFC_CMD 0x1 ++#define NFC_ADDR 0x2 ++#define NFC_INPUT 0x4 ++#define NFC_OUTPUT 0x8 ++#define NFC_ID 0x10 ++#define NFC_STATUS 0x20 ++ ++/* Bit Definitions */ ++#define NFC_OPS_STAT (1 << 15) ++#define NFC_SP_EN (1 << 2) ++#define NFC_ECC_EN (1 << 3) ++#define NFC_INT_MSK (1 << 4) ++#define NFC_BIG (1 << 5) ++#define NFC_RST (1 << 6) ++#define NFC_CE (1 << 7) ++#define NFC_ONE_CYCLE (1 << 8) ++#define NFC_BLS_LOCKED 0 ++#define NFC_BLS_LOCKED_DEFAULT 1 ++#define NFC_BLS_UNLOCKED 2 ++#define NFC_WPC_LOCK_TIGHT (1 << 0) ++#define NFC_WPC_LOCK (1 << 1) ++#define NFC_WPC_UNLOCK (1 << 2) ++#define NFC_FLASH_ADDR_SHIFT 0 ++#define NFC_UNLOCK_END_ADDR_SHIFT 0 ++ ++#ifdef CONFIG_ARCH_MXC_HAS_NFC_V2_1 ++#define NFC_ECC_MODE_4 (1 << 0) ++#define NFC_SPAS_16 8 ++#define NFC_SPAS_64 32 ++#define NFC_SPAS_112 56 ++#define NFC_SPAS_128 64 ++#define NFC_SPAS_218 109 ++#endif /* CONFIG_ARCH_MXC_HAS_NFC_V2_1 */ ++/* NFC Register Mapping */ ++#define REG_NFC_OPS_STAT NFC_CONFIG2 ++#define REG_NFC_INTERRUPT NFC_CONFIG1 ++#define REG_NFC_FLASH_ADDR NFC_FLASH_ADDR ++#define REG_NFC_FLASH_CMD NFC_FLASH_CMD ++#define REG_NFC_OPS NFC_CONFIG2 ++#define REG_NFC_SET_RBA NFC_BUF_ADDR ++#define REG_NFC_ECC_EN NFC_CONFIG1 ++#define REG_NFC_ECC_STATUS_RESULT NFC_ECC_STATUS_RESULT ++#define REG_NFC_CE NFC_CONFIG1 ++#define REG_NFC_SP_EN NFC_CONFIG1 ++#define REG_NFC_BLS NFC_CONFIG ++#define REG_NFC_WPC NFC_WRPROT ++#define REG_START_BLKADDR NFC_UNLOCKSTART_BLKADDR ++#define REG_END_BLKADDR NFC_UNLOCKEND_BLKADDR ++#define REG_NFC_RST NFC_CONFIG1 ++#define REG_NFC_ONE_CYCLE NFC_CONFIG1 ++ ++/* NFC V1/V2 Specific MACRO functions definitions */ ++ ++#if defined(CONFIG_MTD_DEBUG) ++#define nfc_write_reg(c, v, r) __nfc_reg_write(v, (c)->reg_base + r, #r, __FUNCTION__) ++static inline void __nfc_reg_write(u16 val, void __iomem *addr, ++ const char *reg, const char *fn) ++{ ++ DBG(3, "%s: Writing %04x to %s[%04lx]\n", fn, val, reg, ++ (unsigned long)addr & 0x1fff); ++ __raw_writew(val, addr); ++} ++ ++#define nfc_read_reg(c, r) __nfc_reg_read((c)->reg_base + r, #r, __FUNCTION__) ++static inline u16 __nfc_reg_read(void __iomem *addr, ++ const char *reg, const char *fn) ++{ ++ u16 val; ++ val = __raw_readw(addr); ++ DBG(3, "%s: Read %04x from %s[%04lx]\n", fn, val, reg, ++ (unsigned long)addr & 0x1fff); ++ return val; ++} ++#else ++#define nfc_read_reg(c, r) __raw_readw((c)->reg_base + r) ++#define nfc_write_reg(c, v, r) __raw_writew(v, (c)->reg_base + r) ++#endif /* CONFIG_MTD_DEBUG */ ++ ++#define NFC_SET_BLS(val) (val) ++ ++#define UNLOCK_ADDR(start_addr,end_addr) \ ++{ \ ++ nfc_write_reg(mxc_nand_data, start_addr,REG_START_BLKADDR); \ ++ nfc_write_reg(mxc_nand_data, end_addr,REG_END_BLKADDR); \ ++} ++ ++#define NFC_SET_NFC_ACTIVE_CS(val) ++#define NFC_GET_MAXCHIP_SP() 1 ++#define NFC_SET_WPC(val) (val) ++ ++#define ACK_OPS ++#define NFC_SET_RBA(val) nfc_write_reg(mxc_nand_data, val, REG_NFC_SET_RBA); ++ ++#ifdef CONFIG_ARCH_MXC_HAS_NFC_V2_1 ++#define READ_PAGE(c) send_read_page(c,0) ++#define PROG_PAGE(c) send_prog_page(c,0) ++#else ++#define READ_PAGE(c) \ ++do { \ ++ send_read_page(c,0); \ ++ send_read_page(c,1); \ ++ send_read_page(c,2); \ ++ send_read_page(c,3); \ ++} while (0) ++ ++#define PROG_PAGE(c) \ ++do { \ ++ send_prog_page(c,0); \ ++ send_prog_page(c,1); \ ++ send_prog_page(c,2); \ ++ send_prog_page(c,3); \ ++} while (0) ++#endif /* CONFIG_ARCH_MXC_HAS_NFC_V2_1 */ ++#define CHECK_NFC_RB 1 ++ ++#endif /* CONFIG_ARCH_MXC_HAS_NFC_V3 */ ++ ++#endif /* __MXC_ND2_H__ */ +diff -urNp linux-2.6.30-rc4/drivers/net/Kconfig linux-2.6.30-rc4-karo/drivers/net/Kconfig +--- linux-2.6.30-rc4/drivers/net/Kconfig 2009-05-13 09:46:19.000000000 +0200 ++++ linux-2.6.30-rc4-karo/drivers/net/Kconfig 2009-06-02 17:05:27.000000000 +0200 +@@ -1859,7 +1859,7 @@ config 68360_ENET + + config FEC + bool "FEC ethernet controller (of ColdFire CPUs)" +- depends on M523x || M527x || M5272 || M528x || M520x || M532x || MACH_MX27 ++ depends on M523x || M527x || M5272 || M528x || M520x || M532x || MACH_MX27 || MACH_TX25 + help + Say Y here if you want to use the built-in 10/100 Fast ethernet + controller on some Motorola ColdFire and Freescale i.MX processors. +diff -urNp linux-2.6.30-rc4/drivers/net/fec.c linux-2.6.30-rc4-karo/drivers/net/fec.c +--- linux-2.6.30-rc4/drivers/net/fec.c 2009-05-13 09:46:19.000000000 +0200 ++++ linux-2.6.30-rc4-karo/drivers/net/fec.c 2009-06-02 17:05:27.000000000 +0200 +@@ -2,6 +2,12 @@ + * Fast Ethernet Controller (FEC) driver for Motorola MPC8xx. + * Copyright (c) 1997 Dan Malek (dmalek@jlc.net) + * ++ * This version of the driver is specific to the FADS implementation, ++ * since the board contains control registers external to the processor ++ * for the control of the LevelOne LXT970 transceiver. The MPC860T manual ++ * describes connections using the internal parallel port I/O, which ++ * is basically all of Port D. ++ * + * Right now, I am very wasteful with the buffers. I allocate memory + * pages and then divide them into 2K frame buffers. This way I know I + * have buffers large enough to hold one frame within one buffer descriptor. +@@ -18,77 +24,123 @@ + * Bug fixes and cleanup by Philippe De Muyter (phdm@macqel.be) + * Copyright (c) 2004-2006 Macq Electronique SA. + */ ++/* ++ * Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved. ++ */ + + #include <linux/module.h> + #include <linux/kernel.h> +-#include <linux/string.h> +-#include <linux/ptrace.h> ++#include <linux/resource.h> + #include <linux/errno.h> + #include <linux/ioport.h> + #include <linux/slab.h> + #include <linux/interrupt.h> +-#include <linux/pci.h> +-#include <linux/init.h> ++#include <linux/wait.h> + #include <linux/delay.h> ++#include <linux/platform_device.h> + #include <linux/netdevice.h> + #include <linux/etherdevice.h> + #include <linux/skbuff.h> + #include <linux/spinlock.h> +-#include <linux/workqueue.h> +-#include <linux/bitops.h> +-#include <linux/io.h> +-#include <linux/irq.h> ++#include <linux/dma-mapping.h> + #include <linux/clk.h> +-#include <linux/platform_device.h> ++#include <linux/fec_enet.h> ++#include <linux/phy.h> + +-#include <asm/cacheflush.h> ++#include <asm/irq.h> ++#include <asm/io.h> + +-#ifndef CONFIG_ARCH_MXC +-#include <asm/coldfire.h> +-#include <asm/mcfsim.h> ++#define DRV_NAME "fec" ++#define DEBUG ++ ++#ifdef DEBUG ++static int debug = 0; ++#define dbg_lvl(n) ((n) < debug) ++module_param(debug, int, S_IRUGO | S_IWUSR); ++ ++#define DBG(lvl, fmt...) do { if (dbg_lvl(lvl)) printk(KERN_DEBUG fmt); } while (0) ++#else ++static int debug; ++#define dbg_lvl(n) 0 ++module_param(debug, int, 0); ++ ++#define DBG(lvl, fmt...) do { } while (0) + #endif + ++#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || \ ++ defined(CONFIG_M5272) || defined(CONFIG_M528x) || \ ++ defined(CONFIG_M520x) || defined(CONFIG_M532x) ++#include <asm/coldfire.h> ++#include <asm/mcfsim.h> + #include "fec.h" +- +-#ifdef CONFIG_ARCH_MXC ++#define FEC_ALIGNMENT (0x03) /*FEC needs 4bytes alignment*/ ++#elif defined(CONFIG_ARCH_MXC) + #include <mach/hardware.h> +-#define FEC_ALIGNMENT 0xf ++#include <mach/iim.h> ++#include "fec.h" ++#define FEC_ALIGNMENT (0x0F) /*FEC needs 128bits(16bytes) alignment*/ + #else +-#define FEC_ALIGNMENT 0x3 ++#include <asm/8xx_immap.h> ++#include <asm/mpc8xx.h> ++#include "commproc.h" ++#define FEC_ALIGNMENT (0x03) /*FEC needs 4bytes alignment */ + #endif + ++#define FEC_ADDR_ALIGNMENT(x) ((unsigned char *)(((unsigned long)(x) + (FEC_ALIGNMENT)) & (~FEC_ALIGNMENT))) ++ ++#if 0 + /* + * Define the fixed address of the FEC hardware. + */ ++/* USE resources provided by platform_device! */ ++static unsigned int fec_hw[] = { + #if defined(CONFIG_M5272) +-#define HAVE_mii_link_interrupt +- +-static unsigned char fec_mac_default[] = { +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ (MCF_MBAR + 0x840), ++#elif defined(CONFIG_M527x) ++ (MCF_MBAR + 0x1000), ++ (MCF_MBAR + 0x1800), ++#elif defined(CONFIG_M523x) || defined(CONFIG_M528x) ++ (MCF_MBAR + 0x1000), ++#elif defined(CONFIG_M520x) ++ (MCF_MBAR+0x30000), ++#elif defined(CONFIG_M532x) ++ (MCF_MBAR+0xfc030000), ++#elif defined(CONFIG_ARCH_MXC) ++ (IO_ADDRESS(FEC_BASE_ADDR)), ++#else ++ &(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec), ++#endif + }; ++#endif + ++#if 0 + /* + * Some hardware gets it MAC address out of local flash memory. + * if this is non-zero then assume it is the address to get MAC from. + */ ++/* implemented using platform_data! */ + #if defined(CONFIG_NETtel) + #define FEC_FLASHMAC 0xf0006006 + #elif defined(CONFIG_GILBARCONAP) || defined(CONFIG_SCALES) + #define FEC_FLASHMAC 0xf0006000 ++#elif defined (CONFIG_MTD_KeyTechnology) ++#define FEC_FLASHMAC 0xffe04000 + #elif defined(CONFIG_CANCam) + #define FEC_FLASHMAC 0xf0020000 + #elif defined (CONFIG_M5272C3) + #define FEC_FLASHMAC (0xffe04000 + 4) + #elif defined(CONFIG_MOD5272) +-#define FEC_FLASHMAC 0xffc0406b ++#define FEC_FLASHMAC 0xffc0406b + #else + #define FEC_FLASHMAC 0 + #endif +-#endif /* CONFIG_M5272 */ ++#endif ++ ++#define platform_func(p, args...) ((p) ? (p)(args) : 0) + + /* Forward declarations of some structures to support different PHYs + */ +- ++#ifndef CONFIG_PHYLIB + typedef struct { + uint mii_data; + void (*funct)(uint mii_reg, struct net_device *dev); +@@ -103,6 +155,7 @@ typedef struct { + const phy_cmd_t *ack_int; + const phy_cmd_t *shutdown; + } phy_info_t; ++#endif + + /* The number of Tx and Rx buffers. These are allocated from the page + * pool. The code may assume these are power of two, so it it best +@@ -116,12 +169,13 @@ typedef struct { + #define RX_RING_SIZE (FEC_ENET_RX_FRPPG * FEC_ENET_RX_PAGES) + #define FEC_ENET_TX_FRSIZE 2048 + #define FEC_ENET_TX_FRPPG (PAGE_SIZE / FEC_ENET_TX_FRSIZE) +-#define TX_RING_SIZE 16 /* Must be power of two */ +-#define TX_RING_MOD_MASK 15 /* for this to work */ ++#define TX_RING_SIZE 16 /* Must be power of two */ ++#define TX_RING_MOD_MASK (TX_RING_SIZE - 1) /* for this to work */ + + #if (((RX_RING_SIZE + TX_RING_SIZE) * 8) > PAGE_SIZE) + #error "FEC: descriptor ring size constants too large" + #endif ++#define CBD_BUF_SIZE ((RX_RING_SIZE + TX_RING_SIZE) * sizeof(cbd_t)) + + /* Interrupt events/masks. + */ +@@ -136,6 +190,17 @@ typedef struct { + #define FEC_ENET_MII ((uint)0x00800000) /* MII interrupt */ + #define FEC_ENET_EBERR ((uint)0x00400000) /* SDMA bus error */ + ++/* MXC arch interrupt bits */ ++#define FEC_ENET_LC ((uint)0x00200000) /* Late collision */ ++#define FEC_ENET_RL ((uint)0x00100000) /* Collision retry limit exceeded */ ++#define FEC_ENET_UN ((uint)0x00080000) /* TX Fifo underrun */ ++ ++#ifndef CONFIG_ARCH_MXC ++#define FEC_ENET_MASK ((uint)0xffc00000) ++#else ++#define FEC_ENET_MASK ((uint)0xfff80000) ++#endif ++ + /* The FEC stores dest/src/type, data, and checksum for receive packets. + */ + #define PKT_MAXBUF_SIZE 1518 +@@ -150,7 +215,7 @@ typedef struct { + */ + #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \ + defined(CONFIG_M520x) || defined(CONFIG_M532x) || defined(CONFIG_ARCH_MXC) +-#define OPT_FRAME_SIZE (PKT_MAXBUF_SIZE << 16) ++#define OPT_FRAME_SIZE (RCR_MAX_FL_set(PKT_MAXBUF_SIZE)) + #else + #define OPT_FRAME_SIZE 0 + #endif +@@ -165,31 +230,45 @@ typedef struct { + */ + struct fec_enet_private { + /* Hardware registers of the FEC device */ +- volatile fec_t *hwp; +- +- struct net_device *netdev; +- +- struct clk *clk; ++ void __iomem *reg_base; ++ void __iomem *mib_base; ++ struct resource *res_mem1; ++ struct resource *res_mem2; ++ int etn_irq; ++ int mii_irq; ++#ifndef CONFIG_PHYLIB ++ struct timer_list *phy_timer; ++#else ++ struct mii_bus *mii; ++ int mii_complete; ++#endif ++ u32 msg_enable; + + /* The saved address of a sent-in-place packet/buffer, for skfree(). */ +- unsigned char *tx_bounce[TX_RING_SIZE]; ++ void *tx_bounce[TX_RING_SIZE]; + struct sk_buff* tx_skbuff[TX_RING_SIZE]; ++ struct sk_buff* rx_skbuff[RX_RING_SIZE]; + ushort skb_cur; + ushort skb_dirty; + + /* CPM dual port RAM relative addresses. + */ +- dma_addr_t bd_dma; ++ struct device *dma_dev; /* pointer to (platform_)device for dma_sync*() functions */ ++ void *cbd_mem_base; /* save the virtual base address of rx&tx buffer descriptor */ ++ dma_addr_t cbd_phys_base; /* physical address of buffer descriptor memory for access by FEC HW */ ++ + cbd_t *rx_bd_base; /* Address of Rx and Tx buffers. */ + cbd_t *tx_bd_base; +- cbd_t *cur_rx, *cur_tx; /* The next free ring entry */ +- cbd_t *dirty_tx; /* The ring entries to be free()ed. */ ++ cbd_t *cur_rx, *cur_tx; /* The next free ring entry */ ++ cbd_t *dirty_tx; /* The ring entries to be free()ed. */ ++ struct net_device_stats stats; + uint tx_full; +- /* hold while accessing the HW like ringbuffer for tx/rx but not MAC */ +- spinlock_t hw_lock; +- /* hold while accessing the mii_list_t() elements */ +- spinlock_t mii_lock; ++ spinlock_t lock; + ++#ifdef CONFIG_PHYLIB ++ struct phy_device *phy; ++ uint phy_speed; ++#else + uint phy_id; + uint phy_id_done; + uint phy_status; +@@ -199,28 +278,41 @@ struct fec_enet_private { + + uint sequence_done; + uint mii_phy_task_queued; +- ++#endif + uint phy_addr; + +- int index; +- int opened; +- int link; +- int old_link; +- int full_duplex; ++ unsigned int opened:1; ++ unsigned int phy_int_enabled:1; ++ unsigned int linkstatus:1; ++#ifndef CONFIG_PHYLIB ++ unsigned int old_linkstatus:1; ++#endif ++ unsigned int full_duplex:1; ++ ++ struct clk *clk; + }; + +-static int fec_enet_open(struct net_device *dev); +-static int fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev); +-static void fec_enet_mii(struct net_device *dev); +-static irqreturn_t fec_enet_interrupt(int irq, void * dev_id); ++#ifdef CONFIG_PHYLIB ++static int fec_connect_phy(struct net_device *dev, struct fec_enet_private *fep); ++#else ++static irqreturn_t mii_link_interrupt(int irq, void *dev_id); ++#endif ++static void fec_restart(struct net_device *dev, int duplex); + static void fec_enet_tx(struct net_device *dev); + static void fec_enet_rx(struct net_device *dev); +-static int fec_enet_close(struct net_device *dev); +-static void set_multicast_list(struct net_device *dev); +-static void fec_restart(struct net_device *dev, int duplex); ++static void fec_enet_mii(struct net_device *dev); + static void fec_stop(struct net_device *dev); +-static void fec_set_mac_address(struct net_device *dev); ++static void _fec_set_mac_address(struct net_device *dev); + ++/* ++ * fec_copy_threshold controls the copy when receiving ethernet frame. ++ * If ethernet header is aligned on a 4byte boundary, the ip header and ++ * higher level header will not be aligned. ++ * The reason is, that an ethernet header is 14bytes long. ++ * And the max size of tcp & ip header is 128bytes. Normally it is 40bytes. ++ * So I set the default value between 128 to 256. ++ */ ++static int fec_copy_threshold = 192; + + /* MII processing. We keep this as simple as possible. Requests are + * placed on the list (if there is room). When the request is finished +@@ -232,14 +324,16 @@ typedef struct mii_list { + struct mii_list *mii_next; + } mii_list_t; + ++#ifndef CONFIG_PHYLIB + #define NMII 20 + static mii_list_t mii_cmds[NMII]; + static mii_list_t *mii_free; + static mii_list_t *mii_head; + static mii_list_t *mii_tail; + +-static int mii_queue(struct net_device *dev, int request, +- void (*func)(uint, struct net_device *)); ++static int mii_queue(struct net_device *dev, int request, ++ void (*func)(uint, struct net_device *)); ++#endif + + /* Make MII read/write commands for the FEC. + */ +@@ -284,87 +378,233 @@ static int mii_queue(struct net_device * + #define PHY_STAT_100HDX 0x4000 /* 100 Mbit half duplex selected */ + #define PHY_STAT_100FDX 0x8000 /* 100 Mbit full duplex selected */ + ++#ifndef DEBUG ++static inline unsigned long fec_reg_read(struct fec_enet_private *fep, unsigned int reg) ++{ ++ return readl(fep->reg_base + reg); ++} ++ ++static inline void fec_reg_write(struct fec_enet_private *fep, unsigned int reg, unsigned long val) ++{ ++ writel(val, fep->reg_base + reg); ++} ++#else ++#define fec_reg_read(fep, reg) __fec_reg_read(fep, reg, __FUNCTION__, #reg) ++#define fec_reg_write(fep, reg, val) __fec_reg_write(fep, reg, val, __FUNCTION__, #reg) ++ ++static inline unsigned long __fec_reg_read(struct fec_enet_private *fep, unsigned int reg, ++ const char *func, const char *reg_name) ++{ ++ unsigned long val = readl(fep->reg_base + reg); ++ DBG(3, "%s: Read %08lx from %s(%03x)\n", func, val, reg_name, reg); ++ return val; ++} ++ ++static inline void __fec_reg_write(struct fec_enet_private *fep, unsigned int reg, ++ unsigned long val, const char *func, const char *reg_name) ++{ ++ DBG(3, "%s: Writing %08lx to %s(%03x)\n", func, val, reg_name, reg); ++ writel(val, fep->reg_base + reg); ++} ++#endif ++ ++static inline void fec_enet_cbd_get(struct fec_enet_private *fep) ++{ ++ DBG(2, "%s: Requesting cbd area: %08lx\n", __FUNCTION__, ++ (unsigned long)fep->cbd_phys_base); ++ dma_sync_single_for_cpu(fep->dma_dev, fep->cbd_phys_base, ++ CBD_BUF_SIZE, DMA_BIDIRECTIONAL); ++} ++ ++static inline void fec_enet_cbd_put(struct fec_enet_private *fep) ++{ ++ DBG(2, "%s: Flushing changes to cbd area\n", __FUNCTION__); ++ dma_sync_single_for_device(fep->dma_dev, fep->cbd_phys_base, ++ CBD_BUF_SIZE, DMA_BIDIRECTIONAL); ++} ++ ++static inline void fec_enet_rxbuf_get(struct fec_enet_private *fep, cbd_t *bdp, ushort len) ++{ ++ DBG(2, "%s: Requesting RX buffer %08lx(%u)\n", __FUNCTION__, ++ (unsigned long)bdp->cbd_bufaddr, len); ++ dma_sync_single_for_cpu(fep->dma_dev, bdp->cbd_bufaddr, ++ len, DMA_FROM_DEVICE); ++} ++ ++static inline void fec_enet_rxbuf_put(struct fec_enet_private *fep, cbd_t *bdp, ushort len) ++{ ++ DBG(2, "%s: Releasing RX buffer %08lx(%u)\n", __FUNCTION__, (ulong)bdp->cbd_bufaddr, len); ++ dma_sync_single_for_device(fep->dma_dev, bdp->cbd_bufaddr, len, DMA_FROM_DEVICE); ++} ++ ++static inline void fec_enet_rxbuf_map(struct fec_enet_private *fep, cbd_t *bdp, ++ void *buf, ushort len) ++{ ++ BUG_ON(!dma_mapping_error(fep->dma_dev, bdp->cbd_bufaddr)); ++ bdp->cbd_bufaddr = dma_map_single(fep->dma_dev, buf, ++ len, DMA_FROM_DEVICE); ++ DBG(2, "%s: RX buffer %p(%u) mapped to %08lx\n", __FUNCTION__, ++ buf, len, (unsigned long)bdp->cbd_bufaddr); ++} ++ ++static inline void fec_enet_rxbuf_unmap(struct fec_enet_private *fep, cbd_t *bdp, ushort len) ++{ ++ DBG(2, "%s: Unmapping RX buffer %08lx(%u)\n", __FUNCTION__, ++ (unsigned long)bdp->cbd_bufaddr, len); ++ BUG_ON(dma_mapping_error(fep->dma_dev, bdp->cbd_bufaddr)); ++ dma_unmap_single(fep->dma_dev, bdp->cbd_bufaddr, ++ len, DMA_FROM_DEVICE); ++ bdp->cbd_bufaddr = ~0; ++} ++ ++static inline void fec_enet_txbuf_map(struct fec_enet_private *fep, cbd_t *bdp, ++ void *buf, ushort len) ++{ ++ BUG_ON(!dma_mapping_error(fep->dma_dev, bdp->cbd_bufaddr)); ++ bdp->cbd_bufaddr = dma_map_single(fep->dma_dev, buf, ++ len, DMA_TO_DEVICE); ++ DBG(2, "%s: TX buffer %p(%u) mapped to %08lx\n", __FUNCTION__, ++ buf, len, (unsigned long)bdp->cbd_bufaddr); ++} ++ ++static inline void fec_enet_txbuf_unmap(struct fec_enet_private *fep, cbd_t *bdp, ushort len) ++{ ++ DBG(2, "%s: Unmapping TX buffer %08lx(%u)\n", __FUNCTION__, ++ (unsigned long)bdp->cbd_bufaddr, len); ++ BUG_ON(dma_mapping_error(fep->dma_dev, bdp->cbd_bufaddr)); ++ dma_unmap_single(fep->dma_dev, bdp->cbd_bufaddr, ++ len, DMA_TO_DEVICE); ++ bdp->cbd_bufaddr = ~0; ++} ++ ++static inline void fec_enet_txbuf_get(struct fec_enet_private *fep, cbd_t *bdp, ushort len) ++{ ++ DBG(2, "%s: Requesting TX buffer %08lx(%u)\n", __FUNCTION__, ++ (unsigned long)bdp->cbd_bufaddr, len); ++ dma_sync_single_for_cpu(fep->dma_dev, bdp->cbd_bufaddr, ++ len, DMA_TO_DEVICE); ++} ++ ++static inline void fec_enet_txbuf_put(struct fec_enet_private *fep, cbd_t *bdp, ushort len) ++{ ++ DBG(2, "%s: Releasing TX buffer %08lx(%u)\n", __FUNCTION__, ++ (unsigned long)bdp->cbd_bufaddr, len); ++ dma_sync_single_for_device(fep->dma_dev, bdp->cbd_bufaddr, ++ len, DMA_TO_DEVICE); ++} ++ ++static void dump_packet(const char *prefix, const unsigned char *data, int len) ++{ ++ if (dbg_lvl(3)) { ++ print_hex_dump_bytes(prefix, DUMP_PREFIX_OFFSET, data, len); ++ } ++} ++ ++static void dump_tx_buffers(struct fec_enet_private *fep) ++{ ++ cbd_t *bdp = fep->tx_bd_base; ++ int i; ++ ++ printk(KERN_DEBUG "tx buffers: %u buffers\n", TX_RING_SIZE); ++ for (i = 0; i < TX_RING_SIZE; i++, bdp++) { ++ printk(KERN_DEBUG " %p: %04x %04x %08x\n", ++ bdp, ++ bdp->cbd_sc, ++ bdp->cbd_datlen, ++ bdp->cbd_bufaddr); ++ print_hex_dump_bytes("tx buffers:", DUMP_PREFIX_ADDRESS, bdp, sizeof(cbd_t)); ++ } ++} ++ ++static void dump_rx_buffers(struct fec_enet_private *fep) ++{ ++ cbd_t *bdp = fep->rx_bd_base; ++ int i; ++ ++ printk(KERN_DEBUG "rx buffers: %lu buffers\n", RX_RING_SIZE); ++ for (i = 0; i < RX_RING_SIZE; i++, bdp++) { ++ printk(KERN_DEBUG " %p: %04x %04x %08x\n", ++ bdp, ++ bdp->cbd_sc, ++ bdp->cbd_datlen, ++ bdp->cbd_bufaddr); ++ print_hex_dump_bytes("rx buffers:", DUMP_PREFIX_ADDRESS, bdp, sizeof(cbd_t)); ++ } ++} + + static int + fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) + { +- struct fec_enet_private *fep; +- volatile fec_t *fecp; +- volatile cbd_t *bdp; +- unsigned short status; ++ struct fec_enet_private *fep = netdev_priv(dev); ++ cbd_t *bdp; ++ unsigned short status; + unsigned long flags; + +- fep = netdev_priv(dev); +- fecp = (volatile fec_t*)dev->base_addr; +- +- if (!fep->link) { ++ if (!fep->linkstatus) { ++ DBG(0, "%s: Cannot send packet; link is down\n", __FUNCTION__); + /* Link is down or autonegotiation is in progress. */ + return 1; + } + +- spin_lock_irqsave(&fep->hw_lock, flags); ++ spin_lock_irqsave(&fep->lock, flags); ++ ++ //WARN_ON(fec_reg_read(fep, FEC_TDAR) & TDAR_BUSY); ++ fec_enet_cbd_get(fep); ++ + /* Fill in a Tx ring entry */ + bdp = fep->cur_tx; + + status = bdp->cbd_sc; +-#ifndef final_version ++#ifdef DEBUG + if (status & BD_ENET_TX_READY) { + /* Ooops. All transmit buffers are full. Bail out. + * This should not happen, since dev->tbusy should be set. + */ + printk("%s: tx queue full!.\n", dev->name); +- spin_unlock_irqrestore(&fep->hw_lock, flags); ++ fec_enet_cbd_put(fep); ++ spin_unlock_irqrestore(&fep->lock, flags); + return 1; + } + #endif +- + /* Clear all of the status flags. + */ + status &= ~BD_ENET_TX_STATS; + + /* Set buffer length and buffer pointer. + */ +- bdp->cbd_bufaddr = __pa(skb->data); + bdp->cbd_datlen = skb->len; + ++ dump_packet("sending packet:", skb->data, skb->len); + /* + * On some FEC implementations data must be aligned on + * 4-byte boundaries. Use bounce buffers to copy data + * and get it aligned. Ugh. + */ +- if (bdp->cbd_bufaddr & FEC_ALIGNMENT) { ++ if (unlikely((bdp->cbd_bufaddr) & FEC_ALIGNMENT)) { + unsigned int index; + index = bdp - fep->tx_bd_base; +- memcpy(fep->tx_bounce[index], (void *)skb->data, skb->len); +- bdp->cbd_bufaddr = __pa(fep->tx_bounce[index]); ++ memcpy(fep->tx_bounce[index], skb->data, skb->len); ++ fec_enet_txbuf_map(fep, bdp, fep->tx_bounce[index], skb->len); ++ } else { ++ fec_enet_txbuf_map(fep, bdp, skb->data, skb->len); + } + + /* Save skb pointer. + */ + fep->tx_skbuff[fep->skb_cur] = skb; + +- dev->stats.tx_bytes += skb->len; +- fep->skb_cur = (fep->skb_cur+1) & TX_RING_MOD_MASK; +- +- /* Push the data cache so the CPM does not get stale memory +- * data. +- */ +- dma_sync_single(NULL, bdp->cbd_bufaddr, +- bdp->cbd_datlen, DMA_TO_DEVICE); ++ fep->stats.tx_bytes += skb->len; ++ fep->skb_cur = (fep->skb_cur + 1) & TX_RING_MOD_MASK; + + /* Send it on its way. Tell FEC it's ready, interrupt when done, + * it's the last BD of the frame, and to put the CRC on the end. + */ +- + status |= (BD_ENET_TX_READY | BD_ENET_TX_INTR + | BD_ENET_TX_LAST | BD_ENET_TX_TC); + bdp->cbd_sc = status; + + dev->trans_start = jiffies; + +- /* Trigger transmission start */ +- fecp->fec_x_des_active = 0; +- + /* If this was the last BD in the ring, start at the beginning again. + */ + if (status & BD_ENET_TX_WRAP) { +@@ -375,12 +615,22 @@ fec_enet_start_xmit(struct sk_buff *skb, + + if (bdp == fep->dirty_tx) { + fep->tx_full = 1; ++ DBG(0, "TX ring full, stopping netif queue\n"); + netif_stop_queue(dev); + } + +- fep->cur_tx = (cbd_t *)bdp; ++ fep->cur_tx = bdp; ++ fec_enet_cbd_put(fep); ++#if 0 ++ if (dbg_lvl(3)) { ++ dump_tx_buffers(fep); ++ dump_rx_buffers(fep); ++ } ++#endif ++ /* Trigger transmission start */ ++ fec_reg_write(fep, FEC_TDAR, DONT_CARE); + +- spin_unlock_irqrestore(&fep->hw_lock, flags); ++ spin_unlock_irqrestore(&fep->lock, flags); + + return 0; + } +@@ -390,101 +640,126 @@ fec_timeout(struct net_device *dev) + { + struct fec_enet_private *fep = netdev_priv(dev); + +- printk("%s: transmit timed out.\n", dev->name); +- dev->stats.tx_errors++; +-#ifndef final_version ++ printk(KERN_WARNING "%s: transmit timed out.\n", dev->name); ++ fep->stats.tx_errors++; ++#ifdef DEBUG + { +- int i; +- cbd_t *bdp; ++ int i; ++ cbd_t *bdp; + +- printk("Ring data dump: cur_tx %lx%s, dirty_tx %lx cur_rx: %lx\n", +- (unsigned long)fep->cur_tx, fep->tx_full ? " (full)" : "", +- (unsigned long)fep->dirty_tx, +- (unsigned long)fep->cur_rx); ++ fec_enet_cbd_get(fep); + +- bdp = fep->tx_bd_base; +- printk(" tx: %u buffers\n", TX_RING_SIZE); +- for (i = 0 ; i < TX_RING_SIZE; i++) { +- printk(" %08x: %04x %04x %08x\n", +- (uint) bdp, +- bdp->cbd_sc, +- bdp->cbd_datlen, +- (int) bdp->cbd_bufaddr); +- bdp++; +- } ++ printk(KERN_DEBUG "%s: Ring data dump: cur_tx %p%s, dirty_tx %p cur_rx: %p\n", ++ __FUNCTION__, ++ fep->cur_tx, fep->tx_full ? " (full)" : "", ++ fep->dirty_tx, ++ fep->cur_rx); + +- bdp = fep->rx_bd_base; +- printk(" rx: %lu buffers\n", (unsigned long) RX_RING_SIZE); +- for (i = 0 ; i < RX_RING_SIZE; i++) { +- printk(" %08x: %04x %04x %08x\n", +- (uint) bdp, +- bdp->cbd_sc, +- bdp->cbd_datlen, +- (int) bdp->cbd_bufaddr); +- bdp++; +- } ++ bdp = fep->tx_bd_base; ++ printk(" tx: %u buffers\n", TX_RING_SIZE); ++ for (i = 0; i < TX_RING_SIZE; i++) { ++ printk(" %p: %04x %04x %08x\n", ++ bdp, ++ bdp->cbd_sc, ++ bdp->cbd_datlen, ++ bdp->cbd_bufaddr); ++ bdp++; ++ } ++ ++ bdp = fep->rx_bd_base; ++ printk(" rx: %lu buffers\n", RX_RING_SIZE); ++ for (i = 0; i < RX_RING_SIZE; i++) { ++ printk(" %p: %04x %04x %08x\n", ++ bdp, ++ bdp->cbd_sc, ++ bdp->cbd_datlen, ++ bdp->cbd_bufaddr); ++ bdp++; ++ } ++ fec_enet_cbd_put(fep); + } + #endif + fec_restart(dev, fep->full_duplex); +- netif_wake_queue(dev); ++ DBG(0, "%s: Scheduling netif queue\n", __FUNCTION__); ++ //netif_schedule(dev); + } + + /* The interrupt handler. + * This is called from the MPC core interrupt. + */ + static irqreturn_t +-fec_enet_interrupt(int irq, void * dev_id) ++fec_enet_interrupt(int irq, void *dev_id) + { +- struct net_device *dev = dev_id; +- volatile fec_t *fecp; +- uint int_events; +- irqreturn_t ret = IRQ_NONE; +- +- fecp = (volatile fec_t*)dev->base_addr; ++ struct net_device *dev = dev_id; ++ struct fec_enet_private *fep = netdev_priv(dev); ++ uint int_events; ++ int handled = 0; ++ unsigned int eimr = fec_reg_read(fep, FEC_EIMR); + ++ DBG(2, "%s: %08lx:%08lx\n", __FUNCTION__, ++ fec_reg_read(fep, FEC_EIR), fec_reg_read(fep, FEC_EIMR)); + /* Get the interrupt events that caused us to be here. + */ +- do { +- int_events = fecp->fec_ievent; +- fecp->fec_ievent = int_events; ++ while ((int_events = fec_reg_read(fep, FEC_EIR) & FEC_ENET_MASK) != 0) { ++ if (int_events & ~eimr) { ++ printk(KERN_WARNING "%s: masked interrupt condition: %08x\n", ++ __FUNCTION__, int_events & ~eimr); ++ } ++ ++ fec_reg_write(fep, FEC_EIR, int_events); + + /* Handle receive event in its own function. + */ +- if (int_events & FEC_ENET_RXF) { +- ret = IRQ_HANDLED; ++ if (int_events & (FEC_ENET_RXF | FEC_ENET_RXB)) { ++ DBG(2, "%s: Handling RX Interrupt\n", __FUNCTION__); ++ handled = 1; + fec_enet_rx(dev); + } + ++ if (int_events & FEC_ENET_UN) { ++ printk(KERN_WARNING "TX fifo underrun"); ++ } + /* Transmit OK, or non-fatal error. Update the buffer + descriptors. FEC handles all errors, we just discover + them as part of the transmit process. + */ +- if (int_events & FEC_ENET_TXF) { +- ret = IRQ_HANDLED; ++ if (int_events & (FEC_ENET_TXF | FEC_ENET_TXB)) { ++ DBG(2, "%s: Handling TX Interrupt\n", __FUNCTION__); ++ handled = 1; + fec_enet_tx(dev); + } + +- if (int_events & FEC_ENET_MII) { +- ret = IRQ_HANDLED; ++ if (int_events & (FEC_ENET_MII | FEC_ENET_HBERR)) { ++ DBG(2, "%s: Handling MII Interrupt\n", __FUNCTION__); ++ handled = 1; + fec_enet_mii(dev); + } +- +- } while (int_events); +- +- return ret; ++ } ++ return IRQ_RETVAL(handled); + } + ++static void fec_free_skb(struct fec_enet_private *fep, cbd_t *bdp, struct sk_buff **pskb) ++{ ++ struct sk_buff *skb = *pskb; ++ if (!dma_mapping_error(fep->dma_dev, bdp->cbd_bufaddr)) { ++ fec_enet_txbuf_unmap(fep, bdp, skb->len); ++ } ++ dev_kfree_skb_any(skb); ++ *pskb = NULL; ++} + + static void + fec_enet_tx(struct net_device *dev) + { +- struct fec_enet_private *fep; +- volatile cbd_t *bdp; ++ struct fec_enet_private *fep = netdev_priv(dev); ++ cbd_t *bdp; + unsigned short status; +- struct sk_buff *skb; ++ struct sk_buff *skb; + +- fep = netdev_priv(dev); +- spin_lock_irq(&fep->hw_lock); ++ spin_lock(&fep->lock); ++ ++ //WARN_ON(fec_reg_read(fep, FEC_TDAR) & TDAR_BUSY); ++ fec_enet_cbd_get(fep); + bdp = fep->dirty_tx; + + while (((status = bdp->cbd_sc) & BD_ENET_TX_READY) == 0) { +@@ -495,22 +770,22 @@ fec_enet_tx(struct net_device *dev) + if (status & (BD_ENET_TX_HB | BD_ENET_TX_LC | + BD_ENET_TX_RL | BD_ENET_TX_UN | + BD_ENET_TX_CSL)) { +- dev->stats.tx_errors++; ++ fep->stats.tx_errors++; + if (status & BD_ENET_TX_HB) /* No heartbeat */ +- dev->stats.tx_heartbeat_errors++; ++ fep->stats.tx_heartbeat_errors++; + if (status & BD_ENET_TX_LC) /* Late collision */ +- dev->stats.tx_window_errors++; ++ fep->stats.tx_window_errors++; + if (status & BD_ENET_TX_RL) /* Retrans limit */ +- dev->stats.tx_aborted_errors++; ++ fep->stats.tx_aborted_errors++; + if (status & BD_ENET_TX_UN) /* Underrun */ +- dev->stats.tx_fifo_errors++; ++ fep->stats.tx_fifo_errors++; + if (status & BD_ENET_TX_CSL) /* Carrier lost */ +- dev->stats.tx_carrier_errors++; ++ fep->stats.tx_carrier_errors++; + } else { +- dev->stats.tx_packets++; ++ fep->stats.tx_packets++; + } + +-#ifndef final_version ++#ifdef DEBUG + if (status & BD_ENET_TX_READY) + printk("HEY! Enet xmit interrupt and TX_READY.\n"); + #endif +@@ -518,12 +793,13 @@ fec_enet_tx(struct net_device *dev) + * but we eventually sent the packet OK. + */ + if (status & BD_ENET_TX_DEF) +- dev->stats.collisions++; ++ fep->stats.collisions++; + ++ dump_packet("sent packet:", fep->tx_skbuff[fep->skb_dirty]->data, ++ fep->tx_skbuff[fep->skb_dirty]->len); + /* Free the sk buffer associated with this last transmit. + */ +- dev_kfree_skb_any(skb); +- fep->tx_skbuff[fep->skb_dirty] = NULL; ++ fec_free_skb(fep, bdp, &fep->tx_skbuff[fep->skb_dirty]); + fep->skb_dirty = (fep->skb_dirty + 1) & TX_RING_MOD_MASK; + + /* Update pointer to next buffer descriptor to be transmitted. +@@ -538,12 +814,15 @@ fec_enet_tx(struct net_device *dev) + */ + if (fep->tx_full) { + fep->tx_full = 0; +- if (netif_queue_stopped(dev)) ++ if (netif_queue_stopped(dev)) { ++ DBG(0, "%s: Waking up netif queue\n", __FUNCTION__); + netif_wake_queue(dev); ++ } + } + } +- fep->dirty_tx = (cbd_t *)bdp; +- spin_unlock_irq(&fep->hw_lock); ++ fec_enet_cbd_put(fep); ++ fep->dirty_tx = bdp; ++ spin_unlock(&fep->lock); + } + + +@@ -555,22 +834,22 @@ fec_enet_tx(struct net_device *dev) + static void + fec_enet_rx(struct net_device *dev) + { +- struct fec_enet_private *fep; +- volatile fec_t *fecp; +- volatile cbd_t *bdp; ++ struct fec_enet_private *fep = netdev_priv(dev); ++ cbd_t *bdp; + unsigned short status; +- struct sk_buff *skb; +- ushort pkt_len; +- __u8 *data; ++ struct sk_buff *skb; ++ ushort pkt_len; ++ int rx_index; + + #ifdef CONFIG_M532x ++ /* This is probably nonsense ++ Proper use of dma-mapping functions should make this obsolete ++ */ + flush_cache_all(); + #endif +- +- fep = netdev_priv(dev); +- fecp = (volatile fec_t*)dev->base_addr; +- +- spin_lock_irq(&fep->hw_lock); ++ /* reserve the dual port memory area for our use */ ++ //WARN_ON(fec_reg_read(fep, FEC_RDAR) & RDAR_BUSY); ++ fec_enet_cbd_get(fep); + + /* First, grab all of the stats for the incoming packet. + * These get messed up if we get called due to a busy condition. +@@ -578,32 +857,34 @@ fec_enet_rx(struct net_device *dev) + bdp = fep->cur_rx; + + while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) { +- +-#ifndef final_version ++ rx_index = bdp - fep->rx_bd_base; ++#ifdef DEBUG + /* Since we have allocated space to hold a complete frame, + * the last indicator should be set. + */ +- if ((status & BD_ENET_RX_LAST) == 0) +- printk("FEC ENET: rcv is not +last\n"); ++ WARN_ON(!(status & BD_ENET_RX_LAST)); + #endif + +- if (!fep->opened) ++ if (WARN_ON(!fep->opened)) { ++ DBG(0, "%s: Driver not opened; ignoring packet\n", __FUNCTION__); ++#if 0 + goto rx_processing_done; +- ++#endif ++ } + /* Check for errors. */ + if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_NO | + BD_ENET_RX_CR | BD_ENET_RX_OV)) { +- dev->stats.rx_errors++; ++ fep->stats.rx_errors++; + if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH)) { + /* Frame too long or too short. */ +- dev->stats.rx_length_errors++; ++ fep->stats.rx_length_errors++; + } + if (status & BD_ENET_RX_NO) /* Frame alignment */ +- dev->stats.rx_frame_errors++; ++ fep->stats.rx_frame_errors++; + if (status & BD_ENET_RX_CR) /* CRC Error */ +- dev->stats.rx_crc_errors++; ++ fep->stats.rx_crc_errors++; + if (status & BD_ENET_RX_OV) /* FIFO overrun */ +- dev->stats.rx_fifo_errors++; ++ fep->stats.rx_fifo_errors++; + } + + /* Report late collisions as a frame error. +@@ -611,39 +892,91 @@ while (!((status = bdp->cbd_sc) & BD_ENE + * have in the buffer. So, just drop this frame on the floor. + */ + if (status & BD_ENET_RX_CL) { +- dev->stats.rx_errors++; +- dev->stats.rx_frame_errors++; ++ fep->stats.rx_errors++; ++ fep->stats.rx_frame_errors++; ++ DBG(0, "%s: Collision detected; dropping packet\n", __FUNCTION__); ++ if (bdp->cbd_datlen > PKT_MAXBUF_SIZE) { ++ printk(KERN_ERR "invalid packet size %u; max %u\n", bdp->cbd_datlen, ++ PKT_MAXBUF_SIZE); ++ } else { ++ fec_enet_rxbuf_get(fep, bdp, bdp->cbd_datlen); ++ dump_packet("received packet:", ++ fep->rx_skbuff[rx_index]->data, bdp->cbd_datlen); ++ fec_enet_rxbuf_put(fep, bdp, bdp->cbd_datlen); ++ } + goto rx_processing_done; + } +- ++#if 1 ++ if (!fep->opened) { ++ DBG(0, "%s: Driver not opened; ignoring packet\n", __FUNCTION__); ++ if (bdp->cbd_datlen > PKT_MAXBUF_SIZE) { ++ printk(KERN_ERR "invalid packet size %u; max %u\n", bdp->cbd_datlen, ++ PKT_MAXBUF_SIZE); ++ } else { ++ fec_enet_rxbuf_get(fep, bdp, bdp->cbd_datlen); ++ dump_packet("received packet:", ++ fep->rx_skbuff[rx_index]->data, bdp->cbd_datlen); ++ fec_enet_rxbuf_put(fep, bdp, bdp->cbd_datlen); ++ } ++ goto rx_processing_done; ++ } ++#endif + /* Process the incoming frame. + */ +- dev->stats.rx_packets++; ++ fep->stats.rx_packets++; + pkt_len = bdp->cbd_datlen; +- dev->stats.rx_bytes += pkt_len; +- data = (__u8*)__va(bdp->cbd_bufaddr); +- +- dma_sync_single(NULL, (unsigned long)__pa(data), +- pkt_len - 4, DMA_FROM_DEVICE); ++ fep->stats.rx_bytes += pkt_len; + + /* This does 16 byte alignment, exactly what we need. + * The packet length includes FCS, but we don't want to + * include that when passing upstream as it messes up + * bridging applications. + */ +- skb = dev_alloc_skb(pkt_len-4); ++ if ((pkt_len - 4) < fec_copy_threshold) { ++ skb = dev_alloc_skb(pkt_len); ++ } else { ++ skb = dev_alloc_skb(FEC_ENET_RX_FRSIZE); ++ } + + if (skb == NULL) { + printk("%s: Memory squeeze, dropping packet.\n", dev->name); +- dev->stats.rx_dropped++; ++ fep->stats.rx_dropped++; + } else { +- skb_put(skb,pkt_len-4); /* Make room */ +- skb_copy_to_linear_data(skb, data, pkt_len-4); +- skb->protocol=eth_type_trans(skb,dev); ++ if ((pkt_len - 4) < fec_copy_threshold) { ++ /* skip 2 bytes, so IP header is on a 4 bytes boundary */ ++ skb_reserve(skb, 2); ++ skb_put(skb, pkt_len - 4); /* Make room */ ++ fec_enet_rxbuf_get(fep, bdp, pkt_len - 4); ++ skb_copy_to_linear_data(skb, ++ fep->rx_skbuff[rx_index]->data, ++ pkt_len - 4); ++ fec_enet_rxbuf_put(fep, bdp, pkt_len - 4); ++ } else { ++ struct sk_buff *pskb = fep->rx_skbuff[rx_index]; ++ ++ /* unmap the skb we are going to hand down to the network layer */ ++ fec_enet_rxbuf_unmap(fep, bdp, FEC_ENET_RX_FRSIZE); ++ ++ /* init the newly allocated skb */ ++ fep->rx_skbuff[rx_index] = skb; ++ skb->data = FEC_ADDR_ALIGNMENT(skb->data); ++ /* map the newly allocated skb's data buffer for DMA */ ++ fec_enet_rxbuf_map(fep, bdp, skb->data, FEC_ENET_RX_FRSIZE); ++ ++ skb_put(pskb, pkt_len - 4); /* Make room */ ++ skb = pskb; ++ } ++ skb->dev = dev; ++ skb->protocol = eth_type_trans(skb, dev); + netif_rx(skb); + } + rx_processing_done: +- ++#if 0 ++ if (dbg_lvl(3)) { ++ dump_rx_buffers(fep); ++ dump_tx_buffers(fep); ++ } ++#endif + /* Clear the status flags for this buffer. + */ + status &= ~BD_ENET_RX_STATS; +@@ -653,6 +986,9 @@ while (!((status = bdp->cbd_sc) & BD_ENE + status |= BD_ENET_RX_EMPTY; + bdp->cbd_sc = status; + ++ /* release the dual port memory area for use by the FEC hardware */ ++ fec_enet_cbd_put(fep); ++ + /* Update BD pointer to next entry. + */ + if (status & BD_ENET_RX_WRAP) +@@ -665,10 +1001,10 @@ while (!((status = bdp->cbd_sc) & BD_ENE + * incoming frames. On a heavily loaded network, we should be + * able to keep up at the expense of system resources. + */ +- fecp->fec_r_des_active = 0; ++ fec_reg_write(fep, FEC_RDAR, DONT_CARE); + #endif + } /* while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) */ +- fep->cur_rx = (cbd_t *)bdp; ++ fep->cur_rx = bdp; + + #if 0 + /* Doing this here will allow us to process all frames in the +@@ -678,27 +1014,28 @@ while (!((status = bdp->cbd_sc) & BD_ENE + * our way back to the interrupt return only to come right back + * here. + */ +- fecp->fec_r_des_active = 0; ++ fec_reg_write(fep, FEC_RDAR, DONT_CARE); + #endif +- +- spin_unlock_irq(&fep->hw_lock); + } + +- ++#ifdef CONFIG_PHYLIB + /* called from interrupt context */ ++static void fec_enet_mii(struct net_device *dev) ++{ ++ struct fec_enet_private *fep = netdev_priv(dev); ++ fep->mii_complete = 1; ++} ++#else + static void + fec_enet_mii(struct net_device *dev) + { +- struct fec_enet_private *fep; +- volatile fec_t *ep; ++ struct fec_enet_private *fep = netdev_priv(dev); + mii_list_t *mip; + uint mii_reg; + +- fep = netdev_priv(dev); +- spin_lock_irq(&fep->mii_lock); ++ mii_reg = fec_reg_read(fep, FEC_MMFR); + +- ep = fep->hwp; +- mii_reg = ep->fec_mii_data; ++ spin_lock(&fep->lock); + + if ((mip = mii_head) == NULL) { + printk("MII and no head!\n"); +@@ -713,27 +1050,27 @@ fec_enet_mii(struct net_device *dev) + mii_free = mip; + + if ((mip = mii_head) != NULL) +- ep->fec_mii_data = mip->mii_regval; ++ fec_reg_write(fep, FEC_MMFR, mip->mii_regval); + + unlock: +- spin_unlock_irq(&fep->mii_lock); ++ spin_unlock(&fep->lock); + } + + static int + mii_queue(struct net_device *dev, int regval, void (*func)(uint, struct net_device *)) + { +- struct fec_enet_private *fep; ++ struct fec_enet_private *fep = netdev_priv(dev); + unsigned long flags; + mii_list_t *mip; + int retval; + ++ retval = 0; ++ ++ spin_lock_irqsave(&fep->lock,flags); ++ + /* Add PHY address to register command. + */ +- fep = netdev_priv(dev); +- spin_lock_irqsave(&fep->mii_lock, flags); +- + regval |= fep->phy_addr << 23; +- retval = 0; + + if ((mip = mii_free) != NULL) { + mii_free = mip->mii_next; +@@ -745,32 +1082,32 @@ mii_queue(struct net_device *dev, int re + mii_tail = mip; + } else { + mii_head = mii_tail = mip; +- fep->hwp->fec_mii_data = regval; ++ fec_reg_write(fep, FEC_MMFR, regval); + } + } else { + retval = 1; + } + +- spin_unlock_irqrestore(&fep->mii_lock, flags); +- return retval; ++ spin_unlock_irqrestore(&fep->lock,flags); ++ ++ return(retval); + } + + static void mii_do_cmd(struct net_device *dev, const phy_cmd_t *c) + { +- if(!c) +- return; ++ int k; + +- for (; c->mii_data != mk_mii_end; c++) +- mii_queue(dev, c->mii_data, c->funct); ++ for (k = 0; c != NULL && c[k].mii_data != mk_mii_end; k++) { ++ mii_queue(dev, c[k].mii_data, c[k].funct); ++ } + } + + static void mii_parse_sr(uint mii_reg, struct net_device *dev) + { + struct fec_enet_private *fep = netdev_priv(dev); +- volatile uint *s = &(fep->phy_status); + uint status; + +- status = *s & ~(PHY_STAT_LINK | PHY_STAT_FAULT | PHY_STAT_ANC); ++ status = fep->phy_status & ~(PHY_STAT_LINK | PHY_STAT_FAULT | PHY_STAT_ANC); + + if (mii_reg & 0x0004) + status |= PHY_STAT_LINK; +@@ -778,31 +1115,30 @@ static void mii_parse_sr(uint mii_reg, s + status |= PHY_STAT_FAULT; + if (mii_reg & 0x0020) + status |= PHY_STAT_ANC; +- *s = status; ++ ++ fep->phy_status = status; + } + + static void mii_parse_cr(uint mii_reg, struct net_device *dev) + { + struct fec_enet_private *fep = netdev_priv(dev); +- volatile uint *s = &(fep->phy_status); + uint status; + +- status = *s & ~(PHY_CONF_ANE | PHY_CONF_LOOP); ++ status = fep->phy_status & ~(PHY_CONF_ANE | PHY_CONF_LOOP); + + if (mii_reg & 0x1000) + status |= PHY_CONF_ANE; + if (mii_reg & 0x4000) + status |= PHY_CONF_LOOP; +- *s = status; ++ fep->phy_status = status; + } + + static void mii_parse_anar(uint mii_reg, struct net_device *dev) + { + struct fec_enet_private *fep = netdev_priv(dev); +- volatile uint *s = &(fep->phy_status); + uint status; + +- status = *s & ~(PHY_CONF_SPMASK); ++ status = fep->phy_status & ~(PHY_CONF_SPMASK); + + if (mii_reg & 0x0020) + status |= PHY_CONF_10HDX; +@@ -812,7 +1148,7 @@ static void mii_parse_anar(uint mii_reg, + status |= PHY_CONF_100HDX; + if (mii_reg & 0x00100) + status |= PHY_CONF_100FDX; +- *s = status; ++ fep->phy_status = status; + } + + /* ------------------------------------------------------------------------- */ +@@ -827,10 +1163,9 @@ static void mii_parse_anar(uint mii_reg, + static void mii_parse_lxt970_csr(uint mii_reg, struct net_device *dev) + { + struct fec_enet_private *fep = netdev_priv(dev); +- volatile uint *s = &(fep->phy_status); + uint status; + +- status = *s & ~(PHY_STAT_SPMASK); ++ status = fep->phy_status & ~(PHY_STAT_SPMASK); + if (mii_reg & 0x0800) { + if (mii_reg & 0x1000) + status |= PHY_STAT_100FDX; +@@ -842,7 +1177,7 @@ static void mii_parse_lxt970_csr(uint mi + else + status |= PHY_STAT_10HDX; + } +- *s = status; ++ fep->phy_status = status; + } + + static phy_cmd_t const phy_cmd_lxt970_config[] = { +@@ -898,16 +1233,15 @@ static phy_info_t const phy_info_lxt970 + static void mii_parse_lxt971_sr2(uint mii_reg, struct net_device *dev) + { + struct fec_enet_private *fep = netdev_priv(dev); +- volatile uint *s = &(fep->phy_status); + uint status; + +- status = *s & ~(PHY_STAT_SPMASK | PHY_STAT_LINK | PHY_STAT_ANC); ++ status = fep->phy_status & ~(PHY_STAT_SPMASK | PHY_STAT_LINK | PHY_STAT_ANC); + + if (mii_reg & 0x0400) { +- fep->link = 1; ++ fep->linkstatus = 1; + status |= PHY_STAT_LINK; + } else { +- fep->link = 0; ++ fep->linkstatus = 0; + } + if (mii_reg & 0x0080) + status |= PHY_STAT_ANC; +@@ -925,7 +1259,7 @@ static void mii_parse_lxt971_sr2(uint mi + if (mii_reg & 0x0008) + status |= PHY_STAT_FAULT; + +- *s = status; ++ fep->phy_status = status; + } + + static phy_cmd_t const phy_cmd_lxt971_config[] = { +@@ -982,10 +1316,9 @@ static phy_info_t const phy_info_lxt971 + static void mii_parse_qs6612_pcr(uint mii_reg, struct net_device *dev) + { + struct fec_enet_private *fep = netdev_priv(dev); +- volatile uint *s = &(fep->phy_status); + uint status; + +- status = *s & ~(PHY_STAT_SPMASK); ++ status = fep->phy_status & ~(PHY_STAT_SPMASK); + + switch((mii_reg >> 2) & 7) { + case 1: status |= PHY_STAT_10HDX; break; +@@ -994,7 +1327,7 @@ static void mii_parse_qs6612_pcr(uint mi + case 6: status |= PHY_STAT_100FDX; break; + } + +- *s = status; ++ fep->phy_status = status; + } + + static phy_cmd_t const phy_cmd_qs6612_config[] = { +@@ -1052,10 +1385,9 @@ static phy_info_t const phy_info_qs6612 + static void mii_parse_am79c874_dr(uint mii_reg, struct net_device *dev) + { + struct fec_enet_private *fep = netdev_priv(dev); +- volatile uint *s = &(fep->phy_status); + uint status; + +- status = *s & ~(PHY_STAT_SPMASK | PHY_STAT_ANC); ++ status = fep->phy_status & ~(PHY_STAT_SPMASK | PHY_STAT_ANC); + + if (mii_reg & 0x0080) + status |= PHY_STAT_ANC; +@@ -1064,7 +1396,7 @@ static void mii_parse_am79c874_dr(uint m + else + status |= ((mii_reg & 0x0800) ? PHY_STAT_10FDX : PHY_STAT_10HDX); + +- *s = status; ++ fep->phy_status = status; + } + + static phy_cmd_t const phy_cmd_am79c874_config[] = { +@@ -1107,7 +1439,7 @@ static phy_info_t const phy_info_am79c87 + /* register definitions for the 8721 */ + + #define MII_KS8721BL_RXERCR 21 +-#define MII_KS8721BL_ICSR 27 ++#define MII_KS8721BL_ICSR 22 + #define MII_KS8721BL_PHYCR 31 + + static phy_cmd_t const phy_cmd_ks8721bl_config[] = { +@@ -1149,32 +1481,31 @@ static phy_info_t const phy_info_ks8721b + static void mii_parse_dp8384x_sr2(uint mii_reg, struct net_device *dev) + { + struct fec_enet_private *fep = netdev_priv(dev); +- volatile uint *s = &(fep->phy_status); + +- *s &= ~(PHY_STAT_SPMASK | PHY_STAT_LINK | PHY_STAT_ANC); ++ fep->phy_status &= ~(PHY_STAT_SPMASK | PHY_STAT_LINK | PHY_STAT_ANC); + + /* Link up */ + if (mii_reg & 0x0001) { +- fep->link = 1; +- *s |= PHY_STAT_LINK; ++ fep->linkstatus = 1; ++ fep->phy_status |= PHY_STAT_LINK; + } else +- fep->link = 0; ++ fep->linkstatus = 0; + /* Status of link */ + if (mii_reg & 0x0010) /* Autonegotioation complete */ +- *s |= PHY_STAT_ANC; ++ fep->phy_status |= PHY_STAT_ANC; + if (mii_reg & 0x0002) { /* 10MBps? */ + if (mii_reg & 0x0004) /* Full Duplex? */ +- *s |= PHY_STAT_10FDX; ++ fep->phy_status |= PHY_STAT_10FDX; + else +- *s |= PHY_STAT_10HDX; ++ fep->phy_status |= PHY_STAT_10HDX; + } else { /* 100 Mbps? */ + if (mii_reg & 0x0004) /* Full Duplex? */ +- *s |= PHY_STAT_100FDX; ++ fep->phy_status |= PHY_STAT_100FDX; + else +- *s |= PHY_STAT_100HDX; ++ fep->phy_status |= PHY_STAT_100HDX; + } + if (mii_reg & 0x0008) +- *s |= PHY_STAT_FAULT; ++ fep->phy_status |= PHY_STAT_FAULT; + } + + static phy_info_t phy_info_dp83848= { +@@ -1211,92 +1542,362 @@ static phy_info_t const * const phy_info + &phy_info_dp83848, + NULL + }; +- +-/* ------------------------------------------------------------------------- */ +-#ifdef HAVE_mii_link_interrupt +-static irqreturn_t +-mii_link_interrupt(int irq, void * dev_id); ++#endif + + /* +- * This is specific to the MII interrupt setup of the M5272EVB. ++ * do some initializtion based architecture of this chip ++MOVED to platform_data hooks! + */ +-static void __inline__ fec_request_mii_intr(struct net_device *dev) +-{ +- if (request_irq(66, mii_link_interrupt, IRQF_DISABLED, "fec(MII)", dev) != 0) +- printk("FEC: Could not allocate fec(MII) IRQ(66)!\n"); +-} + +-static void __inline__ fec_disable_phy_intr(void) +-{ +- volatile unsigned long *icrp; +- icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1); +- *icrp = 0x08000000; +-} ++#define PHY_POLL_LINK_ON (1 * HZ) ++#define PHY_POLL_LINK_OFF (HZ / 5) + +-static void __inline__ fec_phy_ack_intr(void) ++static int fec_mii_read(struct mii_bus *bus, int phy_id, int regnum); ++ ++#ifdef CONFIG_PHYLIB ++static void fec_link_change(struct net_device *dev) + { +- volatile unsigned long *icrp; +- /* Acknowledge the interrupt */ +- icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1); +- *icrp = 0x0d000000; +-} +-#endif ++ struct fec_enet_private *fep = netdev_priv(dev); ++ struct phy_device *phydev = fep->phy; + +-#ifdef CONFIG_M5272 +-static void __inline__ fec_get_mac(struct net_device *dev) ++ if (phydev->link != fep->linkstatus || ++ phydev->duplex != fep->full_duplex) { ++ DBG(0, "%s: link status changed from %d to %d %s -> %s duplex\n", __FUNCTION__, ++ fep->linkstatus, phydev->link, fep->full_duplex ? "full" : "half", ++ phydev->duplex ? "full" : "half"); ++ if (phydev->link) { ++ fec_restart(dev, phydev->duplex); ++ } else { ++ fec_stop(dev); ++ } ++ if (fep->linkstatus != phydev->link && netif_msg_link(fep)) { ++ phy_print_status(phydev); ++ } ++ fep->linkstatus = phydev->link; ++#if 0 ++ int i; ++ for (i = 0; i < 32; i++) { ++ DBG(0, "%s: PHY reg[%02x]=%04x\n", __FUNCTION__, i, ++ fec_mii_read(fep->mii, fep->phy_addr, i)); ++ } ++#endif ++ } ++} ++#else ++static void fec_link_change(struct net_device *dev) + { + struct fec_enet_private *fep = netdev_priv(dev); +- volatile fec_t *fecp; +- unsigned char *iap, tmpaddr[ETH_ALEN]; + +- fecp = fep->hwp; ++ DBG(0, "%s: link status changed from %d to %d\n", __FUNCTION__, ++ fep->old_linkstatus, fep->linkstatus); ++ if (fep->linkstatus) { ++ int duplex; + +- if (FEC_FLASHMAC) { +- /* +- * Get MAC address from FLASH. +- * If it is all 1's or 0's, use the default. +- */ +- iap = (unsigned char *)FEC_FLASHMAC; +- if ((iap[0] == 0) && (iap[1] == 0) && (iap[2] == 0) && +- (iap[3] == 0) && (iap[4] == 0) && (iap[5] == 0)) +- iap = fec_mac_default; +- if ((iap[0] == 0xff) && (iap[1] == 0xff) && (iap[2] == 0xff) && +- (iap[3] == 0xff) && (iap[4] == 0xff) && (iap[5] == 0xff)) +- iap = fec_mac_default; ++ duplex = 0; ++ if (fep->phy_status & (PHY_STAT_100FDX | PHY_STAT_10FDX)) { ++ duplex = 1; ++ } ++ fec_restart(dev, duplex); ++ if (fep->phy_timer) { ++ mod_timer(fep->phy_timer, jiffies + PHY_POLL_LINK_ON); ++ } + } else { +- *((unsigned long *) &tmpaddr[0]) = fecp->fec_addr_low; +- *((unsigned short *) &tmpaddr[4]) = (fecp->fec_addr_high >> 16); +- iap = &tmpaddr[0]; ++ fec_stop(dev); ++ if (fep->phy_timer) { ++ mod_timer(fep->phy_timer, jiffies + PHY_POLL_LINK_OFF); ++ } + } + +- memcpy(dev->dev_addr, iap, ETH_ALEN); +- +- /* Adjust MAC if using default MAC address */ +- if (iap == fec_mac_default) +- dev->dev_addr[ETH_ALEN-1] = fec_mac_default[ETH_ALEN-1] + fep->index; ++ fep->old_linkstatus = fep->linkstatus; + } +-#endif + +-/* ------------------------------------------------------------------------- */ +- +-static void mii_display_status(struct net_device *dev) ++static void fec_phy_timer(unsigned long data) + { ++ struct net_device *dev = (struct net_device *)data; + struct fec_enet_private *fep = netdev_priv(dev); +- volatile uint *s = &(fep->phy_status); ++ int link_poll_interval = fep->linkstatus ? PHY_POLL_LINK_ON : PHY_POLL_LINK_OFF; + +- if (!fep->link && !fep->old_link) { +- /* Link is still down - don't print anything */ ++ if (fep->old_linkstatus != fep->linkstatus) { ++ fec_link_change(dev); ++ } ++ mod_timer(fep->phy_timer, link_poll_interval); ++} ++#endif ++ ++/* ++ * Code specific to Freescale i.MXC ++ */ ++static int fec_request_intrs(struct platform_device *pdev, struct net_device *dev) ++{ ++ int ret; ++ struct fec_enet_private *fep = netdev_priv(dev); ++ ++ fep->etn_irq = platform_get_irq(pdev, 0); ++ fep->mii_irq = platform_get_irq(pdev, 1); ++ ++ /* Setup interrupt handlers. */ ++ ret = request_irq(fep->etn_irq, fec_enet_interrupt, 0, "fec", dev); ++ if (ret != 0) { ++ printk(KERN_ERR "FEC: Could not allocate FEC IRQ(%d)!\n", fep->etn_irq); ++ return ret; ++ } ++#ifndef CONFIG_PHYLIB ++ if (fep->mii_irq >= 0) { ++ /* TODO: disable now due to CPLD issue */ ++ ret = request_irq(fep->mii_irq, mii_link_interrupt, 0, "fec(MII)", dev); ++ if (ret != 0) { ++ printk(KERN_ERR "FEC: Could not allocate FEC(MII) IRQ(%d)!\n", ++ fep->mii_irq); ++ free_irq(fep->etn_irq, dev); ++ return ret; ++ } ++ /* ++ * board specific workaround should be done in board specific code ++ * This is unsafe anyway. An interrupt might have been asserted ++ * already. Use IRQ_NOAUTOEN with request_irq() to have irq initially disabled. ++ */ ++ fep->phy_int_enabled = 1; ++ } else { ++ fep->phy_timer = kzalloc(sizeof(struct timer_list), GFP_KERNEL); ++ if (fep->phy_timer == NULL) { ++ free_irq(fep->etn_irq, dev); ++ return -ENOMEM; ++ } ++ init_timer(fep->phy_timer); ++ fep->phy_timer->function = fec_phy_timer; ++ fep->phy_timer->data = (unsigned long)dev; ++ fec_link_change(dev); ++ } ++#endif ++ ++ return 0; ++} ++ ++static void fec_release_intrs(struct net_device *dev) ++{ ++ struct fec_enet_private *fep = netdev_priv(dev); ++ ++ free_irq(fep->etn_irq, dev); ++#ifndef CONFIG_PHYLIB ++ if (fep->mii_irq >= 0) { ++ free_irq(fep->mii_irq, dev); ++ } ++#endif ++} ++ ++#ifdef CONFIG_MACH_MX25 ++/* ++ * i.MX25 allows RMII mode to be configured via a gasket ++ */ ++#define FEC_MIIGSK_CFGR 0x300 ++#define FEC_MIIGSK_ENR 0x308 ++ ++#define FEC_MIIGSK_CFGR_FRCONT (1 << 6) ++#define FEC_MIIGSK_CFGR_LBMODE (1 << 4) ++#define FEC_MIIGSK_CFGR_EMODE (1 << 3) ++#define FEC_MIIGSK_CFGR_IF_MODE_MASK (3 << 0) ++#define FEC_MIIGSK_CFGR_IF_MODE_MII (0 << 0) ++#define FEC_MIIGSK_CFGR_IF_MODE_RMII (1 << 0) ++ ++#define FEC_MIIGSK_ENR_READY (1 << 2) ++#define FEC_MIIGSK_ENR_EN (1 << 1) ++ ++#ifndef DEBUG ++static inline unsigned long fec_reg_read16(struct fec_enet_private *fep, unsigned int reg) ++{ ++ return readw(fep->reg_base + reg); ++} ++ ++static inline void fec_reg_write(struct fec_enet_private *fep, unsigned int reg, unsigned long val) ++{ ++ writew(val, fep->reg_base + reg); ++} ++#else ++#define fec_reg_read16(fep, reg) __fec_reg_read16(fep, reg, __FUNCTION__, #reg) ++#define fec_reg_write16(fep, reg, val) __fec_reg_write16(fep, reg, val, __FUNCTION__, #reg) ++ ++static inline u16 __fec_reg_read16(struct fec_enet_private *fep, unsigned int reg, ++ const char *func, const char *reg_name) ++{ ++ u16 val = readw(fep->reg_base + reg); ++ DBG(0, "%s: Read %04x from %s(%03x)\n", func, val, reg_name, reg); ++ return val; ++} ++ ++static inline void __fec_reg_write16(struct fec_enet_private *fep, unsigned int reg, ++ u16 val, const char *func, const char *reg_name) ++{ ++ DBG(0, "%s: Writing %04x to %s(%03x)\n", func, val, reg_name, reg); ++ writew(val, fep->reg_base + reg); ++} ++#endif ++ ++static void fec_localhw_setup(struct net_device *dev) ++{ ++ struct fec_enet_private *fep = netdev_priv(dev); ++ int loops; ++ const int max_loops = 10000; ++ ++ /* ++ * Set up the MII gasket for RMII mode ++ */ ++ dev_dbg(&dev->dev, "enable RMII gasket\n"); ++ ++ /* disable the gasket and wait */ ++ fec_reg_write16(fep, FEC_MIIGSK_ENR, 0); ++ DBG(0, "%s: Waiting for RMII gasket idle\n", __FUNCTION__); ++ while (fec_reg_read16(fep, FEC_MIIGSK_ENR) & FEC_MIIGSK_ENR_READY) ++ udelay(1); ++ DBG(0, "%s: RMII gasket idle\n", __FUNCTION__); ++ ++ /* configure the gasket for RMII, 50 MHz, no loopback, no echo */ ++ fec_reg_write16(fep, FEC_MIIGSK_CFGR, FEC_MIIGSK_CFGR_IF_MODE_RMII); ++ ++ /* re-enable the gasket */ ++ fec_reg_write16(fep, FEC_MIIGSK_ENR, FEC_MIIGSK_ENR_EN); ++ fec_reg_read16(fep, FEC_MIIGSK_CFGR); ++ fec_reg_read16(fep, FEC_MIIGSK_ENR); ++ ++#if 1 ++ DBG(0, "%s: Waiting for RMII gasket ready\n", __FUNCTION__); ++ for (loops = 0; loops < max_loops; loops++) { ++ if (readw(fep->reg_base + FEC_MIIGSK_ENR) & FEC_MIIGSK_ENR_READY) ++ break; ++ udelay(1); ++ } ++ if (fec_reg_read16(fep, FEC_MIIGSK_ENR) & FEC_MIIGSK_ENR_READY) { ++ DBG(0, "%s: RMII gasket ready after %u loops\n", __FUNCTION__, loops); ++ } else { ++ DBG(0, "%s: RMII gasket NOT ready after %u loops\n", __FUNCTION__, loops); ++ } ++#endif ++} ++#else ++static inline void fec_localhw_setup(struct net_device *dev) ++{ ++} ++#endif ++ ++static int fec_set_mii(struct net_device *dev, struct fec_enet_private *fep) ++{ ++ unsigned long rate; ++ struct clk *clk; ++ ++ DBG(0, "%s: \n", __FUNCTION__); ++ ++ fec_reg_write(fep, FEC_RCR, OPT_FRAME_SIZE | RCR_MII_MODE); ++ fec_reg_write(fep, FEC_TCR, 0x00); ++ ++ /* ++ * Set MII speed to 2.5 MHz ++ */ ++ clk = clk_get(fep->dma_dev, NULL); ++ if (!IS_ERR(clk)) { ++ rate = clk_get_rate(clk); ++ clk_put(clk); ++ } else { ++ printk(KERN_ERR "Failed to get fec clock: %ld\n", PTR_ERR(clk)); ++ return PTR_ERR(clk); ++ } ++ fep->phy_speed = ((((rate + 4999999) / 2500000) / 2) & 0x3F) << 1; ++ fec_reg_write(fep, FEC_MSCR, fep->phy_speed); ++ DBG(0, "%s: clkdiv set to %u for MII clock %u at base clock %lu\n", ++ __FUNCTION__, fep->phy_speed >> 1, 2500000, rate); ++ DBG(0, "%s: actual MII clock is: %lu\n", __FUNCTION__, rate / (fep->phy_speed)); ++ ++ return 0; ++} ++ ++static const unsigned char default_mac[ETH_ALEN] = { ++ 0x00, 0x04, 0x9f, 0x00, 0x74, 0x4a, ++}; ++ ++#define FEC_IIM_BASE IO_ADDRESS(IIM_BASE_ADDR) ++static void fec_get_mac(struct net_device *dev) ++{ ++#if 1 ++ // keep bootloader assigned MAC address ++ struct fec_enet_private *fep = netdev_priv(dev); ++ unsigned long eth_addr = fec_reg_read(fep, FEC_PALR); ++ dev->dev_addr[0] = eth_addr >> 24; ++ dev->dev_addr[1] = eth_addr >> 16; ++ dev->dev_addr[2] = eth_addr >> 8; ++ dev->dev_addr[3] = eth_addr >> 0; ++ eth_addr = fec_reg_read(fep, FEC_PAUR); ++ dev->dev_addr[5] = eth_addr >> 16; ++ dev->dev_addr[4] = eth_addr >> 24; ++#else ++ int i; ++ unsigned long fec_mac_base = FEC_IIM_BASE + MXC_IIMKEY0; ++ ++ if (cpu_is_mx27_rev(CHIP_REV_2_0) > 0) { ++ fec_mac_base = FEC_IIM_BASE + MXC_IIMMAC; ++ } ++ ++ DBG(0, "%s: Reading MAC address from %08lx\n", __FUNCTION__, fec_mac_base); ++ for (i = 0; i < ETH_ALEN; i++) { ++ dev->dev_addr[ETH_ALEN - 1 - i] = __raw_readb(fec_mac_base + i * 4); ++ } ++ //memcpy(dev->dev_addr, default_mac, ETH_ALEN); ++#endif ++} ++ ++#ifdef CONFIG_PHYLIB ++static inline void fec_enable_phy_intr(struct fec_enet_private *fep) ++{ ++} ++static inline void fec_disable_phy_intr(struct fec_enet_private *fep) ++{ ++} ++static inline void fec_phy_ack_intr(struct fec_enet_private *fep) ++{ ++} ++#else ++static inline void fec_enable_phy_intr(struct fec_enet_private *fep) ++{ ++ if (!fep->phy_int_enabled) { ++ fep->phy_int_enabled = 1; ++ enable_irq(fep->mii_irq); ++ } ++} ++ ++static inline void fec_disable_phy_intr(struct fec_enet_private *fep) ++{ ++ if (fep->phy_int_enabled) { ++ disable_irq(fep->mii_irq); ++ fep->phy_int_enabled = 0; ++ } ++} ++ ++static inline void fec_phy_ack_intr(struct fec_enet_private *fep) ++{ ++ if (fep->phy_int_enabled) { ++ disable_irq(fep->mii_irq); ++ fep->phy_int_enabled = 0; ++ } ++} ++#endif ++ ++/* ------------------------------------------------------------------------- */ ++ ++#ifndef CONFIG_PHYLIB ++static void mii_display_status(struct net_device *dev) ++{ ++ struct fec_enet_private *fep = netdev_priv(dev); ++ ++ if (!fep->linkstatus && !fep->old_linkstatus) { ++ /* Link is still down - don't print anything */ + return; + } + + printk("%s: status: ", dev->name); + +- if (!fep->link) { ++ if (!fep->linkstatus) { + printk("link down"); + } else { + printk("link up"); + +- switch(*s & PHY_STAT_SPMASK) { ++ switch(fep->phy_status & PHY_STAT_SPMASK) { + case PHY_STAT_100FDX: printk(", 100MBit Full Duplex"); break; + case PHY_STAT_100HDX: printk(", 100MBit Half Duplex"); break; + case PHY_STAT_10FDX: printk(", 10MBit Full Duplex"); break; +@@ -1305,20 +1906,19 @@ static void mii_display_status(struct ne + printk(", Unknown speed/duplex"); + } + +- if (*s & PHY_STAT_ANC) ++ if (fep->phy_status & PHY_STAT_ANC) + printk(", auto-negotiation complete"); + } + +- if (*s & PHY_STAT_FAULT) ++ if (fep->phy_status & PHY_STAT_FAULT) + printk(", remote fault"); + + printk(".\n"); + } + +-static void mii_display_config(struct work_struct *work) ++static void mii_display_config(struct work_struct *w) + { +- struct fec_enet_private *fep = container_of(work, struct fec_enet_private, phy_task); +- struct net_device *dev = fep->netdev; ++ struct fec_enet_private *fep = container_of(w, struct fec_enet_private, phy_task); + uint status = fep->phy_status; + + /* +@@ -1326,7 +1926,7 @@ static void mii_display_config(struct wo + ** the workqueue. It is thus safe to allow to reuse it. + */ + fep->mii_phy_task_queued = 0; +- printk("%s: config: auto-negotiation ", dev->name); ++ //printk("%s: config: auto-negotiation ", dev->name); + + if (status & PHY_CONF_ANE) + printk("on"); +@@ -1351,11 +1951,21 @@ static void mii_display_config(struct wo + + fep->sequence_done = 1; + } ++#endif + +-static void mii_relink(struct work_struct *work) ++#ifndef CONFIG_PHYLIB ++static inline void *priv_netdev(struct fec_enet_private *fep) + { +- struct fec_enet_private *fep = container_of(work, struct fec_enet_private, phy_task); +- struct net_device *dev = fep->netdev; ++ /* ugly hack, stolen from include linux/netdevice.h */ ++ return (char *)fep - ((sizeof(struct net_device) ++ + NETDEV_ALIGN_CONST) ++ & ~NETDEV_ALIGN_CONST); ++} ++ ++static void mii_relink(struct work_struct *w) ++{ ++ struct fec_enet_private *fep = container_of(w, struct fec_enet_private, phy_task); ++ struct net_device *dev = priv_netdev(fep); + int duplex; + + /* +@@ -1363,23 +1973,19 @@ static void mii_relink(struct work_struc + ** the workqueue. It is thus safe to allow to reuse it. + */ + fep->mii_phy_task_queued = 0; +- fep->link = (fep->phy_status & PHY_STAT_LINK) ? 1 : 0; ++ fep->linkstatus = (fep->phy_status & PHY_STAT_LINK) ? 1 : 0; + mii_display_status(dev); +- fep->old_link = fep->link; ++ fep->old_linkstatus = fep->linkstatus; + +- if (fep->link) { ++ if (fep->linkstatus) { + duplex = 0; +- if (fep->phy_status +- & (PHY_STAT_100FDX | PHY_STAT_10FDX)) ++ if (fep->phy_status & (PHY_STAT_100FDX | PHY_STAT_10FDX)) { + duplex = 1; ++ } + fec_restart(dev, duplex); +- } else ++ } else { + fec_stop(dev); +- +-#if 0 +- enable_irq(fep->mii_irq); +-#endif +- ++ } + } + + /* mii_queue_relink is called in interrupt context from mii_link_interrupt */ +@@ -1429,15 +2035,14 @@ phy_cmd_t const phy_cmd_config[] = { + static void + mii_discover_phy3(uint mii_reg, struct net_device *dev) + { +- struct fec_enet_private *fep; ++ struct fec_enet_private *fep = netdev_priv(dev); + int i; + +- fep = netdev_priv(dev); + fep->phy_id |= (mii_reg & 0xffff); + printk("fec: PHY @ 0x%x, ID 0x%08x", fep->phy_addr, fep->phy_id); + +- for(i = 0; phy_info[i]; i++) { +- if(phy_info[i]->id == (fep->phy_id >> 4)) ++ for (i = 0; phy_info[i]; i++) { ++ if (phy_info[i]->id == (fep->phy_id >> 4)) + break; + } + +@@ -1456,13 +2061,9 @@ mii_discover_phy3(uint mii_reg, struct n + static void + mii_discover_phy(uint mii_reg, struct net_device *dev) + { +- struct fec_enet_private *fep; +- volatile fec_t *fecp; ++ struct fec_enet_private *fep = netdev_priv(dev); + uint phytype; + +- fep = netdev_priv(dev); +- fecp = fep->hwp; +- + if (fep->phy_addr < 32) { + if ((phytype = (mii_reg & 0xffff)) != 0xffff && phytype != 0) { + +@@ -1470,39 +2071,40 @@ mii_discover_phy(uint mii_reg, struct ne + */ + fep->phy_id = phytype << 16; + mii_queue(dev, mk_mii_read(MII_REG_PHYIR2), +- mii_discover_phy3); ++ mii_discover_phy3); + } else { + fep->phy_addr++; + mii_queue(dev, mk_mii_read(MII_REG_PHYIR1), +- mii_discover_phy); ++ mii_discover_phy); + } + } else { + printk("FEC: No PHY device found.\n"); + /* Disable external MII interface */ +- fecp->fec_mii_speed = fep->phy_speed = 0; +-#ifdef HAVE_mii_link_interrupt +- fec_disable_phy_intr(); +-#endif ++ fec_disable_phy_intr(fep); ++ fec_reg_write(fep, FEC_MSCR, 0); + } + } ++#endif + +-/* This interrupt occurs when the PHY detects a link change. +-*/ +-#ifdef HAVE_mii_link_interrupt ++#ifndef CONFIG_PHYLIB + static irqreturn_t +-mii_link_interrupt(int irq, void * dev_id) ++mii_link_interrupt(int irq, void *dev_id) + { +- struct net_device *dev = dev_id; ++ struct net_device *dev = dev_id; + struct fec_enet_private *fep = netdev_priv(dev); + +- fec_phy_ack_intr(); ++ DBG(0, "%s: \n", __FUNCTION__); + +-#if 0 +- disable_irq(fep->mii_irq); /* disable now, enable later */ +-#endif ++ fec_phy_ack_intr(fep); + +- mii_do_cmd(dev, fep->phy->ack_int); +- mii_do_cmd(dev, phy_cmd_relink); /* restart and display status */ ++ /* ++ * Some board will trigger phy interrupt before phy enable. ++ * And at that moment , fep->phy is not initialized. ++ */ ++ if (fep->phy) { ++ mii_do_cmd(dev, fep->phy->ack_int); ++ mii_do_cmd(dev, phy_cmd_relink); /* restart and display status */ ++ } + + return IRQ_HANDLED; + } +@@ -1511,16 +2113,31 @@ mii_link_interrupt(int irq, void * dev_i + static int + fec_enet_open(struct net_device *dev) + { ++ int ret = 0; + struct fec_enet_private *fep = netdev_priv(dev); + + /* I should reset the ring buffers here, but I don't yet know + * a simple way to do that. + */ +- fec_set_mac_address(dev); ++ DBG(0, "%s: \n", __FUNCTION__); ++ _fec_set_mac_address(dev); + +- fep->sequence_done = 0; +- fep->link = 0; ++#ifdef CONFIG_PHYLIB ++ fec_restart(dev, 0); + ++ ret = fec_connect_phy(dev, fep); ++ if (ret != 0) { ++ DBG(0, "%s: Failed to connect to PHY: %d\n", __FUNCTION__, ret); ++ return ret; ++ } ++ phy_start(fep->phy); ++ ++ fep->linkstatus = fep->phy->link; ++ //fec_restart(dev, 0); ++ DBG(0, "%s: Link status is: %d\n", __FUNCTION__, fep->linkstatus); ++#else ++ fep->linkstatus = 0; ++ fep->sequence_done = 0; + if (fep->phy) { + mii_do_cmd(dev, fep->phy->ack_int); + mii_do_cmd(dev, fep->phy->config); +@@ -1542,16 +2159,20 @@ fec_enet_open(struct net_device *dev) + * based on this device does not implement a PHY interrupt, + * so we are never notified of link change. + */ +- fep->link = 1; ++ fep->linkstatus = 1; + } else { +- fep->link = 1; /* lets just try it and see */ ++ fep->linkstatus = 1; /* lets just try it and see */ + /* no phy, go full duplex, it's most likely a hub chip */ + fec_restart(dev, 1); + } +- +- netif_start_queue(dev); ++ fep->old_linkstatus = fep->linkstatus; ++#endif + fep->opened = 1; +- return 0; /* Success */ ++#if 1 ++ /* enable receiver */ ++ fec_reg_write(fep, FEC_RDAR, DONT_CARE); ++#endif ++ return ret; + } + + static int +@@ -1559,15 +2180,46 @@ fec_enet_close(struct net_device *dev) + { + struct fec_enet_private *fep = netdev_priv(dev); + +- /* Don't know what to do yet. +- */ ++ DBG(0, "%s: \n", __FUNCTION__); ++ + fep->opened = 0; +- netif_stop_queue(dev); +- fec_stop(dev); ++ if (fep->linkstatus) { ++ fec_stop(dev); ++ } ++#ifdef CONFIG_PHYLIB ++ if (fep->phy) { ++ DBG(0, "%s: Stopping PHY %p\n", __FUNCTION__, fep->phy); ++ phy_stop(fep->phy); + ++ DBG(0, "%s: Disconnecting PHY %p\n", __FUNCTION__, fep->phy); ++ phy_disconnect(fep->phy); ++ fep->phy = NULL; ++ } ++#endif ++#if 1 ++ /* Whack a reset. We should wait for this. ++ */ ++ fec_reg_write(fep, FEC_ECR, FEC_ECR_RESET); ++ udelay(10); ++ ++ /* Mask and clear outstanding MII command interrupts. ++ */ ++ fec_reg_write(fep, FEC_EIMR, 0); ++ fec_reg_write(fep, FEC_EIR, FEC_ENET_MII); ++ fec_disable_phy_intr(fep); ++ /* Switch off MII */ ++ fec_reg_write(fep, FEC_MSCR, 0); ++#endif + return 0; + } + ++static struct net_device_stats *fec_enet_get_stats(struct net_device *dev) ++{ ++ struct fec_enet_private *fep = netdev_priv(dev); ++ ++ return &fep->stats; ++} ++ + /* Set or clear the multicast filter for this adaptor. + * Skeleton taken from sunlance driver. + * The CPM Ethernet implementation allows Multicast as well as individual +@@ -1583,37 +2235,32 @@ fec_enet_close(struct net_device *dev) + + static void set_multicast_list(struct net_device *dev) + { +- struct fec_enet_private *fep; +- volatile fec_t *ep; ++ struct fec_enet_private *fep = netdev_priv(dev); + struct dev_mc_list *dmi; + unsigned int i, j, bit, data, crc; + unsigned char hash; + +- fep = netdev_priv(dev); +- ep = fep->hwp; +- +- if (dev->flags&IFF_PROMISC) { +- ep->fec_r_cntrl |= 0x0008; ++ if (dev->flags & IFF_PROMISC) { ++ fec_reg_write(fep, FEC_RCR, fec_reg_read(fep, FEC_RCR) | RCR_PROM); + } else { + +- ep->fec_r_cntrl &= ~0x0008; ++ fec_reg_write(fep, FEC_RCR, fec_reg_read(fep, FEC_RCR) & ~RCR_PROM); + + if (dev->flags & IFF_ALLMULTI) { + /* Catch all multicast addresses, so set the + * filter to all 1's. + */ +- ep->fec_grp_hash_table_high = 0xffffffff; +- ep->fec_grp_hash_table_low = 0xffffffff; ++ fec_reg_write(fep, FEC_IAUR, ~0); ++ fec_reg_write(fep, FEC_IALR, ~0); + } else { + /* Clear filter and add the addresses in hash register. + */ +- ep->fec_grp_hash_table_high = 0; +- ep->fec_grp_hash_table_low = 0; ++ fec_reg_write(fep, FEC_IAUR, 0); ++ fec_reg_write(fep, FEC_IALR, 0); + + dmi = dev->mc_list; + +- for (j = 0; j < dev->mc_count; j++, dmi = dmi->next) +- { ++ for (j = 0; j < dev->mc_count; j++, dmi = dmi->next) { + /* Only support group multicast for now. + */ + if (!(dmi->dmi_addr[0] & 1)) +@@ -1621,13 +2268,11 @@ static void set_multicast_list(struct ne + + /* calculate crc32 value of mac address + */ +- crc = 0xffffffff; ++ crc = ~0; + +- for (i = 0; i < dmi->dmi_addrlen; i++) +- { ++ for (i = 0; i < dmi->dmi_addrlen; i++) { + data = dmi->dmi_addr[i]; +- for (bit = 0; bit < 8; bit++, data >>= 1) +- { ++ for (bit = 0; bit < 8; bit++, data >>= 1) { + crc = (crc >> 1) ^ + (((crc ^ data) & 1) ? CRC32_POLY : 0); + } +@@ -1639,9 +2284,13 @@ static void set_multicast_list(struct ne + hash = (crc >> (32 - HASH_BITS)) & 0x3f; + + if (hash > 31) +- ep->fec_grp_hash_table_high |= 1 << (hash - 32); ++ fec_reg_write(fep, FEC_IAUR, ++ fec_reg_read(fep, FEC_IAUR) | ++ (1 << (hash - 32))); + else +- ep->fec_grp_hash_table_low |= 1 << hash; ++ fec_reg_write(fep, FEC_IALR, ++ fec_reg_read(fep, FEC_IALR) | ++ (1 << hash)); + } + } + } +@@ -1650,106 +2299,272 @@ static void set_multicast_list(struct ne + /* Set a MAC change in hardware. + */ + static void +-fec_set_mac_address(struct net_device *dev) ++_fec_set_mac_address(struct net_device *dev) + { +- volatile fec_t *fecp; +- +- fecp = ((struct fec_enet_private *)netdev_priv(dev))->hwp; ++ struct fec_enet_private *fep = netdev_priv(dev); + + /* Set station address. */ +- fecp->fec_addr_low = dev->dev_addr[3] | (dev->dev_addr[2] << 8) | +- (dev->dev_addr[1] << 16) | (dev->dev_addr[0] << 24); +- fecp->fec_addr_high = (dev->dev_addr[5] << 16) | +- (dev->dev_addr[4] << 24); ++ fec_reg_write(fep, FEC_PALR, dev->dev_addr[3] | (dev->dev_addr[2] << 8) | ++ (dev->dev_addr[1] << 16) | (dev->dev_addr[0] << 24)); ++ fec_reg_write(fep, FEC_PAUR, (dev->dev_addr[5] << 16) | ++ (dev->dev_addr[4] << 24)); ++} ++ ++static int ++fec_set_mac_address(struct net_device *dev, void *_addr) ++{ ++ struct sockaddr *addr = _addr; ++ ++ if (!is_valid_ether_addr((const char *)&addr->sa_data)) { ++ printk(KERN_WARNING "Bad ethernet address: %02x:%02x:%02x:%02x:%02x:%02x\n", ++ addr->sa_data[0], addr->sa_data[1], addr->sa_data[2], addr->sa_data[3], ++ addr->sa_data[4], addr->sa_data[5]); ++ return -EINVAL; ++ } ++ printk(KERN_DEBUG "Setting MAC address to %02x:%02x:%02x:%02x:%02x:%02x\n", ++ addr->sa_data[0], addr->sa_data[1], addr->sa_data[2], addr->sa_data[3], ++ addr->sa_data[4], addr->sa_data[5]); ++ ++ memcpy(&dev->dev_addr, &addr->sa_data, ETH_ALEN); + ++ _fec_set_mac_address(dev); ++ ++ return 0; + } + +- /* +- * XXX: We need to clean up on failure exits here. +- * +- * index is only used in legacy code +- */ +-int __init fec_enet_init(struct net_device *dev, int index) ++static void fec_enet_free_buffers(struct fec_enet_private *fep) ++{ ++ cbd_t *bdp = fep->rx_bd_base; ++ int i; ++ ++ DBG(0, "%s: Freeing TX bounce buffers %p\n", __FUNCTION__, fep->tx_bounce[0]); ++ kfree(fep->tx_bounce[0]); ++ memset(fep->tx_bounce, 0, TX_RING_SIZE * sizeof(void*)); ++ for (i = 0; i < RX_RING_SIZE; i++, bdp++) { ++ if (fep->rx_skbuff[i] != NULL) { ++ DBG(0, "%s: Freeing RX skb %p\n", __FUNCTION__, fep->rx_skbuff[i]); ++ fec_enet_rxbuf_unmap(fep, bdp, FEC_ENET_RX_FRSIZE); ++ kfree_skb(fep->rx_skbuff[i]); ++ fep->rx_skbuff[i] = NULL; ++ } ++ } ++} ++ ++#ifdef CONFIG_PHYLIB ++/* called by the generic PHY layer in interrupt context */ ++static int phy_regs[32] = { [0 ... ARRAY_SIZE(phy_regs) - 1] = -1}; ++static int fec_mii_read(struct mii_bus *bus, int phy_id, int regnum) + { ++ int ret; ++ struct net_device *dev = bus->priv; + struct fec_enet_private *fep = netdev_priv(dev); +- unsigned long mem_addr; +- volatile cbd_t *bdp; +- cbd_t *cbd_base; +- volatile fec_t *fecp; +- int i, j; ++ unsigned long regval = mk_mii_read(regnum) | phy_id << 23; ++ unsigned long flags; ++ int loops = 0; + +- /* Allocate memory for buffer descriptors. +- */ +- mem_addr = (unsigned long)dma_alloc_coherent(NULL, PAGE_SIZE, +- &fep->bd_dma, GFP_KERNEL); +- if (mem_addr == 0) { +- printk("FEC: allocate descriptor memory failed?\n"); ++ DBG(1, "%s: \n", __FUNCTION__); ++#if 0 ++ DBG(0, "%s: ECR: %08lx\n", __FUNCTION__, fec_reg_read(fep, FEC_ECR)); ++ DBG(0, "%s: EIR: %08lx\n", __FUNCTION__, fec_reg_read(fep, FEC_EIR)); ++ DBG(0, "%s: EIMR: %08lx\n", __FUNCTION__, fec_reg_read(fep, FEC_EIMR)); ++ DBG(0, "%s: RCR: %08lx\n", __FUNCTION__, fec_reg_read(fep, FEC_RCR)); ++ DBG(0, "%s: TCR: %08lx\n", __FUNCTION__, fec_reg_read(fep, FEC_TCR)); ++#endif ++ spin_lock_irqsave(&fep->lock, flags); ++ fep->mii_complete = 0; ++ fec_reg_write(fep, FEC_MMFR, regval); ++ spin_unlock_irqrestore(&fep->lock, flags); ++ ++ while (!fep->mii_complete) { ++ if (loops++ == 1000) { ++ DBG(1, "%s: Waiting for MII completion\n", __FUNCTION__); ++ } ++ cpu_relax(); ++ } ++ if (loops >= 1000) { ++ DBG(1, "%s: MII transaction completed\n", __FUNCTION__); ++ } ++ ret = fec_reg_read(fep, FEC_MMFR); ++ if (ret < 0) { ++ DBG(0, "%s: Failed to read PHY[%02x] reg %02x: %d\n", __FUNCTION__, ++ phy_id, regnum, ret); ++ return ret; ++ } ++ ret &= 0xffff; ++ if (phy_regs[regnum] != ret) { ++ DBG(1, "%s: Read %04x from PHY[%02x] reg %02x\n", __FUNCTION__, ++ ret, phy_id, regnum); ++ phy_regs[regnum] = ret; ++ } ++ return ret; ++} ++ ++static int fec_mii_write(struct mii_bus *bus, int phy_id, int regnum, u16 val) ++{ ++ struct net_device *dev = bus->priv; ++ struct fec_enet_private *fep = netdev_priv(dev); ++ unsigned long regval = mk_mii_write(regnum, val) | phy_id << 23; ++ unsigned long flags; ++ ++ DBG(0, "%s: \n", __FUNCTION__); ++ ++ spin_lock_irqsave(&fep->lock, flags); ++ fep->mii_complete = 0; ++ fec_reg_write(fep, FEC_MMFR, regval); ++ spin_unlock_irqrestore(&fep->lock, flags); ++ ++ while (!fep->mii_complete) { ++ cpu_relax(); ++ } ++ DBG(1, "%s: Wrote %04x to PHY[%02x] reg %02x\n", __FUNCTION__, val, phy_id, regnum); ++ return 0; ++} ++ ++static int fec_mii_reset(struct mii_bus *bus) ++{ ++ DBG(0, "%s: \n", __FUNCTION__); ++ memset(phy_regs, -1, sizeof(phy_regs)); ++ return 0; ++} ++ ++static int fec_init_phy(struct net_device *dev, struct fec_enet_private *fep) ++{ ++ int ret; ++ int i; ++ struct mii_bus *mii; ++ ++ mii = mdiobus_alloc(); ++ if (mii == NULL) { + return -ENOMEM; + } ++ mii->name = "fec mii"; ++ mii->read = fec_mii_read; ++ mii->write = fec_mii_write; ++ mii->reset = fec_mii_reset; ++ mii->priv = dev; ++ snprintf(mii->id, MII_BUS_ID_SIZE, "%x", 0); ++ mii->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL); ++ for (i = 0; i < PHY_MAX_ADDR; i++) { ++ mii->irq[i] = fep->mii_irq >= 0 ? fep->mii_irq : PHY_POLL; ++ } ++ ++ ret = mdiobus_register(mii); ++ if (ret != 0) { ++ DBG(0, "%s: Failed to register MII bus: %d\n", __FUNCTION__, ret); ++ kfree(mii->irq); ++ mdiobus_free(mii); ++ return ret; ++ } ++ fep->phy_addr = -1; ++ DBG(0, "%s: MII bus registered\n", __FUNCTION__); ++ for (i = 0; i < PHY_MAX_ADDR; i++) { ++ if (mii->phy_map[i] != NULL) { ++ fep->phy_addr = i; ++ break; ++ } ++ } ++ if (fep->phy_addr == -1) { ++ DBG(0, "%s: No PHY found\n", __FUNCTION__); ++ return -ENODEV; ++ } ++ DBG(0, "%s: Using PHY at addr %02x\n", __FUNCTION__, fep->phy_addr); ++ fep->mii = mii; + +- spin_lock_init(&fep->hw_lock); +- spin_lock_init(&fep->mii_lock); ++ return 0; ++} + +- /* Create an Ethernet device instance. +- */ +- fecp = (volatile fec_t *)dev->base_addr; ++static int fec_connect_phy(struct net_device *dev, struct fec_enet_private *fep) ++{ ++ struct mii_bus *mii = fep->mii; + +- fep->index = index; +- fep->hwp = fecp; +- fep->netdev = dev; ++ DBG(0, "%s: Connecting PHY at addr %02x\n", __FUNCTION__, ++ fep->phy_addr); + +- /* Whack a reset. We should wait for this. +- */ +- fecp->fec_ecntrl = 1; +- udelay(10); ++ fep->phy = phy_connect(dev, dev_name(&mii->phy_map[fep->phy_addr]->dev), ++ fec_link_change, 0, mii->phy_map[fep->phy_addr]->interface); ++ if (IS_ERR(fep->phy)) { ++ int ret = PTR_ERR(fep->phy); ++ printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name); ++ fep->phy = NULL; ++ return ret; ++ } ++ DBG(0, "%s: Registered PHY %s[%02x] IRQ %d with %s\n", __FUNCTION__, ++ dev_name(&fep->phy->dev), fep->phy_addr, fep->phy->irq, dev->name); + +- /* Set the Ethernet address */ +-#ifdef CONFIG_M5272 +- fec_get_mac(dev); ++ return 0; ++} + #else +- { +- unsigned long l; +- l = fecp->fec_addr_low; +- dev->dev_addr[0] = (unsigned char)((l & 0xFF000000) >> 24); +- dev->dev_addr[1] = (unsigned char)((l & 0x00FF0000) >> 16); +- dev->dev_addr[2] = (unsigned char)((l & 0x0000FF00) >> 8); +- dev->dev_addr[3] = (unsigned char)((l & 0x000000FF) >> 0); +- l = fecp->fec_addr_high; +- dev->dev_addr[4] = (unsigned char)((l & 0xFF000000) >> 24); +- dev->dev_addr[5] = (unsigned char)((l & 0x00FF0000) >> 16); +- } ++static int fec_init_phy(struct net_device *dev, struct fec_enet_private *fep) ++{ ++ /* Queue up command to detect the PHY and initialize the ++ * remainder of the interface. ++ */ ++ fep->phy_id_done = 0; ++ fep->phy_addr = 0; ++ mii_queue(dev, mk_mii_read(MII_REG_PHYIR1), mii_discover_phy); ++ ++ return 0; ++} + #endif + +- cbd_base = (cbd_t *)mem_addr; ++/* Initialize the FEC Ethernet on 860T (or ColdFire 5272). ++ */ ++ /* ++ * XXX: We need to clean up on failure exits here. ++ */ + +- /* Set receive and transmit descriptor base. ++int __devinit fec_enet_init(struct platform_device *pdev, struct net_device *dev) ++{ ++ int ret; ++ struct fec_enet_private *fep = netdev_priv(dev); ++ cbd_t *bdp; ++ struct sk_buff *pskb; ++ int i; ++ void *mem; ++ ++ spin_lock_init(&fep->lock); ++ ++ /* Whack a reset. We should wait for this. + */ +- fep->rx_bd_base = cbd_base; +- fep->tx_bd_base = cbd_base + RX_RING_SIZE; ++ fec_reg_write(fep, FEC_ECR, FEC_ECR_RESET); ++ udelay(10); ++ ++ /* Set the Ethernet address. If using multiple Enets on the 8xx, ++ * this needs some work to get unique addresses. ++ * ++ * This is our default MAC address unless the user changes ++ * it via eth_mac_addr (our dev->set_mac_addr handler). ++ */ ++ fec_get_mac(dev); + + fep->dirty_tx = fep->cur_tx = fep->tx_bd_base; + fep->cur_rx = fep->rx_bd_base; + + fep->skb_cur = fep->skb_dirty = 0; + +- /* Initialize the receive buffer descriptors. ++ /* allocate memory for TX bounce buffers */ ++ mem = kzalloc(TX_RING_SIZE * FEC_ENET_TX_FRSIZE, GFP_KERNEL); ++ if (mem == NULL) { ++ return -ENOMEM; ++ } ++ ++ fec_enet_cbd_get(fep); ++ ++ /* Initialize the transmit buffer descriptors. + */ +- bdp = fep->rx_bd_base; +- for (i=0; i<FEC_ENET_RX_PAGES; i++) { ++ bdp = fep->tx_bd_base; + +- /* Allocate a page. +- */ +- mem_addr = __get_free_page(GFP_KERNEL); +- /* XXX: missing check for allocation failure */ ++ DBG(0, "%s: Allocated %d byte of TX buffer memory @ %p\n", __FUNCTION__, ++ TX_RING_SIZE * FEC_ENET_TX_FRSIZE, mem); ++ for (i = 0; i < TX_RING_SIZE; i++) { ++ fep->tx_bounce[i] = mem; ++ DBG(0, "%s: TX bounce buffer[%d]=%p\n", __FUNCTION__, i, fep->tx_bounce[i]); ++ mem = (void *)((unsigned long)(mem + FEC_ENET_TX_FRSIZE)); + + /* Initialize the BD for every fragment in the page. + */ +- for (j=0; j<FEC_ENET_RX_FRPPG; j++) { +- bdp->cbd_sc = BD_ENET_RX_EMPTY; +- bdp->cbd_bufaddr = __pa(mem_addr); +- mem_addr += FEC_ENET_RX_FRSIZE; +- bdp++; +- } ++ bdp->cbd_bufaddr = ~0; ++ bdp++; + } + + /* Set the last buffer to wrap. +@@ -1757,87 +2572,88 @@ int __init fec_enet_init(struct net_devi + bdp--; + bdp->cbd_sc |= BD_SC_WRAP; + +- /* ...and the same for transmmit. ++ /* ...and the same for receive. + */ +- bdp = fep->tx_bd_base; +- for (i=0, j=FEC_ENET_TX_FRPPG; i<TX_RING_SIZE; i++) { +- if (j >= FEC_ENET_TX_FRPPG) { +- mem_addr = __get_free_page(GFP_KERNEL); +- j = 1; +- } else { +- mem_addr += FEC_ENET_TX_FRSIZE; +- j++; ++ bdp = fep->rx_bd_base; ++ for (i = 0; i < RX_RING_SIZE; i++, bdp++) { ++ pskb = __dev_alloc_skb(FEC_ENET_RX_FRSIZE, GFP_KERNEL); ++ if (pskb == NULL) { ++ DBG(0, "%s: Failed to allocate RX skb; cleaning up\n", __FUNCTION__); ++ ret = -ENOMEM; ++ goto cleanup; + } +- fep->tx_bounce[i] = (unsigned char *) mem_addr; +- +- /* Initialize the BD for every fragment in the page. +- */ +- bdp->cbd_sc = 0; +- bdp->cbd_bufaddr = 0; +- bdp++; ++ DBG(0, "%s: RX skb allocated @ %p\n", __FUNCTION__, pskb); ++ fep->rx_skbuff[i] = pskb; ++ pskb->data = FEC_ADDR_ALIGNMENT(pskb->data); ++ bdp->cbd_sc = BD_ENET_RX_EMPTY; ++ bdp->cbd_bufaddr = ~0; ++ fec_enet_rxbuf_map(fep, bdp, pskb->data, FEC_ENET_RX_FRSIZE); + } +- + /* Set the last buffer to wrap. + */ + bdp--; + bdp->cbd_sc |= BD_SC_WRAP; ++ fec_enet_cbd_put(fep); + + /* Set receive and transmit descriptor base. + */ +- fecp->fec_r_des_start = fep->bd_dma; +- fecp->fec_x_des_start = (unsigned long)fep->bd_dma + sizeof(cbd_t) +- * RX_RING_SIZE; +- +-#ifdef HAVE_mii_link_interrupt +- fec_request_mii_intr(dev); +-#endif +- +- fecp->fec_grp_hash_table_high = 0; +- fecp->fec_grp_hash_table_low = 0; +- fecp->fec_r_buff_size = PKT_MAXBLR_SIZE; +- fecp->fec_ecntrl = 2; +- fecp->fec_r_des_active = 0; +-#ifndef CONFIG_M5272 +- fecp->fec_hash_table_high = 0; +- fecp->fec_hash_table_low = 0; +-#endif ++ fec_reg_write(fep, FEC_ERDSR, fep->cbd_phys_base); ++ fec_reg_write(fep, FEC_ETDSR, fep->cbd_phys_base + RX_RING_SIZE * sizeof(cbd_t)); + ++ /* Install our interrupt handlers. This varies depending on ++ * the architecture. ++ */ ++ ret = fec_request_intrs(pdev, dev); ++ if (ret != 0) { ++ goto cleanup; ++ } ++ /* Clear and enable interrupts */ ++ fec_reg_write(fep, FEC_EIR, fec_reg_read(fep, FEC_EIR)); ++ fec_reg_write(fep, FEC_EIMR, FEC_ENET_TXF | FEC_ENET_TXB | ++ FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII); ++ ++ fec_reg_write(fep, FEC_IAUR, 0); ++ fec_reg_write(fep, FEC_IALR, 0); ++ fec_reg_write(fep, FEC_EMRBR, PKT_MAXBLR_SIZE); ++ fec_reg_write(fep, FEC_ECR, FEC_ECR_ETHER_EN); ++ fec_localhw_setup(dev); ++#if 0 ++ /* do this in enet_open()! */ ++ fec_reg_write(fep, FEC_RDAR, DONT_CARE); ++#endif + /* The FEC Ethernet specific entries in the device structure. */ + dev->open = fec_enet_open; + dev->hard_start_xmit = fec_enet_start_xmit; + dev->tx_timeout = fec_timeout; + dev->watchdog_timeo = TX_TIMEOUT; + dev->stop = fec_enet_close; ++ dev->get_stats = fec_enet_get_stats; + dev->set_multicast_list = set_multicast_list; ++ dev->set_mac_address = fec_set_mac_address; + +- for (i=0; i<NMII-1; i++) +- mii_cmds[i].mii_next = &mii_cmds[i+1]; ++#ifndef CONFIG_PHYLIB ++ for (i = 1; i < NMII; i++) { ++ mii_cmds[i - 1].mii_next = &mii_cmds[i]; ++ } + mii_free = mii_cmds; +- ++#endif + /* setup MII interface */ +- fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04; +- fecp->fec_x_cntrl = 0x00; +- +- /* +- * Set MII speed to 2.5 MHz +- */ +- fep->phy_speed = ((((clk_get_rate(fep->clk) / 2 + 4999999) +- / 2500000) / 2) & 0x3F) << 1; +- fecp->fec_mii_speed = fep->phy_speed; +- fec_restart(dev, 0); +- +- /* Clear and enable interrupts */ +- fecp->fec_ievent = 0xffc00000; +- fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII); +- +- /* Queue up command to detect the PHY and initialize the +- * remainder of the interface. +- */ +- fep->phy_id_done = 0; +- fep->phy_addr = 0; +- mii_queue(dev, mk_mii_read(MII_REG_PHYIR1), mii_discover_phy); ++ ret = fec_set_mii(dev, fep); ++ if (ret) { ++ DBG(0, "%s: Failed to initialize MII interface: %d\n", __FUNCTION__, ret); ++ goto cleanup; ++ } + ++ ret = fec_init_phy(dev, fep); ++ if (ret) { ++ DBG(0, "%s: Failed to initialize PHY: %d\n", __FUNCTION__, ret); ++ goto cleanup; ++ } + return 0; ++ cleanup: ++ fec_enet_free_buffers(fep); ++ fec_enet_cbd_put(fep); ++ return ret; + } + + /* This function is called to start or restart the FEC during a link +@@ -1847,60 +2663,67 @@ int __init fec_enet_init(struct net_devi + static void + fec_restart(struct net_device *dev, int duplex) + { +- struct fec_enet_private *fep; +- volatile cbd_t *bdp; +- volatile fec_t *fecp; ++ struct fec_enet_private *fep = netdev_priv(dev); ++ cbd_t *bdp; + int i; ++ u32 rcr = OPT_FRAME_SIZE | RCR_MII_MODE; /* MII enable */ ++ u32 tcr = TCR_HBC; + +- fep = netdev_priv(dev); +- fecp = fep->hwp; +- ++ DBG(0, "%s: Restarting FEC in %s-duplex mode\n", __FUNCTION__, ++ duplex ? "full" : "half"); + /* Whack a reset. We should wait for this. +- */ +- fecp->fec_ecntrl = 1; ++ */ ++ fec_reg_write(fep, FEC_ECR, FEC_ECR_RESET); + udelay(10); + ++ /* Enable interrupts we wish to service. ++ */ ++ fec_reg_write(fep, FEC_EIMR, FEC_ENET_TXF | FEC_ENET_TXB | ++ FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII); ++ + /* Clear any outstanding interrupt. +- */ +- fecp->fec_ievent = 0xffc00000; ++ * ++ */ ++ fec_reg_write(fep, FEC_EIR, FEC_ENET_MASK); ++ ++ fec_enable_phy_intr(fep); + + /* Set station address. +- */ +- fec_set_mac_address(dev); ++ */ ++ _fec_set_mac_address(dev); + + /* Reset all multicast. +- */ +- fecp->fec_grp_hash_table_high = 0; +- fecp->fec_grp_hash_table_low = 0; ++ */ ++ fec_reg_write(fep, FEC_IAUR, 0); ++ fec_reg_write(fep, FEC_IALR, 0); + + /* Set maximum receive buffer size. +- */ +- fecp->fec_r_buff_size = PKT_MAXBLR_SIZE; ++ */ ++ fec_reg_write(fep, FEC_EMRBR, PKT_MAXBLR_SIZE); + + /* Set receive and transmit descriptor base. +- */ +- fecp->fec_r_des_start = fep->bd_dma; +- fecp->fec_x_des_start = (unsigned long)fep->bd_dma + sizeof(cbd_t) +- * RX_RING_SIZE; ++ */ ++ fec_reg_write(fep, FEC_ERDSR, fep->cbd_phys_base); ++ fec_reg_write(fep, FEC_ETDSR, fep->cbd_phys_base + RX_RING_SIZE * sizeof(cbd_t)); + + fep->dirty_tx = fep->cur_tx = fep->tx_bd_base; + fep->cur_rx = fep->rx_bd_base; + + /* Reset SKB transmit buffers. +- */ ++ */ + fep->skb_cur = fep->skb_dirty = 0; +- for (i=0; i<=TX_RING_MOD_MASK; i++) { ++ bdp = fep->tx_bd_base; ++ for (i = 0; i <= TX_RING_MOD_MASK; i++) { + if (fep->tx_skbuff[i] != NULL) { +- dev_kfree_skb_any(fep->tx_skbuff[i]); +- fep->tx_skbuff[i] = NULL; ++ fec_free_skb(fep, bdp, &fep->tx_skbuff[i]); ++ bdp++; + } + } + + /* Initialize the receive buffer descriptors. +- */ ++ */ + bdp = fep->rx_bd_base; +- for (i=0; i<RX_RING_SIZE; i++) { +- ++ for (i = 0; i < RX_RING_SIZE; i++) { + /* Initialize the BD for every fragment in the page. + */ + bdp->cbd_sc = BD_ENET_RX_EMPTY; +@@ -1908,246 +2731,366 @@ fec_restart(struct net_device *dev, int + } + + /* Set the last buffer to wrap. +- */ ++ */ + bdp--; + bdp->cbd_sc |= BD_SC_WRAP; + + /* ...and the same for transmmit. +- */ ++ */ + bdp = fep->tx_bd_base; +- for (i=0; i<TX_RING_SIZE; i++) { +- ++ for (i = 0; i < TX_RING_SIZE; i++) { + /* Initialize the BD for every fragment in the page. + */ + bdp->cbd_sc = 0; +- bdp->cbd_bufaddr = 0; ++ bdp->cbd_bufaddr = ~0; + bdp++; + } + + /* Set the last buffer to wrap. +- */ ++ */ + bdp--; + bdp->cbd_sc |= BD_SC_WRAP; + + /* Enable MII mode. +- */ ++ */ + if (duplex) { +- fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04;/* MII enable */ +- fecp->fec_x_cntrl = 0x04; /* FD enable */ ++ tcr |= TCR_FDEN; /* FD enable */ + } else { +- /* MII enable|No Rcv on Xmit */ +- fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x06; +- fecp->fec_x_cntrl = 0x00; ++ rcr |= RCR_DRT; /* No Rcv on Xmit */ + } ++ fec_reg_write(fep, FEC_RCR, rcr); ++ fec_reg_write(fep, FEC_TCR, tcr); + fep->full_duplex = duplex; + + /* Set MII speed. +- */ +- fecp->fec_mii_speed = fep->phy_speed; ++ */ ++ fec_reg_write(fep, FEC_MSCR, fep->phy_speed); + + /* And last, enable the transmit and receive processing. +- */ +- fecp->fec_ecntrl = 2; +- fecp->fec_r_des_active = 0; ++ */ ++ fec_reg_write(fep, FEC_ECR, FEC_ECR_ETHER_EN); ++ fec_localhw_setup(dev); ++ fec_reg_write(fep, FEC_RDAR, DONT_CARE); + +- /* Enable interrupts we wish to service. +- */ +- fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII); ++ DBG(0, "%s: Starting netif queue\n", __FUNCTION__); ++ netif_start_queue(dev); + } + + static void + fec_stop(struct net_device *dev) + { +- volatile fec_t *fecp; +- struct fec_enet_private *fep; ++ struct fec_enet_private *fep = netdev_priv(dev); + +- fep = netdev_priv(dev); +- fecp = fep->hwp; ++ DBG(0, "%s: Stopping netif queue\n", __FUNCTION__); ++ netif_stop_queue(dev); + + /* +- ** We cannot expect a graceful transmit stop without link !!! +- */ +- if (fep->link) +- { +- fecp->fec_x_cntrl = 0x01; /* Graceful transmit stop */ ++ * We cannot expect a graceful transmit stop without link! ++ */ ++ if (fep->linkstatus) { ++ fec_reg_write(fep, FEC_TCR, 0x01); /* Graceful transmit stop */ + udelay(10); +- if (!(fecp->fec_ievent & FEC_ENET_GRA)) +- printk("fec_stop : Graceful transmit stop did not complete !\n"); +- } +- ++ if (!(fec_reg_read(fep, FEC_EIR) & FEC_ENET_GRA)) ++ dev_warn(&dev->dev, "Graceful transmit stop did not complete!\n"); ++ } ++#if 0 + /* Whack a reset. We should wait for this. +- */ +- fecp->fec_ecntrl = 1; ++ */ ++ fec_reg_write(fep, FEC_ECR, FEC_ECR_RESET); + udelay(10); +- +- /* Clear outstanding MII command interrupts. +- */ +- fecp->fec_ievent = FEC_ENET_MII; +- +- fecp->fec_imask = FEC_ENET_MII; +- fecp->fec_mii_speed = fep->phy_speed; ++ /* Mask and clear outstanding MII command interrupts. ++ */ ++ fec_reg_write(fep, FEC_EIMR, 0); ++ fec_reg_write(fep, FEC_EIR, FEC_ENET_MII); ++ fec_enable_phy_intr(fep); ++ fec_reg_write(fep, FEC_MSCR, fep->phy_speed); ++#endif + } + +-static int __devinit +-fec_probe(struct platform_device *pdev) ++static int __devinit fec_enet_probe(struct platform_device *pdev) + { ++ int ret; + struct fec_enet_private *fep; +- struct net_device *ndev; +- int i, irq, ret = 0; +- struct resource *r; +- +- r = platform_get_resource(pdev, IORESOURCE_MEM, 0); +- if (!r) +- return -ENXIO; ++ struct net_device *dev; ++ struct fec_enet_platform_data *pdata = pdev->dev.platform_data; ++ struct resource *res_mem1; ++ struct resource *res_mem2; ++ ++ res_mem1 = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (res_mem1 == NULL) { ++ return -ENODEV; ++ } + +- r = request_mem_region(r->start, resource_size(r), pdev->name); +- if (!r) ++ res_mem1 = request_mem_region(res_mem1->start, ++ resource_size(res_mem1), ++ DRV_NAME); ++ if (res_mem1 == NULL) { + return -EBUSY; ++ } ++ res_mem2 = platform_get_resource(pdev, IORESOURCE_MEM, 1); ++ if (res_mem2 != NULL) { ++ res_mem2 = request_mem_region(res_mem2->start, ++ resource_size(res_mem2), ++ DRV_NAME); ++ if (res_mem2 == NULL) { ++ ret = -EBUSY; ++ goto release1; ++ } ++ } + +- /* Init network device */ +- ndev = alloc_etherdev(sizeof(struct fec_enet_private)); +- if (!ndev) +- return -ENOMEM; +- +- SET_NETDEV_DEV(ndev, &pdev->dev); +- +- /* setup board info structure */ +- fep = netdev_priv(ndev); +- memset(fep, 0, sizeof(*fep)); ++ dev = alloc_etherdev(sizeof(struct fec_enet_private)); ++ if (dev == NULL) { ++ ret = -ENOMEM; ++ goto release2; ++ } ++ platform_set_drvdata(pdev, dev); ++ fep = netdev_priv(dev); ++ fep->res_mem1 = res_mem1; ++ fep->res_mem2 = res_mem2; ++ fep->dma_dev = &pdev->dev; ++ ++ fep->reg_base = ioremap(res_mem1->start, resource_size(res_mem1)); ++ if (fep->reg_base == NULL) { ++ printk("FEC: Mapping FEC registers failed\n"); ++ ret = -ENOMEM; ++ goto free_netdev; ++ } ++ DBG(0, "%s: FEC registers @ %08lx mapped to %p\n", __FUNCTION__, ++ (unsigned long)res_mem1->start, fep->reg_base); + +- ndev->base_addr = (unsigned long)ioremap(r->start, resource_size(r)); ++ fep->mib_base = ioremap(res_mem2->start, resource_size(res_mem2)); ++ if (fep->mib_base == NULL) { ++ printk("FEC: Mapping FEC registers failed\n"); ++ ret = -ENOMEM; ++ goto unmap1; ++ } ++ DBG(0, "%s: FEC registers @ %08lx mapped to %p\n", __FUNCTION__, ++ (unsigned long)res_mem2->start, fep->mib_base); + +- if (!ndev->base_addr) { ++ /* Allocate memory for buffer descriptors. */ ++ fep->cbd_mem_base = dma_alloc_coherent(&pdev->dev, CBD_BUF_SIZE, ++ &fep->cbd_phys_base, ++ GFP_KERNEL); ++ if (fep->cbd_mem_base == NULL) { ++ printk("FEC: allocate descriptor memory failed\n"); + ret = -ENOMEM; +- goto failed_ioremap; ++ goto unmap2; + } ++ DBG(0, "%s: Allocated %lu [(%u + %lu) * %d] byte for CBD buffer @ %p[%08lx]\n", ++ __FUNCTION__, CBD_BUF_SIZE, TX_RING_SIZE, RX_RING_SIZE, ++ sizeof(cbd_t), fep->cbd_mem_base, ++ (unsigned long)fep->cbd_phys_base); + +- platform_set_drvdata(pdev, ndev); ++ /* Set receive and transmit descriptor base. ++ */ ++ fep->rx_bd_base = fep->cbd_mem_base; ++ fep->tx_bd_base = fep->rx_bd_base + RX_RING_SIZE; + +- /* This device has up to three irqs on some platforms */ +- for (i = 0; i < 3; i++) { +- irq = platform_get_irq(pdev, i); +- if (i && irq < 0) +- break; +- ret = request_irq(irq, fec_enet_interrupt, IRQF_DISABLED, pdev->name, ndev); +- if (ret) { +- while (i >= 0) { +- irq = platform_get_irq(pdev, i); +- free_irq(irq, ndev); +- i--; +- } +- goto failed_irq; +- } ++ printk("FEC ENET Driver\n"); ++ ret = platform_func(pdata->arch_init, pdev); ++ if (ret != 0) { ++ dev_err(&pdev->dev, "platform init failed: %d\n", ret); ++ goto free_dma; + } + +- fep->clk = clk_get(&pdev->dev, "fec_clk"); +- if (IS_ERR(fep->clk)) { +- ret = PTR_ERR(fep->clk); +- goto failed_clk; ++ ret = fec_enet_init(pdev, dev); ++ if (ret != 0) { ++ goto fec_disable; + } +- clk_enable(fep->clk); + +- ret = fec_enet_init(ndev, 0); +- if (ret) +- goto failed_init; ++ /* Enable most messages by default */ ++ fep->msg_enable = (NETIF_MSG_IFUP << 1) - 1; ++ ret = register_netdev(dev); ++ if (ret != 0) { ++ /* XXX: missing cleanup here */ ++ goto free_buffers; ++ } + +- ret = register_netdev(ndev); +- if (ret) +- goto failed_register; ++ printk(KERN_INFO "%s: ethernet %02x:%02x:%02x:%02x:%02x:%02x\n", dev->name, ++ dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], ++ dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); + + return 0; + +-failed_register: +-failed_init: +- clk_disable(fep->clk); +- clk_put(fep->clk); +-failed_clk: +- for (i = 0; i < 3; i++) { +- irq = platform_get_irq(pdev, i); +- if (irq > 0) +- free_irq(irq, ndev); +- } +-failed_irq: +- iounmap((void __iomem *)ndev->base_addr); +-failed_ioremap: +- free_netdev(ndev); ++ free_buffers: ++ fec_enet_free_buffers(fep); ++ ++ fec_disable: ++ platform_func(pdata->arch_exit, pdev); ++ ++ free_dma: ++ dma_free_coherent(&pdev->dev, CBD_BUF_SIZE, fep->cbd_mem_base, fep->cbd_phys_base); ++ ++ unmap2: ++ if (fep->mib_base) ++ iounmap(fep->mib_base); ++ ++ unmap1: ++ iounmap(fep->reg_base); ++ ++ free_netdev: ++ free_netdev(dev); ++ ++ release2: ++ if (res_mem2 != NULL) { ++ release_resource(res_mem2); ++ } ++ ++ release1: ++ release_resource(res_mem1); + + return ret; + } + +-static int __devexit +-fec_drv_remove(struct platform_device *pdev) ++static int __devexit fec_enet_remove(struct platform_device *pdev) + { +- struct net_device *ndev = platform_get_drvdata(pdev); +- struct fec_enet_private *fep = netdev_priv(ndev); ++ struct net_device *dev = platform_get_drvdata(pdev); ++ struct fec_enet_private *fep = netdev_priv(dev); ++ ++ unregister_netdev(dev); ++ free_netdev(dev); ++ ++#ifdef CONFIG_PHYLIB ++ if (fep->mii != NULL) { ++ kfree(fep->mii->irq); ++ mdiobus_unregister(fep->mii); ++ } ++ mdiobus_free(fep->mii); ++#endif ++ fec_release_intrs(dev); ++ ++ DBG(0, "%s: Unmapping FEC registers %p\n", __FUNCTION__, fep->reg_base); ++ iounmap(fep->reg_base); ++ if (fep->mib_base) ++ iounmap(fep->mib_base); ++ ++ fec_enet_free_buffers(fep); + +- platform_set_drvdata(pdev, NULL); ++ DBG(0, "%s: Freeing CBD buffer area %p[%08lx]\n", __FUNCTION__, ++ fep->cbd_mem_base, (unsigned long)fep->cbd_phys_base); ++ dma_free_coherent(&pdev->dev, CBD_BUF_SIZE, fep->cbd_mem_base, fep->cbd_phys_base); + +- fec_stop(ndev); +- clk_disable(fep->clk); +- clk_put(fep->clk); +- iounmap((void __iomem *)ndev->base_addr); +- unregister_netdev(ndev); +- free_netdev(ndev); ++ release_resource(fep->res_mem1); ++ if (fep->res_mem2 != NULL) { ++ release_resource(fep->res_mem2); ++ } + return 0; + } + +-static int +-fec_suspend(struct platform_device *dev, pm_message_t state) ++static void fec_enet_shutdown(struct platform_device *pdev) + { +- struct net_device *ndev = platform_get_drvdata(dev); +- struct fec_enet_private *fep; ++ struct fec_enet_platform_data *pdata = pdev->dev.platform_data; ++ ++ DBG(0, "%s: Shutting down FEC Hardware\n", __FUNCTION__); ++ platform_func(pdata->arch_exit, pdev); ++} ++ ++#ifdef CONFIG_PM ++static int fec_enet_suspend(struct platform_device *pdev, pm_message_t state) ++{ ++ int ret; ++ struct fec_enet_platform_data *pdata = pdev->dev.platform_data; ++ struct net_device *ndev = platform_get_drvdata(pdev); ++ struct fec_enet_private *fep = netdev_priv(ndev); + +- if (ndev) { +- fep = netdev_priv(ndev); +- if (netif_running(ndev)) { +- netif_device_detach(ndev); +- fec_stop(ndev); ++ if (netif_running(ndev)) { ++ DBG(0, "%s: Detaching netif\n", __FUNCTION__); ++ netif_device_detach(ndev); ++#ifdef CONFIG_PHYLIB ++ DBG(0, "%s: Disconnecting PHY %p\n", __FUNCTION__, fep->phy); ++ phy_disconnect(fep->phy); ++ fep->phy = NULL; ++#endif ++ } ++#ifndef CONFIG_PHYLIB ++ if (fep->phy_timer) { ++ ret = del_timer_sync(fep->phy_timer); ++ if (ret != 0) { ++ DBG(0, "%s: Failed to delete PHY timer: %d\n", __FUNCTION__, ret); ++ return ret; + } + } +- return 0; ++#endif ++ DBG(0, "%s: Shutting down FEC Hardware %d\n", __FUNCTION__, ++ netif_running(ndev)); ++ ret = platform_func(pdata->suspend, pdev); ++ if (ret != 0 && netif_running(ndev)) { ++ DBG(0, "%s: Failed to suspend: %d\n", __FUNCTION__, ret); ++ /* Undo suspend */ ++#ifdef CONFIG_PHYLIB ++ DBG(0, "%s: Reconnecting PHY\n", __FUNCTION__); ++ if (fec_connect_phy(ndev, fep) != 0) { ++ DBG(0, "%s: Failed to connect to PHY\n", __FUNCTION__); ++ return ret; ++ } ++ phy_start(fep->phy); ++#endif ++ fec_link_change(ndev); ++ netif_device_attach(ndev); ++ } ++ return ret; + } + +-static int +-fec_resume(struct platform_device *dev) ++static int fec_enet_resume(struct platform_device *pdev) + { +- struct net_device *ndev = platform_get_drvdata(dev); ++ int ret; ++ struct fec_enet_platform_data *pdata = pdev->dev.platform_data; ++ struct net_device *ndev = platform_get_drvdata(pdev); + +- if (ndev) { +- if (netif_running(ndev)) { +- fec_enet_init(ndev, 0); +- netif_device_attach(ndev); ++ DBG(0, "%s: Powering up FEC Hardware %d\n", __FUNCTION__, ++ netif_running(ndev)); ++ ret = platform_func(pdata->resume, pdev); ++ if (ret != 0) { ++ DBG(0, "%s: Failed to resume: %d\n", __FUNCTION__, ret); ++ return ret; ++ } ++ if (netif_running(ndev)) { ++#ifdef CONFIG_PHYLIB ++ struct fec_enet_private *fep = netdev_priv(ndev); ++ ++ DBG(0, "%s: Reconnecting PHY\n", __FUNCTION__); ++ ret = fec_connect_phy(ndev, fep); ++ if (ret != 0) { ++ DBG(0, "%s: Failed to connect to PHY: %d\n", __FUNCTION__, ret); ++ return ret; + } ++ phy_start(fep->phy); ++#endif ++ fec_link_change(ndev); ++ netif_device_attach(ndev); + } + return 0; + } ++#else ++#define fec_enet_suspend NULL ++#define fec_enet_resume NULL ++#endif + +-static struct platform_driver fec_driver = { +- .driver = { +- .name = "fec", +- .owner = THIS_MODULE, ++static struct platform_driver fec_enet_driver = { ++ .driver = { ++ .name = DRV_NAME, + }, +- .probe = fec_probe, +- .remove = __devexit_p(fec_drv_remove), +- .suspend = fec_suspend, +- .resume = fec_resume, ++ .probe = fec_enet_probe, ++ .remove = __devexit_p(fec_enet_remove), ++ .shutdown = fec_enet_shutdown, ++ .suspend = fec_enet_suspend, ++ .resume = fec_enet_resume, + }; + +-static int __init +-fec_enet_module_init(void) ++static int __init fec_enet_module_init(void) + { +- printk(KERN_INFO "FEC Ethernet Driver\n"); ++ int ret; ++ ++ ret = platform_driver_register(&fec_enet_driver); + +- return platform_driver_register(&fec_driver); ++ return ret; + } ++module_init(fec_enet_module_init); + +-static void __exit +-fec_enet_cleanup(void) ++static void __exit fec_enet_module_cleanup(void) + { +- platform_driver_unregister(&fec_driver); ++ platform_driver_unregister(&fec_enet_driver); + } +- +-module_exit(fec_enet_cleanup); +-module_init(fec_enet_module_init); ++module_exit(fec_enet_module_cleanup); + + MODULE_LICENSE("GPL"); +diff -urNp linux-2.6.30-rc4/drivers/net/fec.h linux-2.6.30-rc4-karo/drivers/net/fec.h +--- linux-2.6.30-rc4/drivers/net/fec.h 2009-05-13 09:46:19.000000000 +0200 ++++ linux-2.6.30-rc4-karo/drivers/net/fec.h 2009-06-02 17:05:27.000000000 +0200 +@@ -13,6 +13,15 @@ + #define FEC_H + /****************************************************************************/ + ++/* ++ * dummy value to write into RDAR,TDAR. FEC hardware will scan the TX/RX ++ * descriptors in memory upon any write access to those registers. ++ * The actual value written to those registers does not matter. ++*/ ++#define DONT_CARE 0 ++#define RDAR_BUSY (1 << 24) ++#define TDAR_BUSY (1 << 24) ++ + #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \ + defined(CONFIG_M520x) || defined(CONFIG_M532x) || defined(CONFIG_ARCH_MXC) + /* +@@ -20,6 +29,36 @@ + * registers in the same peripheral device on different models + * of the ColdFire! + */ ++// relying on structure alignment for hardware register is just evil ++#ifndef GARBAGE ++#define FEC_EIR 0x004 ++#define FEC_EIMR 0x008 ++#define FEC_RDAR 0x010 ++#define FEC_TDAR 0x014 ++#define FEC_ECR 0x024 ++#define FEC_MMFR 0x040 ++#define FEC_MSCR 0x044 ++#define FEC_MIBC 0x064 ++#define FEC_RCR 0x084 ++#define FEC_TCR 0x0c4 ++#define FEC_PALR 0x0e4 ++#define FEC_PAUR 0x0e8 ++#define FEC_OPD 0x0ec ++#define FEC_IAUR 0x118 ++#define FEC_IALR 0x11c ++#define FEC_GAUR 0x120 ++#define FEC_GALR 0x124 ++#define FEC_TFWR 0x144 ++#define FEC_FRBR 0x14c ++#define FEC_FRSR 0x150 ++#define FEC_ERDSR 0x180 ++#define FEC_ETDSR 0x184 ++#define FEC_EMRBR 0x188 ++ ++#define FEC_ECR_RESET (1 << 0) ++#define FEC_ECR_ETHER_EN (1 << 1) ++#else ++ + typedef struct fec { + unsigned long fec_reserved0; + unsigned long fec_ievent; /* Interrupt event reg */ +@@ -57,6 +96,7 @@ typedef struct fec { + unsigned long fec_x_des_start; /* Transmit descriptor ring */ + unsigned long fec_r_buff_size; /* Maximum receive buff size */ + } fec_t; ++#endif + + #else + +@@ -88,8 +128,8 @@ typedef struct fec { + unsigned long fec_reserved7[158]; + unsigned long fec_addr_low; /* Low 32bits MAC address */ + unsigned long fec_addr_high; /* High 16bits MAC address */ +- unsigned long fec_grp_hash_table_high;/* High 32bits hash table */ +- unsigned long fec_grp_hash_table_low; /* Low 32bits hash table */ ++ unsigned long fec_hash_table_high; /* High 32bits hash table */ ++ unsigned long fec_hash_table_low; /* Low 32bits hash table */ + unsigned long fec_r_des_start; /* Receive descriptor ring */ + unsigned long fec_x_des_start; /* Transmit descriptor ring */ + unsigned long fec_r_buff_size; /* Maximum receive buff size */ +@@ -103,17 +143,20 @@ typedef struct fec { + /* + * Define the buffer descriptor structure. + */ +-#ifdef CONFIG_ARCH_MXC ++/* Please see "Receive Buffer Descriptor Field Definitions" in Specification. ++ * It's LE. ++ */ ++#if defined(CONFIG_ARCH_MXC) + typedef struct bufdesc { +- unsigned short cbd_datlen; /* Data length */ +- unsigned short cbd_sc; /* Control and status info */ +- unsigned long cbd_bufaddr; /* Buffer address */ ++ unsigned short cbd_datlen; /* Data length */ ++ unsigned short cbd_sc; /* Control and status info */ ++ dma_addr_t cbd_bufaddr; /* Buffer address as seen by FEC Hardware */ + } cbd_t; + #else + typedef struct bufdesc { + unsigned short cbd_sc; /* Control and status info */ + unsigned short cbd_datlen; /* Data length */ +- unsigned long cbd_bufaddr; /* Buffer address */ ++ dma_addr_t cbd_bufaddr; /* Buffer address */ + } cbd_t; + #endif + +@@ -121,7 +164,7 @@ typedef struct bufdesc { + * The following definitions courtesy of commproc.h, which where + * Copyright (c) 1997 Dan Malek (dmalek@jlc.net). + */ +-#define BD_SC_EMPTY ((ushort)0x8000) /* Recieve is empty */ ++#define BD_SC_EMPTY ((ushort)0x8000) /* Receive is empty */ + #define BD_SC_READY ((ushort)0x8000) /* Transmit is ready */ + #define BD_SC_WRAP ((ushort)0x2000) /* Last buffer descriptor */ + #define BD_SC_INTRPT ((ushort)0x1000) /* Interrupt on change */ +@@ -168,5 +211,22 @@ typedef struct bufdesc { + #define BD_ENET_TX_STATS ((ushort)0x03ff) /* All status bits */ + + ++#define RCR_LOOP (1 << 0) ++#define RCR_DRT (1 << 1) ++#define RCR_MII_MODE (1 << 2) ++#define RCR_PROM (1 << 3) ++#define RCR_BC_REJ (1 << 4) ++#define RCR_FCE (1 << 5) ++#define RCR_MAX_FL_SHIFT 16 ++#define RCR_MAX_FL_MASK (0x7ff << (RCR_MAX_FL_SHIFT)) ++#define RCR_MAX_FL_set(n) (((n) << (RCR_MAX_FL_SHIFT)) & (RCR_MAX_FL_MASK)) ++#define RCR_MAX_FL_get(n) (((n) & (RCR_MAX_FL_MASK)) >> (RCR_MAX_FL_SHIFT)) ++ ++#define TCR_GTS (1 << 0) ++#define TCR_HBC (1 << 1) ++#define TCR_FDEN (1 << 2) ++#define TCR_TFCPAUSE (1 << 3) ++#define TCR_RFCPAUSE (1 << 4) ++ + /****************************************************************************/ + #endif /* FEC_H */ +diff -urNp linux-2.6.30-rc4/drivers/video/imxfb.c linux-2.6.30-rc4-karo/drivers/video/imxfb.c +--- linux-2.6.30-rc4/drivers/video/imxfb.c 2009-05-13 09:46:19.000000000 +0200 ++++ linux-2.6.30-rc4-karo/drivers/video/imxfb.c 2009-06-02 17:05:26.000000000 +0200 +@@ -570,7 +570,7 @@ static int imxfb_resume(struct platform_ + #define imxfb_resume NULL + #endif + +-static int __init imxfb_init_fbinfo(struct platform_device *pdev) ++static int __devinit imxfb_init_fbinfo(struct platform_device *pdev) + { + struct imx_fb_platform_data *pdata = pdev->dev.platform_data; + struct fb_info *info = dev_get_drvdata(&pdev->dev); +@@ -636,7 +636,7 @@ static int __init imxfb_init_fbinfo(stru + return 0; + } + +-static int __init imxfb_probe(struct platform_device *pdev) ++static int __devinit imxfb_probe(struct platform_device *pdev) + { + struct imxfb_info *fbi; + struct fb_info *info; +@@ -754,7 +754,7 @@ failed_map: + failed_getclock: + iounmap(fbi->regs); + failed_ioremap: +- release_mem_region(res->start, res->end - res->start); ++ release_mem_region(res->start, resource_size(res)); + failed_req: + kfree(info->pseudo_palette); + failed_init: +@@ -763,7 +763,7 @@ failed_init: + return ret; + } + +-static int __devexit imxfb_remove(struct platform_device *pdev) ++static int imxfb_remove(struct platform_device *pdev) + { + struct imx_fb_platform_data *pdata; + struct fb_info *info = platform_get_drvdata(pdev); +@@ -785,7 +785,7 @@ static int __devexit imxfb_remove(struct + framebuffer_release(info); + + iounmap(fbi->regs); +- release_mem_region(res->start, res->end - res->start + 1); ++ release_mem_region(res->start, resource_size(res)); + clk_disable(fbi->clk); + clk_put(fbi->clk); + +@@ -794,7 +794,7 @@ static int __devexit imxfb_remove(struct + return 0; + } + +-void imxfb_shutdown(struct platform_device * dev) ++void imxfb_shutdown(struct platform_device *dev) + { + struct fb_info *info = platform_get_drvdata(dev); + struct imxfb_info *fbi = info->par; +@@ -804,7 +804,8 @@ void imxfb_shutdown(struct platform_dev + static struct platform_driver imxfb_driver = { + .suspend = imxfb_suspend, + .resume = imxfb_resume, +- .remove = __devexit_p(imxfb_remove), ++// .remove = __devexit_p(imxfb_remove), ++ .remove = imxfb_remove, + .shutdown = imxfb_shutdown, + .driver = { + .name = DRIVER_NAME, +diff -urNp linux-2.6.30-rc4/include/linux/fec_enet.h linux-2.6.30-rc4-karo/include/linux/fec_enet.h +--- linux-2.6.30-rc4/include/linux/fec_enet.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30-rc4-karo/include/linux/fec_enet.h 2009-06-02 17:05:27.000000000 +0200 +@@ -0,0 +1,26 @@ ++/* ++ * Copyright (C) 2007 Lothar Wassmann <LW@KARO-electronics.de> ++ * ++ * platform_data definitions for fec_enet device ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 as published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the: ++ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 ++ */ ++ ++struct fec_enet_platform_data { ++ /* callback for platform specific initialization */ ++ int (*arch_init)(struct platform_device *dev); ++ void (*arch_exit)(struct platform_device *dev); ++ int (*suspend)(struct platform_device *dev); ++ int (*resume)(struct platform_device *dev); ++}; +diff -urNp linux-2.6.30-rc4/kernel/printk.c linux-2.6.30-rc4-karo/kernel/printk.c +--- linux-2.6.30-rc4/kernel/printk.c 2009-05-13 09:46:19.000000000 +0200 ++++ linux-2.6.30-rc4-karo/kernel/printk.c 2009-06-02 17:05:27.000000000 +0200 +@@ -637,9 +637,12 @@ static int acquire_console_semaphore_for + static const char recursion_bug_msg [] = + KERN_CRIT "BUG: recent printk recursion!\n"; + static int recursion_bug; +-static int new_text_line = 1; ++ static int new_text_line = 1; + static char printk_buf[1024]; + ++#ifdef CONFIG_DEBUG_LL ++extern void asmlinkage printascii(const char *); ++#endif + asmlinkage int vprintk(const char *fmt, va_list args) + { + int printed_len = 0; +@@ -687,6 +690,9 @@ asmlinkage int vprintk(const char *fmt, + sizeof(printk_buf) - printed_len, fmt, args); + + ++#ifdef CONFIG_DEBUG_LL ++ printascii(printk_buf); ++#endif + /* + * Copy the output into log_buf. If the caller didn't provide + * appropriate log level tags, we insert them here |