diff options
author | OpenEmbedded Project <openembedded-devel@lists.openembedded.org> | 2007-10-18 19:29:43 +0000 |
---|---|---|
committer | OpenEmbedded Project <openembedded-devel@lists.openembedded.org> | 2007-10-18 19:29:43 +0000 |
commit | 1010441880aee280580534f0fb0a68e4a98eb375 (patch) | |
tree | 58800c7dbb1b770ab67a02fa08d9767f6fc9471c /packages/linux | |
parent | 7bcfa6ab969ca61e3bcde9eee3240f32f578d1e5 (diff) | |
parent | fdb7f09ca89562f586e1d9a6235e6a72da1ff77b (diff) |
merge of '947287d07500dfb42d1f2f6b23d0bcd2ed00c920'
and 'da91d7ddb56154d2bd01a37943cd55b4ba49ac8a'
Diffstat (limited to 'packages/linux')
70 files changed, 27960 insertions, 267 deletions
diff --git a/packages/linux/compulab-pxa270_2.6.16.bb b/packages/linux/compulab-pxa270_2.6.16.bb index ce6748149b..bd3135510f 100644 --- a/packages/linux/compulab-pxa270_2.6.16.bb +++ b/packages/linux/compulab-pxa270_2.6.16.bb @@ -68,5 +68,5 @@ do_deploy[dirs] = "${S}" addtask deploy before do_install after do_compile addtask compulab_image before do_install after do_deploy -COMPATIBLE_MACHINE = "compulab-pxa270" +COMPATIBLE_MACHINE = "cm-x270" diff --git a/packages/linux/compulab-pxa270_2.6.22.bb b/packages/linux/compulab-pxa270_2.6.22.bb deleted file mode 100644 index 86a7626d8a..0000000000 --- a/packages/linux/compulab-pxa270_2.6.22.bb +++ /dev/null @@ -1,67 +0,0 @@ -require linux.inc - -SECTION = "kernel" -DESCRIPTION = "Linux kernel for the Compulab PXA270 system" -LICENSE = "GPL" -PR = "r1" - -SRC_URI = "ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-${PV}.tar.bz2 \ - file://0001-cm-x270-base2.patch;patch=1 \ - file://0002-cm-x270-match-type.patch;patch=1 \ - file://0003-cm-x270-ide.patch;patch=1 \ - file://0004-cm-x270-it8152.patch;patch=1 \ - file://0005-cm-x270-pcmcia.patch;patch=1 \ - file://0006-ramdisk_load.patch;patch=1 \ - file://0007-mmcsd_large_cards-r0.patch;patch=1 \ - file://0008-cm-x270-nand-simplify-name.patch;patch=1 \ - file://defconfig \ - " - -# file://0009-cursor-fix.patch - - - -# Note, for 2.6.22, we are no longer using the compulab binary -# flash driver -- use JFFS2 instead -# see notes in conf/machine/compulab-pxa270.conf - -S = "${WORKDIR}/linux-${PV}" - -COMPATIBLE_HOST = 'arm.*-linux' -COMPATIBLE_MACHINE = "compulab-pxa270" - -CMDLINE = "console=${CMX270_CONSOLE_SERIAL_PORT},38400 monitor=8 bpp=16 mem=64M mtdparts=physmap-flash.0:256k(boot)ro,0x180000(kernel),-(root);cm-x270-nand:64m(app),-(data) rdinit=/sbin/init root=mtd3 rootfstype=jffs2" - -inherit kernel -inherit package - -ARCH = "arm" - -FILES_kernel-image = "" - -python do_compulab_image() { - import os - import os.path - import struct - - deploy_dir = bb.data.getVar('DEPLOY_DIR_IMAGE', d, 1) - kernel_file = os.path.join(deploy_dir, bb.data.expand('${KERNEL_IMAGE_BASE_NAME}', d) + '.bin') - img_file = os.path.join(deploy_dir, bb.data.expand('${KERNEL_IMAGE_BASE_NAME}', d) + '.cmx270') - - fo = open(img_file, 'wb') - - image_data = open(kernel_file, 'rb').read() - - # first write size into first 4 bytes - size_s = struct.pack('i', len(image_data)) - - # truncate size if we are running on a 64-bit host - size_s = size_s[:4] - - fo.write(size_s) - fo.write(image_data) - fo.close() -} - -addtask compulab_image after do_deploy before do_package - diff --git a/packages/linux/compulab-pxa270-2.6.22/.mtn2git_empty b/packages/linux/em-x270-2.6.23/.mtn2git_empty index e69de29bb2..e69de29bb2 100644 --- a/packages/linux/compulab-pxa270-2.6.22/.mtn2git_empty +++ b/packages/linux/em-x270-2.6.23/.mtn2git_empty diff --git a/packages/linux/em-x270-2.6.23/defconfig b/packages/linux/em-x270-2.6.23/defconfig new file mode 100644 index 0000000000..3246136571 --- /dev/null +++ b/packages/linux/em-x270-2.6.23/defconfig @@ -0,0 +1,1354 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.23-rc9 +# Tue Oct 9 11:19:21 2007 +# +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_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_ZONE_DMA=y +CONFIG_ARCH_MTD_XIP=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="-em-x270" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_USER_NS is not set +# CONFIG_AUDIT is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=17 +CONFIG_SYSFS_DEPRECATED=y +# CONFIG_RELAY is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=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_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_ANON_INODES=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLUB_DEBUG=y +# CONFIG_SLAB is not set +CONFIG_SLUB=y +# CONFIG_SLOB is not set +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set +# CONFIG_BLK_DEV_BSG 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" + +# +# 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_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IMX 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_KS8695 is not set +# CONFIG_ARCH_NS9XXX is not set +# CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_PNX4008 is not set +CONFIG_ARCH_PXA=y +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 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 + +# +# Intel PXA2xx Implementations +# +# CONFIG_ARCH_LUBBOCK is not set +# CONFIG_MACH_LOGICPD_PXA270 is not set +# CONFIG_MACH_MAINSTONE is not set +# CONFIG_ARCH_PXA_IDP is not set +# CONFIG_PXA_SHARPSL is not set +# CONFIG_MACH_TRIZEPS4 is not set +CONFIG_MACH_EM_X270=y +CONFIG_PXA27x=y +CONFIG_PXA_PWR_I2C=y + +# +# Boot options +# + +# +# Power management +# + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_XSCALE=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5T=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_OUTER_CACHE is not set +CONFIG_IWMMXT=y +CONFIG_XSCALE_PMU=y + +# +# Bus support +# +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +# CONFIG_TICK_ONESHOT is not set +# CONFIG_NO_HZ is not set +# CONFIG_HIGH_RES_TIMERS is not set +# CONFIG_PREEMPT is not set +CONFIG_HZ=100 +CONFIG_AEABI=y +CONFIG_OABI_COMPAT=y +# CONFIG_ARCH_DISCONTIGMEM_ENABLE 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_SPARSEMEM_STATIC is not set +CONFIG_SPLIT_PTLOCK_CPUS=4096 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=1 +CONFIG_BOUNCE=y +CONFIG_VIRT_TO_BUS=y +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="root=/dev/mtdblock2 rootfstype=jffs2 console=ttyS0,115200" +# CONFIG_XIP_KERNEL is not set +# CONFIG_KEXEC is not set + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_TABLE=y +# CONFIG_CPU_FREQ_DEBUG is not set +CONFIG_CPU_FREQ_STAT=y +# CONFIG_CPU_FREQ_STAT_DETAILS is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=m +CONFIG_CPU_FREQ_GOV_USERSPACE=m +CONFIG_CPU_FREQ_GOV_ONDEMAND=m +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m +CONFIG_CPU_FREQ_PXA=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 + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_AOUT=m +CONFIG_BINFMT_MISC=m + +# +# Power management options +# +CONFIG_PM=y +CONFIG_PM_LEGACY=y +# CONFIG_PM_DEBUG is not set +CONFIG_PM_SLEEP=y +CONFIG_SUSPEND_UP_POSSIBLE=y +CONFIG_SUSPEND=y +CONFIG_APM_EMULATION=y + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# 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 is not set +# 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=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# 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_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL 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_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 + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +CONFIG_NET_SCH_FIFO=y + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +CONFIG_BT=m +CONFIG_BT_L2CAP=m +CONFIG_BT_SCO=m +CONFIG_BT_RFCOMM=m +# CONFIG_BT_RFCOMM_TTY is not set +CONFIG_BT_BNEP=m +# CONFIG_BT_BNEP_MC_FILTER is not set +# CONFIG_BT_BNEP_PROTO_FILTER is not set +CONFIG_BT_HIDP=m + +# +# Bluetooth device drivers +# +CONFIG_BT_HCIUSB=m +# CONFIG_BT_HCIUSB_SCO is not set +CONFIG_BT_HCIUART=m +# CONFIG_BT_HCIUART_H4 is not set +# CONFIG_BT_HCIUART_BCSP is not set +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBPA10X=m +CONFIG_BT_HCIBFUSB=m +# CONFIG_BT_HCIVHCI is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +CONFIG_CFG80211=m +CONFIG_WIRELESS_EXT=y +CONFIG_MAC80211=m +# CONFIG_MAC80211_LEDS is not set +CONFIG_MAC80211_DEBUGFS=y +# CONFIG_MAC80211_DEBUG is not set +CONFIG_IEEE80211=m +# CONFIG_IEEE80211_DEBUG is not set +CONFIG_IEEE80211_CRYPT_WEP=m +CONFIG_IEEE80211_CRYPT_CCMP=m +# CONFIG_IEEE80211_CRYPT_TKIP is not set +# CONFIG_IEEE80211_SOFTMAC is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +# 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 is not set +CONFIG_MTD_CONCAT=y +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set +# CONFIG_MTD_AFS_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 + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +CONFIG_MTD_JEDECPROBE=y +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS 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_CFI_INTELEXT=y +CONFIG_MTD_CFI_AMDSTD=y +CONFIG_MTD_CFI_STAA=y +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_XIP is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_START=0x0 +CONFIG_MTD_PHYSMAP_LEN=0x100000 +CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_IMPA7 is not set +# CONFIG_MTD_SHARP_SL 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 is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +# CONFIG_MTD_NAND_H1900 is not set +CONFIG_MTD_NAND_IDS=y +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_SHARPSL is not set +# CONFIG_MTD_NAND_NANDSIM is not set +CONFIG_MTD_NAND_PLATFORM=y +# CONFIG_MTD_ONENAND is not set + +# +# UBI - Unsorted block images +# +CONFIG_MTD_UBI=m +CONFIG_MTD_UBI_WL_THRESHOLD=4096 +CONFIG_MTD_UBI_BEB_RESERVE=1 +CONFIG_MTD_UBI_GLUEBI=y + +# +# UBI debugging options +# +# CONFIG_MTD_UBI_DEBUG is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=12000 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +# CONFIG_SCSI_PROC_FS is not set + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +CONFIG_SCSI_LOWLEVEL=y +# CONFIG_ISCSI_TCP is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +CONFIG_NETDEVICES=y +# CONFIG_NETDEVICES_MULTIQUEUE is not set +# 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_PHYLIB is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_AX88796 is not set +# CONFIG_SMC91X is not set +CONFIG_DM9000=y +# CONFIG_SMC911X 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 + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET_MII is not set +# CONFIG_USB_USBNET is not set +# CONFIG_WAN is not set +CONFIG_PPP=m +# CONFIG_PPP_MULTILINK is not set +# CONFIG_PPP_FILTER is not set +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_MPPE=m +# CONFIG_PPPOE is not set +CONFIG_PPPOL2TP=m +# CONFIG_SLIP is not set +CONFIG_SLHC=m +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# 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=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG 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_PXA27x=y +# CONFIG_KEYBOARD_GPIO is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +CONFIG_INPUT_TOUCHSCREEN=y +# CONFIG_TOUCHSCREEN_FUJITSU is not set +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +CONFIG_TOUCHSCREEN_WM97XX=y +# CONFIG_TOUCHSCREEN_WM9705 is not set +CONFIG_TOUCHSCREEN_WM9712=y +# CONFIG_TOUCHSCREEN_WM9713 is not set +# CONFIG_TOUCHSCREEN_PENMOUNT is not set +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set +# CONFIG_TOUCHSCREEN_UCB1400 is not set +# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +# CONFIG_SERIO_SERPORT is not set +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_PXA=y +CONFIG_SERIAL_PXA_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +# CONFIG_LEGACY_PTYS is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_WATCHDOG is not set +CONFIG_HW_RANDOM=m +# CONFIG_NVRAM is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +# CONFIG_I2C_CHARDEV is not set + +# +# I2C Algorithms +# +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_GPIO is not set +CONFIG_I2C_PXA=y +# CONFIG_I2C_PXA_SLAVE is not set +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_TINY_USB is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_SENSORS_DS1337 is not set +# CONFIG_SENSORS_DS1374 is not set +# CONFIG_DS1682 is not set +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_MAX6875 is not set +# CONFIG_SENSORS_TSL2550 is not set +CONFIG_DA9030=y +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set +# CONFIG_W1 is not set +CONFIG_POWER_SUPPLY=y +# CONFIG_POWER_SUPPLY_DEBUG is not set +# CONFIG_PDA_POWER is not set +CONFIG_APM_POWER=y +# CONFIG_BATTERY_DS2760 is not set +# CONFIG_BATTERY_EM_X270 is not set +# CONFIG_HWMON is not set +CONFIG_MISC_DEVICES=y +# CONFIG_EEPROM_93CX6 is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=m + +# +# LED drivers +# +CONFIG_LEDS_GPIO=m +CONFIG_LEDS_EM_X270=m + +# +# LED Triggers +# +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_TIMER=m +CONFIG_LEDS_TRIGGER_HEARTBEAT=m + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set +# CONFIG_DVB_CORE is not set +# CONFIG_DAB is not set + +# +# Graphics support +# +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_LCD_CLASS_DEVICE=y +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_CORGI=y + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set +# CONFIG_VGASTATE is not set +CONFIG_VIDEO_OUTPUT_CONTROL=m +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_SYS_FOPS is not set +CONFIG_FB_DEFERRED_IO=y +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_S1D13XXX is not set +CONFIG_FB_PXA=y +CONFIG_FB_PXA_PARAMETERS=y +# CONFIG_FB_MBX is not set +# CONFIG_FB_VIRTUAL 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 is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +# 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 + +# +# Sound +# +CONFIG_SOUND=y + +# +# Advanced Linux Sound Architecture +# +CONFIG_SND=y +CONFIG_SND_TIMER=y +CONFIG_SND_PCM=y +# CONFIG_SND_SEQUENCER is not set +CONFIG_SND_OSSEMUL=y +CONFIG_SND_MIXER_OSS=y +CONFIG_SND_PCM_OSS=y +CONFIG_SND_PCM_OSS_PLUGINS=y +# CONFIG_SND_DYNAMIC_MINORS is not set +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set + +# +# Generic devices +# +CONFIG_SND_AC97_CODEC=m +# CONFIG_SND_DUMMY is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set + +# +# ALSA ARM devices +# +CONFIG_SND_PXA2XX_PCM=m +CONFIG_SND_PXA2XX_AC97=m + +# +# USB devices +# +# CONFIG_SND_USB_AUDIO is not set +# CONFIG_SND_USB_CAIAQ is not set + +# +# System on Chip audio support +# +CONFIG_SND_SOC_AC97_BUS=y +CONFIG_SND_SOC=y +CONFIG_SND_PXA2XX_SOC=y +CONFIG_SND_PXA2XX_SOC_AC97=y +CONFIG_SND_PXA2XX_SOC_EM_X270=y + +# +# SoC Audio support for SuperH +# +CONFIG_SND_SOC_WM9712=y + +# +# Open Sound System +# +# CONFIG_SOUND_PRIME is not set +CONFIG_AC97_BUS=y +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +# CONFIG_HID_DEBUG is not set + +# +# USB Input Devices +# +CONFIG_USB_HID=y +# CONFIG_USB_HIDINPUT_POWERBOOK is not set +# CONFIG_HID_FF is not set +# CONFIG_USB_HIDDEV is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB_ARCH_HAS_EHCI is not set +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_DEVICE_CLASS is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_SUSPEND is not set +# CONFIG_USB_PERSIST is not set +# CONFIG_USB_OTG is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_ISP116X_HCD is not set +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set + +# +# USB Device Class drivers +# +CONFIG_USB_ACM=m +CONFIG_USB_PRINTER=m + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# may also be needed; see USB_STORAGE Help for more information +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Imaging devices +# +CONFIG_USB_MDC800=m +CONFIG_USB_MICROTEK=m +# CONFIG_USB_MON is not set + +# +# USB port drivers +# + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_BERRY_CHARGE is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGET is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set + +# +# USB DSL modem support +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +CONFIG_MMC_UNSAFE_RESUME=y + +# +# MMC/SD Card Drivers +# +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_BOUNCE=y + +# +# MMC/SD Host Controller Drivers +# +CONFIG_MMC_PXA=y +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc1" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set + +# +# SPI RTC drivers +# + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_CMOS is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T59 is not set +CONFIG_RTC_DRV_V3020=y + +# +# on-CPU RTC drivers +# +CONFIG_RTC_DRV_SA1100=y + +# +# DMA Engine support +# +# CONFIG_DMA_ENGINE is not set + +# +# DMA Clients +# + +# +# DMA Devices +# + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +# CONFIG_EXT4DEV_FS is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# 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_SUMMARY=y +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_SUNRPC_BIND34 is not set +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +CONFIG_SMB_FS=y +# CONFIG_SMB_NLS_DEFAULT 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 is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# 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 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=y +# 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 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +CONFIG_NLS_UTF8=y + +# +# Distributed Lock Manager +# +# CONFIG_DLM is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +# CONFIG_DETECT_SOFTLOCKUP is not set +CONFIG_SCHED_DEBUG=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set +# CONFIG_SLUB_DEBUG_ON 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 is not set +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_LIST is not set +CONFIG_FRAME_POINTER=y +CONFIG_FORCED_INLINING=y +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_FAULT_INJECTION is not set +CONFIG_DEBUG_USER=y +CONFIG_DEBUG_ERRORS=y +CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_ICEDCC is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +CONFIG_CRYPTO=y +CONFIG_CRYPTO_ALGAPI=m +CONFIG_CRYPTO_BLKCIPHER=m +CONFIG_CRYPTO_MANAGER=m +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_MD4 is not set +# CONFIG_CRYPTO_MD5 is not set +CONFIG_CRYPTO_SHA1=m +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_GF128MUL is not set +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_CBC=m +CONFIG_CRYPTO_PCBC=m +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_DES is not set +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_SERPENT is not set +CONFIG_CRYPTO_AES=m +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_TEA is not set +CONFIG_CRYPTO_ARC4=m +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_TEST is not set +CONFIG_CRYPTO_HW=y + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_CRC_CCITT=m +# CONFIG_CRC16 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_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y diff --git a/packages/linux/em-x270-2.6.23/em-x270.patch b/packages/linux/em-x270-2.6.23/em-x270.patch new file mode 100644 index 0000000000..3c28be83c7 --- /dev/null +++ b/packages/linux/em-x270-2.6.23/em-x270.patch @@ -0,0 +1,12063 @@ + arch/arm/Kconfig | 13 +- + arch/arm/configs/em_x270_defconfig | 367 +++-- + arch/arm/mach-pxa/Kconfig | 8 + + arch/arm/mach-pxa/Makefile | 9 +- + arch/arm/mach-pxa/cpu-pxa.c | 442 ++++++ + arch/arm/mach-pxa/em-x270-devices.c | 331 +++++ + arch/arm/mach-pxa/em-x270-lcd.c | 223 +++ + arch/arm/mach-pxa/em-x270-pm.c | 892 ++++++++++++ + arch/arm/mach-pxa/em-x270.c | 127 ++- + arch/arm/mach-pxa/pwr-i2c.c | 539 +++++++ + arch/arm/mach-pxa/pxa27x.c | 6 +- + arch/arm/mach-pxa/spitz.c | 27 + + drivers/i2c/chips/Kconfig | 13 + + drivers/i2c/chips/Makefile | 1 + + drivers/i2c/chips/da9030.c | 1213 ++++++++++++++++ + drivers/i2c/chips/da9030.h | 282 ++++ + drivers/input/touchscreen/Kconfig | 43 + + drivers/input/touchscreen/Makefile | 14 + + drivers/input/touchscreen/wm9705.c | 360 +++++ + drivers/input/touchscreen/wm9712.c | 464 ++++++ + drivers/input/touchscreen/wm9713.c | 461 ++++++ + drivers/input/touchscreen/wm97xx-core.c | 859 +++++++++++ + drivers/leds/Kconfig | 6 + + drivers/leds/Makefile | 1 + + drivers/leds/leds-em-x270.c | 99 ++ + drivers/mtd/chips/jedec_probe.c | 58 +- + drivers/net/dm9000.c | 1 + + drivers/power/Kconfig | 6 + + drivers/power/Makefile | 1 + + drivers/power/em_x270_battery.c | 579 ++++++++ + drivers/usb/gadget/Kconfig | 20 + + drivers/usb/gadget/Makefile | 1 + + drivers/usb/gadget/epautoconf.c | 9 +- + drivers/usb/gadget/ether.c | 63 +- + drivers/usb/gadget/file_storage.c | 11 +- + drivers/usb/gadget/pxa27x_udc.c | 2387 +++++++++++++++++++++++++++++++ + drivers/usb/gadget/pxa27x_udc.h | 298 ++++ + drivers/usb/gadget/pxa2xx_udc.h | 7 +- + drivers/usb/gadget/serial.c | 18 +- + drivers/usb/gadget/zero.c | 13 +- + drivers/video/backlight/Kconfig | 2 +- + include/asm-arm/arch-pxa/pwr-i2c.h | 61 + + include/linux/da9030.h | 118 ++ + include/linux/usb_gadget.h | 23 +- + include/linux/wm97xx.h | 291 ++++ + sound/soc/pxa/Kconfig | 9 + + sound/soc/pxa/Makefile | 2 + + sound/soc/pxa/em-x270.c | 137 ++ + 48 files changed, 10742 insertions(+), 173 deletions(-) + +diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig +index 691aae3..cf1dbc2 100644 +--- a/arch/arm/Kconfig ++++ b/arch/arm/Kconfig +@@ -858,7 +858,7 @@ config KEXEC + + endmenu + +-if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP || ARCH_IMX ) ++if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP || ARCH_IMX || ARCH_PXA) + + menu "CPU Frequency scaling" + +@@ -894,6 +894,15 @@ config CPU_FREQ_IMX + + If in doubt, say N. + ++config CPU_FREQ_PXA ++ tristate "CPUfreq driver for PXA2xx CPUs" ++ depends on CPU_FREQ && ARCH_PXA ++ default y ++ help ++ Thes enables the CPUfreq driver for PXA2xx CPUs. ++ ++ If in doubt, say Y. ++ + endmenu + + endif +@@ -1029,6 +1038,8 @@ source "drivers/spi/Kconfig" + + source "drivers/w1/Kconfig" + ++source "drivers/power/Kconfig" ++ + source "drivers/hwmon/Kconfig" + + #source "drivers/l3/Kconfig" +diff --git a/arch/arm/configs/em_x270_defconfig b/arch/arm/configs/em_x270_defconfig +index 6bea090..3246136 100644 +--- a/arch/arm/configs/em_x270_defconfig ++++ b/arch/arm/configs/em_x270_defconfig +@@ -1,13 +1,13 @@ + # + # Automatically generated make config: don't edit +-# Linux kernel version: 2.6.22 +-# Mon Jul 9 15:18:20 2007 ++# Linux kernel version: 2.6.23-rc9 ++# Tue Oct 9 11:19:21 2007 + # + CONFIG_ARM=y + CONFIG_SYS_SUPPORTS_APM_EMULATION=y + CONFIG_GENERIC_GPIO=y + CONFIG_GENERIC_TIME=y +-# CONFIG_GENERIC_CLOCKEVENTS is not set ++CONFIG_GENERIC_CLOCKEVENTS=y + CONFIG_MMU=y + # CONFIG_NO_IOPORT is not set + CONFIG_GENERIC_HARDIRQS=y +@@ -27,25 +27,20 @@ CONFIG_VECTORS_BASE=0xffff0000 + CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + + # +-# Code maturity level options ++# General setup + # + CONFIG_EXPERIMENTAL=y + CONFIG_BROKEN_ON_SMP=y + CONFIG_INIT_ENV_ARG_LIMIT=32 +- +-# +-# General setup +-# + CONFIG_LOCALVERSION="-em-x270" + # CONFIG_LOCALVERSION_AUTO is not set + CONFIG_SWAP=y + CONFIG_SYSVIPC=y +-# CONFIG_IPC_NS is not set + CONFIG_SYSVIPC_SYSCTL=y + # CONFIG_POSIX_MQUEUE is not set + # CONFIG_BSD_PROCESS_ACCT is not set + # CONFIG_TASKSTATS is not set +-# CONFIG_UTS_NS is not set ++# CONFIG_USER_NS is not set + # CONFIG_AUDIT is not set + CONFIG_IKCONFIG=y + CONFIG_IKCONFIG_PROC=y +@@ -71,34 +66,27 @@ CONFIG_FUTEX=y + CONFIG_ANON_INODES=y + CONFIG_EPOLL=y + CONFIG_SIGNALFD=y +-CONFIG_TIMERFD=y + CONFIG_EVENTFD=y + CONFIG_SHMEM=y + CONFIG_VM_EVENT_COUNTERS=y +-CONFIG_SLAB=y +-# CONFIG_SLUB is not set ++CONFIG_SLUB_DEBUG=y ++# CONFIG_SLAB is not set ++CONFIG_SLUB=y + # CONFIG_SLOB is not set + CONFIG_RT_MUTEXES=y + # CONFIG_TINY_SHMEM is not set + CONFIG_BASE_SMALL=0 +- +-# +-# Loadable module support +-# + CONFIG_MODULES=y + CONFIG_MODULE_UNLOAD=y + CONFIG_MODULE_FORCE_UNLOAD=y + # CONFIG_MODVERSIONS is not set + # CONFIG_MODULE_SRCVERSION_ALL is not set + CONFIG_KMOD=y +- +-# +-# Block layer +-# + CONFIG_BLOCK=y + # CONFIG_LBD is not set + # CONFIG_BLK_DEV_IO_TRACE is not set + # CONFIG_LSF is not set ++# CONFIG_BLK_DEV_BSG is not set + + # + # IO Schedulers +@@ -139,6 +127,7 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" + # CONFIG_ARCH_L7200 is not set + # CONFIG_ARCH_KS8695 is not set + # CONFIG_ARCH_NS9XXX is not set ++# CONFIG_ARCH_MXC is not set + # CONFIG_ARCH_PNX4008 is not set + CONFIG_ARCH_PXA=y + # CONFIG_ARCH_RPC is not set +@@ -160,6 +149,15 @@ CONFIG_ARCH_PXA=y + # CONFIG_MACH_TRIZEPS4 is not set + CONFIG_MACH_EM_X270=y + CONFIG_PXA27x=y ++CONFIG_PXA_PWR_I2C=y ++ ++# ++# Boot options ++# ++ ++# ++# Power management ++# + + # + # Processor Type +@@ -185,6 +183,7 @@ CONFIG_XSCALE_PMU=y + # + # Bus support + # ++# CONFIG_PCI_SYSCALL is not set + # CONFIG_ARCH_SUPPORTS_MSI is not set + + # +@@ -196,8 +195,9 @@ CONFIG_XSCALE_PMU=y + # Kernel Features + # + # CONFIG_TICK_ONESHOT is not set ++# CONFIG_NO_HZ is not set ++# CONFIG_HIGH_RES_TIMERS is not set + # CONFIG_PREEMPT is not set +-# CONFIG_NO_IDLE_HZ is not set + CONFIG_HZ=100 + CONFIG_AEABI=y + CONFIG_OABI_COMPAT=y +@@ -212,6 +212,8 @@ CONFIG_FLAT_NODE_MEM_MAP=y + CONFIG_SPLIT_PTLOCK_CPUS=4096 + # CONFIG_RESOURCES_64BIT is not set + CONFIG_ZONE_DMA_FLAG=1 ++CONFIG_BOUNCE=y ++CONFIG_VIRT_TO_BUS=y + CONFIG_ALIGNMENT_TRAP=y + + # +@@ -219,11 +221,28 @@ CONFIG_ALIGNMENT_TRAP=y + # + CONFIG_ZBOOT_ROM_TEXT=0x0 + CONFIG_ZBOOT_ROM_BSS=0x0 +-CONFIG_CMDLINE="" ++CONFIG_CMDLINE="root=/dev/mtdblock2 rootfstype=jffs2 console=ttyS0,115200" + # CONFIG_XIP_KERNEL is not set + # CONFIG_KEXEC is not set + + # ++# CPU Frequency scaling ++# ++CONFIG_CPU_FREQ=y ++CONFIG_CPU_FREQ_TABLE=y ++# CONFIG_CPU_FREQ_DEBUG is not set ++CONFIG_CPU_FREQ_STAT=y ++# CONFIG_CPU_FREQ_STAT_DETAILS is not set ++CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y ++# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set ++CONFIG_CPU_FREQ_GOV_PERFORMANCE=y ++CONFIG_CPU_FREQ_GOV_POWERSAVE=m ++CONFIG_CPU_FREQ_GOV_USERSPACE=m ++CONFIG_CPU_FREQ_GOV_ONDEMAND=m ++CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m ++CONFIG_CPU_FREQ_PXA=y ++ ++# + # Floating point emulation + # + +@@ -238,8 +257,8 @@ CONFIG_FPE_NWFPE=y + # Userspace binary formats + # + CONFIG_BINFMT_ELF=y +-# CONFIG_BINFMT_AOUT is not set +-# CONFIG_BINFMT_MISC is not set ++CONFIG_BINFMT_AOUT=m ++CONFIG_BINFMT_MISC=m + + # + # Power management options +@@ -247,8 +266,10 @@ CONFIG_BINFMT_ELF=y + CONFIG_PM=y + CONFIG_PM_LEGACY=y + # CONFIG_PM_DEBUG is not set +-# CONFIG_PM_SYSFS_DEPRECATED is not set +-CONFIG_APM_EMULATION=m ++CONFIG_PM_SLEEP=y ++CONFIG_SUSPEND_UP_POSSIBLE=y ++CONFIG_SUSPEND=y ++CONFIG_APM_EMULATION=y + + # + # Networking +@@ -316,6 +337,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" + # QoS and/or fair queueing + # + # CONFIG_NET_SCHED is not set ++CONFIG_NET_SCH_FIFO=y + + # + # Network testing +@@ -350,9 +372,12 @@ CONFIG_BT_HCIBFUSB=m + # + # Wireless + # +-# CONFIG_CFG80211 is not set +-# CONFIG_WIRELESS_EXT is not set +-# CONFIG_MAC80211 is not set ++CONFIG_CFG80211=m ++CONFIG_WIRELESS_EXT=y ++CONFIG_MAC80211=m ++# CONFIG_MAC80211_LEDS is not set ++CONFIG_MAC80211_DEBUGFS=y ++# CONFIG_MAC80211_DEBUG is not set + CONFIG_IEEE80211=m + # CONFIG_IEEE80211_DEBUG is not set + CONFIG_IEEE80211_CRYPT_WEP=m +@@ -360,6 +385,7 @@ CONFIG_IEEE80211_CRYPT_CCMP=m + # CONFIG_IEEE80211_CRYPT_TKIP is not set + # CONFIG_IEEE80211_SOFTMAC is not set + # CONFIG_RFKILL is not set ++# CONFIG_NET_9P is not set + + # + # Device Drivers +@@ -374,10 +400,6 @@ CONFIG_FW_LOADER=y + # CONFIG_DEBUG_DRIVER is not set + # CONFIG_DEBUG_DEVRES is not set + # CONFIG_SYS_HYPERVISOR is not set +- +-# +-# Connector - unified userspace <-> kernelspace linker +-# + # CONFIG_CONNECTOR is not set + CONFIG_MTD=y + # CONFIG_MTD_DEBUG is not set +@@ -402,11 +424,10 @@ CONFIG_MTD_BLOCK=y + # + # RAM/ROM/Flash chip drivers + # +-# CONFIG_MTD_CFI is not set +-# CONFIG_MTD_JEDECPROBE is not set +-# CONFIG_MTD_CFI_NOSWAP is not set +-# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +-# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set ++CONFIG_MTD_CFI=y ++CONFIG_MTD_JEDECPROBE=y ++CONFIG_MTD_GEN_PROBE=y ++# CONFIG_MTD_CFI_ADV_OPTIONS is not set + CONFIG_MTD_MAP_BANK_WIDTH_1=y + CONFIG_MTD_MAP_BANK_WIDTH_2=y + CONFIG_MTD_MAP_BANK_WIDTH_4=y +@@ -417,14 +438,25 @@ 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_CFI_INTELEXT=y ++CONFIG_MTD_CFI_AMDSTD=y ++CONFIG_MTD_CFI_STAA=y ++CONFIG_MTD_CFI_UTIL=y + # CONFIG_MTD_RAM is not set + # CONFIG_MTD_ROM is not set + # CONFIG_MTD_ABSENT is not set ++# CONFIG_MTD_XIP is not set + + # + # Mapping drivers for chip access + # + # CONFIG_MTD_COMPLEX_MAPPINGS is not set ++CONFIG_MTD_PHYSMAP=y ++CONFIG_MTD_PHYSMAP_START=0x0 ++CONFIG_MTD_PHYSMAP_LEN=0x100000 ++CONFIG_MTD_PHYSMAP_BANKWIDTH=2 ++# CONFIG_MTD_ARM_INTEGRATOR is not set ++# CONFIG_MTD_IMPA7 is not set + # CONFIG_MTD_SHARP_SL is not set + # CONFIG_MTD_PLATRAM is not set + +@@ -457,21 +489,17 @@ CONFIG_MTD_NAND_PLATFORM=y + # + # UBI - Unsorted block images + # +-# CONFIG_MTD_UBI is not set ++CONFIG_MTD_UBI=m ++CONFIG_MTD_UBI_WL_THRESHOLD=4096 ++CONFIG_MTD_UBI_BEB_RESERVE=1 ++CONFIG_MTD_UBI_GLUEBI=y + + # +-# Parallel port support ++# UBI debugging options + # ++# CONFIG_MTD_UBI_DEBUG is not set + # CONFIG_PARPORT is not set +- +-# +-# Plug and Play support +-# +-# CONFIG_PNPACPI is not set +- +-# +-# Block devices +-# ++CONFIG_BLK_DEV=y + # CONFIG_BLK_DEV_COW_COMMON is not set + CONFIG_BLK_DEV_LOOP=y + # CONFIG_BLK_DEV_CRYPTOLOOP is not set +@@ -490,6 +518,7 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 + # + # CONFIG_RAID_ATTRS is not set + CONFIG_SCSI=y ++CONFIG_SCSI_DMA=y + # CONFIG_SCSI_TGT is not set + # CONFIG_SCSI_NETLINK is not set + # CONFIG_SCSI_PROC_FS is not set +@@ -519,36 +548,23 @@ CONFIG_SCSI_WAIT_SCAN=m + # CONFIG_SCSI_SPI_ATTRS is not set + # CONFIG_SCSI_FC_ATTRS is not set + # CONFIG_SCSI_ISCSI_ATTRS is not set +-# CONFIG_SCSI_SAS_ATTRS is not set + # CONFIG_SCSI_SAS_LIBSAS is not set +- +-# +-# SCSI low-level drivers +-# ++CONFIG_SCSI_LOWLEVEL=y + # CONFIG_ISCSI_TCP is not set + # CONFIG_SCSI_DEBUG is not set + # CONFIG_ATA is not set +- +-# +-# Multi-device support (RAID and LVM) +-# + # CONFIG_MD is not set +- +-# +-# Network device support +-# + CONFIG_NETDEVICES=y ++# CONFIG_NETDEVICES_MULTIQUEUE is not set + # 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_PHYLIB is not set +- +-# +-# Ethernet (10 or 100Mbit) +-# + CONFIG_NET_ETHERNET=y + CONFIG_MII=y ++# CONFIG_AX88796 is not set + # CONFIG_SMC91X is not set + CONFIG_DM9000=y + # CONFIG_SMC911X is not set +@@ -571,16 +587,22 @@ CONFIG_DM9000=y + # CONFIG_USB_USBNET_MII is not set + # CONFIG_USB_USBNET is not set + # CONFIG_WAN is not set +-# CONFIG_PPP is not set ++CONFIG_PPP=m ++# CONFIG_PPP_MULTILINK is not set ++# CONFIG_PPP_FILTER is not set ++CONFIG_PPP_ASYNC=m ++CONFIG_PPP_SYNC_TTY=m ++CONFIG_PPP_DEFLATE=m ++CONFIG_PPP_BSDCOMP=m ++CONFIG_PPP_MPPE=m ++# CONFIG_PPPOE is not set ++CONFIG_PPPOL2TP=m + # CONFIG_SLIP is not set ++CONFIG_SLHC=m + # CONFIG_SHAPER is not set + # CONFIG_NETCONSOLE is not set + # CONFIG_NETPOLL is not set + # CONFIG_NET_POLL_CONTROLLER is not set +- +-# +-# ISDN subsystem +-# + # CONFIG_ISDN is not set + + # +@@ -612,16 +634,21 @@ CONFIG_INPUT_KEYBOARD=y + # CONFIG_KEYBOARD_XTKBD is not set + # CONFIG_KEYBOARD_NEWTON is not set + # CONFIG_KEYBOARD_STOWAWAY is not set +-CONFIG_KEYBOARD_PXA27x=m ++CONFIG_KEYBOARD_PXA27x=y + # CONFIG_KEYBOARD_GPIO is not set + # CONFIG_INPUT_MOUSE is not set + # CONFIG_INPUT_JOYSTICK is not set + # CONFIG_INPUT_TABLET is not set + CONFIG_INPUT_TOUCHSCREEN=y ++# CONFIG_TOUCHSCREEN_FUJITSU is not set + # CONFIG_TOUCHSCREEN_GUNZE is not set + # CONFIG_TOUCHSCREEN_ELO is not set + # CONFIG_TOUCHSCREEN_MTOUCH is not set + # CONFIG_TOUCHSCREEN_MK712 is not set ++CONFIG_TOUCHSCREEN_WM97XX=y ++# CONFIG_TOUCHSCREEN_WM9705 is not set ++CONFIG_TOUCHSCREEN_WM9712=y ++# CONFIG_TOUCHSCREEN_WM9713 is not set + # CONFIG_TOUCHSCREEN_PENMOUNT is not set + # CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set + # CONFIG_TOUCHSCREEN_TOUCHWIN is not set +@@ -660,58 +687,91 @@ CONFIG_SERIAL_PXA_CONSOLE=y + CONFIG_SERIAL_CORE=y + CONFIG_SERIAL_CORE_CONSOLE=y + CONFIG_UNIX98_PTYS=y +-CONFIG_LEGACY_PTYS=y +-CONFIG_LEGACY_PTY_COUNT=256 +- +-# +-# IPMI +-# ++# CONFIG_LEGACY_PTYS is not set + # CONFIG_IPMI_HANDLER is not set + # CONFIG_WATCHDOG is not set + CONFIG_HW_RANDOM=m + # CONFIG_NVRAM is not set + # CONFIG_R3964 is not set + # CONFIG_RAW_DRIVER is not set ++# CONFIG_TCG_TPM is not set ++CONFIG_I2C=y ++CONFIG_I2C_BOARDINFO=y ++# CONFIG_I2C_CHARDEV is not set + + # +-# TPM devices ++# I2C Algorithms + # +-# CONFIG_TCG_TPM is not set +-# CONFIG_I2C is not set ++# CONFIG_I2C_ALGOBIT is not set ++# CONFIG_I2C_ALGOPCF is not set ++# CONFIG_I2C_ALGOPCA is not set + + # +-# SPI support ++# I2C Hardware Bus support + # +-# CONFIG_SPI is not set +-# CONFIG_SPI_MASTER is not set ++# CONFIG_I2C_GPIO is not set ++CONFIG_I2C_PXA=y ++# CONFIG_I2C_PXA_SLAVE is not set ++# CONFIG_I2C_OCORES is not set ++# CONFIG_I2C_PARPORT_LIGHT is not set ++# CONFIG_I2C_SIMTEC is not set ++# CONFIG_I2C_TAOS_EVM is not set ++# CONFIG_I2C_STUB is not set ++# CONFIG_I2C_TINY_USB is not set + + # +-# Dallas's 1-wire bus ++# Miscellaneous I2C Chip support + # +-# CONFIG_W1 is not set +-# CONFIG_HWMON is not set ++# CONFIG_SENSORS_DS1337 is not set ++# CONFIG_SENSORS_DS1374 is not set ++# CONFIG_DS1682 is not set ++# CONFIG_SENSORS_EEPROM is not set ++# CONFIG_SENSORS_PCF8574 is not set ++# CONFIG_SENSORS_PCA9539 is not set ++# CONFIG_SENSORS_PCF8591 is not set ++# CONFIG_SENSORS_MAX6875 is not set ++# CONFIG_SENSORS_TSL2550 is not set ++CONFIG_DA9030=y ++# CONFIG_I2C_DEBUG_CORE is not set ++# CONFIG_I2C_DEBUG_ALGO is not set ++# CONFIG_I2C_DEBUG_BUS is not set ++# CONFIG_I2C_DEBUG_CHIP is not set + + # +-# Misc devices ++# SPI support + # ++# CONFIG_SPI is not set ++# CONFIG_SPI_MASTER is not set ++# CONFIG_W1 is not set ++CONFIG_POWER_SUPPLY=y ++# CONFIG_POWER_SUPPLY_DEBUG is not set ++# CONFIG_PDA_POWER is not set ++CONFIG_APM_POWER=y ++# CONFIG_BATTERY_DS2760 is not set ++# CONFIG_BATTERY_EM_X270 is not set ++# CONFIG_HWMON is not set ++CONFIG_MISC_DEVICES=y ++# CONFIG_EEPROM_93CX6 is not set + + # + # Multifunction device drivers + # + # CONFIG_MFD_SM501 is not set +- +-# +-# LED devices +-# +-# CONFIG_NEW_LEDS is not set ++CONFIG_NEW_LEDS=y ++CONFIG_LEDS_CLASS=m + + # + # LED drivers + # ++CONFIG_LEDS_GPIO=m ++CONFIG_LEDS_EM_X270=m + + # + # LED Triggers + # ++CONFIG_LEDS_TRIGGERS=y ++CONFIG_LEDS_TRIGGER_TIMER=m ++CONFIG_LEDS_TRIGGER_HEARTBEAT=m + + # + # Multimedia devices +@@ -723,13 +783,17 @@ CONFIG_HW_RANDOM=m + # + # Graphics support + # +-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set ++CONFIG_BACKLIGHT_LCD_SUPPORT=y ++CONFIG_LCD_CLASS_DEVICE=y ++CONFIG_BACKLIGHT_CLASS_DEVICE=y ++CONFIG_BACKLIGHT_CORGI=y + + # + # Display device support + # + # CONFIG_DISPLAY_SUPPORT is not set + # CONFIG_VGASTATE is not set ++CONFIG_VIDEO_OUTPUT_CONTROL=m + CONFIG_FB=y + # CONFIG_FIRMWARE_EDID is not set + # CONFIG_FB_DDC is not set +@@ -752,7 +816,7 @@ CONFIG_FB_DEFERRED_IO=y + # + # CONFIG_FB_S1D13XXX is not set + CONFIG_FB_PXA=y +-# CONFIG_FB_PXA_PARAMETERS is not set ++CONFIG_FB_PXA_PARAMETERS=y + # CONFIG_FB_MBX is not set + # CONFIG_FB_VIRTUAL is not set + +@@ -762,6 +826,7 @@ CONFIG_FB_PXA=y + # CONFIG_VGA_CONSOLE is not set + CONFIG_DUMMY_CONSOLE=y + CONFIG_FRAMEBUFFER_CONSOLE=y ++# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set + # CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set + # CONFIG_FONTS is not set + CONFIG_FONT_8x8=y +@@ -774,18 +839,18 @@ CONFIG_LOGO_LINUX_CLUT224=y + # + # Sound + # +-CONFIG_SOUND=m ++CONFIG_SOUND=y + + # + # Advanced Linux Sound Architecture + # +-CONFIG_SND=m +-CONFIG_SND_TIMER=m +-CONFIG_SND_PCM=m ++CONFIG_SND=y ++CONFIG_SND_TIMER=y ++CONFIG_SND_PCM=y + # CONFIG_SND_SEQUENCER is not set + CONFIG_SND_OSSEMUL=y +-CONFIG_SND_MIXER_OSS=m +-CONFIG_SND_PCM_OSS=m ++CONFIG_SND_MIXER_OSS=y ++CONFIG_SND_PCM_OSS=y + CONFIG_SND_PCM_OSS_PLUGINS=y + # CONFIG_SND_DYNAMIC_MINORS is not set + CONFIG_SND_SUPPORT_OLD_API=y +@@ -817,17 +882,23 @@ CONFIG_SND_PXA2XX_AC97=m + # + # System on Chip audio support + # +-# CONFIG_SND_SOC is not set ++CONFIG_SND_SOC_AC97_BUS=y ++CONFIG_SND_SOC=y ++CONFIG_SND_PXA2XX_SOC=y ++CONFIG_SND_PXA2XX_SOC_AC97=y ++CONFIG_SND_PXA2XX_SOC_EM_X270=y + + # +-# Open Sound System ++# SoC Audio support for SuperH + # +-# CONFIG_SOUND_PRIME is not set +-CONFIG_AC97_BUS=m ++CONFIG_SND_SOC_WM9712=y + + # +-# HID Devices ++# Open Sound System + # ++# CONFIG_SOUND_PRIME is not set ++CONFIG_AC97_BUS=y ++CONFIG_HID_SUPPORT=y + CONFIG_HID=y + # CONFIG_HID_DEBUG is not set + +@@ -838,10 +909,7 @@ CONFIG_USB_HID=y + # CONFIG_USB_HIDINPUT_POWERBOOK is not set + # CONFIG_HID_FF is not set + # CONFIG_USB_HIDDEV is not set +- +-# +-# USB support +-# ++CONFIG_USB_SUPPORT=y + CONFIG_USB_ARCH_HAS_HCD=y + CONFIG_USB_ARCH_HAS_OHCI=y + # CONFIG_USB_ARCH_HAS_EHCI is not set +@@ -855,6 +923,7 @@ CONFIG_USB_DEVICEFS=y + # CONFIG_USB_DEVICE_CLASS is not set + # CONFIG_USB_DYNAMIC_MINORS is not set + # CONFIG_USB_SUSPEND is not set ++# CONFIG_USB_PERSIST is not set + # CONFIG_USB_OTG is not set + + # +@@ -866,12 +935,13 @@ CONFIG_USB_OHCI_HCD=y + # CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set + CONFIG_USB_OHCI_LITTLE_ENDIAN=y + # CONFIG_USB_SL811_HCD is not set ++# CONFIG_USB_R8A66597_HCD is not set + + # + # USB Device Class drivers + # +-# CONFIG_USB_ACM is not set +-# CONFIG_USB_PRINTER is not set ++CONFIG_USB_ACM=m ++CONFIG_USB_PRINTER=m + + # + # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +@@ -896,8 +966,8 @@ CONFIG_USB_STORAGE=y + # + # USB Imaging devices + # +-# CONFIG_USB_MDC800 is not set +-# CONFIG_USB_MICROTEK is not set ++CONFIG_USB_MDC800=m ++CONFIG_USB_MICROTEK=m + # CONFIG_USB_MON is not set + + # +@@ -940,25 +1010,25 @@ CONFIG_USB_STORAGE=y + # USB Gadget Support + # + # CONFIG_USB_GADGET is not set +-CONFIG_MMC=m ++CONFIG_MMC=y + # CONFIG_MMC_DEBUG is not set +-# CONFIG_MMC_UNSAFE_RESUME is not set ++CONFIG_MMC_UNSAFE_RESUME=y + + # + # MMC/SD Card Drivers + # +-CONFIG_MMC_BLOCK=m ++CONFIG_MMC_BLOCK=y ++CONFIG_MMC_BLOCK_BOUNCE=y + + # + # MMC/SD Host Controller Drivers + # +-CONFIG_MMC_PXA=m +- +-# +-# Real Time Clock +-# ++CONFIG_MMC_PXA=y + CONFIG_RTC_LIB=y +-CONFIG_RTC_CLASS=m ++CONFIG_RTC_CLASS=y ++CONFIG_RTC_HCTOSYS=y ++CONFIG_RTC_HCTOSYS_DEVICE="rtc1" ++# CONFIG_RTC_DEBUG is not set + + # + # RTC interfaces +@@ -972,6 +1042,15 @@ CONFIG_RTC_INTF_DEV=y + # + # I2C RTC drivers + # ++# CONFIG_RTC_DRV_DS1307 is not set ++# CONFIG_RTC_DRV_DS1672 is not set ++# CONFIG_RTC_DRV_MAX6900 is not set ++# CONFIG_RTC_DRV_RS5C372 is not set ++# CONFIG_RTC_DRV_ISL1208 is not set ++# CONFIG_RTC_DRV_X1205 is not set ++# CONFIG_RTC_DRV_PCF8563 is not set ++# CONFIG_RTC_DRV_PCF8583 is not set ++# CONFIG_RTC_DRV_M41T80 is not set + + # + # SPI RTC drivers +@@ -982,14 +1061,29 @@ CONFIG_RTC_INTF_DEV=y + # + # CONFIG_RTC_DRV_CMOS is not set + # CONFIG_RTC_DRV_DS1553 is not set ++# CONFIG_RTC_DRV_STK17TA8 is not set + # CONFIG_RTC_DRV_DS1742 is not set + # CONFIG_RTC_DRV_M48T86 is not set +-CONFIG_RTC_DRV_V3020=m ++# CONFIG_RTC_DRV_M48T59 is not set ++CONFIG_RTC_DRV_V3020=y + + # + # on-CPU RTC drivers + # +-CONFIG_RTC_DRV_SA1100=m ++CONFIG_RTC_DRV_SA1100=y ++ ++# ++# DMA Engine support ++# ++# CONFIG_DMA_ENGINE is not set ++ ++# ++# DMA Clients ++# ++ ++# ++# DMA Devices ++# + + # + # File systems +@@ -1098,7 +1192,6 @@ CONFIG_SMB_FS=y + # CONFIG_NCP_FS is not set + # CONFIG_CODA_FS is not set + # CONFIG_AFS_FS is not set +-# CONFIG_9P_FS is not set + + # + # Partition Types +@@ -1167,20 +1260,22 @@ CONFIG_NLS_UTF8=y + CONFIG_ENABLE_MUST_CHECK=y + CONFIG_MAGIC_SYSRQ=y + # CONFIG_UNUSED_SYMBOLS is not set +-# CONFIG_DEBUG_FS is not set ++CONFIG_DEBUG_FS=y + # CONFIG_HEADERS_CHECK is not set + CONFIG_DEBUG_KERNEL=y + # CONFIG_DEBUG_SHIRQ is not set + # CONFIG_DETECT_SOFTLOCKUP is not set ++CONFIG_SCHED_DEBUG=y + # CONFIG_SCHEDSTATS is not set + # CONFIG_TIMER_STATS is not set +-# CONFIG_DEBUG_SLAB is not set ++# CONFIG_SLUB_DEBUG_ON 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 +@@ -1202,10 +1297,6 @@ CONFIG_DEBUG_LL=y + # + # CONFIG_KEYS is not set + # CONFIG_SECURITY is not set +- +-# +-# Cryptographic options +-# + CONFIG_CRYPTO=y + CONFIG_CRYPTO_ALGAPI=m + CONFIG_CRYPTO_BLKCIPHER=m +@@ -1215,7 +1306,7 @@ CONFIG_CRYPTO_MANAGER=m + # CONFIG_CRYPTO_NULL is not set + # CONFIG_CRYPTO_MD4 is not set + # CONFIG_CRYPTO_MD5 is not set +-# CONFIG_CRYPTO_SHA1 is not set ++CONFIG_CRYPTO_SHA1=m + # CONFIG_CRYPTO_SHA256 is not set + # CONFIG_CRYPTO_SHA512 is not set + # CONFIG_CRYPTO_WP512 is not set +@@ -1243,19 +1334,17 @@ CONFIG_CRYPTO_ARC4=m + # CONFIG_CRYPTO_CRC32C is not set + # CONFIG_CRYPTO_CAMELLIA is not set + # CONFIG_CRYPTO_TEST is not set +- +-# +-# Hardware crypto devices +-# ++CONFIG_CRYPTO_HW=y + + # + # Library routines + # + CONFIG_BITREVERSE=y +-# CONFIG_CRC_CCITT is not set ++CONFIG_CRC_CCITT=m + # CONFIG_CRC16 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 +diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig +index 5ebec6d..2957cb9 100644 +--- a/arch/arm/mach-pxa/Kconfig ++++ b/arch/arm/mach-pxa/Kconfig +@@ -148,4 +148,12 @@ config PXA_SSP + tristate + help + Enable support for PXA2xx SSP ports ++ ++config PXA_PWR_I2C ++ bool "Simple Power I2C interface" ++ depends on PXA27x ++ help ++ Enable support for PXA27x Power I2C interface. This driver ++ enables very simple blocking access to Power I2C, which ++ might be useful for early access to Power Management ICs. + endif +diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile +index 7d6ab5c..2d7a431 100644 +--- a/arch/arm/mach-pxa/Makefile ++++ b/arch/arm/mach-pxa/Makefile +@@ -18,7 +18,7 @@ obj-$(CONFIG_PXA_SHARP_Cxx00) += spitz.o corgi_ssp.o corgi_lcd.o sharpsl_pm.o sp + obj-$(CONFIG_MACH_AKITA) += akita-ioexp.o + obj-$(CONFIG_MACH_POODLE) += poodle.o corgi_ssp.o + obj-$(CONFIG_MACH_TOSA) += tosa.o +-obj-$(CONFIG_MACH_EM_X270) += em-x270.o ++obj-$(CONFIG_MACH_EM_X270) += em-x270.o em-x270-pm.o em-x270-lcd.o em-x270-devices.o + + # Support for blinky lights + led-y := leds.o +@@ -29,9 +29,16 @@ led-$(CONFIG_MACH_TRIZEPS4) += leds-trizeps4.o + + obj-$(CONFIG_LEDS) += $(led-y) + ++# CPU Frequency scaling ++obj-$(CONFIG_CPU_FREQ_PXA) += cpu-pxa.o ++ + # Misc features + obj-$(CONFIG_PM) += pm.o sleep.o + obj-$(CONFIG_PXA_SSP) += ssp.o ++obj-$(CONFIG_PXA_PWR_I2C) += pwr-i2c.o ++ ++#obj-m += da9030_asm.o ++#da9030_asm-y += da9030.o da9030_c.o + + ifeq ($(CONFIG_PXA27x),y) + obj-$(CONFIG_PM) += standby.o +diff --git a/arch/arm/mach-pxa/cpu-pxa.c b/arch/arm/mach-pxa/cpu-pxa.c +new file mode 100644 +index 0000000..7fa9703 +--- /dev/null ++++ b/arch/arm/mach-pxa/cpu-pxa.c +@@ -0,0 +1,442 @@ ++/* ++ * linux/arch/arm/mach-pxa/cpu-pxa.c ++ * ++ * Copyright (C) 2002,2003 Intrinsyc Software ++ * ++ * 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 ++ * ++ * History: ++ * 31-Jul-2002 : Initial version [FB] ++ * 29-Jan-2003 : added PXA255 support [FB] ++ * 20-Apr-2003 : ported to v2.5 (Dustin McIntire, Sensoria Corp.) ++ * 11-Jan-2006 : v2.6, support for PXA27x processor up to 624MHz (Bill Reese, Hewlett Packard) ++ * ++ * Note: ++ * This driver may change the memory bus clock rate, but will not do any ++ * platform specific access timing changes... for example if you have flash ++ * memory connected to CS0, you will need to register a platform specific ++ * notifier which will adjust the memory access strobes to maintain a ++ * minimum strobe width. ++ * ++ */ ++ ++#include <linux/kernel.h> ++#include <linux/module.h> ++#include <linux/sched.h> ++#include <linux/init.h> ++#include <linux/cpufreq.h> ++ ++#include <asm/hardware.h> ++ ++#include <asm/arch/pxa-regs.h> ++ ++/* ++ * This comes from generic.h in this directory. ++ */ ++extern unsigned int get_clk_frequency_khz(int info); ++ ++#define DEBUG 0 ++ ++#ifdef DEBUG ++ static unsigned int freq_debug = DEBUG; ++ module_param(freq_debug, int, 0644); ++ MODULE_PARM_DESC(freq_debug, "Set the debug messages to on=1/off=0"); ++#else ++ #define freq_debug 0 ++#endif ++ ++typedef struct ++{ ++ unsigned int khz; /* CPU frequency */ ++ unsigned int membus; /* memory bus frequency */ ++ unsigned int cccr; /* new CCLKCFG setting */ ++ unsigned int div2; /* alter memory controller settings to divide by 2 */ ++ unsigned int cclkcfg; /* new CCLKCFG setting */ ++} pxa_freqs_t; ++ ++/* Define the refresh period in mSec for the SDRAM and the number of rows */ ++#define SDRAM_TREF 64 /* standard 64ms SDRAM */ ++#if defined(CONFIG_MACH_H4700) || defined(CONFIG_ARCH_H2200) || defined(CONFIG_MACH_MAGICIAN) ++#define SDRAM_ROWS 8192 /* hx4700 uses 2 64Mb DRAMs, 8912 rows */ ++#else ++#define SDRAM_ROWS 4096 /* 64MB=8192 32MB=4096 */ ++#endif ++#define MDREFR_DRI(x) (((x*SDRAM_TREF/SDRAM_ROWS - 31)/32)) ++ ++#define CCLKCFG_TURBO 0x1 ++#define CCLKCFG_FCS 0x2 ++#define CCLKCFG_HALFTURBO 0x4 ++#define CCLKCFG_FASTBUS 0x8 ++#ifdef CONFIG_ARCH_H5400 ++/* H5400's SAMCOP chip does not like when K2DB2 touched */ ++#define MDREFR_DB2_MASK (MDREFR_K1DB2) ++#else ++#define MDREFR_DB2_MASK (MDREFR_K2DB2 | MDREFR_K1DB2) ++#endif ++#define MDREFR_DRI_MASK 0xFFF ++#define PXA25x_CCLKCFG CCLKCFG_TURBO | CCLKCFG_FCS ++ ++/* ++ * For the PXA27x: ++ * Control variables are A, L, 2N for CCCR; B, HT, T for CLKCFG. ++ * ++ * A = 0 => memory controller clock from table 3-7, ++ * A = 1 => memory controller clock = system bus clock ++ * Run mode frequency = 13 MHz * L ++ * Turbo mode frequency = 13 MHz * L * N ++ * System bus frequency = 13 MHz * L / (B + 1) ++ * System initialized by bootldr to: ++ * ++ * In CCCR: ++ * A = 1 ++ * L = 16 oscillator to run mode ratio ++ * 2N = 6 2 * (turbo mode to run mode ratio) ++ * ++ * In CCLKCFG: ++ * B = 1 Fast bus mode ++ * HT = 0 Half-Turbo mode ++ * T = 1 Turbo mode ++ * ++ * For now, just support some of the combinations in table 3-7 of ++ * PXA27x Processor Family Developer's Manual to simplify frequency ++ * change sequences. ++ * ++ * Specify 2N in the PXA27x_CCCR macro, not N! ++ */ ++#define PXA27x_CCCR(A, L, N2) (A << 25 | N2 << 7 | L) ++#define PXA27x_CCLKCFG(B, HT, T) (B << 3 | HT << 2 | CCLKCFG_FCS | T) ++ ++#define PXA25x_CCCR(L, M, N) (L << 0 | M << 5 | N << 7) ++ ++/* ++ * Valid frequency assignments ++ */ ++static pxa_freqs_t pxa2xx_freqs[] = ++{ ++ /* CPU MEMBUS CCCR DIV2 */ ++#if defined(CONFIG_PXA25x) ++#if defined(CONFIG_PXA25x_ALTERNATE_FREQS) ++ { 99500, 99500, PXA25x_CCCR(1, 1, 2), 1, PXA25x_CCLKCFG}, /* run=99, turbo= 99, PXbus=50, SDRAM=50 */ ++ {199100, 99500, PXA25x_CCCR(1, 1, 4), 0, PXA25x_CCLKCFG}, /* run=99, turbo=199, PXbus=50, SDRAM=99 */ ++ {298500, 99500, PXA25x_CCCR(1, 1, 6), 0, PXA25x_CCLKCFG}, /* run=99, turbo=287, PXbus=50, SDRAM=99 */ ++ {298600, 99500, PXA25x_CCCR(1, 2, 3), 0, PXA25x_CCLKCFG}, /* run=199, turbo=287, PXbus=99, SDRAM=99 */ ++ {398100, 99500, PXA25x_CCCR(1, 2, 4), 0, PXA25x_CCLKCFG} /* run=199, turbo=398, PXbus=99, SDRAM=99 */ ++#else ++ { 99500, 99500, PXA25x_CCCR(1, 1, 2), 1, PXA25x_CCLKCFG}, /* run= 99, turbo= 99, PXbus=50, SDRAM=50 */ ++ {132700, 132700, PXA25x_CCCR(3, 1, 2), 1, PXA25x_CCLKCFG}, /* run=133, turbo=133, PXbus=66, SDRAM=66 */ ++ {199100, 99500, PXA25x_CCCR(1, 2, 2), 0, PXA25x_CCLKCFG}, /* run=199, turbo=199, PXbus=99, SDRAM=99 */ ++ {265400, 132700, PXA25x_CCCR(3, 2, 2), 1, PXA25x_CCLKCFG}, /* run=265, turbo=265, PXbus=133, SDRAM=66 */ ++ {331800, 165900, PXA25x_CCCR(5, 2, 2), 1, PXA25x_CCLKCFG}, /* run=331, turbo=331, PXbus=166, SDRAM=83 */ ++ {398100, 99500, PXA25x_CCCR(1, 3, 2), 0, PXA25x_CCLKCFG} /* run=398, turbo=398, PXbus=196, SDRAM=99 */ ++#endif ++#elif defined(CONFIG_PXA27x) ++ {104000, 104000, PXA27x_CCCR(1, 8, 2), 0, PXA27x_CCLKCFG(1, 0, 1)}, ++ {156000, 104000, PXA27x_CCCR(1, 8, 6), 0, PXA27x_CCLKCFG(1, 1, 1)}, ++ {208000, 208000, PXA27x_CCCR(0, 16, 2), 1, PXA27x_CCLKCFG(0, 0, 1)}, ++ {312000, 208000, PXA27x_CCCR(1, 16, 3), 1, PXA27x_CCLKCFG(1, 0, 1)}, ++ {416000, 208000, PXA27x_CCCR(1, 16, 4), 1, PXA27x_CCLKCFG(1, 0, 1)}, ++ {520000, 208000, PXA27x_CCCR(1, 16, 5), 1, PXA27x_CCLKCFG(1, 0, 1)}, ++/* {624000, 208000, PXA27x_CCCR(1, 16, 6), 1, PXA27x_CCLKCFG(1, 0, 1)} */ ++#endif ++}; ++#define NUM_FREQS (sizeof(pxa2xx_freqs)/sizeof(pxa_freqs_t)) ++ ++static struct cpufreq_frequency_table pxa2xx_freq_table[NUM_FREQS+1]; ++ ++/* Return the memory clock rate for a given cpu frequency. */ ++int pxa_cpufreq_memclk(int cpu_khz) ++{ ++ int i; ++ int freq_mem = 0; ++ ++ for (i = 0; i < NUM_FREQS; i++) { ++ if (pxa2xx_freqs[i].khz == cpu_khz) { ++ freq_mem = pxa2xx_freqs[i].membus; ++ break; ++ } ++ } ++ ++ return freq_mem; ++} ++EXPORT_SYMBOL(pxa_cpufreq_memclk); ++ ++ ++/* find a valid frequency point */ ++static int pxa_verify_policy(struct cpufreq_policy *policy) ++{ ++ int ret; ++ ++ ret=cpufreq_frequency_table_verify(policy, pxa2xx_freq_table); ++ ++ if(freq_debug) { ++ printk("Verified CPU policy: %dKhz min to %dKhz max\n", ++ policy->min, policy->max); ++ } ++ ++ return ret; ++} ++ ++static int pxa_set_target(struct cpufreq_policy *policy, ++ unsigned int target_freq, ++ unsigned int relation) ++{ ++ int idx; ++ cpumask_t cpus_allowed, allowedcpuset; ++ int cpu = policy->cpu; ++ struct cpufreq_freqs freqs; ++ unsigned long flags; ++ unsigned int unused; ++ unsigned int preset_mdrefr, postset_mdrefr, cclkcfg; ++ ++ if(freq_debug) { ++ printk ("CPU PXA: target freq %d\n", target_freq); ++ printk ("CPU PXA: relation %d\n", relation); ++ } ++ ++ /* ++ * Save this threads cpus_allowed mask. ++ */ ++ cpus_allowed = current->cpus_allowed; ++ ++ /* ++ * Bind to the specified CPU. When this call returns, ++ * we should be running on the right CPU. ++ */ ++ cpus_clear (allowedcpuset); ++ cpu_set (cpu, allowedcpuset); ++ set_cpus_allowed(current, allowedcpuset); ++ BUG_ON(cpu != smp_processor_id()); ++ ++ /* Lookup the next frequency */ ++ if (cpufreq_frequency_table_target(policy, pxa2xx_freq_table, ++ target_freq, relation, &idx)) { ++ return -EINVAL; ++ } ++ ++ freqs.old = policy->cur; ++ freqs.new = pxa2xx_freqs[idx].khz; ++ freqs.cpu = policy->cpu; ++ if(freq_debug) { ++ printk(KERN_INFO "Changing CPU frequency to %d Mhz, (SDRAM %d Mhz)\n", ++ freqs.new/1000, (pxa2xx_freqs[idx].div2) ? ++ (pxa2xx_freqs[idx].membus/2000) : ++ (pxa2xx_freqs[idx].membus/1000)); ++ } ++ ++ /* ++ * Tell everyone what we're about to do... ++ * you should add a notify client with any platform specific ++ * Vcc changing capability ++ */ ++ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); ++ ++ /* Calculate the next MDREFR. If we're slowing down the SDRAM clock ++ * we need to preset the smaller DRI before the change. If we're speeding ++ * up we need to set the larger DRI value after the change. ++ */ ++ preset_mdrefr = postset_mdrefr = MDREFR; ++ if((MDREFR & MDREFR_DRI_MASK) > MDREFR_DRI(pxa2xx_freqs[idx].membus)) { ++ preset_mdrefr = (preset_mdrefr & ~MDREFR_DRI_MASK) | ++ MDREFR_DRI(pxa2xx_freqs[idx].membus); ++ } ++ postset_mdrefr = (postset_mdrefr & ~MDREFR_DRI_MASK) | ++ MDREFR_DRI(pxa2xx_freqs[idx].membus); ++ ++ /* If we're dividing the memory clock by two for the SDRAM clock, this ++ * must be set prior to the change. Clearing the divide must be done ++ * after the change. ++ */ ++ if(pxa2xx_freqs[idx].div2) { ++ /* ++ * Potentially speeding up memory clock, so slow down the memory ++ * before speeding up the clock. ++ */ ++ preset_mdrefr |= MDREFR_DB2_MASK | MDREFR_K0DB4; ++ preset_mdrefr &= ~MDREFR_K0DB2; ++ ++ postset_mdrefr |= MDREFR_DB2_MASK | MDREFR_K0DB4; ++ postset_mdrefr &= ~MDREFR_K0DB2; ++ } else { ++ /* ++ * Potentially slowing down memory clock. Wait until after the change ++ * to speed up the memory. ++ */ ++ postset_mdrefr &= ~MDREFR_DB2_MASK; ++ postset_mdrefr &= ~MDREFR_K0DB4; ++ postset_mdrefr |= MDREFR_K0DB2; ++ } ++ ++ cclkcfg = pxa2xx_freqs[idx].cclkcfg; ++ ++ if (freq_debug) { ++ printk (KERN_INFO "CPU PXA writing 0x%08x to CCCR\n", ++ pxa2xx_freqs[idx].cccr); ++ printk (KERN_INFO "CPU PXA writing 0x%08x to CCLKCFG\n", ++ pxa2xx_freqs[idx].cclkcfg); ++ printk (KERN_INFO "CPU PXA writing 0x%08x to MDREFR before change\n", ++ preset_mdrefr); ++ printk (KERN_INFO "CPU PXA writing 0x%08x to MDREFR after change\n", ++ postset_mdrefr); ++ } ++ ++ local_irq_save(flags); ++ ++ /* Set new the CCCR */ ++ CCCR = pxa2xx_freqs[idx].cccr; ++ ++ /* ++ * Should really set both of PMCR[xIDAE] while changing the core frequency ++ */ ++ ++ /* ++ * TODO: On the PXA27x: If we're setting half-turbo mode and changing the ++ * core frequency at the same time we must split it up into two operations. ++ * The current values in the pxa2xx_freqs table don't do this, so the code ++ * is unimplemented. ++ */ ++ ++ __asm__ __volatile__(" \ ++ ldr r4, [%1] ; /* load MDREFR */ \ ++ b 2f ; \ ++ .align 5 ; \ ++1: \ ++ str %3, [%1] ; /* preset the MDREFR */ \ ++ mcr p14, 0, %2, c6, c0, 0 ; /* set CCLKCFG[FCS] */ \ ++ str %4, [%1] ; /* postset the MDREFR */ \ ++ \ ++ b 3f ; \ ++2: b 1b ; \ ++3: nop ; \ ++ " ++ : "=&r" (unused) ++ : "r" (&MDREFR), "r" (cclkcfg), \ ++ "r" (preset_mdrefr), "r" (postset_mdrefr) ++ : "r4", "r5"); ++ local_irq_restore(flags); ++ ++ if (freq_debug) { ++ printk (KERN_INFO "CPU PXA Frequency change successful\n"); ++ printk (KERN_INFO "CPU PXA new CCSR 0x%08x\n", CCSR); ++ } ++ ++ /* ++ * Restore the CPUs allowed mask. ++ */ ++ set_cpus_allowed(current, cpus_allowed); ++ ++ /* ++ * Tell everyone what we've just done... ++ * you should add a notify client with any platform specific ++ * SDRAM refresh timer adjustments ++ */ ++ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); ++ ++ return 0; ++} ++ ++static int pxa_cpufreq_init(struct cpufreq_policy *policy) ++{ ++ cpumask_t cpus_allowed, allowedcpuset; ++ unsigned int cpu = policy->cpu; ++ int i; ++ unsigned int cclkcfg; ++ ++ cpus_allowed = current->cpus_allowed; ++ ++ cpus_clear (allowedcpuset); ++ cpu_set (cpu, allowedcpuset); ++ set_cpus_allowed(current, allowedcpuset); ++ BUG_ON(cpu != smp_processor_id()); ++ ++ /* set default governor and cpuinfo */ ++ policy->governor = CPUFREQ_DEFAULT_GOVERNOR; ++ policy->cpuinfo.transition_latency = 1000; /* FIXME: 1 ms, assumed */ ++ policy->cur = get_clk_frequency_khz(0); /* current freq */ ++ ++ /* Generate the cpufreq_frequency_table struct */ ++ for(i=0;i<NUM_FREQS;i++) { ++ pxa2xx_freq_table[i].frequency = pxa2xx_freqs[i].khz; ++ pxa2xx_freq_table[i].index = i; ++ } ++ pxa2xx_freq_table[i].frequency = CPUFREQ_TABLE_END; ++ ++ /* ++ * Set the policy's minimum and maximum frequencies from the tables ++ * just constructed. This sets cpuinfo.mxx_freq, min and max. ++ */ ++ cpufreq_frequency_table_cpuinfo (policy, pxa2xx_freq_table); ++ ++ set_cpus_allowed(current, cpus_allowed); ++ printk(KERN_INFO "PXA CPU frequency change support initialized\n"); ++ ++ if (freq_debug) { ++ printk (KERN_INFO "PXA CPU initial CCCR 0x%08x\n", CCCR); ++ asm ++ ( ++ "mrc p14, 0, %0, c6, c0, 0 ; /* read CCLKCFG from CP14 */ " ++ : "=r" (cclkcfg) : ++ ); ++ printk ("PXA CPU initial CCLKCFG 0x%08x\n", cclkcfg); ++ printk ("PXA CPU initial MDREFR 0x%08x\n", MDREFR); ++ } ++ ++ return 0; ++} ++ ++static unsigned int pxa_cpufreq_get(unsigned int cpu) ++{ ++ cpumask_t cpumask_saved; ++ unsigned int cur_freq; ++ ++ cpumask_saved = current->cpus_allowed; ++ set_cpus_allowed(current, cpumask_of_cpu(cpu)); ++ BUG_ON(cpu != smp_processor_id()); ++ ++ cur_freq = get_clk_frequency_khz(0); ++ ++ set_cpus_allowed(current, cpumask_saved); ++ ++ return cur_freq; ++} ++ ++static struct cpufreq_driver pxa_cpufreq_driver = { ++ .verify = pxa_verify_policy, ++ .target = pxa_set_target, ++ .init = pxa_cpufreq_init, ++ .get = pxa_cpufreq_get, ++#if defined(CONFIG_PXA25x) ++ .name = "PXA25x", ++#elif defined(CONFIG_PXA27x) ++ .name = "PXA27x", ++#endif ++}; ++ ++static int __init pxa_cpu_init(void) ++{ ++ return cpufreq_register_driver(&pxa_cpufreq_driver); ++} ++ ++static void __exit pxa_cpu_exit(void) ++{ ++ cpufreq_unregister_driver(&pxa_cpufreq_driver); ++} ++ ++ ++MODULE_AUTHOR ("Intrinsyc Software Inc."); ++MODULE_DESCRIPTION ("CPU frequency changing driver for the PXA architecture"); ++MODULE_LICENSE("GPL"); ++module_init(pxa_cpu_init); ++module_exit(pxa_cpu_exit); ++ +diff --git a/arch/arm/mach-pxa/em-x270-devices.c b/arch/arm/mach-pxa/em-x270-devices.c +new file mode 100644 +index 0000000..d142930 +--- /dev/null ++++ b/arch/arm/mach-pxa/em-x270-devices.c +@@ -0,0 +1,331 @@ ++/* ++ * Support for CompuLab EM-X270 platfrom specific device ++ * initialization, and per-device power management functions. ++ * ++ * Copyright (C) 2007 CompuLab, Ltd. ++ * Author: Mike Rapoport <mike@compulab.co.il> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++#include <linux/module.h> ++#include <linux/platform_device.h> ++#include <linux/sysfs.h> ++#include <linux/ctype.h> ++#include <linux/delay.h> ++#include <linux/da9030.h> ++#include <linux/interrupt.h> ++#include <linux/irq.h> ++ ++#include "../../../drivers/i2c/chips/da9030.h" ++ ++#include <asm/arch/hardware.h> ++#include <asm/arch/pxa-regs.h> ++ ++struct em_x270_dev_data { ++ int (*is_on)(struct device *dev); ++ int (*set_on)(struct device *dev, int on); ++ int (*get_opts)(struct device *dev, ++ struct device_attribute *attr, ++ char *buf); ++ int (*set_opts)(struct device *dev, int opts); ++}; ++ ++static void em_x270_dev_release(struct device * dev) ++{ ++ ++} ++ ++static ssize_t em_x270_dev_pm_show(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct em_x270_dev_data *pm_data = dev->platform_data; ++ int is_on = pm_data->is_on(dev); ++ ++ return sprintf(buf, "%d\n", is_on); ++} ++ ++static ssize_t em_x270_dev_pm_store(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ char *endp; ++ int on = simple_strtoul(buf, &endp, 0); ++ size_t size = endp - buf; ++ struct em_x270_dev_data *pm_data = dev->platform_data; ++ ++ pr_info("%s: %s\n", __FUNCTION__, buf); ++ ++ if (*endp && isspace(*endp)) ++ size++; ++ if (size != count) ++ return -EINVAL; ++ ++ pm_data->set_on(dev, on); ++ ++ return count; ++} ++ ++static DEVICE_ATTR(pwr_on, S_IWUSR | S_IRUGO, ++ em_x270_dev_pm_show, em_x270_dev_pm_store); ++ ++static int gprs_is_on(struct device *dev) ++{ ++ return !!(pxa_gpio_get_value(20)); ++} ++ ++static int gprs_set_on(struct device *dev, int on) ++{ ++ pr_info("%s: on = %d\n", __FUNCTION__, on); ++ if (on) { ++ pxa_gpio_mode(20 | GPIO_OUT | GPIO_DFLT_HIGH); ++ mdelay(500); ++ pxa_gpio_set_value(82, 0); ++ mdelay(500); ++ pxa_gpio_mode(82 | GPIO_OUT | GPIO_DFLT_HIGH); ++ mdelay(1000); ++ pxa_gpio_set_value(82, 0); ++ } ++ else { ++ pxa_gpio_set_value(20, 0); ++ pxa_gpio_mode(20 | GPIO_OUT); ++ } ++ ++ return 0; ++} ++ ++static struct em_x270_dev_data em_x270_gprs_data = { ++ .is_on = gprs_is_on, ++ .set_on = gprs_set_on, ++}; ++ ++static struct platform_device em_x270_gprs = { ++ .name = "gprs", ++ .id = -1, ++ .dev = { ++ .platform_data = &em_x270_gprs_data, ++ .release = em_x270_dev_release, ++ }, ++}; ++ ++static int is_wlan_on; ++ ++static int wlan_is_on(struct device *dev) ++{ ++ return is_wlan_on; ++} ++ ++static int wlan_set_on(struct device *dev, int on) ++{ ++ if (on) { ++ /* WLAN power-up sequence */ ++ /* Mask LDO17 and LDO19 tolerance events */ ++ da9030_set_reg(IRQ_MASK_C, ++ IRQ_MASK_C_LDO19 | IRQ_MASK_C_LDO17); ++ ++ /* Force I2C control over LDO17, LDO19 */ ++ da9030_set_reg(SLEEP_CONTROL, ++ APP_SLEEP_CTL_BYPASS_LDO19 | ++ APP_SLEEP_CTL_BYPASS_LDO17); ++ ++ /* Turn off LDO17 and LDO19 */ ++ da9030_set_reg(REG_CONTROL_1_17, ++ RC1_LDO16_EN | RC1_LDO15_EN | ++ RC1_LDO11_EN | RC1_LDO10_EN | RC1_BUCK2_EN); ++ da9030_set_reg(REG_CONTROL_2_18, RC2_SIMCP_EN | RC2_LDO18_EN); ++ ++ /* Set LDO17 voltage to 3V (VCC_WLAN_IO) */ ++ da9030_set_reg(LDO_17_SIMCP0, LDO_17_SIMCP0_LDO17_3V); ++ mdelay(200); ++ ++ /* Turn WLAN RF power on */ ++ pxa_gpio_mode(115 | GPIO_OUT | GPIO_DFLT_HIGH); ++ ++ /* Turn LDO17 on */ ++ da9030_set_reg(REG_CONTROL_1_17, ++ RC1_LDO17_EN| RC1_LDO16_EN | RC1_LDO15_EN | ++ RC1_LDO11_EN | RC1_LDO10_EN | RC1_BUCK2_EN); ++ mdelay(200); ++ ++ /* Turn on LDO19 */ ++ da9030_set_reg(REG_CONTROL_2_18, ++ RC2_SIMCP_EN | RC2_LDO18_EN | RC2_LDO19_EN); ++ ++ } ++ else { ++ /* FIXME: implement BGW shutdown */ ++ } ++ is_wlan_on = on; ++ ++ return 0; ++} ++ ++static struct em_x270_dev_data em_x270_wlan_data = { ++ .is_on = wlan_is_on, ++ .set_on = wlan_set_on, ++}; ++ ++static struct platform_device em_x270_wlan = { ++ .name = "wlan", ++ .id = -1, ++ .dev = { ++ .platform_data = &em_x270_wlan_data, ++ .release = em_x270_dev_release, ++ }, ++}; ++ ++static int gps_is_on(struct device *dev) ++{ ++ int val = da9030_get_reg(REG_CONTROL_1_97); ++ return !!(val & RC3_LDO3_EN); ++} ++ ++static int gps_set_on(struct device *dev, int on) ++{ ++ int val = da9030_get_reg(REG_CONTROL_1_97); ++ ++ if (on) ++ val |= RC3_LDO3_EN; ++ else ++ val &= ~RC3_LDO3_EN; ++ da9030_set_reg(REG_CONTROL_1_97, val); ++ ++ return 0; ++} ++ ++static struct em_x270_dev_data em_x270_gps_data = { ++ .is_on = gps_is_on, ++ .set_on = gps_set_on, ++}; ++ ++static struct platform_device em_x270_gps = { ++ .name = "gps", ++ .id = -1, ++ .dev = { ++ .platform_data = &em_x270_gps_data, ++ .release = em_x270_dev_release, ++ }, ++}; ++ ++static int usb_mode; ++static int usb_host_is_on(struct device *dev) ++{ ++ return usb_mode; ++} ++ ++static int usb_host_set_on(struct device *dev, int on) ++{ ++ if (on) { ++ da9030_set_reg(MISC_CONTROLB, MISCB_SESSION_VALID_ENABLE); ++ da9030_set_reg(USBPUMP, ++ USB_PUMP_EN_USBVEP | ++ USB_PUMP_EN_USBVE | ++ USB_PUMP_USBVE); ++ ++ /* enable port 2 transiever */ ++ UP2OCR = UP2OCR_HXS | UP2OCR_HXOE; ++ usb_mode = 1; ++ } ++ else { ++ UP2OCR = UP2OCR_DPPUE | UP2OCR_DPPUBE | UP2OCR_HXOE; ++ da9030_set_reg(USBPUMP, ++ USB_PUMP_EN_USBVEP | USB_PUMP_EN_USBVE); ++ usb_mode = 0; ++ } ++ ++ return 0; ++} ++ ++static struct em_x270_dev_data em_x270_usb_host_data = { ++ .is_on = usb_host_is_on, ++ .set_on = usb_host_set_on, ++}; ++ ++static struct platform_device em_x270_usb_host = { ++ .name = "usb_host", ++ .id = -1, ++ .dev = { ++ .platform_data = &em_x270_usb_host_data, ++ .release = em_x270_dev_release, ++ }, ++}; ++ ++static struct platform_device *em_x270_devices[] = { ++ &em_x270_gprs, ++ &em_x270_wlan, ++ &em_x270_gps, ++ &em_x270_usb_host, ++}; ++ ++static struct work_struct usb_work; ++static void usb_worker(struct work_struct *work) ++{ ++ usb_host_set_on(NULL, !pxa_gpio_get_value(21)); ++} ++ ++static irqreturn_t usb_irq_handler(int irq, void *regs) ++{ ++ schedule_work(&usb_work); ++ ++ pr_info("%s\n", __FUNCTION__); ++ return IRQ_HANDLED; ++} ++ ++static int em_x270_devices_init(void) ++{ ++ int i, ret; ++ ++ for (i = 0; i < ARRAY_SIZE(em_x270_devices); i++ ) { ++ ret = platform_device_register(em_x270_devices[i]); ++ if (ret) { ++ dev_dbg(&em_x270_devices[i]->dev, ++ "Registration failed: %d\n", ret); ++ continue; ++ } ++ ++ ret = device_create_file(&em_x270_devices[i]->dev, ++ &dev_attr_pwr_on); ++ if (ret) { ++ dev_dbg(&em_x270_devices[i]->dev, ++ "PWR_ON attribute failed: %d\n", ret); ++ } ++ ++ dev_dbg(&em_x270_devices[i]->dev, ++ "Registered PWR ON attribute\n"); ++ } ++ ++ /* setup USB detection irq */ ++ INIT_WORK(&usb_work, usb_worker); ++ set_irq_type(IRQ_GPIO(21), IRQT_BOTHEDGE); ++ ret = request_irq(IRQ_GPIO(21), usb_irq_handler, IRQF_DISABLED, ++ "usb detect", 0); ++ if (ret) { ++ pr_info("USB device detection disabled\n"); ++ } ++ else { ++ schedule_work(&usb_work); ++ } ++ ++ return 0; ++} ++ ++static void em_x270_devices_exit(void) ++{ ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(em_x270_devices); i++ ) { ++ device_remove_file(&em_x270_devices[i]->dev, ++ &dev_attr_pwr_on); ++ platform_device_unregister(em_x270_devices[i]); ++ } ++} ++ ++late_initcall(em_x270_devices_init); ++module_exit(em_x270_devices_exit); ++ ++MODULE_AUTHOR("Mike Rapoport"); ++MODULE_DESCRIPTION("Support for platfrom specific device attributes for EM-X270"); ++MODULE_LICENSE("GPL"); +diff --git a/arch/arm/mach-pxa/em-x270-lcd.c b/arch/arm/mach-pxa/em-x270-lcd.c +new file mode 100644 +index 0000000..437efe1 +--- /dev/null ++++ b/arch/arm/mach-pxa/em-x270-lcd.c +@@ -0,0 +1,223 @@ ++/* ++ * LCD initialization and backlight managemnet for EM-X270 ++ * ++ * Copyright (C) 2007 CompuLab, Ltd. ++ * Author: Igor Vaisbein <igor@compulab.co.il> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ */ ++ ++#include <linux/module.h> ++#include <linux/platform_device.h> ++#include <linux/da9030.h> ++#include <linux/delay.h> ++ ++#include <asm/arch/hardware.h> ++#include <asm/arch/pxa-regs.h> ++#include <asm/arch/sharpsl.h> ++#include <asm/arch/ssp.h> ++ ++#include "devices.h" ++ ++#define GPIO87_nPCE_2 87 /* Card Enable for Card Space (PXA27x) */ ++#define GPIO87_nPCE_2_MD (87 | GPIO_ALT_FN_1_IN) ++#define GPIO87_USB3_1_MD (87 | GPIO_ALT_FN_3_IN) ++#define GPIO87_SSPTXD2_MD (87 | GPIO_ALT_FN_1_OUT) ++#define GPIO87_SSFRM2_MD (87 | GPIO_ALT_FN_3_OUT) ++ ++#define LCCR4 __REG(0x44000010) ++ ++#define TD035STEE1_LCD_ID 0x2008 ++ ++static void em_x270_set_bl_intensity(int intensity) ++{ ++ da9030_set_wled((intensity != 0), intensity); ++} ++ ++struct corgibl_machinfo em_x270_bl_machinfo = { ++ .max_intensity = 0x7, ++ .default_intensity = 0x3, ++ .limit_mask = 0x1, ++ .set_bl_intensity = em_x270_set_bl_intensity, ++}; ++ ++static void em_x270_bl_release(struct device * dev) ++{ ++ ++} ++ ++static struct platform_device em_x270_bl = { ++ .name = "corgi-bl", ++ .dev = { ++ .release = em_x270_bl_release, ++ .parent = &pxa_device_fb.dev, ++ .platform_data = &em_x270_bl_machinfo, ++ }, ++ .id = -1, ++}; ++ ++/* ++ * Helper functions to access LCD throuhg SPI interface ++ */ ++static void set_ssp_9bit(void) ++{ ++ int temp; ++ SSCR0 = 0xFF208; ++ SSCR0 = 0xFF288; ++ SSCR1 = 0x40000018; ++ ++ while (SSSR & 0x8) ++ temp = SSDR; ++} ++ ++static void set_ssp_18bit(void) ++{ ++ int temp; ++ SSCR0 = 0x1FF201; ++ SSCR0 = 0x1FF281; ++ SSCR1 = 0x40000018; ++ while (SSSR & 0x8) ++ temp = SSDR; ++} ++ ++static void set_ssp_rcv(void) ++{ ++ int temp; ++ SSCR0 = 0x1FF20F; ++ SSCR0 = 0x1FF28F; ++ SSCR1 = 0x40000018; ++ while (SSSR & 0x8) ++ temp = SSDR; ++} ++ ++static void send_ssp_9bit(unsigned int value) ++{ ++ int temp; ++ SSDR = (value); ++ ++ asm volatile ("mcr p15, 0, r0, c7, c10, 4":::"r0"); ++ ++ if (!(SSSR & 0x4)) ++ while ((SSSR & 0xf00) == 0) ++ ; ++ ++ while ((SSSR & 0xf00) != 0) ++ ; ++ while (SSSR & 0x10) ++ ; ++ while (SSSR & 0x8) ++ temp = SSDR; ++} ++ ++static void send_ssp_18bit(unsigned int value) ++{ ++ int temp; ++ SSDR = (value); ++ ++ asm volatile ("mcr p15, 0, r0, c7, c10, 4":::"r0"); ++ ++ if (!(SSSR & 0x4)) ++ while ((SSSR & 0xf00) == 0) ++ ; ++ ++ while ((SSSR & 0xf00) != 0) ++ ; ++ while (SSSR & 0x10) ++ ; ++ while (SSSR & 0x8) ++ temp = SSDR; ++} ++ ++static unsigned int rcv_ssp_18bit(void) ++{ ++ SSDR = ((0x04) << 23); ++ asm volatile ("mcr p15, 0, r0, c7, c10, 4":::"r0"); ++ if (!(SSSR & 0x4)) ++ while ((SSSR & 0xf00) == 0) ++ ; ++ while ((SSSR & 0xf00) != 0) ++ ; ++ while (SSSR & 0x10) ++ ; ++ return SSDR; ++} ++ ++/* LCD init sequence */ ++int em_x270_lcd_detect(void) ++{ ++ unsigned int data; ++ ++ /* Reset the LCD module */ ++ pxa_gpio_mode(GPIO87_nPCE_2 | GPIO_OUT); ++ GPCR(GPIO87_nPCE_2) |= GPIO_bit(GPIO87_nPCE_2); ++ mdelay(75); ++ GPSR(GPIO87_nPCE_2) |= GPIO_bit(GPIO87_nPCE_2); ++ mdelay(70); ++ ++ /* TD035STEE1 LCD_SSP initialization commands */ ++ set_ssp_9bit(); ++ send_ssp_9bit(0x000); ++ mdelay(5); ++ ++ send_ssp_9bit(0x000); ++ mdelay(5); ++ ++ send_ssp_9bit(0x000); ++ mdelay(5); ++ ++ set_ssp_18bit(); ++ send_ssp_18bit(0x17980); ++ mdelay(5); ++ ++ send_ssp_18bit(0x17F10); ++ mdelay(5); ++ ++ set_ssp_9bit(); ++ send_ssp_9bit(0x011); ++ mdelay(50); ++ ++ send_ssp_9bit(0x029); ++ mdelay(10); ++ ++ set_ssp_rcv(); ++ ++ /* Check for LCD ID, to enable the back-light */ ++ data = rcv_ssp_18bit(); ++ ++ if ((data & 0xFFFF) != TD035STEE1_LCD_ID) ++ return -ENODEV; ++ ++ /* enable backlight */ ++ da9030_set_wled(1, 2); ++ return 0; ++} ++ ++static int em_x270_lcd_init(void) ++{ ++ int ret; ++ pr_debug("%s\n", __FUNCTION__); ++ ret = em_x270_lcd_detect(); ++ if (ret) ++ return ret; ++ ++ /* make sure we keep LCCR4 with PCD=0 */ ++ LCCR4 = 0x0; ++ ++ return platform_device_register(&em_x270_bl); ++} ++ ++static void em_x270_lcd_exit(void) ++{ ++ pr_debug("%s\n", __FUNCTION__); ++ platform_device_unregister(&em_x270_bl); ++} ++ ++late_initcall(em_x270_lcd_init); ++module_exit(em_x270_lcd_exit); ++ ++MODULE_DESCRIPTION("EM-X270 backlight and LCD initialization driver"); ++MODULE_AUTHOR("Mike Rapoport"); ++MODULE_LICENSE("GPL"); +diff --git a/arch/arm/mach-pxa/em-x270-pm.c b/arch/arm/mach-pxa/em-x270-pm.c +new file mode 100644 +index 0000000..55ba4cd +--- /dev/null ++++ b/arch/arm/mach-pxa/em-x270-pm.c +@@ -0,0 +1,892 @@ ++/* ++ * Support for CompuLab EM-X270 platform power management ++ * ++ * Copyright (C) 2007 CompuLab, Ltd. ++ * Author: Mike Rapoport <mike@compulab.co.il> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++#include <linux/kernel.h> ++#include <linux/init.h> ++#include <linux/module.h> ++#include <linux/sysfs.h> ++#include <linux/pm.h> ++#include <linux/da9030.h> ++#include <linux/interrupt.h> ++#include <linux/irq.h> ++#include <linux/delay.h> ++#include <linux/ctype.h> ++ ++#include <linux/apm-emulation.h> ++#include <linux/platform_device.h> ++#include <linux/power_supply.h> ++ ++#include <linux/debugfs.h> ++#include <linux/seq_file.h> ++ ++#include "../../../drivers/i2c/chips/da9030.h" ++ ++#include <asm/arch/pm.h> ++#include <asm/arch/hardware.h> ++#include <asm/arch/pxa-regs.h> ++#include <asm/arch/pwr-i2c.h> ++ ++#define DA9030_ADDR 0x92 ++ ++#define EM_X270_BATCHK_TIME_SUSPEND (10*60) /* 10 min */ ++ ++#define VOLTAGE_MAX_DESIGN 4200000 /* 4.2V in uV */ ++#define VOLTAGE_MIN_DESIGN 3000000 /* 3V in uV */ ++ ++#define REG2VOLT(x) ((((x) * 2650) >> 8) + 2650) ++#define VOLT2REG(x) ((((x) - 2650) << 8) / 2650) ++ ++#define REG2CURR(x) ((((x) * 24000) >> 8) / 15) ++ ++#define VCHARGE_MIN_THRESHOLD VOLT2REG(3200) ++#define VCHARGE_MAX_THRESHOLD VOLT2REG(5500) ++ ++#define VBAT_LOW_THRESHOLD VOLT2REG(3600) ++#define VBAT_CRIT_THRESHOLD VOLT2REG(3400) ++ ++#define VBAT_CHARGE_START VOLT2REG(4100) ++#define VBAT_CHARGE_STOP VOLT2REG(4200) ++#define VBAT_CHARGE_RESTART VOLT2REG(4000) ++ ++#define TBAT_LOW_THRESHOLD 197 /* 0oC */ ++#define TBAT_HIGH_THRESHOLD 78 /* 45oC */ ++#define TBAT_RESUME_THRESHOLD 100 /* 35oC */ ++ ++struct em_x270_charger; ++ ++struct em_x270_charger_ops { ++ void (*get_status)(struct em_x270_charger *charger); ++ void (*set_charge)(struct em_x270_charger *charger, int on); ++ ++ s32 (*da9030_get_reg)(u32 reg); ++ s32 (*da9030_set_reg)(u32 reg, u8 val); ++}; ++ ++struct em_x270_charger { ++ struct device *dev; ++ ++ struct power_supply bat; ++ struct da9030_adc_res adc; ++ struct delayed_work work; ++ ++ int interval; ++ ++ int da9030_status; ++ int da9030_fault; ++ int mA; ++ int mV; ++ int is_on; ++ ++ struct em_x270_charger_ops *ops; ++ ++#ifdef CONFIG_DEBUG_FS ++ struct dentry *debug_file; ++#endif ++}; ++ ++static struct em_x270_charger *the_charger; ++ ++static unsigned short tbat_readings[] = { ++ 300, 244, 200, 178, 163, 152, 144, 137, 131, ++ 126, 122, 118, 114, 111, 108, 105, 103, 101, ++ 98, 96, 94, 93, 91, 89, 88, 86, 85, ++ 83, 82, 81, 79, 78, 77, 76, 75, 74, ++ 73, 72, 71, 70, 69, 68, 67, 67, 66, ++ 65, 64, 63, 63, 62, 61, 60, 60, 59, ++ 58, 58, 57, 57, 56, 55, 55, 54, 53, ++ 53, 52, 52, 51, 51, 50, 50, 49, 49, ++ 48, 48, 47, 47, 46, 46, 45, 45, 44, ++ 44, 43, 43, 42, 42, 41, 41, 41, 40, ++ 40, 39, 39, 38, 38, 38, 37, 37, 36, ++ 36, 35, 35, 35, 34, 34, 34, 33, 33, ++ 32, 32, 32, 31, 31, 30, 30, 30, 29, ++ 29, 29, 28, 28, 28, 27, 27, 26, 26, ++ 26, 25, 25, 25, 24, 24, 24, 23, 23, ++ 23, 22, 22, 21, 21, 21, 20, 20, 20, ++ 19, 19, 19, 18, 18, 18, 17, 17, 17, ++ 16, 16, 16, 15, 15, 14, 14, 14, 13, ++ 13, 13, 12, 12, 12, 11, 11, 11, 10, ++ 10, 10, 9, 9, 8, 8, 8, 7, 7, ++ 7, 6, 6, 5, 5, 5, 4, 4, 3, ++ 3, 3, 2, 2, 1, 1, 1, 0, 0, ++ -1, -1, -1, -2, -2, -3, -3, -4, -4, ++ -5, -5, -6, -6, -6, -7, -7, -8, -9, ++ -9, -10, -10, -11, -11, -12, -12, -13, -14, ++ -14, -15, -16, -16, -17, -18, -18, -19, -20, ++ -21, -21, -22, -23, -24, -25, -26, -27, -28, ++ -30, -31, -32, -34, -35, -37, -39, -41, -44, ++ -47, -50, -56, -64, ++}; ++ ++static inline int usb_host_on(void) ++{ ++ return !pxa_gpio_get_value(21); ++} ++ ++#ifdef CONFIG_DEBUG_FS ++ ++static int debug_show(struct seq_file *s, void *data) ++{ ++ struct em_x270_charger *charger = s->private; ++ ++ seq_printf(s, "charger is %s\n", charger->is_on ? "on" : "off"); ++ if (charger->da9030_status & CHRG_CHARGER_ENABLE) { ++ seq_printf(s, "iset = %dmA, vset = %dmV\n", ++ charger->mA, charger->mV); ++ } ++ ++ seq_printf(s, "vbat_res = %d (%dmV)\n", ++ charger->adc.vbat_res, REG2VOLT(charger->adc.vbat_res)); ++ seq_printf(s, "vbatmin_res = %d (%dmV)\n", ++ charger->adc.vbatmin_res, ++ REG2VOLT(charger->adc.vbatmin_res)); ++ seq_printf(s, "vbatmintxon = %d (%dmV)\n", ++ charger->adc.vbatmintxon, ++ REG2VOLT(charger->adc.vbatmintxon)); ++ seq_printf(s, "ichmax_res = %d (%dmA)\n", ++ charger->adc.ichmax_res, ++ REG2CURR(charger->adc.ichmax_res)); ++ seq_printf(s, "ichmin_res = %d (%dmA)\n", ++ charger->adc.ichmin_res, ++ REG2CURR(charger->adc.ichmin_res)); ++ seq_printf(s, "ichaverage_res = %d (%dmA)\n", ++ charger->adc.ichaverage_res, ++ REG2CURR(charger->adc.ichaverage_res)); ++ seq_printf(s, "vchmax_res = %d (%dmV)\n", ++ charger->adc.vchmax_res, ++ REG2VOLT(charger->adc.vchmax_res)); ++ seq_printf(s, "vchmin_res = %d (%dmV)\n", ++ charger->adc.vchmin_res, ++ REG2VOLT(charger->adc.vchmin_res)); ++ seq_printf(s, "tbat_res = %d (%doC)\n", charger->adc.tbat_res, ++ tbat_readings[charger->adc.tbat_res]); ++ seq_printf(s, "adc_in4_res = %d\n", charger->adc.adc_in4_res); ++ seq_printf(s, "adc_in5_res = %d\n", charger->adc.adc_in5_res); ++ ++ return 0; ++} ++ ++static int debug_open(struct inode *inode, struct file *file) ++{ ++ return single_open(file, debug_show, inode->i_private); ++} ++ ++static const struct file_operations debug_fops = { ++ .open = debug_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .release = single_release, ++}; ++ ++static struct dentry* em_x270_create_debugfs(struct em_x270_charger *charger) ++{ ++ charger->debug_file = debugfs_create_file("charger", 0666, 0, charger, ++ &debug_fops); ++ return charger->debug_file; ++} ++ ++static void em_x270_remove_debugfs(struct em_x270_charger *charger) ++{ ++ debugfs_remove(charger->debug_file); ++} ++#else ++#define em_x270_create_debugfs(x) NULL ++#define em_x270_remove_debugfs(x) do {} while(0) ++#endif ++ ++/*********************************************************************/ ++/* DA9030 access functions for suspend/resume */ ++#define DA_ADDR 0x49 ++static inline s32 __da9030_get_reg(u32 reg) ++{ ++ pr_info("%s: reg = %d\n", __FUNCTION__, reg); ++ return pxa_pwr_i2c_reg_read(DA_ADDR, reg); ++} ++ ++static inline s32 __da9030_set_reg(u32 reg, u8 val) ++{ ++ pr_info("%s: reg = %d, val = %d\n", __FUNCTION__, reg, val); ++ return pxa_pwr_i2c_reg_write(DA_ADDR, reg, val); ++} ++ ++/*********************************************************************/ ++/* helpers for charger state monnitor. Different version for stready ++ * state and suspended system ++ */ ++static void em_x270_get_charger_status(struct em_x270_charger *charger) ++{ ++ da9030_get_charger(&charger->is_on, &charger->mA, &charger->mV); ++ da9030_read_adc(&charger->adc); ++ charger->da9030_status = da9030_get_status(); ++ charger->da9030_fault = da9030_get_fault_log(); ++} ++ ++static void em_x270_set_charge(struct em_x270_charger *charger, int on) ++{ ++ if (on) { ++ pr_debug("%s: enabling charger\n", __FUNCTION__); ++ da9030_set_thresholds(TBAT_HIGH_THRESHOLD, ++ TBAT_RESUME_THRESHOLD, ++ TBAT_LOW_THRESHOLD, ++ VBAT_LOW_THRESHOLD); ++ da9030_set_reg(CCTR_CONTROL, CCTR_SET_8MIN); ++ da9030_set_charger(1, 1000, 4200); ++ da9030_set_led(3, 1, 0, 0, 0); ++ charger->is_on = 1; ++ } ++ else { ++ /* disable charger */ ++ pr_debug("%s: disabling charger\n", __FUNCTION__); ++ da9030_set_charger(0, 0, 0); ++ da9030_set_led(3, 0, 0, 0, 0); ++ charger->is_on = 0; ++ } ++} ++ ++static void em_x270_get_charger_status_suspend(struct em_x270_charger *charger) ++{ ++ s32 val; ++ ++ val = __da9030_get_reg(CHARGE_CONTROL); ++ charger->is_on = (val & CHRG_CHARGER_ENABLE) ? 1 : 0; ++ charger->mA = ((val >> 3) & 0xf) * 100; ++ charger->mV = (val & 0x7) * 50 + 4000; ++ ++ charger->adc.vbat_res = __da9030_get_reg(VBAT_RES); ++ charger->adc.vchmax_res = __da9030_get_reg(VCHMAX_RES); ++ charger->adc.vchmin_res = __da9030_get_reg(VCHMIN_RES); ++ charger->adc.tbat_res = __da9030_get_reg(TBAT_RES); ++ ++ charger->da9030_status = __da9030_get_reg(STATUS); ++ charger->da9030_fault = __da9030_get_reg(FAULT_LOG); ++} ++ ++static void em_x270_set_charge_suspend(struct em_x270_charger *charger, int on) ++{ ++ if (on) { ++ u8 val = 0; ++ int mA = 1000; ++ int mV = 4200; ++ ++ pr_debug("%s: enabling charger\n", __FUNCTION__); ++ val = CHRG_CHARGER_ENABLE; ++ val |= (mA / 100) << 3; ++ val |= (mV - 4000) / 50; ++ ++ __da9030_set_reg(CCTR_CONTROL, CCTR_SET_8MIN); ++ __da9030_set_reg(VBATMON, VBAT_LOW_THRESHOLD); ++ __da9030_set_reg(CHARGE_CONTROL, val); ++ charger->is_on = 1; ++ } ++ else { ++ /* disable charger */ ++ pr_debug("%s: disabling charger\n", __FUNCTION__); ++ __da9030_set_reg(CHARGE_CONTROL, 0); ++ charger->is_on = 0; ++ } ++} ++ ++static struct em_x270_charger_ops em_x270_charger_ops = { ++ .get_status = em_x270_get_charger_status, ++ .set_charge = em_x270_set_charge, ++ .da9030_get_reg = da9030_get_reg, ++ .da9030_set_reg = da9030_set_reg, ++}; ++ ++static struct em_x270_charger_ops em_x270_charger_ops_suspend = { ++ .get_status = em_x270_get_charger_status_suspend, ++ .set_charge = em_x270_set_charge_suspend, ++ .da9030_get_reg = __da9030_get_reg, ++ .da9030_set_reg = __da9030_set_reg, ++}; ++ ++/*********************************************************************/ ++/* charging state machine */ ++static void em_x270_check_charger_state(struct em_x270_charger *charger) ++{ ++ charger->ops->get_status(charger); ++ ++/* we wake or boot with external power on */ ++ if (!charger->is_on) { ++ if ((charger->da9030_status & STATUS_CHDET) && ++ (!usb_host_on()) && ++ (charger->adc.vbat_res < VBAT_CHARGE_START)) { ++ pr_debug("%s: vbat_res <= 4100\n", __FUNCTION__); ++ charger->ops->set_charge(charger, 1); ++ } ++ } ++ else { ++ if (charger->adc.vbat_res >= VBAT_CHARGE_STOP) { ++ pr_debug("%s: vbat_res >= 4200\n", __FUNCTION__); ++ charger->ops->set_charge(charger, 0); ++ charger->ops->da9030_set_reg(VBATMON, ++ VBAT_CHARGE_RESTART); ++ } ++ else if (charger->adc.vbat_res > VBAT_LOW_THRESHOLD) { ++ /* we are charging and passed LOW_THRESH, ++ so upate DA9030 VBAT threshold ++ */ ++ pr_debug("%s: vbat_res >= %d\n", __FUNCTION__, ++ REG2VOLT(VBAT_LOW_THRESHOLD)); ++ charger->ops->da9030_set_reg(VBATMON, ++ VBAT_LOW_THRESHOLD); ++ } ++ if (charger->adc.vchmax_res > VCHARGE_MAX_THRESHOLD || ++ charger->adc.vchmin_res < VCHARGE_MIN_THRESHOLD || ++ /* Tempreture readings are negative */ ++ charger->adc.tbat_res < TBAT_HIGH_THRESHOLD || ++ charger->adc.tbat_res > TBAT_LOW_THRESHOLD ) { ++ /* disable charger */ ++ pr_info("%s: thresholds fail\n", __FUNCTION__); ++ charger->ops->set_charge(charger, 0); ++ } ++ } ++} ++ ++static void em_x270_charging_monitor(struct work_struct *work) ++{ ++ struct em_x270_charger *charger; ++ ++ charger = container_of(work, struct em_x270_charger, work.work); ++ ++ em_x270_check_charger_state(charger); ++ ++ /* reschedule for the next time */ ++ schedule_delayed_work(&charger->work, charger->interval); ++} ++ ++void em_x270_battery_release(struct device * dev) ++{ ++} ++ ++struct em_x270_battery_thresh { ++ int voltage; ++ int percentage; ++}; ++ ++static struct em_x270_battery_thresh vbat_ranges[] = { ++ { 150, 100}, ++ { 149, 99}, ++ { 148, 98}, ++ { 147, 98}, ++ { 146, 97}, ++ { 145, 96}, ++ { 144, 96}, ++ { 143, 95}, ++ { 142, 94}, ++ { 141, 93}, ++ { 140, 92}, ++ { 139, 91}, ++ { 138, 90}, ++ { 137, 90}, ++ { 136, 89}, ++ { 135, 88}, ++ { 134, 88}, ++ { 133, 87}, ++ { 132, 86}, ++ { 131, 85}, ++ { 130, 83}, ++ { 129, 82}, ++ { 128, 81}, ++ { 127, 81}, ++ { 126, 80}, ++ { 125, 75}, ++ { 124, 74}, ++ { 123, 73}, ++ { 122, 70}, ++ { 121, 66}, ++ { 120, 65}, ++ { 119, 64}, ++ { 118, 64}, ++ { 117, 63}, ++ { 116, 59}, ++ { 115, 58}, ++ { 114, 57}, ++ { 113, 57}, ++ { 112, 56}, ++ { 111, 50}, ++ { 110, 49}, ++ { 109, 49}, ++ { 108, 48}, ++ { 107, 48}, ++ { 106, 33}, ++ { 105, 32}, ++ { 104, 32}, ++ { 103, 32}, ++ { 102, 31}, ++ { 101, 16}, ++ { 100, 15}, ++ { 99, 15}, ++ { 98, 15}, ++ { 97, 10}, ++ { 96, 9}, ++ { 95, 7}, ++ { 94, 3}, ++ { 93, 0}, ++}; ++ ++static enum power_supply_property em_x270_bat_props[] = { ++ POWER_SUPPLY_PROP_STATUS, ++ POWER_SUPPLY_PROP_HEALTH, ++ POWER_SUPPLY_PROP_TECHNOLOGY, ++ POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, ++ POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, ++ POWER_SUPPLY_PROP_VOLTAGE_NOW, ++ POWER_SUPPLY_PROP_CURRENT_AVG, ++ POWER_SUPPLY_PROP_CAPACITY, /* in percents! */ ++ POWER_SUPPLY_PROP_TEMP, ++ POWER_SUPPLY_PROP_MANUFACTURER, ++ POWER_SUPPLY_PROP_MODEL_NAME, ++}; ++ ++static void em_x270_bat_check_status(struct em_x270_charger *charger, ++ union power_supply_propval *val) ++{ ++ /* FIXME: below code is very crude approximation of actual ++ states, we need to take into account voltage and current ++ measurements to determine actual charger state */ ++ if (charger->da9030_status & STATUS_CHDET) { ++ if (!usb_host_on()) { ++ if (charger->is_on) { ++ val->intval = POWER_SUPPLY_STATUS_CHARGING; ++ } ++ else { ++ val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; ++ } ++ } ++ } ++ else { ++ val->intval = POWER_SUPPLY_STATUS_DISCHARGING; ++ } ++} ++ ++static void em_x270_bat_check_health(struct em_x270_charger *charger, ++ union power_supply_propval *val) ++{ ++ if (charger->da9030_fault & FAULT_LOG_OVER_TEMP) { ++ val->intval = POWER_SUPPLY_HEALTH_OVERHEAT; ++ } ++ else if (charger->da9030_fault & FAULT_LOG_VBAT_OVER) { ++ val->intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE; ++ } ++ else { ++ val->intval = POWER_SUPPLY_HEALTH_GOOD; ++ } ++} ++ ++static int vbat_interpolate(int reg) ++{ ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(vbat_ranges); i++ ) ++ if (vbat_ranges[i].voltage == reg) { ++ pr_debug("%s: voltage = %d, percentage = %d\n", ++ __FUNCTION__, vbat_ranges[i].voltage, ++ vbat_ranges[i].percentage); ++ return vbat_ranges[i].percentage; ++ } ++ ++ return 0; ++} ++ ++static int em_x270_bat_get_property(struct power_supply *psy, ++ enum power_supply_property psp, ++ union power_supply_propval *val) ++{ ++ u32 reg; ++ struct em_x270_charger *charger; ++ charger = container_of(psy, struct em_x270_charger, bat); ++ ++ switch(psp) { ++ case POWER_SUPPLY_PROP_STATUS: ++ em_x270_bat_check_status(charger, val); ++ break; ++ case POWER_SUPPLY_PROP_HEALTH: ++ em_x270_bat_check_health(charger, val); ++ break; ++ case POWER_SUPPLY_PROP_TECHNOLOGY: ++ val->intval = POWER_SUPPLY_TECHNOLOGY_LIPO; ++ break; ++ case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN: ++ val->intval = VOLTAGE_MAX_DESIGN; ++ break; ++ case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: ++ val->intval = VOLTAGE_MIN_DESIGN; ++ break; ++ case POWER_SUPPLY_PROP_VOLTAGE_NOW: ++ reg = charger->adc.vbat_res; ++ /* V = (reg / 256) * 2.65 + 2.65 (V) */ ++ val->intval = ((reg * 2650000) >> 8) + 2650000; ++ break; ++ case POWER_SUPPLY_PROP_CURRENT_AVG: ++ reg = charger->adc.ichaverage_res; ++ val->intval = reg; /* reg */ ++ break; ++ case POWER_SUPPLY_PROP_CAPACITY: ++ reg = charger->adc.vbat_res; ++ val->intval = vbat_interpolate(reg); ++ break; ++ case POWER_SUPPLY_PROP_TEMP: ++ reg = charger->adc.tbat_res; ++ val->intval = tbat_readings[reg]; ++ break; ++ case POWER_SUPPLY_PROP_MANUFACTURER: ++ val->strval = "MaxPower"; ++ pr_debug("%s: MFG = %s\n", __FUNCTION__, val->strval); ++ break; ++ case POWER_SUPPLY_PROP_MODEL_NAME: ++ val->strval = "LP555597P6H-FPS"; ++ pr_debug("%s: MODEL = %s\n", __FUNCTION__, val->strval); ++ break; ++ default: break; ++ } ++ ++ return 0; ++} ++ ++static void em_x270_setup_battery(struct power_supply *bat) ++{ ++ bat->name = "em-x270-battery"; ++ bat->type = POWER_SUPPLY_TYPE_BATTERY; ++ bat->properties = em_x270_bat_props; ++ bat->num_properties = ARRAY_SIZE(em_x270_bat_props); ++ bat->get_property = em_x270_bat_get_property; ++ bat->use_for_apm = 1; ++}; ++ ++static void em_x270_chiover_callback(int event, void *_charger) ++{ ++ /* disable charger */ ++ struct em_x270_charger *charger = _charger; ++/* pr_info("%s\n", __FUNCTION__); */ ++ em_x270_set_charge(charger, 0); ++} ++ ++static void em_x270_tbat_callback(int event, void *_charger) ++{ ++ /* disable charger */ ++ struct em_x270_charger *charger = _charger; ++/* pr_info("%s\n", __FUNCTION__); */ ++ em_x270_set_charge(charger, 0); ++} ++ ++static void em_x270_vbat_callback(int event, void *_charger) ++{ ++ struct em_x270_charger *charger = _charger; ++ da9030_read_adc(&charger->adc); ++ ++ if (!charger->is_on) { ++ if (charger->adc.vbat_res < VBAT_LOW_THRESHOLD) { ++ /* set VBAT threshold for critical */ ++ da9030_set_reg(VBATMON, VBAT_CRIT_THRESHOLD); ++ da9030_set_reg(VBATMON_1, VBAT_CRIT_THRESHOLD); ++ apm_queue_event(APM_LOW_BATTERY); ++ } ++ else if (charger->adc.vbat_res < VBAT_CRIT_THRESHOLD) { ++ /* notify the system of battery critical */ ++ apm_queue_event(APM_CRITICAL_SUSPEND); ++ } ++ } ++} ++ ++static void em_x270_chdet_callback(int event, void *_charger) ++{ ++ struct em_x270_charger *charger = _charger; ++ int status = da9030_get_status(); ++ pr_info("%s\n", __FUNCTION__); ++ ++/* em_x270_check_charger_state(charger); */ ++ ++ /* check if we have "real" charger or our own USB pump */ ++ if (!usb_host_on()) ++ em_x270_set_charge(charger, !!(status & CHRG_CHARGER_ENABLE)); ++} ++ ++static int em_x270_battery_probe(struct platform_device *pdev) ++{ ++ struct em_x270_charger *charger; ++ ++ pr_debug("%s\n", __FUNCTION__); ++ charger = kzalloc(sizeof(*charger), GFP_KERNEL); ++ if (charger == NULL) { ++ return -ENOMEM; ++ } ++ ++ the_charger = charger; ++ ++ charger->dev = &pdev->dev; ++ ++ charger->ops = &em_x270_charger_ops; ++ ++ charger->interval = 10 * HZ; /* 10 seconds between monotor runs */ ++ em_x270_setup_battery(&charger->bat); ++ ++ platform_set_drvdata(pdev, charger); ++ ++ da9030_enable_adc(); ++ ++ INIT_DELAYED_WORK(&charger->work, em_x270_charging_monitor); ++ schedule_delayed_work(&charger->work, charger->interval); ++ ++ charger->debug_file = em_x270_create_debugfs(charger); ++ ++ em_x270_setup_battery(&charger->bat); ++ ++ da9030_register_callback(DA9030_IRQ_CHDET, ++ em_x270_chdet_callback, ++ charger); ++ da9030_register_callback(DA9030_IRQ_VBATMON, ++ em_x270_vbat_callback, ++ charger); ++ ++ /* critical condition events */ ++ da9030_register_callback(DA9030_IRQ_CHIOVER, ++ em_x270_chiover_callback, ++ charger); ++ da9030_register_callback(DA9030_IRQ_TBAT, ++ em_x270_tbat_callback, ++ charger); ++ ++ da9030_set_thresholds(TBAT_HIGH_THRESHOLD, ++ TBAT_RESUME_THRESHOLD, ++ TBAT_LOW_THRESHOLD, ++ VBAT_LOW_THRESHOLD); ++ ++ power_supply_register(&pdev->dev, &charger->bat); ++ ++ return 0; ++} ++ ++static int em_x270_battery_remove(struct platform_device *dev) ++{ ++ struct em_x270_charger *charger = platform_get_drvdata(dev); ++ ++ pr_debug("%s\n", __FUNCTION__); ++ em_x270_remove_debugfs(charger); ++ cancel_delayed_work(&charger->work); ++ power_supply_unregister(&charger->bat); ++ ++ kfree(charger); ++ the_charger = NULL; ++ ++ return 0; ++} ++ ++static int em_x270_battery_suspend(struct platform_device *pdev, ++ pm_message_t state) ++{ ++ pr_info("%s\n", __FUNCTION__); ++ da9030_set_reg(REG_CONTROL_1_97, RC3_BUCK_EN | RC3_LDO6_EN); ++ da9030_set_reg(REG_CONTROL_2_98, 0); ++ da9030_set_reg(REG_CONTROL_2_18,RC2_LDO18_EN); ++ da9030_set_reg(REG_CONTROL_1_17, ++ RC1_LDO16_EN | RC1_LDO15_EN | RC1_BUCK2_EN); ++ da9030_set_reg(WLED_CONTROL, 0); ++ ++ da9030_set_reg(LED_1_CONTROL, 0); ++ da9030_set_reg(LED_4_CONTROL, 0); ++ ++ return 0; ++} ++ ++extern int em_x270_lcd_detect(void); ++static int em_x270_battery_resume(struct platform_device *pdev) ++{ ++ pr_info("%s\n", __FUNCTION__); ++ ++ da9030_set_reg(LED_1_CONTROL, 0xff); ++ da9030_set_reg(LED_4_CONTROL, 0xff); ++ ++ da9030_set_reg(REG_CONTROL_1_97, ++ RC3_BUCK_EN | RC3_LDO1_EN | RC3_LDO2_EN | ++ RC3_LDO3_EN | RC3_LDO6_EN | RC3_LDO7_EN); ++ da9030_set_reg(REG_CONTROL_2_98, ++ RC4_SIMCP_ENABLE | RC4_LDO11_EN | ++ RC4_LDO9_EN | RC4_LDO8_EN); ++ da9030_set_reg(REG_CONTROL_2_18, ++ RC2_SIMCP_EN | RC2_LDO18_EN | RC2_LDO19_EN); ++ da9030_set_reg(REG_CONTROL_1_17, ++ RC1_LDO17_EN| RC1_LDO16_EN | RC1_LDO15_EN | ++ RC1_LDO11_EN | RC1_LDO10_EN | RC1_BUCK2_EN); ++ ++ if (em_x270_lcd_detect() != 0) ++ pr_info("%s: LCD resume failed\n", __FUNCTION__); ++ ++ return 0; ++} ++ ++static struct platform_driver em_x270_battery_driver = { ++ .driver = { ++ .name = "em-x270-battery", ++ .owner = THIS_MODULE, ++ }, ++ .probe = em_x270_battery_probe, ++ .remove = em_x270_battery_remove, ++ ++ .suspend_late = em_x270_battery_suspend, ++ .resume_early = em_x270_battery_resume, ++}; ++ ++/**************************************************************************/ ++/* global patform power management */ ++/**************************************************************************/ ++/* suspend/resume button */ ++static irqreturn_t em_x270_suspend_irq(int irq, void *data) ++{ ++ apm_queue_event(APM_USER_SUSPEND); ++ return IRQ_HANDLED; ++} ++ ++static void em_x270_goto_sleep(suspend_state_t state, ++ unsigned long alarm_time, ++ unsigned int alarm_enable) ++{ ++ pr_info("%s\n", __FUNCTION__); ++ ++ the_charger->ops = &em_x270_charger_ops_suspend; ++ ++ RTSR &= RTSR_ALE; ++ RTAR = RCNR + EM_X270_BATCHK_TIME_SUSPEND; ++ ++ pxa_pm_enter(state); ++} ++ ++static int em_x270_enter_suspend(unsigned long alarm_time, ++ unsigned int alarm_enable) ++{ ++ s32 status = 0; ++ s32 event_a, event_b; ++ int ret; ++ int retry = 10; ++ pr_info("%s\n", __FUNCTION__); ++ ++ /* make sure power I2C state is consistent */ ++ PWRICR &= ~ICR_IUE; ++ ++ if ((PEDR & PWER_GPIO1)) { ++ /* button pressed */ ++ /* clear pending event to avoid interrupt*/ ++ PEDR &= ~PWER_GPIO1; ++ GEDR0 &= ~GPIO_bit(1); ++ ++ ret = 0; ++ } ++ else if ((PEDR & PWER_RTC)) { ++ PEDR &= ~PWER_RTC; ++ pr_debug("%s: timer alarm\n", __FUNCTION__); ++ em_x270_check_charger_state(the_charger); ++ ret = 1; ++ } ++ else if ((PEDR & PWER_GPIO0)) { ++ PEDR &= ~PWER_GPIO0; ++ GEDR0 &= ~GPIO_bit(0); ++ ++ /* we woke up because of DA9030 event */ ++ do { ++ status = the_charger->ops->da9030_get_reg(STATUS); ++ udelay(1000); ++ } while (status < 0 && retry--); ++ ++ the_charger->da9030_status = status; ++ event_a = the_charger->ops->da9030_get_reg(EVENT_A); ++ event_b = the_charger->ops->da9030_get_reg(EVENT_B); ++ ++ pr_info("%s: DA9030 wakeup: status: %x, ev_a: %x, ev_b: %x\n", ++ __FUNCTION__, the_charger->da9030_status, ++ event_a, event_b); ++ ++/* if ((the_charger->da9030_status & STATUS_CHDET)) { */ ++ if (event_a & EVENT_A_CHDET) { ++ pr_info("%s: EVENT_A_CHDET\n", __FUNCTION__); ++ em_x270_check_charger_state(the_charger); ++ } ++ else { ++ pr_info("%s: What the hell?\n", __FUNCTION__); ++ } ++ ++ ret = 1; ++ } ++ else { ++ /* wake up is not DA9030, so continue and let battery ++ driver check the charger state */ ++ ret = 0; ++ } ++ ++ /* get back to sleep */ ++ if (ret) ++ em_x270_goto_sleep(PM_SUSPEND_MEM, alarm_time, alarm_enable); ++ ++ return ret; ++} ++ ++static int em_x270_pm_enter(suspend_state_t state) ++{ ++ unsigned long alarm_time = RTAR; ++ unsigned int alarm_status = ((RTSR & RTSR_ALE) != 0); ++ ++ /* pre-suspend */ ++ pr_info("suspending emma\n"); ++ pxa_gpio_mode(38 | GPIO_OUT | GPIO_DFLT_HIGH); ++ ++ em_x270_goto_sleep(state, alarm_time, alarm_status); ++ ++ /* check if we were resumed because of charger events */ ++ while (em_x270_enter_suspend(alarm_time, alarm_status)) ++ {} ++ ++ /* make sure power I2C state is consistent */ ++ PWRICR &= ~ICR_IUE; ++ ++ /* resume */ ++ pr_info("emma is resumed\n"); ++ the_charger->ops = &em_x270_charger_ops; ++ ++ return 0; ++} ++ ++static struct pm_ops em_x270_pm_ops = { ++ .enter = em_x270_pm_enter, ++ .valid = pm_valid_only_mem, ++}; ++ ++static int em_x270_pm_init(void) ++{ ++ int ret; ++ pm_set_ops(&em_x270_pm_ops); ++ ++ set_irq_type(IRQ_GPIO(1), IRQT_RISING); ++ ++ ret = platform_driver_register(&em_x270_battery_driver); ++ if (ret) ++ return ret; ++ ++ ret = request_irq(IRQ_GPIO(1), em_x270_suspend_irq, IRQF_DISABLED, ++ "suspend button", 0); ++ if (ret) { ++ platform_driver_unregister(&em_x270_battery_driver); ++ } ++ ++ return ret; ++} ++ ++static void em_x270_pm_exit(void) ++{ ++ free_irq(IRQ_GPIO(1), em_x270_suspend_irq); ++ platform_driver_unregister(&em_x270_battery_driver); ++} ++ ++/* make sure I2C is already running */ ++late_initcall(em_x270_pm_init); ++module_exit(em_x270_pm_exit); ++ ++MODULE_DESCRIPTION("EM-X270 power manager"); ++MODULE_AUTHOR("Mike Rapoport"); ++MODULE_LICENSE("GPL"); +diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c +index 3d0ad50..402d792 100644 +--- a/arch/arm/mach-pxa/em-x270.c ++++ b/arch/arm/mach-pxa/em-x270.c +@@ -18,20 +18,26 @@ + #include <linux/mtd/nand.h> + #include <linux/mtd/partitions.h> + +-#include <asm/mach-types.h> ++#include <linux/i2c.h> ++#include <linux/input.h> + ++#include <asm/mach-types.h> + #include <asm/mach/arch.h> + + #include <asm/arch/pxa-regs.h> + #include <asm/arch/pxafb.h> + #include <asm/arch/ohci.h> + #include <asm/arch/mmc.h> ++#include <asm/arch/pxa27x_keyboard.h> + #include <asm/arch/bitfield.h> + ++#include <asm/arch/udc.h> ++ ++#include <asm/arch/sharpsl.h> ++ + #include "generic.h" + + /* GPIO IRQ usage */ +-#define EM_X270_MMC_PD (105) + #define EM_X270_ETHIRQ IRQ_GPIO(41) + #define EM_X270_MMC_IRQ IRQ_GPIO(13) + +@@ -213,6 +219,68 @@ static struct platform_device em_x270_nand = { + } + }; + ++/* DA9030 */ ++static struct i2c_board_info em_x270_pmic_info = { ++ .driver_name = "da9030", ++ .type = "pmic", ++ .addr = 0x49, ++ .irq = IRQ_GPIO(0), ++}; ++ ++/* Keypad */ ++/* The Demo KeyPad has the following mapping: ++ * (0,0) (1,2) (2,1) ++ * (0,2) (1,1) (2,0) ++ * (0,1) (1,0) (2,2) ++ */ ++static struct pxa27x_keyboard_platform_data em_x270_kbd = { ++ .nr_rows = 3, ++ .nr_cols = 3, ++ .keycodes = { ++ { /* row 0 */ ++ -1, ++ -1, ++ KEY_LEFT, ++ }, ++ { /* row 1 */ ++ KEY_UP, ++ KEY_ENTER, ++ KEY_DOWN ++ }, ++ { /* row 2 */ ++ KEY_RIGHT, ++ -1, ++ -1 ++ }, ++ }, ++ .gpio_modes = { ++ (100 | GPIO_ALT_FN_1_IN), ++ (101 | GPIO_ALT_FN_1_IN), ++ (102 | GPIO_ALT_FN_1_IN), ++ (103 | GPIO_ALT_FN_2_OUT), ++ (104 | GPIO_ALT_FN_2_OUT), ++ (105 | GPIO_ALT_FN_2_OUT), ++ }, ++}; ++ ++static struct platform_device em_x270_pxa_keypad = { ++ .name = "pxa27x-keyboard", ++ .id = -1, ++ .dev = { ++ .platform_data = &em_x270_kbd, ++ }, ++}; ++ ++static struct platform_device em_x270_battery_device = { ++ .name = "em-x270-battery", ++ .id = -1, ++}; ++ ++static struct platform_device em_x270_led_device = { ++ .name = "em-x270-led", ++ .id = -1, ++}; ++ + /* platform devices */ + static struct platform_device *platform_devices[] __initdata = { + &em_x270_dm9k, +@@ -220,6 +288,9 @@ static struct platform_device *platform_devices[] __initdata = { + &em_x270_ts, + &em_x270_rtc, + &em_x270_nand, ++ &em_x270_pxa_keypad, ++ &em_x270_battery_device, ++ &em_x270_led_device, + }; + + +@@ -241,6 +312,33 @@ static struct pxaohci_platform_data em_x270_ohci_platform_data = { + .init = em_x270_ohci_init, + }; + ++/* ++ * USB Client (Gadget/UDC) ++ */ ++static void em_x270_udc_command(int cmd) ++{ ++ switch(cmd) { ++ case PXA2XX_UDC_CMD_CONNECT: ++ UP2OCR = UP2OCR_HXOE | UP2OCR_DMPUE | UP2OCR_DMPUBE; ++ break; ++ case PXA2XX_UDC_CMD_DISCONNECT: ++/* UP2OCR = UP2OCR_HXS | UP2OCR_HXOE; */ ++ //UP2OCR = UP2OCR_HXOE | UP2OCR_DMPUE | UP2OCR_DMPUBE; ++ break; ++ } ++} ++ ++static int em_x270_udc_detect(void) ++{ ++ return 1; ++} ++ ++static struct pxa2xx_udc_mach_info em_x270_udc_info __initdata = { ++ .udc_is_connected = em_x270_udc_detect, ++ .udc_command = em_x270_udc_command, ++}; ++ ++ + + static int em_x270_mci_init(struct device *dev, + irq_handler_t em_x270_detect_int, +@@ -256,9 +354,6 @@ static int em_x270_mci_init(struct device *dev, + pxa_gpio_mode(GPIO110_MMCDAT2_MD); + pxa_gpio_mode(GPIO111_MMCDAT3_MD); + +- /* EM-X270 uses GPIO13 as SD power enable */ +- pxa_gpio_mode(EM_X270_MMC_PD | GPIO_OUT); +- + err = request_irq(EM_X270_MMC_IRQ, em_x270_detect_int, + IRQF_DISABLED | IRQF_TRIGGER_FALLING, + "MMC card detect", data); +@@ -313,12 +408,19 @@ static struct pxafb_mach_info em_x270_lcd = { + .num_modes = 1, + .cmap_inverse = 0, + .cmap_static = 0, +- .lccr0 = LCCR0_PAS, +- .lccr3 = LCCR3_PixClkDiv(0x01) | LCCR3_Acb(0xff), ++ ++ .lccr0 = LCCR0_Act, ++ .lccr3 = LCCR3_PixFlEdg, + }; + + static void __init em_x270_init(void) + { ++ /* register PMIC */ ++ i2c_register_board_info(1, &em_x270_pmic_info, 1); ++ ++ /* setup DA9030 irq */ ++ set_irq_type(IRQ_GPIO(0), IRQT_FALLING); ++ + /* setup LCD */ + set_pxa_fb_info(&em_x270_lcd); + +@@ -329,6 +431,8 @@ static void __init em_x270_init(void) + pxa_set_mci_info(&em_x270_mci_platform_data); + pxa_set_ohci_info(&em_x270_ohci_platform_data); + ++ pxa_set_udc_info(&em_x270_udc_info); ++ + /* setup STUART GPIOs */ + pxa_gpio_mode(GPIO46_STRXD_MD); + pxa_gpio_mode(GPIO47_STTXD_MD); +@@ -341,9 +445,16 @@ static void __init em_x270_init(void) + + /* Setup interrupt for dm9000 */ + set_irq_type(EM_X270_ETHIRQ, IRQT_RISING); ++ ++ PCFR = 0x6; ++ PSLR = 0xff400000; ++ PMCR = 0x00000005; ++ PWER = 0x80000003; ++ PFER = 0x00000003; ++ PRER = 0x00000000; + } + +-MACHINE_START(EM_X270, "Compulab EM-x270") ++MACHINE_START(EM_X270, "Compulab EM-X270") + .boot_params = 0xa0000100, + .phys_io = 0x40000000, + .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, +diff --git a/arch/arm/mach-pxa/pwr-i2c.c b/arch/arm/mach-pxa/pwr-i2c.c +new file mode 100644 +index 0000000..8a501c4 +--- /dev/null ++++ b/arch/arm/mach-pxa/pwr-i2c.c +@@ -0,0 +1,539 @@ ++/* ++ * (C) Copyrihgt 2007 CompuLab, Ltd. ++ * Mike Rapoport <mike@compulab.co.il> ++ * Adaptation of U-Boot I2C driver for PXA. ++ * ++ * (C) Copyright 2000 ++ * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio@tin.it ++ * ++ * (C) Copyright 2000 Sysgo Real-Time Solutions, GmbH <www.elinos.com> ++ * Marius Groeger <mgroeger@sysgo.de> ++ * ++ * (C) Copyright 2003 Pengutronix e.K. ++ * Robert Schwebel <r.schwebel@pengutronix.de> ++ * ++ * See file CREDITS for list of people who contributed to this ++ * project. ++ * ++ * 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 ++ * ++ * Back ported to the 8xx platform (from the 8260 platform) by ++ * Murray.Jensen@cmst.csiro.au, 27-Jan-01. ++ */ ++ ++/* #define DEBUG */ ++ ++#include <linux/kernel.h> ++#include <linux/delay.h> ++#include <linux/module.h> ++#include <linux/jiffies.h> ++ ++#include <asm/arch/hardware.h> ++#include <asm/arch/pxa-regs.h> ++#include <asm/arch/pwr-i2c.h> ++ ++#define I2C_ICR_INIT (ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE) ++#define I2C_ISR_INIT 0x7FF ++ ++/* Shall the current transfer have a start/stop condition? */ ++#define I2C_COND_NORMAL 0 ++#define I2C_COND_START 1 ++#define I2C_COND_STOP 2 ++ ++/* Shall the current transfer be ack/nacked or being waited for it? */ ++#define I2C_ACKNAK_WAITACK 1 ++#define I2C_ACKNAK_SENDACK 2 ++#define I2C_ACKNAK_SENDNAK 4 ++ ++/* Specify who shall transfer the data (master or slave) */ ++#define I2C_READ 0 ++#define I2C_WRITE 1 ++ ++/* All transfers are described by this data structure */ ++struct i2c_msg { ++ u8 condition; ++ u8 acknack; ++ u8 direction; ++ u8 data; ++}; ++ ++/** ++ * pxa_pwr_i2c_transfer: - reset the host controller ++ * ++ */ ++/* static void pxa_pwr_i2c_reset(void) */ ++/* { */ ++/* int i; */ ++ ++/* /\* CKEN |= CKEN_PWRI2C; *\/ */ ++/* /\* PWRICR |= PCFR_PI2C_EN; *\/ */ ++ ++/* /\* /\\* delay 250ms *\\/ *\/ */ ++/* /\* for (i = 0; i < 250; i++) *\/ */ ++/* /\* udelay(1000); *\/ */ ++ ++/* /\* PWRICR &= ~(ICR_MA | ICR_START | ICR_STOP); *\/ */ ++/* /\* PWRICR |= ICR_UR; *\/ */ ++/* /\* PWRISR = 0x7ff; *\/ */ ++ ++/* /\* PWRICR &= ~ICR_UR; *\/ */ ++/* /\* PWRICR = ICR_GCD | ICR_SCLE; *\/ */ ++/* /\* PWRICR |= ICR_IUE; *\/ */ ++/* /\* PWRICR |= 0x8000; *\/ */ ++ ++/* /\* udelay(1000); *\/ */ ++ ++/* return; */ ++ ++/* PWRICR &= ~ICR_IUE; /\* disable unit *\/ */ ++/* PWRICR |= ICR_UR; /\* reset the unit *\/ */ ++/* udelay(100); */ ++/* PWRICR &= ~ICR_IUE; /\* disable unit *\/ */ ++ ++/* CKEN |= CKEN_PWRI2C; */ ++/* PCFR |= PCFR_PI2C_EN; */ ++ ++/* PWRICR = I2C_ICR_INIT; /\* set control register values *\/ */ ++/* PWRISR = I2C_ISR_INIT; /\* set clear interrupt bits *\/ */ ++/* PWRICR |= ICR_IUE; /\* enable unit *\/ */ ++/* udelay(100); */ ++/* } */ ++ ++static void pwr_i2c_abort() ++{ ++ unsigned long timeout = 250000; ++ unsigned long time = 0; ++ ++ while ((time < timeout) && (PWRIBMR & 0x1) == 0) { ++ unsigned long icr = PWRICR; ++ ++ icr &= ~ICR_START; ++ icr |= ICR_ACKNAK | ICR_STOP | ICR_TB; ++ ++ PWRICR = icr; ++ ++ udelay(1000); ++ time += 1000; ++ } ++ ++ PWRICR &= ~(ICR_MA | ICR_START | ICR_STOP); ++} ++ ++static void pxa_pwr_i2c_reset(void) ++{ ++ pr_debug("Resetting I2C Controller Unit\n"); ++ ++ /* abort any transfer currently under way */ ++ pwr_i2c_abort(); ++ ++ /* reset according to 9.8 */ ++ PWRICR = ICR_UR; ++ PWRISR = I2C_ISR_INIT; ++ PWRISR &= ~ICR_UR; ++ ++ /* set control register values */ ++ PWRICR = I2C_ICR_INIT; ++ ++ /* enable unit */ ++ PWRICR |= ICR_IUE; ++ udelay(100); ++ ++/* CKEN |= CKEN_PWRI2C; */ ++/* PCFR |= PCFR_PI2C_EN; */ ++} ++ ++/** ++ * i2c_isr_set_cleared: - wait until certain bits of the I2C status register ++ * are set and cleared ++ * ++ * @return: 1 in case of success, 0 means timeout (no match within 10 ms). ++ */ ++static int pxa_pwr_i2c_isr_set_cleared(unsigned long set_mask, ++ unsigned long cleared_mask) ++{ ++ int timeout = 10000; ++ ++ while (((PWRISR & set_mask) != set_mask) ++ || ((PWRISR & cleared_mask) != 0)) { ++ udelay(10); ++ if (timeout-- < 0) ++ return 0; ++ } ++ ++ return 1; ++} ++ ++/** ++ * pxa_pwr_i2c_transfer: - Transfer one byte over the i2c bus ++ * ++ * This function can tranfer a byte over the i2c bus in both directions. ++ * It is used by the public API functions. ++ * ++ * @return: 0: transfer successful ++ * -EINVAL: message is empty ++ * -ETIMEDOUT: transmit timeout ++ * -E: ACK missing ++ * -ETIMEDOUT: receive timeout ++ * -EINVAL: illegal parameters ++ * -EBUSY: bus is busy and couldn't be aquired ++ */ ++int pxa_pwr_i2c_transfer(struct i2c_msg *msg) ++{ ++ int ret; ++ ++ if (!msg) ++ goto transfer_error_msg_empty; ++ ++ switch (msg->direction) { ++ case I2C_WRITE: ++ /* check if bus is not busy */ ++/* if (!pxa_pwr_i2c_isr_set_cleared(0, (ISR_IBB | ISR_UB))) */ ++/* goto transfer_error_bus_busy; */ ++ ++ /* start transmission */ ++ PWRICR &= ~ICR_START; ++ PWRICR &= ~ICR_STOP; ++ PWRIDBR = msg->data; ++ if (msg->condition == I2C_COND_START) ++ PWRICR |= ICR_START; ++ if (msg->condition == I2C_COND_STOP) ++ PWRICR |= ICR_STOP; ++ if (msg->acknack == I2C_ACKNAK_SENDNAK) ++ PWRICR |= ICR_ACKNAK; ++ if (msg->acknack == I2C_ACKNAK_SENDACK) ++ PWRICR &= ~ICR_ACKNAK; ++ PWRICR &= ~ICR_ALDIE; ++ PWRICR |= ICR_TB; ++ ++ /* transmit register empty? */ ++ if (!pxa_pwr_i2c_isr_set_cleared(ISR_ITE, 0)) ++ goto transfer_error_transmit_timeout; ++ ++ /* clear 'transmit empty' state */ ++ PWRISR |= ISR_ITE; ++ ++ /* wait for ACK from slave */ ++ if (msg->acknack == I2C_ACKNAK_WAITACK) ++ if (!pxa_pwr_i2c_isr_set_cleared(0, ISR_ACKNAK)) ++ goto transfer_error_ack_missing; ++ break; ++ case I2C_READ: ++ /* check if bus is not busy */ ++/* if (!pxa_pwr_i2c_isr_set_cleared(0, ISR_IBB)) */ ++/* goto transfer_error_bus_busy; */ ++ ++ /* start receive */ ++ PWRICR &= ~ICR_START; ++ PWRICR &= ~ICR_STOP; ++ if (msg->condition == I2C_COND_START) ++ PWRICR |= ICR_START; ++ if (msg->condition == I2C_COND_STOP) ++ PWRICR |= ICR_STOP; ++ if (msg->acknack == I2C_ACKNAK_SENDNAK) ++ PWRICR |= ICR_ACKNAK; ++ if (msg->acknack == I2C_ACKNAK_SENDACK) ++ PWRICR &= ~ICR_ACKNAK; ++ PWRICR &= ~ICR_ALDIE; ++ PWRICR |= ICR_TB; ++ ++ /* receive register full? */ ++ if (!pxa_pwr_i2c_isr_set_cleared(ISR_IRF, 0)) ++ goto transfer_error_receive_timeout; ++ ++ msg->data = PWRIDBR; ++ ++ /* clear 'receive empty' state */ ++ PWRISR |= ISR_IRF; ++ ++ break; ++ default: ++ goto transfer_error_illegal_param; ++ ++ } ++ ++ return 0; ++ ++transfer_error_msg_empty: ++ pr_debug("%s: error: 'msg' is empty\n", __FUNCTION__); ++ ret = -1; ++ goto i2c_transfer_finish; ++ ++transfer_error_transmit_timeout: ++ pr_debug("%s: error: transmit timeout\n", __FUNCTION__); ++ ret = -2; ++ goto i2c_transfer_finish; ++ ++transfer_error_ack_missing: ++ pr_debug("%s: error: ACK missing\n", __FUNCTION__); ++ ret = -3; ++ goto i2c_transfer_finish; ++ ++transfer_error_receive_timeout: ++ pr_debug("%s: error: receive timeout\n", __FUNCTION__); ++ ret = -4; ++ goto i2c_transfer_finish; ++ ++transfer_error_illegal_param: ++ pr_debug("%s: error: illegal parameters\n", __FUNCTION__); ++ ret = -5; ++ goto i2c_transfer_finish; ++ ++transfer_error_bus_busy: ++ pr_debug("%s: error: bus is busy\n", __FUNCTION__); ++ ret = -6; ++ goto i2c_transfer_finish; ++ ++i2c_transfer_finish: ++ pr_debug("%s: ISR: 0x%04x\n", __FUNCTION__, ISR); ++ return ret; ++} ++ ++/* ------------------------------------------------------------------------ */ ++/* API Functions */ ++/* ------------------------------------------------------------------------ */ ++/** ++ * i2c_probe: - Test if a chip answers for a given i2c address ++ * ++ * @chip: address of the chip which is searched for ++ * @return: 0 if a chip was found, -1 otherwhise ++ */ ++int pxa_pwr_i2c_probe(u8 chip) ++{ ++ struct i2c_msg msg; ++ int ret; ++ ++ pxa_pwr_i2c_reset(); ++ ++ msg.condition = I2C_COND_START; ++ msg.acknack = I2C_ACKNAK_WAITACK; ++ msg.direction = I2C_WRITE; ++ msg.data = (chip << 1) + 1; ++ if ((ret = pxa_pwr_i2c_transfer(&msg))) ++ return ret; ++ ++ msg.condition = I2C_COND_STOP; ++ msg.acknack = I2C_ACKNAK_SENDNAK; ++ msg.direction = I2C_READ; ++ msg.data = 0x00; ++ if ((ret = pxa_pwr_i2c_transfer(&msg))) ++ return ret; ++ ++ return 0; ++} ++ ++/** ++ * i2c_read: - Read multiple bytes from an i2c device ++ * ++ * The higher level routines take into account that this function is only ++ * called with len < page length of the device (see configuration file) ++ * ++ * @chip: address of the chip which is to be read ++ * @addr: i2c data address within the chip ++ * @alen: length of the i2c data address (1..2 bytes) ++ * @buffer: where to write the data ++ * @len: how much byte do we want to read ++ * @return: 0 in case of success ++ */ ++int pxa_pwr_i2c_read(u8 chip, uint addr, int alen, u8 * buffer, int len) ++{ ++ struct i2c_msg msg; ++ u8 addr_bytes[3]; /* lowest...highest byte of data address */ ++ int ret; ++ ++ pr_debug("%s(chip=0x%02x, addr=0x%02x, alen=0x%02x, len=0x%02x)\n", ++ __FUNCTION__, chip, addr, alen, len); ++ ++ pxa_pwr_i2c_reset(); ++ ++ /* dummy chip address write */ ++ pr_debug("%s: dummy chip address write\n", __FUNCTION__); ++ msg.condition = I2C_COND_START; ++ msg.acknack = I2C_ACKNAK_WAITACK; ++ msg.direction = I2C_WRITE; ++ msg.data = (chip << 1); ++ msg.data &= 0xFE; ++ if ((ret = pxa_pwr_i2c_transfer(&msg))) ++ return ret; ++ ++ /* ++ * send memory address bytes; ++ * alen defines how much bytes we have to send. ++ */ ++ /*addr &= ((1 << CFG_EEPROM_PAGE_WRITE_BITS)-1); */ ++ addr_bytes[0] = (u8) ((addr >> 0) & 0x000000FF); ++ addr_bytes[1] = (u8) ((addr >> 8) & 0x000000FF); ++ addr_bytes[2] = (u8) ((addr >> 16) & 0x000000FF); ++ ++ while (--alen >= 0) { ++ pr_debug("%s: send memory word address byte %1d\n", ++ __FUNCTION__, alen); ++ msg.condition = I2C_COND_NORMAL; ++ msg.acknack = I2C_ACKNAK_WAITACK; ++ msg.direction = I2C_WRITE; ++ msg.data = addr_bytes[alen]; ++ if ((ret = pxa_pwr_i2c_transfer(&msg))) ++ return ret; ++ } ++ ++ /* start read sequence */ ++ pr_debug("%s: start read sequence\n", __FUNCTION__); ++ msg.condition = I2C_COND_START; ++ msg.acknack = I2C_ACKNAK_WAITACK; ++ msg.direction = I2C_WRITE; ++ msg.data = (chip << 1); ++ msg.data |= 0x01; ++ if ((ret = pxa_pwr_i2c_transfer(&msg))) ++ return ret; ++ ++ /* read bytes; send NACK at last byte */ ++ while (len--) { ++ if (len == 0) { ++ msg.condition = I2C_COND_STOP; ++ msg.acknack = I2C_ACKNAK_SENDNAK; ++ } else { ++ msg.condition = I2C_COND_NORMAL; ++ msg.acknack = I2C_ACKNAK_SENDACK; ++ } ++ ++ msg.direction = I2C_READ; ++ msg.data = 0x00; ++ if ((ret = pxa_pwr_i2c_transfer(&msg))) ++ return ret; ++ ++ *buffer = msg.data; ++ pr_debug("%s: reading byte (0x%08x)=0x%02x\n", ++ __FUNCTION__, (unsigned int)buffer, *buffer); ++ buffer++; ++ } ++ ++ pxa_pwr_i2c_reset(); ++ return 0; ++} ++ ++/** ++ * i2c_write: - Write multiple bytes to an i2c device ++ * ++ * The higher level routines take into account that this function is only ++ * called with len < page length of the device (see configuration file) ++ * ++ * @chip: address of the chip which is to be written ++ * @addr: i2c data address within the chip ++ * @alen: length of the i2c data address (1..2 bytes) ++ * @buffer: where to find the data to be written ++ * @len: how much byte do we want to read ++ * @return: 0 in case of success ++ */ ++int pxa_pwr_i2c_write(u8 chip, uint addr, int alen, u8 * buffer, int len) ++{ ++ struct i2c_msg msg; ++ u8 addr_bytes[3]; /* lowest...highest byte of data address */ ++ int ret; ++ ++ pr_debug("%s(chip=0x%02x, addr=0x%02x, alen=0x%02x, len=0x%02x)\n", ++ __FUNCTION__, chip, addr, alen, len); ++ ++ pxa_pwr_i2c_reset(); ++ ++ /* chip address write */ ++ pr_debug("%s: chip address write\n", __FUNCTION__); ++ msg.condition = I2C_COND_START; ++ msg.acknack = I2C_ACKNAK_WAITACK; ++ msg.direction = I2C_WRITE; ++ msg.data = (chip << 1); ++ msg.data &= 0xFE; ++ if ((ret = pxa_pwr_i2c_transfer(&msg))) ++ return ret; ++ ++ /* ++ * send memory address bytes; ++ * alen defines how much bytes we have to send. ++ */ ++ addr_bytes[0] = (u8) ((addr >> 0) & 0x000000FF); ++ addr_bytes[1] = (u8) ((addr >> 8) & 0x000000FF); ++ addr_bytes[2] = (u8) ((addr >> 16) & 0x000000FF); ++ ++ while (--alen >= 0) { ++ pr_debug("%s: send memory word address\n", __FUNCTION__); ++ msg.condition = I2C_COND_NORMAL; ++ msg.acknack = I2C_ACKNAK_WAITACK; ++ msg.direction = I2C_WRITE; ++ msg.data = addr_bytes[alen]; ++ if ((ret = pxa_pwr_i2c_transfer(&msg))) ++ return ret; ++ } ++ ++ /* write bytes; send NACK at last byte */ ++ while (len--) { ++ pr_debug("%s: writing byte (0x%08x)=0x%02x\n", ++ __FUNCTION__, (unsigned int)buffer, *buffer); ++ ++ if (len == 0) ++ msg.condition = I2C_COND_STOP; ++ else ++ msg.condition = I2C_COND_NORMAL; ++ ++ msg.acknack = I2C_ACKNAK_WAITACK; ++ msg.direction = I2C_WRITE; ++ msg.data = *(buffer++); ++ ++ if ((ret = pxa_pwr_i2c_transfer(&msg))) ++ return ret; ++ } ++ ++ pxa_pwr_i2c_reset(); ++ return 0; ++} ++ ++/** ++ * pxa_pwr_i2c_reg_read: - Read single byte from an i2c device ++ * ++ * @chip: address of the chip which is to be read ++ * @reg: i2c data address within the chip ++ * @return: data in case of success, negative error code otherwise ++ */ ++s32 pxa_pwr_i2c_reg_read(u8 chip, u8 reg) ++{ ++ char buf; ++ int ret; ++ ++ pr_debug("%s(chip=0x%02x, reg=0x%02x)\n", __FUNCTION__, chip, reg); ++ ret = pxa_pwr_i2c_read(chip, reg, 1, &buf, 1); ++ if (ret == 0) ++ ret = buf; ++ ++ return ret; ++} ++ ++/** ++ * pxa_pwr_i2c_reg_write: - Write multiple bytes to an i2c device ++ * ++ * The higher level routines take into account that this function is only ++ * called with len < page length of the device (see configuration file) ++ * ++ * @chip: address of the chip which is to be written ++ * @reg: i2c data address within the chip ++ * @return: 0 in case of success, negative error code otherwise ++ */ ++s32 pxa_pwr_i2c_reg_write(u8 chip, u8 reg, u8 val) ++{ ++ pr_debug("%s(chip=0x%02x, reg=0x%02x, val=0x%02x)\n", ++ __FUNCTION__, chip, reg, val); ++ return pxa_pwr_i2c_write(chip, reg, 1, &val, 1); ++} ++ ++MODULE_DESCRIPTION("PXA Power I2C"); ++MODULE_AUTHOR("Mike Rapoport"); ++MODULE_LICENSE("GPL"); +diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c +index 203371a..36b695f 100644 +--- a/arch/arm/mach-pxa/pxa27x.c ++++ b/arch/arm/mach-pxa/pxa27x.c +@@ -243,7 +243,11 @@ void pxa27x_cpu_pm_enter(suspend_state_t state) + case PM_SUSPEND_MEM: + /* set resume return address */ + PSPR = virt_to_phys(pxa_cpu_resume); +- pxa27x_cpu_suspend(PWRMODE_SLEEP); ++#ifdef CONFIG_MACH_EM_X270 ++ pxa27x_cpu_suspend(PWRMODE_DEEPSLEEP); ++#else ++ pxa27x_cpu_suspend(PWRMODE_SLEEP); ++#endif + break; + } + } +diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c +index bae47e1..a16e532 100644 +--- a/arch/arm/mach-pxa/spitz.c ++++ b/arch/arm/mach-pxa/spitz.c +@@ -349,6 +349,32 @@ static struct pxamci_platform_data spitz_mci_platform_data = { + + + /* ++ * USB Client (Gadget/UDC) ++ */ ++static void spitz_udc_command(int cmd) ++{ ++ switch(cmd) { ++ case PXA2XX_UDC_CMD_CONNECT: ++ UP2OCR = UP2OCR_HXOE | UP2OCR_DMPUE | UP2OCR_DMPUBE; ++ break; ++ case PXA2XX_UDC_CMD_DISCONNECT: ++ //UP2OCR = UP2OCR_HXOE | UP2OCR_DMPUE | UP2OCR_DMPUBE; ++ break; ++ } ++} ++ ++static int spitz_udc_detect(void) ++{ ++ return 1; ++} ++ ++static struct pxa2xx_udc_mach_info spitz_udc_info __initdata = { ++ .udc_is_connected = spitz_udc_detect, ++ .udc_command = spitz_udc_command, ++}; ++ ++ ++/* + * USB Host (OHCI) + */ + static int spitz_ohci_init(struct device *dev) +@@ -499,6 +525,7 @@ static void __init common_init(void) + pxa_gpio_mode(SPITZ_GPIO_HSYNC | GPIO_IN); + + platform_add_devices(devices, ARRAY_SIZE(devices)); ++ pxa_set_udc_info(&spitz_udc_info); + pxa_set_mci_info(&spitz_mci_platform_data); + pxa_set_ohci_info(&spitz_ohci_platform_data); + pxa_set_ficp_info(&spitz_ficp_platform_data); +diff --git a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig +index 2e1c24f..f80f2b1 100644 +--- a/drivers/i2c/chips/Kconfig ++++ b/drivers/i2c/chips/Kconfig +@@ -163,4 +163,17 @@ config MENELAUS + and other features that are often used in portable devices like + cell phones and PDAs. + ++config DA9030 ++ tristate "Dialog Semiconductor DA9030 power management chip" ++ depends on EXPERIMENTAL && EMBEDDED ++ help ++ If you say yes here you get support for the Dialog ++ Semiconductor DA9030 power management chip. ++ This includes voltage regulators, lithium ion/polymer battery ++ charging, and other features that are often used in portable ++ devices like PDAs, cell phones and cameras. ++ ++ This driver can also be built as a module. If so, the module ++ will be called da9030. ++ + endmenu +diff --git a/drivers/i2c/chips/Makefile b/drivers/i2c/chips/Makefile +index ca924e1..69f545c 100644 +--- a/drivers/i2c/chips/Makefile ++++ b/drivers/i2c/chips/Makefile +@@ -15,6 +15,7 @@ obj-$(CONFIG_ISP1301_OMAP) += isp1301_omap.o + obj-$(CONFIG_TPS65010) += tps65010.o + obj-$(CONFIG_MENELAUS) += menelaus.o + obj-$(CONFIG_SENSORS_TSL2550) += tsl2550.o ++obj-$(CONFIG_DA9030) += da9030.o + + ifeq ($(CONFIG_I2C_DEBUG_CHIP),y) + EXTRA_CFLAGS += -DDEBUG +diff --git a/drivers/i2c/chips/da9030.c b/drivers/i2c/chips/da9030.c +new file mode 100644 +index 0000000..9791272 +--- /dev/null ++++ b/drivers/i2c/chips/da9030.c +@@ -0,0 +1,1213 @@ ++/* ++ * Dialog Semiconductor DA9030 power management IC driver ++ * ++ * Copyright (C) 2007 Compulab, Ltd. ++ * Mike Rapoport <mike@compulab.co.il> ++ * ++ * Some parts based on menelaus.c: ++ * Copyright (C) 2004 Texas Instruments, Inc. ++ * Copyright (C) 2005, 2006 Nokia Corporation ++ * ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file COPYING in the main directory of this archive for ++ * more details. ++ */ ++ ++#include <linux/module.h> ++#include <linux/ctype.h> ++#include <linux/uaccess.h> ++#include <linux/i2c.h> ++#include <linux/irq.h> ++#include <linux/interrupt.h> ++#include <linux/da9030.h> ++#include <linux/kernel_stat.h> ++#include <linux/random.h> ++#include <linux/mutex.h> ++ ++#include <linux/debugfs.h> ++#include <linux/seq_file.h> ++ ++#include "da9030.h" ++ ++#define DRIVER_NAME "da9030" ++ ++static unsigned short normal_i2c[] = { 0x49, I2C_CLIENT_END }; ++ ++I2C_CLIENT_INSMOD; ++ ++struct da9030 { ++ struct mutex lock; ++ struct i2c_client *client; ++ ++ struct work_struct event_work; ++ ++ /* there are 24 interrupts */ ++ void (*callbacks[24])(int event, void *data); ++ void *callbacks_data[24]; ++ ++ struct dentry *debug_file; ++}; ++ ++/* I hardly believe there can be more than 1 such chip in the system, ++ so keeping its global instance won't really hurt */ ++static struct da9030 *the_da9030; ++ ++unsigned char defined_regs[] = { ++ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, ++ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, ++ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, ++ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, ++ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, ++ 0x50, 0x51, ++ 0x60, 0x61, 0x62, 0x63, ++ 0x80, 0x81, ++ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, ++ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, ++ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, ++}; ++ ++static inline int is_reg_valid(u32 reg) ++{ ++ int i; ++ for (i = 0; i < ARRAY_SIZE(defined_regs); i++) ++ if (reg == defined_regs[i]) ++ return 1; ++ ++ return 0; ++} ++ ++s32 da9030_get_reg(u32 reg) ++{ ++ if (!is_reg_valid(reg)) ++ return -EINVAL; ++ ++ return i2c_smbus_read_byte_data(the_da9030->client, reg); ++} ++EXPORT_SYMBOL(da9030_get_reg); ++ ++s32 da9030_set_reg(u32 reg, u8 val) ++{ ++ if (!is_reg_valid(reg)) ++ return -EINVAL; ++ ++ return i2c_smbus_write_byte_data(the_da9030->client, reg, val); ++} ++EXPORT_SYMBOL(da9030_set_reg); ++ ++static s32 da9030_update_reg_bits(u32 reg, int bits, int shift, int val) ++{ ++ int ret; ++ int new_val; ++ ++ mutex_lock(&the_da9030->lock); ++ ret = da9030_get_reg(reg); ++ if (ret < 0) ++ goto out; ++ ++ new_val = reg & ~(((1 << bits) - 1) << shift); ++ new_val |= (val << shift); ++ ++ ret = da9030_set_reg(reg, new_val); ++ mutex_unlock(&the_da9030->lock); ++ ++out: ++ return ret; ++} ++ ++int da9030_get_status(void) ++{ ++ s32 ret; ++ ++ mutex_lock(&the_da9030->lock); ++ ret = da9030_get_reg(STATUS); ++ mutex_unlock(&the_da9030->lock); ++ ++ return ret; ++} ++EXPORT_SYMBOL(da9030_get_status); ++ ++int da9030_get_fault_log(void) ++{ ++ s32 ret; ++ ++ mutex_lock(&the_da9030->lock); ++ ret = da9030_get_reg(FAULT_LOG); ++ mutex_unlock(&the_da9030->lock); ++ ++ return ret; ++} ++EXPORT_SYMBOL(da9030_get_fault_log); ++ ++void da9030_read_adc(struct da9030_adc_res *adc) ++{ ++ mutex_lock(&the_da9030->lock); ++ ++ adc->vbat_res = da9030_get_reg(VBAT_RES); ++ adc->vbatmin_res = da9030_get_reg(VBATMIN_RES); ++ adc->vbatmintxon = da9030_get_reg(VBATMINTXON_RES); ++ adc->ichmax_res = da9030_get_reg(ICHMAX_RES); ++ adc->ichmin_res = da9030_get_reg(ICHMIN_RES); ++ adc->ichaverage_res = da9030_get_reg(ICHAVERAGE_RES); ++ adc->vchmax_res = da9030_get_reg(VCHMAX_RES); ++ adc->vchmin_res = da9030_get_reg(VCHMIN_RES); ++ adc->tbat_res = da9030_get_reg(TBAT_RES); ++ adc->adc_in4_res = da9030_get_reg(ADC_IN4_RES); ++ adc->adc_in5_res = da9030_get_reg(ADC_IN5_RES); ++ ++ mutex_unlock(&the_da9030->lock); ++} ++EXPORT_SYMBOL(da9030_read_adc); ++ ++void da9030_enable_adc(void) ++{ ++ /* enable automatic A/D measurements */ ++ mutex_lock(&the_da9030->lock); ++ ++ da9030_set_reg(ADC_MAN_CONTROL, ++ ADC_LDO_INT_ENABLE | ADC_TBATREF_ENABLE); ++ da9030_set_reg(ADC_MAN_CONTROL_1, ++ ADC_LDO_INT_ENABLE | ADC_TBATREF_ENABLE); ++ da9030_set_reg(ADC_AUTO_CONTROL_1, ++ ADC_TBAT_ENABLE | ADC_VBAT_IN_TXON | ADC_VCH_ENABLE | ++ ADC_ICH_ENABLE | ADC_VBAT_ENABLE | ++ ADC_AUTO_SLEEP_ENABLE); ++ da9030_set_reg(ADC_AUTO_CONTROL, ++ ADC_TBAT_ENABLE | ADC_VBAT_IN_TXON | ADC_VCH_ENABLE | ++ ADC_ICH_ENABLE | ADC_VBAT_ENABLE | ++ ADC_AUTO_SLEEP_ENABLE); ++ ++ mutex_unlock(&the_da9030->lock); ++} ++EXPORT_SYMBOL(da9030_enable_adc); ++ ++void da9030_set_wled(int on, unsigned int brightness) ++{ ++ u8 val; ++ ++ mutex_lock(&the_da9030->lock); ++ ++ if (on) ++ val = WLED_CP_ENABLE | (brightness & 0x7); ++ else ++ val = da9030_get_reg(WLED_CONTROL) & ~WLED_CP_ENABLE; ++ ++ da9030_set_reg(WLED_CONTROL, val); ++ ++ mutex_unlock(&the_da9030->lock); ++} ++EXPORT_SYMBOL(da9030_set_wled); ++ ++int da9030_set_charger(int on, unsigned int mA, unsigned int mV) ++{ ++ int ret; ++ u8 val = 0; ++ if (on) { ++ if (mA >= 1500 || mV < 4000 || mV > 4350) ++ return -EINVAL; ++ ++ val = CHRG_CHARGER_ENABLE; ++ val |= (mA / 100) << 3; ++ val |= (mV - 4000) / 50; ++ } ++ ++ mutex_lock(&the_da9030->lock); ++ ret = da9030_set_reg(CHARGE_CONTROL, val); ++ mutex_unlock(&the_da9030->lock); ++ ++ return ret; ++} ++EXPORT_SYMBOL(da9030_set_charger); ++ ++void da9030_get_charger(int *on, unsigned int *mA, unsigned int *mV) ++{ ++ s32 val; ++ ++ mutex_lock(&the_da9030->lock); ++ ++ val = da9030_get_reg(CHARGE_CONTROL); ++ ++ mutex_unlock(&the_da9030->lock); ++ ++ if (on) ++ *on = (val & CHRG_CHARGER_ENABLE) ? 1 : 0; ++ ++ if (mA) ++ *mA = ((val >> 3) & 0xf) * 100; ++ ++ if (mV) ++ *mV = (val & 0x7) * 50 + 4000; ++} ++EXPORT_SYMBOL(da9030_get_charger); ++ ++int da9030_set_led(int led, int on, ++ enum da9030_led_rate rate, ++ enum da9030_led_duty_cycle duty, ++ enum da9030_led_pwm_chop pwm_chop) ++{ ++ int reg; ++ int ret; ++ ++ u8 val = 0; ++ ++ if (led > 4) ++ return -EINVAL; ++ ++ reg = LED_1_CONTROL + led; ++ if (on) { ++ val = LED_ENABLE; ++ val |= (rate & 0x3) << 5; ++ val |= (duty & 0x3) << 3; ++ val |= (pwm_chop & 0x7); ++ } ++ ++ mutex_lock(&the_da9030->lock); ++ ret = da9030_set_reg(reg, val); ++ mutex_unlock(&the_da9030->lock); ++ ++ return ret; ++} ++EXPORT_SYMBOL(da9030_set_led); ++ ++void da9030_set_thresholds(unsigned int tbathighp, unsigned int tbathighn, ++ unsigned int tbatlow, unsigned int vbatmon) ++{ ++ mutex_lock(&the_da9030->lock); ++ ++ da9030_set_reg(TBATHIGHP, tbathighp); ++ da9030_set_reg(TBATHIGHN, tbathighn); ++ da9030_set_reg(TBATLOW, tbatlow); ++ da9030_set_reg(VBATMONTXON, vbatmon); ++ da9030_set_reg(VBATMON, vbatmon); ++ ++ da9030_set_reg(TBATHIGHP_1, tbathighp); ++ da9030_set_reg(TBATHIGHN_1, tbathighn); ++ da9030_set_reg(TBATLOW_1, tbatlow); ++ da9030_set_reg(VBATMONTXMON_1, vbatmon); ++ da9030_set_reg(VBATMON_1, vbatmon); ++ ++ mutex_unlock(&the_da9030->lock); ++} ++EXPORT_SYMBOL(da9030_set_thresholds); ++ ++struct da9030_vtg_value { ++ u16 vtg; ++ u16 val; ++}; ++ ++struct da9030_vtg_value da9030_vtg_1V8_3V2[] = { ++ {1800, 0x0}, ++ {1900, 0x1}, ++ {2000, 0x2}, ++ {2100, 0x3}, ++ {2200, 0x4}, ++ {2300, 0x5}, ++ {2400, 0x6}, ++ {2500, 0x7}, ++ {2600, 0x8}, ++ {2700, 0x9}, ++ {2800, 0xa}, ++ {2900, 0xb}, ++ {3000, 0xc}, ++ {3100, 0xd}, ++ {3200, 0xe}, ++ {3200, 0xf}, ++}; ++ ++struct da9030_vtg_value da9030_vtg_1V1_2V65[] = { ++ {1100, 0x0}, ++ {1150, 0x1}, ++ {1200, 0x2}, ++ {1250, 0x3}, ++ {1300, 0x4}, ++ {1350, 0x5}, ++ {1400, 0x6}, ++ {1450, 0x7}, ++ {1500, 0x8}, ++ {1550, 0x9}, ++ {1600, 0xa}, ++ {1650, 0xb}, ++ {1700, 0xc}, ++ {1750, 0xd}, ++ {1800, 0xe}, ++ {1850, 0xf}, ++ {1900, 0x10}, ++ {1950, 0x11}, ++ {2000, 0x12}, ++ {2050, 0x13}, ++ {2100, 0x14}, ++ {2150, 0x15}, ++ {2200, 0x16}, ++ {2250, 0x17}, ++ {2300, 0x18}, ++ {2350, 0x19}, ++ {2400, 0x1a}, ++ {2450, 0x1b}, ++ {2500, 0x1c}, ++ {2550, 0x1d}, ++ {2600, 0x1e}, ++ {2650, 0x1f}, ++}; ++ ++struct da9030_vtg_value da9030_vtg_2V76_2V94[] = { ++ {2760, 0x7}, ++ {2790, 0x6}, ++ {2820, 0x5}, ++ {2850, 0x4}, ++ {2850, 0x3}, ++ {2880, 0x1}, ++ {2910, 0x2}, ++ {2940, 0x3}, ++}; ++ ++struct da9030_vtg_value da9030_vtg_0V85_1V625[] = { ++ {850, 0x0}, ++ {875, 0x1}, ++ {900, 0x2}, ++ {925, 0x3}, ++ {950, 0x4}, ++ {975, 0x5}, ++ {1000, 0x6}, ++ {1025, 0x7}, ++ {1050, 0x8}, ++ {1075, 0x9}, ++ {1100, 0xa}, ++ {1125, 0xb}, ++ {1150, 0xc}, ++ {1175, 0xd}, ++ {1200, 0xe}, ++ {1225, 0xf}, ++ {1250, 0x10}, ++ {1275, 0x11}, ++ {1300, 0x12}, ++ {1325, 0x13}, ++ {1350, 0x14}, ++ {1375, 0x15}, ++ {1400, 0x16}, ++ {1425, 0x17}, ++ {1450, 0x18}, ++ {1475, 0x19}, ++ {1500, 0x1a}, ++ {1525, 0x1b}, ++ {1550, 0x1c}, ++ {1575, 0x1d}, ++ {1600, 0x1e}, ++ {1625, 0x1f}, ++}; ++ ++struct ldo_param { ++ u8 reg; ++ u8 shift; ++ u8 bits; ++}; ++ ++struct da9030_ldo { ++ const char *name; ++ ++ struct ldo_param vtg; ++ struct ldo_param sleep; ++ struct ldo_param lock; ++ ++ /* several LDOs have two enable/disable bits */ ++ struct ldo_param enable[2]; ++ ++ struct da9030_vtg_value *values; ++ int values_count; ++}; ++ ++static struct da9030_ldo da9030_ldos[] = { ++ [0] = { ++ .name = "LDO1", ++ .vtg = { ++ .reg = LDO_1, ++ .shift = 0, ++ .bits = 5, ++ }, ++ .enable[0] = { ++ .reg = REG_CONTROL_1_97, ++ .shift = 1, ++ .bits = 1, ++ }, ++ .sleep = { ++ .reg = LDO_1, ++ .shift = 5, ++ .bits = 2, ++ }, ++ .lock = { ++ .reg = REG_SLEEP_CONTROL1, ++ .shift = 0, ++ .bits = 2, ++ }, ++ .values = da9030_vtg_1V8_3V2, ++ .values_count = ARRAY_SIZE(da9030_vtg_1V8_3V2), ++ }, ++ [1] = { ++ .name = "LDO2", ++ .vtg = { ++ .reg = LDO_2_3, ++ .shift = 0, ++ .bits = 4, ++ }, ++ .enable[0] = { ++ .reg = REG_CONTROL_1_97, ++ .shift = 2, ++ .bits = 1, ++ }, ++ .sleep = { ++ .reg = REG_SLEEP_CONTROL1, ++ .shift = 2, ++ .bits = 2, ++ }, ++ .values = da9030_vtg_1V8_3V2, ++ .values_count = ARRAY_SIZE(da9030_vtg_1V8_3V2), ++ }, ++ [2] = { ++ .name = "LDO3", ++ .vtg = { ++ .reg = LDO_2_3, ++ .shift = 4, ++ .bits = 4, ++ }, ++ .enable[0] = { ++ .reg = REG_CONTROL_1_97, ++ .shift = 3, ++ .bits = 1, ++ }, ++ .sleep = { ++ .reg = REG_SLEEP_CONTROL1, ++ .shift = 4, ++ .bits = 2, ++ }, ++ .values = da9030_vtg_1V8_3V2, ++ .values_count = ARRAY_SIZE(da9030_vtg_1V8_3V2), ++ }, ++ [3] = { ++ .name = "LDO4", ++ .vtg = { ++ .reg = LDO_4_5, ++ .shift = 0, ++ .bits = 4, ++ }, ++ .enable[0] = { ++ .reg = REG_CONTROL_1_97, ++ .shift = 4, ++ .bits = 1, ++ }, ++ .sleep = { ++ .reg = REG_SLEEP_CONTROL1, ++ .shift = 6, ++ .bits = 2, ++ }, ++ .values = da9030_vtg_1V8_3V2, ++ .values_count = ARRAY_SIZE(da9030_vtg_1V8_3V2), ++ }, ++ [4] = { ++ .name = "LDO5", ++ .vtg = { ++ .reg = LDO_4_5, ++ .shift = 4, ++ .bits = 4, ++ }, ++ .enable[0] = { ++ .reg = REG_CONTROL_1_97, ++ .shift = 5, ++ .bits = 1, ++ }, ++ .sleep = { ++ .reg = REG_SLEEP_CONTROL2, ++ .shift = 0, ++ .bits = 2, ++ }, ++ .values = da9030_vtg_1V8_3V2, ++ .values_count = ARRAY_SIZE(da9030_vtg_1V8_3V2), ++ }, ++ [5] = { ++ .name = "LDO6", ++ .vtg = { ++ .reg = LDO_6_SIMCP, ++ .shift = 0, ++ .bits = 4, ++ }, ++ .enable[0] = { ++ .reg = REG_CONTROL_1_97, ++ .shift = 6, ++ .bits = 1, ++ }, ++ .sleep = { ++ .reg = 0, ++ .shift = 0, ++ .bits = 0, ++ }, ++ .values = da9030_vtg_1V8_3V2, ++ .values_count = ARRAY_SIZE(da9030_vtg_1V8_3V2), ++ }, ++ [6] = { ++ .name = "LDO7", ++ .vtg = { ++ .reg = LDO_7_8, ++ .shift = 0, ++ .bits = 4, ++ }, ++ .enable[0] = { ++ .reg = REG_CONTROL_1_97, ++ .shift = 7, ++ .bits = 1, ++ }, ++ .sleep = { ++ .reg = REG_SLEEP_CONTROL2, ++ .shift = 2, ++ .bits = 2, ++ }, ++ .values = da9030_vtg_1V8_3V2, ++ .values_count = ARRAY_SIZE(da9030_vtg_1V8_3V2), ++ }, ++ [7] = { ++ .name = "LDO8", ++ .vtg = { ++ .reg = LDO_7_8, ++ .shift = 4, ++ .bits = 4, ++ }, ++ .enable[0] = { ++ .reg = REG_CONTROL_2_98, ++ .shift = 0, ++ .bits = 1, ++ }, ++ .sleep = { ++ .reg = REG_SLEEP_CONTROL2, ++ .shift = 4, ++ .bits = 2, ++ }, ++ .values = da9030_vtg_1V8_3V2, ++ .values_count = ARRAY_SIZE(da9030_vtg_1V8_3V2), ++ }, ++ [8] = { ++ .name = "LDO9", ++ .vtg = { ++ .reg = LDO_9_12, ++ .shift = 0, ++ .bits = 4, ++ }, ++ .enable[0] = { ++ .reg = REG_CONTROL_2_98, ++ .shift = 1, ++ .bits = 1, ++ }, ++ .sleep = { ++ .reg = REG_SLEEP_CONTROL2, ++ .shift = 6, ++ .bits = 2, ++ }, ++ .values = da9030_vtg_1V8_3V2, ++ .values_count = ARRAY_SIZE(da9030_vtg_1V8_3V2), ++ }, ++ [9] = { ++ .name = "LDO10", ++ .vtg = { ++ .reg = LDO_10_11, ++ .shift = 0, ++ .bits = 4, ++ }, ++ .enable[0] = { ++ .reg = REG_CONTROL_1_17, ++ .shift = 1, ++ .bits = 1, ++ }, ++ .enable[1] = { ++ .reg = REG_CONTROL_2_98, ++ .shift = 2, ++ .bits = 1, ++ }, ++ .sleep = { ++ .reg = 0, ++ .shift = 0, ++ .bits = 0, ++ }, ++ .values = da9030_vtg_1V8_3V2, ++ .values_count = ARRAY_SIZE(da9030_vtg_1V8_3V2), ++ }, ++ [10] = { ++ .name = "LDO11", ++ .vtg = { ++ .reg = LDO_10_11, ++ .shift = 4, ++ .bits = 4, ++ }, ++ .enable[0] = { ++ .reg = REG_CONTROL_1_17, ++ .shift = 2, ++ .bits = 1, ++ }, ++ .enable[1] = { ++ .reg = REG_CONTROL_2_98, ++ .shift = 3, ++ .bits = 1, ++ }, ++ .sleep = { ++ .reg = 0, ++ .shift = 0, ++ .bits = 0, ++ }, ++ .values = da9030_vtg_1V8_3V2, ++ .values_count = ARRAY_SIZE(da9030_vtg_1V8_3V2), ++ }, ++ [11] = { ++ .name = "LDO12", ++ .vtg = { ++ .reg = LDO_9_12, ++ .shift = 4, ++ .bits = 4, ++ }, ++ .enable[0] = { ++ .reg = REG_CONTROL_2_98, ++ .shift = 4, ++ .bits = 1, ++ }, ++ .sleep = { ++ .reg = REG_SLEEP_CONTROL3, ++ .shift = 0, ++ .bits = 2, ++ }, ++ .values = da9030_vtg_1V8_3V2, ++ .values_count = ARRAY_SIZE(da9030_vtg_1V8_3V2), ++ }, ++ [12] = { ++ .name = "LDO13", ++ .vtg = { ++ .reg = 0, ++ .shift = 0, ++ .bits = 0, ++ }, ++ .enable[0] = { ++ .reg = REG_CONTROL_1_17, ++ .shift = 3, ++ .bits = 1, ++ }, ++ .sleep = { ++ .reg = 0, ++ .shift = 0, ++ .bits = 0, ++ }, ++ .values = NULL, ++ .values_count = 0, ++ }, ++ [13] = { ++ .name = "LDO14", ++ .vtg = { ++ .reg = LDO_14_16, ++ .shift = 0, ++ .bits = 3, ++ }, ++ .enable[0] = { ++ .reg = REG_CONTROL_1_17, /* FIXME: or 2_98? */ ++ .shift = 4, ++ .bits = 1, ++ }, ++ .enable[1] = { ++ .reg = REG_CONTROL_2_98, /* FIXME: or 2_98? */ ++ .shift = 5, ++ .bits = 1, ++ }, ++ .sleep = { ++ .reg = 0, ++ .shift = 0, ++ .bits = 0, ++ }, ++ .values = da9030_vtg_2V76_2V94, ++ .values_count = ARRAY_SIZE(da9030_vtg_2V76_2V94), ++ }, ++ [14] = { ++ .name = "LDO15", ++ .vtg = { ++ .reg = LDO_15, ++ .shift = 0, ++ .bits = 5, ++ }, ++ .enable[0] = { ++ .reg = REG_CONTROL_1_17, ++ .shift = 5, ++ .bits = 1, ++ }, ++ .sleep = { ++ .reg = 0, ++ .shift = 0, ++ .bits = 0, ++ }, ++ .lock = { ++ .reg = LDO_15, ++ .shift = 5, ++ .bits = 3, ++ }, ++ .values = da9030_vtg_1V1_2V65, ++ .values_count = ARRAY_SIZE(da9030_vtg_1V1_2V65), ++ }, ++ [15] = { ++ .name = "LDO16", ++ .vtg = { ++ .reg = LDO_14_16, ++ .shift = 3, ++ .bits = 5, ++ }, ++ .enable[0] = { ++ .reg = REG_CONTROL_1_17, ++ .shift = 6, ++ .bits = 1, ++ }, ++ .sleep = { ++ .reg = 0, ++ .shift = 0, ++ .bits = 0, ++ }, ++ .values = da9030_vtg_1V1_2V65, ++ .values_count = ARRAY_SIZE(da9030_vtg_1V1_2V65), ++ }, ++ [16] = { ++ .name = "LDO17", ++ .vtg = { ++ .reg = LDO_17_SIMCP0, ++ .shift = 0, ++ .bits = 4, ++ }, ++ .enable[0] = { ++ .reg = REG_CONTROL_1_17, ++ .shift = 7, ++ .bits = 1, ++ }, ++ .sleep = { ++ .reg = 0, ++ .shift = 0, ++ .bits = 0, ++ }, ++ .values = da9030_vtg_1V8_3V2, ++ .values_count = ARRAY_SIZE(da9030_vtg_1V8_3V2), ++ }, ++ [17] = { ++ .name = "LDO18", ++ .vtg = { ++ .reg = LDO_18_19, ++ .shift = 0, ++ .bits = 4, ++ }, ++ .enable[0] = { ++ .reg = REG_CONTROL_2_18, ++ .shift = 2, ++ .bits = 1, ++ }, ++ .sleep = { ++ .reg = 0, ++ .shift = 0, ++ .bits = 0, ++ }, ++ .values = da9030_vtg_1V8_3V2, ++ .values_count = ARRAY_SIZE(da9030_vtg_1V8_3V2), ++ }, ++ [18] = { ++ .name = "LDO19", ++ .vtg = { ++ .reg = LDO_18_19, ++ .shift = 4, ++ .bits = 4, ++ }, ++ .enable[0] = { ++ .reg = REG_CONTROL_2_18, ++ .shift = 1, ++ .bits = 1, ++ }, ++ .sleep = { ++ .reg = 0, ++ .shift = 0, ++ .bits = 0, ++ }, ++ .values = da9030_vtg_1V8_3V2, ++ .values_count = ARRAY_SIZE(da9030_vtg_1V8_3V2), ++ }, ++}; ++ ++static int da9030_get_vtg_value(int vtg, const struct da9030_vtg_value *tbl, ++ int n) ++{ ++ int i; ++ ++ for (i = 0; i < n; i++, tbl++) ++ if (tbl->vtg == vtg) ++ return tbl->val; ++ return -EINVAL; ++} ++ ++static int da9030_set_ldo_volt(struct da9030_ldo *ldo, unsigned int mV) ++{ ++ int val; ++ ++ val = da9030_get_vtg_value(mV, ldo->values, ldo->values_count); ++ if (val < 0) ++ return val; ++ ++ return da9030_update_reg_bits(ldo->vtg.reg, ldo->vtg.bits, ++ ldo->vtg.shift, val); ++} ++ ++static int da9030_enable_ldo(struct da9030_ldo *ldo, int enable) ++{ ++ int ret; ++ ++ ret = da9030_update_reg_bits(ldo->enable[0].reg, ldo->enable[1].bits, ++ ldo->enable[0].shift, enable); ++ ++ if (ret < 0) ++ return ret; ++ ++ if (unlikely(ldo->enable[1].reg != 0)) ++ ret = da9030_update_reg_bits(ldo->enable[1].reg, ++ ldo->enable[1].bits, ++ ldo->enable[1].shift, enable); ++ ++ return ret; ++} ++ ++static int da9030_set_ldo_sleep(struct da9030_ldo *ldo, ++ enum da9030_ldo_sleep_mode sleep_mode) ++{ ++ return da9030_update_reg_bits(ldo->sleep.reg, ldo->sleep.bits, ++ ldo->sleep.shift, sleep_mode); ++} ++ ++int da9030_set_ldo(int ldo_num, int on, unsigned int mV, ++ enum da9030_ldo_sleep_mode sleep_mode) ++{ ++ struct da9030_ldo *ldo; ++ int ret; ++ ++ if (ldo_num < 0 || ldo_num > ARRAY_SIZE(da9030_ldos)) ++ return -EINVAL; ++ ++ ldo = &da9030_ldos[ldo_num]; ++ ++ ret = da9030_set_ldo_volt(ldo, mV); ++ if (ret < 0) ++ return ret; ++ ++ ret = da9030_enable_ldo(ldo, on); ++ if (ret < 0) ++ return ret; ++ ++ ret = da9030_set_ldo_sleep(ldo, sleep_mode); ++ if (ret < 0) ++ return ret; ++ ++ return 0; ++} ++EXPORT_SYMBOL(da9030_set_ldo); ++ ++int da9030_set_buck(int buck, int on, unsigned int mV, int flags) ++{ ++ /* FIXME: implement */ ++ return 0; ++} ++EXPORT_SYMBOL(da9030_set_buck); ++ ++static void da9030_disable_irq(unsigned int irq) ++{ ++ int reg, val; ++ ++ if (irq < 8) { ++ reg = IRQ_MASK_A; ++ val = 1 << irq; ++ } else if (irq < 16) { ++ reg = IRQ_MASK_B; ++ val = 1 << (irq - 8); ++ } else { ++ reg = IRQ_MASK_C; ++ val = 1 << (irq - 16); ++ } ++ ++ i2c_smbus_write_byte_data( ++ the_da9030->client, reg, ++ i2c_smbus_read_byte_data(the_da9030->client, reg) | val); ++} ++ ++static void da9030_enable_irq(unsigned int irq) ++{ ++ int reg, val; ++ ++ if (irq < 8) { ++ reg = IRQ_MASK_A; ++ val = 1 << irq; ++ } else if (irq < 16) { ++ reg = IRQ_MASK_B; ++ val = 1 << (irq - 8); ++ } else { ++ reg = IRQ_MASK_C; ++ val = 1 << (irq - 16); ++ } ++ ++ i2c_smbus_write_byte_data( ++ the_da9030->client, reg, ++ i2c_smbus_read_byte_data(the_da9030->client, reg) & ~val); ++} ++ ++int da9030_register_callback(int event, ++ void (*callback)(int event, void *data), ++ void *data) ++{ ++ int ret; ++ ++ if (event < 0 || event > 23) ++ return -EINVAL; ++ ++ mutex_lock(&the_da9030->lock); ++ if (the_da9030->callbacks[event]) ++ ret = -EBUSY; ++ else { ++ the_da9030->callbacks[event] = callback; ++ the_da9030->callbacks_data[event] = data; ++ da9030_enable_irq(event); ++ ret = 0; ++ } ++ mutex_unlock(&the_da9030->lock); ++ ++ return ret; ++} ++EXPORT_SYMBOL(da9030_register_callback); ++ ++void da9030_unregister_callback(int event) ++{ ++ mutex_lock(&the_da9030->lock); ++ ++ da9030_disable_irq(event); ++ the_da9030->callbacks[event] = NULL; ++ the_da9030->callbacks_data[event] = 0; ++ ++ mutex_unlock(&the_da9030->lock); ++} ++EXPORT_SYMBOL(da9030_unregister_callback); ++ ++#ifdef CONFIG_DEBUG_FS ++#define MAX_BUF 256 ++ ++static int da9030_debug_show(struct seq_file *s, void *data) ++{ ++ int i, res = 0; ++ struct da9030 *da9030 = s->private; ++ struct i2c_client *client = da9030->client; ++ ++ seq_printf(s, "DA9030 state: da = %p, cl = %p, s->private = %p\n", ++ da9030, client, s->private); ++ ++ for (i = 0; i < ARRAY_SIZE(defined_regs); i++) { ++ res = i2c_smbus_read_byte_data(client, defined_regs[i]); ++ seq_printf(s, "%02x %x\n", defined_regs[i], res); ++ } ++ return 0; ++} ++ ++static int da9030_debug_open(struct inode *inode, struct file *file) ++{ ++ return single_open(file, da9030_debug_show, inode->i_private); ++} ++ ++ssize_t da9030_debug_write(struct file *f, const char __user *buf, size_t len, ++ loff_t *off) ++{ ++ char buffer[MAX_BUF]; ++ int reg, val; ++ char *endp; ++ struct da9030 *da9030 = ((struct seq_file *)f->private_data)->private; ++ struct i2c_client *client = da9030->client; ++ ++ if (len > MAX_BUF) { ++ printk(KERN_INFO "%s: large buffer\n", __FUNCTION__); ++ len = MAX_BUF; ++ } ++ ++ if (copy_from_user(buffer, buf, len)) { ++ printk(KERN_INFO "%s: copy_from_user failed\n", __FUNCTION__); ++ return -EFAULT; ++ } ++ buffer[len] = '\0'; ++ ++ reg = simple_strtoul(buffer, &endp, 0); ++ while (endp && isspace(*endp)) ++ endp++; ++ ++ val = simple_strtoul(endp, 0, 0); ++ ++ i2c_smbus_write_byte_data(client, reg, val); ++ ++ return len; ++} ++ ++static const struct file_operations debug_fops = { ++ .open = da9030_debug_open, ++ .read = seq_read, ++ .write = da9030_debug_write, ++ .llseek = seq_lseek, ++ .release = single_release, ++}; ++ ++static struct dentry *da9030_create_debugfs(struct da9030 *da9030) ++{ ++ da9030->debug_file = debugfs_create_file("da9030", 0666, 0, da9030, ++ &debug_fops); ++ return da9030->debug_file; ++} ++ ++static void da9030_remove_debugfs(struct da9030 *da9030) ++{ ++ debugfs_remove(da9030->debug_file); ++} ++#else ++#define da9030_create_debugfs(x) NULL ++#define da9030_remove_debugfs(x) do {} while (0) ++#endif ++ ++static irqreturn_t da9030_irq(int irq, void *_da9030) ++{ ++ struct da9030 *da9030 = _da9030; ++ ++ (void)schedule_work(&da9030->event_work); ++ ++ return IRQ_HANDLED; ++} ++ ++static void da9030_irq_worker(struct work_struct *work) ++{ ++ struct da9030 *da9030 = container_of(work, struct da9030, event_work); ++ void (*callback)(int event, void *data); ++ u32 pending = 0; ++ u32 mask = 0; ++ int i; ++ ++ while (1) { ++ pending = (i2c_smbus_read_byte_data(da9030->client, ++ EVENT_A)) | ++ ((i2c_smbus_read_byte_data(da9030->client, ++ EVENT_B)) << 8) | ++ ((i2c_smbus_read_byte_data(da9030->client, ++ EVENT_C)) << 16); ++ ++ mask = (i2c_smbus_read_byte_data(da9030->client, ++ IRQ_MASK_A)) | ++ ((i2c_smbus_read_byte_data(da9030->client, ++ IRQ_MASK_B)) << 8) | ++ ((i2c_smbus_read_byte_data(da9030->client, ++ IRQ_MASK_C)) << 16); ++ pending &= ~mask; ++ ++ if (!pending) ++ return; ++ ++ while (pending) { ++ i = __ffs(pending); ++ callback = da9030->callbacks[i]; ++ if (callback) ++ callback(i, da9030->callbacks_data[i]); ++ pending &= ~(1 << i); ++ } ++ } ++} ++ ++static inline void da9030_disable_interrupts(struct da9030 *da9030) ++{ ++ /* clear pending interruts */ ++ (void)i2c_smbus_read_byte_data(da9030->client, EVENT_A); ++ (void)i2c_smbus_read_byte_data(da9030->client, EVENT_B); ++ (void)i2c_smbus_read_byte_data(da9030->client, EVENT_C); ++ ++ /* disable interrupts */ ++ i2c_smbus_write_byte_data(da9030->client, IRQ_MASK_A, 0xff); ++ i2c_smbus_write_byte_data(da9030->client, IRQ_MASK_B, 0xff); ++ i2c_smbus_write_byte_data(da9030->client, IRQ_MASK_C, 0xff); ++} ++ ++static int da9030_probe(struct i2c_client *client) ++{ ++ int ret; ++ struct da9030 *da9030; ++ ++ if (the_da9030) { ++ dev_dbg(&client->dev, "only one %s for now\n", ++ DRIVER_NAME); ++ return -ENODEV; ++ } ++ ++ ret = i2c_smbus_read_byte_data(client, CHIP_ID); ++ ++ dev_info(&client->dev, "initialized chip revision %x\n", ret); ++ ++ da9030 = kzalloc(sizeof(struct da9030), GFP_KERNEL); ++ if (da9030 == NULL) { ++ dev_err(&client->dev, "insufficient memory\n"); ++ return -ENOMEM; ++ } ++ the_da9030 = da9030; ++ da9030->client = client; ++ ++ mutex_init(&the_da9030->lock); ++ ++ da9030_disable_interrupts(da9030); ++ INIT_WORK(&da9030->event_work, da9030_irq_worker); ++ ++ ret = request_irq(client->irq, da9030_irq, ++ IRQF_DISABLED, DRIVER_NAME, da9030); ++ ++ if (ret) { ++ kfree(da9030); ++ dev_err(&client->dev, ++ "failed to allocate irq %d\n", ++ client->irq); ++ return ret; ++ } ++ ++ i2c_set_clientdata(client, da9030); ++ ++ da9030->debug_file = da9030_create_debugfs(da9030); ++ ++ return 0; ++} ++ ++/* static int da9030_detach_adapter(struct i2c_adapter *a) */ ++static int da9030_remove(struct i2c_client *client) ++{ ++ struct da9030 *da9030 = i2c_get_clientdata(client); ++ ++ da9030_remove_debugfs(da9030); ++ ++ free_irq(da9030->client->irq, da9030); ++ kfree(da9030); ++ i2c_set_clientdata(client, NULL); ++ the_da9030 = NULL; ++ ++ return 0; ++} ++ ++static struct i2c_driver da9030_driver = { ++ .driver = { ++ .name = "da9030", ++ .owner = THIS_MODULE, ++ }, ++ ++ .probe = da9030_probe, ++ .remove = da9030_remove, ++}; ++ ++static int da9030_init(void) ++{ ++ i2c_add_driver(&da9030_driver); ++ return 0; ++} ++ ++static void da9030_exit(void) ++{ ++ i2c_del_driver(&da9030_driver); ++} ++ ++/* NOTE: this MUST be initialized before the other parts of the system ++ * that rely on it ... but after the i2c bus on which this relies. ++ * That is, much earlier than on PC-type systems, which don't often use ++ * I2C as a core system bus. ++ */ ++subsys_initcall(da9030_init); ++module_exit(da9030_exit); ++ ++MODULE_DESCRIPTION("DA9030 power manager driver"); ++MODULE_AUTHOR("Mike Rapoport, Compulab"); ++MODULE_LICENSE("GPL"); +diff --git a/drivers/i2c/chips/da9030.h b/drivers/i2c/chips/da9030.h +new file mode 100644 +index 0000000..4163156 +--- /dev/null ++++ b/drivers/i2c/chips/da9030.h +@@ -0,0 +1,282 @@ ++/* DA9030 Register definintions */ ++ ++#define CHIP_ID 0x00 ++ ++#define EVENT_A 0x01 ++#define EVENT_A_CHIOVER (1 << 7) ++#define EVENT_A_VBAT_MON_TXON (1 << 6) ++#define EVENT_A_VBAT_MON (1 << 5) ++#define EVENT_A_TBAT (1 << 4) ++#define EVENT_A_CHDET (1 << 3) ++#define EVENT_A_EXTON (1 << 2) ++#define EVENT_A_PWREN1 (1 << 1) ++#define EVENT_A_ONKEY_N (1 << 0) ++ ++#define EVENT_B 0x02 ++#define EVENT_B_WDOG_INT (1 << 7) ++#define EVENT_B_SRP_DETECT (1 << 6) ++#define EVENT_B_SESSION_VALID (1 << 5) ++#define EVENT_B_VBUS_VALID_4_0 (1 << 4) ++#define EVENT_B_VBUS_VALID_4_4 (1 << 3) ++#define EVENT_B_ADC_READY (1 << 2) ++#define EVENT_B_CCTO (1 << 1) ++#define EVENT_B_TCTO (1 << 0) ++ ++#define EVENT_C 0x03 ++#define EVENT_C_ADC_IN5 (1 << 7) ++#define EVENT_C_ADC_IN4 (1 << 6) ++#define EVENT_C_BUCK2 (1 << 5) ++#define EVENT_C_LDO19 (1 << 4) ++#define EVENT_C_LDO18 (1 << 3) ++#define EVENT_C_LDO17 (1 << 2) ++#define EVENT_C_LDO16 (1 << 1) ++#define EVENT_C_LDO15 (1 << 0) ++ ++#define STATUS 0x04 ++#define STATUS_MCLK_DETECT (1 << 7) ++#define STATUS_VBAT_MON_TXON (1 << 6) ++#define STATUS_VBAT_MON (1 << 5) ++#define STATUS_TBAT (1 << 4) ++#define STATUS_CHDET (1 << 3) ++#define STATUS_EXTON (1 << 2) ++#define STATUS_PWREN1 (1 << 1) ++#define STATUS_ONKEY_N (1 << 0) ++ ++#define IRQ_MASK_A 0x05 ++#define IRQ_MASK_A_CHIOVER (1 << 7) ++#define IRQ_MASK_A_VBAT_MON_TXON (1 << 6) ++#define IRQ_MASK_A_VBAT_MON (1 << 5) ++#define IRQ_MASK_A_TBAT (1 << 4) ++#define IRQ_MASK_A_CHDET (1 << 3) ++#define IRQ_MASK_A_EXTON (1 << 2) ++#define IRQ_MASK_A_PWREN1 (1 << 1) ++#define IRQ_MASK_A_ONKEY_N (1 << 0) ++ ++#define IRQ_MASK_B 0x06 ++#define IRQ_MASK_B_WDOG_INT (1 << 7) ++#define IRQ_MASK_B_SRP_DETECT (1 << 6) ++#define IRQ_MASK_B_SESSION_VALID (1 << 5) ++#define IRQ_MASK_B_VBUS_VALID_4_0 (1 << 4) ++#define IRQ_MASK_B_VBUS_VALID_4_4 (1 << 3) ++#define IRQ_MASK_B_ADC_READY (1 << 2) ++#define IRQ_MASK_B_CCTO (1 << 1) ++#define IRQ_MASK_B_TCTO (1 << 0) ++ ++#define IRQ_MASK_C 0x07 ++#define IRQ_MASK_C_ADC_IN5 (1 << 7) ++#define IRQ_MASK_C_ADC_IN4 (1 << 6) ++#define IRQ_MASK_C_BUCK2 (1 << 5) ++#define IRQ_MASK_C_LDO19 (1 << 4) ++#define IRQ_MASK_C_LDO18 (1 << 3) ++#define IRQ_MASK_C_LDO17 (1 << 2) ++#define IRQ_MASK_C_LDO16 (1 << 1) ++#define IRQ_MASK_C_LDO15 (1 << 0) ++ ++#define SYS_CTRL_A 0x08 ++#define SYS_CONTROL_A_SLEEP_N_PIN_ENABLE 0x1 ++#define SYS_CONTROL_A_SHUT_DOWN (1<<1) ++#define SYS_CONTROL_A_HWRES_ENABLE (1<<2) ++#define SYS_CONTROL_A_WDOG_ACTION (1<<3) ++#define SYS_CONTROL_A_WATCHDOG (1<<7) ++ ++#define SYS_CONTROL_B 0x09 ++#define SYS_CLTR_B_SLEEP_13MHZ_EN (1 << 4) ++#define SYS_CLTR_B_AUTO_CLK_SWITCH (1 << 3) ++ ++#define FAULT_LOG 0x0a ++#define FAULT_LOG_OVER_TEMP (1 << 7) ++#define FAULT_LOG_VBAT_OVER (1 << 4) ++ ++#define LDO_10_11 0x10 ++#define LDO_10_11_LDO10_3V (0xc) ++#define LDO_10_11_LDO11_3V2 (0xe << 4) ++ ++#define LDO_15 0x11 ++#define LDO_14_16 0x12 ++#define LDO_18_19 0x13 ++#define LDO_18_19_LDO18_3V2 (0xe) ++ ++#define LDO_17_SIMCP0 0x14 ++#define LDO_17_SIMCP0_LDO17_3V 0x0F ++ ++#define BUCK_2_DVC1 0x15 ++#define BUCK_2_GO (1 << 7) ++#define BUCK_2_SLEEP (1 << 6) ++#define BUCK_2_TRIM_1V5 (0x1a) ++ ++#define BUCK_2_DVC2 0x16 ++ ++#define REG_CONTROL_1_17 0x17 ++#define RC1_LDO17_EN (1 << 7) ++#define RC1_LDO16_EN (1 << 6) ++#define RC1_LDO15_EN (1 << 5) ++#define RC1_LDO14_EN (1 << 4) ++#define RC1_LDO13_EN (1 << 3) ++#define RC1_LDO11_EN (1 << 2) ++#define RC1_LDO10_EN (1 << 1) ++#define RC1_BUCK2_EN (1 << 0) ++ ++#define REG_CONTROL_2_18 0x18 ++#define RC2_SIMCP_EN (1 << 6) ++#define RC2_LDO19_EN (1 << 1) ++#define RC2_LDO18_EN (1 << 0) ++ ++#define REG_CONTROL_3_ ++ ++#define USBPUMP 0x19 ++#define USB_PUMP_EN_USBVEP (1 << 7) ++#define USB_PUMP_EN_USBVE (1 << 6) ++#define USB_PUMP_SPR_DETECT (1 << 5) ++#define USB_PUMP_SESSION_VALID (1 << 4) ++#define USB_PUMP_VBUS_VALID_4_0 (1 << 3) ++#define USB_PUMP_VBUS_VALID_4_4 (1 << 2) ++#define USB_PUMP_USBVEP (1 << 1) ++#define USB_PUMP_USBVE (1 << 0) ++ ++#define SLEEP_CONTROL 0x1a ++#define APP_SLEEP_CTL_PWR_EN (1 << 7) ++#define APP_SLEEP_CTL_SYS_EN (1 << 6) ++#define APP_SLEEP_CTL_BYPASS_LDO19 (1 << 2) ++#define APP_SLEEP_CTL_BYPASS_LDO18 (1 << 1) ++#define APP_SLEEP_CTL_BYPASS_LDO17 (1 << 0) ++ ++#define STARTUP_CONTROL 0x1b ++#define STARTUP_CTL_LDO11_PWR_SYS (1 << 3) ++#define STARTUP_CTL_LDO10_PWR_SYS (1 << 2) ++#define STARTUP_CTL_LDO11_START (1 << 1) ++#define STARTUP_CTL_LDO10_START (1 << 0) ++ ++#define LED_1_CONTROL 0x20 ++#define LED_2_CONTROL 0x21 ++#define LED_3_CONTROL 0x22 ++#define LED_4_CONTROL 0x23 ++#define LEDPC_CONTROL 0x24 ++#define LED_ENABLE (1 << 7) ++ ++#define WLED_CONTROL 0x25 ++#define WLED_CP_ENABLE (1 << 6) ++#define WLED_ISET_10 (3) ++ ++#define MISC_CONTROLA 0x26 ++#define MISC_CONTROLB 0x27 ++#define MISCB_SESSION_VALID_ENABLE (1 << 3) ++#define MISCB_USB_INT_RISING (1 << 2) ++#define MISCB_I2C_ADDRESS (1 << 1) ++#define MISCB_STARTUP_SEQUENCE (1 << 0) ++ ++#define CHARGE_CONTROL 0x28 ++#define CHRG_CHARGER_ENABLE (1 << 7) ++ ++#define CCTR_CONTROL 0x29 ++#define CCTR_SET_8MIN 0x01 ++ ++#define TCTR_CONTROL 0x2a ++#define CHARGE_PULSE 0x2b ++ ++#define ADC_MAN_CONTROL 0x30 ++ ++#define ADC_AUTO_CONTROL 0x31 ++#define ADC_IN5_EN (1 << 7) ++#define ADC_IN4_EN (1 << 6) ++#define ADC_TBAT_ENABLE (1 << 5) ++#define ADC_VBAT_IN_TXON (1 << 4) ++#define ADC_VCH_ENABLE (1 << 3) ++#define ADC_ICH_ENABLE (1 << 2) ++#define ADC_VBAT_ENABLE (1 << 1) ++#define ADC_AUTO_SLEEP_ENABLE (1 << 0) ++ ++#define VBATMON 0x32 ++#define VBATMONTXON 0x33 ++#define TBATHIGHP 0x34 ++#define TBATHIGHN 0x35 ++#define TBATLOW 0x36 ++#define ADC_IN4_MIN 0x37 ++#define ADC_IN4_MAX 0x38 ++#define ADC_IN5_MIN 0x39 ++#define ADC_IN5_MAX 0x3a ++ ++#define VBAT_RES 0x41 ++#define VBATMIN_RES 0x42 ++#define VBATMINTXON 0x43 ++#define ICHMAX_RES 0x44 ++#define ICHMIN_RES 0x45 ++#define ICHAVERAGE_RES 0x46 ++#define VCHMAX_RES 0x47 ++#define VCHMIN_RES 0x48 ++#define TBAT_RES 0x49 ++#define ADC_IN4_RES 0x4a ++#define ADC_IN5_RES 0x4b ++ ++#define LDO_1 0x90 ++#define LDO_1_UNLOCK (0x5 << 5) ++#define LDO_1_TRIM_3V (0x12) ++ ++#define LDO_2_3 0x91 ++#define LDO_2_3_LDO2_3V2 (0xe << 4) ++#define LDO_2_3_LDO3_3V (0xc) ++ ++#define LDO_4_5 0x92 ++#define LDO_6_SIMCP 0x93 ++#define LDO_6_SIMCP_LDO6_3V2 (0xe) ++ ++#define LDO_7_8 0x94 ++#define LDO_9_12 0x95 ++#define BUCK 0x96 ++#define REG_CONTROL_1_97 0x97 ++#define RC3_LDO7_EN (1 << 7) ++#define RC3_LDO6_EN (1 << 6) ++#define RC3_LDO5_EN (1 << 5) ++#define RC3_LDO4_EN (1 << 4) ++#define RC3_LDO3_EN (1 << 3) ++#define RC3_LDO2_EN (1 << 2) ++#define RC3_LDO1_EN (1 << 1) ++#define RC3_BUCK_EN (1 << 0) ++ ++#define REG_CONTROL_2_98 0x98 ++#define RC4_SLEEP (1 << 7) ++#define RC4_SIMCP_ENABLE (1 << 6) ++#define RC4_LDO14_EN (1 << 5) ++#define RC4_LDO12_EN (1 << 4) ++#define RC4_LDO11_EN (1 << 3) ++#define RC4_LDO10_EN (1 << 2) ++#define RC4_LDO9_EN (1 << 1) ++#define RC4_LDO8_EN (1 << 0) ++ ++#define REG_SLEEP_CONTROL1 0x99 ++#define REG_SLEEP_CONTROL2 0x9a ++#define REG_SLEEP_CONTROL3 0x9b ++ ++#define ADC_MAN_CONTROL_1 0xa0 ++#define ADC_DEBOUNCE_VBATMON_TXON (1 << 7) ++#define ADC_DEBOUNCE_VBATMON (1 << 6) ++#define ADC_TBATREF_ENABLE (1 << 5) ++#define ADC_LDO_INT_ENABLE (1 << 4) ++#define ADC_MAN_CONV (1 << 3) ++#define ADC_MUX_VBAT (0) ++ ++#define ADC_AUTO_CONTROL_1 0xa1 ++#define ADC_IN5_EN (1 << 7) ++#define ADC_IN4_EN (1 << 6) ++#define ADC_TBAT_ENABLE (1 << 5) ++#define ADC_VBAT_IN_TXON (1 << 4) ++#define ADC_VCH_ENABLE (1 << 3) ++#define ADC_ICH_ENABLE (1 << 2) ++#define ADC_VBAT_ENABLE (1 << 1) ++#define ADC_AUTO_SLEEP_ENABLE (1 << 0) ++ ++#define VBATMON_1 0xa2 ++#define VBATMONTXMON_1 0xa3 ++#define TBATHIGHP_1 0xa4 ++#define TBATHIGHN_1 0xa5 ++#define TBATLOW_1 0xa6 ++#define MAN_RES 0xb0 ++#define VBAT_RES_1 0xb1 ++#define VBATMIN_RES_1 0xb2 ++#define VBATMINTXON_RES 0xb3 ++#define ICHMAX_RES_1 0xb4 ++#define ICHMIN_RES_1 0xb5 ++#define ICHAVERAGE_RES_1 0xb6 ++#define VCHMAX_RES_1 0xb7 ++#define VCHMIN_RES_1 0xb8 ++#define TBAT_RES_1 0xb9 ++#define ADC_IN4_RES_1 0xba +diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig +index f929fcd..174ea2e 100644 +--- a/drivers/input/touchscreen/Kconfig ++++ b/drivers/input/touchscreen/Kconfig +@@ -126,6 +126,49 @@ config TOUCHSCREEN_HP600 + To compile this driver as a module, choose M here: the + module will be called hp680_ts_input. + ++config TOUCHSCREEN_WM97XX ++ tristate "Support for WM97xx AC97 touchscreen controllers" ++ depends AC97_BUS ++ ++choice ++ prompt "WM97xx codec type" ++ depends TOUCHSCREEN_WM97XX ++ ++config TOUCHSCREEN_WM9705 ++ bool "WM9705 Touchscreen interface support" ++ depends on TOUCHSCREEN_WM97XX ++ help ++ Say Y here if you have the wm9705 touchscreen. ++ ++ If unsure, say N. ++ ++ To compile this driver as a module, choose M here: the ++ module will be called wm9705. ++ ++config TOUCHSCREEN_WM9712 ++ bool "WM9712 Touchscreen interface support" ++ depends on TOUCHSCREEN_WM97XX ++ help ++ Say Y here if you have the wm9712 touchscreen. ++ ++ If unsure, say N. ++ ++ To compile this driver as a module, choose M here: the ++ module will be called wm9712. ++ ++config TOUCHSCREEN_WM9713 ++ bool "WM9713 Touchscreen interface support" ++ depends on TOUCHSCREEN_WM97XX ++ help ++ Say Y here if you have the wm9713 touchscreen. ++ ++ If unsure, say N. ++ ++ To compile this driver as a module, choose M here: the ++ module will be called wm9713. ++ ++endchoice ++ + config TOUCHSCREEN_PENMOUNT + tristate "Penmount serial touchscreen" + select SERIO +diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile +index 5de8933..3a059b1 100644 +--- a/drivers/input/touchscreen/Makefile ++++ b/drivers/input/touchscreen/Makefile +@@ -3,6 +3,7 @@ + # + + # Each configuration option enables a list of files. ++wm97xx-ts-objs := wm97xx-core.o + + obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o + obj-$(CONFIG_TOUCHSCREEN_BITSY) += h3600_ts_input.o +@@ -18,3 +19,16 @@ obj-$(CONFIG_TOUCHSCREEN_PENMOUNT) += penmount.o + obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT) += touchright.o + obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN) += touchwin.o + obj-$(CONFIG_TOUCHSCREEN_UCB1400) += ucb1400_ts.o ++obj-$(CONFIG_TOUCHSCREEN_WM97XX) += wm97xx-ts.o ++ ++ifeq ($(CONFIG_TOUCHSCREEN_WM9713),y) ++wm97xx-ts-objs += wm9713.o ++endif ++ ++ifeq ($(CONFIG_TOUCHSCREEN_WM9712),y) ++wm97xx-ts-objs += wm9712.o ++endif ++ ++ifeq ($(CONFIG_TOUCHSCREEN_WM9705),y) ++wm97xx-ts-objs += wm9705.o ++endif +diff --git a/drivers/input/touchscreen/wm9705.c b/drivers/input/touchscreen/wm9705.c +new file mode 100644 +index 0000000..1dae63d +--- /dev/null ++++ b/drivers/input/touchscreen/wm9705.c +@@ -0,0 +1,360 @@ ++/* ++ * wm9705.c -- Codec driver for Wolfson WM9705 AC97 Codec. ++ * ++ * Copyright 2003, 2004, 2005, 2006 Wolfson Microelectronics PLC. ++ * Author: Liam Girdwood ++ * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com ++ * Parts Copyright : Ian Molton <spyro@f2s.com> ++ * Andrew Zabolotny <zap@homelink.ru> ++ * Russell King <rmk@arm.linux.org.uk> ++ * ++ * 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. ++ * ++ * Revision history ++ * 6th Sep 2006 Mike Arthur <linux@wolfsonmicro.com> ++ * Added pre and post sample calls. ++ * ++ */ ++ ++#include <linux/module.h> ++#include <linux/moduleparam.h> ++#include <linux/version.h> ++#include <linux/kernel.h> ++#include <linux/input.h> ++#include <linux/delay.h> ++#include <linux/bitops.h> ++#include <linux/wm97xx.h> ++ ++#define TS_NAME "wm97xx" ++#define WM9705_VERSION "0.62" ++#define DEFAULT_PRESSURE 0xb0c0 ++ ++/* ++ * Debug ++ */ ++#if 0 ++#define dbg(format, arg...) printk(KERN_DEBUG TS_NAME ": " format "\n" , ## arg) ++#else ++#define dbg(format, arg...) ++#endif ++#define err(format, arg...) printk(KERN_ERR TS_NAME ": " format "\n" , ## arg) ++#define info(format, arg...) printk(KERN_INFO TS_NAME ": " format "\n" , ## arg) ++#define warn(format, arg...) printk(KERN_WARNING TS_NAME ": " format "\n" , ## arg) ++ ++/* ++ * Module parameters ++ */ ++ ++/* ++ * Set current used for pressure measurement. ++ * ++ * Set pil = 2 to use 400uA ++ * pil = 1 to use 200uA and ++ * pil = 0 to disable pressure measurement. ++ * ++ * This is used to increase the range of values returned by the adc ++ * when measureing touchpanel pressure. ++ */ ++static int pil = 0; ++module_param(pil, int, 0); ++MODULE_PARM_DESC(pil, "Set current used for pressure measurement."); ++ ++/* ++ * Set threshold for pressure measurement. ++ * ++ * Pen down pressure below threshold is ignored. ++ */ ++static int pressure = DEFAULT_PRESSURE & 0xfff; ++module_param(pressure, int, 0); ++MODULE_PARM_DESC(pressure, "Set threshold for pressure measurement."); ++ ++/* ++ * Set adc sample delay. ++ * ++ * For accurate touchpanel measurements, some settling time may be ++ * required between the switch matrix applying a voltage across the ++ * touchpanel plate and the ADC sampling the signal. ++ * ++ * This delay can be set by setting delay = n, where n is the array ++ * position of the delay in the array delay_table below. ++ * Long delays > 1ms are supported for completeness, but are not ++ * recommended. ++ */ ++static int delay = 4; ++module_param(delay, int, 0); ++MODULE_PARM_DESC(delay, "Set adc sample delay."); ++ ++/* ++ * Pen detect comparator threshold. ++ * ++ * 0 to Vmid in 15 steps, 0 = use zero power comparator with Vmid threshold ++ * i.e. 1 = Vmid/15 threshold ++ * 15 = Vmid/1 threshold ++ * ++ * Adjust this value if you are having problems with pen detect not ++ * detecting any down events. ++ */ ++static int pdd = 8; ++module_param(pdd, int, 0); ++MODULE_PARM_DESC(pdd, "Set pen detect comparator threshold"); ++ ++/* ++ * Set adc mask function. ++ * ++ * Sources of glitch noise, such as signals driving an LCD display, may feed ++ * through to the touch screen plates and affect measurement accuracy. In ++ * order to minimise this, a signal may be applied to the MASK pin to delay or ++ * synchronise the sampling. ++ * ++ * 0 = No delay or sync ++ * 1 = High on pin stops conversions ++ * 2 = Edge triggered, edge on pin delays conversion by delay param (above) ++ * 3 = Edge triggered, edge on pin starts conversion after delay param ++ */ ++static int mask = 0; ++module_param(mask, int, 0); ++MODULE_PARM_DESC(mask, "Set adc mask function."); ++ ++/* ++ * ADC sample delay times in uS ++ */ ++static const int delay_table[] = { ++ 21, // 1 AC97 Link frames ++ 42, // 2 ++ 84, // 4 ++ 167, // 8 ++ 333, // 16 ++ 667, // 32 ++ 1000, // 48 ++ 1333, // 64 ++ 2000, // 96 ++ 2667, // 128 ++ 3333, // 160 ++ 4000, // 192 ++ 4667, // 224 ++ 5333, // 256 ++ 6000, // 288 ++ 0 // No delay, switch matrix always on ++}; ++ ++/* ++ * Delay after issuing a POLL command. ++ * ++ * The delay is 3 AC97 link frames + the touchpanel settling delay ++ */ ++static inline void poll_delay(int d) ++{ ++ udelay (3 * AC97_LINK_FRAME + delay_table [d]); ++} ++ ++/* ++ * set up the physical settings of the WM9705 ++ */ ++static void init_wm9705_phy(struct wm97xx* wm) ++{ ++ u16 dig1 = 0, dig2 = WM97XX_RPR; ++ ++ /* ++ * mute VIDEO and AUX as they share X and Y touchscreen ++ * inputs on the WM9705 ++ */ ++ wm97xx_reg_write(wm, AC97_AUX, 0x8000); ++ wm97xx_reg_write(wm, AC97_VIDEO, 0x8000); ++ ++ /* touchpanel pressure current*/ ++ if (pil == 2) { ++ dig2 |= WM9705_PIL; ++ dbg("setting pressure measurement current to 400uA."); ++ } else if (pil) ++ dbg("setting pressure measurement current to 200uA."); ++ if(!pil) ++ pressure = 0; ++ ++ /* polling mode sample settling delay */ ++ if (delay!=4) { ++ if (delay < 0 || delay > 15) { ++ dbg("supplied delay out of range."); ++ delay = 4; ++ } ++ } ++ dig1 &= 0xff0f; ++ dig1 |= WM97XX_DELAY(delay); ++ dbg("setting adc sample delay to %d u Secs.", delay_table[delay]); ++ ++ /* WM9705 pdd */ ++ dig2 |= (pdd & 0x000f); ++ dbg("setting pdd to Vmid/%d", 1 - (pdd & 0x000f)); ++ ++ /* mask */ ++ dig2 |= ((mask & 0x3) << 4); ++ ++ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, dig1); ++ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, dig2); ++} ++ ++static int wm9705_digitiser_ioctl(struct wm97xx* wm, int cmd) ++{ ++ switch(cmd) { ++ case WM97XX_DIG_START: ++ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, wm->dig[2] | WM97XX_PRP_DET_DIG); ++ wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); /* dummy read */ ++ break; ++ case WM97XX_DIG_STOP: ++ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, wm->dig[2] & ~WM97XX_PRP_DET_DIG); ++ break; ++ case WM97XX_AUX_PREPARE: ++ memcpy(wm->dig_save, wm->dig, sizeof(wm->dig)); ++ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, 0); ++ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, WM97XX_PRP_DET_DIG); ++ break; ++ case WM97XX_DIG_RESTORE: ++ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, wm->dig_save[1]); ++ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, wm->dig_save[2]); ++ break; ++ case WM97XX_PHY_INIT: ++ init_wm9705_phy(wm); ++ break; ++ default: ++ return -EINVAL; ++ } ++ return 0; ++} ++ ++static inline int is_pden (struct wm97xx* wm) ++{ ++ return wm->dig[2] & WM9705_PDEN; ++} ++ ++/* ++ * Read a sample from the WM9705 adc in polling mode. ++ */ ++static int wm9705_poll_sample (struct wm97xx* wm, int adcsel, int *sample) ++{ ++ int timeout = 5 * delay; ++ ++ if (!wm->pen_probably_down) { ++ u16 data = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); ++ if (!(data & WM97XX_PEN_DOWN)) ++ return RC_PENUP; ++ wm->pen_probably_down = 1; ++ } ++ ++ /* set up digitiser */ ++ if (adcsel & 0x8000) ++ adcsel = ((adcsel & 0x7fff) + 3) << 12; ++ ++ if (wm->mach_ops && wm->mach_ops->pre_sample) ++ wm->mach_ops->pre_sample(adcsel); ++ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, adcsel | WM97XX_POLL | WM97XX_DELAY(delay)); ++ ++ /* wait 3 AC97 time slots + delay for conversion */ ++ poll_delay (delay); ++ ++ /* wait for POLL to go low */ ++ while ((wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER1) & WM97XX_POLL) && timeout) { ++ udelay(AC97_LINK_FRAME); ++ timeout--; ++ } ++ ++ if (timeout <= 0) { ++ /* If PDEN is set, we can get a timeout when pen goes up */ ++ if (is_pden(wm)) ++ wm->pen_probably_down = 0; ++ else ++ dbg ("adc sample timeout"); ++ return RC_PENUP; ++ } ++ ++ *sample = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); ++ if (wm->mach_ops && wm->mach_ops->post_sample) ++ wm->mach_ops->post_sample(adcsel); ++ ++ /* check we have correct sample */ ++ if ((*sample & WM97XX_ADCSEL_MASK) != adcsel) { ++ dbg ("adc wrong sample, read %x got %x", adcsel, ++ *sample & WM97XX_ADCSEL_MASK); ++ return RC_PENUP; ++ } ++ ++ if (!(*sample & WM97XX_PEN_DOWN)) { ++ wm->pen_probably_down = 0; ++ return RC_PENUP; ++ } ++ ++ return RC_VALID; ++} ++ ++/* ++ * Sample the WM9705 touchscreen in polling mode ++ */ ++static int wm9705_poll_touch(struct wm97xx* wm, struct wm97xx_data *data) ++{ ++ int rc; ++ ++ if ((rc = wm9705_poll_sample(wm, WM97XX_ADCSEL_X, &data->x)) != RC_VALID) ++ return rc; ++ if ((rc = wm9705_poll_sample(wm, WM97XX_ADCSEL_Y, &data->y)) != RC_VALID) ++ return rc; ++ if (pil) { ++ if ((rc = wm9705_poll_sample(wm, WM97XX_ADCSEL_PRES, &data->p)) != RC_VALID) ++ return rc; ++ } else ++ data->p = DEFAULT_PRESSURE; ++ ++ return RC_VALID; ++} ++ ++/* ++ * Enable WM9705 continuous mode, i.e. touch data is streamed across an AC97 slot ++ */ ++static int wm9705_acc_enable (struct wm97xx* wm, int enable) ++{ ++ u16 dig1, dig2; ++ int ret = 0; ++ ++ dig1 = wm->dig[1]; ++ dig2 = wm->dig[2]; ++ ++ if (enable) { ++ /* continous mode */ ++ if (wm->mach_ops->acc_startup && (ret = wm->mach_ops->acc_startup(wm)) < 0) ++ return ret; ++ dig1 &= ~(WM97XX_CM_RATE_MASK | WM97XX_ADCSEL_MASK | ++ WM97XX_DELAY_MASK | WM97XX_SLT_MASK); ++ dig1 |= WM97XX_CTC | WM97XX_COO | WM97XX_SLEN | ++ WM97XX_DELAY (delay) | ++ WM97XX_SLT (wm->acc_slot) | ++ WM97XX_RATE (wm->acc_rate); ++ if (pil) ++ dig1 |= WM97XX_ADCSEL_PRES; ++ dig2 |= WM9705_PDEN; ++ } else { ++ dig1 &= ~(WM97XX_CTC | WM97XX_COO | WM97XX_SLEN); ++ dig2 &= ~WM9705_PDEN; ++ if (wm->mach_ops->acc_shutdown) ++ wm->mach_ops->acc_shutdown(wm); ++ } ++ ++ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, dig1); ++ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, dig2); ++ return ret; ++} ++ ++struct wm97xx_codec_drv wm97xx_codec = { ++ .id = WM9705_ID2, ++ .name = "wm9705", ++ .poll_sample = wm9705_poll_sample, ++ .poll_touch = wm9705_poll_touch, ++ .acc_enable = wm9705_acc_enable, ++ .digitiser_ioctl = wm9705_digitiser_ioctl, ++}; ++ ++EXPORT_SYMBOL_GPL(wm97xx_codec); ++ ++/* Module information */ ++MODULE_AUTHOR("Liam Girdwood, liam.girdwood@wolfsonmicro.com, www.wolfsonmicro.com"); ++MODULE_DESCRIPTION("WM9705 Touch Screen Driver"); ++MODULE_LICENSE("GPL"); +diff --git a/drivers/input/touchscreen/wm9712.c b/drivers/input/touchscreen/wm9712.c +new file mode 100644 +index 0000000..99433e9 +--- /dev/null ++++ b/drivers/input/touchscreen/wm9712.c +@@ -0,0 +1,464 @@ ++/* ++ * wm9712.c -- Codec driver for Wolfson WM9712 AC97 Codecs. ++ * ++ * Copyright 2003, 2004, 2005, 2006 Wolfson Microelectronics PLC. ++ * Author: Liam Girdwood ++ * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com ++ * Parts Copyright : Ian Molton <spyro@f2s.com> ++ * Andrew Zabolotny <zap@homelink.ru> ++ * Russell King <rmk@arm.linux.org.uk> ++ * ++ * 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. ++ * ++ * Revision history ++ * 4th Jul 2005 Initial version. ++ * 6th Sep 2006 Mike Arthur <linux@wolfsonmicro.com> ++ * Added pre and post sample calls. ++ * ++ */ ++ ++#include <linux/module.h> ++#include <linux/moduleparam.h> ++#include <linux/version.h> ++#include <linux/kernel.h> ++#include <linux/input.h> ++#include <linux/delay.h> ++#include <linux/bitops.h> ++#include <linux/wm97xx.h> ++ ++#define TS_NAME "wm97xx" ++#define WM9712_VERSION "0.61" ++#define DEFAULT_PRESSURE 0xb0c0 ++ ++/* ++ * Debug ++ */ ++#if 0 ++#define dbg(format, arg...) printk(KERN_DEBUG TS_NAME ": " format "\n" , ## arg) ++#else ++#define dbg(format, arg...) ++#endif ++#define err(format, arg...) printk(KERN_ERR TS_NAME ": " format "\n" , ## arg) ++#define info(format, arg...) printk(KERN_INFO TS_NAME ": " format "\n" , ## arg) ++#define warn(format, arg...) printk(KERN_WARNING TS_NAME ": " format "\n" , ## arg) ++ ++/* ++ * Module parameters ++ */ ++ ++/* ++ * Set internal pull up for pen detect. ++ * ++ * Pull up is in the range 1.02k (least sensitive) to 64k (most sensitive) ++ * i.e. pull up resistance = 64k Ohms / rpu. ++ * ++ * Adjust this value if you are having problems with pen detect not ++ * detecting any down event. ++ */ ++static int rpu = 8; ++module_param(rpu, int, 0); ++MODULE_PARM_DESC(rpu, "Set internal pull up resitor for pen detect."); ++ ++/* ++ * Set current used for pressure measurement. ++ * ++ * Set pil = 2 to use 400uA ++ * pil = 1 to use 200uA and ++ * pil = 0 to disable pressure measurement. ++ * ++ * This is used to increase the range of values returned by the adc ++ * when measureing touchpanel pressure. ++ */ ++static int pil = 0; ++module_param(pil, int, 0); ++MODULE_PARM_DESC(pil, "Set current used for pressure measurement."); ++ ++/* ++ * Set threshold for pressure measurement. ++ * ++ * Pen down pressure below threshold is ignored. ++ */ ++static int pressure = DEFAULT_PRESSURE & 0xfff; ++module_param(pressure, int, 0); ++MODULE_PARM_DESC(pressure, "Set threshold for pressure measurement."); ++ ++/* ++ * Set adc sample delay. ++ * ++ * For accurate touchpanel measurements, some settling time may be ++ * required between the switch matrix applying a voltage across the ++ * touchpanel plate and the ADC sampling the signal. ++ * ++ * This delay can be set by setting delay = n, where n is the array ++ * position of the delay in the array delay_table below. ++ * Long delays > 1ms are supported for completeness, but are not ++ * recommended. ++ */ ++static int delay = 3; ++module_param(delay, int, 0); ++MODULE_PARM_DESC(delay, "Set adc sample delay."); ++ ++/* ++ * Set five_wire = 1 to use a 5 wire touchscreen. ++ * ++ * NOTE: Five wire mode does not allow for readback of pressure. ++ */ ++static int five_wire; ++module_param(five_wire, int, 0); ++MODULE_PARM_DESC(five_wire, "Set to '1' to use 5-wire touchscreen."); ++ ++/* ++ * Set adc mask function. ++ * ++ * Sources of glitch noise, such as signals driving an LCD display, may feed ++ * through to the touch screen plates and affect measurement accuracy. In ++ * order to minimise this, a signal may be applied to the MASK pin to delay or ++ * synchronise the sampling. ++ * ++ * 0 = No delay or sync ++ * 1 = High on pin stops conversions ++ * 2 = Edge triggered, edge on pin delays conversion by delay param (above) ++ * 3 = Edge triggered, edge on pin starts conversion after delay param ++ */ ++static int mask = 0; ++module_param(mask, int, 0); ++MODULE_PARM_DESC(mask, "Set adc mask function."); ++ ++/* ++ * Coordinate Polling Enable. ++ * ++ * Set to 1 to enable coordinate polling. e.g. x,y[,p] is sampled together ++ * for every poll. ++ */ ++static int coord = 0; ++module_param(coord, int, 0); ++MODULE_PARM_DESC(coord, "Polling coordinate mode"); ++ ++/* ++ * ADC sample delay times in uS ++ */ ++static const int delay_table[] = { ++ 21, // 1 AC97 Link frames ++ 42, // 2 ++ 84, // 4 ++ 167, // 8 ++ 333, // 16 ++ 667, // 32 ++ 1000, // 48 ++ 1333, // 64 ++ 2000, // 96 ++ 2667, // 128 ++ 3333, // 160 ++ 4000, // 192 ++ 4667, // 224 ++ 5333, // 256 ++ 6000, // 288 ++ 0 // No delay, switch matrix always on ++}; ++ ++/* ++ * Delay after issuing a POLL command. ++ * ++ * The delay is 3 AC97 link frames + the touchpanel settling delay ++ */ ++static inline void poll_delay(int d) ++{ ++ udelay (3 * AC97_LINK_FRAME + delay_table [d]); ++} ++ ++/* ++ * set up the physical settings of the WM9712 ++ */ ++static void init_wm9712_phy(struct wm97xx* wm) ++{ ++ u16 dig1 = 0; ++ u16 dig2 = WM97XX_RPR | WM9712_RPU(1); ++ ++ /* WM9712 rpu */ ++ if (rpu) { ++ dig2 &= 0xffc0; ++ dig2 |= WM9712_RPU(rpu); ++ dbg("setting pen detect pull-up to %d Ohms",64000 / rpu); ++ } ++ ++ /* touchpanel pressure current*/ ++ if (pil == 2) { ++ dig2 |= WM9712_PIL; ++ dbg("setting pressure measurement current to 400uA."); ++ } else if (pil) ++ dbg("setting pressure measurement current to 200uA."); ++ if(!pil) ++ pressure = 0; ++ ++ /* WM9712 five wire */ ++ if (five_wire) { ++ dig2 |= WM9712_45W; ++ dbg("setting 5-wire touchscreen mode."); ++ } ++ ++ /* polling mode sample settling delay */ ++ if (delay < 0 || delay > 15) { ++ dbg("supplied delay out of range."); ++ delay = 4; ++ } ++ dig1 &= 0xff0f; ++ dig1 |= WM97XX_DELAY(delay); ++ dbg("setting adc sample delay to %d u Secs.", delay_table[delay]); ++ ++ /* mask */ ++ dig2 |= ((mask & 0x3) << 6); ++ if (mask) { ++ u16 reg; ++ /* Set GPIO4 as Mask Pin*/ ++ reg = wm97xx_reg_read(wm, AC97_MISC_AFE); ++ wm97xx_reg_write(wm, AC97_MISC_AFE, reg | WM97XX_GPIO_4); ++ reg = wm97xx_reg_read(wm, AC97_GPIO_CFG); ++ wm97xx_reg_write(wm, AC97_GPIO_CFG, reg | WM97XX_GPIO_4); ++ } ++ ++ /* wait - coord mode */ ++ if(coord) ++ dig2 |= WM9712_WAIT; ++ ++ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, dig1); ++ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, dig2); ++} ++ ++static int wm9712_digitiser_ioctl(struct wm97xx* wm, int cmd) ++{ ++ u16 dig2 = wm->dig[2]; ++ ++ switch(cmd) { ++ case WM97XX_DIG_START: ++ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, dig2 | WM97XX_PRP_DET_DIG); ++ wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); /* dummy read */ ++ break; ++ case WM97XX_DIG_STOP: ++ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, dig2 & ~WM97XX_PRP_DET_DIG); ++ break; ++ case WM97XX_AUX_PREPARE: ++ memcpy(wm->dig_save, wm->dig, sizeof(wm->dig)); ++ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, 0); ++ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, WM97XX_PRP_DET_DIG); ++ break; ++ case WM97XX_DIG_RESTORE: ++ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, wm->dig_save[1]); ++ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, wm->dig_save[2]); ++ break; ++ case WM97XX_PHY_INIT: ++ init_wm9712_phy(wm); ++ break; ++ default: ++ return -EINVAL; ++ } ++ return 0; ++} ++ ++static inline int is_pden (struct wm97xx* wm) ++{ ++ return wm->dig[2] & WM9712_PDEN; ++} ++ ++/* ++ * Read a sample from the WM9712 adc in polling mode. ++ */ ++static int wm9712_poll_sample (struct wm97xx* wm, int adcsel, int *sample) ++{ ++ int timeout = 5 * delay; ++ ++ if (!wm->pen_probably_down) { ++ u16 data = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); ++ if (!(data & WM97XX_PEN_DOWN)) ++ return RC_PENUP; ++ wm->pen_probably_down = 1; ++ } ++ ++ /* set up digitiser */ ++ if (adcsel & 0x8000) ++ adcsel = ((adcsel & 0x7fff) + 3) << 12; ++ ++ if (wm->mach_ops && wm->mach_ops->pre_sample) ++ wm->mach_ops->pre_sample(adcsel); ++ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, adcsel | WM97XX_POLL | WM97XX_DELAY(delay)); ++ ++ /* wait 3 AC97 time slots + delay for conversion */ ++ poll_delay (delay); ++ ++ /* wait for POLL to go low */ ++ while ((wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER1) & WM97XX_POLL) && timeout) { ++ udelay(AC97_LINK_FRAME); ++ timeout--; ++ } ++ ++ if (timeout <= 0) { ++ /* If PDEN is set, we can get a timeout when pen goes up */ ++ if (is_pden(wm)) ++ wm->pen_probably_down = 0; ++ else ++ dbg ("adc sample timeout"); ++ return RC_PENUP; ++ } ++ ++ *sample = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); ++ if (wm->mach_ops && wm->mach_ops->post_sample) ++ wm->mach_ops->post_sample(adcsel); ++ ++ /* check we have correct sample */ ++ if ((*sample & WM97XX_ADCSEL_MASK) != adcsel) { ++ dbg ("adc wrong sample, read %x got %x", adcsel, ++ *sample & WM97XX_ADCSEL_MASK); ++ return RC_PENUP; ++ } ++ ++ if (!(*sample & WM97XX_PEN_DOWN)) { ++ wm->pen_probably_down = 0; ++ return RC_PENUP; ++ } ++ ++ return RC_VALID; ++} ++ ++/* ++ * Read a coord from the WM9712 adc in polling mode. ++ */ ++static int wm9712_poll_coord (struct wm97xx* wm, struct wm97xx_data *data) ++{ ++ int timeout = 5 * delay; ++ ++ if (!wm->pen_probably_down) { ++ u16 data = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); ++ if (!(data & WM97XX_PEN_DOWN)) ++ return RC_PENUP; ++ wm->pen_probably_down = 1; ++ } ++ ++ /* set up digitiser */ ++ if (wm->mach_ops && wm->mach_ops->pre_sample) ++ wm->mach_ops->pre_sample(WM97XX_ADCSEL_X | WM97XX_ADCSEL_Y); ++ ++ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, ++ WM97XX_COO | WM97XX_POLL | WM97XX_DELAY(delay)); ++ ++ /* wait 3 AC97 time slots + delay for conversion and read x */ ++ poll_delay(delay); ++ data->x = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); ++ /* wait for POLL to go low */ ++ while ((wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER1) & WM97XX_POLL) && timeout) { ++ udelay(AC97_LINK_FRAME); ++ timeout--; ++ } ++ ++ if (timeout <= 0) { ++ /* If PDEN is set, we can get a timeout when pen goes up */ ++ if (is_pden(wm)) ++ wm->pen_probably_down = 0; ++ else ++ dbg ("adc sample timeout"); ++ return RC_PENUP; ++ } ++ ++ /* read back y data */ ++ data->y = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); ++ if (pil) ++ data->p = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); ++ else ++ data->p = DEFAULT_PRESSURE; ++ ++ if (wm->mach_ops && wm->mach_ops->post_sample) ++ wm->mach_ops->post_sample(WM97XX_ADCSEL_X | WM97XX_ADCSEL_Y); ++ ++ /* check we have correct sample */ ++ if (!(data->x & WM97XX_ADCSEL_X) || !(data->y & WM97XX_ADCSEL_Y)) ++ goto err; ++ if(pil && !(data->p & WM97XX_ADCSEL_PRES)) ++ goto err; ++ ++ if (!(data->x & WM97XX_PEN_DOWN)) { ++ wm->pen_probably_down = 0; ++ return RC_PENUP; ++ } ++ return RC_VALID; ++err: ++ return RC_PENUP; ++} ++ ++/* ++ * Sample the WM9712 touchscreen in polling mode ++ */ ++static int wm9712_poll_touch(struct wm97xx* wm, struct wm97xx_data *data) ++{ ++ int rc; ++ ++ if(coord) { ++ if((rc = wm9712_poll_coord(wm, data)) != RC_VALID) ++ return rc; ++ } else { ++ if ((rc = wm9712_poll_sample(wm, WM97XX_ADCSEL_X, &data->x)) != RC_VALID) ++ return rc; ++ ++ if ((rc = wm9712_poll_sample(wm, WM97XX_ADCSEL_Y, &data->y)) != RC_VALID) ++ return rc; ++ ++ if (pil && !five_wire) { ++ if ((rc = wm9712_poll_sample(wm, WM97XX_ADCSEL_PRES, &data->p)) != RC_VALID) ++ return rc; ++ } else ++ data->p = DEFAULT_PRESSURE; ++ } ++ return RC_VALID; ++} ++ ++/* ++ * Enable WM9712 continuous mode, i.e. touch data is streamed across an AC97 slot ++ */ ++static int wm9712_acc_enable (struct wm97xx* wm, int enable) ++{ ++ u16 dig1, dig2; ++ int ret = 0; ++ ++ dig1 = wm->dig[1]; ++ dig2 = wm->dig[2]; ++ ++ if (enable) { ++ /* continous mode */ ++ if (wm->mach_ops->acc_startup && (ret = wm->mach_ops->acc_startup(wm)) < 0) ++ return ret; ++ dig1 &= ~(WM97XX_CM_RATE_MASK | WM97XX_ADCSEL_MASK | ++ WM97XX_DELAY_MASK | WM97XX_SLT_MASK); ++ dig1 |= WM97XX_CTC | WM97XX_COO | WM97XX_SLEN | ++ WM97XX_DELAY (delay) | ++ WM97XX_SLT (wm->acc_slot) | ++ WM97XX_RATE (wm->acc_rate); ++ if (pil) ++ dig1 |= WM97XX_ADCSEL_PRES; ++ dig2 |= WM9712_PDEN; ++ } else { ++ dig1 &= ~(WM97XX_CTC | WM97XX_COO | WM97XX_SLEN); ++ dig2 &= ~WM9712_PDEN; ++ if (wm->mach_ops->acc_shutdown) ++ wm->mach_ops->acc_shutdown(wm); ++ } ++ ++ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, dig1); ++ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, dig2); ++ return 0; ++} ++ ++struct wm97xx_codec_drv wm97xx_codec = { ++ .id = WM9712_ID2, ++ .name = "wm9712", ++ .poll_sample = wm9712_poll_sample, ++ .poll_touch = wm9712_poll_touch, ++ .acc_enable = wm9712_acc_enable, ++ .digitiser_ioctl = wm9712_digitiser_ioctl, ++}; ++ ++EXPORT_SYMBOL_GPL(wm97xx_codec); ++ ++/* Module information */ ++MODULE_AUTHOR("Liam Girdwood, liam.girdwood@wolfsonmicro.com, www.wolfsonmicro.com"); ++MODULE_DESCRIPTION("WM9712 Touch Screen Driver"); ++MODULE_LICENSE("GPL"); +diff --git a/drivers/input/touchscreen/wm9713.c b/drivers/input/touchscreen/wm9713.c +new file mode 100644 +index 0000000..42f5f30 +--- /dev/null ++++ b/drivers/input/touchscreen/wm9713.c +@@ -0,0 +1,461 @@ ++/* ++ * wm9713.c -- Codec touch driver for Wolfson WM9713 AC97 Codec. ++ * ++ * Copyright 2003, 2004, 2005, 2006 Wolfson Microelectronics PLC. ++ * Author: Liam Girdwood ++ * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com ++ * Parts Copyright : Ian Molton <spyro@f2s.com> ++ * Andrew Zabolotny <zap@homelink.ru> ++ * Russell King <rmk@arm.linux.org.uk> ++ * ++ * 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. ++ * ++ * Revision history ++ * 6th Sep 2006 Mike Arthur <linux@wolfsonmicro.com> ++ * Added pre and post sample calls. ++ * ++ */ ++ ++#include <linux/module.h> ++#include <linux/moduleparam.h> ++#include <linux/version.h> ++#include <linux/kernel.h> ++#include <linux/input.h> ++#include <linux/delay.h> ++#include <linux/bitops.h> ++#include <linux/wm97xx.h> ++ ++#define TS_NAME "wm97xx" ++#define WM9713_VERSION "0.53" ++#define DEFAULT_PRESSURE 0xb0c0 ++ ++/* ++ * Debug ++ */ ++#if 0 ++#define dbg(format, arg...) printk(KERN_DEBUG TS_NAME ": " format "\n" , ## arg) ++#else ++#define dbg(format, arg...) ++#endif ++#define err(format, arg...) printk(KERN_ERR TS_NAME ": " format "\n" , ## arg) ++#define info(format, arg...) printk(KERN_INFO TS_NAME ": " format "\n" , ## arg) ++#define warn(format, arg...) printk(KERN_WARNING TS_NAME ": " format "\n" , ## arg) ++ ++/* ++ * Module parameters ++ */ ++ ++/* ++ * Set internal pull up for pen detect. ++ * ++ * Pull up is in the range 1.02k (least sensitive) to 64k (most sensitive) ++ * i.e. pull up resistance = 64k Ohms / rpu. ++ * ++ * Adjust this value if you are having problems with pen detect not ++ * detecting any down event. ++ */ ++static int rpu = 8; ++module_param(rpu, int, 0); ++MODULE_PARM_DESC(rpu, "Set internal pull up resitor for pen detect."); ++ ++/* ++ * Set current used for pressure measurement. ++ * ++ * Set pil = 2 to use 400uA ++ * pil = 1 to use 200uA and ++ * pil = 0 to disable pressure measurement. ++ * ++ * This is used to increase the range of values returned by the adc ++ * when measureing touchpanel pressure. ++ */ ++static int pil = 0; ++module_param(pil, int, 0); ++MODULE_PARM_DESC(pil, "Set current used for pressure measurement."); ++ ++/* ++ * Set threshold for pressure measurement. ++ * ++ * Pen down pressure below threshold is ignored. ++ */ ++static int pressure = DEFAULT_PRESSURE & 0xfff; ++module_param(pressure, int, 0); ++MODULE_PARM_DESC(pressure, "Set threshold for pressure measurement."); ++ ++/* ++ * Set adc sample delay. ++ * ++ * For accurate touchpanel measurements, some settling time may be ++ * required between the switch matrix applying a voltage across the ++ * touchpanel plate and the ADC sampling the signal. ++ * ++ * This delay can be set by setting delay = n, where n is the array ++ * position of the delay in the array delay_table below. ++ * Long delays > 1ms are supported for completeness, but are not ++ * recommended. ++ */ ++static int delay = 4; ++module_param(delay, int, 0); ++MODULE_PARM_DESC(delay, "Set adc sample delay."); ++ ++/* ++ * Set adc mask function. ++ * ++ * Sources of glitch noise, such as signals driving an LCD display, may feed ++ * through to the touch screen plates and affect measurement accuracy. In ++ * order to minimise this, a signal may be applied to the MASK pin to delay or ++ * synchronise the sampling. ++ * ++ * 0 = No delay or sync ++ * 1 = High on pin stops conversions ++ * 2 = Edge triggered, edge on pin delays conversion by delay param (above) ++ * 3 = Edge triggered, edge on pin starts conversion after delay param ++ */ ++static int mask = 0; ++module_param(mask, int, 0); ++MODULE_PARM_DESC(mask, "Set adc mask function."); ++ ++/* ++ * Coordinate Polling Enable. ++ * ++ * Set to 1 to enable coordinate polling. e.g. x,y[,p] is sampled together ++ * for every poll. ++ */ ++static int coord = 0; ++module_param(coord, int, 0); ++MODULE_PARM_DESC(coord, "Polling coordinate mode"); ++ ++/* ++ * ADC sample delay times in uS ++ */ ++static const int delay_table[] = { ++ 21, // 1 AC97 Link frames ++ 42, // 2 ++ 84, // 4 ++ 167, // 8 ++ 333, // 16 ++ 667, // 32 ++ 1000, // 48 ++ 1333, // 64 ++ 2000, // 96 ++ 2667, // 128 ++ 3333, // 160 ++ 4000, // 192 ++ 4667, // 224 ++ 5333, // 256 ++ 6000, // 288 ++ 0 // No delay, switch matrix always on ++}; ++ ++/* ++ * Delay after issuing a POLL command. ++ * ++ * The delay is 3 AC97 link frames + the touchpanel settling delay ++ */ ++static inline void poll_delay(int d) ++{ ++ udelay (3 * AC97_LINK_FRAME + delay_table [d]); ++} ++ ++/* ++ * set up the physical settings of the WM9713 ++ */ ++static void init_wm9713_phy(struct wm97xx* wm) ++{ ++ u16 dig1 = 0, dig2, dig3; ++ ++ /* default values */ ++ dig2 = WM97XX_DELAY(4) | WM97XX_SLT(5); ++ dig3= WM9712_RPU(1); ++ ++ /* rpu */ ++ if (rpu) { ++ dig3 &= 0xffc0; ++ dig3 |= WM9712_RPU(rpu); ++ info("setting pen detect pull-up to %d Ohms",64000 / rpu); ++ } ++ ++ /* touchpanel pressure */ ++ if (pil == 2) { ++ dig3 |= WM9712_PIL; ++ info("setting pressure measurement current to 400uA."); ++ } else if (pil) ++ info ("setting pressure measurement current to 200uA."); ++ if(!pil) ++ pressure = 0; ++ ++ /* sample settling delay */ ++ if (delay < 0 || delay > 15) { ++ info ("supplied delay out of range."); ++ delay = 4; ++ info("setting adc sample delay to %d u Secs.", delay_table[delay]); ++ } ++ dig2 &= 0xff0f; ++ dig2 |= WM97XX_DELAY(delay); ++ ++ /* mask */ ++ dig3 |= ((mask & 0x3) << 4); ++ if(coord) ++ dig3 |= WM9713_WAIT; ++ ++ wm->misc = wm97xx_reg_read(wm, 0x5a); ++ ++ wm97xx_reg_write(wm, AC97_WM9713_DIG1, dig1); ++ wm97xx_reg_write(wm, AC97_WM9713_DIG2, dig2); ++ wm97xx_reg_write(wm, AC97_WM9713_DIG3, dig3); ++ wm97xx_reg_write(wm, AC97_GPIO_STICKY, 0x0); ++} ++ ++static int wm9713_digitiser_ioctl(struct wm97xx* wm, int cmd) ++{ ++ u16 val = 0; ++ ++ switch(cmd){ ++ case WM97XX_DIG_START: ++ val = wm97xx_reg_read(wm, AC97_EXTENDED_MID); ++ wm97xx_reg_write(wm, AC97_EXTENDED_MID, val & 0x7fff); ++ wm97xx_reg_write(wm, AC97_WM9713_DIG3, wm->dig[2] | WM97XX_PRP_DET_DIG); ++ wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); /* dummy read */ ++ break; ++ case WM97XX_DIG_STOP: ++ wm97xx_reg_write(wm, AC97_WM9713_DIG3, wm->dig[2] & ~WM97XX_PRP_DET_DIG); ++ val = wm97xx_reg_read(wm, AC97_EXTENDED_MID); ++ wm97xx_reg_write(wm, AC97_EXTENDED_MID, val | 0x8000); ++ break; ++ case WM97XX_AUX_PREPARE: ++ memcpy(wm->dig_save, wm->dig, sizeof(wm->dig)); ++ wm97xx_reg_write(wm, AC97_WM9713_DIG1, 0); ++ wm97xx_reg_write(wm, AC97_WM9713_DIG2, 0); ++ wm97xx_reg_write(wm, AC97_WM9713_DIG3, WM97XX_PRP_DET_DIG); ++ break; ++ case WM97XX_DIG_RESTORE: ++ wm97xx_reg_write(wm, AC97_WM9713_DIG1, wm->dig_save[0]); ++ wm97xx_reg_write(wm, AC97_WM9713_DIG2, wm->dig_save[1]); ++ wm97xx_reg_write(wm, AC97_WM9713_DIG3, wm->dig_save[2]); ++ break; ++ case WM97XX_PHY_INIT: ++ init_wm9713_phy(wm); ++ break; ++ default: ++ return -EINVAL; ++ } ++ return 0; ++} ++ ++static inline int is_pden (struct wm97xx* wm) ++{ ++ return wm->dig[2] & WM9713_PDEN; ++} ++ ++/* ++ * Read a sample from the WM9713 adc in polling mode. ++ */ ++static int wm9713_poll_sample (struct wm97xx* wm, int adcsel, int *sample) ++{ ++ u16 dig1; ++ int timeout = 5 * delay; ++ ++ if (!wm->pen_probably_down) { ++ u16 data = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); ++ if (!(data & WM97XX_PEN_DOWN)) ++ return RC_PENUP; ++ wm->pen_probably_down = 1; ++ } ++ ++ /* set up digitiser */ ++ if (adcsel & 0x8000) ++ adcsel = 1 << ((adcsel & 0x7fff) + 3); ++ ++ dig1 = wm97xx_reg_read(wm, AC97_WM9713_DIG1); ++ dig1 &= ~WM9713_ADCSEL_MASK; ++ ++ if (wm->mach_ops && wm->mach_ops->pre_sample) ++ wm->mach_ops->pre_sample(adcsel); ++ wm97xx_reg_write(wm, AC97_WM9713_DIG1, dig1 | adcsel |WM9713_POLL); ++ ++ /* wait 3 AC97 time slots + delay for conversion */ ++ poll_delay(delay); ++ ++ /* wait for POLL to go low */ ++ while ((wm97xx_reg_read(wm, AC97_WM9713_DIG1) & WM9713_POLL) && timeout) { ++ udelay(AC97_LINK_FRAME); ++ timeout--; ++ } ++ ++ if (timeout <= 0) { ++ /* If PDEN is set, we can get a timeout when pen goes up */ ++ if (is_pden(wm)) ++ wm->pen_probably_down = 0; ++ else ++ dbg ("adc sample timeout"); ++ return RC_PENUP; ++ } ++ ++ *sample =wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); ++ if (wm->mach_ops && wm->mach_ops->post_sample) ++ wm->mach_ops->post_sample(adcsel); ++ ++ /* check we have correct sample */ ++ if ((*sample & WM97XX_ADCSRC_MASK) != ffs(adcsel >> 1) << 12) { ++ dbg ("adc wrong sample, read %x got %x", adcsel, ++ *sample & WM97XX_ADCSRC_MASK); ++ return RC_PENUP; ++ } ++ ++ if (!(*sample & WM97XX_PEN_DOWN)) { ++ wm->pen_probably_down = 0; ++ return RC_PENUP; ++ } ++ ++ return RC_VALID; ++} ++ ++/* ++ * Read a coordinate from the WM9713 adc in polling mode. ++ */ ++static int wm9713_poll_coord (struct wm97xx* wm, struct wm97xx_data *data) ++{ ++ u16 dig1; ++ int timeout = 5 * delay; ++ ++ if (!wm->pen_probably_down) { ++ u16 data = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); ++ if (!(data & WM97XX_PEN_DOWN)) ++ return RC_PENUP; ++ wm->pen_probably_down = 1; ++ } ++ ++ /* set up digitiser */ ++ dig1 = wm97xx_reg_read(wm, AC97_WM9713_DIG1); ++ dig1 &= ~WM9713_ADCSEL_MASK; ++ if(pil) ++ dig1 |= WM97XX_ADCSEL_PRES; ++ ++ if (wm->mach_ops && wm->mach_ops->pre_sample) ++ wm->mach_ops->pre_sample(WM97XX_ADCSEL_X | WM97XX_ADCSEL_Y); ++ wm97xx_reg_write(wm, AC97_WM9713_DIG1, dig1 | WM9713_POLL | WM9713_COO); ++ ++ /* wait 3 AC97 time slots + delay for conversion */ ++ poll_delay(delay); ++ data->x = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); ++ /* wait for POLL to go low */ ++ while ((wm97xx_reg_read(wm, AC97_WM9713_DIG1) & WM9713_POLL) && timeout) { ++ udelay(AC97_LINK_FRAME); ++ timeout--; ++ } ++ ++ if (timeout <= 0) { ++ /* If PDEN is set, we can get a timeout when pen goes up */ ++ if (is_pden(wm)) ++ wm->pen_probably_down = 0; ++ else ++ dbg ("adc sample timeout"); ++ return RC_PENUP; ++ } ++ ++ /* read back data */ ++ data->y = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); ++ if (pil) ++ data->p = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); ++ else ++ data->p = DEFAULT_PRESSURE; ++ ++ if (wm->mach_ops && wm->mach_ops->post_sample) ++ wm->mach_ops->post_sample(WM97XX_ADCSEL_X | WM97XX_ADCSEL_Y); ++ ++ /* check we have correct sample */ ++ if (!(data->x & WM97XX_ADCSEL_X) || !(data->y & WM97XX_ADCSEL_Y)) ++ goto err; ++ if(pil && !(data->p & WM97XX_ADCSEL_PRES)) ++ goto err; ++ ++ if (!(data->x & WM97XX_PEN_DOWN)) { ++ wm->pen_probably_down = 0; ++ return RC_PENUP; ++ } ++ return RC_VALID; ++err: ++ return RC_PENUP; ++} ++ ++/* ++ * Sample the WM9713 touchscreen in polling mode ++ */ ++static int wm9713_poll_touch(struct wm97xx* wm, struct wm97xx_data *data) ++{ ++ int rc; ++ ++ if(coord) { ++ if((rc = wm9713_poll_coord(wm, data)) != RC_VALID) ++ return rc; ++ } else { ++ if ((rc = wm9713_poll_sample(wm, WM9713_ADCSEL_X, &data->x)) != RC_VALID) ++ return rc; ++ if ((rc = wm9713_poll_sample(wm, WM9713_ADCSEL_Y, &data->y)) != RC_VALID) ++ return rc; ++ if (pil) { ++ if ((rc = wm9713_poll_sample(wm, WM9713_ADCSEL_PRES, &data->p)) != RC_VALID) ++ return rc; ++ } else ++ data->p = DEFAULT_PRESSURE; ++ } ++ return RC_VALID; ++} ++ ++/* ++ * Enable WM9713 continuous mode, i.e. touch data is streamed across an AC97 slot ++ */ ++static int wm9713_acc_enable (struct wm97xx* wm, int enable) ++{ ++ u16 dig1, dig2, dig3; ++ int ret = 0; ++ ++ dig1 = wm->dig[0]; ++ dig2 = wm->dig[1]; ++ dig3 = wm->dig[2]; ++ ++ if (enable) { ++ /* continous mode */ ++ if (wm->mach_ops->acc_startup && ++ (ret = wm->mach_ops->acc_startup(wm)) < 0) ++ return ret; ++ ++ dig1 &= ~WM9713_ADCSEL_MASK; ++ dig1 |= WM9713_CTC | WM9713_COO | WM9713_ADCSEL_X | WM9713_ADCSEL_Y; ++ if (pil) ++ dig1 |= WM9713_ADCSEL_PRES; ++ dig2 &= ~(WM97XX_DELAY_MASK | WM97XX_SLT_MASK | WM97XX_CM_RATE_MASK); ++ dig2 |= WM97XX_SLEN | WM97XX_DELAY (delay) | ++ WM97XX_SLT (wm->acc_slot) | WM97XX_RATE (wm->acc_rate); ++ dig3 |= WM9713_PDEN; ++ } else { ++ dig1 &= ~(WM9713_CTC | WM9713_COO); ++ dig2 &= ~WM97XX_SLEN; ++ dig3 &= ~WM9713_PDEN; ++ if (wm->mach_ops->acc_shutdown) ++ wm->mach_ops->acc_shutdown(wm); ++ } ++ ++ wm97xx_reg_write(wm, AC97_WM9713_DIG1, dig1); ++ wm97xx_reg_write(wm, AC97_WM9713_DIG2, dig2); ++ wm97xx_reg_write(wm, AC97_WM9713_DIG3, dig3); ++ return ret; ++} ++ ++struct wm97xx_codec_drv wm97xx_codec = { ++ .id = WM9713_ID2, ++ .name = "wm9713", ++ .poll_sample = wm9713_poll_sample, ++ .poll_touch = wm9713_poll_touch, ++ .acc_enable = wm9713_acc_enable, ++ .digitiser_ioctl = wm9713_digitiser_ioctl, ++}; ++ ++EXPORT_SYMBOL_GPL(wm97xx_codec); ++ ++/* Module information */ ++MODULE_AUTHOR("Liam Girdwood, liam.girdwood@wolfsonmicro.com, www.wolfsonmicro.com"); ++MODULE_DESCRIPTION("WM9713 Touch Screen Driver"); ++MODULE_LICENSE("GPL"); +diff --git a/drivers/input/touchscreen/wm97xx-core.c b/drivers/input/touchscreen/wm97xx-core.c +new file mode 100644 +index 0000000..87179d2 +--- /dev/null ++++ b/drivers/input/touchscreen/wm97xx-core.c +@@ -0,0 +1,859 @@ ++/* ++ * wm97xx-core.c -- Touch screen driver core for Wolfson WM9705, WM9712 ++ * and WM9713 AC97 Codecs. ++ * ++ * Copyright 2003, 2004, 2005, 2006 Wolfson Microelectronics PLC. ++ * Author: Liam Girdwood ++ * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com ++ * Parts Copyright : Ian Molton <spyro@f2s.com> ++ * Andrew Zabolotny <zap@homelink.ru> ++ * Russell King <rmk@arm.linux.org.uk> ++ * ++ * 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. ++ * ++ * Notes: ++ * ++ * Features: ++ * - supports WM9705, WM9712, WM9713 ++ * - polling mode ++ * - continuous mode (arch-dependent) ++ * - adjustable rpu/dpp settings ++ * - adjustable pressure current ++ * - adjustable sample settle delay ++ * - 4 and 5 wire touchscreens (5 wire is WM9712 only) ++ * - pen down detection ++ * - battery monitor ++ * - sample AUX adc's ++ * - power management ++ * - codec GPIO ++ * - codec event notification ++ * Todo ++ * - Support for async sampling control for noisy LCD's. ++ * ++ * Revision history ++ * 7th May 2003 Initial version. ++ * 6th June 2003 Added non module support and AC97 registration. ++ * 18th June 2003 Added AUX adc sampling. ++ * 23rd June 2003 Did some minimal reformatting, fixed a couple of ++ * codec_mutexing bugs and noted a race to fix. ++ * 24th June 2003 Added power management and fixed race condition. ++ * 10th July 2003 Changed to a misc device. ++ * 31st July 2003 Moved TS_EVENT and TS_CAL to wm97xx.h ++ * 8th Aug 2003 Added option for read() calling wm97xx_sample_touch() ++ * because some ac97_read/ac_97_write call schedule() ++ * 7th Nov 2003 Added Input touch event interface, stanley.cai@intel.com ++ * 13th Nov 2003 Removed h3600 touch interface, added interrupt based ++ * pen down notification and implemented continous mode ++ * on XScale arch. ++ * 16th Nov 2003 Ian Molton <spyro@f2s.com> ++ * Modified so that it suits the new 2.6 driver model. ++ * 25th Jan 2004 Andrew Zabolotny <zap@homelink.ru> ++ * Implemented IRQ-driven pen down detection, implemented ++ * the private API meant to be exposed to platform-specific ++ * drivers, reorganized the driver so that it supports ++ * an arbitrary number of devices. ++ * 1st Feb 2004 Moved continuous mode handling to a separate ++ * architecture-dependent file. For now only PXA ++ * built-in AC97 controller is supported (pxa-ac97-wm97xx.c). ++ * 11th Feb 2004 Reduced CPU usage by keeping a cached copy of both ++ * digitizer registers instead of reading them every time. ++ * A reorganization of the whole code for better ++ * error handling. ++ * 17th Apr 2004 Added BMON support. ++ * 17th Nov 2004 Added codec GPIO, codec event handling (real and virtual ++ * GPIOs) and 2.6 power management. ++ * 29th Nov 2004 Added WM9713 support. ++ * 4th Jul 2005 Moved codec specific code out to seperate files. ++ * 6th Sep 2006 Mike Arthur <linux@wolfsonmicro.com> ++ * Added bus interface. ++ */ ++ ++#include <linux/module.h> ++#include <linux/moduleparam.h> ++#include <linux/version.h> ++#include <linux/kernel.h> ++#include <linux/init.h> ++#include <linux/delay.h> ++#include <linux/string.h> ++#include <linux/proc_fs.h> ++#include <linux/pm.h> ++#include <linux/interrupt.h> ++#include <linux/bitops.h> ++#include <linux/workqueue.h> ++#include <linux/device.h> ++#include <linux/freezer.h> ++#include <linux/wm97xx.h> ++#include <asm/uaccess.h> ++#include <asm/io.h> ++ ++#include <asm/arch/irqs.h> ++ ++#define TS_NAME "wm97xx" ++#define WM_CORE_VERSION "0.64" ++#define DEFAULT_PRESSURE 0xb0c0 ++ ++ ++/* ++ * Touchscreen absolute values ++ * ++ * These parameters are used to help the input layer discard out of ++ * range readings and reduce jitter etc. ++ * ++ * o min, max:- indicate the min and max values your touch screen returns ++ * o fuzz:- use a higher number to reduce jitter ++ * ++ * The default values correspond to Mainstone II in QVGA mode ++ * ++ * Please read ++ * Documentation/input/input-programming.txt for more details. ++ */ ++ ++static int abs_x[3] = {350,3900,5}; ++module_param_array(abs_x, int, NULL, 0); ++MODULE_PARM_DESC(abs_x, "Touchscreen absolute X min, max, fuzz"); ++ ++static int abs_y[3] = {320,3750,40}; ++module_param_array(abs_y, int, NULL, 0); ++MODULE_PARM_DESC(abs_y, "Touchscreen absolute Y min, max, fuzz"); ++ ++static int abs_p[3] = {0,150,4}; ++module_param_array(abs_p, int, NULL, 0); ++MODULE_PARM_DESC(abs_p, "Touchscreen absolute Pressure min, max, fuzz"); ++ ++/* ++ * Debug ++ */ ++#if 0 ++#define dbg(format, arg...) printk(KERN_DEBUG TS_NAME ": " format "\n" , ## arg) ++#else ++#define dbg(format, arg...) ++#endif ++#define err(format, arg...) printk(KERN_ERR TS_NAME ": " format "\n" , ## arg) ++#define info(format, arg...) printk(KERN_INFO TS_NAME ": " format "\n" , ## arg) ++#define warn(format, arg...) printk(KERN_WARNING TS_NAME ": " format "\n" , ## arg) ++ ++/* ++ * wm97xx IO access, all IO locking done by AC97 layer ++ */ ++int wm97xx_reg_read(struct wm97xx *wm, u16 reg) ++{ ++ if (wm->ac97) ++ return wm->ac97->bus->ops->read(wm->ac97, reg); ++ else ++ return -1; ++} ++EXPORT_SYMBOL_GPL(wm97xx_reg_read); ++ ++void wm97xx_reg_write(struct wm97xx *wm, u16 reg, u16 val) ++{ ++ /* cache digitiser registers */ ++ if(reg >= AC97_WM9713_DIG1 && reg <= AC97_WM9713_DIG3) ++ wm->dig[(reg - AC97_WM9713_DIG1) >> 1] = val; ++ ++ /* cache gpio regs */ ++ if(reg >= AC97_GPIO_CFG && reg <= AC97_MISC_AFE) ++ wm->gpio[(reg - AC97_GPIO_CFG) >> 1] = val; ++ ++ /* wm9713 irq reg */ ++ if(reg == 0x5a) ++ wm->misc = val; ++ ++ if (wm->ac97) ++ wm->ac97->bus->ops->write(wm->ac97, reg, val); ++} ++EXPORT_SYMBOL_GPL(wm97xx_reg_write); ++ ++/** ++ * wm97xx_read_aux_adc - Read the aux adc. ++ * @wm: wm97xx device. ++ * @adcsel: codec ADC to be read ++ * ++ * Reads the selected AUX ADC. ++ */ ++ ++int wm97xx_read_aux_adc(struct wm97xx *wm, u16 adcsel) ++{ ++ int power_adc = 0, auxval; ++ u16 power = 0; ++ ++ /* get codec */ ++ mutex_lock(&wm->codec_mutex); ++ ++ /* When the touchscreen is not in use, we may have to power up the AUX ADC ++ * before we can use sample the AUX inputs-> ++ */ ++ if (wm->id == WM9713_ID2 && ++ (power = wm97xx_reg_read(wm, AC97_EXTENDED_MID)) & 0x8000) { ++ power_adc = 1; ++ wm97xx_reg_write(wm, AC97_EXTENDED_MID, power & 0x7fff); ++ } ++ ++ /* Prepare the codec for AUX reading */ ++ wm->codec->digitiser_ioctl(wm, WM97XX_AUX_PREPARE); ++ ++ /* Turn polling mode on to read AUX ADC */ ++ wm->pen_probably_down = 1; ++ wm->codec->poll_sample(wm, adcsel, &auxval); ++ ++ if (power_adc) ++ wm97xx_reg_write(wm, AC97_EXTENDED_MID, power | 0x8000); ++ ++ wm->codec->digitiser_ioctl(wm, WM97XX_DIG_RESTORE); ++ ++ wm->pen_probably_down = 0; ++ ++ mutex_unlock(&wm->codec_mutex); ++ return auxval & 0xfff; ++} ++EXPORT_SYMBOL_GPL(wm97xx_read_aux_adc); ++ ++/** ++ * wm97xx_get_gpio - Get the status of a codec GPIO. ++ * @wm: wm97xx device. ++ * @gpio: gpio ++ * ++ * Get the status of a codec GPIO pin ++ */ ++ ++wm97xx_gpio_status_t wm97xx_get_gpio(struct wm97xx *wm, u32 gpio) ++{ ++ u16 status; ++ wm97xx_gpio_status_t ret; ++ ++ mutex_lock(&wm->codec_mutex); ++ status = wm97xx_reg_read(wm, AC97_GPIO_STATUS); ++ ++ if (status & gpio) ++ ret = WM97XX_GPIO_HIGH; ++ else ++ ret = WM97XX_GPIO_LOW; ++ ++ mutex_unlock(&wm->codec_mutex); ++ return ret; ++} ++EXPORT_SYMBOL_GPL(wm97xx_get_gpio); ++ ++/** ++ * wm97xx_set_gpio - Set the status of a codec GPIO. ++ * @wm: wm97xx device. ++ * @gpio: gpio ++ * ++ * ++ * Set the status of a codec GPIO pin ++ */ ++ ++void wm97xx_set_gpio(struct wm97xx *wm, u32 gpio, ++ wm97xx_gpio_status_t status) ++{ ++ u16 reg; ++ ++ mutex_lock(&wm->codec_mutex); ++ reg = wm97xx_reg_read(wm, AC97_GPIO_STATUS); ++ ++ if (status & WM97XX_GPIO_HIGH) ++ reg |= gpio; ++ else ++ reg &= ~gpio; ++ ++ if (wm->id == WM9712_ID2) ++ wm97xx_reg_write(wm, AC97_GPIO_STATUS, reg << 1); ++ else ++ wm97xx_reg_write(wm, AC97_GPIO_STATUS, reg); ++ mutex_unlock(&wm->codec_mutex); ++} ++EXPORT_SYMBOL_GPL(wm97xx_set_gpio); ++ ++/* ++ * Codec GPIO pin configuration, this set's pin direction, polarity, ++ * stickyness and wake up. ++ */ ++void wm97xx_config_gpio(struct wm97xx *wm, u32 gpio, wm97xx_gpio_dir_t dir, ++ wm97xx_gpio_pol_t pol, wm97xx_gpio_sticky_t sticky, ++ wm97xx_gpio_wake_t wake) ++{ ++ u16 reg; ++ ++ mutex_lock(&wm->codec_mutex); ++ reg = wm97xx_reg_read(wm, AC97_GPIO_POLARITY); ++ ++ if (pol == WM97XX_GPIO_POL_HIGH) ++ reg |= gpio; ++ else ++ reg &= ~gpio; ++ ++ wm97xx_reg_write(wm, AC97_GPIO_POLARITY, reg); ++ reg = wm97xx_reg_read(wm, AC97_GPIO_STICKY); ++ ++ if (sticky == WM97XX_GPIO_STICKY) ++ reg |= gpio; ++ else ++ reg &= ~gpio; ++ ++ wm97xx_reg_write(wm, AC97_GPIO_STICKY, reg); ++ reg = wm97xx_reg_read(wm, AC97_GPIO_WAKEUP); ++ ++ if (wake == WM97XX_GPIO_WAKE) ++ reg |= gpio; ++ else ++ reg &= ~gpio; ++ ++ wm97xx_reg_write(wm, AC97_GPIO_WAKEUP, reg); ++ reg = wm97xx_reg_read(wm, AC97_GPIO_CFG); ++ ++ if (dir == WM97XX_GPIO_IN) ++ reg |= gpio; ++ else ++ reg &= ~gpio; ++ ++ wm97xx_reg_write(wm, AC97_GPIO_CFG, reg); ++ mutex_unlock(&wm->codec_mutex); ++} ++EXPORT_SYMBOL_GPL(wm97xx_config_gpio); ++ ++/* ++ * Handle a pen down interrupt. ++ */ ++static void wm97xx_pen_irq_worker(struct work_struct *w) ++{ ++/* struct wm97xx *wm = (struct wm97xx *) ptr; */ ++ struct wm97xx *wm = container_of(w, struct wm97xx, pen_event_work); ++ ++ /* do we need to enable the touch panel reader */ ++ if (wm->id == WM9705_ID2) { ++ if (wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD) & WM97XX_PEN_DOWN) ++ wm->pen_is_down = 1; ++ else ++ wm->pen_is_down = 0; ++ wake_up_interruptible(&wm->pen_irq_wait); ++ } else { ++ u16 status, pol; ++ mutex_lock(&wm->codec_mutex); ++ status = wm97xx_reg_read(wm, AC97_GPIO_STATUS); ++ pol = wm97xx_reg_read(wm, AC97_GPIO_POLARITY); ++ ++ if (WM97XX_GPIO_13 & pol & status) { ++ wm->pen_is_down = 1; ++ wm97xx_reg_write(wm, AC97_GPIO_POLARITY, pol & ~WM97XX_GPIO_13); ++ } else { ++ wm->pen_is_down = 0; ++ wm97xx_reg_write(wm, AC97_GPIO_POLARITY, pol | WM97XX_GPIO_13); ++ } ++ ++ if (wm->id == WM9712_ID2) ++ wm97xx_reg_write(wm, AC97_GPIO_STATUS, (status & ~WM97XX_GPIO_13) << 1); ++ else ++ wm97xx_reg_write(wm, AC97_GPIO_STATUS, status & ~WM97XX_GPIO_13); ++ mutex_unlock(&wm->codec_mutex); ++ wake_up_interruptible(&wm->pen_irq_wait); ++ } ++ ++ if (!wm->pen_is_down && wm->mach_ops && wm->mach_ops->acc_enabled) ++ wm->mach_ops->acc_pen_up(wm); ++ enable_irq(wm->pen_irq); ++} ++ ++/* ++ * Codec PENDOWN irq handler ++ * ++ * We have to disable the codec interrupt in the handler because it can ++ * take upto 1ms to clear the interrupt source. The interrupt is then enabled ++ * again in the slow handler when the source has been cleared. ++ */ ++static irqreturn_t wm97xx_pen_interrupt(int irq, void *dev_id) ++{ ++ struct wm97xx *wm = (struct wm97xx *) dev_id; ++ disable_irq(wm->pen_irq); ++ queue_work(wm->pen_irq_workq, &wm->pen_event_work); ++ return IRQ_HANDLED; ++} ++ ++/* ++ * initialise pen IRQ handler and workqueue ++ */ ++static int wm97xx_init_pen_irq(struct wm97xx *wm) ++{ ++ u16 reg; ++ ++ INIT_WORK(&wm->pen_event_work, wm97xx_pen_irq_worker/* , wm */); ++ if ((wm->pen_irq_workq = ++ create_singlethread_workqueue("kwm97pen")) == NULL) { ++ err("could not create pen irq work queue"); ++ wm->pen_irq = 0; ++ return -EINVAL; ++ } ++ ++ ++ wm->pen_irq = IRQ_GPIO(90); ++ if (request_irq (wm->pen_irq, wm97xx_pen_interrupt, SA_SHIRQ, "wm97xx-pen", wm)) { ++ err("could not register codec pen down interrupt, will poll for pen down"); ++ destroy_workqueue(wm->pen_irq_workq); ++ wm->pen_irq = 0; ++ return -EINVAL; ++ } ++ ++ /* enable PEN down on wm9712/13 */ ++ if (wm->id != WM9705_ID2) { ++ reg = wm97xx_reg_read(wm, AC97_MISC_AFE); ++ wm97xx_reg_write(wm, AC97_MISC_AFE, reg & 0xfffb); ++ reg = wm97xx_reg_read(wm, 0x5a); ++ wm97xx_reg_write(wm, 0x5a, reg & ~0x0001); ++ } ++ ++ return 0; ++} ++ ++/* Private struct for communication between struct wm97xx_tshread ++ * and wm97xx_read_samples */ ++struct ts_state { ++ int sleep_time; ++ int min_sleep_time; ++}; ++ ++static int wm97xx_read_samples(struct wm97xx *wm, struct ts_state *state) ++{ ++ struct wm97xx_data data; ++ int rc; ++ ++ mutex_lock(&wm->codec_mutex); ++ ++ if (wm->mach_ops && wm->mach_ops->acc_enabled) ++ rc = wm->mach_ops->acc_pen_down(wm); ++ else ++ rc = wm->codec->poll_touch(wm, &data); ++ ++ if (rc & RC_PENUP) { ++ if (wm->pen_is_down) { ++ wm->pen_is_down = 0; ++ dbg("pen up"); ++ input_report_abs(wm->input_dev, ABS_PRESSURE, 0); ++ input_sync(wm->input_dev); ++ } else if (!(rc & RC_AGAIN)) { ++ /* We need high frequency updates only while pen is down, ++ * the user never will be able to touch screen faster than ++ * a few times per second... On the other hand, when the ++ * user is actively working with the touchscreen we don't ++ * want to lose the quick response. So we will slowly ++ * increase sleep time after the pen is up and quicky ++ * restore it to ~one task switch when pen is down again. ++ */ ++ if (state->sleep_time < HZ / 10) ++ state->sleep_time++; ++ } ++ ++ } else if (rc & RC_VALID) { ++ dbg("pen down: x=%x:%d, y=%x:%d, pressure=%x:%d\n", ++ data.x >> 12, data.x & 0xfff, data.y >> 12, ++ data.y & 0xfff, data.p >> 12, data.p & 0xfff); ++ input_report_abs(wm->input_dev, ABS_X, data.x & 0xfff); ++ input_report_abs(wm->input_dev, ABS_Y, data.y & 0xfff); ++ input_report_abs(wm->input_dev, ABS_PRESSURE, data.p & 0xfff); ++ input_sync(wm->input_dev); ++ wm->pen_is_down = 1; ++ state->sleep_time = state->min_sleep_time; ++ } else if (rc & RC_PENDOWN) { ++ dbg("pen down"); ++ wm->pen_is_down = 1; ++ state->sleep_time = state->min_sleep_time; ++ } ++ ++ mutex_unlock(&wm->codec_mutex); ++ return rc; ++} ++ ++/* ++* The touchscreen sample reader thread. ++*/ ++static int wm97xx_ts_read(void *data) ++{ ++ int rc; ++ struct ts_state state; ++ struct wm97xx *wm = (struct wm97xx *) data; ++ ++ /* set up thread context */ ++ wm->ts_task = current; ++ daemonize("kwm97xxts"); ++ ++ if (wm->codec == NULL) { ++ wm->ts_task = NULL; ++ printk(KERN_ERR "codec is NULL, bailing\n"); ++ } ++ ++ complete(&wm->ts_init); ++ wm->pen_is_down = 0; ++ state.min_sleep_time = HZ >= 100 ? HZ / 100 : 1; ++ if (state.min_sleep_time < 1) ++ state.min_sleep_time = 1; ++ state.sleep_time = state.min_sleep_time; ++ ++ /* touch reader loop */ ++ while (wm->ts_task) { ++ do { ++ try_to_freeze(); ++ rc = wm97xx_read_samples(wm, &state); ++ } while (rc & RC_AGAIN); ++ if (!wm->pen_is_down && wm->pen_irq) { ++ /* Nice, we don't have to poll for pen down event */ ++ wait_event_interruptible(wm->pen_irq_wait, wm->pen_is_down); ++ } else { ++ set_task_state(current, TASK_INTERRUPTIBLE); ++ schedule_timeout(state.sleep_time); ++ } ++ } ++ complete_and_exit(&wm->ts_exit, 0); ++} ++ ++/** ++ * wm97xx_ts_input_open - Open the touch screen input device. ++ * @idev: Input device to be opened. ++ * ++ * Called by the input sub system to open a wm97xx touchscreen device. ++ * Starts the touchscreen thread and touch digitiser. ++ */ ++static int wm97xx_ts_input_open(struct input_dev *idev) ++{ ++ int ret = 0; ++ struct wm97xx *wm = (struct wm97xx *) idev->private; ++ ++ mutex_lock(&wm->codec_mutex); ++ /* first time opened ? */ ++ if (wm->ts_use_count++ == 0) { ++ /* start touchscreen thread */ ++ init_completion(&wm->ts_init); ++ init_completion(&wm->ts_exit); ++ ret = kernel_thread(wm97xx_ts_read, wm, CLONE_KERNEL); ++ ++ if (ret >= 0) { ++ wait_for_completion(&wm->ts_init); ++ if (wm->ts_task == NULL) ++ ret = -EINVAL; ++ } else { ++ mutex_unlock(&wm->codec_mutex); ++ return ret; ++ } ++ ++ /* start digitiser */ ++ if (wm->mach_ops && wm->mach_ops->acc_enabled) ++ wm->codec->acc_enable(wm, 1); ++ wm->codec->digitiser_ioctl(wm, WM97XX_DIG_START); ++ ++ /* init pen down/up irq handling */ ++ if (wm->pen_irq) { ++ wm97xx_init_pen_irq(wm); ++ ++ if (wm->pen_irq == 0) { ++ /* we failed to get an irq for pen down events, ++ * so we resort to polling. kickstart the reader */ ++ wm->pen_is_down = 1; ++ wake_up_interruptible(&wm->pen_irq_wait); ++ } ++ } ++ } ++ ++ mutex_unlock(&wm->codec_mutex); ++ return 0; ++} ++ ++/** ++ * wm97xx_ts_input_close - Close the touch screen input device. ++ * @idev: Input device to be closed. ++ * ++ * Called by the input sub system to close a wm97xx touchscreen device. ++ * Kills the touchscreen thread and stops the touch digitiser. ++ */ ++ ++static void wm97xx_ts_input_close(struct input_dev *idev) ++{ ++ struct wm97xx *wm = (struct wm97xx *) idev->private; ++ ++ mutex_lock(&wm->codec_mutex); ++ if (--wm->ts_use_count == 0) { ++ /* destroy workqueues and free irqs */ ++ if (wm->pen_irq) { ++ free_irq(wm->pen_irq, wm); ++ destroy_workqueue(wm->pen_irq_workq); ++ } ++ ++ /* kill thread */ ++ if (wm->ts_task) { ++ wm->ts_task = NULL; ++ wm->pen_is_down = 1; ++ mutex_unlock(&wm->codec_mutex); ++ wake_up_interruptible(&wm->pen_irq_wait); ++ wait_for_completion(&wm->ts_exit); ++ wm->pen_is_down = 0; ++ mutex_lock(&wm->codec_mutex); ++ } ++ ++ /* stop digitiser */ ++ wm->codec->digitiser_ioctl(wm, WM97XX_DIG_STOP); ++ if (wm->mach_ops && wm->mach_ops->acc_enabled) ++ wm->codec->acc_enable(wm, 0); ++ } ++ mutex_unlock(&wm->codec_mutex); ++} ++ ++/* ++ * Bus interface to allow for client drivers codec access ++ * e.g. battery monitor ++ */ ++static int wm97xx_bus_match(struct device *dev, struct device_driver *drv) ++{ ++ return !(strcmp(dev->bus_id,drv->name)); ++} ++ ++/* ++ * The AC97 audio driver will do all the Codec suspend and resume ++ * tasks. This is just for anything machine specific or extra. ++ */ ++static int wm97xx_bus_suspend(struct device *dev, pm_message_t state) ++{ ++ int ret = 0; ++ ++ if (dev->driver && dev->driver->suspend) ++ ret = dev->driver->suspend(dev, state); ++ ++ return ret; ++} ++ ++static int wm97xx_bus_resume(struct device *dev) ++{ ++ int ret = 0; ++ ++ if (dev->driver && dev->driver->resume) ++ ret = dev->driver->resume(dev); ++ ++ return ret; ++} ++ ++struct bus_type wm97xx_bus_type = { ++ .name = "wm97xx", ++ .match = wm97xx_bus_match, ++ .suspend = wm97xx_bus_suspend, ++ .resume = wm97xx_bus_resume, ++}; ++EXPORT_SYMBOL_GPL(wm97xx_bus_type); ++ ++static void wm97xx_release(struct device *dev) ++{ ++ kfree(dev); ++} ++ ++static int wm97xx_probe(struct device *dev) ++{ ++ struct wm97xx* wm; ++ int ret = 0, id = 0; ++ ++ if (!(wm = kzalloc(sizeof(struct wm97xx), GFP_KERNEL))) ++ return -ENOMEM; ++ mutex_init(&wm->codec_mutex); ++ ++ init_waitqueue_head(&wm->pen_irq_wait); ++ wm->dev = dev; ++ dev->driver_data = wm; ++ wm->ac97 = to_ac97_t(dev); ++ ++ /* check that we have a supported codec */ ++ if ((id = wm97xx_reg_read(wm, AC97_VENDOR_ID1)) != WM97XX_ID1) { ++ err("could not find a wm97xx, found a %x instead\n", id); ++ kfree(wm); ++ return -ENODEV; ++ } ++ ++ wm->id = wm97xx_reg_read(wm, AC97_VENDOR_ID2); ++ if(wm->id != wm97xx_codec.id) { ++ err("could not find a the selected codec, please build for wm97%2x", wm->id & 0xff); ++ kfree(wm); ++ return -ENODEV; ++ } ++ ++ if((wm->input_dev = input_allocate_device()) == NULL) { ++ kfree(wm); ++ return -ENOMEM; ++ } ++ ++ /* set up touch configuration */ ++ info("detected a wm97%2x codec", wm->id & 0xff); ++ wm->input_dev->name = "wm97xx touchscreen"; ++ wm->input_dev->open = wm97xx_ts_input_open; ++ wm->input_dev->close = wm97xx_ts_input_close; ++ set_bit(EV_ABS, wm->input_dev->evbit); ++ set_bit(ABS_X, wm->input_dev->absbit); ++ set_bit(ABS_Y, wm->input_dev->absbit); ++ set_bit(ABS_PRESSURE, wm->input_dev->absbit); ++ wm->input_dev->absmax[ABS_X] = abs_x[1]; ++ wm->input_dev->absmax[ABS_Y] = abs_y[1]; ++ wm->input_dev->absmax[ABS_PRESSURE] = abs_p[1]; ++ wm->input_dev->absmin[ABS_X] = abs_x[0]; ++ wm->input_dev->absmin[ABS_Y] = abs_y[0]; ++ wm->input_dev->absmin[ABS_PRESSURE] = abs_p[0]; ++ wm->input_dev->absfuzz[ABS_X] = abs_x[2]; ++ wm->input_dev->absfuzz[ABS_Y] = abs_y[2]; ++ wm->input_dev->absfuzz[ABS_PRESSURE] = abs_p[2]; ++ wm->input_dev->private = wm; ++ wm->codec = &wm97xx_codec; ++ if((ret = input_register_device(wm->input_dev)) < 0) { ++ kfree(wm); ++ return -ENOMEM; ++ } ++ ++ /* set up physical characteristics */ ++ wm->codec->digitiser_ioctl(wm, WM97XX_PHY_INIT); ++ ++ /* load gpio cache */ ++ wm->gpio[0] = wm97xx_reg_read(wm, AC97_GPIO_CFG); ++ wm->gpio[1] = wm97xx_reg_read(wm, AC97_GPIO_POLARITY); ++ wm->gpio[2] = wm97xx_reg_read(wm, AC97_GPIO_STICKY); ++ wm->gpio[3] = wm97xx_reg_read(wm, AC97_GPIO_WAKEUP); ++ wm->gpio[4] = wm97xx_reg_read(wm, AC97_GPIO_STATUS); ++ wm->gpio[5] = wm97xx_reg_read(wm, AC97_MISC_AFE); ++ ++ /* register our battery device */ ++ if (!(wm->battery_dev = kzalloc(sizeof(struct device), GFP_KERNEL))) { ++ ret = -ENOMEM; ++ goto batt_err; ++ } ++ wm->battery_dev->bus = &wm97xx_bus_type; ++ strcpy(wm->battery_dev->bus_id,"wm97xx-battery"); ++ wm->battery_dev->driver_data = wm; ++ wm->battery_dev->parent = dev; ++ wm->battery_dev->release = wm97xx_release; ++ if((ret = device_register(wm->battery_dev)) < 0) ++ goto batt_reg_err; ++ ++ /* register our extended touch device (for machine specific extensions) */ ++ if (!(wm->touch_dev = kzalloc(sizeof(struct device), GFP_KERNEL))) { ++ ret = -ENOMEM; ++ goto touch_err; ++ } ++ wm->touch_dev->bus = &wm97xx_bus_type; ++ strcpy(wm->touch_dev->bus_id,"wm97xx-touchscreen"); ++ wm->touch_dev->driver_data = wm; ++ wm->touch_dev->parent = dev; ++ wm->touch_dev->release = wm97xx_release; ++ if((ret = device_register(wm->touch_dev)) < 0) ++ goto touch_reg_err; ++ ++ return ret; ++ ++touch_reg_err: ++ kfree(wm->touch_dev); ++touch_err: ++ device_unregister(wm->battery_dev); ++batt_reg_err: ++ kfree(wm->battery_dev); ++batt_err: ++ input_unregister_device(wm->input_dev); ++ kfree(wm); ++ return ret; ++} ++ ++static int wm97xx_remove(struct device *dev) ++{ ++ struct wm97xx *wm = dev_get_drvdata(dev); ++ ++ /* Stop touch reader thread */ ++ if (wm->ts_task) { ++ wm->ts_task = NULL; ++ wm->pen_is_down = 1; ++ wake_up_interruptible(&wm->pen_irq_wait); ++ wait_for_completion(&wm->ts_exit); ++ } ++ device_unregister(wm->battery_dev); ++ device_unregister(wm->touch_dev); ++ input_unregister_device(wm->input_dev); ++ ++ kfree(wm); ++ return 0; ++} ++ ++#ifdef CONFIG_PM ++int wm97xx_resume(struct device* dev) ++{ ++ struct wm97xx *wm = dev_get_drvdata(dev); ++ ++ /* restore digitiser and gpio's */ ++ if(wm->id == WM9713_ID2) { ++ wm97xx_reg_write(wm, AC97_WM9713_DIG1, wm->dig[0]); ++ wm97xx_reg_write(wm, 0x5a, wm->misc); ++ if(wm->ts_use_count) { ++ u16 reg = wm97xx_reg_read(wm, AC97_EXTENDED_MID) & 0x7fff; ++ wm97xx_reg_write(wm, AC97_EXTENDED_MID, reg); ++ } ++ } ++ ++ wm97xx_reg_write(wm, AC97_WM9713_DIG2, wm->dig[1]); ++ wm97xx_reg_write(wm, AC97_WM9713_DIG3, wm->dig[2]); ++ ++ wm97xx_reg_write(wm, AC97_GPIO_CFG, wm->gpio[0]); ++ wm97xx_reg_write(wm, AC97_GPIO_POLARITY, wm->gpio[1]); ++ wm97xx_reg_write(wm, AC97_GPIO_STICKY, wm->gpio[2]); ++ wm97xx_reg_write(wm, AC97_GPIO_WAKEUP, wm->gpio[3]); ++ wm97xx_reg_write(wm, AC97_GPIO_STATUS, wm->gpio[4]); ++ wm97xx_reg_write(wm, AC97_MISC_AFE, wm->gpio[5]); ++ ++ return 0; ++} ++ ++#else ++#define wm97xx_resume NULL ++#endif ++ ++/* ++ * Machine specific operations ++ */ ++int wm97xx_register_mach_ops(struct wm97xx *wm, struct wm97xx_mach_ops *mach_ops) ++{ ++ mutex_lock(&wm->codec_mutex); ++ if(wm->mach_ops) { ++ mutex_unlock(&wm->codec_mutex); ++ return -EINVAL; ++ } ++ wm->mach_ops = mach_ops; ++ mutex_unlock(&wm->codec_mutex); ++ return 0; ++} ++EXPORT_SYMBOL_GPL(wm97xx_register_mach_ops); ++ ++void wm97xx_unregister_mach_ops(struct wm97xx *wm) ++{ ++ mutex_lock(&wm->codec_mutex); ++ wm->mach_ops = NULL; ++ mutex_unlock(&wm->codec_mutex); ++} ++EXPORT_SYMBOL_GPL(wm97xx_unregister_mach_ops); ++ ++static struct device_driver wm97xx_driver = { ++ .name = "ac97", ++ .bus = &ac97_bus_type, ++ .owner = THIS_MODULE, ++ .probe = wm97xx_probe, ++ .remove = wm97xx_remove, ++ .resume = wm97xx_resume, ++}; ++ ++static int __init wm97xx_init(void) ++{ ++ int ret; ++ ++ info("version %s liam.girdwood@wolfsonmicro.com", WM_CORE_VERSION); ++ if((ret = bus_register(&wm97xx_bus_type)) < 0) ++ return ret; ++ return driver_register(&wm97xx_driver); ++} ++ ++static void __exit wm97xx_exit(void) ++{ ++ driver_unregister(&wm97xx_driver); ++ bus_unregister(&wm97xx_bus_type); ++} ++ ++module_init(wm97xx_init); ++module_exit(wm97xx_exit); ++ ++/* Module information */ ++MODULE_AUTHOR("Liam Girdwood, liam.girdwood@wolfsonmicro.com, www.wolfsonmicro.com"); ++MODULE_DESCRIPTION("WM97xx Core - Touch Screen / AUX ADC / GPIO Driver"); ++MODULE_LICENSE("GPL"); +diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig +index 4468cb3..01b4828 100644 +--- a/drivers/leds/Kconfig ++++ b/drivers/leds/Kconfig +@@ -101,6 +101,12 @@ config LEDS_GPIO + outputs. To be useful the particular board must have LEDs + and they must be connected to the GPIO lines. + ++config LEDS_EM_X270 ++ tristate "LED Support for the CompuLab EM-X270" ++ depends on LEDS_CLASS && MACH_EM_X270 ++ help ++ This option enables support for the LEDs on CompuLab EM-X270. ++ + comment "LED Triggers" + + config LEDS_TRIGGERS +diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile +index f8995c9..6d3941e 100644 +--- a/drivers/leds/Makefile ++++ b/drivers/leds/Makefile +@@ -17,6 +17,7 @@ obj-$(CONFIG_LEDS_WRAP) += leds-wrap.o + obj-$(CONFIG_LEDS_H1940) += leds-h1940.o + obj-$(CONFIG_LEDS_COBALT) += leds-cobalt.o + obj-$(CONFIG_LEDS_GPIO) += leds-gpio.o ++obj-$(CONFIG_LEDS_EM_X270) += leds-em-x270.o + + # LED Triggers + obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o +diff --git a/drivers/leds/leds-em-x270.c b/drivers/leds/leds-em-x270.c +new file mode 100644 +index 0000000..485e7da +--- /dev/null ++++ b/drivers/leds/leds-em-x270.c +@@ -0,0 +1,99 @@ ++/* ++ * LED Triggers Core ++ * ++ * Copyright 2007 CompuLab, Ltd. ++ * Author: Mike Rapoport <mike@compulab.co.il> ++ * ++ * Based on Corgi leds driver: ++ * Copyright 2005-2006 Openedhand Ltd. ++ * Author: Richard Purdie <rpurdie@openedhand.com> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ */ ++ ++#include <linux/kernel.h> ++#include <linux/init.h> ++#include <linux/platform_device.h> ++#include <linux/leds.h> ++#include <linux/da9030.h> ++ ++static void em_x270_led_orange_set(struct led_classdev *led_cdev, ++ enum led_brightness value) ++{ ++ int on = 1; ++ int pwm_chop = 0; ++ ++ pr_info("%s: value = %d\n", __FUNCTION__, value); ++ if (value == LED_OFF) ++ on = 0; ++ else if (value == LED_HALF) ++ pwm_chop = 4; ++ ++ da9030_set_led(3, on, 0, 0, pwm_chop); ++} ++ ++static struct led_classdev em_x270_orange_led = { ++ .name = "em_x270:orange", ++ .default_trigger = "em-x270-battery.0-charging-or-full", ++ .brightness_set = em_x270_led_orange_set, ++}; ++ ++#ifdef CONFIG_PM ++static int em_x270_led_suspend(struct platform_device *dev, pm_message_t state) ++{ ++#ifdef CONFIG_LEDS_TRIGGERS ++ if (em_x270_orange_led.trigger && strcmp(em_x270_orange_led.trigger->name, "em-x270-battery-charging-or-full")) ++#endif ++ led_classdev_suspend(&em_x270_orange_led); ++ return 0; ++} ++ ++static int em_x270_led_resume(struct platform_device *dev) ++{ ++ led_classdev_resume(&em_x270_orange_led); ++ return 0; ++} ++#endif ++ ++static int em_x270_led_probe(struct platform_device *pdev) ++{ ++ return led_classdev_register(&pdev->dev, &em_x270_orange_led); ++} ++ ++static int em_x270_led_remove(struct platform_device *pdev) ++{ ++ led_classdev_unregister(&em_x270_orange_led); ++ return 0; ++} ++ ++static struct platform_driver em_x270_led_driver = { ++ .probe = em_x270_led_probe, ++ .remove = em_x270_led_remove, ++#ifdef CONFIG_PM ++ .suspend = em_x270_led_suspend, ++ .resume = em_x270_led_resume, ++#endif ++ .driver = { ++ .name = "em-x270-led", ++ }, ++}; ++ ++static int __init em_x270_led_init(void) ++{ ++ return platform_driver_register(&em_x270_led_driver); ++} ++ ++static void __exit em_x270_led_exit(void) ++{ ++ platform_driver_unregister(&em_x270_led_driver); ++} ++ ++module_init(em_x270_led_init); ++module_exit(em_x270_led_exit); ++ ++MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>"); ++MODULE_DESCRIPTION("EX-X270 LED driver"); ++MODULE_LICENSE("GPL"); +diff --git a/drivers/mtd/chips/jedec_probe.c b/drivers/mtd/chips/jedec_probe.c +index 58e561e..7050e71 100644 +--- a/drivers/mtd/chips/jedec_probe.c ++++ b/drivers/mtd/chips/jedec_probe.c +@@ -38,7 +38,7 @@ + #define MANUFACTURER_ST 0x0020 + #define MANUFACTURER_TOSHIBA 0x0098 + #define MANUFACTURER_WINBOND 0x00da +- ++#define CONTINUATION_CODE 0x007f + + /* AMD */ + #define AM29DL800BB 0x22C8 +@@ -68,6 +68,10 @@ + #define AT49BV32X 0x00C8 + #define AT49BV32XT 0x00C9 + ++/* Eon */ ++#define EN29SL800BB 0x226B ++#define EN29SL800BT 0x22EA ++ + /* Fujitsu */ + #define MBM29F040C 0x00A4 + #define MBM29LV650UE 0x22D7 +@@ -632,6 +636,40 @@ static const struct amd_flash_info jedec_table[] = { + ERASEINFO(0x02000,8) + } + }, { ++ .mfr_id = 0x1c, ++ .dev_id = EN29SL800BT, ++ .name = "Eon EN29SL800BT", ++ .uaddr = { ++ [0] = MTD_UADDR_0x0555_0x02AA, /* x8 */ ++ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ ++ }, ++ .DevSize = SIZE_1MiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 4, ++ .regions = { ++ ERASEINFO(0x10000, 15), ++ ERASEINFO(0x08000, 1), ++ ERASEINFO(0x02000, 2), ++ ERASEINFO(0x04000, 1), ++ } ++ }, { ++ .mfr_id = 0x1c, ++ .dev_id = EN29SL800BB, ++ .name = "Eon EN29SL800BB", ++ .uaddr = { ++ [0] = MTD_UADDR_0x0555_0x02AA, /* x8 */ ++ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ ++ }, ++ .DevSize = SIZE_1MiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 4, ++ .regions = { ++ ERASEINFO(0x04000, 1), ++ ERASEINFO(0x02000, 2), ++ ERASEINFO(0x08000, 1), ++ ERASEINFO(0x10000, 15), ++ } ++ }, { + .mfr_id = MANUFACTURER_FUJITSU, + .dev_id = MBM29F040C, + .name = "Fujitsu MBM29F040C", +@@ -1769,9 +1807,21 @@ static inline u32 jedec_read_mfr(struct map_info *map, __u32 base, + { + map_word result; + unsigned long mask; +- u32 ofs = cfi_build_cmd_addr(0, cfi_interleave(cfi), cfi->device_type); +- mask = (1 << (cfi->device_type * 8)) -1; +- result = map_read(map, base + ofs); ++ int bank = 0; ++ ++ /* According to JEDEC "Standard Manufacturer's Identification Code" ++ * (http://www.jedec.org/download/search/jep106W.pdf) ++ * several first banks can contain 0x7f instead of actual ID ++ */ ++ do { ++ u32 ofs = cfi_build_cmd_addr(0 + (bank << 8), ++ cfi_interleave(cfi), ++ cfi->device_type); ++ mask = (1 << (cfi->device_type * 8)) -1; ++ result = map_read(map, base + ofs); ++ bank++; ++ } while ((result.x[0] & mask) == CONTINUATION_CODE); ++ + return result.x[0] & mask; + } + +diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c +index 738aa59..88dbbdf 100644 +--- a/drivers/net/dm9000.c ++++ b/drivers/net/dm9000.c +@@ -546,6 +546,7 @@ dm9000_probe(struct platform_device *pdev) + + if (id_val != DM9000_ID) { + printk("%s: wrong id: 0x%08x\n", CARDNAME, id_val); ++ ret = -ENODEV; + goto release; + } + +diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig +index 58c806e..3a16d9c 100644 +--- a/drivers/power/Kconfig ++++ b/drivers/power/Kconfig +@@ -49,4 +49,10 @@ config BATTERY_OLPC + help + Say Y to enable support for the battery on the OLPC laptop. + ++config BATTERY_EM_X270 ++ tristate "EM-X270 battery" ++ depends on DA9030 && MACH_EM_X270 ++ help ++ Say Y here to enable support for battery on EM-X270. ++ + endif # POWER_SUPPLY +diff --git a/drivers/power/Makefile b/drivers/power/Makefile +index 6413ded..dc9585e 100644 +--- a/drivers/power/Makefile ++++ b/drivers/power/Makefile +@@ -20,3 +20,4 @@ obj-$(CONFIG_APM_POWER) += apm_power.o + obj-$(CONFIG_BATTERY_DS2760) += ds2760_battery.o + obj-$(CONFIG_BATTERY_PMU) += pmu_battery.o + obj-$(CONFIG_BATTERY_OLPC) += olpc_battery.o ++obj-$(CONFIG_BATTERY_EM_X270) += em_x270_battery.o +diff --git a/drivers/power/em_x270_battery.c b/drivers/power/em_x270_battery.c +new file mode 100644 +index 0000000..2630c68 +--- /dev/null ++++ b/drivers/power/em_x270_battery.c +@@ -0,0 +1,579 @@ ++/* ++ * Power managemnet implementation for EM-X270 ++ * ++ * Copyright (C) 2007 CompuLab, Ltd. ++ * Author: Mike Rapoport <mike@compulab.co.il> ++ * ++ * 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. ++ * ++ */ ++ ++#define DEBUG ++ ++#include <linux/module.h> ++#include <linux/platform_device.h> ++#include <linux/pda_power.h> ++#include <linux/apm-emulation.h> ++#include <linux/da9030.h> ++#include <linux/power_supply.h> ++#include <linux/pm.h> ++ ++#include <linux/debugfs.h> ++#include <linux/seq_file.h> ++ ++#include "../i2c/chips/da9030.h" ++ ++#define VOLTAGE_MAX_DESIGN 4200000 /* 4.2V in uV */ ++#define VOLTAGE_MIN_DESIGN 3000000 /* 3V in uV */ ++ ++/* #define VCHARGE_MIN_THRESHOLD 72 /\* 4.5V *\/ */ ++ ++#define VCHARGE_MIN_THRESHOLD 60 /* ?.?V */ ++#define VCHARGE_MAX_THRESHOLD 89 /* 5.5V */ ++#define TBAT_LOW_THRESHOLD 197 /* 0oC */ ++#define TBAT_HIGH_THRESHOLD 78 /* 45oC */ ++#define TBAT_RESUME_THRESHOLD 100 /* 35oC */ ++#define VBAT_LOW_THRESHOLD 82 /* 3.498V */ ++#define VBAT_CRIT_THRESHOLD 62 /* 3.291V */ ++ ++struct da9030_charger { ++ struct device *dev; ++ ++ struct power_supply bat; ++ struct da9030_adc_res adc; ++ struct delayed_work work; ++ ++ int interval; ++ int status; ++ int mA; ++ int mV; ++ ++ int is_charging:1; ++ ++#ifdef CONFIG_DEBUG_FS ++ struct dentry *debug_file; ++#endif ++}; ++ ++static unsigned short tbat_readings[] = { ++ 300, 244, 200, 178, 163, 152, 144, 137, 131, ++ 126, 122, 118, 114, 111, 108, 105, 103, 101, ++ 98, 96, 94, 93, 91, 89, 88, 86, 85, ++ 83, 82, 81, 79, 78, 77, 76, 75, 74, ++ 73, 72, 71, 70, 69, 68, 67, 67, 66, ++ 65, 64, 63, 63, 62, 61, 60, 60, 59, ++ 58, 58, 57, 57, 56, 55, 55, 54, 53, ++ 53, 52, 52, 51, 51, 50, 50, 49, 49, ++ 48, 48, 47, 47, 46, 46, 45, 45, 44, ++ 44, 43, 43, 42, 42, 41, 41, 41, 40, ++ 40, 39, 39, 38, 38, 38, 37, 37, 36, ++ 36, 35, 35, 35, 34, 34, 34, 33, 33, ++ 32, 32, 32, 31, 31, 30, 30, 30, 29, ++ 29, 29, 28, 28, 28, 27, 27, 26, 26, ++ 26, 25, 25, 25, 24, 24, 24, 23, 23, ++ 23, 22, 22, 21, 21, 21, 20, 20, 20, ++ 19, 19, 19, 18, 18, 18, 17, 17, 17, ++ 16, 16, 16, 15, 15, 14, 14, 14, 13, ++ 13, 13, 12, 12, 12, 11, 11, 11, 10, ++ 10, 10, 9, 9, 8, 8, 8, 7, 7, ++ 7, 6, 6, 5, 5, 5, 4, 4, 3, ++ 3, 3, 2, 2, 1, 1, 1, 0, 0, ++ -1, -1, -1, -2, -2, -3, -3, -4, -4, ++ -5, -5, -6, -6, -6, -7, -7, -8, -9, ++ -9, -10, -10, -11, -11, -12, -12, -13, -14, ++ -14, -15, -16, -16, -17, -18, -18, -19, -20, ++ -21, -21, -22, -23, -24, -25, -26, -27, -28, ++ -30, -31, -32, -34, -35, -37, -39, -41, -44, ++ -47, -50, -56, -64, ++}; ++ ++#ifdef CONFIG_DEBUG_FS ++ ++#define REG2VOLT(x) ((((x) * 2650) >> 8) + 2650) ++ ++static int debug_show(struct seq_file *s, void *data) ++{ ++ struct da9030_charger *charger = s->private; ++ ++ seq_printf(s, "charger is %s\n", ++ charger->status & CHRG_CHARGER_ENABLE ? "on" : "off"); ++ if (charger->status & CHRG_CHARGER_ENABLE) { ++ seq_printf(s, "iset = %dmA, vset = %dmV\n", ++ charger->mA, charger->mV); ++ } ++ ++ seq_printf(s, "vbat_res = %d (%dmV)\n", ++ charger->adc.vbat_res, REG2VOLT(charger->adc.vbat_res)); ++ seq_printf(s, "vbatmin_res = %d (%dmV)\n", ++ charger->adc.vbatmin_res, ++ REG2VOLT(charger->adc.vbatmin_res)); ++ seq_printf(s, "vbatmintxon = %d (%dmV)\n", ++ charger->adc.vbatmintxon, ++ REG2VOLT(charger->adc.vbatmintxon)); ++ seq_printf(s, "ichmax_res = %d\n", charger->adc.ichmax_res); ++ seq_printf(s, "ichmin_res = %d\n", charger->adc.ichmin_res); ++ seq_printf(s, "ichaverage_res = %d\n", charger->adc.ichaverage_res); ++ seq_printf(s, "vchmax_res = %d (%dmV)\n", ++ charger->adc.vchmax_res, ++ REG2VOLT(charger->adc.vchmax_res)); ++ seq_printf(s, "vchmin_res = %d (%dmV)\n", ++ charger->adc.vchmin_res, ++ REG2VOLT(charger->adc.vchmin_res)); ++ seq_printf(s, "tbat_res = %d (%doC\n", charger->adc.tbat_res, ++ tbat_readings[charger->adc.tbat_res]); ++ seq_printf(s, "adc_in4_res = %d\n", charger->adc.adc_in4_res); ++ seq_printf(s, "adc_in5_res = %d\n", charger->adc.adc_in5_res); ++ ++ return 0; ++} ++ ++static int debug_open(struct inode *inode, struct file *file) ++{ ++ return single_open(file, debug_show, inode->i_private); ++} ++ ++static const struct file_operations debug_fops = { ++ .open = debug_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .release = single_release, ++}; ++ ++static struct dentry* da9030_create_debugfs(struct da9030_charger *charger) ++{ ++ charger->debug_file = debugfs_create_file("charger", 0666, 0, charger, ++ &debug_fops); ++ return charger->debug_file; ++} ++ ++static void da9030_remove_debugfs(struct da9030_charger *charger) ++{ ++ debugfs_remove(charger->debug_file); ++} ++#else ++#define da9030_create_debugfs(x) NULL ++#define da9030_remove_debugfs(x) do {} while(0) ++#endif ++ ++static void da9030_set_charge(struct da9030_charger *charger, int on) ++{ ++/* int status = da9030_get_status(); */ ++ if (on) { ++ pr_debug("%s: enabling charger\n", __FUNCTION__); ++ da9030_set_thresholds(TBAT_HIGH_THRESHOLD, ++ TBAT_RESUME_THRESHOLD, ++ TBAT_LOW_THRESHOLD); ++ da9030_set_charger(1, 1000, 4200); ++ charger->is_charging = 1; ++ } ++ else { ++ /* disable charger */ ++ pr_debug("%s: disabling charger\n", __FUNCTION__); ++ da9030_set_charger(0, 0, 0); ++ charger->is_charging = 0; ++ } ++} ++ ++static void da9030_charging_monitor(struct work_struct *work) ++{ ++ struct da9030_charger *charger; ++ int is_on; ++ unsigned int mA, mV; ++ ++ charger = container_of(work, struct da9030_charger, work.work); ++ ++ da9030_get_charger(&is_on, &mA, &mV); ++ da9030_read_adc(&charger->adc); ++ ++ charger->status = da9030_get_status(); ++ charger->mA = mA; ++ charger->mV = mV; ++ ++ /* we wake or boot with external power on */ ++ if (!is_on && (charger->status & STATUS_CHDET)) { ++ da9030_set_charge(charger, 1); ++ return; ++ } ++ ++ if (is_on) { ++/* pr_info("%s: mA = %d, mV = %d\n", __FUNCTION__, mA, mV); */ ++/* pr_info("%s: vchmin_res = %d, vchmax_res = %d\n", */ ++/* __FUNCTION__, charger->adc.vchmin_res, */ ++/* charger->adc.vchmax_res); */ ++/* pr_info("%s: tbat_res = %d\n", */ ++/* __FUNCTION__, charger->adc.tbat_res); */ ++ if (charger->adc.vbat_res > VBAT_LOW_THRESHOLD) { ++ /* update VBAT threshlods ? */ ++ da9030_set_reg(VBATMON, VBAT_LOW_THRESHOLD); ++ } ++ if (charger->adc.vchmax_res > VCHARGE_MAX_THRESHOLD || ++ charger->adc.vchmin_res < VCHARGE_MIN_THRESHOLD || ++ /* Tempreture readings are negative */ ++ charger->adc.tbat_res < TBAT_HIGH_THRESHOLD || ++ charger->adc.tbat_res > TBAT_LOW_THRESHOLD) { ++ /* disable charger */ ++ da9030_set_charge(charger, 0); ++ } ++ } ++ ++ /* reschedule for the next time */ ++ schedule_delayed_work(&charger->work, charger->interval); ++} ++ ++void da9030_battery_release(struct device * dev) ++{ ++} ++ ++static void da9030_external_power_changed(struct power_supply *psy) ++{ ++/* struct da9030_charger *charger; */ ++ ++/* charger = container_of(psy, struct da9030_charger, bat); */ ++/* pr_info("%s:\n", __FUNCTION__); */ ++/* da9030_set_charge(charger); */ ++} ++ ++struct da9030_battery_thresh { ++ int voltage; ++ int percentage; ++}; ++ ++static struct da9030_battery_thresh vbat_ranges[] = { ++ { 150, 100}, ++ { 149, 99}, ++ { 148, 98}, ++ { 147, 98}, ++ { 146, 97}, ++ { 145, 96}, ++ { 144, 96}, ++ { 143, 95}, ++ { 142, 94}, ++ { 141, 93}, ++ { 140, 92}, ++ { 139, 91}, ++ { 138, 90}, ++ { 137, 90}, ++ { 136, 89}, ++ { 135, 88}, ++ { 134, 88}, ++ { 133, 87}, ++ { 132, 86}, ++ { 131, 85}, ++ { 130, 83}, ++ { 129, 82}, ++ { 128, 81}, ++ { 127, 81}, ++ { 126, 80}, ++ { 125, 75}, ++ { 124, 74}, ++ { 123, 73}, ++ { 122, 70}, ++ { 121, 66}, ++ { 120, 65}, ++ { 119, 64}, ++ { 118, 64}, ++ { 117, 63}, ++ { 116, 59}, ++ { 115, 58}, ++ { 114, 57}, ++ { 113, 57}, ++ { 112, 56}, ++ { 111, 50}, ++ { 110, 49}, ++ { 109, 49}, ++ { 108, 48}, ++ { 107, 48}, ++ { 106, 33}, ++ { 105, 32}, ++ { 104, 32}, ++ { 103, 32}, ++ { 102, 31}, ++ { 101, 16}, ++ { 100, 15}, ++ { 99, 15}, ++ { 98, 15}, ++ { 97, 10}, ++ { 96, 9}, ++ { 95, 7}, ++ { 94, 3}, ++ { 93, 0}, ++}; ++ ++static enum power_supply_property da9030_bat_props[] = { ++ POWER_SUPPLY_PROP_STATUS, ++ POWER_SUPPLY_PROP_HEALTH, ++ POWER_SUPPLY_PROP_TECHNOLOGY, ++ POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, ++ POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, ++ POWER_SUPPLY_PROP_VOLTAGE_NOW, ++ POWER_SUPPLY_PROP_CURRENT_AVG, ++ POWER_SUPPLY_PROP_CAPACITY, /* in percents! */ ++ POWER_SUPPLY_PROP_TEMP, ++ POWER_SUPPLY_PROP_MANUFACTURER, ++ POWER_SUPPLY_PROP_MODEL_NAME, ++}; ++ ++static void da9030_bat_check_status(union power_supply_propval *val) ++{ ++ int charger_on; ++ int status = da9030_get_status(); ++ ++ da9030_get_charger(&charger_on, 0, 0); ++ ++ /* FIXME: below code is very crude approximation of actual ++ states, we need to take into account voltage and current ++ measurements to determine actual charger state */ ++ if (status & STATUS_CHDET) { ++ if (charger_on) { ++ val->intval = POWER_SUPPLY_STATUS_CHARGING; ++ } ++ else { ++ val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; ++ } ++ } ++ else { ++ val->intval = POWER_SUPPLY_STATUS_DISCHARGING; ++ } ++} ++ ++static void da9030_bat_check_health(union power_supply_propval *val) ++{ ++ int fault_log = da9030_get_fault_log(); ++ ++ if (fault_log & FAULT_LOG_OVER_TEMP) { ++ val->intval = POWER_SUPPLY_HEALTH_OVERHEAT; ++ } ++ else if (fault_log & FAULT_LOG_VBAT_OVER) { ++ val->intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE; ++ } ++ else { ++ val->intval = POWER_SUPPLY_HEALTH_GOOD; ++ } ++} ++ ++static int vbat_interpolate(int reg) ++{ ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(vbat_ranges); i++ ) ++ if (vbat_ranges[i].voltage == reg) { ++ pr_debug("%s: voltage = %d, percentage = %d\n", ++ __FUNCTION__, vbat_ranges[i].voltage, ++ vbat_ranges[i].percentage); ++ return vbat_ranges[i].percentage; ++ } ++ ++ return 0; ++} ++ ++static int da9030_bat_get_property(struct power_supply *psy, ++ enum power_supply_property psp, ++ union power_supply_propval *val) ++{ ++ u32 reg; ++ struct da9030_charger *charger; ++ charger = container_of(psy, struct da9030_charger, bat); ++ ++ switch(psp) { ++ case POWER_SUPPLY_PROP_STATUS: ++ da9030_bat_check_status(val); ++ break; ++ case POWER_SUPPLY_PROP_HEALTH: ++ da9030_bat_check_health(val); ++ break; ++ case POWER_SUPPLY_PROP_TECHNOLOGY: ++ val->intval = POWER_SUPPLY_TECHNOLOGY_LIPO; ++ break; ++ case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN: ++ val->intval = VOLTAGE_MAX_DESIGN; ++ break; ++ case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: ++ val->intval = VOLTAGE_MIN_DESIGN; ++ break; ++ case POWER_SUPPLY_PROP_VOLTAGE_NOW: ++ reg = charger->adc.vbat_res; ++ /* V = (reg / 256) * 2.65 + 2.65 (V) */ ++ val->intval = ((reg * 2650000) >> 8) + 2650000; ++ break; ++ case POWER_SUPPLY_PROP_CURRENT_AVG: ++ reg = charger->adc.ichaverage_res; ++ val->intval = reg; /* reg */ ++ break; ++ case POWER_SUPPLY_PROP_CAPACITY: ++ reg = charger->adc.vbat_res; ++ val->intval = vbat_interpolate(reg); ++ break; ++ case POWER_SUPPLY_PROP_TEMP: ++ reg = charger->adc.tbat_res; ++ val->intval = tbat_readings[reg]; ++ break; ++ case POWER_SUPPLY_PROP_MANUFACTURER: ++ val->strval = "MaxPower"; ++ pr_debug("%s: MFG = %s\n", __FUNCTION__, val->strval); ++ break; ++ case POWER_SUPPLY_PROP_MODEL_NAME: ++ val->strval = "LP555597P6H-FPS"; ++ pr_debug("%s: MODEL = %s\n", __FUNCTION__, val->strval); ++ break; ++ default: break; ++ } ++ ++ return 0; ++} ++ ++static void da9030_setup_battery(struct power_supply *bat) ++{ ++ bat->name = "em-x270-battery"; ++ bat->type = POWER_SUPPLY_TYPE_BATTERY; ++ bat->properties = da9030_bat_props; ++ bat->num_properties = ARRAY_SIZE(da9030_bat_props); ++ bat->get_property = da9030_bat_get_property; ++ bat->use_for_apm = 1; ++ bat->external_power_changed = da9030_external_power_changed; ++}; ++ ++static void da9030_chiover_callback(int event, void *_charger) ++{ ++ /* disable charger */ ++ struct da9030_charger *charger = _charger; ++ da9030_set_charge(charger, 0); ++} ++ ++static void da9030_tbat_callback(int event, void *_charger) ++{ ++ /* disable charger */ ++ struct da9030_charger *charger = _charger; ++ da9030_set_charge(charger, 0); ++} ++ ++static void da9030_vbat_callback(int event, void *_charger) ++{ ++ struct da9030_charger *charger = _charger; ++ da9030_read_adc(&charger->adc); ++ ++ if (charger->is_charging) { ++ if (charger->adc.vbat_res < VBAT_LOW_THRESHOLD) { ++ /* set VBAT threshold for critical */ ++ da9030_set_reg(VBATMON, VBAT_CRIT_THRESHOLD); ++ } ++ else if (charger->adc.vbat_res < VBAT_CRIT_THRESHOLD) { ++ /* notify the system of battery critical */ ++ apm_queue_event(APM_CRITICAL_SUSPEND); ++ } ++ } ++} ++ ++static void da9030_ccto_callback(int event, void *_charger) ++{ ++ /* x3 */ ++} ++ ++static void da9030_tcto_callback(int event, void *_charger) ++{ ++ /* x3 */ ++} ++ ++static void da9030_chdet_callback(int event, void *_charger) ++{ ++ struct da9030_charger *charger = _charger; ++ int status = da9030_get_status(); ++ da9030_set_charge(charger, !!(status & CHRG_CHARGER_ENABLE)); ++} ++ ++static int da9030_battery_probe(struct platform_device *pdev) ++{ ++ struct da9030_charger *charger; ++ ++ pr_debug("%s\n", __FUNCTION__); ++ charger = kzalloc(sizeof(*charger), GFP_KERNEL); ++ if (charger == NULL) { ++ return -ENOMEM; ++ } ++ ++ charger->dev = &pdev->dev; ++ ++ charger->interval = 10 * HZ; /* 10 seconds between monotor runs */ ++ da9030_setup_battery(&charger->bat); ++ ++ platform_set_drvdata(pdev, charger); ++ ++ da9030_enable_adc(); ++ ++ INIT_DELAYED_WORK(&charger->work, da9030_charging_monitor); ++ schedule_delayed_work(&charger->work, charger->interval); ++ ++ charger->debug_file = da9030_create_debugfs(charger); ++ ++ da9030_setup_battery(&charger->bat); ++ ++ da9030_register_callback(DA9030_IRQ_CHDET, ++ da9030_chdet_callback, ++ charger); ++ da9030_register_callback(DA9030_IRQ_VBATMON, ++ da9030_vbat_callback, ++ charger); ++ ++ /* critical condition events */ ++ da9030_register_callback(DA9030_IRQ_CHIOVER, ++ da9030_chiover_callback, ++ charger); ++ da9030_register_callback(DA9030_IRQ_TBAT, ++ da9030_tbat_callback, ++ charger); ++ ++ /* timer events */ ++ da9030_register_callback(DA9030_IRQ_TCTO, ++ da9030_tcto_callback, ++ charger); ++ da9030_register_callback(DA9030_IRQ_CCTO, ++ da9030_ccto_callback, ++ charger); ++ ++ power_supply_register(&pdev->dev, &charger->bat); ++ ++ return 0; ++} ++ ++static int da9030_battery_remove(struct platform_device *dev) ++{ ++ struct da9030_charger *charger = platform_get_drvdata(dev); ++ ++ pr_debug("%s\n", __FUNCTION__); ++ da9030_remove_debugfs(charger); ++ cancel_delayed_work(&charger->work); ++ power_supply_unregister(&charger->bat); ++ kfree(charger); ++ return 0; ++} ++ ++static struct platform_driver da9030_battery_driver = { ++ .driver = { ++ .name = "da9030-battery", ++ .owner = THIS_MODULE, ++ }, ++ .probe = da9030_battery_probe, ++ .remove = da9030_battery_remove, ++}; ++ ++static int da9030_battery_init(void) ++{ ++ pr_debug("%s\n", __FUNCTION__); ++ ++ return platform_driver_register(&da9030_battery_driver); ++} ++ ++static void da9030_battery_exit(void) ++{ ++ pr_debug("%s\n", __FUNCTION__); ++ ++ platform_driver_unregister(&da9030_battery_driver); ++} ++ ++module_init(da9030_battery_init); ++module_exit(da9030_battery_exit); ++ ++MODULE_DESCRIPTION("DA9030 charger driver"); ++MODULE_AUTHOR("Mike Rapoport"); ++MODULE_LICENSE("GPL"); +diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig +index 767aed5..4c44a7a 100644 +--- a/drivers/usb/gadget/Kconfig ++++ b/drivers/usb/gadget/Kconfig +@@ -195,6 +195,26 @@ config USB_M66592 + default USB_GADGET + select USB_GADGET_SELECTED + ++config USB_GADGET_PXA27X ++ boolean "PXA 27x" ++ depends on ARCH_PXA && PXA27x ++ help ++ Intel's PXA 27x series XScale ARM-5TE processors include ++ an integrated full speed USB 1.1 device controller. ++ ++ It has 23 endpoints, as well as endpoint zero (for control ++ transfers). ++ ++ Say "y" to link the driver statically, or "m" to build a ++ dynamically linked module called "pxa27x_udc" and force all ++ gadget drivers to also be dynamically linked. ++ ++config USB_PXA27X ++ tristate ++ depends on USB_GADGET_PXA27X ++ default USB_GADGET ++ select USB_GADGET_SELECTED ++ + config USB_GADGET_GOKU + boolean "Toshiba TC86C001 'Goku-S'" + depends on PCI +diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile +index 1bc0f03..b8743bf 100644 +--- a/drivers/usb/gadget/Makefile ++++ b/drivers/usb/gadget/Makefile +@@ -9,6 +9,7 @@ obj-$(CONFIG_USB_DUMMY_HCD) += dummy_hcd.o + obj-$(CONFIG_USB_NET2280) += net2280.o + obj-$(CONFIG_USB_AMD5536UDC) += amd5536udc.o + obj-$(CONFIG_USB_PXA2XX) += pxa2xx_udc.o ++obj-$(CONFIG_USB_PXA27X) += pxa27x_udc.o + obj-$(CONFIG_USB_GOKU) += goku_udc.o + obj-$(CONFIG_USB_OMAP) += omap_udc.o + obj-$(CONFIG_USB_LH7A40X) += lh7a40x_udc.o +diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c +index 3aa46cf..d7d5550 100644 +--- a/drivers/usb/gadget/epautoconf.c ++++ b/drivers/usb/gadget/epautoconf.c +@@ -228,14 +228,19 @@ find_ep (struct usb_gadget *gadget, const char *name) + * + * On failure, this returns a null endpoint descriptor. + */ +-struct usb_ep * __devinit usb_ep_autoconfig ( ++struct usb_ep * usb_ep_autoconfig ( + struct usb_gadget *gadget, +- struct usb_endpoint_descriptor *desc ++ struct usb_endpoint_descriptor *desc, ++ struct usb_endpoint_config *epconfig, int numconfigs + ) + { + struct usb_ep *ep; + u8 type; + ++ /* Use device specific ep allocation code if provided */ ++ if (gadget->ops->ep_alloc) ++ return gadget->ops->ep_alloc(gadget, desc, epconfig, numconfigs); ++ + type = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; + + /* First, apply chip-specific "best usage" knowledge. +diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c +index 593e235..87aa9fb 100644 +--- a/drivers/usb/gadget/ether.c ++++ b/drivers/usb/gadget/ether.c +@@ -1350,6 +1350,10 @@ static void rndis_response_complete (struct usb_ep *ep, struct usb_request *req) + /* done sending after USB_CDC_GET_ENCAPSULATED_RESPONSE */ + } + ++#ifdef CONFIG_USB_GADGET_PXA27X ++int write_ep0_zlp(void); ++#endif ++ + static void rndis_command_complete (struct usb_ep *ep, struct usb_request *req) + { + struct eth_dev *dev = ep->driver_data; +@@ -1360,6 +1364,10 @@ static void rndis_command_complete (struct usb_ep *ep, struct usb_request *req) + status = rndis_msg_parser (dev->rndis_config, (u8 *) req->buf); + if (status < 0) + ERROR(dev, "%s: rndis parse error %d\n", __FUNCTION__, status); ++ ++#ifdef CONFIG_USB_GADGET_PXA27X ++ write_ep0_zlp(); ++#endif + spin_unlock(&dev->lock); + } + +@@ -2287,7 +2295,8 @@ eth_bind (struct usb_gadget *gadget) + struct eth_dev *dev; + struct net_device *net; + u8 cdc = 1, zlp = 1, rndis = 1; +- struct usb_ep *in_ep, *out_ep, *status_ep = NULL; ++ struct usb_ep *in_ep = NULL , *out_ep = NULL, *status_ep = NULL; ++ struct usb_endpoint_config ep_config[2]; + int status = -ENOMEM; + int gcnum; + +@@ -2386,7 +2395,30 @@ eth_bind (struct usb_gadget *gadget) + + /* all we really need is bulk IN/OUT */ + usb_ep_autoconfig_reset (gadget); +- in_ep = usb_ep_autoconfig (gadget, &fs_source_desc); ++ ++ ep_config[0].config = DEV_CONFIG_VALUE; ++#if defined(DEV_CONFIG_CDC) ++ ep_config[0].interface = data_intf.bInterfaceNumber; ++ ep_config[0].altinterface = data_intf.bAlternateSetting; ++#else /* DEV_CONFIG_SUBSET */ ++ ep_config[0].interface = subset_data_intf.bInterfaceNumber; ++ ep_config[0].altinterface = subset_data_intf.bAlternateSetting; ++#endif ++ ++#ifdef CONFIG_USB_ETH_RNDIS ++ ep_config[1].config = DEV_RNDIS_CONFIG_VALUE; ++#ifdef CONFIG_USB_GADGET_PXA27X ++ ep_config[1].interface = 0; ++#else ++ ep_config[1].interface = rndis_data_intf.bInterfaceNumber; ++#endif ++ ep_config[1].altinterface = rndis_data_intf.bAlternateSetting; ++ ++ in_ep = usb_ep_autoconfig(gadget, &fs_source_desc, &ep_config[0], 2); ++#else ++ in_ep = usb_ep_autoconfig(gadget, &fs_source_desc, &ep_config[0], 1); ++#endif ++ + if (!in_ep) { + autoconf_fail: + dev_err (&gadget->dev, +@@ -2396,7 +2428,12 @@ autoconf_fail: + } + in_ep->driver_data = in_ep; /* claim */ + +- out_ep = usb_ep_autoconfig (gadget, &fs_sink_desc); ++#ifdef CONFIG_USB_ETH_RNDIS ++ out_ep = usb_ep_autoconfig(gadget, &fs_sink_desc, &ep_config[0], 2); ++#else ++ out_ep = usb_ep_autoconfig(gadget, &fs_sink_desc, &ep_config[0], 1); ++#endif ++ + if (!out_ep) + goto autoconf_fail; + out_ep->driver_data = out_ep; /* claim */ +@@ -2406,7 +2443,25 @@ autoconf_fail: + * Since some hosts expect one, try to allocate one anyway. + */ + if (cdc || rndis) { +- status_ep = usb_ep_autoconfig (gadget, &fs_status_desc); ++#ifdef DEV_CONFIG_CDC ++ ep_config[0].config = DEV_CONFIG_VALUE; ++ ep_config[0].interface = control_intf.bInterfaceNumber; ++ ep_config[0].altinterface = control_intf.bAlternateSetting; ++#endif ++#ifdef CONFIG_USB_ETH_RNDIS ++ ep_config[1].config = DEV_RNDIS_CONFIG_VALUE; ++ ep_config[1].interface = rndis_control_intf.bInterfaceNumber; ++ ep_config[1].altinterface = rndis_control_intf.bAlternateSetting; ++#endif ++ ++#if defined(DEV_CONFIG_CDC) && defined(CONFIG_USB_ETH_RNDIS) ++ status_ep = usb_ep_autoconfig(gadget, &fs_status_desc, &ep_config[0], 2); ++#elif defined(CONFIG_USB_ETH_RNDIS) ++ status_ep = usb_ep_autoconfig(gadget, &fs_status_desc, &ep_config[1], 1); ++#else ++ status_ep = usb_ep_autoconfig(gadget, &fs_status_desc, &ep_config[0], 1); ++#endif ++ + if (status_ep) { + status_ep->driver_data = status_ep; /* claim */ + } else if (rndis) { +diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c +index 965ad7b..b9cd8c9 100644 +--- a/drivers/usb/gadget/file_storage.c ++++ b/drivers/usb/gadget/file_storage.c +@@ -3841,6 +3841,7 @@ static int __init fsg_bind(struct usb_gadget *gadget) + struct usb_ep *ep; + struct usb_request *req; + char *pathbuf, *p; ++ struct usb_endpoint_config ep_config; + + fsg->gadget = gadget; + set_gadget_data(gadget, fsg); +@@ -3911,21 +3912,25 @@ static int __init fsg_bind(struct usb_gadget *gadget) + } + + /* Find all the endpoints we will use */ ++ ep_config.config = CONFIG_VALUE; ++ ep_config.interface = intf_desc.bInterfaceNumber; ++ ep_config.altinterface = intf_desc.bAlternateSetting; ++ + usb_ep_autoconfig_reset(gadget); +- ep = usb_ep_autoconfig(gadget, &fs_bulk_in_desc); ++ ep = usb_ep_autoconfig(gadget, &fs_bulk_in_desc, &ep_config, 1); + if (!ep) + goto autoconf_fail; + ep->driver_data = fsg; // claim the endpoint + fsg->bulk_in = ep; + +- ep = usb_ep_autoconfig(gadget, &fs_bulk_out_desc); ++ ep = usb_ep_autoconfig(gadget, &fs_bulk_out_desc, &ep_config, 1); + if (!ep) + goto autoconf_fail; + ep->driver_data = fsg; // claim the endpoint + fsg->bulk_out = ep; + + if (transport_is_cbi()) { +- ep = usb_ep_autoconfig(gadget, &fs_intr_in_desc); ++ ep = usb_ep_autoconfig(gadget, &fs_intr_in_desc, &ep_config, 1); + if (!ep) + goto autoconf_fail; + ep->driver_data = fsg; // claim the endpoint +diff --git a/drivers/usb/gadget/pxa27x_udc.c b/drivers/usb/gadget/pxa27x_udc.c +new file mode 100644 +index 0000000..d4270d4 +--- /dev/null ++++ b/drivers/usb/gadget/pxa27x_udc.c +@@ -0,0 +1,2387 @@ ++/* ++ * Handles the Intel 27x USB Device Controller (UDC) ++ * ++ * Copyright (C) 2002 Intrinsyc, Inc. (Frank Becker) ++ * Copyright (C) 2003 Robert Schwebel, Pengutronix ++ * Copyright (C) 2003 Benedikt Spranger, Pengutronix ++ * Copyright (C) 2003 David Brownell ++ * Copyright (C) 2003 Joshua Wise ++ * Copyright (C) 2004 Intel Corporation ++ * Copyright (C) 2005 SDG Systems, LLC (Aric Blumer) ++ * Copyright (C) 2005-2006 Openedhand Ltd. (Richard Purdie) ++ * ++ * 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 ++ * ++ */ ++ ++#undef DEBUG ++//#define DEBUG 1 ++//#define VERBOSE DBG_VERBOSE ++ ++#include <linux/module.h> ++#include <linux/kernel.h> ++#include <linux/ioport.h> ++#include <linux/types.h> ++#include <linux/version.h> ++#include <linux/errno.h> ++#include <linux/platform_device.h> ++#include <linux/delay.h> ++#include <linux/sched.h> ++#include <linux/slab.h> ++#include <linux/init.h> ++#include <linux/timer.h> ++#include <linux/list.h> ++#include <linux/interrupt.h> ++#include <linux/proc_fs.h> ++#include <linux/mm.h> ++#include <linux/device.h> ++#include <linux/dma-mapping.h> ++ ++#include <asm/byteorder.h> ++#include <asm/dma.h> ++#include <asm/io.h> ++#include <asm/irq.h> ++#include <asm/system.h> ++#include <asm/mach-types.h> ++#include <asm/unaligned.h> ++#include <asm/hardware.h> ++#include <asm/arch/pxa-regs.h> ++ ++#include <linux/usb/ch9.h> ++#include <linux/usb_gadget.h> ++ ++#include <asm/arch/udc.h> ++ ++/* ++ * This driver handles the USB Device Controller (UDC) in Intel's PXA 27x ++ * series processors. ++ * ++ * Such controller drivers work with a gadget driver. The gadget driver ++ * returns descriptors, implements configuration and data protocols used ++ * by the host to interact with this device, and allocates endpoints to ++ * the different protocol interfaces. The controller driver virtualizes ++ * usb hardware so that the gadget drivers will be more portable. ++ * ++ * This UDC hardware wants to implement a bit too much USB protocol. The ++ * biggest issue is that the endpoints have to be setup before the controller ++ * can be enabled and each endpoint can only have one configuration, interface ++ * and alternative interface number. Once enabled, these cannot be changed ++ * without a controller reset. ++ * ++ * Intel Errata #22 mentions issues when changing alternate interface. ++ * The exact meaning of this remains uncertain as gadget drivers using alternate ++ * interfaces such as CDC-Ethernet appear to work... ++ */ ++ ++#define DRIVER_VERSION "01-01-2006" ++#define DRIVER_DESC "PXA 27x USB Device Controller driver" ++ ++static const char driver_name [] = "pxa27x_udc"; ++ ++static const char ep0name [] = "ep0"; ++ ++ ++#define USE_DMA ++//#undef USE_DMA ++ ++#ifdef CONFIG_PROC_FS ++#define UDC_PROC_FILE ++#endif ++ ++#include "pxa27x_udc.h" ++ ++#ifdef USE_DMA ++static int use_dma = 1; ++module_param(use_dma, bool, 0); ++MODULE_PARM_DESC(use_dma, "true to use dma"); ++ ++static void dma_nodesc_handler(int dmach, void *_ep); ++static void kick_dma(struct pxa27x_ep *ep, struct pxa27x_request *req); ++ ++#define DMASTR " (dma support)" ++ ++#else /* !USE_DMA */ ++#define DMASTR " (pio only)" ++#endif ++ ++#define UDCISR0_IR0 0x3 ++#define UDCISR_INT_MASK (UDC_INT_FIFOERROR | UDC_INT_PACKETCMP) ++#define UDCICR_INT_MASK UDCISR_INT_MASK ++ ++#define UDCCSR_MASK (UDCCSR_FST | UDCCSR_DME) ++ ++static void pxa27x_ep_fifo_flush(struct usb_ep *ep); ++static void nuke(struct pxa27x_ep *, int status); ++static void udc_init_ep(struct pxa27x_udc *dev); ++ ++ ++/* ++ * Endpoint Functions ++ */ ++static void pio_irq_enable(int ep_num) ++{ ++ if (ep_num < 16) ++ UDCICR0 |= 3 << (ep_num * 2); ++ else { ++ ep_num -= 16; ++ UDCICR1 |= 3 << (ep_num * 2); ++ } ++} ++ ++static void pio_irq_disable(int ep_num) ++{ ++ ep_num &= 0xf; ++ if (ep_num < 16) ++ UDCICR0 &= ~(3 << (ep_num * 2)); ++ else { ++ ep_num -= 16; ++ UDCICR1 &= ~(3 << (ep_num * 2)); ++ } ++} ++ ++/* The UDCCR reg contains mask and interrupt status bits, ++ * so using '|=' isn't safe as it may ack an interrupt. ++ */ ++#define UDCCR_MASK_BITS (UDCCR_OEN | UDCCR_UDE) ++ ++static inline void udc_set_mask_UDCCR(int mask) ++{ ++ UDCCR = (UDCCR & UDCCR_MASK_BITS) | (mask & UDCCR_MASK_BITS); ++} ++ ++static inline void udc_clear_mask_UDCCR(int mask) ++{ ++ UDCCR = (UDCCR & UDCCR_MASK_BITS) & ~(mask & UDCCR_MASK_BITS); ++} ++ ++static inline void udc_ack_int_UDCCR(int mask) ++{ ++ /* udccr contains the bits we dont want to change */ ++ __u32 udccr = UDCCR & UDCCR_MASK_BITS; ++ ++ UDCCR = udccr | (mask & ~UDCCR_MASK_BITS); ++} ++ ++/* ++ * Endpoint enable/disable ++ * ++ * Not much to do here as the ep_alloc function sets up most things. Once ++ * enabled, not much of the pxa27x configuration can be changed. ++ * ++ */ ++static int pxa27x_ep_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) ++{ ++ struct pxa27x_virt_ep *virt_ep = container_of(_ep, struct pxa27x_virt_ep, usb_ep); ++ struct pxa27x_ep *ep = virt_ep->pxa_ep; ++ struct pxa27x_udc *dev; ++ ++ if (!_ep || !desc || _ep->name == ep0name ++ || desc->bDescriptorType != USB_DT_ENDPOINT ++ || ep->fifo_size < le16_to_cpu(desc->wMaxPacketSize)) { ++ dev_err(ep->dev->dev, "%s, bad ep or descriptor\n", __FUNCTION__); ++ return -EINVAL; ++ } ++ ++ /* xfer types must match, except that interrupt ~= bulk */ ++ if( ep->ep_type != USB_ENDPOINT_XFER_BULK ++ && desc->bmAttributes != USB_ENDPOINT_XFER_INT) { ++ dev_err(ep->dev->dev, "%s, %s type mismatch\n", __FUNCTION__, _ep->name); ++ return -EINVAL; ++ } ++ ++ /* hardware _could_ do smaller, but driver doesn't */ ++ if ((desc->bmAttributes == USB_ENDPOINT_XFER_BULK ++ && le16_to_cpu (desc->wMaxPacketSize) ++ != BULK_FIFO_SIZE) ++ || !desc->wMaxPacketSize) { ++ dev_err(ep->dev->dev, "%s, bad %s maxpacket\n", __FUNCTION__, _ep->name); ++ return -ERANGE; ++ } ++ ++ dev = ep->dev; ++ if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) { ++ dev_err(ep->dev->dev, "%s, bogus device state\n", __FUNCTION__); ++ return -ESHUTDOWN; ++ } ++ ++ ep->desc = desc; ++ ep->dma = -1; ++ ep->stopped = 0; ++ ep->pio_irqs = ep->dma_irqs = 0; ++ ep->usb_ep->maxpacket = le16_to_cpu(desc->wMaxPacketSize); ++ ++ /* flush fifo (mostly for OUT buffers) */ ++ pxa27x_ep_fifo_flush(_ep); ++ ++ /* ... reset halt state too, if we could ... */ ++ ++#ifdef USE_DMA ++ /* for (some) bulk and ISO endpoints, try to get a DMA channel and ++ * bind it to the endpoint. otherwise use PIO. ++ */ ++ dev_dbg(ep->dev->dev, "%s: called attributes=%d\n", __FUNCTION__, ep->ep_type); ++ switch (ep->ep_type) { ++ case USB_ENDPOINT_XFER_ISOC: ++ if (le16_to_cpu(desc->wMaxPacketSize) % 32) ++ break; ++ // fall through ++ case USB_ENDPOINT_XFER_BULK: ++ if (!use_dma || !ep->reg_drcmr) ++ break; ++ ep->dma = pxa_request_dma((char *)_ep->name, (le16_to_cpu(desc->wMaxPacketSize) > 64) ++ ? DMA_PRIO_MEDIUM : DMA_PRIO_LOW, dma_nodesc_handler, ep); ++ if (ep->dma >= 0) { ++ *ep->reg_drcmr = DRCMR_MAPVLD | ep->dma; ++ dev_dbg(ep->dev->dev, "%s using dma%d\n", _ep->name, ep->dma); ++ } ++ default: ++ break; ++ } ++#endif ++ DBG(DBG_VERBOSE, "enabled %s\n", _ep->name); ++ return 0; ++} ++ ++static int pxa27x_ep_disable(struct usb_ep *_ep) ++{ ++ struct pxa27x_virt_ep *virt_ep = container_of(_ep, struct pxa27x_virt_ep, usb_ep); ++ struct pxa27x_ep *ep = virt_ep->pxa_ep; ++ unsigned long flags; ++ ++ if (!_ep || !ep->desc) { ++ dev_err(ep->dev->dev, "%s, %s not enabled\n", __FUNCTION__, ++ _ep ? _ep->name : NULL); ++ return -EINVAL; ++ } ++ local_irq_save(flags); ++ nuke(ep, -ESHUTDOWN); ++ ++#ifdef USE_DMA ++ if (ep->dma >= 0) { ++ *ep->reg_drcmr = 0; ++ pxa_free_dma(ep->dma); ++ ep->dma = -1; ++ } ++#endif ++ ++ /* flush fifo (mostly for IN buffers) */ ++ pxa27x_ep_fifo_flush(_ep); ++ ++ ep->desc = 0; ++ ep->stopped = 1; ++ ++ local_irq_restore(flags); ++ DBG(DBG_VERBOSE, "%s disabled\n", _ep->name); ++ return 0; ++} ++ ++ ++ ++/* for the pxa27x, these can just wrap kmalloc/kfree. gadget drivers ++ * must still pass correctly initialized endpoints, since other controller ++ * drivers may care about how it's currently set up (dma issues etc). ++ */ ++ ++/* ++ * pxa27x_ep_alloc_request - allocate a request data structure ++ */ ++static struct usb_request * ++pxa27x_ep_alloc_request(struct usb_ep *_ep, unsigned gfp_flags) ++{ ++ struct pxa27x_request *req; ++ ++ req = kzalloc(sizeof *req, gfp_flags); ++ if (!req) ++ return 0; ++ ++ INIT_LIST_HEAD(&req->queue); ++ return &req->req; ++} ++ ++ ++/* ++ * pxa27x_ep_free_request - deallocate a request data structure ++ */ ++static void ++pxa27x_ep_free_request(struct usb_ep *_ep, struct usb_request *_req) ++{ ++ struct pxa27x_request *req; ++ ++ req = container_of(_req, struct pxa27x_request, req); ++ WARN_ON(!list_empty(&req->queue)); ++ kfree(req); ++} ++ ++ ++/*-------------------------------------------------------------------------*/ ++ ++/* ++ * done - retire a request; caller blocked irqs ++ */ ++static void done(struct pxa27x_ep *ep, struct pxa27x_request *req, int status) ++{ ++ list_del_init(&req->queue); ++ if (likely (req->req.status == -EINPROGRESS)) ++ req->req.status = status; ++ else ++ status = req->req.status; ++ ++ if (status && status != -ESHUTDOWN) ++ DBG(DBG_VERBOSE, "complete %s req %p stat %d len %u/%u\n", ++ ep->usb_ep->name, &req->req, status, ++ req->req.actual, req->req.length); ++ ++ /* don't modify queue heads during completion callback */ ++ req->req.complete(ep->usb_ep, &req->req); ++} ++ ++ ++static inline void ep0_idle(struct pxa27x_udc *dev) ++{ ++ dev->ep0state = EP0_IDLE; ++} ++ ++static int write_packet(volatile u32 *uddr, struct pxa27x_request *req, unsigned max) ++{ ++ u32 *buf; ++ int length, count, remain; ++ ++ buf = (u32*)(req->req.buf + req->req.actual); ++ prefetch(buf); ++ ++ /* how big will this packet be? */ ++ length = min(req->req.length - req->req.actual, max); ++ req->req.actual += length; ++ ++ remain = length & 0x3; ++ count = length & ~(0x3); ++ ++ //dev_dbg(ep->dev->dev, "Length %d, Remain %d, Count %d\n",length, remain, count); ++ ++ while (likely(count)) { ++ //dev_dbg(ep->dev->dev, "Sending:0x%x\n", *buf); ++ *uddr = *buf++; ++ count -= 4; ++ } ++ ++ if (remain) { ++ volatile u8* reg=(u8*)uddr; ++ char *rd =(u8*)buf; ++ ++ while (remain--) { ++ *reg=*rd++; ++ } ++ } ++ ++ return length; ++} ++ ++/* ++ * write to an IN endpoint fifo, as many packets as possible. ++ * irqs will use this to write the rest later. ++ * caller guarantees at least one packet buffer is ready (or a zlp). ++ */ ++static int ++write_fifo(struct pxa27x_ep *ep, struct pxa27x_request *req) ++{ ++ unsigned max; ++ ++ max = le16_to_cpu(ep->desc->wMaxPacketSize); ++ do { ++ int count, is_last, is_short; ++ ++ //dev_dbg(ep->dev->dev, "write_fifo7 %x\n", *ep->reg_udccsr); ++ ++ if (*ep->reg_udccsr & UDCCSR_PC) { ++ //dev_dbg(ep->dev->dev, "Transmit Complete\n"); ++ *ep->reg_udccsr = UDCCSR_PC | (*ep->reg_udccsr & UDCCSR_MASK); ++ } ++ ++ if (*ep->reg_udccsr & UDCCSR_TRN) { ++ //dev_dbg(ep->dev->dev, "Clearing Underrun\n"); ++ *ep->reg_udccsr = UDCCSR_TRN | (*ep->reg_udccsr & UDCCSR_MASK); ++ } ++ //dev_dbg(ep->dev->dev, "write_fifo8 %x\n", *ep->reg_udccsr); ++ ++ count = write_packet(ep->reg_udcdr, req, max); ++ ++ /* last packet is usually short (or a zlp) */ ++ if (unlikely (count != max)) ++ is_last = is_short = 1; ++ else { ++ if (likely(req->req.length != req->req.actual) ++ || req->req.zero) ++ is_last = 0; ++ else ++ is_last = 1; ++ /* interrupt/iso maxpacket may not fill the fifo */ ++ is_short = unlikely (max < ep->fifo_size); ++ } ++ ++ //dev_dbg(ep->dev->dev, "write_fifo0 %x\n", *ep->reg_udccsr); ++ ++ dev_dbg(ep->dev->dev, "wrote %s count:%d bytes%s%s %d left %p\n", ++ ep->usb_ep->name, count, ++ is_last ? "/L" : "", is_short ? "/S" : "", ++ req->req.length - req->req.actual, &req->req); ++ ++ /* let loose that packet. maybe try writing another one, ++ * double buffering might work. ++ */ ++ ++ if (is_short) ++ *ep->reg_udccsr = UDCCSR_SP | (*ep->reg_udccsr & UDCCSR_MASK); ++ ++ dev_dbg(ep->dev->dev, "write_fifo0.5 %x\n", *ep->reg_udccsr); ++ ++ /* requests complete when all IN data is in the FIFO */ ++ if (is_last) { ++ done(ep, req, 0); ++ if (list_empty(&ep->queue) || unlikely(ep->dma >= 0)) { ++ pio_irq_disable(ep->pxa_ep_num); ++ //dev_dbg(ep->dev->dev, "write_fifo1 %x\n", *ep->reg_udccsr); ++#ifdef USE_DMA ++ /* unaligned data and zlps couldn't use dma */ ++ if (unlikely(!list_empty(&ep->queue))) { ++ req = list_entry(ep->queue.next, ++ struct pxa27x_request, queue); ++ kick_dma(ep,req); ++ return 0; ++ } ++#endif ++ } ++ //dev_dbg(ep->dev->dev, "write_fifo2 %x\n", *ep->reg_udccsr); ++ return 1; ++ } ++ ++ // TODO experiment: how robust can fifo mode tweaking be? ++ // double buffering is off in the default fifo mode, which ++ // prevents TFS from being set here. ++ ++ } while (*ep->reg_udccsr & UDCCSR_FS); ++ //dev_dbg(ep->dev->dev, "write_fifo2 %x\n", *ep->reg_udccsr); ++ return 0; ++} ++ ++/* caller asserts req->pending (ep0 irq status nyet cleared); starts ++ * ep0 data stage. these chips want very simple state transitions. ++ */ ++static inline ++void ep0start(struct pxa27x_udc *dev, u32 flags, const char *tag) ++{ ++ UDCCSR0 = flags|UDCCSR0_SA|UDCCSR0_OPC; ++ UDCISR0 = UDCICR_INT(0, UDC_INT_FIFOERROR | UDC_INT_PACKETCMP); ++ dev->req_pending = 0; ++ DBG(DBG_VERY_NOISY, "%s %s, %02x/%02x\n", ++ __FUNCTION__, tag, UDCCSR0, flags); ++} ++ ++static int ++write_ep0_fifo(struct pxa27x_ep *ep, struct pxa27x_request *req) ++{ ++ unsigned count; ++ int is_short; ++ ++ count = write_packet(&UDCDR0, req, EP0_FIFO_SIZE); ++ ep->dev->stats.write.bytes += count; ++ ++ /* last packet "must be" short (or a zlp) */ ++ is_short = (count != EP0_FIFO_SIZE); ++ ++ DBG(DBG_VERY_NOISY, "ep0in %d bytes %d left %p\n", count, ++ req->req.length - req->req.actual, &req->req); ++ ++ if (unlikely (is_short)) { ++ if (ep->dev->req_pending) ++ ep0start(ep->dev, UDCCSR0_IPR, "short IN"); ++ else ++ UDCCSR0 = UDCCSR0_IPR; ++ ++ count = req->req.length; ++ done(ep, req, 0); ++ ep0_idle(ep->dev); ++#if 0 ++ /* This seems to get rid of lost status irqs in some cases: ++ * host responds quickly, or next request involves config ++ * change automagic, or should have been hidden, or ... ++ * ++ * FIXME get rid of all udelays possible... ++ */ ++ if (count >= EP0_FIFO_SIZE) { ++ count = 100; ++ do { ++ if ((UDCCSR0 & UDCCSR0_OPC) != 0) { ++ /* clear OPC, generate ack */ ++ UDCCSR0 = UDCCSR0_OPC; ++ break; ++ } ++ count--; ++ udelay(1); ++ } while (count); ++ } ++#endif ++ } else if (ep->dev->req_pending) ++ ep0start(ep->dev, 0, "IN"); ++ return is_short; ++} ++ ++ ++/* ++ * read_fifo - unload packet(s) from the fifo we use for usb OUT ++ * transfers and put them into the request. caller should have made ++ * sure there's at least one packet ready. ++ * ++ * returns true if the request completed because of short packet or the ++ * request buffer having filled (and maybe overran till end-of-packet). ++ */ ++static int read_fifo(struct pxa27x_ep *ep, struct pxa27x_request *req) ++{ ++ for (;;) { ++ u32 *buf; ++ int bufferspace, count, is_short; ++ ++ /* make sure there's a packet in the FIFO.*/ ++ if (unlikely ((*ep->reg_udccsr & UDCCSR_PC) == 0)) ++ break; ++ buf =(u32*) (req->req.buf + req->req.actual); ++ prefetchw(buf); ++ bufferspace = req->req.length - req->req.actual; ++ ++ /* read all bytes from this packet */ ++ if (likely (*ep->reg_udccsr & UDCCSR_BNE)) { ++ count = 0x3ff & *ep->reg_udcbcr; ++ req->req.actual += min(count, bufferspace); ++ } else /* zlp */ ++ count = 0; ++ ++ is_short = (count < ep->usb_ep->maxpacket); ++ dev_dbg(ep->dev->dev, "read %s udccsr:%02x, count:%d bytes%s req %p %d/%d\n", ++ ep->usb_ep->name, *ep->reg_udccsr, count, ++ is_short ? "/S" : "", ++ &req->req, req->req.actual, req->req.length); ++ ++ count = min(count, bufferspace); ++ while (likely (count > 0)) { ++ *buf++ = *ep->reg_udcdr; ++ count -= 4; ++ } ++ dev_dbg(ep->dev->dev, "Buf:0x%p\n", req->req.buf); ++ ++ *ep->reg_udccsr = UDCCSR_PC; ++ /* RPC/RSP/RNE could now reflect the other packet buffer */ ++ ++ /* completion */ ++ if (is_short || req->req.actual == req->req.length) { ++ done(ep, req, 0); ++ if (list_empty(&ep->queue)) ++ pio_irq_disable(ep->pxa_ep_num); ++ return 1; ++ } ++ ++ /* finished that packet. the next one may be waiting... */ ++ } ++ return 0; ++} ++ ++/* ++ * special ep0 version of the above. no UBCR0 or double buffering; status ++ * handshaking is magic. most device protocols don't need control-OUT. ++ * CDC vendor commands (and RNDIS), mass storage CB/CBI, and some other ++ * protocols do use them. ++ */ ++static int read_ep0_fifo(struct pxa27x_ep *ep, struct pxa27x_request *req) ++{ ++ u32 *buf, word; ++ unsigned bufferspace; ++ ++ buf = (u32*) (req->req.buf + req->req.actual); ++ bufferspace = req->req.length - req->req.actual; ++ ++ while (UDCCSR0 & UDCCSR0_RNE) { ++ word = UDCDR0; ++ ++ if (unlikely (bufferspace == 0)) { ++ /* this happens when the driver's buffer ++ * is smaller than what the host sent. ++ * discard the extra data. ++ */ ++ if (req->req.status != -EOVERFLOW) ++ dev_info(ep->dev->dev, "%s overflow\n", ep->usb_ep->name); ++ req->req.status = -EOVERFLOW; ++ } else { ++ *buf++ = word; ++ req->req.actual += 4; ++ bufferspace -= 4; ++ } ++ } ++ ++ UDCCSR0 = UDCCSR0_OPC ; ++ ++ /* completion */ ++ if (req->req.actual >= req->req.length) ++ return 1; ++ ++ /* finished that packet. the next one may be waiting... */ ++ return 0; ++} ++ ++#ifdef USE_DMA ++ ++#define MAX_IN_DMA ((DCMD_LENGTH + 1) - BULK_FIFO_SIZE) ++static void kick_dma(struct pxa27x_ep *ep, struct pxa27x_request *req) ++{ ++ u32 dcmd = 0; ++ u32 len = req->req.length; ++ u32 buf = req->req.dma; ++ u32 fifo = io_v2p((u32)ep->reg_udcdr); ++ ++ buf += req->req.actual; ++ len -= req->req.actual; ++ ep->dma_con = 0; ++ ++ DMSG("%s: req:0x%p length:%d, actual:%d dma:%d\n", ++ __FUNCTION__, &req->req, req->req.length, ++ req->req.actual,ep->dma); ++ ++ /* no-descriptor mode can be simple for bulk-in, iso-in, iso-out */ ++ DCSR(ep->dma) = DCSR_NODESC; ++ if (buf & 0x3) ++ DALGN |= 1 << ep->dma; ++ else ++ DALGN &= ~(1 << ep->dma); ++ ++ if (ep->dir_in) { ++ DSADR(ep->dma) = buf; ++ DTADR(ep->dma) = fifo; ++ if (len > MAX_IN_DMA) { ++ len= MAX_IN_DMA; ++ ep->dma_con =1 ; ++ } else if (len >= ep->usb_ep->maxpacket) { ++ if ((ep->dma_con = (len % ep->usb_ep->maxpacket) != 0)) ++ len = ep->usb_ep->maxpacket; ++ } ++ dcmd = len | DCMD_BURST32 | DCMD_WIDTH4 | DCMD_ENDIRQEN ++ | DCMD_FLOWTRG | DCMD_INCSRCADDR; ++ } else { ++ DSADR(ep->dma) = fifo; ++ DTADR(ep->dma) = buf; ++ dcmd = len | DCMD_BURST32 | DCMD_WIDTH4 | DCMD_ENDIRQEN ++ | DCMD_FLOWSRC | DCMD_INCTRGADDR; ++ } ++ *ep->reg_udccsr = UDCCSR_DME; ++ DCMD(ep->dma) = dcmd; ++ DCSR(ep->dma) = DCSR_NODESC | DCSR_EORIRQEN \ ++ | ((ep->dir_in) ? DCSR_STOPIRQEN : 0); ++ *ep->reg_drcmr = ep->dma | DRCMR_MAPVLD; ++ DCSR(ep->dma) |= DCSR_RUN; ++} ++ ++static void cancel_dma(struct pxa27x_ep *ep) ++{ ++ struct pxa27x_request *req; ++ u32 tmp; ++ ++ if (DCSR(ep->dma) == 0 || list_empty(&ep->queue)) ++ return; ++ ++ DMSG("hehe dma:%d,dcsr:0x%x\n", ep->dma, DCSR(ep->dma)); ++ DCSR(ep->dma) = 0; ++ while ((DCSR(ep->dma) & DCSR_STOPSTATE) == 0) ++ cpu_relax(); ++ ++ req = list_entry(ep->queue.next, struct pxa27x_request, queue); ++ tmp = DCMD(ep->dma) & DCMD_LENGTH; ++ req->req.actual = req->req.length - tmp; ++ ++ /* the last tx packet may be incomplete, so flush the fifo. ++ * FIXME correct req.actual if we can ++ */ ++ *ep->reg_udccsr = UDCCSR_FEF; ++} ++ ++static void dma_nodesc_handler(int dmach, void *_ep) ++{ ++ struct pxa27x_ep *ep = _ep; ++ struct pxa27x_request *req, *req_next; ++ u32 dcsr, tmp, completed; ++ ++ local_irq_disable(); ++ ++ req = list_entry(ep->queue.next, struct pxa27x_request, queue); ++ ++ DMSG("%s, buf:0x%p\n",__FUNCTION__, req->req.buf); ++ ++ ep->dma_irqs++; ++ ep->dev->stats.irqs++; ++ ++ completed = 0; ++ ++ dcsr = DCSR(dmach); ++ DCSR(ep->dma) &= ~DCSR_RUN; ++ ++ if (dcsr & DCSR_BUSERR) { ++ DCSR(dmach) = DCSR_BUSERR; ++ dev_err(ep->dev->dev, "DMA Bus Error\n"); ++ req->req.status = -EIO; ++ completed = 1; ++ } else if (dcsr & DCSR_ENDINTR) { ++ DCSR(dmach) = DCSR_ENDINTR; ++ if (ep->dir_in) { ++ tmp = req->req.length - req->req.actual; ++ /* Last packet is a short one*/ ++ if (tmp < ep->usb_ep->maxpacket) { ++ int count = 0; ++ ++ *ep->reg_udccsr = UDCCSR_SP | \ ++ (*ep->reg_udccsr & UDCCSR_MASK); ++ /*Wait for packet out */ ++ while( (count++ < 10000) && \ ++ !(*ep->reg_udccsr & UDCCSR_FS)); ++ if (count >= 10000) ++ DMSG("Failed to send packet\n"); ++ else ++ DMSG("%s: short packet sent len:%d," ++ "length:%d,actual:%d\n", __FUNCTION__, ++ tmp, req->req.length, req->req.actual); ++ req->req.actual = req->req.length; ++ completed = 1; ++ /* There are still packets to transfer */ ++ } else if ( ep->dma_con) { ++ DMSG("%s: more packets,length:%d,actual:%d\n", ++ __FUNCTION__,req->req.length, ++ req->req.actual); ++ req->req.actual += ep->usb_ep->maxpacket; ++ completed = 0; ++ } else { ++ DMSG("%s: no more packets,length:%d," ++ "actual:%d\n", __FUNCTION__, ++ req->req.length, req->req.actual); ++ req->req.actual = req->req.length; ++ completed = 1; ++ } ++ } else { ++ req->req.actual = req->req.length; ++ completed = 1; ++ } ++ } else if (dcsr & DCSR_EORINTR) { //Only happened in OUT DMA ++ int remain,udccsr ; ++ ++ DCSR(dmach) = DCSR_EORINTR; ++ remain = DCMD(dmach) & DCMD_LENGTH; ++ req->req.actual = req->req.length - remain; ++ ++ udccsr = *ep->reg_udccsr; ++ if (udccsr & UDCCSR_SP) { ++ *ep->reg_udccsr = UDCCSR_PC | (udccsr & UDCCSR_MASK); ++ completed = 1; ++ } ++ DMSG("%s: length:%d actual:%d\n", ++ __FUNCTION__, req->req.length, req->req.actual); ++ } else ++ DMSG("%s: Others dma:%d DCSR:0x%x DCMD:0x%x\n", ++ __FUNCTION__, dmach, DCSR(dmach), DCMD(dmach)); ++ ++ if (likely(completed)) { ++ if (req->queue.next != &ep->queue) { ++ req_next = list_entry(req->queue.next, ++ struct pxa27x_request, queue); ++ kick_dma(ep, req_next); ++ } ++ done(ep, req, 0); ++ } else { ++ kick_dma(ep, req); ++ } ++ ++ local_irq_enable(); ++} ++ ++#endif ++/*-------------------------------------------------------------------------*/ ++ ++static int ++pxa27x_ep_queue(struct usb_ep *_ep, struct usb_request *_req, unsigned gfp_flags) ++{ ++ struct pxa27x_virt_ep *virt_ep; ++ struct pxa27x_ep *ep; ++ struct pxa27x_request *req; ++ struct pxa27x_udc *dev; ++ unsigned long flags; ++ ++ virt_ep = container_of(_ep, struct pxa27x_virt_ep, usb_ep); ++ ep = virt_ep->pxa_ep; ++ ++ req = container_of(_req, struct pxa27x_request, req); ++ if (unlikely (!_req || !_req->complete || !_req->buf|| ++ !list_empty(&req->queue))) { ++ DMSG("%s, bad params\n", __FUNCTION__); ++ return -EINVAL; ++ } ++ ++ if (unlikely (!_ep || (!ep->desc && _ep->name != ep0name))) { ++ DMSG("%s, bad ep\n", __FUNCTION__); ++ return -EINVAL; ++ } ++ ++ DMSG("%s, ep point %d is queue\n", __FUNCTION__, ep->ep_num); ++ ++ dev = ep->dev; ++ if (unlikely (!dev->driver ++ || dev->gadget.speed == USB_SPEED_UNKNOWN)) { ++ DMSG("%s, bogus device state\n", __FUNCTION__); ++ return -ESHUTDOWN; ++ } ++ ++ /* iso is always one packet per request, that's the only way ++ * we can report per-packet status. that also helps with dma. ++ */ ++ if (unlikely (ep->ep_type == USB_ENDPOINT_XFER_ISOC ++ && req->req.length > le16_to_cpu ++ (ep->desc->wMaxPacketSize))) ++ return -EMSGSIZE; ++ ++#ifdef USE_DMA ++ // FIXME caller may already have done the dma mapping ++ if (ep->dma >= 0) { ++ _req->dma = dma_map_single(dev->dev, _req->buf, _req->length, ++ (ep->dir_in) ? DMA_TO_DEVICE : DMA_FROM_DEVICE); ++ } ++#endif ++ ++ DBG(DBG_NOISY, "%s queue req %p, len %d buf %p\n", ++ _ep->name, _req, _req->length, _req->buf); ++ ++ local_irq_save(flags); ++ ++ _req->status = -EINPROGRESS; ++ _req->actual = 0; ++ ++ /* kickstart this i/o queue? */ ++ if (list_empty(&ep->queue) && !ep->stopped) { ++ if (ep->desc == 0 /* ep0 */) { ++ unsigned length = _req->length; ++ ++ switch (dev->ep0state) { ++ case EP0_IN_DATA_PHASE: ++ dev->stats.write.ops++; ++ if (write_ep0_fifo(ep, req)) ++ req = 0; ++ break; ++ ++ case EP0_OUT_DATA_PHASE: ++ dev->stats.read.ops++; ++ if (dev->req_pending) ++ ep0start(dev, UDCCSR0_IPR, "OUT"); ++ if (length == 0 || ((UDCCSR0 & UDCCSR0_RNE) != 0 ++ && read_ep0_fifo(ep, req))) { ++ ep0_idle(dev); ++ done(ep, req, 0); ++ req = 0; ++ } ++ break; ++ case EP0_NO_ACTION: ++ ep0_idle(dev); ++ req=0; ++ break; ++ default: ++ DMSG("ep0 i/o, odd state %d\n", dev->ep0state); ++ local_irq_restore (flags); ++ return -EL2HLT; ++ } ++#ifdef USE_DMA ++ /* either start dma or prime pio pump */ ++ } else if (ep->dma >= 0) { ++ kick_dma(ep, req); ++#endif ++ /* can the FIFO can satisfy the request immediately? */ ++ } else if (ep->dir_in && (*ep->reg_udccsr & UDCCSR_FS) != 0 ++ && write_fifo(ep, req)) { ++ req = 0; ++ } else if ((*ep->reg_udccsr & UDCCSR_FS) != 0 ++ && read_fifo(ep, req)) { ++ req = 0; ++ } ++ DMSG("req:%p,ep->desc:%p,ep->dma:%d\n", req, ep->desc, ep->dma); ++ if (likely (req && ep->desc) && ep->dma < 0) ++ pio_irq_enable(ep->pxa_ep_num); ++ } ++ ++ /* pio or dma irq handler advances the queue. */ ++ if (likely (req != 0)) ++ list_add_tail(&req->queue, &ep->queue); ++ local_irq_restore(flags); ++ ++ return 0; ++} ++ ++ ++/* ++ * nuke - dequeue ALL requests ++ */ ++static void nuke(struct pxa27x_ep *ep, int status) ++{ ++ struct pxa27x_request *req; ++ ++ /* called with irqs blocked */ ++#ifdef USE_DMA ++ if (ep->dma >= 0 && !ep->stopped) ++ cancel_dma(ep); ++#endif ++ while (!list_empty(&ep->queue)) { ++ req = list_entry(ep->queue.next, struct pxa27x_request, queue); ++ done(ep, req, status); ++ } ++ if (ep->desc) ++ pio_irq_disable(ep->pxa_ep_num); ++} ++ ++ ++/* dequeue JUST ONE request */ ++static int pxa27x_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req) ++{ ++ struct pxa27x_virt_ep *virt_ep = container_of(_ep, struct pxa27x_virt_ep, usb_ep); ++ struct pxa27x_ep *ep = virt_ep->pxa_ep; ++ struct pxa27x_request *req; ++ unsigned long flags; ++ ++ if (!_ep || _ep->name == ep0name) ++ return -EINVAL; ++ ++ local_irq_save(flags); ++ ++ /* make sure it's actually queued on this endpoint */ ++ list_for_each_entry(req, &ep->queue, queue) { ++ if (&req->req == _req) ++ break; ++ } ++ if (&req->req != _req) { ++ local_irq_restore(flags); ++ return -EINVAL; ++ } ++ ++#ifdef USE_DMA ++ if (ep->dma >= 0 && ep->queue.next == &req->queue && !ep->stopped) { ++ cancel_dma(ep); ++ done(ep, req, -ECONNRESET); ++ /* restart i/o */ ++ if (!list_empty(&ep->queue)) { ++ req = list_entry(ep->queue.next, ++ struct pxa27x_request, queue); ++ kick_dma(ep, req); ++ } ++ } else ++#endif ++ done(ep, req, -ECONNRESET); ++ ++ local_irq_restore(flags); ++ return 0; ++} ++ ++/*-------------------------------------------------------------------------*/ ++ ++static int pxa27x_ep_set_halt(struct usb_ep *_ep, int value) ++{ ++ struct pxa27x_virt_ep *virt_ep = container_of(_ep, struct pxa27x_virt_ep, usb_ep); ++ struct pxa27x_ep *ep = virt_ep->pxa_ep; ++ unsigned long flags; ++ ++ DMSG("%s is called\n", __FUNCTION__); ++ if (unlikely (!_ep || (!ep->desc && _ep->name != ep0name)) ++ || ep->ep_type == USB_ENDPOINT_XFER_ISOC) { ++ DMSG("%s, bad ep\n", __FUNCTION__); ++ return -EINVAL; ++ } ++ if (value == 0) { ++ /* this path (reset toggle+halt) is needed to implement ++ * SET_INTERFACE on normal hardware. but it can't be ++ * done from software on the PXA UDC, and the hardware ++ * forgets to do it as part of SET_INTERFACE automagic. ++ */ ++ DMSG("only host can clear %s halt\n", _ep->name); ++ return -EROFS; ++ } ++ ++ local_irq_save(flags); ++ ++ if (ep->dir_in && ((*ep->reg_udccsr & UDCCSR_FS) == 0 ++ || !list_empty(&ep->queue))) { ++ local_irq_restore(flags); ++ return -EAGAIN; ++ } ++ ++ /* FST bit is the same for control, bulk in, bulk out, interrupt in */ ++ *ep->reg_udccsr = UDCCSR_FST|UDCCSR_FEF; ++ ++ /* ep0 needs special care */ ++ if (!ep->desc) { ++ start_watchdog(ep->dev); ++ ep->dev->req_pending = 0; ++ ep->dev->ep0state = EP0_STALL; ++ ++ /* and bulk/intr endpoints like dropping stalls too */ ++ } else { ++ unsigned i; ++ for (i = 0; i < 1000; i += 20) { ++ if (*ep->reg_udccsr & UDCCSR_SST) ++ break; ++ udelay(20); ++ } ++ } ++ local_irq_restore(flags); ++ ++ DBG(DBG_VERBOSE, "%s halt\n", _ep->name); ++ return 0; ++} ++ ++static int pxa27x_ep_fifo_status(struct usb_ep *_ep) ++{ ++ struct pxa27x_virt_ep *virt_ep = container_of(_ep, struct pxa27x_virt_ep, usb_ep); ++ struct pxa27x_ep *ep = virt_ep->pxa_ep; ++ ++ if (!_ep) { ++ DMSG("%s, bad ep\n", __FUNCTION__); ++ return -ENODEV; ++ } ++ /* pxa can't report unclaimed bytes from IN fifos */ ++ if (ep->dir_in) ++ return -EOPNOTSUPP; ++ if (ep->dev->gadget.speed == USB_SPEED_UNKNOWN ++ || (*ep->reg_udccsr & UDCCSR_FS) == 0) ++ return 0; ++ else ++ return (*ep->reg_udcbcr & 0xfff) + 1; ++} ++ ++static void pxa27x_ep_fifo_flush(struct usb_ep *_ep) ++{ ++ struct pxa27x_virt_ep *virt_ep = container_of(_ep, struct pxa27x_virt_ep, usb_ep); ++ struct pxa27x_ep *ep = virt_ep->pxa_ep; ++ ++ DMSG("pxa27x_ep_fifo_flush\n"); ++ ++ if (!_ep || _ep->name == ep0name || !list_empty(&ep->queue)) { ++ DMSG("%s, bad ep\n", __FUNCTION__); ++ return; ++ } ++ ++ /* toggle and halt bits stay unchanged */ ++ ++ /* for OUT, just read and discard the FIFO contents. */ ++ if (!ep->dir_in) { ++ while (((*ep->reg_udccsr) & UDCCSR_BNE) != 0) ++ (void) *ep->reg_udcdr; ++ return; ++ } ++ ++ /* most IN status is the same, but ISO can't stall */ ++ *ep->reg_udccsr = UDCCSR_PC|UDCCSR_FST|UDCCSR_TRN ++ | (ep->ep_type == USB_ENDPOINT_XFER_ISOC) ++ ? 0 : UDCCSR_SST; ++} ++ ++ ++static struct usb_ep_ops pxa27x_ep_ops = { ++ .enable = pxa27x_ep_enable, ++ .disable = pxa27x_ep_disable, ++ ++ .alloc_request = pxa27x_ep_alloc_request, ++ .free_request = pxa27x_ep_free_request, ++ ++ .queue = pxa27x_ep_queue, ++ .dequeue = pxa27x_ep_dequeue, ++ ++ .set_halt = pxa27x_ep_set_halt, ++ .fifo_status = pxa27x_ep_fifo_status, ++ .fifo_flush = pxa27x_ep_fifo_flush, ++}; ++ ++ ++/* --------------------------------------------------------------------------- ++ * device-scoped parts of the api to the usb controller hardware ++ * --------------------------------------------------------------------------- ++ */ ++ ++static inline unsigned int validate_fifo_size(u8 bmAttributes) ++{ ++ switch (bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { ++ case USB_ENDPOINT_XFER_CONTROL: ++ return EP0_FIFO_SIZE; ++ break; ++ case USB_ENDPOINT_XFER_ISOC: ++ return ISO_FIFO_SIZE; ++ break; ++ case USB_ENDPOINT_XFER_BULK: ++ return BULK_FIFO_SIZE; ++ break; ++ case USB_ENDPOINT_XFER_INT: ++ return INT_FIFO_SIZE; ++ break; ++ default: ++ break; ++ } ++} ++ ++static void pxa27x_ep_free(struct usb_gadget *gadget, struct usb_ep *_ep) ++{ ++ struct pxa27x_udc *dev = the_controller; ++ struct pxa27x_virt_ep *virt_ep; ++ int i; ++ ++ virt_ep = container_of(_ep, struct pxa27x_virt_ep, usb_ep); ++ ++ for (i = 1; i < UDC_EP_NUM; i++) { ++ if (dev->ep[i].usb_ep == &virt_ep->usb_ep) { ++ if (dev->ep[i].desc) { ++ virt_ep->pxa_ep = &dev->ep[i]; ++ pxa27x_ep_disable(&virt_ep->usb_ep); ++ } ++ dev->ep[i].usb_ep = NULL; ++ } ++ } ++ ++ if (!list_empty(&virt_ep->usb_ep.ep_list)) ++ list_del_init(&virt_ep->usb_ep.ep_list); ++ ++ kfree(virt_ep->usb_ep.name); ++ kfree(virt_ep); ++} ++ ++static void pxa27x_ep_freeall(struct usb_gadget *gadget) ++{ ++ struct pxa27x_udc *dev = the_controller; ++ int i; ++ ++ for (i = 1; i < UDC_EP_NUM; i++) { ++ if(dev->ep[i].usb_ep) ++ pxa27x_ep_free(gadget, dev->ep[i].usb_ep); ++ } ++} ++ ++#define NAME_SIZE 18 ++ ++static int pxa27x_find_free_ep(struct pxa27x_udc *dev) ++{ ++ int i; ++ for (i = 1; i < UDC_EP_NUM; i++) { ++ if(!dev->ep[i].assigned) ++ return i; ++ } ++ return -1; ++} ++ ++/* ++ * Endpoint Allocation/Configuration ++ * ++ * pxa27x endpoint configuration is fixed when the device is enabled. Any pxa ++ * endpoint is only active in one configuration, interface and alternate ++ * interface combination so to support gadget drivers, we map one usb_ep to ++ * one of several pxa ep's. One pxa endpoint is assigned per configuration ++ * combination. ++ */ ++static struct usb_ep* pxa27x_ep_alloc(struct usb_gadget *gadget, struct usb_endpoint_descriptor *desc, ++ struct usb_endpoint_config *epconfig, int configs) ++{ ++ struct pxa27x_udc *dev = the_controller; ++ struct pxa27x_virt_ep *virt_ep; ++ unsigned int i, fifo_size; ++ char *name; ++ ++ if (unlikely(configs < 1)) { ++ dev_err(dev->dev, "%s: Error in config data\n", __FUNCTION__); ++ return NULL; ++ } ++ ++ virt_ep = kmalloc(sizeof(struct pxa27x_virt_ep), GFP_KERNEL); ++ name = kmalloc(NAME_SIZE, GFP_KERNEL); ++ if (!virt_ep || !name) { ++ dev_err(dev->dev, "%s: -ENOMEM\n", __FUNCTION__); ++ kfree(name); ++ kfree(virt_ep); ++ return NULL; ++ } ++ ++ if (!(desc->wMaxPacketSize)) { ++ fifo_size = validate_fifo_size(desc->bmAttributes); ++ desc->wMaxPacketSize = fifo_size; ++ } else { ++ fifo_size = desc->wMaxPacketSize; ++ } ++ ++ DMSG("pxa27x_ep_alloc: bLength: %d, bDescriptorType: %x, bEndpointAddress: %x,\n" ++ " bmAttributes: %x, wMaxPacketSize: %d\n", desc->bLength, ++ desc->bDescriptorType, desc->bEndpointAddress, desc->bmAttributes, ++ desc->wMaxPacketSize); ++ ++ if (!(desc->bEndpointAddress & 0xF)) ++ desc->bEndpointAddress |= dev->ep_num; ++ ++ for (i = 0; i < configs; i++) ++ { ++ struct pxa27x_ep *pxa_ep; ++ int j; ++ ++ DMSG("pxa27x_ep_alloc: config: %d, interface: %d, altinterface: %x,\n", ++ epconfig->config, epconfig->interface, epconfig->altinterface); ++ ++ j = pxa27x_find_free_ep(dev); ++ ++ if (unlikely(j < 0)) { ++ dev_err(dev->dev, "pxa27x_ep_alloc: Failed to find a spare endpoint\n"); ++ pxa27x_ep_free(gadget, &virt_ep->usb_ep); ++ return NULL; ++ } ++ ++ pxa_ep = &dev->ep[j]; ++ ++ if (i == 0) ++ virt_ep->pxa_ep = pxa_ep; ++ ++ pxa_ep->assigned = 1; ++ pxa_ep->ep_num = dev->ep_num; ++ pxa_ep->pxa_ep_num = j; ++ pxa_ep->usb_ep = &virt_ep->usb_ep; ++ pxa_ep->dev = dev; ++ pxa_ep->desc = desc; ++ pxa_ep->pio_irqs = pxa_ep->dma_irqs = 0; ++ pxa_ep->dma = -1; ++ ++ pxa_ep->fifo_size = fifo_size; ++ pxa_ep->dir_in = (desc->bEndpointAddress & USB_DIR_IN) ? 1 : 0; ++ pxa_ep->ep_type = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; ++ pxa_ep->stopped = 1; ++ pxa_ep->dma_con = 0; ++ pxa_ep->config = epconfig->config; ++ pxa_ep->interface = epconfig->interface; ++ pxa_ep->aisn = epconfig->altinterface; ++ ++ pxa_ep->reg_udccsr = &UDCCSR0 + j; ++ pxa_ep->reg_udcbcr = &UDCBCR0 + j; ++ pxa_ep->reg_udcdr = &UDCDR0 + j ; ++ pxa_ep->reg_udccr = &UDCCRA - 1 + j; ++#ifdef USE_DMA ++ pxa_ep->reg_drcmr = &DRCMR24 + j; ++#endif ++ ++ /* Configure UDCCR */ ++ *pxa_ep->reg_udccr = ((pxa_ep->config << UDCCONR_CN_S) & UDCCONR_CN) ++ | ((pxa_ep->interface << UDCCONR_IN_S) & UDCCONR_IN) ++ | ((pxa_ep->aisn << UDCCONR_AISN_S) & UDCCONR_AISN) ++ | ((dev->ep_num << UDCCONR_EN_S) & UDCCONR_EN) ++ | ((pxa_ep->ep_type << UDCCONR_ET_S) & UDCCONR_ET) ++ | ((pxa_ep->dir_in) ? UDCCONR_ED : 0) ++ | ((min(pxa_ep->fifo_size, (unsigned)desc->wMaxPacketSize) << UDCCONR_MPS_S ) & UDCCONR_MPS) ++ | UDCCONR_EE; ++// | UDCCONR_DE | UDCCONR_EE; ++ ++ ++ ++#ifdef USE_DMA ++ /* Only BULK use DMA */ ++ if ((pxa_ep->ep_type & USB_ENDPOINT_XFERTYPE_MASK)\ ++ == USB_ENDPOINT_XFER_BULK) ++ *pxa_ep->reg_udccsr = UDCCSR_DME; ++#endif ++ ++ DMSG("UDCCR: 0x%p is 0x%x\n", pxa_ep->reg_udccr,*pxa_ep->reg_udccr); ++ ++ epconfig++; ++ } ++ ++ /* Fill ep name*/ ++ switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { ++ case USB_ENDPOINT_XFER_BULK: ++ sprintf(name, "ep%d%s-bulk", dev->ep_num, ++ ((desc->bEndpointAddress & USB_DIR_IN) ? "in":"out")); ++ break; ++ case USB_ENDPOINT_XFER_INT: ++ sprintf(name, "ep%d%s-intr", dev->ep_num, ++ ((desc->bEndpointAddress & USB_DIR_IN) ? "in":"out")); ++ break; ++ default: ++ sprintf(name, "ep%d%s", dev->ep_num, ++ ((desc->bEndpointAddress & USB_DIR_IN) ? "in":"out")); ++ break; ++ } ++ ++ virt_ep->desc = desc; ++ virt_ep->usb_ep.name = name; ++ virt_ep->usb_ep.ops = &pxa27x_ep_ops; ++ virt_ep->usb_ep.maxpacket = min((ushort)fifo_size, desc->wMaxPacketSize); ++ ++ list_add_tail(&virt_ep->usb_ep.ep_list, &gadget->ep_list); ++ ++ dev->ep_num++; ++ return &virt_ep->usb_ep; ++} ++ ++static int pxa27x_udc_get_frame(struct usb_gadget *_gadget) ++{ ++ return (UDCFNR & 0x7FF); ++} ++ ++static int pxa27x_udc_wakeup(struct usb_gadget *_gadget) ++{ ++ /* host may not have enabled remote wakeup */ ++ if ((UDCCR & UDCCR_DWRE) == 0) ++ return -EHOSTUNREACH; ++ udc_set_mask_UDCCR(UDCCR_UDR); ++ return 0; ++} ++ ++static const struct usb_gadget_ops pxa27x_udc_ops = { ++ .ep_alloc = pxa27x_ep_alloc, ++ .get_frame = pxa27x_udc_get_frame, ++ .wakeup = pxa27x_udc_wakeup, ++ // current versions must always be self-powered ++}; ++ ++ ++/*-------------------------------------------------------------------------*/ ++ ++#ifdef UDC_PROC_FILE ++ ++static const char proc_node_name [] = "driver/udc"; ++ ++static int ++udc_proc_read(char *page, char **start, off_t off, int count, ++ int *eof, void *_dev) ++{ ++ char *buf = page; ++ struct pxa27x_udc *dev = _dev; ++ char *next = buf; ++ unsigned size = count; ++ unsigned long flags; ++ int i, t; ++ u32 tmp; ++ ++ if (off != 0) ++ return 0; ++ ++ local_irq_save(flags); ++ ++ /* basic device status */ ++ t = scnprintf(next, size, DRIVER_DESC "\n" ++ "%s version: %s\nGadget driver: %s\n", ++ driver_name, DRIVER_VERSION DMASTR, ++ dev->driver ? dev->driver->driver.name : "(none)"); ++ size -= t; ++ next += t; ++ ++ /* registers for device and ep0 */ ++ t = scnprintf(next, size, ++ "uicr %02X.%02X, usir %02X.%02x, ufnr %02X\n", ++ UDCICR1, UDCICR0, UDCISR1, UDCISR0, UDCFNR); ++ size -= t; ++ next += t; ++ ++ tmp = UDCCR; ++ t = scnprintf(next, size,"udccr %02X =%s%s%s%s%s%s%s%s%s%s, con=%d,inter=%d,altinter=%d\n", tmp, ++ (tmp & UDCCR_OEN) ? " oen":"", ++ (tmp & UDCCR_AALTHNP) ? " aalthnp":"", ++ (tmp & UDCCR_AHNP) ? " rem" : "", ++ (tmp & UDCCR_BHNP) ? " rstir" : "", ++ (tmp & UDCCR_DWRE) ? " dwre" : "", ++ (tmp & UDCCR_SMAC) ? " smac" : "", ++ (tmp & UDCCR_EMCE) ? " emce" : "", ++ (tmp & UDCCR_UDR) ? " udr" : "", ++ (tmp & UDCCR_UDA) ? " uda" : "", ++ (tmp & UDCCR_UDE) ? " ude" : "", ++ (tmp & UDCCR_ACN) >> UDCCR_ACN_S, ++ (tmp & UDCCR_AIN) >> UDCCR_AIN_S, ++ (tmp & UDCCR_AAISN)>> UDCCR_AAISN_S ); ++ ++ size -= t; ++ next += t; ++ ++ tmp = UDCCSR0; ++ t = scnprintf(next, size, ++ "udccsr0 %02X =%s%s%s%s%s%s%s\n", tmp, ++ (tmp & UDCCSR0_SA) ? " sa" : "", ++ (tmp & UDCCSR0_RNE) ? " rne" : "", ++ (tmp & UDCCSR0_FST) ? " fst" : "", ++ (tmp & UDCCSR0_SST) ? " sst" : "", ++ (tmp & UDCCSR0_DME) ? " dme" : "", ++ (tmp & UDCCSR0_IPR) ? " ipr" : "", ++ (tmp & UDCCSR0_OPC) ? " opc" : ""); ++ size -= t; ++ next += t; ++ ++ if (!dev->driver) ++ goto done; ++ ++ t = scnprintf(next, size, "ep0 IN %lu/%lu, OUT %lu/%lu\nirqs %lu\n\n", ++ dev->stats.write.bytes, dev->stats.write.ops, ++ dev->stats.read.bytes, dev->stats.read.ops, ++ dev->stats.irqs); ++ size -= t; ++ next += t; ++ ++ /* dump endpoint queues */ ++ for (i = 0; i < UDC_EP_NUM; i++) { ++ struct pxa27x_ep *ep = &dev->ep [i]; ++ struct pxa27x_request *req; ++ int t; ++ ++ if (i != 0) { ++ const struct usb_endpoint_descriptor *d; ++ ++ d = ep->desc; ++ if (!d) ++ continue; ++ tmp = *dev->ep [i].reg_udccsr; ++ t = scnprintf(next, size, ++ "%d max %d %s udccs %02x udccr:0x%x\n", ++ i, le16_to_cpu (d->wMaxPacketSize), ++ (ep->dma >= 0) ? "dma" : "pio", tmp, ++ *dev->ep[i].reg_udccr); ++ /* TODO translate all five groups of udccs bits! */ ++ ++ } else /* ep0 should only have one transfer queued */ ++ t = scnprintf(next, size, "ep0 max 16 pio irqs %lu\n", ++ ep->pio_irqs); ++ if (t <= 0 || t > size) ++ goto done; ++ size -= t; ++ next += t; ++ ++ if (list_empty(&ep->queue)) { ++ t = scnprintf(next, size, "\t(nothing queued)\n"); ++ if (t <= 0 || t > size) ++ goto done; ++ size -= t; ++ next += t; ++ continue; ++ } ++ list_for_each_entry(req, &ep->queue, queue) { ++#ifdef USE_DMA ++ if (ep->dma >= 0 && req->queue.prev == &ep->queue) ++ t = scnprintf(next, size, "\treq %p len %d/%d " ++ "buf %p (dma%d dcmd %08x)\n", ++ &req->req, req->req.actual, ++ req->req.length, req->req.buf, ++ ep->dma, DCMD(ep->dma) ++ /* low 13 bits == bytes-to-go */); ++ else ++#endif ++ t = scnprintf(next, size, ++ "\treq %p len %d/%d buf %p\n", ++ &req->req, req->req.actual, ++ req->req.length, req->req.buf); ++ if (t <= 0 || t > size) ++ goto done; ++ size -= t; ++ next += t; ++ } ++ } ++ ++done: ++ local_irq_restore(flags); ++ *eof = 1; ++ return count - size; ++} ++ ++#define create_proc_files() \ ++ create_proc_read_entry(proc_node_name, 0, NULL, udc_proc_read, dev) ++#define remove_proc_files() \ ++ remove_proc_entry(proc_node_name, NULL) ++ ++#else /* !UDC_PROC_FILE */ ++#define create_proc_files() do {} while (0) ++#define remove_proc_files() do {} while (0) ++ ++#endif /* UDC_PROC_FILE */ ++ ++/* "function" sysfs attribute */ ++static ssize_t show_function(struct device *_dev, struct device_attribute *attr, char *buf) ++{ ++ struct pxa27x_udc *dev = dev_get_drvdata(_dev); ++ ++ if (!dev->driver || !dev->driver->function ++ || strlen(dev->driver->function) > PAGE_SIZE) ++ return 0; ++ return scnprintf(buf, PAGE_SIZE, "%s\n", dev->driver->function); ++} ++static DEVICE_ATTR(function, S_IRUGO, show_function, NULL); ++ ++/*-------------------------------------------------------------------------*/ ++ ++/* ++ * udc_disable - disable USB device controller ++ */ ++static void udc_disable(struct pxa27x_udc *dev) ++{ ++ UDCICR0 = UDCICR1 = 0x00000000; ++ ++ udc_clear_mask_UDCCR(UDCCR_UDE); ++ ++ /* Disable clock for USB device */ ++ pxa_set_cken(CKEN_USB, 0); ++ ++ ep0_idle(dev); ++ dev->gadget.speed = USB_SPEED_UNKNOWN; ++ dev->mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT); ++} ++ ++ ++/* ++ * udc_reinit - initialize software state ++ */ ++static void udc_reinit(struct pxa27x_udc *dev) ++{ ++ u32 i; ++ ++ dev->ep0state = EP0_IDLE; ++ ++ /* basic endpoint records init */ ++ for (i = 0; i < UDC_EP_NUM; i++) { ++ struct pxa27x_ep *ep = &dev->ep[i]; ++ ++ ep->stopped = 0; ++ ep->pio_irqs = ep->dma_irqs = 0; ++ } ++ dev->configuration = 0; ++ dev->interface = 0; ++ dev->alternate = 0; ++ /* the rest was statically initialized, and is read-only */ ++} ++ ++/* until it's enabled, this UDC should be completely invisible ++ * to any USB host. ++ */ ++static void udc_enable(struct pxa27x_udc *dev) ++{ ++ udc_clear_mask_UDCCR(UDCCR_UDE); ++ ++ /* Enable clock for USB device */ ++ pxa_set_cken(CKEN_USB, 1); ++ ++ UDCICR0 = UDCICR1 = 0; ++ ++ ep0_idle(dev); ++ dev->gadget.speed = USB_SPEED_FULL; ++ dev->stats.irqs = 0; ++ ++ udc_set_mask_UDCCR(UDCCR_UDE); ++ udelay(2); ++ if (UDCCR & UDCCR_EMCE) ++ dev_err(dev->dev, "There are error in configuration, udc disabled\n"); ++ ++ /* caller must be able to sleep in order to cope ++ * with startup transients. ++ */ ++ msleep(100); ++ ++ /* enable suspend/resume and reset irqs */ ++ UDCICR1 = UDCICR1_IECC | UDCICR1_IERU | UDCICR1_IESU | UDCICR1_IERS; ++ ++ /* enable ep0 irqs */ ++ UDCICR0 = UDCICR_INT(0,UDCICR_INT_MASK); ++ ++ DMSG("Connecting\n"); ++ /* RPFIXME */ ++ UP2OCR = UP2OCR_HXOE | UP2OCR_DPPUE | UP2OCR_DPPUBE; ++ //dev->mach->udc_command(PXA2XX_UDC_CMD_CONNECT); ++} ++ ++ ++/* when a driver is successfully registered, it will receive ++ * control requests including set_configuration(), which enables ++ * non-control requests. then usb traffic follows until a ++ * disconnect is reported. then a host may connect again, or ++ * the driver might get unbound. ++ */ ++int usb_gadget_register_driver(struct usb_gadget_driver *driver) ++{ ++ struct pxa27x_udc *dev = the_controller; ++ int retval; ++ ++ if (!driver || driver->speed != USB_SPEED_FULL || !driver->bind ++ || !driver->unbind || !driver->disconnect || !driver->setup) ++ return -EINVAL; ++ if (!dev) ++ return -ENODEV; ++ if (dev->driver) ++ return -EBUSY; ++ ++ udc_disable(dev); ++ udc_init_ep(dev); ++ udc_reinit(dev); ++ ++ /* first hook up the driver ... */ ++ dev->driver = driver; ++ dev->gadget.dev.driver = &driver->driver; ++ dev->ep_num = 1; ++ ++ retval = device_add(&dev->gadget.dev); ++ if (retval) { ++ DMSG("device_add error %d\n", retval); ++ goto add_fail; ++ } ++ retval = driver->bind(&dev->gadget); ++ if (retval) { ++ DMSG("bind to driver %s --> error %d\n", ++ driver->driver.name, retval); ++ goto bind_fail; ++ } ++ retval = device_create_file(dev->dev, &dev_attr_function); ++ if (retval) { ++ DMSG("device_create_file failed: %d\n", retval); ++ goto create_file_fail; ++ } ++ ++ /* ... then enable host detection and ep0; and we're ready ++ * for set_configuration as well as eventual disconnect. ++ * NOTE: this shouldn't power up until later. ++ */ ++ DMSG("registered gadget driver '%s'\n", driver->driver.name); ++ udc_enable(dev); ++ dump_state(dev); ++ return 0; ++ ++create_file_fail: ++ driver->unbind(&dev->gadget); ++bind_fail: ++ device_del(&dev->gadget.dev); ++add_fail: ++ dev->driver = 0; ++ dev->gadget.dev.driver = 0; ++ return retval; ++} ++EXPORT_SYMBOL(usb_gadget_register_driver); ++ ++static void ++stop_activity(struct pxa27x_udc *dev, struct usb_gadget_driver *driver) ++{ ++ int i; ++ ++ DMSG("Trace path 1\n"); ++ /* don't disconnect drivers more than once */ ++ if (dev->gadget.speed == USB_SPEED_UNKNOWN) ++ driver = 0; ++ dev->gadget.speed = USB_SPEED_UNKNOWN; ++ ++ /* prevent new request submissions, kill any outstanding requests */ ++ for (i = 0; i < UDC_EP_NUM; i++) { ++ struct pxa27x_ep *ep = &dev->ep[i]; ++ ++ ep->stopped = 1; ++ nuke(ep, -ESHUTDOWN); ++ } ++ del_timer_sync(&dev->timer); ++ ++ /* report disconnect; the driver is already quiesced */ ++ if (driver) ++ driver->disconnect(&dev->gadget); ++ ++ /* re-init driver-visible data structures */ ++ udc_reinit(dev); ++} ++ ++int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) ++{ ++ struct pxa27x_udc *dev = the_controller; ++ ++ if (!dev) ++ return -ENODEV; ++ if (!driver || driver != dev->driver) ++ return -EINVAL; ++ ++ local_irq_disable(); ++ udc_disable(dev); ++ stop_activity(dev, driver); ++ local_irq_enable(); ++ ++ driver->unbind(&dev->gadget); ++ pxa27x_ep_freeall(&dev->gadget); ++ dev->driver = 0; ++ ++ device_del(&dev->gadget.dev); ++ device_remove_file(dev->dev, &dev_attr_function); ++ ++ DMSG("unregistered gadget driver '%s'\n", driver->driver.name); ++ dump_state(dev); ++ return 0; ++} ++EXPORT_SYMBOL(usb_gadget_unregister_driver); ++ ++ ++/*-------------------------------------------------------------------------*/ ++ ++static inline void clear_ep_state(struct pxa27x_udc *dev) ++{ ++ unsigned i; ++ ++ /* hardware SET_{CONFIGURATION,INTERFACE} automagic resets endpoint ++ * fifos, and pending transactions mustn't be continued in any case. ++ */ ++ for (i = 1; i < UDC_EP_NUM; i++) ++ nuke(&dev->ep[i], -ECONNABORTED); ++} ++ ++static void udc_watchdog(unsigned long _dev) ++{ ++ struct pxa27x_udc *dev = (void *)_dev; ++ ++ local_irq_disable(); ++ if (dev->ep0state == EP0_STALL ++ && (UDCCSR0 & UDCCSR0_FST) == 0 ++ && (UDCCSR0 & UDCCSR0_SST) == 0) { ++ UDCCSR0 = UDCCSR0_FST|UDCCSR0_FTF; ++ DBG(DBG_VERBOSE, "ep0 re-stall\n"); ++ start_watchdog(dev); ++ } ++ local_irq_enable(); ++} ++ ++static void handle_ep0(struct pxa27x_udc *dev) ++{ ++ u32 udccsr0 = UDCCSR0; ++ struct pxa27x_ep *ep = &dev->ep[0]; ++ struct pxa27x_request *req; ++ union { ++ struct usb_ctrlrequest r; ++ u8 raw[8]; ++ u32 word[2]; ++ } u; ++ ++ if (list_empty(&ep->queue)) ++ req = 0; ++ else ++ req = list_entry(ep->queue.next, struct pxa27x_request, queue); ++ ++ /* clear stall status */ ++ if (udccsr0 & UDCCSR0_SST) { ++ nuke(ep, -EPIPE); ++ UDCCSR0 = UDCCSR0_SST; ++ del_timer(&dev->timer); ++ ep0_idle(dev); ++ } ++ ++ /* previous request unfinished? non-error iff back-to-back ... */ ++ if ((udccsr0 & UDCCSR0_SA) != 0 && dev->ep0state != EP0_IDLE) { ++ nuke(ep, 0); ++ del_timer(&dev->timer); ++ ep0_idle(dev); ++ } ++ ++ switch (dev->ep0state) { ++ case EP0_NO_ACTION: ++ dev_info(dev->dev, "%s: Busy\n", __FUNCTION__); ++ /*Fall through */ ++ case EP0_IDLE: ++ /* late-breaking status? */ ++ udccsr0 = UDCCSR0; ++ ++ /* start control request? */ ++ if (likely((udccsr0 & (UDCCSR0_OPC|UDCCSR0_SA|UDCCSR0_RNE)) ++ == (UDCCSR0_OPC|UDCCSR0_SA|UDCCSR0_RNE))) { ++ int i; ++ ++ nuke(ep, -EPROTO); ++ /* read SETUP packet */ ++ for (i = 0; i < 2; i++) { ++ if (unlikely(!(UDCCSR0 & UDCCSR0_RNE))) { ++bad_setup: ++ DMSG("SETUP %d!\n", i); ++ goto stall; ++ } ++ u.word [i] = UDCDR0; ++ } ++ if (unlikely((UDCCSR0 & UDCCSR0_RNE) != 0)) ++ goto bad_setup; ++ ++ le16_to_cpus(&u.r.wValue); ++ le16_to_cpus(&u.r.wIndex); ++ le16_to_cpus(&u.r.wLength); ++ ++ DBG(DBG_VERBOSE, "SETUP %02x.%02x v%04x i%04x l%04x\n", ++ u.r.bRequestType, u.r.bRequest, ++ u.r.wValue, u.r.wIndex, u.r.wLength); ++ /* cope with automagic for some standard requests. */ ++ dev->req_std = (u.r.bRequestType & USB_TYPE_MASK) ++ == USB_TYPE_STANDARD; ++ dev->req_config = 0; ++ dev->req_pending = 1; ++#if 0 ++ switch (u.r.bRequest) { ++ /* hardware was supposed to hide this */ ++ case USB_REQ_SET_CONFIGURATION: ++ case USB_REQ_SET_INTERFACE: ++ case USB_REQ_SET_ADDRESS: ++ dev_err(dev->dev, "Should not come here\n"); ++ break; ++ } ++ ++#endif ++ if (u.r.bRequestType & USB_DIR_IN) ++ dev->ep0state = EP0_IN_DATA_PHASE; ++ else ++ dev->ep0state = EP0_OUT_DATA_PHASE; ++ i = dev->driver->setup(&dev->gadget, &u.r); ++ ++ if (i < 0) { ++ /* hardware automagic preventing STALL... */ ++ if (dev->req_config) { ++ /* hardware sometimes neglects to tell ++ * tell us about config change events, ++ * so later ones may fail... ++ */ ++ WARN("config change %02x fail %d?\n", ++ u.r.bRequest, i); ++ return; ++ /* TODO experiment: if has_cfr, ++ * hardware didn't ACK; maybe we ++ * could actually STALL! ++ */ ++ } ++ DBG(DBG_VERBOSE, "protocol STALL, " ++ "%02x err %d\n", UDCCSR0, i); ++stall: ++ /* the watchdog timer helps deal with cases ++ * where udc seems to clear FST wrongly, and ++ * then NAKs instead of STALLing. ++ */ ++ ep0start(dev, UDCCSR0_FST|UDCCSR0_FTF, "stall"); ++ start_watchdog(dev); ++ dev->ep0state = EP0_STALL; ++ ++ /* deferred i/o == no response yet */ ++ } else if (dev->req_pending) { ++ if (likely(dev->ep0state == EP0_IN_DATA_PHASE ++ || dev->req_std || u.r.wLength)) ++ ep0start(dev, 0, "defer"); ++ else ++ ep0start(dev, UDCCSR0_IPR, "defer/IPR"); ++ } ++ ++ /* expect at least one data or status stage irq */ ++ return; ++ ++ } else { ++ /* some random early IRQ: ++ * - we acked FST ++ * - IPR cleared ++ * - OPC got set, without SA (likely status stage) ++ */ ++ UDCCSR0 = udccsr0 & (UDCCSR0_SA|UDCCSR0_OPC); ++ } ++ break; ++ case EP0_IN_DATA_PHASE: /* GET_DESCRIPTOR etc */ ++ if (udccsr0 & UDCCSR0_OPC) { ++ UDCCSR0 = UDCCSR0_OPC|UDCCSR0_FTF; ++ DBG(DBG_VERBOSE, "ep0in premature status\n"); ++ if (req) ++ done(ep, req, 0); ++ ep0_idle(dev); ++ } else /* irq was IPR clearing */ { ++ if (req) { ++ /* this IN packet might finish the request */ ++ (void) write_ep0_fifo(ep, req); ++ } /* else IN token before response was written */ ++ } ++ break; ++ case EP0_OUT_DATA_PHASE: /* SET_DESCRIPTOR etc */ ++ if (udccsr0 & UDCCSR0_OPC) { ++ if (req) { ++ /* this OUT packet might finish the request */ ++ if (read_ep0_fifo(ep, req)) ++ done(ep, req, 0); ++ /* else more OUT packets expected */ ++ } /* else OUT token before read was issued */ ++ } else /* irq was IPR clearing */ { ++ DBG(DBG_VERBOSE, "ep0out premature status\n"); ++ if (req) ++ done(ep, req, 0); ++ ep0_idle(dev); ++ } ++ break; ++ case EP0_STALL: ++ UDCCSR0 = UDCCSR0_FST; ++ break; ++ } ++ UDCISR0 = UDCISR_INT(0, UDCISR_INT_MASK); ++} ++ ++ ++static void handle_ep(struct pxa27x_ep *ep) ++{ ++ struct pxa27x_request *req; ++ int completed; ++ u32 udccsr=0; ++ ++ DMSG("%s is called\n", __FUNCTION__); ++ do { ++ completed = 0; ++ if (likely (!list_empty(&ep->queue))) { ++ req = list_entry(ep->queue.next, ++ struct pxa27x_request, queue); ++ } else ++ req = 0; ++ ++// udccsr = *ep->reg_udccsr; ++ DMSG("%s: req:%p, udcisr0:0x%x udccsr %p:0x%x\n", __FUNCTION__, ++ req, UDCISR0, ep->reg_udccsr, *ep->reg_udccsr); ++ if (unlikely(ep->dir_in)) { ++ udccsr = (UDCCSR_SST | UDCCSR_TRN) & *ep->reg_udccsr; ++ if (unlikely (udccsr)) ++ *ep->reg_udccsr = udccsr; ++ ++ if (req && likely ((*ep->reg_udccsr & UDCCSR_FS) != 0)) ++ completed = write_fifo(ep, req); ++ ++ } else { ++ udccsr = (UDCCSR_SST | UDCCSR_TRN) & *ep->reg_udccsr; ++ if (unlikely(udccsr)) ++ *ep->reg_udccsr = udccsr; ++ ++ /* fifos can hold packets, ready for reading... */ ++ if (likely(req)) { ++ completed = read_fifo(ep, req); ++ } else { ++ pio_irq_disable (ep->pxa_ep_num); ++ //*ep->reg_udccsr = UDCCSR_FEF; ++ DMSG("%s: no req for out data\n", ++ __FUNCTION__); ++ } ++ } ++ ep->pio_irqs++; ++ } while (completed); ++} ++ ++static void pxa27x_update_eps(struct pxa27x_udc *dev) ++{ ++ struct pxa27x_virt_ep *virt_ep; ++ int i; ++ ++ for (i = 1; i < UDC_EP_NUM; i++) { ++ if(!dev->ep[i].assigned || !dev->ep[i].usb_ep) ++ continue; ++ virt_ep = container_of(dev->ep[i].usb_ep, struct pxa27x_virt_ep, usb_ep); ++ ++ DMSG("%s, Updating eps %d:%d, %d:%d, %d:%d, %p,%p\n", __FUNCTION__, dev->ep[i].config, dev->configuration ++ ,dev->ep[i].interface, dev->interface, dev->ep[i].aisn, dev->alternate, virt_ep->pxa_ep, &dev->ep[i]); ++ ++ if(dev->ep[i].config == dev->configuration && virt_ep->pxa_ep != &dev->ep[i]) { ++ if ((dev->ep[i].interface == dev->interface && ++ dev->ep[i].aisn == dev->alternate) || virt_ep->pxa_ep->config != dev->configuration) { ++ ++ if (virt_ep->pxa_ep->desc) { ++ DMSG("%s, Changing end point to %d (en/dis)\n", __FUNCTION__, i); ++ pxa27x_ep_disable(&virt_ep->usb_ep); ++ virt_ep->pxa_ep = &dev->ep[i]; ++ pxa27x_ep_enable(&virt_ep->usb_ep, virt_ep->desc); ++ } else { ++ DMSG("%s, Changing end point to %d (no en/dis)\n", __FUNCTION__, i); ++ virt_ep->pxa_ep = &dev->ep[i]; ++ } ++ } ++ } ++ } ++} ++ ++static void pxa27x_change_configuration(struct pxa27x_udc *dev) ++{ ++ struct usb_ctrlrequest req ; ++ ++ pxa27x_update_eps(dev); ++ ++ req.bRequestType = 0; ++ req.bRequest = USB_REQ_SET_CONFIGURATION; ++ req.wValue = dev->configuration; ++ req.wIndex = 0; ++ req.wLength = 0; ++ ++ dev->ep0state = EP0_NO_ACTION; ++ dev->driver->setup(&dev->gadget, &req); ++} ++ ++static void pxa27x_change_interface(struct pxa27x_udc *dev) ++{ ++ struct usb_ctrlrequest req; ++ ++ pxa27x_update_eps(dev); ++ ++ req.bRequestType = USB_RECIP_INTERFACE; ++ req.bRequest = USB_REQ_SET_INTERFACE; ++ req.wValue = dev->alternate; ++ req.wIndex = dev->interface; ++ req.wLength = 0; ++ ++ dev->ep0state = EP0_NO_ACTION; ++ dev->driver->setup(&dev->gadget, &req); ++} ++ ++/* ++ * pxa27x_udc_irq - interrupt handler ++ * ++ * avoid delays in ep0 processing. the control handshaking isn't always ++ * under software control (pxa250c0 and the pxa255 are better), and delays ++ * could cause usb protocol errors. ++ */ ++static irqreturn_t pxa27x_udc_irq(int irq, void *_dev) ++{ ++ struct pxa27x_udc *dev = _dev; ++ int handled; ++ ++ dev->stats.irqs++; ++ ++ DBG(DBG_VERBOSE, "Interrupt, UDCISR0:0x%08x, UDCISR1:0x%08x, " ++ "UDCCR:0x%08x\n", UDCISR0, UDCISR1, UDCCR); ++ do { ++ u32 udcir = UDCISR1 & 0xF8000000; ++ ++ handled = 0; ++ ++ /* SUSpend Interrupt Request */ ++ if (unlikely(udcir & UDCISR1_IRSU)) { ++ UDCISR1 = UDCISR1_IRSU; ++ handled = 1; ++ DBG(DBG_VERBOSE, "USB suspend\n"); ++ if (dev->gadget.speed != USB_SPEED_UNKNOWN ++ && dev->driver ++ && dev->driver->suspend) ++ dev->driver->suspend(&dev->gadget); ++ ep0_idle(dev); ++ } ++ ++ /* RESume Interrupt Request */ ++ if (unlikely(udcir & UDCISR1_IRRU)) { ++ UDCISR1 = UDCISR1_IRRU; ++ handled = 1; ++ DBG(DBG_VERBOSE, "USB resume\n"); ++ ++ if (dev->gadget.speed != USB_SPEED_UNKNOWN ++ && dev->driver ++ && dev->driver->resume) ++ dev->driver->resume(&dev->gadget); ++ } ++ ++ if (unlikely(udcir & UDCISR1_IRCC)) { ++ unsigned config, interface, alternate; ++ ++ handled = 1; ++ DBG(DBG_VERBOSE, "USB SET_CONFIGURATION or " ++ "SET_INTERFACE command received\n"); ++ ++ config = (UDCCR & UDCCR_ACN) >> UDCCR_ACN_S; ++ ++ if (dev->configuration != config) { ++ dev->configuration = config; ++ pxa27x_change_configuration(dev) ; ++ } ++ ++ interface = (UDCCR & UDCCR_AIN) >> UDCCR_AIN_S; ++ alternate = (UDCCR & UDCCR_AAISN) >> UDCCR_AAISN_S; ++ ++ if ((dev->interface != interface) || (dev->alternate != alternate)) { ++ dev->interface = interface; ++ dev->alternate = alternate; ++ pxa27x_change_interface(dev); ++ } ++ ++ UDCCR |= UDCCR_SMAC; ++ ++ UDCISR1 = UDCISR1_IRCC; ++ DMSG("%s: con:%d,inter:%d,alt:%d\n", ++ __FUNCTION__, config,interface, alternate); ++ } ++ ++ /* ReSeT Interrupt Request - USB reset */ ++ if (unlikely(udcir & UDCISR1_IRRS)) { ++ UDCISR1 = UDCISR1_IRRS; ++ handled = 1; ++ ++ if ((UDCCR & UDCCR_UDA) == 0) { ++ DBG(DBG_VERBOSE, "USB reset start\n"); ++ ++ /* reset driver and endpoints, ++ * in case that's not yet done ++ */ ++ stop_activity(dev, dev->driver); ++ } ++ INFO("USB reset\n"); ++ dev->gadget.speed = USB_SPEED_FULL; ++ memset(&dev->stats, 0, sizeof dev->stats); ++ ++ } else { ++ u32 udcisr0 = UDCISR0 ; ++ u32 udcisr1 = UDCISR1 & 0xFFFF; ++ int i; ++ ++ if (unlikely (!udcisr0 && !udcisr1)) ++ continue; ++ ++ DBG(DBG_VERY_NOISY, "irq %02x.%02x\n", udcisr1,udcisr0); ++ ++ /* control traffic */ ++ if (udcisr0 & UDCISR0_IR0) { ++ dev->ep[0].pio_irqs++; ++ handle_ep0(dev); ++ handled = 1; ++ } ++ ++ udcisr0 >>= 2; ++ /* endpoint data transfers */ ++ for (i = 1; udcisr0!=0 && i < 16; udcisr0>>=2,i++) { ++ UDCISR0 = UDCISR_INT(i, UDCISR_INT_MASK); ++ ++ if (udcisr0 & UDC_INT_FIFOERROR) ++ dev_err(dev->dev, " Endpoint %d Fifo error\n", i); ++ if (udcisr0 & UDC_INT_PACKETCMP) { ++ handle_ep(&dev->ep[i]); ++ handled = 1; ++ } ++ ++ } ++ ++ for (i = 0; udcisr1!=0 && i < 8; udcisr1 >>= 2, i++) { ++ UDCISR1 = UDCISR_INT(i, UDCISR_INT_MASK); ++ ++ if (udcisr1 & UDC_INT_FIFOERROR) { ++ dev_err(dev->dev, "Endpoint %d fifo error\n", (i+16)); ++ } ++ ++ if (udcisr1 & UDC_INT_PACKETCMP) { ++ handle_ep(&dev->ep[i+16]); ++ handled = 1; ++ } ++ } ++ } ++ ++ /* we could also ask for 1 msec SOF (SIR) interrupts */ ++ ++ } while (handled); ++ return IRQ_HANDLED; ++} ++ ++int write_ep0_zlp(void) ++{ ++ UDCCSR0 = UDCCSR0_IPR; ++ return 0; ++} ++EXPORT_SYMBOL(write_ep0_zlp); ++ ++static void udc_init_ep(struct pxa27x_udc *dev) ++{ ++ int i; ++ ++ INIT_LIST_HEAD(&dev->gadget.ep_list); ++ INIT_LIST_HEAD(&dev->gadget.ep0->ep_list); ++ ++ for (i = 0; i < UDC_EP_NUM; i++) { ++ struct pxa27x_ep *ep = &dev->ep[i]; ++ ++ ep->dma = -1; ++ if (i != 0) { ++ memset(ep, 0, sizeof(*ep)); ++ } ++ INIT_LIST_HEAD(&ep->queue); ++ } ++} ++ ++/*-------------------------------------------------------------------------*/ ++ ++static void nop_release(struct device *dev) ++{ ++ DMSG("%s %s\n", __FUNCTION__, dev->bus_id); ++} ++ ++/* this uses load-time allocation and initialization (instead of ++ * doing it at run-time) to save code, eliminate fault paths, and ++ * be more obviously correct. ++ */ ++ ++static struct pxa27x_udc memory = { ++ .gadget = { ++ .ops = &pxa27x_udc_ops, ++ .ep0 = &memory.virt_ep0.usb_ep, ++ .name = driver_name, ++ .dev = { ++ .bus_id = "gadget", ++ .release = nop_release, ++ }, ++ }, ++ ++ /* control endpoint */ ++ .virt_ep0 = { ++ .pxa_ep = &memory.ep[0], ++ .usb_ep = { ++ .name = ep0name, ++ .ops = &pxa27x_ep_ops, ++ .maxpacket = EP0_FIFO_SIZE, ++ }, ++ }, ++ ++ .ep[0] = { ++ .usb_ep = &memory.virt_ep0.usb_ep, ++ .dev = &memory, ++ .reg_udccsr = &UDCCSR0, ++ .reg_udcdr = &UDCDR0, ++ }, ++}; ++ ++static int __init pxa27x_udc_probe(struct platform_device *_dev) ++{ ++ struct pxa27x_udc *dev = &memory; ++ int retval; ++ ++ /* other non-static parts of init */ ++ dev->dev = &_dev->dev; ++ dev->mach = _dev->dev.platform_data; ++ ++ /* RPFIXME */ ++ UP2OCR = UP2OCR_HXOE | UP2OCR_DPPUE | UP2OCR_DPPUBE; ++ ++ init_timer(&dev->timer); ++ dev->timer.function = udc_watchdog; ++ dev->timer.data = (unsigned long) dev; ++ ++ device_initialize(&dev->gadget.dev); ++ dev->gadget.dev.parent = &_dev->dev; ++ dev->gadget.dev.dma_mask = _dev->dev.dma_mask; ++ ++ the_controller = dev; ++ platform_set_drvdata(_dev, dev); ++ ++ udc_disable(dev); ++ udc_init_ep(dev); ++ udc_reinit(dev); ++ ++ /* irq setup after old hardware state is cleaned up */ ++ retval = request_irq(IRQ_USB, pxa27x_udc_irq, ++ SA_INTERRUPT, driver_name, dev); ++ if (retval != 0) { ++ dev_err(dev->dev, "%s: can't get irq %i, err %d\n", ++ driver_name, IRQ_USB, retval); ++ return -EBUSY; ++ } ++ dev->got_irq = 1; ++ ++ create_proc_files(); ++ ++ return 0; ++} ++ ++static int pxa27x_udc_remove(struct platform_device *_dev) ++{ ++ struct pxa27x_udc *dev = platform_get_drvdata(_dev); ++ ++ udc_disable(dev); ++ remove_proc_files(); ++ usb_gadget_unregister_driver(dev->driver); ++ ++ pxa27x_ep_freeall(&dev->gadget); ++ ++ if (dev->got_irq) { ++ free_irq(IRQ_USB, dev); ++ dev->got_irq = 0; ++ } ++ platform_set_drvdata(_dev, 0); ++ the_controller = 0; ++ return 0; ++} ++ ++#ifdef CONFIG_PM ++static void pxa27x_udc_shutdown(struct platform_device *_dev) ++{ ++ struct pxa27x_udc *dev = platform_get_drvdata(_dev); ++ ++ udc_disable(dev); ++} ++ ++static int pxa27x_udc_suspend(struct platform_device *_dev, pm_message_t state) ++{ ++ int i; ++ struct pxa27x_udc *dev = platform_get_drvdata(_dev); ++ ++ DMSG("%s is called\n", __FUNCTION__); ++ ++ dev->udccsr0 = UDCCSR0; ++ for(i=1; (i<UDC_EP_NUM); i++) { ++ if (dev->ep[i].assigned) { ++ struct pxa27x_ep *ep = &dev->ep[i]; ++ ep->udccsr_value = *ep->reg_udccsr; ++ ep->udccr_value = *ep->reg_udccr; ++ DMSG("EP%d, udccsr:0x%x, udccr:0x%x\n", ++ i, *ep->reg_udccsr, *ep->reg_udccr); ++ } ++ } ++ ++ udc_clear_mask_UDCCR(UDCCR_UDE); ++ pxa_set_cken(CKEN_USB, 0); ++ ++ return 0; ++} ++ ++static int pxa27x_udc_resume(struct platform_device *_dev) ++{ ++ int i; ++ struct pxa27x_udc *dev = platform_get_drvdata(_dev); ++ ++ DMSG("%s is called\n", __FUNCTION__); ++ UDCCSR0 = dev->udccsr0 & (UDCCSR0_FST | UDCCSR0_DME); ++ for (i=1; i < UDC_EP_NUM; i++) { ++ if (dev->ep[i].assigned) { ++ struct pxa27x_ep *ep = &dev->ep[i]; ++ *ep->reg_udccsr = ep->udccsr_value; ++ *ep->reg_udccr = ep->udccr_value; ++ DMSG("EP%d, udccsr:0x%x, udccr:0x%x\n", ++ i, *ep->reg_udccsr, *ep->reg_udccr); ++ } ++ } ++ ++ udc_enable(dev); ++ ++ /* OTGPH bit is set when sleep mode is entered. ++ * it indicates that OTG pad is retaining its state. ++ * Upon exit from sleep mode and before clearing OTGPH, ++ * Software must configure the USB OTG pad, UDC, and UHC ++ * to the state they were in before entering sleep mode.*/ ++ PSSR |= PSSR_OTGPH; ++ ++ return 0; ++} ++#endif ++ ++/*-------------------------------------------------------------------------*/ ++ ++static struct platform_driver udc_driver = { ++ .driver = { ++ .name = "pxa2xx-udc", ++ }, ++ .probe = pxa27x_udc_probe, ++ .remove = pxa27x_udc_remove, ++#ifdef CONFIG_PM ++ .shutdown = pxa27x_udc_shutdown, ++ .suspend = pxa27x_udc_suspend, ++ .resume = pxa27x_udc_resume ++#endif ++}; ++ ++static int __init udc_init(void) ++{ ++ printk(KERN_INFO "%s: version %s\n", driver_name, DRIVER_VERSION); ++ return platform_driver_register(&udc_driver); ++} ++module_init(udc_init); ++ ++static void __exit udc_exit(void) ++{ ++ platform_driver_unregister(&udc_driver); ++} ++module_exit(udc_exit); ++ ++MODULE_DESCRIPTION(DRIVER_DESC); ++MODULE_AUTHOR("Frank Becker, Robert Schwebel, David Brownell"); ++MODULE_LICENSE("GPL"); +diff --git a/drivers/usb/gadget/pxa27x_udc.h b/drivers/usb/gadget/pxa27x_udc.h +new file mode 100644 +index 0000000..d4377cf +--- /dev/null ++++ b/drivers/usb/gadget/pxa27x_udc.h +@@ -0,0 +1,298 @@ ++/* ++ * linux/drivers/usb/gadget/pxa27x_udc.h ++ * Intel PXA27x on-chip full speed USB device controller ++ * ++ * Copyright (C) 2003 Robert Schwebel <r.schwebel@pengutronix.de>, Pengutronix ++ * Copyright (C) 2003 David Brownell ++ * Copyright (C) 2004 Intel Corporation ++ * ++ * 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 ++ */ ++ ++#ifndef __LINUX_USB_GADGET_PXA27X_H ++#define __LINUX_USB_GADGET_PXA27X_H ++ ++#include <linux/types.h> ++ ++struct pxa27x_udc; ++ ++struct pxa27x_ep { ++ struct pxa27x_udc *dev; ++ struct usb_ep *usb_ep; ++ const struct usb_endpoint_descriptor *desc; ++ ++ struct list_head queue; ++ unsigned long pio_irqs; ++ unsigned long dma_irqs; ++ ++ unsigned pxa_ep_num; ++ int dma; ++ unsigned fifo_size; ++ unsigned ep_type; ++ ++ unsigned stopped : 1; ++ unsigned dma_con : 1; ++ unsigned dir_in : 1; ++ unsigned assigned : 1; ++ ++ unsigned ep_num; ++ unsigned config; ++ unsigned interface; ++ unsigned aisn; ++ /* UDCCSR = UDC Control/Status Register for this EP ++ * UBCR = UDC Byte Count Remaining (contents of OUT fifo) ++ * UDCDR = UDC Endpoint Data Register (the fifo) ++ * UDCCR = UDC Endpoint Configuration Registers ++ * DRCM = DMA Request Channel Map ++ */ ++ volatile u32 *reg_udccsr; ++ volatile u32 *reg_udcbcr; ++ volatile u32 *reg_udcdr; ++ volatile u32 *reg_udccr; ++#ifdef USE_DMA ++ volatile u32 *reg_drcmr; ++#define drcmr(n) .reg_drcmr = & DRCMR ## n , ++#else ++#define drcmr(n) ++#endif ++ ++#ifdef CONFIG_PM ++ unsigned udccsr_value; ++ unsigned udccr_value; ++#endif ++}; ++ ++struct pxa27x_virt_ep { ++ struct usb_ep usb_ep; ++ const struct usb_endpoint_descriptor *desc; ++ struct pxa27x_ep *pxa_ep; ++}; ++ ++struct pxa27x_request { ++ struct usb_request req; ++ struct list_head queue; ++}; ++ ++enum ep0_state { ++ EP0_IDLE, ++ EP0_IN_DATA_PHASE, ++ EP0_OUT_DATA_PHASE, ++// EP0_END_XFER, ++ EP0_STALL, ++ EP0_NO_ACTION ++}; ++ ++#define EP0_FIFO_SIZE ((unsigned)16) ++#define BULK_FIFO_SIZE ((unsigned)64) ++#define ISO_FIFO_SIZE ((unsigned)256) ++#define INT_FIFO_SIZE ((unsigned)8) ++ ++struct udc_stats { ++ struct ep0stats { ++ unsigned long ops; ++ unsigned long bytes; ++ } read, write; ++ unsigned long irqs; ++}; ++ ++#define UDC_EP_NUM 24 ++ ++ ++struct pxa27x_udc { ++ struct usb_gadget gadget; ++ struct usb_gadget_driver *driver; ++ ++ enum ep0_state ep0state; ++ struct udc_stats stats; ++ unsigned got_irq : 1, ++ has_cfr : 1, ++ req_pending : 1, ++ req_std : 1, ++ req_config : 1; ++ ++#define start_watchdog(dev) mod_timer(&dev->timer, jiffies + (HZ/200)) ++ struct timer_list timer; ++ ++ struct device *dev; ++ struct pxa2xx_udc_mach_info *mach; ++ u64 dma_mask; ++ struct pxa27x_virt_ep virt_ep0; ++ struct pxa27x_ep ep[UDC_EP_NUM]; ++ unsigned int ep_num; ++ ++ unsigned configuration, ++ interface, ++ alternate; ++#ifdef CONFIG_PM ++ unsigned udccsr0; ++#endif ++}; ++ ++static struct pxa27x_udc *the_controller; ++ ++#if 0 ++/*-------------------------------------------------------------------------*/ ++ ++ ++/* one GPIO should be used to detect host disconnect */ ++static inline int is_usb_connected(void) ++{ ++ if (!the_controller->mach->udc_is_connected) ++ return 1; ++ return the_controller->mach->udc_is_connected(); ++} ++ ++/* one GPIO should force the host to see this device (or not) */ ++static inline void make_usb_disappear(void) ++{ ++ if (!the_controller->mach->udc_command) ++ return; ++ the_controller->mach->udc_command(PXA27X_UDC_CMD_DISCONNECT); ++} ++ ++static inline void let_usb_appear(void) ++{ ++ if (!the_controller->mach->udc_command) ++ return; ++ the_controller->mach->udc_command(PXA2XX_UDC_CMD_CONNECT); ++} ++#endif ++ ++/*-------------------------------------------------------------------------*/ ++ ++/* ++ * Debugging support vanishes in non-debug builds. DBG_NORMAL should be ++ * mostly silent during normal use/testing, with no timing side-effects. ++ */ ++#define DBG_NORMAL 1 /* error paths, device state transitions */ ++#define DBG_VERBOSE 2 /* add some success path trace info */ ++#define DBG_NOISY 3 /* ... even more: request level */ ++#define DBG_VERY_NOISY 4 /* ... even more: packet level */ ++ ++#ifdef DEBUG ++static const char *state_name[] = { ++ "EP0_IDLE", ++ "EP0_IN_DATA_PHASE", "EP0_OUT_DATA_PHASE", ++ "EP0_END_XFER", "EP0_STALL" ++}; ++ ++#define DMSG(stuff...) printk(KERN_ERR "udc: " stuff) ++ ++#ifdef VERBOSE ++# define UDC_DEBUG DBG_VERBOSE ++#else ++# define UDC_DEBUG DBG_NORMAL ++#endif ++ ++static void __attribute__ ((__unused__)) ++dump_udccr(const char *label) ++{ ++ u32 udccr = UDCCR; ++ DMSG("%s 0x%08x =%s%s%s%s%s%s%s%s%s%s, con=%d,inter=%d,altinter=%d\n", ++ label, udccr, ++ (udccr & UDCCR_OEN) ? " oen":"", ++ (udccr & UDCCR_AALTHNP) ? " aalthnp":"", ++ (udccr & UDCCR_AHNP) ? " rem" : "", ++ (udccr & UDCCR_BHNP) ? " rstir" : "", ++ (udccr & UDCCR_DWRE) ? " dwre" : "", ++ (udccr & UDCCR_SMAC) ? " smac" : "", ++ (udccr & UDCCR_EMCE) ? " emce" : "", ++ (udccr & UDCCR_UDR) ? " udr" : "", ++ (udccr & UDCCR_UDA) ? " uda" : "", ++ (udccr & UDCCR_UDE) ? " ude" : "", ++ (udccr & UDCCR_ACN) >> UDCCR_ACN_S, ++ (udccr & UDCCR_AIN) >> UDCCR_AIN_S, ++ (udccr & UDCCR_AAISN)>> UDCCR_AAISN_S ); ++} ++ ++static void __attribute__ ((__unused__)) ++dump_udccsr0(const char *label) ++{ ++ u32 udccsr0 = UDCCSR0; ++ ++ DMSG("%s %s 0x%08x =%s%s%s%s%s%s%s\n", ++ label, state_name[the_controller->ep0state], udccsr0, ++ (udccsr0 & UDCCSR0_SA) ? " sa" : "", ++ (udccsr0 & UDCCSR0_RNE) ? " rne" : "", ++ (udccsr0 & UDCCSR0_FST) ? " fst" : "", ++ (udccsr0 & UDCCSR0_SST) ? " sst" : "", ++ (udccsr0 & UDCCSR0_DME) ? " dme" : "", ++ (udccsr0 & UDCCSR0_IPR) ? " ipr" : "", ++ (udccsr0 & UDCCSR0_OPC) ? " opr" : ""); ++} ++ ++static void __attribute__ ((__unused__)) ++dump_state(struct pxa27x_udc *dev) ++{ ++ unsigned i; ++ ++ DMSG("%s, udcicr %02X.%02X, udcsir %02X.%02x, udcfnr %02X\n", ++ state_name[dev->ep0state], ++ UDCICR1, UDCICR0, UDCISR1, UDCISR0, UDCFNR); ++ dump_udccr("udccr"); ++ ++ if (!dev->driver) { ++ DMSG("no gadget driver bound\n"); ++ return; ++ } else ++ DMSG("ep0 driver '%s'\n", dev->driver->driver.name); ++ ++ ++ dump_udccsr0 ("udccsr0"); ++ DMSG("ep0 IN %lu/%lu, OUT %lu/%lu\n", ++ dev->stats.write.bytes, dev->stats.write.ops, ++ dev->stats.read.bytes, dev->stats.read.ops); ++ ++ for (i = 1; i < UDC_EP_NUM; i++) { ++ if (dev->ep[i].assigned) ++ DMSG ("udccs%d = %02x\n", i, *dev->ep->reg_udccsr); ++ } ++} ++ ++#if 0 ++static void dump_regs(u8 ep) ++{ ++ DMSG("EP:%d UDCCSR:0x%08x UDCBCR:0x%08x\n UDCCR:0x%08x\n", ++ ep,UDCCSN(ep), UDCBCN(ep), UDCCN(ep)); ++} ++static void dump_req (struct pxa27x_request *req) ++{ ++ struct usb_request *r = &req->req; ++ ++ DMSG("%s: buf:0x%08x length:%d dma:0x%08x actual:%d\n", ++ __FUNCTION__, (unsigned)r->buf, r->length, ++ r->dma, r->actual); ++} ++#endif ++ ++#else ++ ++#define DMSG(stuff...) do{}while(0) ++ ++#define dump_udccr(x) do{}while(0) ++#define dump_udccsr0(x) do{}while(0) ++#define dump_state(x) do{}while(0) ++ ++#define UDC_DEBUG ((unsigned)4) ++ ++#endif ++ ++#define DBG(lvl, stuff...) do{if ((lvl) <= UDC_DEBUG) DMSG(stuff);}while(0) ++ ++#define WARN(stuff...) printk(KERN_WARNING "udc: " stuff) ++#define INFO(stuff...) printk(KERN_INFO "udc: " stuff) ++ ++ ++#endif /* __LINUX_USB_GADGET_PXA27X_H */ +diff --git a/drivers/usb/gadget/pxa2xx_udc.h b/drivers/usb/gadget/pxa2xx_udc.h +index 0e5d0e6..9483a49 100644 +--- a/drivers/usb/gadget/pxa2xx_udc.h ++++ b/drivers/usb/gadget/pxa2xx_udc.h +@@ -206,7 +206,8 @@ dump_state(struct pxa2xx_udc *dev) + unsigned i; + + DMSG("%s %s, uicr %02X.%02X, usir %02X.%02x, ufnr %02X.%02X\n", +- is_usb_connected() ? "host " : "disconnected", ++ //is_usb_connected() ? "host " : "disconnected", ++ "host ", + state_name[dev->ep0state], + UICR1, UICR0, USIR1, USIR0, UFNRH, UFNRL); + dump_udccr("udccr"); +@@ -223,8 +224,8 @@ dump_state(struct pxa2xx_udc *dev) + } else + DMSG("ep0 driver '%s'\n", dev->driver->driver.name); + +- if (!is_usb_connected()) +- return; ++ //if (!is_usb_connected()) ++ // return; + + dump_udccs0 ("udccs0"); + DMSG("ep0 IN %lu/%lu, OUT %lu/%lu\n", +diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c +index ce4d2e0..5dac23f 100644 +--- a/drivers/usb/gadget/serial.c ++++ b/drivers/usb/gadget/serial.c +@@ -1356,6 +1356,7 @@ static int __init gs_bind(struct usb_gadget *gadget) + struct usb_ep *ep; + struct gs_dev *dev; + int gcnum; ++ struct usb_endpoint_config ep_config[2]; + + /* Some controllers can't support CDC ACM: + * - sh doesn't support multiple interfaces or configs; +@@ -1376,22 +1377,33 @@ static int __init gs_bind(struct usb_gadget *gadget) + __constant_cpu_to_le16(GS_VERSION_NUM|0x0099); + } + ++ ep_config[0].config = GS_BULK_CONFIG_ID; ++ ep_config[0].interface = gs_bulk_interface_desc.bInterfaceNumber; ++ ep_config[0].altinterface = gs_bulk_interface_desc.bAlternateSetting; ++ ep_config[1].config = GS_ACM_CONFIG_ID; ++ ep_config[1].interface = gs_data_interface_desc.bInterfaceNumber; ++ ep_config[1].altinterface = gs_data_interface_desc.bAlternateSetting; ++ + usb_ep_autoconfig_reset(gadget); + +- ep = usb_ep_autoconfig(gadget, &gs_fullspeed_in_desc); ++ ep = usb_ep_autoconfig(gadget, &gs_fullspeed_in_desc, &ep_config[0], 2); + if (!ep) + goto autoconf_fail; + EP_IN_NAME = ep->name; + ep->driver_data = ep; /* claim the endpoint */ + +- ep = usb_ep_autoconfig(gadget, &gs_fullspeed_out_desc); ++ ep = usb_ep_autoconfig(gadget, &gs_fullspeed_out_desc, &ep_config[0], 2); + if (!ep) + goto autoconf_fail; + EP_OUT_NAME = ep->name; + ep->driver_data = ep; /* claim the endpoint */ + + if (use_acm) { +- ep = usb_ep_autoconfig(gadget, &gs_fullspeed_notify_desc); ++ ep_config[0].config = GS_ACM_CONFIG_ID; ++ ep_config[0].interface = gs_control_interface_desc.bInterfaceNumber; ++ ep_config[0].altinterface = gs_control_interface_desc.bAlternateSetting; ++ ++ ep = usb_ep_autoconfig(gadget, &gs_fullspeed_notify_desc, &ep_config[0], 1); + if (!ep) { + printk(KERN_ERR "gs_bind: cannot run ACM on %s\n", gadget->name); + goto autoconf_fail; +diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c +index fcfe869..1e40d46 100644 +--- a/drivers/usb/gadget/zero.c ++++ b/drivers/usb/gadget/zero.c +@@ -1142,6 +1142,7 @@ zero_bind (struct usb_gadget *gadget) + struct zero_dev *dev; + struct usb_ep *ep; + int gcnum; ++ struct usb_endpoint_config ep_config[2]; + + /* FIXME this can't yet work right with SH ... it has only + * one configuration, numbered one. +@@ -1154,7 +1155,15 @@ zero_bind (struct usb_gadget *gadget) + * but there may also be important quirks to address. + */ + usb_ep_autoconfig_reset (gadget); +- ep = usb_ep_autoconfig (gadget, &fs_source_desc); ++ ++ ep_config[0].config = CONFIG_SOURCE_SINK; ++ ep_config[0].interface = source_sink_intf.bInterfaceNumber; ++ ep_config[0].altinterface = source_sink_intf.bAlternateSetting; ++ ep_config[1].config = CONFIG_LOOPBACK; ++ ep_config[1].interface = loopback_intf.bInterfaceNumber; ++ ep_config[1].altinterface = loopback_intf.bAlternateSetting; ++ ++ ep = usb_ep_autoconfig(gadget, &fs_source_desc, &ep_config[0], 2); + if (!ep) { + autoconf_fail: + printk (KERN_ERR "%s: can't autoconfigure on %s\n", +@@ -1164,7 +1173,7 @@ autoconf_fail: + EP_IN_NAME = ep->name; + ep->driver_data = ep; /* claim */ + +- ep = usb_ep_autoconfig (gadget, &fs_sink_desc); ++ ep = usb_ep_autoconfig(gadget, &fs_sink_desc, &ep_config[0], 2); + if (!ep) + goto autoconf_fail; + EP_OUT_NAME = ep->name; +diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig +index 2580f5f..12e4b91 100644 +--- a/drivers/video/backlight/Kconfig ++++ b/drivers/video/backlight/Kconfig +@@ -40,7 +40,7 @@ config BACKLIGHT_CLASS_DEVICE + + config BACKLIGHT_CORGI + tristate "Sharp Corgi Backlight Driver (SL Series)" +- depends on BACKLIGHT_CLASS_DEVICE && PXA_SHARPSL ++ depends on BACKLIGHT_CLASS_DEVICE && (PXA_SHARPSL || MACH_EM_X270) + default y + help + If you have a Sharp Zaurus SL-C7xx, SL-Cxx00 or SL-6000x say y to enable the +diff --git a/include/asm-arm/arch-pxa/pwr-i2c.h b/include/asm-arm/arch-pxa/pwr-i2c.h +new file mode 100644 +index 0000000..6bad486 +--- /dev/null ++++ b/include/asm-arm/arch-pxa/pwr-i2c.h +@@ -0,0 +1,61 @@ ++/* ++ * (C) Copyright 2007 CompuLab, Ltd ++ * Mike Rapoport <mike@compulab.co.il> ++ * ++ * Simple Power I2C interface for PXA processors. ++ * Based on U-Boot PXA I2C driver. ++ * ++ * 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 ++ * ++ */ ++ ++#ifndef __PXA_PWR_I2C_H__ ++#define __PXA_PWR_I2C_H__ ++ ++/* ++ * Configuration items. ++ */ ++#define I2C_RXTX_LEN 128 /* maximum tx/rx buffer length */ ++ ++/* ++ * Probe the given I2C chip address. Returns 0 if a chip responded, ++ * not 0 on failure. ++ */ ++extern int pxa_pwr_i2c_probe(u8 chip); ++ ++/* ++ * Read/Write interface: ++ * chip: I2C chip address, range 0..127 ++ * addr: Memory (register) address within the chip ++ * alen: Number of bytes to use for addr (typically 1, 2 for larger ++ * memories, 0 for register type devices with only one ++ * register) ++ * buffer: Where to read/write the data ++ * len: How many bytes to read/write ++ * ++ * Returns: 0 on success, not 0 on failure ++ */ ++extern int pxa_pwr_i2c_read(u8 chip, uint addr, int alen, u8 *buffer, int len); ++extern int pxa_pwr_i2c_write(u8 chip, uint addr, int alen, ++ u8 *buffer, int len); ++ ++/* ++ * Utility routines to read/write registers. ++ */ ++extern s32 pxa_pwr_i2c_reg_read (u8 chip, u8 reg); ++extern s32 pxa_pwr_i2c_reg_write(u8 chip, u8 reg, u8 val); ++ ++#endif /* __PXA_PWR_I2C_H___ */ +diff --git a/include/linux/da9030.h b/include/linux/da9030.h +new file mode 100644 +index 0000000..6eb89e2 +--- /dev/null ++++ b/include/linux/da9030.h +@@ -0,0 +1,118 @@ ++#ifndef _DA9030_H ++#define _DA9030_H ++ ++/* DA9030 has 24 possible interrupts */ ++#define DA9030_IRQ_COUNT 24 ++ ++/* EVENT A */ ++#define DA9030_IRQ_ONKEY_EN 0 ++#define DA9030_IRQ_PWREN1 1 ++#define DA9030_IRQ_EXTON 2 ++#define DA9030_IRQ_CHDET 3 ++#define DA9030_IRQ_TBAT 4 ++#define DA9030_IRQ_VBATMON 5 ++#define DA9030_IRQ_VBATMONTXON 6 ++#define DA9030_IRQ_CHIOVER 7 ++ ++/* EVENT B */ ++#define DA9030_IRQ_TCTO 8 ++#define DA9030_IRQ_CCTO 9 ++#define DA9030_IRQ_ADC_READY 10 ++#define DA9030_IRQ_VBUS_4_4 11 ++#define DA9030_IRQ_VBUS_4_0 12 ++#define DA9030_IRQ_SESSION_VALID 13 ++#define DA9030_IRQ_SRP_DETECT 14 ++#define DA9030_IRQ_WDOG_INTR 15 ++ ++/* EVENT C */ ++#define DA9030_IRQ_LDO15 16 ++#define DA9030_IRQ_LDO16 17 ++#define DA9030_IRQ_LDO17 18 ++#define DA9030_IRQ_LDO18 19 ++#define DA9030_IRQ_LDO19 20 ++#define DA9030_IRQ_BUCK2 21 ++#define DA9030_IRQ_ADC_IN4 22 ++#define DA9030_IRQ_ADC_IN5 23 ++ ++enum da9030_ldo_sleep_mode { ++ DA9030_LDO_SLEEP_KEEP = 0x0, ++ DA9030_LDO_SLEEP_SHUT_DOWN = 0x1, ++ DA9030_LDO_SLEEP_POWER_UP = 0x2, ++ DA9030_LDO_SLEEP_HIGH_Z = 0x3, ++}; ++ ++enum da9030_led_rate { ++ DA9030_LED_RATE_ON = 0x0, ++ DA9030_LED_RATE_0_52 = 0x1, ++ DA9030_LED_RATE_1_05 = 0x2, ++ DA9030_LED_RATE_2_1 = 0x3, ++}; ++ ++enum da9030_led_duty_cycle { ++ DA9030_LED_DUTY_1_16 = 0x0, ++ DA9030_LED_DUTY_1_8 = 0x1, ++ DA9030_LED_DUTY_1_4 = 0x2, ++ DA9030_LED_DUTY_1_2 = 0x3, ++}; ++ ++enum da9030_led_pwm_chop { ++ DA9030_LED_PWM_8_8 = 0x0, ++ DA9030_LED_PWM_7_8 = 0x1, ++ DA9030_LED_PWM_6_8 = 0x2, ++ DA9030_LED_PWM_5_8 = 0x3, ++ DA9030_LED_PWM_4_8 = 0x4, ++ DA9030_LED_PWM_3_8 = 0x5, ++ DA9030_LED_PWM_2_8 = 0x6, ++ DA9030_LED_PWM_1_8 = 0x7, ++}; ++ ++struct da9030_adc_res { ++ int vbat_res; ++ int vbatmin_res; ++ int vbatmintxon; ++ int ichmax_res; ++ int ichmin_res; ++ int ichaverage_res; ++ int vchmax_res; ++ int vchmin_res; ++ int tbat_res; ++ int adc_in4_res; ++ int adc_in5_res; ++}; ++ ++extern int da9030_get_status(void); ++extern int da9030_get_fault_log(void); ++ ++extern void da9030_enable_adc(void); ++extern void da9030_read_adc(struct da9030_adc_res *adc); ++ ++extern void da9030_set_wled(int on, unsigned int brightness); ++ ++extern int da9030_set_led(int led, int on, ++ enum da9030_led_rate rate, ++ enum da9030_led_duty_cycle duty, ++ enum da9030_led_pwm_chop pwm_chop); ++ ++extern int da9030_set_charger(int on, unsigned int mA, unsigned int mV); ++extern void da9030_get_charger(int *on, unsigned int *mA, unsigned int *mV); ++ ++extern int da9030_set_ldo(int ldo, int on, unsigned int mV, ++ enum da9030_ldo_sleep_mode sleep_mode); ++extern int da9030_set_buck(int buck, int on, unsigned int mV, int flags); ++ ++extern void da9030_set_thresholds(unsigned int tbathighp, ++ unsigned int tbathighn, ++ unsigned int tbatlow, ++ unsigned int vbatmon); ++ ++extern int da9030_register_callback(int event, ++ void (*callback)(int event, void *data), ++ void *data); ++extern void da9030_unregister_callback(int event); ++ ++/* Keep these for now, although they are unsafe. When I'll see what ++ other methods are needed from DA9030, I'll remove these */ ++extern s32 da9030_get_reg(u32 reg); ++extern s32 da9030_set_reg(u32 reg, u8 val); ++ ++#endif +diff --git a/include/linux/usb_gadget.h b/include/linux/usb_gadget.h +index 4f59b2a..792c568 100644 +--- a/include/linux/usb_gadget.h ++++ b/include/linux/usb_gadget.h +@@ -397,10 +397,28 @@ usb_ep_fifo_flush (struct usb_ep *ep) + + struct usb_gadget; + ++/** ++ * struct usb_endpoint_config - possible configurations of a given endpoint ++ * @config: the configuration number ++ * @interface: the interface number ++ * @altinterface: the altinterface number ++ * ++ * Used as an array to pass information about the possible configurations ++ * of a given endpoint to the bus controller. ++ */ ++struct usb_endpoint_config { ++ u8 config; ++ u8 interface; ++ u8 altinterface; ++}; ++ + /* the rest of the api to the controller hardware: device operations, + * which don't involve endpoints (or i/o). + */ + struct usb_gadget_ops { ++ struct usb_ep* (*ep_alloc)(struct usb_gadget *, ++ struct usb_endpoint_descriptor *, ++ struct usb_endpoint_config *, int); + int (*get_frame)(struct usb_gadget *); + int (*wakeup)(struct usb_gadget *); + int (*set_selfpowered) (struct usb_gadget *, int is_selfpowered); +@@ -824,7 +842,10 @@ int usb_gadget_config_buf(const struct usb_config_descriptor *config, + /* utility wrapping a simple endpoint selection policy */ + + extern struct usb_ep *usb_ep_autoconfig (struct usb_gadget *, +- struct usb_endpoint_descriptor *) __devinit; ++ struct usb_endpoint_descriptor *, ++ struct usb_endpoint_config *, ++ int numconfigs ++); + + extern void usb_ep_autoconfig_reset (struct usb_gadget *) __devinit; + +diff --git a/include/linux/wm97xx.h b/include/linux/wm97xx.h +new file mode 100644 +index 0000000..354e533 +--- /dev/null ++++ b/include/linux/wm97xx.h +@@ -0,0 +1,291 @@ ++ ++/* ++ * Register bits and API for Wolfson WM97xx series of codecs ++ */ ++ ++#ifndef _LINUX_WM97XX_H ++#define _LINUX_WM97XX_H ++ ++#include <sound/driver.h> ++#include <sound/core.h> ++#include <sound/pcm.h> ++#include <sound/ac97_codec.h> ++#include <sound/initval.h> ++#include <linux/types.h> ++#include <linux/list.h> ++#include <linux/input.h> /* Input device layer */ ++ ++/* ++ * WM97xx AC97 Touchscreen registers ++ */ ++#define AC97_WM97XX_DIGITISER1 0x76 ++#define AC97_WM97XX_DIGITISER2 0x78 ++#define AC97_WM97XX_DIGITISER_RD 0x7a ++#define AC97_WM9713_DIG1 0x74 ++#define AC97_WM9713_DIG2 AC97_WM97XX_DIGITISER1 ++#define AC97_WM9713_DIG3 AC97_WM97XX_DIGITISER2 ++ ++/* ++ * WM97xx register bits ++ */ ++#define WM97XX_POLL 0x8000 /* initiate a polling measurement */ ++#define WM97XX_ADCSEL_X 0x1000 /* x coord measurement */ ++#define WM97XX_ADCSEL_Y 0x2000 /* y coord measurement */ ++#define WM97XX_ADCSEL_PRES 0x3000 /* pressure measurement */ ++#define WM97XX_ADCSEL_MASK 0x7000 ++#define WM97XX_COO 0x0800 /* enable coordinate mode */ ++#define WM97XX_CTC 0x0400 /* enable continuous mode */ ++#define WM97XX_CM_RATE_93 0x0000 /* 93.75Hz continuous rate */ ++#define WM97XX_CM_RATE_187 0x0100 /* 187.5Hz continuous rate */ ++#define WM97XX_CM_RATE_375 0x0200 /* 375Hz continuous rate */ ++#define WM97XX_CM_RATE_750 0x0300 /* 750Hz continuous rate */ ++#define WM97XX_CM_RATE_8K 0x00f0 /* 8kHz continuous rate */ ++#define WM97XX_CM_RATE_12K 0x01f0 /* 12kHz continuous rate */ ++#define WM97XX_CM_RATE_24K 0x02f0 /* 24kHz continuous rate */ ++#define WM97XX_CM_RATE_48K 0x03f0 /* 48kHz continuous rate */ ++#define WM97XX_CM_RATE_MASK 0x03f0 ++#define WM97XX_RATE(i) (((i & 3) << 8) | ((i & 4) ? 0xf0 : 0)) ++#define WM97XX_DELAY(i) ((i << 4) & 0x00f0) /* sample delay times */ ++#define WM97XX_DELAY_MASK 0x00f0 ++#define WM97XX_SLEN 0x0008 /* slot read back enable */ ++#define WM97XX_SLT(i) ((i - 5) & 0x7) /* touchpanel slot selection (5-11) */ ++#define WM97XX_SLT_MASK 0x0007 ++#define WM97XX_PRP_DETW 0x4000 /* pen detect on, digitiser off, wake up */ ++#define WM97XX_PRP_DET 0x8000 /* pen detect on, digitiser off, no wake up */ ++#define WM97XX_PRP_DET_DIG 0xc000 /* pen detect on, digitiser on */ ++#define WM97XX_RPR 0x2000 /* wake up on pen down */ ++#define WM97XX_PEN_DOWN 0x8000 /* pen is down */ ++#define WM97XX_ADCSRC_MASK 0x7000 /* ADC source mask */ ++ ++#define WM97XX_AUX_ID1 0x8001 ++#define WM97XX_AUX_ID2 0x8002 ++#define WM97XX_AUX_ID3 0x8003 ++#define WM97XX_AUX_ID4 0x8004 ++ ++ ++/* WM9712 Bits */ ++#define WM9712_45W 0x1000 /* set for 5-wire touchscreen */ ++#define WM9712_PDEN 0x0800 /* measure only when pen down */ ++#define WM9712_WAIT 0x0200 /* wait until adc is read before next sample */ ++#define WM9712_PIL 0x0100 /* current used for pressure measurement. set 400uA else 200uA */ ++#define WM9712_MASK_HI 0x0040 /* hi on mask pin (47) stops conversions */ ++#define WM9712_MASK_EDGE 0x0080 /* rising/falling edge on pin delays sample */ ++#define WM9712_MASK_SYNC 0x00c0 /* rising/falling edge on mask initiates sample */ ++#define WM9712_RPU(i) (i&0x3f) /* internal pull up on pen detect (64k / rpu) */ ++#define WM9712_PD(i) (0x1 << i) /* power management */ ++ ++/* WM9712 Registers */ ++#define AC97_WM9712_POWER 0x24 ++#define AC97_WM9712_REV 0x58 ++ ++/* WM9705 Bits */ ++#define WM9705_PDEN 0x1000 /* measure only when pen is down */ ++#define WM9705_PINV 0x0800 /* inverts sense of pen down output */ ++#define WM9705_BSEN 0x0400 /* BUSY flag enable, pin47 is 1 when busy */ ++#define WM9705_BINV 0x0200 /* invert BUSY (pin47) output */ ++#define WM9705_WAIT 0x0100 /* wait until adc is read before next sample */ ++#define WM9705_PIL 0x0080 /* current used for pressure measurement. set 400uA else 200uA */ ++#define WM9705_PHIZ 0x0040 /* set PHONE and PCBEEP inputs to high impedance */ ++#define WM9705_MASK_HI 0x0010 /* hi on mask stops conversions */ ++#define WM9705_MASK_EDGE 0x0020 /* rising/falling edge on pin delays sample */ ++#define WM9705_MASK_SYNC 0x0030 /* rising/falling edge on mask initiates sample */ ++#define WM9705_PDD(i) (i & 0x000f) /* pen detect comparator threshold */ ++ ++ ++/* WM9713 Bits */ ++#define WM9713_PDPOL 0x0400 /* Pen down polarity */ ++#define WM9713_POLL 0x0200 /* initiate a polling measurement */ ++#define WM9713_CTC 0x0100 /* enable continuous mode */ ++#define WM9713_ADCSEL_X 0x0002 /* X measurement */ ++#define WM9713_ADCSEL_Y 0x0004 /* Y measurement */ ++#define WM9713_ADCSEL_PRES 0x0008 /* Pressure measurement */ ++#define WM9713_COO 0x0001 /* enable coordinate mode */ ++#define WM9713_PDEN 0x0800 /* measure only when pen down */ ++#define WM9713_ADCSEL_MASK 0x00fe /* ADC selection mask */ ++#define WM9713_WAIT 0x0200 /* coordinate wait */ ++ ++/* AUX ADC ID's */ ++#define TS_COMP1 0x0 ++#define TS_COMP2 0x1 ++#define TS_BMON 0x2 ++#define TS_WIPER 0x3 ++ ++/* ID numbers */ ++#define WM97XX_ID1 0x574d ++#define WM9712_ID2 0x4c12 ++#define WM9705_ID2 0x4c05 ++#define WM9713_ID2 0x4c13 ++ ++/* Codec GPIO's */ ++#define WM97XX_MAX_GPIO 16 ++#define WM97XX_GPIO_1 (1 << 1) ++#define WM97XX_GPIO_2 (1 << 2) ++#define WM97XX_GPIO_3 (1 << 3) ++#define WM97XX_GPIO_4 (1 << 4) ++#define WM97XX_GPIO_5 (1 << 5) ++#define WM97XX_GPIO_6 (1 << 6) ++#define WM97XX_GPIO_7 (1 << 7) ++#define WM97XX_GPIO_8 (1 << 8) ++#define WM97XX_GPIO_9 (1 << 9) ++#define WM97XX_GPIO_10 (1 << 10) ++#define WM97XX_GPIO_11 (1 << 11) ++#define WM97XX_GPIO_12 (1 << 12) ++#define WM97XX_GPIO_13 (1 << 13) ++#define WM97XX_GPIO_14 (1 << 14) ++#define WM97XX_GPIO_15 (1 << 15) ++ ++ ++#define AC97_LINK_FRAME 21 /* time in uS for AC97 link frame */ ++ ++ ++/*---------------- Return codes from sample reading functions ---------------*/ ++ ++/* More data is available; call the sample gathering function again */ ++#define RC_AGAIN 0x00000001 ++/* The returned sample is valid */ ++#define RC_VALID 0x00000002 ++/* The pen is up (the first RC_VALID without RC_PENUP means pen is down) */ ++#define RC_PENUP 0x00000004 ++/* The pen is down (RC_VALID implies RC_PENDOWN, but sometimes it is helpful ++ to tell the handler that the pen is down but we don't know yet his coords, ++ so the handler should not sleep or wait for pendown irq) */ ++#define RC_PENDOWN 0x00000008 ++ ++/* The wm97xx driver provides a private API for writing platform-specific ++ * drivers. ++ */ ++ ++/* The structure used to return arch specific sampled data into */ ++struct wm97xx_data { ++ int x; ++ int y; ++ int p; ++}; ++ ++/* Codec GPIO status ++ */ ++typedef enum { ++ WM97XX_GPIO_HIGH, ++ WM97XX_GPIO_LOW ++} wm97xx_gpio_status_t; ++ ++/* Codec GPIO direction ++ */ ++typedef enum { ++ WM97XX_GPIO_IN, ++ WM97XX_GPIO_OUT ++} wm97xx_gpio_dir_t; ++ ++/* Codec GPIO polarity ++ */ ++typedef enum { ++ WM97XX_GPIO_POL_HIGH, ++ WM97XX_GPIO_POL_LOW ++} wm97xx_gpio_pol_t; ++ ++/* Codec GPIO sticky ++ */ ++typedef enum { ++ WM97XX_GPIO_STICKY, ++ WM97XX_GPIO_NOTSTICKY ++} wm97xx_gpio_sticky_t; ++ ++/* Codec GPIO wake ++ */ ++typedef enum { ++ WM97XX_GPIO_WAKE, ++ WM97XX_GPIO_NOWAKE ++} wm97xx_gpio_wake_t; ++ ++ ++/* ++ * Digitiser ioctl commands ++ */ ++#define WM97XX_DIG_START 0x1 ++#define WM97XX_DIG_STOP 0x2 ++#define WM97XX_PHY_INIT 0x3 ++#define WM97XX_AUX_PREPARE 0x4 ++#define WM97XX_DIG_RESTORE 0x5 ++ ++struct wm97xx; ++extern struct wm97xx_codec_drv wm97xx_codec; ++ ++/* ++ * Codec driver interface - allows mapping to WM9705/12/13 and newer codecs ++ */ ++struct wm97xx_codec_drv { ++ u16 id; ++ char *name; ++ int (*poll_sample) (struct wm97xx *, int adcsel, int *sample); /* read 1 sample */ ++ int (*poll_touch) (struct wm97xx *, struct wm97xx_data *); /* read X,Y,[P] in poll */ ++ int (*digitiser_ioctl) (struct wm97xx *, int cmd); ++ int (*acc_enable) (struct wm97xx *, int enable); ++}; ++ ++ ++/* Machine specific and accelerated touch operations */ ++struct wm97xx_mach_ops { ++ ++ /* accelerated touch readback - coords are transmited on AC97 link */ ++ int acc_enabled; ++ void (*acc_pen_up) (struct wm97xx *); ++ int (*acc_pen_down) (struct wm97xx *); ++ int (*acc_startup) (struct wm97xx *); ++ void (*acc_shutdown) (struct wm97xx *); ++ ++ /* pre and post sample - can be used to minimise any analog noise */ ++ void (*pre_sample) (int); /* function to run before sampling */ ++ void (*post_sample) (int); /* function to run after sampling */ ++}; ++ ++struct wm97xx { ++ u16 dig[3], id, gpio[6], misc; /* Cached codec registers */ ++ u16 dig_save[3]; /* saved during aux reading */ ++ struct wm97xx_codec_drv *codec; /* attached codec driver*/ ++ struct input_dev* input_dev; /* touchscreen input device */ ++ struct snd_ac97 *ac97; /* ALSA codec access */ ++ struct device *dev; /* ALSA device */ ++ struct device *battery_dev; ++ struct device *touch_dev; ++ struct wm97xx_mach_ops *mach_ops; ++ struct mutex codec_mutex; ++ struct completion ts_init; ++ struct completion ts_exit; ++ struct task_struct *ts_task; ++ unsigned int pen_irq; /* Pen IRQ number in use */ ++ wait_queue_head_t pen_irq_wait; /* Pen IRQ wait queue */ ++ struct workqueue_struct *pen_irq_workq; ++ struct work_struct pen_event_work; ++ u16 acc_slot; /* AC97 slot used for acc touch data */ ++ u16 acc_rate; /* acc touch data rate */ ++ unsigned int ts_use_count; ++ unsigned pen_is_down:1; /* Pen is down */ ++ unsigned aux_waiting:1; /* aux measurement waiting */ ++ unsigned pen_probably_down:1; /* used in polling mode */ ++}; ++ ++/* Codec GPIO access (not supported on WM9705) ++ * This can be used to set/get codec GPIO and Virtual GPIO status. ++ */ ++wm97xx_gpio_status_t wm97xx_get_gpio(struct wm97xx *wm, u32 gpio); ++void wm97xx_set_gpio(struct wm97xx *wm, u32 gpio, ++ wm97xx_gpio_status_t status); ++void wm97xx_config_gpio(struct wm97xx *wm, u32 gpio, ++ wm97xx_gpio_dir_t dir, ++ wm97xx_gpio_pol_t pol, ++ wm97xx_gpio_sticky_t sticky, ++ wm97xx_gpio_wake_t wake); ++ ++/* codec AC97 IO access */ ++int wm97xx_reg_read(struct wm97xx *wm, u16 reg); ++void wm97xx_reg_write(struct wm97xx *wm, u16 reg, u16 val); ++ ++/* aux adc readback */ ++int wm97xx_read_aux_adc(struct wm97xx *wm, u16 adcsel); ++ ++/* machine ops */ ++int wm97xx_register_mach_ops(struct wm97xx *, struct wm97xx_mach_ops *); ++void wm97xx_unregister_mach_ops(struct wm97xx *); ++ ++extern struct bus_type wm97xx_bus_type; ++#endif +diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig +index a83e229..89b5730 100644 +--- a/sound/soc/pxa/Kconfig ++++ b/sound/soc/pxa/Kconfig +@@ -53,3 +53,12 @@ config SND_PXA2XX_SOC_TOSA + help + Say Y if you want to add support for SoC audio on Sharp + Zaurus SL-C6000x models (Tosa). ++ ++config SND_PXA2XX_SOC_EM_X270 ++ tristate "SoC Audio support for CompuLab EM-x270" ++ depends on SND_PXA2XX_SOC && MACH_EM_X270 ++ select SND_PXA2XX_SOC_AC97 ++ select SND_SOC_WM9712 ++ help ++ Say Y if you want to add support for SoC audio on ++ CompuLab EM-x270. +diff --git a/sound/soc/pxa/Makefile b/sound/soc/pxa/Makefile +index 78e0d6b..32375ac 100644 +--- a/sound/soc/pxa/Makefile ++++ b/sound/soc/pxa/Makefile +@@ -12,9 +12,11 @@ snd-soc-corgi-objs := corgi.o + snd-soc-poodle-objs := poodle.o + snd-soc-tosa-objs := tosa.o + snd-soc-spitz-objs := spitz.o ++snd-soc-em-x270-objs := em-x270.o + + obj-$(CONFIG_SND_PXA2XX_SOC_CORGI) += snd-soc-corgi.o + obj-$(CONFIG_SND_PXA2XX_SOC_POODLE) += snd-soc-poodle.o + obj-$(CONFIG_SND_PXA2XX_SOC_TOSA) += snd-soc-tosa.o + obj-$(CONFIG_SND_PXA2XX_SOC_SPITZ) += snd-soc-spitz.o ++obj-$(CONFIG_SND_PXA2XX_SOC_EM_X270) += snd-soc-em-x270.o + +diff --git a/sound/soc/pxa/em-x270.c b/sound/soc/pxa/em-x270.c +new file mode 100644 +index 0000000..9e891d0 +--- /dev/null ++++ b/sound/soc/pxa/em-x270.c +@@ -0,0 +1,137 @@ ++/* ++ * em-x270.c -- SoC audio for EM-X270 ++ * ++ * Copyright 2007 CompuLab, Ltd. ++ * ++ * Author: Mike Rapoport <mike@compulab.co.il> ++ * ++ * Copied from tosa.c: ++ * Copyright 2005 Wolfson Microelectronics PLC. ++ * Copyright 2005 Openedhand Ltd. ++ * ++ * Authors: Liam Girdwood <liam.girdwood@wolfsonmicro.com> ++ * Richard Purdie <richard@openedhand.com> ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ * ++ */ ++ ++#include <linux/module.h> ++#include <linux/moduleparam.h> ++#include <linux/device.h> ++ ++#include <sound/driver.h> ++#include <sound/core.h> ++#include <sound/pcm.h> ++#include <sound/soc.h> ++#include <sound/soc-dapm.h> ++ ++#include <asm/mach-types.h> ++#include <asm/arch/pxa-regs.h> ++#include <asm/arch/hardware.h> ++#include <asm/arch/audio.h> ++ ++#include "../codecs/wm9712.h" ++#include "pxa2xx-pcm.h" ++#include "pxa2xx-ac97.h" ++ ++static struct snd_soc_machine em_x270; ++ ++#define EM_X270_HP 0 ++#define EM_X270_MIC_INT 1 ++#define EM_X270_HEADSET 2 ++#define EM_X270_HP_OFF 3 ++#define EM_X270_SPK_ON 0 ++#define EM_X270_SPK_OFF 1 ++ ++ ++static struct snd_soc_ops em_x270_ops = { ++}; ++ ++static const struct snd_kcontrol_new em_x270_controls[] = { ++}; ++ ++static int em_x270_ac97_init(struct snd_soc_codec *codec) ++{ ++ int i, err; ++ ++ /* add em_x270 specific controls */ ++ for (i = 0; i < ARRAY_SIZE(em_x270_controls); i++) { ++ err = snd_ctl_add(codec->card, ++ snd_soc_cnew(&em_x270_controls[i],codec, NULL)); ++ if (err < 0) ++ return err; ++ } ++ ++ snd_soc_dapm_sync_endpoints(codec); ++ return 0; ++} ++ ++static struct snd_soc_dai_link em_x270_dai[] = { ++ { ++ .name = "AC97", ++ .stream_name = "AC97 HiFi", ++ .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_HIFI], ++ .codec_dai = &wm9712_dai[WM9712_DAI_AC97_HIFI], ++ .init = em_x270_ac97_init, ++ .ops = &em_x270_ops, ++ }, ++ { ++ .name = "AC97 Aux", ++ .stream_name = "AC97 Aux", ++ .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_AUX], ++ .codec_dai = &wm9712_dai[WM9712_DAI_AC97_AUX], ++ .ops = &em_x270_ops, ++ }, ++}; ++ ++static struct snd_soc_machine em_x270 = { ++ .name = "EM-X270", ++ .dai_link = em_x270_dai, ++ .num_links = ARRAY_SIZE(em_x270_dai), ++}; ++ ++static struct snd_soc_device em_x270_snd_devdata = { ++ .machine = &em_x270, ++ .platform = &pxa2xx_soc_platform, ++ .codec_dev = &soc_codec_dev_wm9712, ++}; ++ ++static struct platform_device *em_x270_snd_device; ++ ++static int __init em_x270_init(void) ++{ ++ int ret; ++ ++ if (!machine_is_em_x270()) ++ return -ENODEV; ++ ++ em_x270_snd_device = platform_device_alloc("soc-audio", -1); ++ if (!em_x270_snd_device) ++ return -ENOMEM; ++ ++ platform_set_drvdata(em_x270_snd_device, &em_x270_snd_devdata); ++ em_x270_snd_devdata.dev = &em_x270_snd_device->dev; ++ ret = platform_device_add(em_x270_snd_device); ++ ++ if (ret) ++ platform_device_put(em_x270_snd_device); ++ ++ return ret; ++} ++ ++static void __exit em_x270_exit(void) ++{ ++ platform_device_unregister(em_x270_snd_device); ++} ++ ++module_init(em_x270_init); ++module_exit(em_x270_exit); ++ ++/* Module information */ ++MODULE_AUTHOR("Mike Rapoport"); ++MODULE_DESCRIPTION("ALSA SoC EM-X270"); ++MODULE_LICENSE("GPL"); diff --git a/packages/linux/em-x270_2.6.23.bb b/packages/linux/em-x270_2.6.23.bb new file mode 100644 index 0000000000..a9d6ee7905 --- /dev/null +++ b/packages/linux/em-x270_2.6.23.bb @@ -0,0 +1,29 @@ +require linux.inc + +SECTION = "kernel" +DESCRIPTION = "Linux kernel for the Compulab EM-X270 system" +LICENSE = "GPL" +DEPENDS = "uboot-utils" +PR = "r0" + +KERNEL_IMAGETYPE = "uImage" + +SRC_URI = "${KERNELORG_MIRROR}/pub/linux/kernel/v2.6/linux-${PV}.tar.bz2 \ + file://em-x270.patch;patch=1 \ + file://defconfig \ + " + +S = "${WORKDIR}/linux-${PV}" + +COMPATIBLE_HOST = 'arm.*-linux' +COMPATIBLE_MACHINE = "em-x270" + +inherit kernel +inherit package + +ARCH = "arm" + +FILES_kernel-image = "" + +S = "${WORKDIR}/linux-${PV}" + diff --git a/packages/linux/linux-2.6.21/gumstix-pxa270-mmc.patch b/packages/linux/linux-2.6.21/gumstix-pxa270-mmc.patch new file mode 100644 index 0000000000..59d97809d1 --- /dev/null +++ b/packages/linux/linux-2.6.21/gumstix-pxa270-mmc.patch @@ -0,0 +1,33 @@ +Index: linux-2.6.21gum/arch/arm/mach-pxa/gumstix.c +=================================================================== +--- linux-2.6.21gum.orig/arch/arm/mach-pxa/gumstix.c ++++ linux-2.6.21gum/arch/arm/mach-pxa/gumstix.c +@@ -33,8 +33,9 @@ + + static struct pxamci_platform_data gumstix_mci_platform_data; + +-static int gumstix_mci_init(struct device *dev, irqreturn_t (*gumstix_detect_int)(int, void *, struct pt_regs *), void *data) ++static int gumstix_mci_init(struct device *dev, irq_handler_t gumstix_detect_int, void *data) + { ++#ifndef CONFIG_ARCH_GUMSTIX_VERDEX + int err; + + pxa_gpio_mode(GPIO6_MMCCLK_MD); +@@ -55,6 +56,17 @@ static int gumstix_mci_init(struct devic + } + + err = set_irq_type(GUMSTIX_IRQ_GPIO_nSD_DETECT, IRQT_BOTHEDGE); ++#else ++ // Setup GPIOs for MMC on the 120-pin connector ++ // There is no card detect on a uSD connector so no interrupt to register ++ // There is no WP detect GPIO line either ++ pxa_gpio_mode(GPIO92_MMCDAT0_MD); ++ pxa_gpio_mode(GPIO112_MMCCMD_MD); ++ pxa_gpio_mode(GPIO110_MMCDAT2_MD); ++ pxa_gpio_mode(GPIO111_MMCDAT3_MD); ++ pxa_gpio_mode(GPIO109_MMCDAT1_MD); ++ pxa_gpio_mode(GPIO32_MMCCLK_MD); ++#endif + + return 0; + } diff --git a/packages/linux/linux-2.6.21/gumstix-verdex/defconfig b/packages/linux/linux-2.6.21/gumstix-verdex/defconfig index 9107cd0d7c..3057d62d5e 100644 --- a/packages/linux/linux-2.6.21/gumstix-verdex/defconfig +++ b/packages/linux/linux-2.6.21/gumstix-verdex/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.21 -# Thu Sep 13 14:49:02 2007 +# Mon Oct 8 11:22:41 2007 # CONFIG_ARM=y CONFIG_SYS_SUPPORTS_APM_EMULATION=y @@ -219,7 +219,7 @@ CONFIG_ALIGNMENT_HANDLING=0x2 # CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE="console=ttyS0,115200n8 root=1f01 rootfstype=jffs2" +CONFIG_CMDLINE="" # CONFIG_XIP_KERNEL is not set CONFIG_KEXEC=y @@ -828,7 +828,8 @@ CONFIG_MII=m CONFIG_SMC91X=m CONFIG_SMC91X_GUMSTIX=m # CONFIG_DM9000 is not set -# CONFIG_SMC911X is not set +CONFIG_SMC911X=m +CONFIG_SMC911X_GUMSTIX=m # # Ethernet (1000 Mbit) @@ -1057,6 +1058,8 @@ CONFIG_I2C_PXA_SLAVE=y # CONFIG_SENSORS_PCA9539 is not set # CONFIG_SENSORS_PCF8591 is not set # CONFIG_SENSORS_MAX6875 is not set +CONFIG_SENSORS_TSC2003=m +CONFIG_SENSORS_TSC2003_SYSFS=m # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set @@ -1137,6 +1140,9 @@ CONFIG_FB_PXA=y # CONFIG_FB_PXA_SHARP_LQ043_PSP is not set CONFIG_FB_PXA_SAMSUNG_LTE430WQ_F0C=y # CONFIG_FB_PXA_NONEOFTHEABOVE is not set +# CONFIG_FB_PXA_LCD_QVGA is not set +CONFIG_FB_PXA_LCD_VGA=y +CONFIG_FB_PXA_OVERLAY=y CONFIG_FB_PXA_PARAMETERS=y # CONFIG_FB_MBX is not set # CONFIG_FB_VIRTUAL is not set diff --git a/packages/linux/linux-2.6.21/mmc-card-detect.patch b/packages/linux/linux-2.6.21/mmc-card-detect.patch index 9a853b4df8..26dd970e3b 100644 --- a/packages/linux/linux-2.6.21/mmc-card-detect.patch +++ b/packages/linux/linux-2.6.21/mmc-card-detect.patch @@ -2,7 +2,7 @@ Index: linux-2.6.21gum/arch/arm/mach-pxa/gumstix.c =================================================================== --- linux-2.6.21gum.orig/arch/arm/mach-pxa/gumstix.c +++ linux-2.6.21gum/arch/arm/mach-pxa/gumstix.c -@@ -29,19 +29,51 @@ +@@ -29,19 +29,55 @@ #include "generic.h" @@ -38,9 +38,13 @@ Index: linux-2.6.21gum/arch/arm/mach-pxa/gumstix.c +static int gumstix_mci_get_ro(struct device *dev) +{ ++#ifdef CONFIG_ARCH_GUMSTIX_VERDEX ++ return 0; // microSD is always writable on verdex ++#else + int ro; + ro = GPLR(GUMSTIX_GPIO_nSD_WP) & GPIO_bit(GUMSTIX_GPIO_nSD_WP); + return ro; ++#endif +} + +static void gumstix_mci_exit(struct device *dev, void *data) diff --git a/packages/linux/linux-2.6.21/pxafb-18bpp-mode.patch b/packages/linux/linux-2.6.21/pxafb-18bpp-mode.patch index 3643b402e5..c9849d22f4 100644 --- a/packages/linux/linux-2.6.21/pxafb-18bpp-mode.patch +++ b/packages/linux/linux-2.6.21/pxafb-18bpp-mode.patch @@ -154,7 +154,7 @@ Index: linux-2.6.21gum/drivers/video/pxafb.c case '-': namelen = i; if (!bpp_specified && !yres_specified) { -@@ -1227,6 +1268,18 @@ static int __init pxafb_parse_options(st +@@ -1227,12 +1268,29 @@ static int __init pxafb_parse_options(st } if (bpp_specified) switch (bpp) { @@ -173,6 +173,17 @@ Index: linux-2.6.21gum/drivers/video/pxafb.c case 1: case 2: case 4: + case 8: + case 16: + inf->modes[0].bpp = bpp; ++ if(nonstd_specified) { ++ dev_err(dev, "Depth %d requires nonstd to *not* be specified\n",bpp); ++ } else { ++ inf->modes[0].nonstd = 0; ++ } + dev_info(dev, "overriding bit depth: %d\n", bpp); + break; + default: Index: linux-2.6.21gum/include/asm-arm/arch-pxa/pxa-regs.h =================================================================== --- linux-2.6.21gum.orig/include/asm-arm/arch-pxa/pxa-regs.h @@ -217,7 +228,7 @@ Index: linux-2.6.21gum/arch/arm/mach-pxa/gumstix.c =================================================================== --- linux-2.6.21gum.orig/arch/arm/mach-pxa/gumstix.c +++ linux-2.6.21gum/arch/arm/mach-pxa/gumstix.c -@@ -100,7 +100,8 @@ static struct pxafb_mode_info gumstix_fb +@@ -116,7 +116,8 @@ static struct pxafb_mode_info gumstix_fb .pixclock = 110000, .xres = 480, .yres = 272, @@ -227,7 +238,7 @@ Index: linux-2.6.21gum/arch/arm/mach-pxa/gumstix.c .hsync_len = 41, .left_margin = 2, .right_margin = 2, -@@ -139,7 +140,8 @@ static struct pxafb_mode_info gumstix_fb +@@ -144,7 +145,8 @@ static struct pxafb_mode_info gumstix_fb .vsync_len = 10, // VLW from datasheet: 10 typ .upper_margin = 2, // VBP - VLW from datasheet: 12 - 10 = 2 .lower_margin = 4, // VFP from datasheet: 4 typ diff --git a/packages/linux/linux-2.6.21/pxafb-definition.patch b/packages/linux/linux-2.6.21/pxafb-definition.patch index 2a782c6143..56369fd788 100644 --- a/packages/linux/linux-2.6.21/pxafb-definition.patch +++ b/packages/linux/linux-2.6.21/pxafb-definition.patch @@ -10,10 +10,26 @@ Index: linux-2.6.21gum/arch/arm/mach-pxa/gumstix.c #include <asm/arch/gumstix.h> #include "generic.h" -@@ -86,6 +87,95 @@ static struct platform_device gum_audio_ +@@ -86,6 +87,89 @@ static struct platform_device gum_audio_ .id = -1, }; ++ ++#if defined(CONFIG_FB_PXA_SHARP_LQ043_PSP) || defined(CONFIG_FB_PXA_SAMSUNG_LTE430WQ_F0C) ++static void gumstix_lcd_backlight(int on_or_off) ++{ ++ if(on_or_off) ++ { ++ pxa_gpio_mode(17 | GPIO_IN); ++ } else { ++ GPCR(17) = GPIO_bit(17); ++ pxa_gpio_mode(17 | GPIO_OUT); ++ GPCR(17) = GPIO_bit(17); ++ } ++} ++#endif ++ ++ +#ifdef CONFIG_FB_PXA_ALPS_CDOLLAR +static struct pxafb_mode_info gumstix_fb_mode = { + .pixclock = 300000, @@ -50,17 +66,6 @@ Index: linux-2.6.21gum/arch/arm/mach-pxa/gumstix.c + .sync = 0, // Hsync and Vsync both active low +}; + -+static void gumstix_lcd_backlight(int on_or_off) -+{ -+ pxa_gpio_mode(17 | GPIO_OUT); -+ if(on_or_off) -+ { -+ GPSR(17) = GPIO_bit(17); -+ } else { -+ GPCR(17) = GPIO_bit(17); -+ } -+} -+ +static struct pxafb_mach_info gumstix_fb_info = { + .modes = &gumstix_fb_mode, + .num_modes = 1, @@ -83,17 +88,6 @@ Index: linux-2.6.21gum/arch/arm/mach-pxa/gumstix.c + .sync = 0, // Hsync and Vsync both active low +}; + -+static void gumstix_lcd_backlight(int on_or_off) -+{ -+ pxa_gpio_mode(17 | GPIO_OUT); -+ if(on_or_off) -+ { -+ GPSR(17) = GPIO_bit(17); -+ } else { -+ GPCR(17) = GPIO_bit(17); -+ } -+} -+ +static struct pxafb_mach_info gumstix_fb_info = { + .modes = &gumstix_fb_mode, + .num_modes = 1, @@ -106,7 +100,7 @@ Index: linux-2.6.21gum/arch/arm/mach-pxa/gumstix.c static struct platform_device *devices[] __initdata = { &gum_audio_device, }; -@@ -94,6 +184,9 @@ static void __init gumstix_init(void) +@@ -94,6 +178,9 @@ static void __init gumstix_init(void) { pxa_set_mci_info(&gumstix_mci_platform_data); pxa_set_udc_info(&gumstix_udc_info); diff --git a/packages/linux/linux-2.6.21/smc911x-fixup.patch b/packages/linux/linux-2.6.21/smc911x-fixup.patch new file mode 100644 index 0000000000..c0b7574d3a --- /dev/null +++ b/packages/linux/linux-2.6.21/smc911x-fixup.patch @@ -0,0 +1,392 @@ +Index: linux-2.6.21gum/drivers/net/smc911x.c +=================================================================== +--- linux-2.6.21gum.orig/drivers/net/smc911x.c ++++ linux-2.6.21gum/drivers/net/smc911x.c +@@ -76,6 +76,7 @@ static const char version[] = + #include <linux/etherdevice.h> + #include <linux/skbuff.h> + ++#include <linux/irq.h> + #include <asm/io.h> + #include <asm/irq.h> + +@@ -303,14 +304,14 @@ static void smc911x_reset(struct net_dev + SMC_SET_AFC_CFG(lp->afc_cfg); + + +- /* Set to LED outputs */ +- SMC_SET_GPIO_CFG(0x70070000); ++ /* Set to LED outputs and configure EEPROM pins as GP outputs */ ++ SMC_SET_GPIO_CFG(GPIO_CFG_LED1_EN_ | GPIO_CFG_LED2_EN_ | 1 << 20); + + /* +- * Deassert IRQ for 1*10us for edge type interrupts ++ * Deassert IRQ for 22*10us for edge type interrupts + * and drive IRQ pin push-pull + */ +- SMC_SET_IRQ_CFG( (1 << 24) | INT_CFG_IRQ_EN_ | INT_CFG_IRQ_TYPE_ ); ++ SMC_SET_IRQ_CFG( (22 << 24) | INT_CFG_IRQ_EN_ | INT_CFG_IRQ_TYPE_ ); + + /* clear anything saved */ + if (lp->pending_tx_skb != NULL) { +@@ -413,7 +414,7 @@ static inline void smc911x_drop_pkt(stru + if (fifo_count <= 4) { + /* Manually dump the packet data */ + while (fifo_count--) +- SMC_GET_RX_FIFO(); ++ (void)SMC_GET_RX_FIFO(); + } else { + /* Fast forward through the bad packet */ + SMC_SET_RX_DP_CTRL(RX_DP_CTRL_FFWD_BUSY_); +@@ -499,7 +500,7 @@ static inline void smc911x_rcv(struct n + SMC_SET_RX_CFG(RX_CFG_RX_END_ALGN4_ | ((2<<8) & RX_CFG_RXDOFF_)); + SMC_PULL_DATA(data, pkt_len+2+3); + +- DBG(SMC_DEBUG_PKTS, "%s: Received packet\n", dev->name,); ++ DBG(SMC_DEBUG_PKTS, "%s: Received packet\n", dev->name); + PRINT_PKT(data, ((pkt_len - 4) <= 64) ? pkt_len - 4 : 64); + dev->last_rx = jiffies; + skb->dev = dev; +@@ -900,6 +901,7 @@ static void smc911x_phy_powerdown(struct + unsigned long ioaddr = dev->base_addr; + unsigned int bmcr; + ++ DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__); + /* Enter Link Disable state */ + SMC_GET_PHY_BMCR(phy, bmcr); + bmcr |= BMCR_PDOWN; +@@ -925,6 +927,7 @@ static void smc911x_phy_check_media(stru + + if (mii_check_media(&lp->mii, netif_msg_link(lp), init)) { + /* duplex state has changed */ ++ DBG(SMC_DEBUG_MISC, "%s: duplex state has changed\n", dev->name); + SMC_GET_PHY_BMCR(phyaddr, bmcr); + SMC_GET_MAC_CR(cr); + if (lp->mii.full_duplex) { +@@ -960,6 +963,7 @@ static void smc911x_phy_configure(struct + int my_phy_caps; /* My PHY capabilities */ + int my_ad_caps; /* My Advertised capabilities */ + int status; ++ int bmcr; + unsigned long flags; + + DBG(SMC_DEBUG_FUNC, "%s: --> %s()\n", dev->name, __FUNCTION__); +@@ -1033,9 +1037,12 @@ static void smc911x_phy_configure(struct + + DBG(SMC_DEBUG_MISC, "%s: phy caps=0x%04x\n", dev->name, my_phy_caps); + DBG(SMC_DEBUG_MISC, "%s: phy advertised caps=0x%04x\n", dev->name, my_ad_caps); ++ DBG(SMC_DEBUG_MISC, "%s: phy advertised readback caps=0x%04x\n", dev->name, status); + + /* Restart auto-negotiation process in order to advertise my caps */ +- SMC_SET_PHY_BMCR(phyaddr, BMCR_ANENABLE | BMCR_ANRESTART); ++ SMC_GET_PHY_BMCR(phyaddr, bmcr); ++ bmcr |= BMCR_ANENABLE | BMCR_ANRESTART; ++ SMC_SET_PHY_BMCR(phyaddr, bmcr); + + smc911x_phy_check_media(dev, 1); + +@@ -1888,6 +1895,39 @@ static int __init smc911x_findirq(unsign + return probe_irq_off(cookie); + } + ++static inline unsigned int is_gumstix_oui(u8 *addr) ++{ ++ return (addr[0] == 0x00 && addr[1] == 0x15 && addr[2] == 0xC9); ++} ++ ++/** ++ * gen_serial_ether_addr - Generate software assigned Ethernet address ++ * based on the system_serial number ++ * @addr: Pointer to a six-byte array containing the Ethernet address ++ * ++ * Generate an Ethernet address (MAC) that is not multicast ++ * and has the local assigned bit set, keyed on the system_serial ++ */ ++static inline void gen_serial_ether_addr(u8 *addr) ++{ ++ static u8 ether_serial_digit = 0; ++ addr [0] = system_serial_high >> 8; ++ addr [1] = system_serial_high; ++ addr [2] = system_serial_low >> 24; ++ addr [3] = system_serial_low >> 16; ++ addr [4] = system_serial_low >> 8; ++ addr [5] = (system_serial_low & 0xc0) | /* top bits are from system serial */ ++ (1 << 4) | /* 2 bits identify interface type 1=ether, 2=usb, 3&4 undef */ ++ ((ether_serial_digit++) & 0x0f); /* 15 possible interfaces of each type */ ++ ++ if(!is_gumstix_oui(addr)) ++ { ++ addr [0] &= 0xfe; /* clear multicast bit */ ++ addr [0] |= 0x02; /* set local assignment bit (IEEE802) */ ++ } ++} ++ ++ + /* + * Function: smc911x_probe(unsigned long ioaddr) + * +@@ -2116,15 +2156,13 @@ static int __init smc911x_probe(struct n + #endif + printk("\n"); + if (!is_valid_ether_addr(dev->dev_addr)) { +- printk("%s: Invalid ethernet MAC address. Please " +- "set using ifconfig\n", dev->name); +- } else { +- /* Print the Ethernet address */ +- printk("%s: Ethernet addr: ", dev->name); +- for (i = 0; i < 5; i++) +- printk("%2.2x:", dev->dev_addr[i]); +- printk("%2.2x\n", dev->dev_addr[5]); ++ gen_serial_ether_addr(dev->dev_addr); + } ++ /* Print the Ethernet address */ ++ printk("%s: Ethernet addr: ", dev->name); ++ for (i = 0; i < 5; i++) ++ printk("%2.2x:", dev->dev_addr[i]); ++ printk("%2.2x\n", dev->dev_addr[5]); + + if (lp->phy_type == 0) { + PRINTK("%s: No PHY found\n", dev->name); +@@ -2300,8 +2338,15 @@ static struct platform_driver smc911x_dr + }, + }; + ++#ifdef CONFIG_ARCH_GUMSTIX ++extern void gumstix_smc911x_load(void); ++#endif ++ + static int __init smc911x_init(void) + { ++#ifdef CONFIG_ARCH_GUMSTIX ++ gumstix_smc911x_load(); ++#endif + return platform_driver_register(&smc911x_driver); + } + +Index: linux-2.6.21gum/drivers/net/gumstix-smc911x.c +=================================================================== +--- /dev/null ++++ linux-2.6.21gum/drivers/net/gumstix-smc911x.c +@@ -0,0 +1,148 @@ ++/* ++ * Gumstix SMC911x chip intialization driver ++ * ++ * Author: Craig Hughes ++ * Created: December 9, 2004 ++ * Copyright: (C) 2004 Craig Hughes ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ */ ++ ++#include <linux/module.h> ++#include <linux/ioport.h> ++#include <linux/device.h> ++#include <linux/platform_device.h> ++#include <linux/delay.h> ++ ++#include <asm/hardware.h> ++#include <asm/arch/pxa-regs.h> ++#include <asm/delay.h> ++ ++#include <asm/arch/gumstix.h> ++ ++#define SMC_DEBUG 9 ++#include <asm/io.h> ++#include "smc911x.h" ++ ++static struct resource gumstix_smc911x0_resources[] = { ++ [0] = { ++ .name = "smc911x-regs", ++ .start = PXA_CS1_PHYS, ++ .end = PXA_CS1_PHYS + 0x000fffff, ++ .flags = IORESOURCE_MEM, ++ }, ++ [1] = { ++ .start = GUMSTIX_ETH0_IRQ, ++ .end = GUMSTIX_ETH0_IRQ, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++static struct resource gumstix_smc911x1_resources[] = { ++ [0] = { ++ .name = "smc911x-regs", ++ .start = PXA_CS2_PHYS, ++ .end = PXA_CS2_PHYS + 0x000fffff, ++ .flags = IORESOURCE_MEM, ++ }, ++ [1] = { ++ .start = GUMSTIX_ETH1_IRQ, ++ .end = GUMSTIX_ETH1_IRQ, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++static struct platform_device gumstix_smc911x0_device = { ++ .name = "smc911x", ++ .id = 0, ++ .num_resources = ARRAY_SIZE(gumstix_smc911x0_resources), ++ .resource = gumstix_smc911x0_resources, ++}; ++ ++static struct platform_device gumstix_smc911x1_device = { ++ .name = "smc911x", ++ .id = 1, ++ .num_resources = ARRAY_SIZE(gumstix_smc911x1_resources), ++ .resource = gumstix_smc911x1_resources, ++}; ++ ++static struct platform_device *smc911x_devices[] = { ++ &gumstix_smc911x0_device, ++ &gumstix_smc911x1_device, ++}; ++ ++/* First we're going to test if there's a 2nd SMC911x, and if not, then we'll free up those resources and the GPIO lines ++ * that it would otherwise use. We have no choice but to probe by doing: ++ * Set nCS2 to CS2 mode ++ * Set the reset line to GPIO out mode, and pull it high, then drop it low (to trigger reset) ++ * Read from the memory space to check for the sentinel sequence identifying a likely SMC911x device ++ */ ++int __init gumstix_smc911x_init(void) ++{ ++ unsigned int val, num_devices=ARRAY_SIZE(smc911x_devices); ++ void *ioaddr; ++ ++ /* Set up nPWE */ ++ pxa_gpio_mode(GPIO49_nPWE_MD); ++ ++ pxa_gpio_mode(GPIO78_nCS_2_MD); ++ // If either if statement fails, then we'll drop out and turn_off_eth1, ++ // if both succeed, then we'll skip that and just proceed with 2 cards ++ if(request_mem_region(gumstix_smc911x1_resources[1].start, SMC911X_IO_EXTENT, "smc911x probe")) ++ { ++ ioaddr = ioremap(gumstix_smc911x1_resources[1].start, SMC911X_IO_EXTENT); ++ val = SMC_GET_PN(); ++ iounmap(ioaddr); ++ release_mem_region(gumstix_smc911x1_resources[1].start, SMC911X_IO_EXTENT); ++ if (CHIP_9115 == val || ++ CHIP_9116 == val || ++ CHIP_9117 == val || ++ CHIP_9118 == val ) { ++ goto proceed; ++ } ++ } ++ ++turn_off_eth1: ++ // This is apparently not an SMC911x ++ // So, let's decrement the number of devices to request, and reset the GPIO lines to GPIO IN mode ++ num_devices--; ++ smc911x_devices[1] = NULL; ++ pxa_gpio_mode(78 | GPIO_IN); ++ ++proceed: ++ pxa_gpio_mode(GPIO15_nCS_1_MD); ++ ++ if(smc911x_devices[1]) pxa_gpio_mode(GPIO_GUMSTIX_ETH1_RST_MD); ++ pxa_gpio_mode(GPIO_GUMSTIX_ETH0_RST_MD); ++ ++ if(smc911x_devices[1]) GPCR(GPIO_GUMSTIX_ETH1_RST) = GPIO_bit(GPIO_GUMSTIX_ETH1_RST); ++ GPCR(GPIO_GUMSTIX_ETH0_RST) = GPIO_bit(GPIO_GUMSTIX_ETH0_RST); ++ msleep(500); // Hold RESET for at least 200µ ++ ++ if(smc911x_devices[1]) GPSR(GPIO_GUMSTIX_ETH1_RST) = GPIO_bit(GPIO_GUMSTIX_ETH1_RST); ++ GPSR(GPIO_GUMSTIX_ETH0_RST) = GPIO_bit(GPIO_GUMSTIX_ETH0_RST); ++ msleep(50); ++ ++ return platform_add_devices(smc911x_devices, num_devices); ++} ++ ++void __exit gumstix_smc911x_exit(void) ++{ ++ if(smc911x_devices[1] != NULL) platform_device_unregister(&gumstix_smc911x1_device); ++ platform_device_unregister(&gumstix_smc911x0_device); ++} ++ ++void gumstix_smc911x_load(void) {} ++EXPORT_SYMBOL(gumstix_smc911x_load); ++ ++module_init(gumstix_smc911x_init); ++module_exit(gumstix_smc911x_exit); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Craig Hughes <craig@gumstix.com>"); ++MODULE_DESCRIPTION("Gumstix board SMC911x chip initialization driver"); ++MODULE_VERSION("1:0.1"); +Index: linux-2.6.21gum/drivers/net/Kconfig +=================================================================== +--- linux-2.6.21gum.orig/drivers/net/Kconfig ++++ linux-2.6.21gum/drivers/net/Kconfig +@@ -897,6 +897,13 @@ config SMC911X + called smc911x. If you want to compile it as a module, say M + here and read <file:Documentation/modules.txt> + ++config SMC911X_GUMSTIX ++ tristate ++ default m if SMC911X=m ++ default y if SMC911X=y ++ depends on SMC911X && ARCH_GUMSTIX ++ ++ + config NET_VENDOR_RACAL + bool "Racal-Interlan (Micom) NI cards" + depends on NET_ETHERNET && ISA +Index: linux-2.6.21gum/drivers/net/Makefile +=================================================================== +--- linux-2.6.21gum.orig/drivers/net/Makefile ++++ linux-2.6.21gum/drivers/net/Makefile +@@ -201,6 +201,7 @@ obj-$(CONFIG_PASEMI_MAC) += pasemi_mac.o + obj-$(CONFIG_MACB) += macb.o + + obj-$(CONFIG_SMC91X_GUMSTIX) += gumstix-smc91x.o ++obj-$(CONFIG_SMC911X_GUMSTIX) += gumstix-smc911x.o + obj-$(CONFIG_ARM) += arm/ + obj-$(CONFIG_DEV_APPLETALK) += appletalk/ + obj-$(CONFIG_TR) += tokenring/ +Index: linux-2.6.21gum/include/asm-arm/arch-pxa/gumstix.h +=================================================================== +--- linux-2.6.21gum.orig/include/asm-arm/arch-pxa/gumstix.h ++++ linux-2.6.21gum/include/asm-arm/arch-pxa/gumstix.h +@@ -52,7 +52,7 @@ + #define GPIO_GUMSTIX_ETH0_RST 80 + #define GPIO_GUMSTIX_ETH0 36 + #else +-#define GPIO_GUMSTIX_ETH0_RST 32 ++#define GPIO_GUMSTIX_ETH0_RST 107 + #define GPIO_GUMSTIX_ETH0 99 + #endif + #define GPIO_GUMSTIX_ETH1_RST 52 +Index: linux-2.6.21gum/drivers/net/smc911x.h +=================================================================== +--- linux-2.6.21gum.orig/drivers/net/smc911x.h ++++ linux-2.6.21gum/drivers/net/smc911x.h +@@ -33,7 +33,9 @@ + * Use the DMA feature on PXA chips + */ + #ifdef CONFIG_ARCH_PXA ++#ifndef CONFIG_SMC911X_GUMSTIX + #define SMC_USE_PXA_DMA 1 ++#endif + #define SMC_USE_16BIT 0 + #define SMC_USE_32BIT 1 + #endif +@@ -46,13 +48,13 @@ + #if SMC_USE_16BIT + #define SMC_inb(a, r) readb((a) + (r)) + #define SMC_inw(a, r) readw((a) + (r)) +-#define SMC_inl(a, r) ((SMC_inw(a, r) & 0xFFFF)+(SMC_inw(a+2, r)<<16)) ++#define SMC_inl(a, r) ((SMC_inw(a, r) & 0xFFFF)+(SMC_inw((a)+2, r)<<16)) + #define SMC_outb(v, a, r) writeb(v, (a) + (r)) + #define SMC_outw(v, a, r) writew(v, (a) + (r)) + #define SMC_outl(v, a, r) \ + do{ \ +- writel(v & 0xFFFF, (a) + (r)); \ +- writel(v >> 16, (a) + (r) + 2); \ ++ writel((v) & 0xFFFF, (a) + (r)); \ ++ writel((v) >> 16, (a) + (r) + 2); \ + } while (0) + #define SMC_insl(a, r, p, l) readsw((short*)((a) + (r)), p, l*2) + #define SMC_outsl(a, r, p, l) writesw((short*)((a) + (r)), p, l*2) diff --git a/packages/linux/linux-2.6.21/tsc2003-config.diff b/packages/linux/linux-2.6.21/tsc2003-config.diff new file mode 100644 index 0000000000..ccad5ed696 --- /dev/null +++ b/packages/linux/linux-2.6.21/tsc2003-config.diff @@ -0,0 +1,31 @@ +--- /tmp/Kconfig 2007-10-07 14:13:14.000000000 +0200 ++++ linux-2.6.21/drivers/i2c/chips/Kconfig 2007-10-07 14:13:56.902045000 +0200 +@@ -125,4 +125,18 @@ + This driver can also be built as a module. If so, the module + will be called max6875. + ++config SENSORS_TSC2003 ++ tristate "TI TSC2003" ++ depends on I2C && EXPERIMENTAL ++ default n ++ help ++ Driver for TI tsc2003 touchscreen and sensor chip/ ++ ++config SENSORS_TSC2003_SYSFS ++ tristate "TI TSC2003 sysfs interface ++ depends on SENSORS_TSC2003 ++ default n ++ help ++ Enabled the sysfs interface for tsc2003 ++ + endmenu +--- /tmp/Makefile 2007-10-07 14:14:14.000000000 +0200 ++++ linux-2.6.21/drivers/i2c/chips/Makefile 2007-10-07 14:14:20.072045000 +0200 +@@ -12,6 +12,7 @@ + obj-$(CONFIG_SENSORS_PCF8591) += pcf8591.o + obj-$(CONFIG_ISP1301_OMAP) += isp1301_omap.o + obj-$(CONFIG_TPS65010) += tps65010.o ++obj-$(CONFIG_SENSORS_TSC2003) += tsc2003.o + + ifeq ($(CONFIG_I2C_DEBUG_CHIP),y) + EXTRA_CFLAGS += -DDEBUG diff --git a/packages/linux/linux-2.6.21/tsc2003.c b/packages/linux/linux-2.6.21/tsc2003.c new file mode 100644 index 0000000000..8d7e5b3f78 --- /dev/null +++ b/packages/linux/linux-2.6.21/tsc2003.c @@ -0,0 +1,557 @@ +/* + * linux/drivers/i2c/chips/tsc2003.c + * + * Copyright (C) 2005 Bill Gatliff <bgat at billgatliff.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Driver for TI's TSC2003 I2C Touch Screen Controller + */ + +#include <linux/module.h> +#include <linux/init.h> +#include <linux/slab.h> +#include <linux/i2c.h> +#include <linux/string.h> +#include <linux/bcd.h> +#include <linux/list.h> +#include <linux/device.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/input.h> +#include <linux/platform_device.h> +#include <asm/delay.h> +#include <linux/delay.h> + +#include <asm/arch/gpio.h> + +#define DRIVER_NAME "tsc2003" + +enum tsc2003_pd { + PD_POWERDOWN = 0, /* penirq */ + PD_IREFOFF_ADCON = 1, /* no penirq */ + PD_IREFON_ADCOFF = 2, /* penirq */ + PD_IREFON_ADCON = 3, /* no penirq */ + PD_PENIRQ_ARM = PD_IREFON_ADCOFF, + PD_PENIRQ_DISARM = PD_IREFON_ADCON, +}; + +enum tsc2003_m { + M_12BIT = 0, + M_8BIT = 1 +}; + +enum tsc2003_cmd { + MEAS_TEMP0 = 0, + MEAS_VBAT1 = 1, + MEAS_IN1 = 2, + MEAS_TEMP1 = 4, + MEAS_VBAT2 = 5, + MEAS_IN2 = 6, + ACTIVATE_NX_DRIVERS = 8, + ACTIVATE_NY_DRIVERS = 9, + ACTIVATE_YNX_DRIVERS = 10, + MEAS_XPOS = 12, + MEAS_YPOS = 13, + MEAS_Z1POS = 14, + MEAS_Z2POS = 15 +}; + +#define TSC2003_CMD(cn,pdn,m) (((cn) << 4) | ((pdn) << 2) | ((m) << 1)) + +#define ADC_MAX ((1 << 12) - 1) + +struct tsc2003_data { + struct i2c_client *client; + struct input_dev *idev; + struct timer_list penirq_timer; + struct semaphore sem; + struct task_struct *tstask; + struct completion tstask_completion; + enum tsc2003_pd pd; + enum tsc2003_m m; + int vbat1; + int vbat2; + int temp0; + int temp1; + int in1; + int in2; +}; + +static int tsc2003_i2c_detect (struct i2c_adapter *adapter, int address, + int kind); + +static inline int tsc2003_command (struct tsc2003_data *data, + enum tsc2003_cmd cmd, + enum tsc2003_pd pd) +{ + char c; + int ret; + down(&data->sem); + c = TSC2003_CMD(cmd, pd, data->m); + ret = i2c_master_send(data->client, &c, 1); + up(&data->sem); + return ret; +} + +static int tsc2003_read (struct tsc2003_data *data, + enum tsc2003_cmd cmd, + enum tsc2003_pd pd, + int *val) +{ + char c; + char d[2]; + int ret; + + c = TSC2003_CMD(cmd, pd, data->m); + ret = i2c_master_send(data->client, &c, 1); + + udelay(20); + ret = i2c_master_recv(data->client, d, data->m == M_12BIT ? 2 : 1); + + if (val) + { + *val = d[0]; + *val <<= 4; + if (data->m == M_12BIT) + *val += (d[1] >> 4); + } + +#if defined(CONFIG_I2C_DEBUG_CHIP) + printk(KERN_ERR "%s: val[%x] = %d\n", + __FUNCTION__, cmd, (((int)d[0]) << 8) + d[1]); +#endif + + return 0; + if (!ret) ret = -ENODEV; + return ret; +} + +static inline int tsc2003_read_temp0 (struct tsc2003_data *d, enum + tsc2003_pd pd, int *t) +{ + return tsc2003_read(d, MEAS_TEMP0, pd, t); +} + +static inline int tsc2003_read_temp1 (struct tsc2003_data *d, enum + tsc2003_pd pd, int *t) +{ + return tsc2003_read(d, MEAS_TEMP1, pd, t); +} + +static inline int tsc2003_read_xpos (struct tsc2003_data *d, enum + tsc2003_pd pd, int *x) +{ + return tsc2003_read(d, MEAS_XPOS, pd, x); +} + +static inline int tsc2003_read_ypos (struct tsc2003_data *d, enum + tsc2003_pd pd, int *y) +{ + return tsc2003_read(d, MEAS_YPOS, pd, y); +} + +static inline int tsc2003_read_pressure (struct tsc2003_data *d, enum + tsc2003_pd pd, int *p) +{ + return tsc2003_read(d, MEAS_Z1POS, pd, p); +} + +static inline int tsc2003_read_in1 (struct tsc2003_data *d, enum + tsc2003_pd pd, int *t) +{ + return tsc2003_read(d, MEAS_IN1, pd, t); +} + +static inline int tsc2003_read_in2 (struct tsc2003_data *d, enum + tsc2003_pd pd, int *t) +{ + return tsc2003_read(d, MEAS_IN2, pd, t); +} + +static inline int tsc2003_read_vbat1 (struct tsc2003_data *d, enum + tsc2003_pd pd, int *t) +{ + return tsc2003_read(d, MEAS_VBAT1, pd, t); +} + +static inline int tsc2003_read_vbat2 (struct tsc2003_data *d, enum + tsc2003_pd pd, int *t) +{ + return tsc2003_read(d, MEAS_VBAT2, pd, t); +} + +static inline int tsc2003_powerdown (struct tsc2003_data *d) +{ + /* we don't have a distinct powerdown command, + so do a benign read with the PD bits cleared */ + return tsc2003_read(d, MEAS_IN1, PD_POWERDOWN, 0); +} + +void tsc2003_init_client (struct i2c_client *client) +{ + struct tsc2003_data *data = i2c_get_clientdata(client); + + data->pd = PD_PENIRQ_DISARM; + data->m = M_8BIT; + return; +} + +static int tsc2003ts_thread (void *v) +{ + struct tsc2003_data *d = v; + struct task_struct *tsk = current; + int pendown=0; + + d->tstask = tsk; + + daemonize(DRIVER_NAME "tsd"); + allow_signal(SIGKILL); + + complete(&d->tstask_completion); + + printk(KERN_INFO "%s: address 0x%x\n", + __FUNCTION__, d->client->addr); + + while (!signal_pending(tsk)) + { + unsigned int x, y, p; + + tsc2003_read_xpos(d, PD_PENIRQ_DISARM, &x); + tsc2003_read_ypos(d, PD_PENIRQ_DISARM, &y); + tsc2003_read_pressure(d, PD_PENIRQ_DISARM, &p); + + /* non-X-Y driver read to avoid glitch in penirq (errata?) */ + if (p > 100) { + pendown = 1; + input_report_abs(d->idev, ABS_X, x); + input_report_abs(d->idev, ABS_Y, y); + input_report_abs(d->idev, ABS_PRESSURE, p); + input_report_key(d->idev, BTN_TOUCH, 1); + input_sync(d->idev); + } else if (pendown == 1) { + pendown = 0; + input_report_key(d->idev, BTN_TOUCH, 0); + input_report_abs(d->idev, ABS_PRESSURE, 0); + input_sync(d->idev); + } + schedule_timeout_interruptible(msecs_to_jiffies(10)); + } + + d->tstask = NULL; + complete_and_exit(&d->tstask_completion, 0); +} + +static int tsc2003_idev_open (struct input_dev *idev) +{ + struct tsc2003_data *d = idev->private; + int ret = 0; + + if (down_interruptible(&d->sem)) + return -EINTR; + + if (d->tstask) + panic(DRIVER_NAME "tsd already running (!). abort."); + + init_completion(&d->tstask_completion); + + ret = kernel_thread(tsc2003ts_thread, d, CLONE_KERNEL); + if (ret >= 0) { + wait_for_completion(&d->tstask_completion); + ret = 0; + } + + up(&d->sem); + + return ret; +} + +static void tsc2003_idev_close (struct input_dev *idev) +{ + struct tsc2003_data *d = idev->private; + down_interruptible(&d->sem); + if (d->tstask) + { + send_sig(SIGKILL, d->tstask, 1); + wait_for_completion(&d->tstask_completion); + } + up(&d->sem); + return; +} + +#if defined(CONFIG_SYSFS) && defined(CONFIG_SENSORS_TSC2003_SYSFS) +static ssize_t show_addr (struct device *dev, char *buf) +{ + struct tsc2003_data *d = container_of(dev->driver, struct + tsc2003_data, driver); + return sprintf(buf, "%d\n", d->client.addr); +} +static DEVICE_ATTR(addr, S_IRUGO, show_addr, NULL); + +static ssize_t show_vbat1 (struct device *dev, char *buf) +{ + struct tsc2003_data *d = container_of(dev->driver, struct + tsc2003_data, driver); + return sprintf(buf, "%d\n", d->vbat1); +} +static DEVICE_ATTR(vbat1, S_IRUGO, show_vbat1, NULL); + +static ssize_t show_vbat2 (struct device *dev, char *buf) +{ + struct tsc2003_data *d = container_of(dev->driver, struct + tsc2003_data, driver); + return sprintf(buf, "%d\n", d->vbat2); +} +static DEVICE_ATTR(vbat2, S_IRUGO, show_vbat2, NULL); + +static ssize_t show_in1 (struct device *dev, char *buf) +{ + struct tsc2003_data *d = container_of(dev->driver, struct + tsc2003_data, driver); + return sprintf(buf, "%d\n", d->in1); +} +static DEVICE_ATTR(in1, S_IRUGO, show_in1, NULL); + +static ssize_t show_in2 (struct device *dev, char *buf) +{ + struct tsc2003_data *d = container_of(dev->driver, struct + tsc2003_data, driver); + return sprintf(buf, "%d\n", d->in2); +} +static DEVICE_ATTR(in2, S_IRUGO, show_in2, NULL); + +static ssize_t show_temp0 (struct device *dev, char *buf) +{ + struct tsc2003_data *d = container_of(dev->driver, struct + tsc2003_data, driver); + return sprintf(buf, "%d\n", d->temp0); +} +static DEVICE_ATTR(temp0, S_IRUGO, show_temp0, NULL); + +static ssize_t show_temp1 (struct device *dev, char *buf) +{ + struct tsc2003_data *d = container_of(dev->driver, struct + tsc2003_data, driver); + return sprintf(buf, "%d\n", d->temp1); +} +static DEVICE_ATTR(temp1, S_IRUGO, show_temp1, NULL); + +#warning "TODO: this daemon sometimes hangs the touchscreen daemon" +#warning "TODO: under periods of heavy touch screen activity." +#warning "TODO: Use with caution until the bug is squashed." +static int tsc2003s_thread (void *v) +{ + struct tsc2003_data *d = v; + + daemonize(DRIVER_NAME "sd"); + allow_signal(SIGKILL); + + printk(KERN_INFO "%s: address 0x%x\n", + __FUNCTION__, d->client.addr); + + while (!signal_pending(current)) + { + if (!down_interruptible(&d->sem)) + { + if (!timer_pending(&d->penirq_timer)) + { + tsc2003_read_vbat1(d, d->pd, &d->vbat1); + tsc2003_read_vbat2(d, d->pd, &d->vbat2); + tsc2003_read_in1(d, d->pd, &d->in1); + tsc2003_read_in2(d, d->pd, &d->in2); + tsc2003_read_temp0(d, d->pd, &d->temp0); + tsc2003_read_temp1(d, d->pd, &d->temp1); + } + up(&d->sem); + } + set_task_state(current, TASK_INTERRUPTIBLE); + schedule_timeout(5 * HZ); + } + do_exit(0); +} +#endif + +static int tsc2003_driver_register (struct tsc2003_data *data) +{ + int ret = 0; + + init_MUTEX(&data->sem); + + data->idev = input_allocate_device(); + if(!data->idev) + { + return -ENOMEM; + } + data->idev->private = data; + data->idev->name = DRIVER_NAME; + data->idev->evbit[0] = BIT(EV_ABS); + data->idev->open = tsc2003_idev_open; + data->idev->close = tsc2003_idev_close; + data->idev->absbit[LONG(ABS_X)] = BIT(ABS_X); + data->idev->absbit[LONG(ABS_Y)] = BIT(ABS_Y); + data->idev->absbit[LONG(ABS_PRESSURE)] = BIT(ABS_PRESSURE); + input_set_abs_params(data->idev, ABS_X, 0, ADC_MAX, 0, 0); + input_set_abs_params(data->idev, ABS_Y, 0, ADC_MAX, 0, 0); + + ret = input_register_device(data->idev); + if(ret) + { + input_free_device(data->idev); + return ret; + } + return ret; +} + +/* Magic definition of all other variables and things */ +static unsigned short normal_i2c[] = {0x48, 0x49, 0x4a, 0x48b, I2C_CLIENT_END }; + +I2C_CLIENT_INSMOD; + +static int tsc2003_i2c_attach_adapter(struct i2c_adapter *adapter) +{ + return i2c_probe(adapter, &addr_data, tsc2003_i2c_detect); +} + +static int tsc2003_i2c_detach_client(struct i2c_client *client) +{ + struct tsc2003_data *data=i2c_get_clientdata(client); + int err; + + input_unregister_device(data->idev); + + err = i2c_detach_client(client); + if (err) { + dev_err(&client->dev, "Client deregistration failed, " + "client not detached.\n"); + return err; + } + + return 0; +} + +static struct i2c_driver tsc2003_i2c_driver = { + .driver = { + .owner = THIS_MODULE, + .name = DRIVER_NAME, + }, + .attach_adapter = tsc2003_i2c_attach_adapter, + .detach_client = tsc2003_i2c_detach_client, + .command = NULL +}; + +static struct i2c_client client_template = { + .name = "TSC2003", + .driver = &tsc2003_i2c_driver, +}; + +static int tsc2003_i2c_detect (struct i2c_adapter *adap, int addr, + int kind) +{ + struct i2c_client *i2c; + int ret; + struct tsc2003_data *data; + + client_template.adapter = adap; + client_template.addr = addr; + + printk(KERN_INFO "tsc2003 i2c touch screen controller\n"); + printk(KERN_INFO "Bill Gatliff <bgat at billgatliff.com>\n"); + + i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL); + if (i2c == NULL){ + return -ENOMEM; + } + + data = kcalloc(1, sizeof(*data), GFP_KERNEL); + if (!data) { + ret = -ENOMEM; + goto err; + } + data->client = i2c; + i2c_set_clientdata(i2c, data); + + ret = i2c_attach_client(i2c); + + if (ret < 0) { + printk("failed to attach codec at addr %x\n", addr); + goto err; + } + + tsc2003_init_client(i2c); + + tsc2003_powerdown(data); + + ret = tsc2003_driver_register(data); + if(ret < 0) { + printk("driver_register failed\n"); + goto err; + } + + return ret; + +err: + kfree(i2c); + return ret; +} + +#define tsc2003_suspend NULL +#define tsc2003_resume NULL + +static int __devinit tsc2003_probe(struct platform_device *dev) +{ + int ret; + + ret=i2c_add_driver(&tsc2003_i2c_driver); + if(ret) + return ret; + +#if defined(CONFIG_SYSFS) && defined(CONFIG_SENSORS_TSC2003_SYSFS) + ret = kernel_thread(tsc2003s_thread, d, CLONE_KERNEL); + if (ret >= 0) + ret = 0; + + device_create_file(dev, &dev_attr_addr); + device_create_file(dev, &dev_attr_vbat1); + device_create_file(dev, &dev_attr_vbat2); + device_create_file(dev, &dev_attr_in1); + device_create_file(dev, &dev_attr_in2); + device_create_file(dev, &dev_attr_temp0); + device_create_file(dev, &dev_attr_temp1); +#endif + return 0; +} + +static int __devexit tsc2003_remove(struct platform_device *dev) +{ + i2c_del_driver(&tsc2003_i2c_driver); + return 0; +} + +static struct platform_driver tsc2003_driver = { + .probe = tsc2003_probe, + .remove = __devexit_p(tsc2003_remove), + .suspend = tsc2003_suspend, + .resume = tsc2003_resume, + .driver = { + .name = "tsc2003", + }, +}; + +static int __init tsc2003_init(void) +{ + return platform_driver_register(&tsc2003_driver); +} + +static void __exit tsc2003_exit(void) +{ + platform_driver_unregister(&tsc2003_driver); +} + +MODULE_AUTHOR("Bill Gatliff <bgat at billgatliff.com>"); +MODULE_DESCRIPTION("TSC2003 Touch Screen Controller driver"); +MODULE_LICENSE("GPL"); + +module_init(tsc2003_init); +module_exit(tsc2003_exit); diff --git a/packages/linux/linux-efika-2.6.20.11/.mtn2git_empty b/packages/linux/linux-2.6.22/.mtn2git_empty index e69de29bb2..e69de29bb2 100644 --- a/packages/linux/linux-efika-2.6.20.11/.mtn2git_empty +++ b/packages/linux/linux-2.6.22/.mtn2git_empty diff --git a/packages/linux/linux-2.6.22/bd-neon/.mtn2git_empty b/packages/linux/linux-2.6.22/bd-neon/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/packages/linux/linux-2.6.22/bd-neon/.mtn2git_empty diff --git a/packages/linux/linux-2.6.22/bd-neon/defconfig b/packages/linux/linux-2.6.22/bd-neon/defconfig new file mode 100644 index 0000000000..9bd82a5e2d --- /dev/null +++ b/packages/linux/linux-2.6.22/bd-neon/defconfig @@ -0,0 +1,1326 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.19.2 +# Thu May 24 16:14:49 2007 +# +CONFIG_ARM=y +# CONFIG_GENERIC_TIME is not set +CONFIG_MMU=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_ARCH_MTD_XIP=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +# CONFIG_SWAP is not set +# CONFIG_SYSVIPC is not set +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_UTS_NS is not set +# CONFIG_AUDIT is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +# CONFIG_RELAY is not set +CONFIG_INITRAMFS_SOURCE="" +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=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_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SHMEM=y +CONFIG_SLAB=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +# CONFIG_SLOB is not set + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y + +# +# Block layer +# +CONFIG_BLOCK=y +# CONFIG_BLK_DEV_IO_TRACE is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" + +# +# 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_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PNX4008 is not set +CONFIG_ARCH_PXA=y +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set + +# +# Intel PXA2xx Implementations +# +# CONFIG_ARCH_LUBBOCK is not set +# CONFIG_MACH_LOGICPD_PXA270 is not set +# CONFIG_MACH_MAINSTONE is not set +# CONFIG_MACH_ARGON is not set +CONFIG_MACH_NEON=y +# CONFIG_ARCH_PXA_IDP is not set +# CONFIG_PXA_SHARPSL is not set +# CONFIG_MACH_TRIZEPS4 is not set +CONFIG_PXA25x=y + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_XSCALE=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5T=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +# CONFIG_ARM_THUMB is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +CONFIG_XSCALE_PMU=y + +# +# Bus support +# + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +# CONFIG_PREEMPT is not set +# CONFIG_NO_IDLE_HZ is not set +CONFIG_HZ=100 +CONFIG_AEABI=y +CONFIG_OABI_COMPAT=y +# CONFIG_ARCH_DISCONTIGMEM_ENABLE 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_SPARSEMEM_STATIC is not set +CONFIG_SPLIT_PTLOCK_CPUS=4096 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="" +# CONFIG_XIP_KERNEL is not set + +# +# 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 + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +# CONFIG_PM is not set +# CONFIG_APM is not set + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_NETDEBUG is not set +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# 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 is not set +# 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 is not set +# 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=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set + +# +# DCCP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set + +# +# TIPC Configuration (EXPERIMENTAL) +# +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE 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 + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_IEEE80211=y +CONFIG_IEEE80211_DEBUG=y +CONFIG_IEEE80211_CRYPT_WEP=y +CONFIG_IEEE80211_CRYPT_CCMP=y +CONFIG_IEEE80211_CRYPT_TKIP=y +CONFIG_IEEE80211_SOFTMAC=y +CONFIG_IEEE80211_SOFTMAC_DEBUG=y +CONFIG_WIRELESS_EXT=y + +# +# Device Drivers +# + +# +# Generic Driver Options +# +# CONFIG_STANDALONE is not set +# CONFIG_PREVENT_FIRMWARE_BUILD is not set +CONFIG_FW_LOADER=y +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_SYS_HYPERVISOR is not set + +# +# Connector - unified userspace <-> kernelspace linker +# +CONFIG_CONNECTOR=y +# CONFIG_PROC_EVENTS is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +# CONFIG_MTD_BLOCK is not set +CONFIG_MTD_BLOCK_RO=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 + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS 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_CFI_INTELEXT=y +CONFIG_MTD_CFI_AMDSTD=y +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set +# CONFIG_MTD_XIP is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_START=0x0 +CONFIG_MTD_PHYSMAP_LEN=0x2000000 +CONFIG_MTD_PHYSMAP_BANKWIDTH=4 +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_SHARP_SL 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 + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# OneNAND Flash Device Drivers +# +# CONFIG_MTD_ONENAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +CONFIG_BLK_DEV_INITRD=y +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set + +# +# SCSI low-level drivers +# +# CONFIG_ISCSI_TCP is not set +# CONFIG_SCSI_DEBUG is not set + +# +# Serial ATA (prod) and Parallel ATA (experimental) drivers +# +# CONFIG_ATA is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# Network device support +# +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# PHY device support +# +# CONFIG_PHYLIB is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +CONFIG_SMC91X=y +# CONFIG_DM9000 is not set +# CONFIG_SMC911X is not set + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# + +# +# Wireless LAN (non-hamradio) +# +CONFIG_NET_RADIO=y +CONFIG_NET_WIRELESS_RTNETLINK=y + +# +# Obsolete Wireless cards support (pre-802.11) +# +# CONFIG_STRIP is not set +# CONFIG_USB_ZD1201 is not set +# CONFIG_HOSTAP is not set +CONFIG_ZD1211RW=m +# CONFIG_ZD1211RW_DEBUG is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +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_TSDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# 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_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_VSXXXAA is not set +CONFIG_INPUT_JOYSTICK=y +# CONFIG_JOYSTICK_ANALOG is not set +# CONFIG_JOYSTICK_A3D is not set +# CONFIG_JOYSTICK_ADI is not set +# CONFIG_JOYSTICK_COBRA is not set +# CONFIG_JOYSTICK_GF2K is not set +# CONFIG_JOYSTICK_GRIP is not set +# CONFIG_JOYSTICK_GRIP_MP is not set +# CONFIG_JOYSTICK_GUILLEMOT is not set +# CONFIG_JOYSTICK_INTERACT is not set +# CONFIG_JOYSTICK_SIDEWINDER is not set +# CONFIG_JOYSTICK_TMDC is not set +# CONFIG_JOYSTICK_IFORCE is not set +# CONFIG_JOYSTICK_WARRIOR is not set +# CONFIG_JOYSTICK_MAGELLAN is not set +# CONFIG_JOYSTICK_SPACEORB is not set +# CONFIG_JOYSTICK_SPACEBALL is not set +# CONFIG_JOYSTICK_STINGER is not set +# CONFIG_JOYSTICK_TWIDJOY is not set +# CONFIG_JOYSTICK_JOYDUMP is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +# CONFIG_SERIO_SERPORT is not set +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +CONFIG_PXA_GPIO=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_PXA=y +CONFIG_SERIAL_PXA_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +CONFIG_WATCHDOG_NOWAYOUT=y + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_SA1100_WATCHDOG=y +# CONFIG_SA1100_WATCHDOG_TICK is not set + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set +CONFIG_HW_RANDOM=y +# CONFIG_NVRAM is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set + +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + +# +# Hardware Monitoring support +# +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_ABITUGURU is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_VT1211 is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Misc devices +# +CONFIG_BD_GENTIMER=y +# CONFIG_TIFM_CORE is not set + +# +# LED devices +# +# CONFIG_NEW_LEDS is not set + +# +# LED drivers +# + +# +# LED Triggers +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set +# CONFIG_USB_DABUSB is not set + +# +# Graphics support +# +CONFIG_FIRMWARE_EDID=y +CONFIG_FB=y +# CONFIG_FB_CFB_FILLRECT is not set +# CONFIG_FB_CFB_COPYAREA is not set +# CONFIG_FB_CFB_IMAGEBLIT is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_PXA is not set +# CONFIG_FB_MBX is not set +CONFIG_FB_SM501=y +CONFIG_FB_SM501MEM=y +CONFIG_FB_SM501YUV=y +CONFIG_FB_SM501ALPHA=y +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +CONFIG_FONTS=y +# CONFIG_FONT_8x8 is not set +CONFIG_FONT_8x16=y +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_7x14 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set +# CONFIG_FONT_MINI_4x6 is not set +# CONFIG_FONT_SUN8x16 is not set +# CONFIG_FONT_SUN12x22 is not set +# CONFIG_FONT_10x18 is not set + +# +# Logo configuration +# +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_LOGO_LINUX_CLUT224=y +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Sound +# +CONFIG_SOUND=y + +# +# Advanced Linux Sound Architecture +# +CONFIG_SND=y +CONFIG_SND_TIMER=y +CONFIG_SND_PCM=y +# CONFIG_SND_SEQUENCER is not set +CONFIG_SND_OSSEMUL=y +CONFIG_SND_MIXER_OSS=y +CONFIG_SND_PCM_OSS=y +CONFIG_SND_PCM_OSS_PLUGINS=y +# CONFIG_SND_DYNAMIC_MINORS is not set +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_VERBOSE_PROCFS=y +CONFIG_SND_VERBOSE_PRINTK=y +CONFIG_SND_DEBUG=y +# CONFIG_SND_DEBUG_DETECT is not set +# CONFIG_SND_PCM_XRUN_DEBUG is not set + +# +# Generic devices +# +CONFIG_SND_AC97_CODEC=y +CONFIG_SND_AC97_BUS=y +# CONFIG_SND_DUMMY is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set + +# +# ALSA ARM devices +# +CONFIG_SND_PXA2XX_PCM=y +CONFIG_SND_PXA2XX_AC97=y + +# +# USB devices +# +# CONFIG_SND_USB_AUDIO is not set + +# +# Open Sound System +# +# CONFIG_SOUND_PRIME is not set + +# +# Multimedia Capabilities Port drivers +# +CONFIG_UCB1400_TS=y +# CONFIG_UCB1400_TS_FIVE_WIRE is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB_ARCH_HAS_EHCI is not set +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_BANDWIDTH is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_ISP116X_HCD is not set +CONFIG_USB_OHCI_SM501=y +# CONFIG_USB_SL811_HCD is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +CONFIG_USB_PRINTER=y + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# may also be needed; see USB_STORAGE Help for more information +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_ONETOUCH is not set +# CONFIG_USB_STORAGE_KARMA is not set +CONFIG_USB_LIBUSUAL=y + +# +# USB Input Devices +# +CONFIG_USB_HID=y +CONFIG_USB_HIDINPUT=y +# CONFIG_USB_HIDINPUT_POWERBOOK is not set +# CONFIG_HID_FF is not set +CONFIG_USB_HIDDEV=y +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_ACECAD is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set +# CONFIG_USB_TOUCHSCREEN is not set +# CONFIG_USB_YEALINK is not set +# CONFIG_USB_XPAD is not set +# CONFIG_USB_ATI_REMOTE is not set +# CONFIG_USB_ATI_REMOTE2 is not set +# CONFIG_USB_KEYSPAN_REMOTE is not set +# CONFIG_USB_APPLETOUCH is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +CONFIG_USB_PEGASUS=y +CONFIG_USB_RTL8150=y +# CONFIG_USB_USBNET_MII is not set +# CONFIG_USB_USBNET is not set +# CONFIG_USB_MON is not set + +# +# USB port drivers +# + +# +# USB Serial Converter support +# +CONFIG_USB_SERIAL=m +CONFIG_USB_SERIAL_GENERIC=y +# CONFIG_USB_SERIAL_AIRCABLE is not set +# CONFIG_USB_SERIAL_AIRPRIME is not set +# CONFIG_USB_SERIAL_ARK3116 is not set +# CONFIG_USB_SERIAL_BELKIN is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +# CONFIG_USB_SERIAL_CP2101 is not set +# CONFIG_USB_SERIAL_CYPRESS_M8 is not set +# CONFIG_USB_SERIAL_EMPEG is not set +# CONFIG_USB_SERIAL_FTDI_SIO is not set +# CONFIG_USB_SERIAL_FUNSOFT is not set +# CONFIG_USB_SERIAL_VISOR is not set +# CONFIG_USB_SERIAL_IPAQ is not set +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_EDGEPORT is not set +# CONFIG_USB_SERIAL_EDGEPORT_TI is not set +# CONFIG_USB_SERIAL_GARMIN is not set +# CONFIG_USB_SERIAL_IPW is not set +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +CONFIG_USB_SERIAL_KEYSPAN=m +# CONFIG_USB_SERIAL_KEYSPAN_MPR is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set +CONFIG_USB_SERIAL_KEYSPAN_USA19=y +# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19QW is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19QI is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA49WLC is not set +# CONFIG_USB_SERIAL_KLSI is not set +# CONFIG_USB_SERIAL_KOBIL_SCT is not set +# CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_MOS7720 is not set +# CONFIG_USB_SERIAL_MOS7840 is not set +# CONFIG_USB_SERIAL_NAVMAN is not set +# CONFIG_USB_SERIAL_PL2303 is not set +# CONFIG_USB_SERIAL_HP4X is not set +# CONFIG_USB_SERIAL_SAFE is not set +# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set +# CONFIG_USB_SERIAL_TI is not set +# CONFIG_USB_SERIAL_CYBERJACK is not set +# CONFIG_USB_SERIAL_XIRCOM is not set +# CONFIG_USB_SERIAL_OPTION is not set +# CONFIG_USB_SERIAL_OMNINET is not set +CONFIG_USB_EZUSB=y +CONFIG_AT91SAM7X=m +CONFIG_AT91SAM7X_SERIAL=m +CONFIG_AT91SAM7X_FLASH=m +CONFIG_AT91SAM7X_FRAM=m +CONFIG_AT91SAM7X_ETHER=m + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGET is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_TEST is not set + +# +# USB DSL modem support +# + +# +# USB Gadget Support +# +CONFIG_USB_GADGET=y +# CONFIG_USB_GADGET_DEBUG_FILES is not set +CONFIG_USB_GADGET_SELECTED=y +# CONFIG_USB_GADGET_NET2280 is not set +CONFIG_USB_GADGET_PXA2XX=y +CONFIG_USB_PXA2XX=y +CONFIG_USB_PXA2XX_SMALL=y +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_DUMMY_HCD is not set +# CONFIG_USB_GADGET_DUALSPEED is not set +# CONFIG_USB_ZERO is not set +# CONFIG_USB_ETH is not set +# CONFIG_USB_GADGETFS is not set +# CONFIG_USB_FILE_STORAGE is not set +CONFIG_USB_G_SERIAL=y +# CONFIG_USB_MIDI_GADGET is not set + +# +# MMC/SD Card support +# +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +CONFIG_MMC_BLOCK=y +CONFIG_MMC_PXA=y +# CONFIG_MMC_TIFM_SD is not set + +# +# Real Time Clock +# +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS 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=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +# CONFIG_EXT4DEV_FS is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# 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_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +CONFIG_JFFS2_SUMMARY=y +CONFIG_CRAMFS=y +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# 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 +# CONFIG_9P_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# 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 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=y +# 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 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +CONFIG_NLS_UTF8=y + +# +# Profiling support +# +CONFIG_PROFILING=y +CONFIG_OPROFILE=y + +# +# Kernel hacking +# +CONFIG_PRINTK_TIME=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_KERNEL=y +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +CONFIG_DEBUG_SPINLOCK=y +CONFIG_DEBUG_MUTEXES=y +CONFIG_DEBUG_RWSEMS=y +CONFIG_DEBUG_SPINLOCK_SLEEP=y +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_FS is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_LIST is not set +CONFIG_FRAME_POINTER=y +CONFIG_FORCED_INLINING=y +# CONFIG_HEADERS_CHECK is not set +# CONFIG_RCU_TORTURE_TEST is not set +CONFIG_DEBUG_USER=y +CONFIG_DEBUG_WAITQ=y +CONFIG_DEBUG_ERRORS=y +CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_ICEDCC is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +CONFIG_CRYPTO=y +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_MANAGER=y +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_MD4 is not set +# CONFIG_CRYPTO_MD5 is not set +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set +CONFIG_CRYPTO_ECB=y +# CONFIG_CRYPTO_CBC is not set +# CONFIG_CRYPTO_DES is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_SERPENT is not set +CONFIG_CRYPTO_AES=y +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_TEA is not set +CONFIG_CRYPTO_ARC4=y +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_DEFLATE is not set +CONFIG_CRYPTO_MICHAEL_MIC=y +CONFIG_CRYPTO_CRC32C=y +# CONFIG_CRYPTO_TEST is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +CONFIG_CRC32=y +CONFIG_LIBCRC32C=y +CONFIG_ZLIB_INFLATE=y +CONFIG_PLIST=y diff --git a/packages/linux/linux-2.6.22/cm-x270/.mtn2git_empty b/packages/linux/linux-2.6.22/cm-x270/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/packages/linux/linux-2.6.22/cm-x270/.mtn2git_empty diff --git a/packages/linux/compulab-pxa270-2.6.22/0001-cm-x270-base2.patch b/packages/linux/linux-2.6.22/cm-x270/0001-cm-x270-base2.patch index 9a635c5cbc..9a635c5cbc 100644 --- a/packages/linux/compulab-pxa270-2.6.22/0001-cm-x270-base2.patch +++ b/packages/linux/linux-2.6.22/cm-x270/0001-cm-x270-base2.patch diff --git a/packages/linux/compulab-pxa270-2.6.22/0002-cm-x270-match-type.patch b/packages/linux/linux-2.6.22/cm-x270/0002-cm-x270-match-type.patch index 68da30191c..68da30191c 100644 --- a/packages/linux/compulab-pxa270-2.6.22/0002-cm-x270-match-type.patch +++ b/packages/linux/linux-2.6.22/cm-x270/0002-cm-x270-match-type.patch diff --git a/packages/linux/compulab-pxa270-2.6.22/0003-cm-x270-ide.patch b/packages/linux/linux-2.6.22/cm-x270/0003-cm-x270-ide.patch index 0ff115efc8..0ff115efc8 100644 --- a/packages/linux/compulab-pxa270-2.6.22/0003-cm-x270-ide.patch +++ b/packages/linux/linux-2.6.22/cm-x270/0003-cm-x270-ide.patch diff --git a/packages/linux/compulab-pxa270-2.6.22/0004-cm-x270-it8152.patch b/packages/linux/linux-2.6.22/cm-x270/0004-cm-x270-it8152.patch index 274eaf24d8..274eaf24d8 100644 --- a/packages/linux/compulab-pxa270-2.6.22/0004-cm-x270-it8152.patch +++ b/packages/linux/linux-2.6.22/cm-x270/0004-cm-x270-it8152.patch diff --git a/packages/linux/compulab-pxa270-2.6.22/0005-cm-x270-pcmcia.patch b/packages/linux/linux-2.6.22/cm-x270/0005-cm-x270-pcmcia.patch index 7dceff5c9d..7dceff5c9d 100644 --- a/packages/linux/compulab-pxa270-2.6.22/0005-cm-x270-pcmcia.patch +++ b/packages/linux/linux-2.6.22/cm-x270/0005-cm-x270-pcmcia.patch diff --git a/packages/linux/compulab-pxa270-2.6.22/0006-ramdisk_load.patch b/packages/linux/linux-2.6.22/cm-x270/0006-ramdisk_load.patch index aa25dd9bfc..aa25dd9bfc 100644 --- a/packages/linux/compulab-pxa270-2.6.22/0006-ramdisk_load.patch +++ b/packages/linux/linux-2.6.22/cm-x270/0006-ramdisk_load.patch diff --git a/packages/linux/compulab-pxa270-2.6.22/0007-mmcsd_large_cards-r0.patch b/packages/linux/linux-2.6.22/cm-x270/0007-mmcsd_large_cards-r0.patch index 90e66b5308..90e66b5308 100644 --- a/packages/linux/compulab-pxa270-2.6.22/0007-mmcsd_large_cards-r0.patch +++ b/packages/linux/linux-2.6.22/cm-x270/0007-mmcsd_large_cards-r0.patch diff --git a/packages/linux/compulab-pxa270-2.6.22/0008-cm-x270-nand-simplify-name.patch b/packages/linux/linux-2.6.22/cm-x270/0008-cm-x270-nand-simplify-name.patch index c07f049e56..c07f049e56 100644 --- a/packages/linux/compulab-pxa270-2.6.22/0008-cm-x270-nand-simplify-name.patch +++ b/packages/linux/linux-2.6.22/cm-x270/0008-cm-x270-nand-simplify-name.patch diff --git a/packages/linux/compulab-pxa270-2.6.22/0009-cursor-fix.patch b/packages/linux/linux-2.6.22/cm-x270/0009-cursor-fix.patch index 08b0db36b0..08b0db36b0 100644 --- a/packages/linux/compulab-pxa270-2.6.22/0009-cursor-fix.patch +++ b/packages/linux/linux-2.6.22/cm-x270/0009-cursor-fix.patch diff --git a/packages/linux/compulab-pxa270-2.6.22/defconfig b/packages/linux/linux-2.6.22/cm-x270/defconfig index 63bc69533f..63bc69533f 100644 --- a/packages/linux/compulab-pxa270-2.6.22/defconfig +++ b/packages/linux/linux-2.6.22/cm-x270/defconfig diff --git a/packages/linux/linux-2.6.23/.mtn2git_empty b/packages/linux/linux-2.6.23/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/packages/linux/linux-2.6.23/.mtn2git_empty diff --git a/packages/linux/linux-2.6.23/binutils-buildid-arm.patch b/packages/linux/linux-2.6.23/binutils-buildid-arm.patch new file mode 100644 index 0000000000..68e35e89e1 --- /dev/null +++ b/packages/linux/linux-2.6.23/binutils-buildid-arm.patch @@ -0,0 +1,16 @@ +--- + arch/arm/kernel/vmlinux.lds.S | 1 + + 1 file changed, 1 insertion(+) + +Index: linux-2.6.22/arch/arm/kernel/vmlinux.lds.S +=================================================================== +--- linux-2.6.22.orig/arch/arm/kernel/vmlinux.lds.S 2007-09-11 18:32:29.000000000 +0200 ++++ linux-2.6.22/arch/arm/kernel/vmlinux.lds.S 2007-09-11 18:33:42.000000000 +0200 +@@ -94,6 +94,7 @@ + TEXT_TEXT + SCHED_TEXT + LOCK_TEXT ++ *(.note.*) + #ifdef CONFIG_MMU + *(.fixup) + #endif diff --git a/packages/linux/linux-2.6.23/cm-x270/.mtn2git_empty b/packages/linux/linux-2.6.23/cm-x270/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/packages/linux/linux-2.6.23/cm-x270/.mtn2git_empty diff --git a/packages/linux/linux-2.6.23/cm-x270/0001-cm-x270-base2.patch b/packages/linux/linux-2.6.23/cm-x270/0001-cm-x270-base2.patch new file mode 100644 index 0000000000..dc68ce9d43 --- /dev/null +++ b/packages/linux/linux-2.6.23/cm-x270/0001-cm-x270-base2.patch @@ -0,0 +1,2851 @@ +From 299199b0cf17d0247a58af6ccd6cf6b859c60e9a Mon Sep 17 00:00:00 2001 +From: Cliff Brake <cbrake@happy.dev.bec-systems.com> +Date: Fri, 20 Jul 2007 18:55:59 -0400 +Subject: [PATCH] cm-x270-base2 + +--- + arch/arm/Kconfig | 8 +- + arch/arm/configs/cm_x270_defconfig | 1567 +++++++++++++++++++++++++++++++++++ + arch/arm/mach-pxa/Kconfig | 6 + + arch/arm/mach-pxa/Makefile | 7 + + arch/arm/mach-pxa/cm-x270.c | 821 ++++++++++++++++++ + drivers/leds/Kconfig | 6 + + drivers/leds/Makefile | 1 + + drivers/leds/leds-cm-x270.c | 126 +++ + drivers/net/Kconfig | 8 + + drivers/net/dm9000.c | 6 + + include/asm-arm/arch-pxa/cm-x270.h | 71 ++ + include/asm-arm/arch-pxa/hardware.h | 11 + + include/asm-arm/arch-pxa/irqs.h | 20 + + include/asm-arm/memory.h | 10 + + 14 files changed, 2667 insertions(+), 1 deletions(-) + create mode 100644 arch/arm/configs/cm_x270_defconfig + create mode 100644 arch/arm/mach-pxa/cm-x270.c + create mode 100644 drivers/leds/leds-cm-x270.c + create mode 100644 include/asm-arm/arch-pxa/cm-x270.h + +diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig +index 691aae3..b9a2b11 100644 +--- a/arch/arm/Kconfig ++++ b/arch/arm/Kconfig +@@ -534,7 +534,7 @@ config ISA_DMA_API + bool + + config PCI +- bool "PCI support" if ARCH_INTEGRATOR_AP || ARCH_VERSATILE_PB || ARCH_IXP4XX || ARCH_KS8695 ++ bool "PCI support" if ARCH_INTEGRATOR_AP || ARCH_VERSATILE_PB || ARCH_IXP4XX || ARCH_KS8695 || MACH_ARMCORE + help + Find out whether you have a PCI motherboard. PCI is the name of a + bus system, i.e. the way the CPU talks to the other stuff inside +@@ -555,6 +555,12 @@ config PCI_HOST_VIA82C505 + depends on PCI && ARCH_SHARK + default y + ++config PCI_HOST_ITE8152 ++ bool ++ depends on PCI && MACH_ARMCORE ++ default y ++ select DMABOUNCE ++ + source "drivers/pci/Kconfig" + + source "drivers/pcmcia/Kconfig" +diff --git a/arch/arm/configs/cm_x270_defconfig b/arch/arm/configs/cm_x270_defconfig +new file mode 100644 +index 0000000..f728363 +--- /dev/null ++++ b/arch/arm/configs/cm_x270_defconfig +@@ -0,0 +1,1567 @@ ++# ++# Automatically generated make config: don't edit ++# Linux kernel version: 2.6.21-rc4 ++# Wed Apr 4 16:42:03 2007 ++# ++CONFIG_ARM=y ++CONFIG_SYS_SUPPORTS_APM_EMULATION=y ++CONFIG_GENERIC_GPIO=y ++CONFIG_GENERIC_TIME=y ++CONFIG_MMU=y ++# CONFIG_NO_IOPORT is not set ++CONFIG_GENERIC_HARDIRQS=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_ZONE_DMA=y ++CONFIG_ARCH_MTD_XIP=y ++CONFIG_VECTORS_BASE=0xffff0000 ++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" ++ ++# ++# Code maturity level options ++# ++CONFIG_EXPERIMENTAL=y ++CONFIG_BROKEN_ON_SMP=y ++CONFIG_INIT_ENV_ARG_LIMIT=32 ++ ++# ++# General setup ++# ++CONFIG_LOCALVERSION="" ++# CONFIG_LOCALVERSION_AUTO is not set ++CONFIG_SWAP=y ++CONFIG_SYSVIPC=y ++# CONFIG_IPC_NS is not set ++CONFIG_SYSVIPC_SYSCTL=y ++# CONFIG_POSIX_MQUEUE is not set ++# CONFIG_BSD_PROCESS_ACCT is not set ++# CONFIG_TASKSTATS is not set ++# CONFIG_UTS_NS is not set ++# CONFIG_AUDIT is not set ++CONFIG_IKCONFIG=y ++CONFIG_IKCONFIG_PROC=y ++CONFIG_SYSFS_DEPRECATED=y ++# CONFIG_RELAY is not set ++CONFIG_BLK_DEV_INITRD=y ++CONFIG_INITRAMFS_SOURCE="" ++CONFIG_CC_OPTIMIZE_FOR_SIZE=y ++CONFIG_SYSCTL=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_HOTPLUG=y ++CONFIG_PRINTK=y ++CONFIG_BUG=y ++CONFIG_ELF_CORE=y ++CONFIG_BASE_FULL=y ++CONFIG_FUTEX=y ++CONFIG_EPOLL=y ++CONFIG_SHMEM=y ++CONFIG_SLAB=y ++CONFIG_VM_EVENT_COUNTERS=y ++CONFIG_RT_MUTEXES=y ++# CONFIG_TINY_SHMEM is not set ++CONFIG_BASE_SMALL=0 ++# CONFIG_SLOB is not set ++ ++# ++# Loadable module support ++# ++CONFIG_MODULES=y ++CONFIG_MODULE_UNLOAD=y ++CONFIG_MODULE_FORCE_UNLOAD=y ++# CONFIG_MODVERSIONS is not set ++# CONFIG_MODULE_SRCVERSION_ALL is not set ++CONFIG_KMOD=y ++ ++# ++# Block layer ++# ++CONFIG_BLOCK=y ++# CONFIG_LBD is not set ++# CONFIG_BLK_DEV_IO_TRACE is not set ++# CONFIG_LSF 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" ++ ++# ++# 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_CLPS7500 is not set ++# CONFIG_ARCH_CLPS711X is not set ++# CONFIG_ARCH_CO285 is not set ++# CONFIG_ARCH_EBSA110 is not set ++# CONFIG_ARCH_EP93XX is not set ++# CONFIG_ARCH_FOOTBRIDGE is not set ++# CONFIG_ARCH_NETX is not set ++# CONFIG_ARCH_H720X is not set ++# CONFIG_ARCH_IMX is not set ++# CONFIG_ARCH_IOP32X is not set ++# CONFIG_ARCH_IOP33X is not set ++# CONFIG_ARCH_IOP13XX is not set ++# CONFIG_ARCH_IXP4XX is not set ++# CONFIG_ARCH_IXP2000 is not set ++# CONFIG_ARCH_IXP23XX is not set ++# CONFIG_ARCH_L7200 is not set ++# CONFIG_ARCH_NS9XXX is not set ++# CONFIG_ARCH_PNX4008 is not set ++CONFIG_ARCH_PXA=y ++# CONFIG_ARCH_RPC is not set ++# CONFIG_ARCH_SA1100 is not set ++# CONFIG_ARCH_S3C2410 is not set ++# CONFIG_ARCH_SHARK is not set ++# CONFIG_ARCH_LH7A40X is not set ++# CONFIG_ARCH_OMAP is not set ++CONFIG_DMABOUNCE=y ++ ++# ++# Intel PXA2xx Implementations ++# ++# CONFIG_ARCH_LUBBOCK is not set ++# CONFIG_MACH_LOGICPD_PXA270 is not set ++# CONFIG_MACH_MAINSTONE is not set ++# CONFIG_ARCH_PXA_IDP is not set ++# CONFIG_PXA_SHARPSL is not set ++# CONFIG_MACH_TRIZEPS4 is not set ++CONFIG_MACH_ARMCORE=y ++CONFIG_PXA27x=y ++ ++# ++# Processor Type ++# ++CONFIG_CPU_32=y ++CONFIG_CPU_XSCALE=y ++CONFIG_CPU_32v5=y ++CONFIG_CPU_ABRT_EV5T=y ++CONFIG_CPU_CACHE_VIVT=y ++CONFIG_CPU_TLB_V4WBI=y ++CONFIG_CPU_CP15=y ++CONFIG_CPU_CP15_MMU=y ++ ++# ++# Processor Features ++# ++CONFIG_ARM_THUMB=y ++# CONFIG_CPU_DCACHE_DISABLE is not set ++# CONFIG_OUTER_CACHE is not set ++CONFIG_IWMMXT=y ++CONFIG_XSCALE_PMU=y ++ ++# ++# Bus support ++# ++CONFIG_PCI=y ++CONFIG_PCI_HOST_ITE8152=y ++# CONFIG_PCI_DEBUG is not set ++ ++# ++# PCCARD (PCMCIA/CardBus) support ++# ++CONFIG_PCCARD=y ++# CONFIG_PCMCIA_DEBUG is not set ++CONFIG_PCMCIA=m ++# CONFIG_PCMCIA_LOAD_CIS is not set ++CONFIG_PCMCIA_IOCTL=y ++CONFIG_CARDBUS=y ++ ++# ++# PC-card bridges ++# ++# CONFIG_YENTA is not set ++# CONFIG_PD6729 is not set ++# CONFIG_I82092 is not set ++CONFIG_PCMCIA_PXA2XX=m ++ ++# ++# Kernel Features ++# ++# CONFIG_PREEMPT is not set ++# CONFIG_NO_IDLE_HZ is not set ++CONFIG_HZ=100 ++# CONFIG_AEABI is not set ++# CONFIG_ARCH_DISCONTIGMEM_ENABLE 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_SPARSEMEM_STATIC is not set ++CONFIG_SPLIT_PTLOCK_CPUS=4096 ++# CONFIG_RESOURCES_64BIT is not set ++CONFIG_ZONE_DMA_FLAG=1 ++CONFIG_ALIGNMENT_TRAP=y ++ ++# ++# Boot options ++# ++CONFIG_ZBOOT_ROM_TEXT=0x0 ++CONFIG_ZBOOT_ROM_BSS=0x0 ++CONFIG_CMDLINE="" ++# CONFIG_XIP_KERNEL is not set ++# CONFIG_KEXEC is not set ++ ++# ++# 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 ++ ++# ++# Userspace binary formats ++# ++CONFIG_BINFMT_ELF=y ++# CONFIG_BINFMT_AOUT is not set ++# CONFIG_BINFMT_MISC is not set ++# CONFIG_ARTHUR is not set ++ ++# ++# Power management options ++# ++CONFIG_PM=y ++# CONFIG_PM_LEGACY is not set ++# CONFIG_PM_DEBUG is not set ++# CONFIG_PM_SYSFS_DEPRECATED is not set ++# CONFIG_APM_EMULATION is not set ++ ++# ++# Networking ++# ++CONFIG_NET=y ++ ++# ++# Networking options ++# ++# CONFIG_NETDEBUG is not set ++CONFIG_PACKET=y ++# CONFIG_PACKET_MMAP is not set ++CONFIG_UNIX=y ++CONFIG_XFRM=y ++# CONFIG_XFRM_USER is not set ++# CONFIG_XFRM_SUB_POLICY is not set ++# CONFIG_XFRM_MIGRATE is not set ++# 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 is not set ++# 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=y ++CONFIG_INET_XFRM_MODE_TUNNEL=y ++CONFIG_INET_XFRM_MODE_BEET=y ++CONFIG_INET_DIAG=y ++CONFIG_INET_TCP_DIAG=y ++# 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_INET6_XFRM_TUNNEL is not set ++# CONFIG_INET6_TUNNEL is not set ++# CONFIG_NETWORK_SECMARK is not set ++# CONFIG_NETFILTER is not set ++ ++# ++# DCCP Configuration (EXPERIMENTAL) ++# ++# CONFIG_IP_DCCP is not set ++ ++# ++# SCTP Configuration (EXPERIMENTAL) ++# ++# CONFIG_IP_SCTP is not set ++ ++# ++# TIPC Configuration (EXPERIMENTAL) ++# ++# CONFIG_TIPC is not set ++# CONFIG_ATM is not set ++# CONFIG_BRIDGE 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 ++ ++# ++# QoS and/or fair queueing ++# ++# CONFIG_NET_SCHED is not set ++ ++# ++# Network testing ++# ++# CONFIG_NET_PKTGEN is not set ++# CONFIG_HAMRADIO is not set ++# CONFIG_IRDA is not set ++# CONFIG_BT is not set ++CONFIG_IEEE80211=m ++# CONFIG_IEEE80211_DEBUG is not set ++CONFIG_IEEE80211_CRYPT_WEP=m ++CONFIG_IEEE80211_CRYPT_CCMP=m ++# CONFIG_IEEE80211_CRYPT_TKIP is not set ++# CONFIG_IEEE80211_SOFTMAC is not set ++CONFIG_WIRELESS_EXT=y ++ ++# ++# Device Drivers ++# ++ ++# ++# Generic Driver Options ++# ++CONFIG_STANDALONE=y ++CONFIG_PREVENT_FIRMWARE_BUILD=y ++CONFIG_FW_LOADER=y ++# CONFIG_DEBUG_DRIVER is not set ++# CONFIG_DEBUG_DEVRES is not set ++# CONFIG_SYS_HYPERVISOR is not set ++ ++# ++# Connector - unified userspace <-> kernelspace linker ++# ++# CONFIG_CONNECTOR is not set ++ ++# ++# Memory Technology Devices (MTD) ++# ++CONFIG_MTD=m ++# CONFIG_MTD_DEBUG is not set ++# CONFIG_MTD_CONCAT is not set ++CONFIG_MTD_PARTITIONS=y ++# CONFIG_MTD_REDBOOT_PARTS is not set ++# CONFIG_MTD_AFS_PARTS is not set ++ ++# ++# User Modules And Translation Layers ++# ++CONFIG_MTD_CHAR=m ++CONFIG_MTD_BLKDEVS=m ++CONFIG_MTD_BLOCK=m ++# CONFIG_MTD_BLOCK_RO is not set ++# 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 ++ ++# ++# 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 ++# CONFIG_MTD_OBSOLETE_CHIPS is not set ++ ++# ++# Mapping drivers for chip access ++# ++# CONFIG_MTD_COMPLEX_MAPPINGS is not set ++# CONFIG_MTD_SHARP_SL is not set ++# CONFIG_MTD_PLATRAM is not set ++ ++# ++# Self-contained MTD device drivers ++# ++# CONFIG_MTD_PMC551 is not set ++# 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 ++ ++# ++# NAND Flash Device Drivers ++# ++CONFIG_MTD_NAND=m ++# CONFIG_MTD_NAND_VERIFY_WRITE is not set ++# CONFIG_MTD_NAND_ECC_SMC is not set ++# CONFIG_MTD_NAND_H1900 is not set ++CONFIG_MTD_NAND_IDS=m ++# CONFIG_MTD_NAND_DISKONCHIP is not set ++# CONFIG_MTD_NAND_SHARPSL is not set ++# CONFIG_MTD_NAND_CAFE is not set ++CONFIG_MTD_NAND_CM_X270=m ++# CONFIG_MTD_NAND_NANDSIM is not set ++ ++# ++# OneNAND Flash Device Drivers ++# ++# CONFIG_MTD_ONENAND is not set ++ ++# ++# Parallel port support ++# ++# CONFIG_PARPORT is not set ++ ++# ++# Plug and Play support ++# ++# CONFIG_PNPACPI is not set ++ ++# ++# Block devices ++# ++# CONFIG_BLK_CPQ_DA is not set ++# CONFIG_BLK_CPQ_CISS_DA is not set ++# CONFIG_BLK_DEV_DAC960 is not set ++# CONFIG_BLK_DEV_UMEM is not set ++# CONFIG_BLK_DEV_COW_COMMON is not set ++CONFIG_BLK_DEV_LOOP=y ++# CONFIG_BLK_DEV_CRYPTOLOOP is not set ++# CONFIG_BLK_DEV_NBD is not set ++# CONFIG_BLK_DEV_SX8 is not set ++# CONFIG_BLK_DEV_UB is not set ++CONFIG_BLK_DEV_RAM=y ++CONFIG_BLK_DEV_RAM_COUNT=16 ++CONFIG_BLK_DEV_RAM_SIZE=12000 ++CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 ++# CONFIG_CDROM_PKTCDVD is not set ++# CONFIG_ATA_OVER_ETH is not set ++ ++# ++# ATA/ATAPI/MFM/RLL support ++# ++CONFIG_IDE=m ++CONFIG_IDE_MAX_HWIFS=4 ++CONFIG_BLK_DEV_IDE=m ++ ++# ++# Please see Documentation/ide.txt for help/info on IDE drives ++# ++# CONFIG_BLK_DEV_IDE_SATA is not set ++CONFIG_BLK_DEV_IDEDISK=m ++# CONFIG_IDEDISK_MULTI_MODE is not set ++CONFIG_BLK_DEV_IDECS=m ++# CONFIG_BLK_DEV_DELKIN is not set ++CONFIG_BLK_DEV_IDECD=m ++# CONFIG_BLK_DEV_IDETAPE is not set ++# CONFIG_BLK_DEV_IDEFLOPPY is not set ++# CONFIG_BLK_DEV_IDESCSI is not set ++# CONFIG_IDE_TASK_IOCTL is not set ++ ++# ++# IDE chipset support/bugfixes ++# ++# CONFIG_IDE_GENERIC is not set ++# CONFIG_BLK_DEV_IDEPCI is not set ++# CONFIG_IDE_ARM is not set ++CONFIG_BLK_DEV_IDE_CM_X270=m ++# CONFIG_BLK_DEV_IDEDMA is not set ++# CONFIG_BLK_DEV_HD is not set ++ ++# ++# SCSI device support ++# ++# CONFIG_RAID_ATTRS is not set ++CONFIG_SCSI=y ++# CONFIG_SCSI_TGT is not set ++# CONFIG_SCSI_NETLINK is not set ++# CONFIG_SCSI_PROC_FS is not set ++ ++# ++# SCSI support type (disk, tape, CD-ROM) ++# ++CONFIG_BLK_DEV_SD=y ++# CONFIG_CHR_DEV_ST is not set ++# CONFIG_CHR_DEV_OSST is not set ++# CONFIG_BLK_DEV_SR is not set ++# CONFIG_CHR_DEV_SG is not set ++# CONFIG_CHR_DEV_SCH is not set ++ ++# ++# Some SCSI devices (e.g. CD jukebox) support multiple LUNs ++# ++# CONFIG_SCSI_MULTI_LUN is not set ++# CONFIG_SCSI_CONSTANTS is not set ++# CONFIG_SCSI_LOGGING is not set ++# CONFIG_SCSI_SCAN_ASYNC is not set ++ ++# ++# SCSI Transports ++# ++# CONFIG_SCSI_SPI_ATTRS is not set ++# CONFIG_SCSI_FC_ATTRS is not set ++# CONFIG_SCSI_ISCSI_ATTRS is not set ++# CONFIG_SCSI_SAS_ATTRS is not set ++# CONFIG_SCSI_SAS_LIBSAS is not set ++ ++# ++# SCSI low-level drivers ++# ++# CONFIG_ISCSI_TCP is not set ++# CONFIG_BLK_DEV_3W_XXXX_RAID is not set ++# CONFIG_SCSI_3W_9XXX is not set ++# CONFIG_SCSI_ACARD is not set ++# CONFIG_SCSI_AACRAID is not set ++# CONFIG_SCSI_AIC7XXX is not set ++# CONFIG_SCSI_AIC7XXX_OLD is not set ++# CONFIG_SCSI_AIC79XX is not set ++# CONFIG_SCSI_AIC94XX is not set ++# CONFIG_SCSI_DPT_I2O is not set ++# CONFIG_SCSI_ARCMSR is not set ++# CONFIG_MEGARAID_NEWGEN is not set ++# CONFIG_MEGARAID_LEGACY is not set ++# CONFIG_MEGARAID_SAS is not set ++# CONFIG_SCSI_HPTIOP is not set ++# CONFIG_SCSI_DMX3191D is not set ++# CONFIG_SCSI_FUTURE_DOMAIN is not set ++# CONFIG_SCSI_IPS is not set ++# CONFIG_SCSI_INITIO is not set ++# CONFIG_SCSI_INIA100 is not set ++# CONFIG_SCSI_STEX is not set ++# CONFIG_SCSI_SYM53C8XX_2 is not set ++# CONFIG_SCSI_QLOGIC_1280 is not set ++# CONFIG_SCSI_QLA_FC is not set ++# CONFIG_SCSI_QLA_ISCSI is not set ++# CONFIG_SCSI_LPFC is not set ++# CONFIG_SCSI_DC395x is not set ++# CONFIG_SCSI_DC390T is not set ++# CONFIG_SCSI_NSP32 is not set ++# CONFIG_SCSI_DEBUG is not set ++# CONFIG_SCSI_SRP is not set ++ ++# ++# PCMCIA SCSI adapter support ++# ++# CONFIG_PCMCIA_AHA152X is not set ++# CONFIG_PCMCIA_FDOMAIN is not set ++# CONFIG_PCMCIA_NINJA_SCSI is not set ++# CONFIG_PCMCIA_QLOGIC is not set ++# CONFIG_PCMCIA_SYM53C500 is not set ++ ++# ++# Serial ATA (prod) and Parallel ATA (experimental) drivers ++# ++# CONFIG_ATA is not set ++ ++# ++# Multi-device support (RAID and LVM) ++# ++# CONFIG_MD is not set ++ ++# ++# Fusion MPT device support ++# ++# CONFIG_FUSION is not set ++# CONFIG_FUSION_SPI is not set ++# CONFIG_FUSION_FC is not set ++# CONFIG_FUSION_SAS is not set ++ ++# ++# IEEE 1394 (FireWire) support ++# ++# CONFIG_IEEE1394 is not set ++ ++# ++# I2O device support ++# ++# CONFIG_I2O is not set ++ ++# ++# Network device support ++# ++CONFIG_NETDEVICES=y ++# CONFIG_DUMMY is not set ++# CONFIG_BONDING is not set ++# CONFIG_EQUALIZER is not set ++# CONFIG_TUN is not set ++ ++# ++# ARCnet devices ++# ++# CONFIG_ARCNET is not set ++ ++# ++# PHY device support ++# ++# CONFIG_PHYLIB is not set ++ ++# ++# Ethernet (10 or 100Mbit) ++# ++CONFIG_NET_ETHERNET=y ++CONFIG_MII=y ++# CONFIG_HAPPYMEAL is not set ++# CONFIG_SUNGEM is not set ++# CONFIG_CASSINI is not set ++# CONFIG_NET_VENDOR_3COM is not set ++# CONFIG_SMC91X is not set ++CONFIG_DM9000=y ++CONFIG_DM9000_NOEPROM=y ++# CONFIG_SMC911X is not set ++ ++# ++# Tulip family network device support ++# ++# CONFIG_NET_TULIP is not set ++# CONFIG_HP100 is not set ++CONFIG_NET_PCI=y ++# CONFIG_PCNET32 is not set ++# CONFIG_AMD8111_ETH is not set ++# CONFIG_ADAPTEC_STARFIRE is not set ++# CONFIG_B44 is not set ++# CONFIG_FORCEDETH is not set ++# CONFIG_DGRS is not set ++# CONFIG_EEPRO100 is not set ++# CONFIG_E100 is not set ++# CONFIG_FEALNX is not set ++# CONFIG_NATSEMI is not set ++# CONFIG_NE2K_PCI is not set ++# CONFIG_8139CP is not set ++CONFIG_8139TOO=m ++# CONFIG_8139TOO_PIO is not set ++# CONFIG_8139TOO_TUNE_TWISTER is not set ++# CONFIG_8139TOO_8129 is not set ++# CONFIG_8139_OLD_RX_RESET is not set ++# CONFIG_SIS900 is not set ++# CONFIG_EPIC100 is not set ++# CONFIG_SUNDANCE is not set ++# CONFIG_TLAN is not set ++# CONFIG_VIA_RHINE is not set ++# CONFIG_SC92031 is not set ++ ++# ++# Ethernet (1000 Mbit) ++# ++# CONFIG_ACENIC is not set ++# CONFIG_DL2K is not set ++# CONFIG_E1000 is not set ++# CONFIG_NS83820 is not set ++# CONFIG_HAMACHI is not set ++# CONFIG_YELLOWFIN is not set ++# CONFIG_R8169 is not set ++# CONFIG_SIS190 is not set ++# CONFIG_SKGE is not set ++# CONFIG_SKY2 is not set ++# CONFIG_SK98LIN is not set ++# CONFIG_VIA_VELOCITY is not set ++# CONFIG_TIGON3 is not set ++# CONFIG_BNX2 is not set ++# CONFIG_QLA3XXX is not set ++# CONFIG_ATL1 is not set ++ ++# ++# Ethernet (10000 Mbit) ++# ++# CONFIG_CHELSIO_T1 is not set ++# CONFIG_CHELSIO_T3 is not set ++# CONFIG_IXGB is not set ++# CONFIG_S2IO is not set ++# CONFIG_MYRI10GE is not set ++# CONFIG_NETXEN_NIC is not set ++ ++# ++# Token Ring devices ++# ++# CONFIG_TR is not set ++ ++# ++# Wireless LAN (non-hamradio) ++# ++CONFIG_NET_RADIO=y ++# CONFIG_NET_WIRELESS_RTNETLINK is not set ++ ++# ++# Obsolete Wireless cards support (pre-802.11) ++# ++# CONFIG_STRIP is not set ++# CONFIG_PCMCIA_WAVELAN is not set ++# CONFIG_PCMCIA_NETWAVE is not set ++ ++# ++# Wireless 802.11 Frequency Hopping cards support ++# ++# CONFIG_PCMCIA_RAYCS is not set ++ ++# ++# Wireless 802.11b ISA/PCI cards support ++# ++# CONFIG_IPW2100 is not set ++# CONFIG_IPW2200 is not set ++# CONFIG_HERMES is not set ++# CONFIG_ATMEL is not set ++ ++# ++# Wireless 802.11b Pcmcia/Cardbus cards support ++# ++# CONFIG_AIRO_CS is not set ++# CONFIG_PCMCIA_WL3501 is not set ++ ++# ++# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support ++# ++# CONFIG_PRISM54 is not set ++# CONFIG_USB_ZD1201 is not set ++# CONFIG_HOSTAP is not set ++CONFIG_NET_WIRELESS=y ++ ++# ++# PCMCIA network device support ++# ++CONFIG_NET_PCMCIA=y ++# CONFIG_PCMCIA_3C589 is not set ++# CONFIG_PCMCIA_3C574 is not set ++# CONFIG_PCMCIA_FMVJ18X is not set ++CONFIG_PCMCIA_PCNET=m ++# CONFIG_PCMCIA_NMCLAN is not set ++# CONFIG_PCMCIA_SMC91C92 is not set ++# CONFIG_PCMCIA_XIRC2PS is not set ++# CONFIG_PCMCIA_AXNET is not set ++ ++# ++# Wan interfaces ++# ++# CONFIG_WAN is not set ++# CONFIG_FDDI is not set ++# CONFIG_HIPPI is not set ++# CONFIG_PPP is not set ++# CONFIG_SLIP is not set ++# CONFIG_NET_FC is not set ++# CONFIG_SHAPER is not set ++# CONFIG_NETCONSOLE is not set ++# CONFIG_NETPOLL is not set ++# CONFIG_NET_POLL_CONTROLLER is not set ++ ++# ++# ISDN subsystem ++# ++# CONFIG_ISDN is not set ++ ++# ++# Input device support ++# ++CONFIG_INPUT=y ++# CONFIG_INPUT_FF_MEMLESS is not set ++ ++# ++# Userland interfaces ++# ++# CONFIG_INPUT_MOUSEDEV is not set ++# CONFIG_INPUT_JOYDEV is not set ++# CONFIG_INPUT_TSDEV is not set ++CONFIG_INPUT_EVDEV=y ++# CONFIG_INPUT_EVBUG is not set ++ ++# ++# Input Device Drivers ++# ++# CONFIG_INPUT_KEYBOARD is not set ++# CONFIG_INPUT_MOUSE is not set ++# CONFIG_INPUT_JOYSTICK is not set ++CONFIG_INPUT_TOUCHSCREEN=y ++# CONFIG_TOUCHSCREEN_GUNZE is not set ++# CONFIG_TOUCHSCREEN_ELO is not set ++# CONFIG_TOUCHSCREEN_MTOUCH is not set ++# CONFIG_TOUCHSCREEN_MK712 is not set ++# CONFIG_TOUCHSCREEN_PENMOUNT is not set ++# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set ++# CONFIG_TOUCHSCREEN_TOUCHWIN is not set ++CONFIG_TOUCHSCREEN_UCB1400=m ++# 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_VT_CONSOLE=y ++CONFIG_HW_CONSOLE=y ++# CONFIG_VT_HW_CONSOLE_BINDING is not set ++# CONFIG_SERIAL_NONSTANDARD is not set ++ ++# ++# Serial drivers ++# ++# CONFIG_SERIAL_8250 is not set ++ ++# ++# Non-8250 serial port support ++# ++CONFIG_SERIAL_PXA=y ++CONFIG_SERIAL_PXA_CONSOLE=y ++CONFIG_SERIAL_CORE=y ++CONFIG_SERIAL_CORE_CONSOLE=y ++# CONFIG_SERIAL_JSM is not set ++CONFIG_UNIX98_PTYS=y ++CONFIG_LEGACY_PTYS=y ++CONFIG_LEGACY_PTY_COUNT=256 ++ ++# ++# IPMI ++# ++# CONFIG_IPMI_HANDLER is not set ++ ++# ++# Watchdog Cards ++# ++# CONFIG_WATCHDOG is not set ++CONFIG_HW_RANDOM=m ++# CONFIG_NVRAM is not set ++# CONFIG_DTLK is not set ++# CONFIG_R3964 is not set ++# CONFIG_APPLICOM is not set ++# CONFIG_DRM is not set ++ ++# ++# PCMCIA character devices ++# ++# CONFIG_SYNCLINK_CS is not set ++# CONFIG_CARDMAN_4000 is not set ++# CONFIG_CARDMAN_4040 is not set ++# CONFIG_RAW_DRIVER is not set ++ ++# ++# TPM devices ++# ++# CONFIG_TCG_TPM is not set ++ ++# ++# I2C support ++# ++# CONFIG_I2C is not set ++ ++# ++# SPI support ++# ++# CONFIG_SPI is not set ++# CONFIG_SPI_MASTER is not set ++ ++# ++# Dallas's 1-wire bus ++# ++# CONFIG_W1 is not set ++ ++# ++# Hardware Monitoring support ++# ++# CONFIG_HWMON is not set ++# CONFIG_HWMON_VID is not set ++ ++# ++# Misc devices ++# ++# CONFIG_SGI_IOC4 is not set ++# CONFIG_TIFM_CORE is not set ++ ++# ++# Multifunction device drivers ++# ++# CONFIG_MFD_SM501 is not set ++ ++# ++# LED devices ++# ++CONFIG_NEW_LEDS=y ++CONFIG_LEDS_CLASS=y ++ ++# ++# LED drivers ++# ++CONFIG_LEDS_CM_X270=y ++ ++# ++# LED Triggers ++# ++CONFIG_LEDS_TRIGGERS=y ++# CONFIG_LEDS_TRIGGER_TIMER is not set ++# CONFIG_LEDS_TRIGGER_IDE_DISK is not set ++CONFIG_LEDS_TRIGGER_HEARTBEAT=y ++ ++# ++# Multimedia devices ++# ++# CONFIG_VIDEO_DEV is not set ++ ++# ++# Digital Video Broadcasting Devices ++# ++# CONFIG_DVB is not set ++# CONFIG_USB_DABUSB is not set ++ ++# ++# Graphics support ++# ++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set ++CONFIG_FB=y ++# CONFIG_FIRMWARE_EDID is not set ++# CONFIG_FB_DDC is not set ++CONFIG_FB_CFB_FILLRECT=y ++CONFIG_FB_CFB_COPYAREA=y ++CONFIG_FB_CFB_IMAGEBLIT=y ++# CONFIG_FB_SVGALIB is not set ++# CONFIG_FB_MACMODES is not set ++# CONFIG_FB_BACKLIGHT is not set ++# CONFIG_FB_MODE_HELPERS is not set ++# CONFIG_FB_TILEBLITTING is not set ++ ++# ++# Frambuffer hardware drivers ++# ++# CONFIG_FB_CIRRUS is not set ++# CONFIG_FB_PM2 is not set ++# CONFIG_FB_CYBER2000 is not set ++# CONFIG_FB_ASILIANT is not set ++# CONFIG_FB_IMSTT is not set ++# CONFIG_FB_S1D13XXX is not set ++# CONFIG_FB_NVIDIA is not set ++# CONFIG_FB_RIVA is not set ++# CONFIG_FB_MATROX is not set ++# CONFIG_FB_RADEON is not set ++# CONFIG_FB_ATY128 is not set ++# CONFIG_FB_ATY is not set ++# CONFIG_FB_S3 is not set ++# CONFIG_FB_SAVAGE is not set ++# CONFIG_FB_SIS is not set ++# CONFIG_FB_NEOMAGIC is not set ++# CONFIG_FB_KYRO is not set ++# CONFIG_FB_3DFX is not set ++# CONFIG_FB_VOODOO1 is not set ++# CONFIG_FB_TRIDENT is not set ++CONFIG_FB_PXA=y ++# CONFIG_FB_PXA_PARAMETERS is not set ++CONFIG_FB_MBX=m ++# CONFIG_FB_VIRTUAL is not set ++ ++# ++# Console display driver support ++# ++# CONFIG_VGA_CONSOLE is not set ++CONFIG_DUMMY_CONSOLE=y ++CONFIG_FRAMEBUFFER_CONSOLE=y ++# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set ++# CONFIG_FONTS is not set ++CONFIG_FONT_8x8=y ++CONFIG_FONT_8x16=y ++ ++# ++# Logo configuration ++# ++CONFIG_LOGO=y ++CONFIG_LOGO_LINUX_MONO=y ++CONFIG_LOGO_LINUX_VGA16=y ++CONFIG_LOGO_LINUX_CLUT224=y ++ ++# ++# Sound ++# ++CONFIG_SOUND=m ++ ++# ++# Advanced Linux Sound Architecture ++# ++CONFIG_SND=m ++CONFIG_SND_TIMER=m ++CONFIG_SND_PCM=m ++# CONFIG_SND_SEQUENCER is not set ++CONFIG_SND_OSSEMUL=y ++CONFIG_SND_MIXER_OSS=m ++CONFIG_SND_PCM_OSS=m ++CONFIG_SND_PCM_OSS_PLUGINS=y ++# CONFIG_SND_DYNAMIC_MINORS is not set ++CONFIG_SND_SUPPORT_OLD_API=y ++CONFIG_SND_VERBOSE_PROCFS=y ++# CONFIG_SND_VERBOSE_PRINTK is not set ++# CONFIG_SND_DEBUG is not set ++ ++# ++# Generic devices ++# ++CONFIG_SND_AC97_CODEC=m ++# CONFIG_SND_DUMMY is not set ++# CONFIG_SND_MTPAV is not set ++# CONFIG_SND_SERIAL_U16550 is not set ++# CONFIG_SND_MPU401 is not set ++ ++# ++# PCI devices ++# ++# CONFIG_SND_AD1889 is not set ++# CONFIG_SND_ALS300 is not set ++# CONFIG_SND_ALI5451 is not set ++# CONFIG_SND_ATIIXP is not set ++# CONFIG_SND_ATIIXP_MODEM is not set ++# CONFIG_SND_AU8810 is not set ++# CONFIG_SND_AU8820 is not set ++# CONFIG_SND_AU8830 is not set ++# CONFIG_SND_AZT3328 is not set ++# CONFIG_SND_BT87X is not set ++# CONFIG_SND_CA0106 is not set ++# CONFIG_SND_CMIPCI is not set ++# CONFIG_SND_CS4281 is not set ++# CONFIG_SND_CS46XX is not set ++# CONFIG_SND_DARLA20 is not set ++# CONFIG_SND_GINA20 is not set ++# CONFIG_SND_LAYLA20 is not set ++# CONFIG_SND_DARLA24 is not set ++# CONFIG_SND_GINA24 is not set ++# CONFIG_SND_LAYLA24 is not set ++# CONFIG_SND_MONA is not set ++# CONFIG_SND_MIA is not set ++# CONFIG_SND_ECHO3G is not set ++# CONFIG_SND_INDIGO is not set ++# CONFIG_SND_INDIGOIO is not set ++# CONFIG_SND_INDIGODJ is not set ++# CONFIG_SND_EMU10K1 is not set ++# CONFIG_SND_EMU10K1X is not set ++# CONFIG_SND_ENS1370 is not set ++# CONFIG_SND_ENS1371 is not set ++# CONFIG_SND_ES1938 is not set ++# CONFIG_SND_ES1968 is not set ++# CONFIG_SND_FM801 is not set ++# CONFIG_SND_HDA_INTEL is not set ++# CONFIG_SND_HDSP is not set ++# CONFIG_SND_HDSPM is not set ++# CONFIG_SND_ICE1712 is not set ++# CONFIG_SND_ICE1724 is not set ++# CONFIG_SND_INTEL8X0 is not set ++# CONFIG_SND_INTEL8X0M is not set ++# CONFIG_SND_KORG1212 is not set ++# CONFIG_SND_MAESTRO3 is not set ++# CONFIG_SND_MIXART is not set ++# CONFIG_SND_NM256 is not set ++# CONFIG_SND_PCXHR is not set ++# CONFIG_SND_RIPTIDE is not set ++# CONFIG_SND_RME32 is not set ++# CONFIG_SND_RME96 is not set ++# CONFIG_SND_RME9652 is not set ++# CONFIG_SND_SONICVIBES is not set ++# CONFIG_SND_TRIDENT is not set ++# CONFIG_SND_VIA82XX is not set ++# CONFIG_SND_VIA82XX_MODEM is not set ++# CONFIG_SND_VX222 is not set ++# CONFIG_SND_YMFPCI is not set ++# CONFIG_SND_AC97_POWER_SAVE is not set ++ ++# ++# ALSA ARM devices ++# ++CONFIG_SND_PXA2XX_PCM=m ++CONFIG_SND_PXA2XX_AC97=m ++ ++# ++# USB devices ++# ++# CONFIG_SND_USB_AUDIO is not set ++ ++# ++# PCMCIA devices ++# ++# CONFIG_SND_VXPOCKET is not set ++# CONFIG_SND_PDAUDIOCF is not set ++ ++# ++# SoC audio support ++# ++# CONFIG_SND_SOC is not set ++ ++# ++# Open Sound System ++# ++# CONFIG_SOUND_PRIME is not set ++CONFIG_AC97_BUS=m ++ ++# ++# HID Devices ++# ++CONFIG_HID=y ++# CONFIG_HID_DEBUG is not set ++ ++# ++# USB support ++# ++CONFIG_USB_ARCH_HAS_HCD=y ++CONFIG_USB_ARCH_HAS_OHCI=y ++CONFIG_USB_ARCH_HAS_EHCI=y ++CONFIG_USB=y ++# CONFIG_USB_DEBUG is not set ++ ++# ++# Miscellaneous USB options ++# ++CONFIG_USB_DEVICEFS=y ++# CONFIG_USB_DYNAMIC_MINORS is not set ++# CONFIG_USB_SUSPEND is not set ++# CONFIG_USB_OTG is not set ++ ++# ++# USB Host Controller Drivers ++# ++# CONFIG_USB_EHCI_HCD is not set ++# CONFIG_USB_ISP116X_HCD is not set ++CONFIG_USB_OHCI_HCD=y ++# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set ++# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set ++CONFIG_USB_OHCI_LITTLE_ENDIAN=y ++# CONFIG_USB_UHCI_HCD is not set ++# CONFIG_USB_SL811_HCD is not set ++ ++# ++# USB Device Class drivers ++# ++# CONFIG_USB_ACM is not set ++# CONFIG_USB_PRINTER is not set ++ ++# ++# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' ++# ++ ++# ++# may also be needed; see USB_STORAGE Help for more information ++# ++CONFIG_USB_STORAGE=y ++# CONFIG_USB_STORAGE_DEBUG is not set ++# CONFIG_USB_STORAGE_DATAFAB is not set ++# CONFIG_USB_STORAGE_FREECOM is not set ++# CONFIG_USB_STORAGE_DPCM is not set ++# CONFIG_USB_STORAGE_USBAT is not set ++# CONFIG_USB_STORAGE_SDDR09 is not set ++# CONFIG_USB_STORAGE_SDDR55 is not set ++# CONFIG_USB_STORAGE_JUMPSHOT is not set ++# CONFIG_USB_STORAGE_ALAUDA is not set ++# CONFIG_USB_STORAGE_KARMA is not set ++# CONFIG_USB_LIBUSUAL is not set ++ ++# ++# USB Input Devices ++# ++CONFIG_USB_HID=y ++# CONFIG_USB_HIDINPUT_POWERBOOK is not set ++# CONFIG_HID_FF is not set ++# CONFIG_USB_HIDDEV is not set ++# CONFIG_USB_AIPTEK is not set ++# CONFIG_USB_WACOM is not set ++# CONFIG_USB_ACECAD is not set ++# CONFIG_USB_KBTAB is not set ++# CONFIG_USB_POWERMATE is not set ++# CONFIG_USB_TOUCHSCREEN is not set ++# CONFIG_USB_YEALINK is not set ++# CONFIG_USB_XPAD is not set ++# CONFIG_USB_ATI_REMOTE is not set ++# CONFIG_USB_ATI_REMOTE2 is not set ++# CONFIG_USB_KEYSPAN_REMOTE is not set ++# CONFIG_USB_APPLETOUCH is not set ++# CONFIG_USB_GTCO is not set ++ ++# ++# USB Imaging devices ++# ++# CONFIG_USB_MDC800 is not set ++# CONFIG_USB_MICROTEK is not set ++ ++# ++# USB Network Adapters ++# ++# CONFIG_USB_CATC is not set ++# CONFIG_USB_KAWETH is not set ++# CONFIG_USB_PEGASUS is not set ++# CONFIG_USB_RTL8150 is not set ++# CONFIG_USB_USBNET_MII is not set ++# CONFIG_USB_USBNET is not set ++CONFIG_USB_MON=y ++ ++# ++# USB port drivers ++# ++ ++# ++# USB Serial Converter support ++# ++# CONFIG_USB_SERIAL is not set ++ ++# ++# USB Miscellaneous drivers ++# ++# CONFIG_USB_EMI62 is not set ++# CONFIG_USB_EMI26 is not set ++# CONFIG_USB_ADUTUX is not set ++# CONFIG_USB_AUERSWALD is not set ++# CONFIG_USB_RIO500 is not set ++# CONFIG_USB_LEGOTOWER is not set ++# CONFIG_USB_LCD is not set ++# CONFIG_USB_BERRY_CHARGE is not set ++# CONFIG_USB_LED is not set ++# CONFIG_USB_CYPRESS_CY7C63 is not set ++# CONFIG_USB_CYTHERM is not set ++# CONFIG_USB_PHIDGET is not set ++# CONFIG_USB_IDMOUSE is not set ++# CONFIG_USB_FTDI_ELAN is not set ++# CONFIG_USB_APPLEDISPLAY is not set ++# CONFIG_USB_LD is not set ++# CONFIG_USB_TRANCEVIBRATOR is not set ++# CONFIG_USB_IOWARRIOR is not set ++# CONFIG_USB_TEST is not set ++ ++# ++# USB DSL modem support ++# ++ ++# ++# USB Gadget Support ++# ++# CONFIG_USB_GADGET is not set ++ ++# ++# MMC/SD Card support ++# ++CONFIG_MMC=m ++# CONFIG_MMC_DEBUG is not set ++CONFIG_MMC_BLOCK=m ++CONFIG_MMC_PXA=m ++# CONFIG_MMC_SDHCI is not set ++# CONFIG_MMC_TIFM_SD is not set ++ ++# ++# Real Time Clock ++# ++CONFIG_RTC_LIB=y ++CONFIG_RTC_CLASS=y ++CONFIG_RTC_HCTOSYS=y ++CONFIG_RTC_HCTOSYS_DEVICE="rtc0" ++# CONFIG_RTC_DEBUG is not set ++ ++# ++# RTC interfaces ++# ++CONFIG_RTC_INTF_SYSFS=y ++CONFIG_RTC_INTF_PROC=y ++CONFIG_RTC_INTF_DEV=y ++# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set ++ ++# ++# RTC drivers ++# ++# CONFIG_RTC_DRV_CMOS is not set ++# CONFIG_RTC_DRV_DS1553 is not set ++# CONFIG_RTC_DRV_DS1742 is not set ++# CONFIG_RTC_DRV_M48T86 is not set ++CONFIG_RTC_DRV_SA1100=y ++# CONFIG_RTC_DRV_TEST is not set ++CONFIG_RTC_DRV_V3020=y ++ ++# ++# File systems ++# ++CONFIG_EXT2_FS=y ++# CONFIG_EXT2_FS_XATTR is not set ++# CONFIG_EXT2_FS_XIP is not set ++CONFIG_EXT3_FS=y ++CONFIG_EXT3_FS_XATTR=y ++# CONFIG_EXT3_FS_POSIX_ACL is not set ++# CONFIG_EXT3_FS_SECURITY is not set ++# CONFIG_EXT4DEV_FS is not set ++CONFIG_JBD=y ++# CONFIG_JBD_DEBUG is not set ++CONFIG_FS_MBCACHE=y ++# CONFIG_REISERFS_FS is not set ++# CONFIG_JFS_FS is not set ++# CONFIG_FS_POSIX_ACL is not set ++# CONFIG_XFS_FS is not set ++# CONFIG_GFS2_FS is not set ++# CONFIG_OCFS2_FS is not set ++# CONFIG_MINIX_FS is not set ++# CONFIG_ROMFS_FS is not set ++CONFIG_INOTIFY=y ++CONFIG_INOTIFY_USER=y ++# CONFIG_QUOTA is not set ++CONFIG_DNOTIFY=y ++# CONFIG_AUTOFS_FS is not set ++# CONFIG_AUTOFS4_FS is not set ++# CONFIG_FUSE_FS is not set ++ ++# ++# CD-ROM/DVD Filesystems ++# ++# CONFIG_ISO9660_FS is not set ++# CONFIG_UDF_FS is not set ++ ++# ++# DOS/FAT/NT Filesystems ++# ++CONFIG_FAT_FS=y ++CONFIG_MSDOS_FS=y ++CONFIG_VFAT_FS=y ++CONFIG_FAT_DEFAULT_CODEPAGE=437 ++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" ++# CONFIG_NTFS_FS is not set ++ ++# ++# Pseudo filesystems ++# ++CONFIG_PROC_FS=y ++CONFIG_PROC_SYSCTL=y ++CONFIG_SYSFS=y ++CONFIG_TMPFS=y ++# CONFIG_TMPFS_POSIX_ACL is not set ++# CONFIG_HUGETLB_PAGE is not set ++CONFIG_RAMFS=y ++# CONFIG_CONFIGFS_FS is not set ++ ++# ++# Miscellaneous filesystems ++# ++# 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 is not set ++# CONFIG_CRAMFS is not set ++# CONFIG_VXFS_FS is not set ++# CONFIG_HPFS_FS is not set ++# CONFIG_QNX4FS_FS is not set ++# CONFIG_SYSV_FS is not set ++# CONFIG_UFS_FS is not set ++ ++# ++# Network File Systems ++# ++CONFIG_NFS_FS=y ++CONFIG_NFS_V3=y ++# CONFIG_NFS_V3_ACL is not set ++# CONFIG_NFS_V4 is not set ++# CONFIG_NFS_DIRECTIO is not set ++# CONFIG_NFSD is not set ++CONFIG_ROOT_NFS=y ++CONFIG_LOCKD=y ++CONFIG_LOCKD_V4=y ++CONFIG_NFS_COMMON=y ++CONFIG_SUNRPC=y ++# CONFIG_RPCSEC_GSS_KRB5 is not set ++# CONFIG_RPCSEC_GSS_SPKM3 is not set ++CONFIG_SMB_FS=y ++# CONFIG_SMB_NLS_DEFAULT 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 ++# CONFIG_9P_FS is not set ++ ++# ++# Partition Types ++# ++# CONFIG_PARTITION_ADVANCED is not set ++CONFIG_MSDOS_PARTITION=y ++ ++# ++# Native Language Support ++# ++CONFIG_NLS=y ++CONFIG_NLS_DEFAULT="iso8859-1" ++CONFIG_NLS_CODEPAGE_437=y ++# CONFIG_NLS_CODEPAGE_737 is not set ++# CONFIG_NLS_CODEPAGE_775 is not set ++# CONFIG_NLS_CODEPAGE_850 is not set ++# 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 is not set ++# CONFIG_NLS_CODEPAGE_1251 is not set ++# CONFIG_NLS_ASCII is not set ++CONFIG_NLS_ISO8859_1=y ++# 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 is not set ++# CONFIG_NLS_KOI8_R is not set ++# CONFIG_NLS_KOI8_U is not set ++# CONFIG_NLS_UTF8 is not set ++ ++# ++# Distributed Lock Manager ++# ++# CONFIG_DLM is not set ++ ++# ++# Profiling support ++# ++# CONFIG_PROFILING is not set ++ ++# ++# Kernel hacking ++# ++# CONFIG_PRINTK_TIME is not set ++CONFIG_ENABLE_MUST_CHECK=y ++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_LOG_BUF_SHIFT=17 ++# CONFIG_DETECT_SOFTLOCKUP is not set ++# CONFIG_SCHEDSTATS is not set ++# CONFIG_TIMER_STATS is not set ++# CONFIG_DEBUG_SLAB 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_SPINLOCK_SLEEP is not set ++# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set ++# CONFIG_DEBUG_KOBJECT is not set ++# CONFIG_DEBUG_BUGVERBOSE is not set ++CONFIG_DEBUG_INFO=y ++# CONFIG_DEBUG_VM is not set ++# CONFIG_DEBUG_LIST is not set ++CONFIG_FRAME_POINTER=y ++CONFIG_FORCED_INLINING=y ++# CONFIG_RCU_TORTURE_TEST is not set ++# CONFIG_FAULT_INJECTION is not set ++CONFIG_DEBUG_USER=y ++CONFIG_DEBUG_ERRORS=y ++CONFIG_DEBUG_LL=y ++# CONFIG_DEBUG_ICEDCC is not set ++ ++# ++# Security options ++# ++# CONFIG_KEYS is not set ++# CONFIG_SECURITY is not set ++ ++# ++# Cryptographic options ++# ++CONFIG_CRYPTO=y ++CONFIG_CRYPTO_ALGAPI=m ++CONFIG_CRYPTO_BLKCIPHER=m ++CONFIG_CRYPTO_MANAGER=m ++# CONFIG_CRYPTO_HMAC is not set ++# CONFIG_CRYPTO_XCBC is not set ++# CONFIG_CRYPTO_NULL is not set ++# CONFIG_CRYPTO_MD4 is not set ++# CONFIG_CRYPTO_MD5 is not set ++# CONFIG_CRYPTO_SHA1 is not set ++# CONFIG_CRYPTO_SHA256 is not set ++# CONFIG_CRYPTO_SHA512 is not set ++# CONFIG_CRYPTO_WP512 is not set ++# CONFIG_CRYPTO_TGR192 is not set ++# CONFIG_CRYPTO_GF128MUL is not set ++CONFIG_CRYPTO_ECB=m ++CONFIG_CRYPTO_CBC=m ++CONFIG_CRYPTO_PCBC=m ++# CONFIG_CRYPTO_LRW is not set ++# CONFIG_CRYPTO_DES is not set ++# CONFIG_CRYPTO_FCRYPT is not set ++# CONFIG_CRYPTO_BLOWFISH is not set ++# CONFIG_CRYPTO_TWOFISH is not set ++# CONFIG_CRYPTO_SERPENT is not set ++CONFIG_CRYPTO_AES=m ++# CONFIG_CRYPTO_CAST5 is not set ++# CONFIG_CRYPTO_CAST6 is not set ++# CONFIG_CRYPTO_TEA is not set ++CONFIG_CRYPTO_ARC4=m ++# CONFIG_CRYPTO_KHAZAD is not set ++# CONFIG_CRYPTO_ANUBIS is not set ++# CONFIG_CRYPTO_DEFLATE is not set ++# CONFIG_CRYPTO_MICHAEL_MIC is not set ++# CONFIG_CRYPTO_CRC32C is not set ++# CONFIG_CRYPTO_CAMELLIA is not set ++# CONFIG_CRYPTO_TEST is not set ++ ++# ++# Hardware crypto devices ++# ++ ++# ++# Library routines ++# ++CONFIG_BITREVERSE=y ++# CONFIG_CRC_CCITT is not set ++# CONFIG_CRC16 is not set ++CONFIG_CRC32=y ++# CONFIG_LIBCRC32C is not set ++CONFIG_PLIST=y ++CONFIG_HAS_IOMEM=y ++CONFIG_HAS_IOPORT=y +diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig +index 5ebec6d..e126926 100644 +--- a/arch/arm/mach-pxa/Kconfig ++++ b/arch/arm/mach-pxa/Kconfig +@@ -40,6 +40,12 @@ config MACH_TRIZEPS4 + config MACH_EM_X270 + bool "CompuLab EM-x270 platform" + select PXA27x ++ select IWMMXT ++ ++config MACH_ARMCORE ++ bool "CompuLab CM-X270 modules" ++ select PXA27x ++ select IWMMXT + + endchoice + +diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile +index 7d6ab5c..b369289 100644 +--- a/arch/arm/mach-pxa/Makefile ++++ b/arch/arm/mach-pxa/Makefile +@@ -19,6 +19,7 @@ obj-$(CONFIG_MACH_AKITA) += akita-ioexp.o + obj-$(CONFIG_MACH_POODLE) += poodle.o corgi_ssp.o + obj-$(CONFIG_MACH_TOSA) += tosa.o + obj-$(CONFIG_MACH_EM_X270) += em-x270.o ++obj-$(CONFIG_MACH_ARMCORE) += cm-x270.o + + # Support for blinky lights + led-y := leds.o +@@ -26,6 +27,8 @@ led-$(CONFIG_ARCH_LUBBOCK) += leds-lubbock.o + led-$(CONFIG_MACH_MAINSTONE) += leds-mainstone.o + led-$(CONFIG_ARCH_PXA_IDP) += leds-idp.o + led-$(CONFIG_MACH_TRIZEPS4) += leds-trizeps4.o ++# FIXME: use driver/leds instead ++led-$(CONFIG_MACH_ARMCORE) += leds-cm-x270.o + + obj-$(CONFIG_LEDS) += $(led-y) + +@@ -36,3 +39,7 @@ obj-$(CONFIG_PXA_SSP) += ssp.o + ifeq ($(CONFIG_PXA27x),y) + obj-$(CONFIG_PM) += standby.o + endif ++ ++ifeq ($(CONFIG_PCI),y) ++obj-$(CONFIG_MACH_ARMCORE) += cm-x270-pci.o ++endif +diff --git a/arch/arm/mach-pxa/cm-x270.c b/arch/arm/mach-pxa/cm-x270.c +new file mode 100644 +index 0000000..7b4e288 +--- /dev/null ++++ b/arch/arm/mach-pxa/cm-x270.c +@@ -0,0 +1,821 @@ ++/* ++ * linux/arch/arm/mach-pxa/cm-x270.c ++ * ++ * Copyright (C) 2007 CompuLab, Ltd. ++ * Mike Rapoport <mike@compulab.co.il> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++#include <linux/pm.h> ++#include <linux/fb.h> ++#include <linux/platform_device.h> ++#include <linux/sysdev.h> ++#include <linux/dm9000.h> ++#include <linux/rtc-v3020.h> ++#include <linux/serial_8250.h> ++#include <video/mbxfb.h> ++ ++#include <asm/types.h> ++#include <asm/setup.h> ++#include <asm/memory.h> ++#include <asm/mach-types.h> ++#include <asm/hardware.h> ++#include <asm/irq.h> ++#include <asm/io.h> ++#include <asm/delay.h> ++ ++#include <asm/mach/arch.h> ++#include <asm/mach/map.h> ++#include <asm/mach/irq.h> ++ ++#include <asm/arch/pxa-regs.h> ++#include <asm/arch/pxafb.h> ++#include <asm/arch/ohci.h> ++#include <asm/arch/mmc.h> ++#include <asm/arch/bitfield.h> ++#include <asm/arch/cm-x270.h> ++ ++#include <asm/hardware/it8152.h> ++ ++#include "generic.h" ++ ++#define RTC_PHYS_BASE (PXA_CS1_PHYS + (5 << 22)) ++#define DM9000_PHYS_BASE (PXA_CS1_PHYS + (6 << 22)) ++ ++static struct resource cmx270_dm9k_resource[] = { ++ [0] = { ++ .start = DM9000_PHYS_BASE, ++ .end = DM9000_PHYS_BASE + 4, ++ .flags = IORESOURCE_MEM, ++ }, ++ [1] = { ++ .start = DM9000_PHYS_BASE + 8, ++ .end = DM9000_PHYS_BASE + 8 + 500, ++ .flags = IORESOURCE_MEM, ++ }, ++ [2] = { ++ .start = CMX270_ETHIRQ, ++ .end = CMX270_ETHIRQ, ++ .flags = IORESOURCE_IRQ, ++ } ++}; ++ ++/* for the moment we limit ourselves to 32bit IO until some ++ * better IO routines can be written and tested ++ */ ++static struct dm9000_plat_data cmx270_dm9k_platdata = { ++ .flags = DM9000_PLATF_32BITONLY, ++}; ++ ++/* Ethernet device */ ++static struct platform_device cmx270_device_dm9k = { ++ .name = "dm9000", ++ .id = 0, ++ .num_resources = ARRAY_SIZE(cmx270_dm9k_resource), ++ .resource = cmx270_dm9k_resource, ++ .dev = { ++ .platform_data = &cmx270_dm9k_platdata, ++ } ++}; ++ ++/* audio device */ ++static struct platform_device cmx270_audio_device = { ++ .name = "pxa2xx-ac97", ++ .id = -1, ++}; ++ ++/* touchscreen controller */ ++static struct platform_device cmx270_ts_device = { ++ .name = "ucb1x00-ts", ++ .id = -1, ++}; ++ ++/* RTC */ ++static struct resource cmx270_v3020_resource[] = { ++ [0] = { ++ .start = RTC_PHYS_BASE, ++ .end = RTC_PHYS_BASE + 4, ++ .flags = IORESOURCE_MEM, ++ }, ++}; ++ ++struct v3020_platform_data cmx270_v3020_pdata = { ++ .leftshift = 16, ++}; ++ ++static struct platform_device cmx270_rtc_device = { ++ .name = "v3020", ++ .num_resources = ARRAY_SIZE(cmx270_v3020_resource), ++ .resource = cmx270_v3020_resource, ++ .id = -1, ++ .dev = { ++ .platform_data = &cmx270_v3020_pdata, ++ } ++}; ++ ++/* ++ * CM-X270 LEDs ++ */ ++static struct platform_device cmx270led_device = { ++ .name = "cm-x270-led", ++ .id = -1, ++}; ++ ++/* 2700G graphics */ ++static u64 fb_dma_mask = ~(u64)0; ++ ++static struct resource cmx270_2700G_resource[] = { ++ /* frame buffer memory including ODFB and External SDRAM */ ++ [0] = { ++ .start = MARATHON_PHYS, ++ .end = MARATHON_PHYS + 0x02000000, ++ .flags = IORESOURCE_MEM, ++ }, ++ /* Marathon registers */ ++ [1] = { ++ .start = MARATHON_PHYS + 0x03fe0000, ++ .end = MARATHON_PHYS + 0x03ffffff, ++ .flags = IORESOURCE_MEM, ++ }, ++}; ++ ++static unsigned long save_lcd_regs[10]; ++ ++static int cmx270_marathon_probe(struct fb_info *fb) ++{ ++ /* save PXA-270 pin settings before enabling 2700G */ ++ save_lcd_regs[0] = GPDR1; ++ save_lcd_regs[1] = GPDR2; ++ save_lcd_regs[2] = GAFR1_U; ++ save_lcd_regs[3] = GAFR2_L; ++ save_lcd_regs[4] = GAFR2_U; ++ ++ /* Disable PXA-270 on-chip controller driving pins */ ++ GPDR1 &= ~(0xfc000000); ++ GPDR2 &= ~(0x00c03fff); ++ GAFR1_U &= ~(0xfff00000); ++ GAFR2_L &= ~(0x0fffffff); ++ GAFR2_U &= ~(0x0000f000); ++ return 0; ++} ++ ++static int cmx270_marathon_remove(struct fb_info *fb) ++{ ++ GPDR1 = save_lcd_regs[0]; ++ GPDR2 = save_lcd_regs[1]; ++ GAFR1_U = save_lcd_regs[2]; ++ GAFR2_L = save_lcd_regs[3]; ++ GAFR2_U = save_lcd_regs[4]; ++ return 0; ++} ++ ++static struct mbxfb_platform_data cmx270_2700G_data = { ++ .xres = { ++ .min = 240, ++ .max = 1200, ++ .defval = 640, ++ }, ++ .yres = { ++ .min = 240, ++ .max = 1200, ++ .defval = 480, ++ }, ++ .bpp = { ++ .min = 16, ++ .max = 32, ++ .defval = 16, ++ }, ++ .memsize = 8*1024*1024, ++ .probe = cmx270_marathon_probe, ++ .remove = cmx270_marathon_remove, ++}; ++ ++static struct platform_device cmx270_2700G = { ++ .name = "mbx-fb", ++ .dev = { ++ .platform_data = &cmx270_2700G_data, ++ .dma_mask = &fb_dma_mask, ++ .coherent_dma_mask = 0xffffffff, ++ }, ++ .num_resources = ARRAY_SIZE(cmx270_2700G_resource), ++ .resource = cmx270_2700G_resource, ++ .id = -1, ++}; ++ ++/* platform devices */ ++static struct platform_device *platform_devices[] __initdata = { ++ &cmx270_device_dm9k, ++ &cmx270_audio_device, ++ &cmx270_rtc_device, ++ &cmx270_2700G, ++ &cmx270led_device, ++}; ++ ++#ifdef CONFIG_PCI ++/* ++ * Install handler for IT8152 IRQ. Yes, yes... we are way down the IRQ ++ * cascade which is not good for IRQ latency, but the hardware has been ++ * designed that way... ++ */ ++static inline void cmx270_irq(int irq, struct pt_regs *regs) ++{ ++ struct irq_desc *desc; ++ desc = irq_desc + irq; ++ desc_handle_irq(irq, desc); ++} ++ ++static void cmx270_irq_demux(unsigned int irq, struct irqdesc *desc, ++ struct pt_regs *regs) ++{ ++ unsigned long pdcnimr, ldcnimr; ++ int pdcnirr, ldcnir; ++ ++ /* clear our parent irq */ ++ GEDR(GPIO_IT8152_IRQ) = GPIO_bit(GPIO_IT8152_IRQ); ++ ++ /* read pending IRQs in the chip registers and clear them */ ++ pdcnirr = IT8152_INTC_PDCNIRR; ++ ldcnir = IT8152_INTC_LDCNIRR; ++ IT8152_INTC_PDCNIRR = ~pdcnirr; ++ IT8152_INTC_LDCNIRR = ~ldcnir; ++ ++ /* mask ITE irqs */ ++ pdcnimr = IT8152_INTC_PDCNIMR; ++ ldcnimr = IT8152_INTC_LDCNIMR; ++ IT8152_INTC_PDCNIMR = 0xffff; ++ IT8152_INTC_LDCNIMR = 0xffff; ++ ++ pdcnirr &= (PCISERR_BIT | H2PTADR_BIT | H2PMAR_BIT | ++ PCI_INTD_BIT | PCI_INTC_BIT | PCI_INTB_BIT | PCI_INTA_BIT | ++ USB_INT_BIT | CDMA_INT_BIT); ++ ++ ldcnir &= ITESER_BIT; ++ ++ IT8152_INTC_PDCNIRR = ~pdcnirr; ++ IT8152_INTC_LDCNIRR = ~ldcnir; ++ ++ /* are there interrupts pending ? */ ++ if( (pdcnirr | ldcnir) ) { ++ if (pdcnirr) { ++ if( pdcnirr & PCISERR_BIT ) ++ cmx270_irq(PCISERR, regs); ++ if( pdcnirr & H2PTADR_BIT ) ++ cmx270_irq(H2PTADR, regs); ++ if( pdcnirr & H2PMAR_BIT ) ++ cmx270_irq(H2PMAR, regs); ++ if( pdcnirr & PCI_INTA_BIT ) ++ cmx270_irq(PCI_INTA, regs); ++ if( pdcnirr & PCI_INTB_BIT ) ++ cmx270_irq(PCI_INTB, regs); ++ if( pdcnirr & PCI_INTC_BIT ) ++ cmx270_irq(PCI_INTC, regs); ++ if( pdcnirr & PCI_INTD_BIT ) ++ cmx270_irq(PCI_INTD, regs); ++ if( pdcnirr & USB_INT_BIT ) ++ cmx270_irq(USB_INT, regs); ++ if( pdcnirr & CDMA_INT_BIT ) ++ cmx270_irq(CDMA_INT, regs); ++ } ++ if(ldcnir) { ++ if( ldcnir & ITESER_BIT ) ++ cmx270_irq(IRQ_ITESER, regs); ++ } ++ } ++ ++ /* re-enable ITE interrupts */ ++ IT8152_INTC_PDCNIMR = pdcnimr; ++ IT8152_INTC_LDCNIMR = ldcnimr; ++} ++#else ++unsigned long it8152_base_address = CMX270_IT8152_VIRT; ++#endif ++ ++/* #define CMX270_FLASH_VIRT (CMX270_IDE104_VIRT + PXA_CS_SIZE - (8<<20)) */ ++/* Map PCI companion and IDE/General Purpose CS statically */ ++static struct map_desc cmx270_io_desc[] __initdata = { ++ [0] = { /* IDE/general purpose space */ ++ .virtual = CMX270_IDE104_VIRT, ++ .pfn = __phys_to_pfn(CMX270_IDE104_PHYS), ++ .length = PXA_CS_SIZE - (8<<20), ++ .type = MT_DEVICE ++ }, ++ [1] = { /* PCI bridge */ ++ .virtual = CMX270_IT8152_VIRT, ++ .pfn = __phys_to_pfn(CMX270_IT8152_PHYS), ++ .length = PXA_CS_SIZE, ++ .type = MT_DEVICE ++ }, ++}; ++ ++/* ++ Display definitions ++ keep these for backwards compatibility, although symbolic names (as ++ e.g. in lpd270.c) looks better ++ */ ++#define MTYPE_STN320x240 0 ++#define MTYPE_TFT640x480 1 ++#define MTYPE_CRT640x480 2 ++#define MTYPE_CRT800x600 3 ++#define MTYPE_TFT320x240 6 ++#define MTYPE_STN640x480 7 ++ ++static struct pxafb_mode_info generic_stn_320x240_mode = { ++ .pixclock = 76923, ++ .bpp = 8, ++ .xres = 320, ++ .yres = 240, ++ .hsync_len = 3, ++ .vsync_len = 2, ++ .left_margin = 3, ++ .upper_margin = 0, ++ .right_margin = 3, ++ .lower_margin = 0, ++ .sync = (FB_SYNC_HOR_HIGH_ACT | ++ FB_SYNC_VERT_HIGH_ACT), ++ .cmap_greyscale = 0, ++}; ++ ++static struct pxafb_mach_info generic_stn_320x240 = { ++ .modes = &generic_stn_320x240_mode, ++ .num_modes = 1, ++ .lccr0 = 0, ++ .lccr3 = (LCCR3_PixClkDiv(0x03) | ++ LCCR3_Acb(0xff) | ++ LCCR3_PCP), ++ .cmap_inverse = 0, ++ .cmap_static = 0, ++}; ++ ++static struct pxafb_mode_info generic_tft_640x480_mode = { ++ .pixclock = 38461, ++ .bpp = 8, ++ .xres = 640, ++ .yres = 480, ++ .hsync_len = 60, ++ .vsync_len = 2, ++ .left_margin = 70, ++ .upper_margin = 10, ++ .right_margin = 70, ++ .lower_margin = 5, ++ .sync = 0, ++ .cmap_greyscale = 0, ++}; ++ ++static struct pxafb_mach_info generic_tft_640x480 = { ++ .modes = &generic_tft_640x480_mode, ++ .num_modes = 1, ++ .lccr0 = (LCCR0_PAS), ++ .lccr3 = (LCCR3_PixClkDiv(0x01) | ++ LCCR3_Acb(0xff) | ++ LCCR3_PCP), ++ .cmap_inverse = 0, ++ .cmap_static = 0, ++}; ++ ++static struct pxafb_mode_info generic_crt_640x480_mode = { ++ .pixclock = 38461, ++ .bpp = 8, ++ .xres = 640, ++ .yres = 480, ++ .hsync_len = 63, ++ .vsync_len = 2, ++ .left_margin = 81, ++ .upper_margin = 33, ++ .right_margin = 16, ++ .lower_margin = 10, ++ .sync = (FB_SYNC_HOR_HIGH_ACT | ++ FB_SYNC_VERT_HIGH_ACT), ++ .cmap_greyscale = 0, ++}; ++ ++static struct pxafb_mach_info generic_crt_640x480 = { ++ .modes = &generic_crt_640x480_mode, ++ .num_modes = 1, ++ .lccr0 = (LCCR0_PAS), ++ .lccr3 = (LCCR3_PixClkDiv(0x01) | ++ LCCR3_Acb(0xff)), ++ .cmap_inverse = 0, ++ .cmap_static = 0, ++}; ++ ++static struct pxafb_mode_info generic_crt_800x600_mode = { ++ .pixclock = 28846, ++ .bpp = 8, ++ .xres = 800, ++ .yres = 600, ++ .hsync_len = 63, ++ .vsync_len = 2, ++ .left_margin = 26, ++ .upper_margin = 21, ++ .right_margin = 26, ++ .lower_margin = 11, ++ .sync = (FB_SYNC_HOR_HIGH_ACT | ++ FB_SYNC_VERT_HIGH_ACT), ++ .cmap_greyscale = 0, ++}; ++ ++static struct pxafb_mach_info generic_crt_800x600 = { ++ .modes = &generic_crt_800x600_mode, ++ .num_modes = 1, ++ .lccr0 = (LCCR0_PAS), ++ .lccr3 = (LCCR3_PixClkDiv(0x02) | ++ LCCR3_Acb(0xff)), ++ .cmap_inverse = 0, ++ .cmap_static = 0, ++}; ++ ++static struct pxafb_mode_info generic_tft_320x240_mode = { ++ .pixclock = 134615, ++ .bpp = 16, ++ .xres = 320, ++ .yres = 240, ++ .hsync_len = 63, ++ .vsync_len = 7, ++ .left_margin = 75, ++ .upper_margin = 0, ++ .right_margin = 15, ++ .lower_margin = 15, ++ .sync = 0, ++ .cmap_greyscale = 0, ++}; ++ ++static struct pxafb_mach_info generic_tft_320x240 = { ++ .modes = &generic_tft_320x240_mode, ++ .num_modes = 1, ++ .lccr0 = (LCCR0_PAS), ++ .lccr3 = (LCCR3_PixClkDiv(0x06) | ++ LCCR3_Acb(0xff) | ++ LCCR3_PCP), ++ .cmap_inverse = 0, ++ .cmap_static = 0, ++}; ++ ++static struct pxafb_mode_info generic_stn_640x480_mode = { ++ .pixclock = 57692, ++ .bpp = 8, ++ .xres = 640, ++ .yres = 480, ++ .hsync_len = 4, ++ .vsync_len = 2, ++ .left_margin = 10, ++ .upper_margin = 5, ++ .right_margin = 10, ++ .lower_margin = 5, ++ .sync = (FB_SYNC_HOR_HIGH_ACT | ++ FB_SYNC_VERT_HIGH_ACT), ++ .cmap_greyscale = 0, ++}; ++ ++static struct pxafb_mach_info generic_stn_640x480 = { ++ .modes = &generic_stn_640x480_mode, ++ .num_modes = 1, ++ .lccr0 = 0, ++ .lccr3 = (LCCR3_PixClkDiv(0x02) | ++ LCCR3_Acb(0xff)), ++ .cmap_inverse = 0, ++ .cmap_static = 0, ++}; ++ ++static struct pxafb_mach_info *cmx270_display = &generic_crt_640x480; ++ ++static int __init cmx270_set_display(char *str) ++{ ++ int disp_type = simple_strtol(str, NULL, 0); ++ switch (disp_type) { ++ case MTYPE_STN320x240: ++ cmx270_display = &generic_stn_320x240; ++ break; ++ case MTYPE_TFT640x480: ++ cmx270_display = &generic_tft_640x480; ++ break; ++ case MTYPE_CRT640x480: ++ cmx270_display = &generic_crt_640x480; ++ break; ++ case MTYPE_CRT800x600: ++ cmx270_display = &generic_crt_800x600; ++ break; ++ case MTYPE_TFT320x240: ++ cmx270_display = &generic_tft_320x240; ++ break; ++ case MTYPE_STN640x480: ++ cmx270_display = &generic_stn_640x480; ++ break; ++ default: /* fallback to CRT 640x480 */ ++ cmx270_display = &generic_crt_640x480; ++ break; ++ } ++ return 1; ++} ++ ++__setup("monitor=", cmx270_set_display); ++ ++/* PXA27x OHCI controller setup */ ++static int cmx270_ohci_init(struct device *dev) ++{ ++ /* Set the Power Control Polarity Low */ ++ UHCHR = (UHCHR | UHCHR_PCPL) & ++ ~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSE); ++ ++ return 0; ++} ++ ++static struct pxaohci_platform_data cmx270_ohci_platform_data = { ++ .port_mode = PMM_PERPORT_MODE, ++ .init = cmx270_ohci_init, ++}; ++ ++ ++static int cmx270_mci_init(struct device *dev, irq_handler_t cmx270_detect_int, void *data) ++{ ++ int err; ++ ++ /* ++ * setup GPIO for PXA27x MMC controller ++ */ ++ pxa_gpio_mode(GPIO32_MMCCLK_MD); ++ pxa_gpio_mode(GPIO112_MMCCMD_MD); ++ pxa_gpio_mode(GPIO92_MMCDAT0_MD); ++ pxa_gpio_mode(GPIO109_MMCDAT1_MD); ++ pxa_gpio_mode(GPIO110_MMCDAT2_MD); ++ pxa_gpio_mode(GPIO111_MMCDAT3_MD); ++ ++ /* SB-X270 uses GPIO105 as SD power enable */ ++ pxa_gpio_mode(105 | GPIO_OUT); ++ ++ /* card detect IRQ on GPIO 83 */ ++ pxa_gpio_mode(IRQ_TO_GPIO(CMX270_MMC_IRQ)); ++ set_irq_type(CMX270_MMC_IRQ, IRQT_FALLING); ++ ++ err = request_irq(CMX270_MMC_IRQ, cmx270_detect_int, SA_INTERRUPT, ++ "MMC card detect", data); ++ if (err) { ++ printk(KERN_ERR "cmx270_mci_init: MMC/SD: can't request MMC card detect IRQ\n"); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++static void cmx270_mci_setpower(struct device *dev, unsigned int vdd) ++{ ++ struct pxamci_platform_data* p_d = dev->platform_data; ++ ++ if (( 1 << vdd) & p_d->ocr_mask) { ++ printk(KERN_DEBUG "%s: on\n", __FUNCTION__); ++ GPCR(105) = GPIO_bit(105); ++ } else { ++ GPSR(105) = GPIO_bit(105); ++ printk(KERN_DEBUG "%s: off\n", __FUNCTION__); ++ } ++} ++ ++static void cmx270_mci_exit(struct device *dev, void *data) ++{ ++ free_irq(CMX270_MMC_IRQ, data); ++} ++ ++static struct pxamci_platform_data cmx270_mci_platform_data = { ++ .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, ++ .init = cmx270_mci_init, ++ .setpower = cmx270_mci_setpower, ++ .exit = cmx270_mci_exit, ++}; ++ ++#ifdef CONFIG_PM ++/* extern struct subsystem power_subsys; */ ++static unsigned long sleep_save_ite[10]; ++static unsigned long sleep_save_msc[10]; ++ ++static int cmx270_suspend(struct sys_device *dev, pm_message_t state) ++{ ++#ifdef CONFIG_PCI ++ /* save ITE state */ ++ sleep_save_ite[0] = IT8152_INTC_PDCNIMR; ++ sleep_save_ite[1] = IT8152_INTC_LPCNIMR; ++ sleep_save_ite[2] = IT8152_INTC_LPNIAR; ++ ++ /* Clear ITE IRQ's */ ++ IT8152_INTC_PDCNIRR = 0; ++ IT8152_INTC_LPCNIRR = 0; ++#endif ++ ++ /* save MSC registers */ ++ sleep_save_msc[0] = MSC0; ++ sleep_save_msc[1] = MSC1; ++ sleep_save_msc[2] = MSC2; ++ ++ /* setup power saving mode registers */ ++ PCFR = 0x0; ++ PSLR = 0xff400000; ++ PMCR = 0x00000005; ++ PWER = 0x80000000; ++ PFER = 0x00000000; ++ PRER = 0x00000000; ++ PGSR0 = 0xC0018800; ++ PGSR1 = 0x004F0002; ++ PGSR2 = 0x6021C000; ++ PGSR3 = 0x00020000; ++ ++ return 0; ++} ++ ++static int cmx270_resume(struct sys_device *dev) ++{ ++#ifdef CONFIG_PCI ++ /* restore IT8152 state */ ++ IT8152_INTC_PDCNIMR = sleep_save_ite[0]; ++ IT8152_INTC_LPCNIMR = sleep_save_ite[1]; ++ IT8152_INTC_LPNIAR = sleep_save_ite[2]; ++#endif ++ ++ /* restore MSC registers */ ++ MSC0 = sleep_save_msc[0]; ++ MSC1 = sleep_save_msc[1]; ++ MSC2 = sleep_save_msc[2]; ++ ++ return 0; ++} ++ ++static struct sysdev_class cmx270_pm_sysclass = { ++ set_kset_name("pm"), ++ .resume = cmx270_resume, ++ .suspend = cmx270_suspend, ++}; ++ ++static struct sys_device cmx270_pm_device = { ++ .cls = &cmx270_pm_sysclass, ++}; ++ ++static int __init cmx270_pm_init(void) ++{ ++ int error; ++ error = sysdev_class_register(&cmx270_pm_sysclass); ++ if (error == 0) ++ error = sysdev_register(&cmx270_pm_device); ++ return error; ++} ++#else ++static int __init cmx270_pm_init(void) { return 0; } ++#endif ++ ++static void __init cmx270_init(void) ++{ ++ cmx270_pm_init(); ++ ++ set_pxa_fb_info(cmx270_display); ++ ++ /* register CM-X270 platform devices */ ++ platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); ++ ++ /* set MCI and OHCI platform parameters */ ++ pxa_set_mci_info(&cmx270_mci_platform_data); ++ pxa_set_ohci_info(&cmx270_ohci_platform_data); ++ ++ /* This enables the STUART */ ++ pxa_gpio_mode(GPIO46_STRXD_MD); ++ pxa_gpio_mode(GPIO47_STTXD_MD); ++ ++ /* This enables the BTUART */ ++ pxa_gpio_mode(GPIO42_BTRXD_MD); ++ pxa_gpio_mode(GPIO43_BTTXD_MD); ++ pxa_gpio_mode(GPIO44_BTCTS_MD); ++ pxa_gpio_mode(GPIO45_BTRTS_MD); ++} ++ ++#ifdef CONFIG_PCI ++static void cmx270_mask_irq(unsigned int irq) ++{ ++ switch(irq) { ++ case IT8152_IRQ(0): ++ IT8152_INTC_PDCNIMR |= PCISERR_BIT; ++ break; ++ case IT8152_IRQ(1): ++ IT8152_INTC_PDCNIMR |= H2PTADR_BIT; ++ break; ++ case IT8152_IRQ(2): ++ IT8152_INTC_PDCNIMR |= H2PMAR_BIT; ++ break; ++ case IT8152_IRQ(3): ++ IT8152_INTC_PDCNIMR |= PCI_INTA_BIT; ++ break; ++ case IT8152_IRQ(4): ++ IT8152_INTC_PDCNIMR |= PCI_INTB_BIT; ++ break; ++ case IT8152_IRQ(5): ++ IT8152_INTC_PDCNIMR |= PCI_INTC_BIT; ++ break; ++ case IT8152_IRQ(6): ++ IT8152_INTC_PDCNIMR |= PCI_INTD_BIT; ++ break; ++ case IT8152_IRQ(7): ++ IT8152_INTC_PDCNIMR |= USB_INT_BIT; ++ break; ++ case IT8152_IRQ(9): ++ IT8152_INTC_PDCNIMR |= CDMA_INT_BIT; ++ break; ++ case IT8152_IRQ(10): ++ IT8152_INTC_LDCNIMR |= ITESER_BIT; ++ break; ++ } ++} ++ ++static void cmx270_unmask_irq(unsigned int irq) ++{ ++ switch(irq) { ++ case IT8152_IRQ(0): ++ IT8152_INTC_PDCNIMR &= (~PCISERR_BIT); ++ break; ++ case IT8152_IRQ(1): ++ IT8152_INTC_PDCNIMR &= (~H2PTADR_BIT); ++ break; ++ case IT8152_IRQ(2): ++ IT8152_INTC_PDCNIMR &= (~H2PMAR_BIT); ++ break; ++ case IT8152_IRQ(3): ++ IT8152_INTC_PDCNIMR &= (~PCI_INTA_BIT); ++ break; ++ case IT8152_IRQ(4): ++ IT8152_INTC_PDCNIMR &= (~PCI_INTB_BIT); ++ break; ++ case IT8152_IRQ(5): ++ IT8152_INTC_PDCNIMR &= (~PCI_INTC_BIT); ++ break; ++ case IT8152_IRQ(6): ++ IT8152_INTC_PDCNIMR &= (~PCI_INTD_BIT); ++ break; ++ case IT8152_IRQ(7): ++ IT8152_INTC_PDCNIMR &= (~USB_INT_BIT); ++ break; ++ case IT8152_IRQ(9): ++ IT8152_INTC_PDCNIMR &= (~CDMA_INT_BIT); ++ break; ++ case IT8152_IRQ(10): ++ IT8152_INTC_LDCNIMR &= (~ITESER_BIT); ++ break; ++ } ++} ++ ++static struct irq_chip cmx270_irq_chip = { ++ .ack = cmx270_mask_irq, ++ .mask = cmx270_mask_irq, ++ .unmask = cmx270_unmask_irq, ++}; ++#endif ++ ++static void __init cmx270_init_irq(void) ++{ ++ int irq; ++ ++ pxa27x_init_irq(); ++ ++ IT8152_INTC_PDCNIMR = 0xffff; ++ ++#ifdef CONFIG_PCI ++ /* Disable and clear IRQ's for ITE8152 */ ++ IT8152_INTC_PDCNIMR = 0xffff; ++ IT8152_INTC_PDCNIRR = 0; ++ IT8152_INTC_LPCNIMR = 0xffff; ++ IT8152_INTC_LPCNIRR = 0; ++ IT8152_INTC_LDCNIMR = 0xffff; ++ IT8152_INTC_LDCNIRR = 0; ++ ++ for(irq = IT8152_IRQ(0); irq <= IT8152_IRQ_MAX; irq++) { ++ set_irq_chip(irq, &cmx270_irq_chip); ++ set_irq_handler(irq, handle_level_irq); ++ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); ++ } ++ ++ /* INTC signal from IT8152 is connected to GPIO0 */ ++ pxa_gpio_mode(IRQ_GPIO_IT8152_IRQ); ++ set_irq_chained_handler(IRQ_GPIO_IT8152_IRQ, cmx270_irq_demux); ++ set_irq_type(IRQ_GPIO_IT8152_IRQ, IRQT_RISING); ++#endif ++ ++ /* Setup interrupt for dm9000 */ ++ pxa_gpio_mode(IRQ_TO_GPIO(CMX270_ETHIRQ)); ++ set_irq_type(CMX270_ETHIRQ, IRQT_RISING); ++ ++ /* Setup interrupt for 2700G */ ++ pxa_gpio_mode(IRQ_TO_GPIO(CMX270_GFXIRQ)); ++ set_irq_type(CMX270_GFXIRQ, IRQT_FALLING); ++} ++ ++static void __init cmx270_map_io(void) ++{ ++ pxa_map_io(); ++ iotable_init(cmx270_io_desc, ARRAY_SIZE(cmx270_io_desc)); ++} ++ ++ ++MACHINE_START(ARMCORE, "Compulab CM-x270") ++ .boot_params = 0xa0000100, ++ .phys_io = 0x40000000, ++ .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, ++ .map_io = cmx270_map_io, ++ .init_irq = cmx270_init_irq, ++ .timer = &pxa_timer, ++ .init_machine = cmx270_init, ++MACHINE_END +diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig +index 4468cb3..02b04e2 100644 +--- a/drivers/leds/Kconfig ++++ b/drivers/leds/Kconfig +@@ -87,6 +87,12 @@ config LEDS_H1940 + help + This option enables support for the LEDs on the h1940. + ++config LEDS_CM_X270 ++ tristate "LED Support for the CM-X270 LEDs" ++ depends on LEDS_CLASS && MACH_ARMCORE ++ help ++ This option enables support for the CM-X270 LEDs. ++ + config LEDS_COBALT + tristate "LED Support for Cobalt Server front LED" + depends on LEDS_CLASS && MIPS_COBALT +diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile +index f8995c9..12a860c 100644 +--- a/drivers/leds/Makefile ++++ b/drivers/leds/Makefile +@@ -17,6 +17,7 @@ obj-$(CONFIG_LEDS_WRAP) += leds-wrap.o + obj-$(CONFIG_LEDS_H1940) += leds-h1940.o + obj-$(CONFIG_LEDS_COBALT) += leds-cobalt.o + obj-$(CONFIG_LEDS_GPIO) += leds-gpio.o ++obj-$(CONFIG_LEDS_CM_X270) += leds-cm-x270.o + + # LED Triggers + obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o +diff --git a/drivers/leds/leds-cm-x270.c b/drivers/leds/leds-cm-x270.c +new file mode 100644 +index 0000000..63b7e9e +--- /dev/null ++++ b/drivers/leds/leds-cm-x270.c +@@ -0,0 +1,126 @@ ++/* ++ * drivers/leds/leds-cm-x270.c ++ * ++ * Copyright 2007 CompuLab Ltd. ++ * Author: Mike Rapoport <mike@compulab.co.il> ++ * ++ * Based on leds-corgi.c ++ * Author: Richard Purdie <rpurdie@openedhand.com> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ */ ++ ++#include <linux/kernel.h> ++#include <linux/init.h> ++#include <linux/platform_device.h> ++#include <linux/leds.h> ++ ++#include <asm/arch/hardware.h> ++#include <asm/arch/pxa-regs.h> ++ ++#define GPIO_RED_LED (93) ++#define GPIO_GREEN_LED (94) ++ ++#define CMX270_RED_ON() GPCR(GPIO_RED_LED) = GPIO_bit(GPIO_RED_LED) ++#define CMX270_RED_OFF() GPSR(GPIO_RED_LED) = GPIO_bit(GPIO_RED_LED) ++#define CMX270_GREEN_ON() GPCR(GPIO_GREEN_LED) = GPIO_bit(GPIO_GREEN_LED) ++#define CMX270_GREEN_OFF() GPSR(GPIO_GREEN_LED) = GPIO_bit(GPIO_GREEN_LED) ++ ++ ++static void cmx270_red_set(struct led_classdev *led_cdev, enum led_brightness value) ++{ ++ if (value) ++ CMX270_RED_ON(); ++ else ++ CMX270_RED_OFF(); ++} ++ ++static void cmx270_green_set(struct led_classdev *led_cdev, enum led_brightness value) ++{ ++ if (value) ++ CMX270_GREEN_ON(); ++ else ++ CMX270_GREEN_OFF(); ++} ++ ++static struct led_classdev cmx270_red_led = { ++ .name = "cm-x270:red", ++ .default_trigger = "nand-disk", ++ .brightness_set = cmx270_red_set, ++}; ++ ++static struct led_classdev cmx270_green_led = { ++ .name = "cm-x270:green", ++ .default_trigger = "heartbeat", ++ .brightness_set = cmx270_green_set, ++}; ++ ++#ifdef CONFIG_PM ++static int cmx270led_suspend(struct platform_device *dev, pm_message_t state) ++{ ++ led_classdev_suspend(&cmx270_red_led); ++ led_classdev_suspend(&cmx270_green_led); ++ return 0; ++} ++ ++static int cmx270led_resume(struct platform_device *dev) ++{ ++ led_classdev_resume(&cmx270_red_led); ++ led_classdev_resume(&cmx270_green_led); ++ return 0; ++} ++#endif ++ ++static int cmx270led_probe(struct platform_device *pdev) ++{ ++ int ret; ++ ++ ret = led_classdev_register(&pdev->dev, &cmx270_red_led); ++ if (ret < 0) ++ return ret; ++ ++ ret = led_classdev_register(&pdev->dev, &cmx270_green_led); ++ if (ret < 0) ++ led_classdev_unregister(&cmx270_red_led); ++ ++ return ret; ++} ++ ++static int cmx270led_remove(struct platform_device *pdev) ++{ ++ led_classdev_unregister(&cmx270_red_led); ++ led_classdev_unregister(&cmx270_green_led); ++ return 0; ++} ++ ++static struct platform_driver cmx270led_driver = { ++ .probe = cmx270led_probe, ++ .remove = cmx270led_remove, ++#ifdef CONFIG_PM ++ .suspend = cmx270led_suspend, ++ .resume = cmx270led_resume, ++#endif ++ .driver = { ++ .name = "cm-x270-led", ++ }, ++}; ++ ++static int __init cmx270led_init(void) ++{ ++ return platform_driver_register(&cmx270led_driver); ++} ++ ++static void __exit cmx270led_exit(void) ++{ ++ platform_driver_unregister(&cmx270led_driver); ++} ++ ++module_init(cmx270led_init); ++module_exit(cmx270led_exit); ++ ++MODULE_AUTHOR("Richard Purdie <rpurdie@openedhand.com>"); ++MODULE_DESCRIPTION("Corgi LED driver"); ++MODULE_LICENSE("GPL"); +diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig +index c551925..b34f875 100644 +--- a/drivers/net/Kconfig ++++ b/drivers/net/Kconfig +@@ -940,6 +940,14 @@ config DM9000 + <file:Documentation/networking/net-modules.txt>. The module will be + called dm9000. + ++config DM9000_NOEPROM ++ bool "DM9000 without EEPROM attached" ++ depends on DM9000 ++ ---help--- ++ Select this option if you have DM9000 chipset without EEPROM ++ containing the MAC address. In this case MAC address should ++ be set either by the bootloader or using ifconfig ++ + config SMC911X + tristate "SMSC LAN911[5678] support" + select CRC32 +diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c +index 738aa59..2371c6b 100644 +--- a/drivers/net/dm9000.c ++++ b/drivers/net/dm9000.c +@@ -577,6 +577,7 @@ dm9000_probe(struct platform_device *pdev) + db->mii.mdio_read = dm9000_phy_read; + db->mii.mdio_write = dm9000_phy_write; + ++#ifndef CONFIG_DM9000_NOEPROM + /* Read SROM content */ + for (i = 0; i < 64; i++) + ((u16 *) db->srom)[i] = read_srom_word(db, i); +@@ -584,6 +585,11 @@ dm9000_probe(struct platform_device *pdev) + /* Set Node Address */ + for (i = 0; i < 6; i++) + ndev->dev_addr[i] = db->srom[i]; ++#else ++ /* The Node Address was set by bootloader */ ++ for (i=0; i<6; i++) ++ ndev->dev_addr[i] = ior(db, 0x10+i); ++#endif + + if (!is_valid_ether_addr(ndev->dev_addr)) { + /* try reading from mac */ +diff --git a/include/asm-arm/arch-pxa/cm-x270.h b/include/asm-arm/arch-pxa/cm-x270.h +new file mode 100644 +index 0000000..24613a5 +--- /dev/null ++++ b/include/asm-arm/arch-pxa/cm-x270.h +@@ -0,0 +1,71 @@ ++/* ++ * linux/include/asm/arch-pxa/armcore.h ++ * ++ * Compulab Ltd., 2003 ++ * ++ * ARMCore registers ++ */ ++ ++ ++#define CMX270_CS1_PHYS (PXA_CS1_PHYS) ++#define MARATHON_PHYS (PXA_CS2_PHYS) ++#define CMX270_IDE104_PHYS (PXA_CS3_PHYS) ++#define CMX270_IT8152_PHYS (PXA_CS4_PHYS) ++ ++#define PXA_CS_SIZE (64*1024*1024) ++ ++/* Virtual map */ ++ ++#define CMX270_VIRT_BASE (0xe8000000) ++ ++#define CMX270_IT8152_VIRT (CMX270_VIRT_BASE) ++#define CMX270_IDE104_VIRT (CMX270_IT8152_VIRT + PXA_CS_SIZE) ++ ++ ++/* GPIO related definitions */ ++#define GPIO_IT8152_IRQ (22) ++#define GPIO_RED_LED (93) ++#define GPIO_GREEN_LED (94) ++ ++ ++#define IRQ_GPIO_IT8152_IRQ IRQ_GPIO(GPIO_IT8152_IRQ) ++#define PME_IRQ IRQ_GPIO(0) ++#define CMX270_IDE_IRQ IRQ_GPIO(100) ++#define CMX270_GPIRQ1 IRQ_GPIO(101) ++#define CMX270_TOUCHIRQ IRQ_GPIO(96) ++#define CMX270_ETHIRQ IRQ_GPIO(10) ++#define CMX270_GFXIRQ IRQ_GPIO(95) ++#define CMX270_NANDIRQ IRQ_GPIO(89) ++#define CMX270_MMC_IRQ IRQ_GPIO(83) ++ ++/* LED macros */ ++#define CMX270_RED_ON() GPCR(GPIO_RED_LED) = GPIO_bit(GPIO_RED_LED) ++#define CMX270_RED_OFF() GPSR(GPIO_RED_LED) = GPIO_bit(GPIO_RED_LED) ++#define CMX270_GREEN_ON() GPCR(GPIO_GREEN_LED) = GPIO_bit(GPIO_GREEN_LED) ++#define CMX270_GREEN_OFF() GPSR(GPIO_GREEN_LED) = GPIO_bit(GPIO_GREEN_LED) ++ ++/* PCMCIA related definitions */ ++#define PCC_DETECT(x) (GPLR(84 - (x)) & GPIO_bit(84 - (x))) ++#define PCC_READY(x) (GPLR(82 - (x)) & GPIO_bit(81 - (x))) ++ ++#define PCMCIA_S0_CD_VALID IRQ_GPIO(84) ++#define PCMCIA_S0_CD_VALID_EDGE GPIO_BOTH_EDGES ++ ++#define PCMCIA_S1_CD_VALID IRQ_GPIO(83) ++#define PCMCIA_S1_CD_VALID_EDGE GPIO_BOTH_EDGES ++ ++#define PCMCIA_S0_RDYINT IRQ_GPIO(82) ++#define PCMCIA_S1_RDYINT IRQ_GPIO(81) ++ ++#define PCMCIA_RESET_GPIO 53 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/include/asm-arm/arch-pxa/hardware.h b/include/asm-arm/arch-pxa/hardware.h +index 3861217..beb240e 100644 +--- a/include/asm-arm/arch-pxa/hardware.h ++++ b/include/asm-arm/arch-pxa/hardware.h +@@ -126,4 +126,15 @@ extern unsigned int get_lcdclk_frequency_10khz(void); + + #endif + ++#if defined(CONFIG_MACH_ARMCORE) && defined(CONFIG_PCI) ++#define HAVE_ARCH_PCI_SET_DMA_MASK ++#ifndef __ASSEMBLY__ ++extern unsigned long armcore_pcibios_min_io; ++extern unsigned long armcore_pcibios_min_mem; ++#endif ++#define PCIBIOS_MIN_IO (armcore_pcibios_min_io) ++#define PCIBIOS_MIN_MEM (armcore_pcibios_min_mem) ++#define pcibios_assign_all_busses() 1 ++#endif ++ + #endif /* _ASM_ARCH_HARDWARE_H */ +diff --git a/include/asm-arm/arch-pxa/irqs.h b/include/asm-arm/arch-pxa/irqs.h +index a07fe0f..efb3d42 100644 +--- a/include/asm-arm/arch-pxa/irqs.h ++++ b/include/asm-arm/arch-pxa/irqs.h +@@ -216,3 +216,23 @@ + #define IRQ_LOCOMO_GPIO_BASE (IRQ_BOARD_START + 1) + #define IRQ_LOCOMO_LT_BASE (IRQ_BOARD_START + 2) + #define IRQ_LOCOMO_SPI_BASE (IRQ_BOARD_START + 3) ++ ++/* ITE8152 irqs on CM-x2xx */ ++#ifdef CONFIG_MACH_ARMCORE ++#define IT8152_IRQ(x) (IRQ_BOARD_START + (x)) ++#define PCISERR IT8152_IRQ(0) ++#define H2PTADR IT8152_IRQ(1) ++#define H2PMAR IT8152_IRQ(2) ++#define PCI_INTA IT8152_IRQ(3) ++#define PCI_INTB IT8152_IRQ(4) ++#define PCI_INTC IT8152_IRQ(5) ++#define PCI_INTD IT8152_IRQ(6) ++#define USB_INT IT8152_IRQ(7) ++#define AUDIO_INT IT8152_IRQ(8) ++#define CDMA_INT IT8152_IRQ(9) ++#define IRQ_ITESER IT8152_IRQ(10) ++#define IT8152_IRQ_MAX IT8152_IRQ(10) ++ ++#undef NR_IRQS ++#define NR_IRQS IT8152_IRQ_MAX+1 ++#endif +diff --git a/include/asm-arm/memory.h b/include/asm-arm/memory.h +index d9bfb39..83db3cb 100644 +--- a/include/asm-arm/memory.h ++++ b/include/asm-arm/memory.h +@@ -141,6 +141,16 @@ + * allocations. This must be the smallest DMA mask in the system, + * so a successful GFP_DMA allocation will always satisfy this. + */ ++ ++#ifdef CONFIG_PCI_HOST_ITE8152 ++void it8152_adjust_zones(int node, unsigned long *size, unsigned long *holes); ++ ++#define arch_adjust_zones(node, size, holes) \ ++ it8152_adjust_zones(node, size, holes) ++ ++#define ISA_DMA_THRESHOLD (PHYS_OFFSET + SZ_64M - 1) ++#endif ++ + #ifndef ISA_DMA_THRESHOLD + #define ISA_DMA_THRESHOLD (0xffffffffULL) + #endif +-- +1.5.2.5 + diff --git a/packages/linux/linux-2.6.23/cm-x270/0002-cm-x270-match-type.patch b/packages/linux/linux-2.6.23/cm-x270/0002-cm-x270-match-type.patch new file mode 100644 index 0000000000..981cef9207 --- /dev/null +++ b/packages/linux/linux-2.6.23/cm-x270/0002-cm-x270-match-type.patch @@ -0,0 +1,25 @@ +From d4e9090a5ff36090402d0c336804f061f391f5de Mon Sep 17 00:00:00 2001 +From: Cliff Brake <cbrake@happy.dev.bec-systems.com> +Date: Fri, 20 Jul 2007 18:58:27 -0400 +Subject: [PATCH] cm-x270-match-type + +--- + arch/arm/boot/compressed/head-xscale.S | 5 +++++ + 1 files changed, 5 insertions(+), 0 deletions(-) + +diff --git a/arch/arm/boot/compressed/head-xscale.S b/arch/arm/boot/compressed/head-xscale.S +index 236bbe5..7ae9de1 100644 +--- a/arch/arm/boot/compressed/head-xscale.S ++++ b/arch/arm/boot/compressed/head-xscale.S +@@ -48,3 +48,8 @@ __XScale_start: + str r1, [r0, #0x18] + #endif + ++#if defined(CONFIG_MACH_ARMCORE) ++ mov r7, #(MACH_TYPE_ARMCORE & 0xFF00) ++ add r7, r7, #(MACH_TYPE_ARMCORE & 0xFF) ++#endif ++ +-- +1.5.2.5 + diff --git a/packages/linux/linux-2.6.23/cm-x270/0003-cm-x270-ide.patch b/packages/linux/linux-2.6.23/cm-x270/0003-cm-x270-ide.patch new file mode 100644 index 0000000000..5c5c39499c --- /dev/null +++ b/packages/linux/linux-2.6.23/cm-x270/0003-cm-x270-ide.patch @@ -0,0 +1,186 @@ +From c07ab3ce1c18437c480c3cec96da210434629c74 Mon Sep 17 00:00:00 2001 +From: Cliff Brake <cbrake@happy.dev.bec-systems.com> +Date: Fri, 20 Jul 2007 18:59:39 -0400 +Subject: [PATCH] cm-x270-ide + +--- + drivers/ide/Kconfig | 8 +++ + drivers/ide/arm/Makefile | 1 + + drivers/ide/arm/cm-x270-ide.c | 135 +++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 144 insertions(+), 0 deletions(-) + create mode 100644 drivers/ide/arm/cm-x270-ide.c + +diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig +index 4200251..ab3a29e 100644 +--- a/drivers/ide/Kconfig ++++ b/drivers/ide/Kconfig +@@ -866,6 +866,14 @@ config BLK_DEV_IDE_BAST + Say Y here if you want to support the onboard IDE channels on the + Simtec BAST or the Thorcom VR1000 + ++config BLK_DEV_IDE_CM_X270 ++ tristate "CompuLab CM-X270 IDE support" ++ depends on ARM && (MACH_ARMCORE) ++ help ++ Say Y here if you want to support the onboard IDE channels on the ++ CompuLab CM-X270 module ++ ++ + config BLK_DEV_GAYLE + bool "Amiga Gayle IDE interface support" + depends on AMIGA +diff --git a/drivers/ide/arm/Makefile b/drivers/ide/arm/Makefile +index 6a78f07..e5cadb7 100644 +--- a/drivers/ide/arm/Makefile ++++ b/drivers/ide/arm/Makefile +@@ -2,5 +2,6 @@ + obj-$(CONFIG_BLK_DEV_IDE_ICSIDE) += icside.o + obj-$(CONFIG_BLK_DEV_IDE_RAPIDE) += rapide.o + obj-$(CONFIG_BLK_DEV_IDE_BAST) += bast-ide.o ++obj-$(CONFIG_BLK_DEV_IDE_CM_X270) += cm-x270-ide.o + + EXTRA_CFLAGS := -Idrivers/ide +diff --git a/drivers/ide/arm/cm-x270-ide.c b/drivers/ide/arm/cm-x270-ide.c +new file mode 100644 +index 0000000..a8b15aa +--- /dev/null ++++ b/drivers/ide/arm/cm-x270-ide.c +@@ -0,0 +1,135 @@ ++/* linux/drivers/ide/arm/cm-x270-ide.c ++ * ++ * Copyright (c) 2006 CompuLab, Ltd ++ * Mike Rapoport <mike@compulab.co.il> ++ * ++ * Based on linux/drivers/ide/arm/bast-ide.c ++ * Copyright (c) 2003-2004 Simtec Electronics ++ * Ben Dooks <ben@simtec.co.uk> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ */ ++ ++#include <linux/module.h> ++#include <linux/errno.h> ++#include <linux/ide.h> ++#include <linux/init.h> ++#include <linux/irq.h> ++ ++#include <asm/mach-types.h> ++ ++#include <asm/io.h> ++#include <asm/arch/pxa-regs.h> ++#include <asm/arch/cm-x270.h> ++ ++#define CMX270_SB270_IDECS0_VIRT (CMX270_IDE104_VIRT + (1<<24) + (1<<25)) ++#define CMX270_SB270_IDECS1_VIRT (CMX270_IDE104_VIRT + (1<<25)) ++#define CMX270_ATX_IDECS0_VIRT (CMX270_IDE104_VIRT + (1<<25)) ++#define CMX270_ATX_IDECS1_VIRT (CMX270_IDE104_VIRT + (1<<25) + (1<<22)) ++ ++/* list of registered interfaces */ ++static ide_hwif_t *ifs[1]; ++ ++static int __init ++cmx270_ide_register(unsigned int base, unsigned int aux, int irq, ++ ide_hwif_t **hwif) ++{ ++ hw_regs_t hw; ++ ++ memset(&hw, 0, sizeof(hw)); ++ ++ if(!base || !aux) return -EINVAL; ++ ++ printk(KERN_DEBUG "%s: base = %08x, aux = %08x\n", __FUNCTION__, ++ base, aux); ++ ++ /* Different mappings for local bus IDE and PCMCIA IDE */ ++ if(base == CMX270_SB270_IDECS0_VIRT) { ++ hw.io_ports[IDE_DATA_OFFSET] = base + 0; ++ hw.io_ports[IDE_ERROR_OFFSET] = base + (0x1<<3); ++ hw.io_ports[IDE_NSECTOR_OFFSET]= base + (0x2<<3); ++ hw.io_ports[IDE_SECTOR_OFFSET]= base + (0x3<<3); ++ hw.io_ports[IDE_LCYL_OFFSET]= base + (0x4<<3); ++ hw.io_ports[IDE_HCYL_OFFSET]= base + (0x5<<3); ++ hw.io_ports[IDE_SELECT_OFFSET]= base + (0x6<<3); ++ hw.io_ports[IDE_STATUS_OFFSET]= base + (0x7<<3); ++ hw.io_ports[IDE_CONTROL_OFFSET] = aux+(0x6<<3); ++ } ++ else if (base == CMX270_ATX_IDECS0_VIRT) { /* atx base */ ++ hw.io_ports[IDE_DATA_OFFSET] = base + 0; ++ hw.io_ports[IDE_ERROR_OFFSET] = base + 8; ++ hw.io_ports[IDE_NSECTOR_OFFSET]= base + 2; ++ hw.io_ports[IDE_SECTOR_OFFSET]= base + 10; ++ hw.io_ports[IDE_LCYL_OFFSET]= base + 4; ++ hw.io_ports[IDE_HCYL_OFFSET]= base + 12; ++ hw.io_ports[IDE_SELECT_OFFSET]= base + 6; //6; ++ hw.io_ports[IDE_STATUS_OFFSET]= base + 14; ++ hw.io_ports[IDE_CONTROL_OFFSET] = (aux+0x6); ++ } else { ++ printk(KERN_DEBUG "%s: registering wrong IDE i/f\n", __FUNCTION__); ++ hw.io_ports[IDE_DATA_OFFSET] = base + 8; ++ hw.io_ports[IDE_ERROR_OFFSET] = base + 13; ++ hw.io_ports[IDE_NSECTOR_OFFSET] = base + 2; ++ hw.io_ports[IDE_SECTOR_OFFSET] = base + 3; ++ hw.io_ports[IDE_LCYL_OFFSET] = base + 4; ++ hw.io_ports[IDE_HCYL_OFFSET] = base + 5; ++ hw.io_ports[IDE_SELECT_OFFSET] = base + 6; ++ hw.io_ports[IDE_STATUS_OFFSET] = base + 7; ++ hw.io_ports[IDE_CONTROL_OFFSET] = aux; ++ } ++ ++ hw.irq = irq; ++ ++ return ide_register_hw(&hw, hwif); ++} ++ ++static int __init cmx270_ide_init(void) ++{ ++ int retval = 0; ++ ++ if (!(machine_is_armcore())) ++ goto out; ++ ++ printk("CM-X270: initializing IDE interface\n"); ++ ++ MSC1 = 0x7ffc7ff4; ++ ++ /* Interrupts on rising edge: lines are inverted before they get to ++ the PXA */ ++ pxa_gpio_mode(IRQ_TO_GPIO(CMX270_IDE_IRQ)); ++ ++ /* try SB-X270 */ ++ set_irq_type(CMX270_IDE_IRQ, IRQ_TYPE_EDGE_RISING); ++ retval = cmx270_ide_register(CMX270_SB270_IDECS0_VIRT, ++ CMX270_SB270_IDECS1_VIRT, ++ CMX270_IDE_IRQ, &ifs[0]); ++ if (retval >= 0) { ++ printk(KERN_DEBUG "%s: found IDE interface on SB-X270\n", ++ __FUNCTION__); ++ goto out; ++ } ++ ++ /* SB-X270 detection failed, try ATX */ ++ set_irq_type(CMX270_IDE_IRQ, IRQ_TYPE_EDGE_FALLING); ++ retval = cmx270_ide_register(CMX270_ATX_IDECS0_VIRT, ++ CMX270_ATX_IDECS1_VIRT, ++ CMX270_IDE_IRQ, &ifs[0]); ++ ++ if ( retval >= 0 ) { ++ printk(KERN_DEBUG "%s: found IDE interface on ATX\n", ++ __FUNCTION__); ++ goto out; ++ } ++ ++ out: ++ return retval; ++} ++ ++module_init(cmx270_ide_init); ++ ++MODULE_AUTHOR("CompuLab"); ++MODULE_LICENSE("GPL"); ++MODULE_DESCRIPTION("CompuLab CM-X270 IDE driver"); +-- +1.5.2.5 + diff --git a/packages/linux/linux-2.6.23/cm-x270/0004-cm-x270-it8152.patch b/packages/linux/linux-2.6.23/cm-x270/0004-cm-x270-it8152.patch new file mode 100644 index 0000000000..8235c2948f --- /dev/null +++ b/packages/linux/linux-2.6.23/cm-x270/0004-cm-x270-it8152.patch @@ -0,0 +1,496 @@ +From 09963a3271b9da8e937e64774fe81454b35d31fd Mon Sep 17 00:00:00 2001 +From: Cliff Brake <cbrake@happy.dev.bec-systems.com> +Date: Fri, 20 Jul 2007 19:00:07 -0400 +Subject: [PATCH] cm-x270-it8152 + +--- + arch/arm/common/Makefile | 1 + + arch/arm/common/it8152.c | 272 +++++++++++++++++++++++++++++++++++++ + arch/arm/kernel/bios32.c | 28 ++++- + include/asm-arm/hardware/it8152.h | 104 ++++++++++++++ + include/asm-arm/pci.h | 7 + + include/linux/pci_ids.h | 1 + + 6 files changed, 410 insertions(+), 3 deletions(-) + create mode 100644 arch/arm/common/it8152.c + create mode 100644 include/asm-arm/hardware/it8152.h + +diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile +index e1289a2..3d0b9fa 100644 +--- a/arch/arm/common/Makefile ++++ b/arch/arm/common/Makefile +@@ -17,3 +17,4 @@ obj-$(CONFIG_SHARPSL_PM) += sharpsl_pm.o + obj-$(CONFIG_SHARP_SCOOP) += scoop.o + obj-$(CONFIG_ARCH_IXP2000) += uengine.o + obj-$(CONFIG_ARCH_IXP23XX) += uengine.o ++obj-$(CONFIG_PCI_HOST_ITE8152) += it8152.o +diff --git a/arch/arm/common/it8152.c b/arch/arm/common/it8152.c +new file mode 100644 +index 0000000..8563610 +--- /dev/null ++++ b/arch/arm/common/it8152.c +@@ -0,0 +1,272 @@ ++/* ++ * arch/arm/common/it8152.c: PCI functions for IT8152 ++ * ++ * Compulab Ltd, 2002-2006 ++ * ++ * The DMA bouncing is taken from arch/arm/mach-ixp4xx/common-pci.c ++ * (see this file for respective copyrights) ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++#include <linux/sched.h> ++#include <linux/kernel.h> ++#include <linux/pci.h> ++#include <linux/ptrace.h> ++#include <linux/interrupt.h> ++#include <linux/mm.h> ++#include <linux/slab.h> ++#include <linux/init.h> ++#include <linux/ioport.h> ++#include <asm/mach/map.h> ++ ++ ++#include <asm/io.h> ++#include <asm/irq.h> ++#include <asm/system.h> ++#include <asm/mach/pci.h> ++#include <asm/hardware/it8152.h> ++ ++#define MAX_SLOTS 21 ++ ++static unsigned long ++it8152_pci_dev_base_address(struct pci_bus *bus, unsigned int devfn) ++{ ++ unsigned long addr = 0; ++ ++ if (bus->number == 0) { ++ if (devfn < PCI_DEVFN(MAX_SLOTS, 0)) ++ addr = (devfn << 8); ++ } else ++ addr = (bus->number << 16) | (devfn << 8); ++ ++ return addr; ++} ++ ++static int ++it8152_pci_read_config(struct pci_bus *bus, unsigned int devfn, int where, ++ int size, u32 *value) ++{ ++ unsigned long addr = it8152_pci_dev_base_address(bus, devfn); ++ u32 v; ++ int shift; ++ ++#ifdef CONFIG_MACH_ARMCORE ++ if(devfn!=0) IT8152_GPIO_GPLR=0x00; ++#endif ++ shift = (where & 3); ++ ++ IT8152_PCI_CFG_ADDR = (addr + where); ++ v = (IT8152_PCI_CFG_DATA >> (8 * (shift))); ++ ++ *value = v; ++ ++#ifdef CONFIG_MACH_ARMCORE ++ if(devfn!=0) IT8152_GPIO_GPLR=0x20; ++#endif ++ ++ return PCIBIOS_SUCCESSFUL; ++} ++ ++ ++static int ++it8152_pci_write_config(struct pci_bus *bus, unsigned int devfn, int where, ++ int size, u32 value) ++{ ++ unsigned long addr = it8152_pci_dev_base_address(bus, devfn); ++ u32 v, vtemp, mask=0; ++ int shift; ++ ++#ifdef CONFIG_MACH_ARMCORE ++ if(devfn!=0) IT8152_GPIO_GPLR=0x00; ++#endif ++ ++ if(size==1) mask=0xff; ++ if(size==2) mask=0xffff; ++ ++ shift = (where & 3); ++ ++ IT8152_PCI_CFG_ADDR = addr + where; ++ vtemp = IT8152_PCI_CFG_DATA; ++ ++ if(mask) vtemp &= ~(mask << (8 * shift)); ++ else vtemp = 0; ++ ++ v = (value << (8 * shift)); ++ IT8152_PCI_CFG_ADDR = addr + where; ++ IT8152_PCI_CFG_DATA = (v | vtemp); ++ ++#ifdef CONFIG_MACH_ARMCORE ++ if(devfn!=0) IT8152_GPIO_GPLR=0x20; ++#endif ++ ++ return PCIBIOS_SUCCESSFUL; ++} ++ ++static struct pci_ops it8152_ops = { ++ .read = it8152_pci_read_config, ++ .write = it8152_pci_write_config, ++}; ++ ++static struct resource it8152_io = { ++ .name = "IT8152 PCI I/O region", ++ .flags = IORESOURCE_IO, ++}; ++ ++static struct resource it8152_mem1 = { ++ .name = "First IT8152 PCI memory region", ++ .start = 0x10000000, ++ .end = 0x13e00000, ++ .flags = IORESOURCE_MEM, ++}; ++ ++/* ++ * The following functions are needed for DMA bouncing. ++ * ITE8152 chip can addrees up to 64MByte, so all the devices ++ * connected to ITE8152 (PCI and USB) should have limited DMA window ++ */ ++ ++/* ++ * Setup DMA mask to 64MB on devices connected to ITE8152. Ignore all ++ * other devices. ++ */ ++static int it8152_pci_platform_notify(struct device *dev) ++{ ++ if ( dev->bus == &pci_bus_type ) { ++ if ( dev->dma_mask ) ++ *dev->dma_mask = (SZ_64M - 1) | PHYS_OFFSET; ++ dev->coherent_dma_mask = (SZ_64M - 1) | PHYS_OFFSET; ++ dmabounce_register_dev(dev, 2048, 4096); ++ } ++ return 0; ++} ++ ++static int it8152_pci_platform_notify_remove(struct device *dev) ++{ ++ if ( dev->bus == &pci_bus_type ) { ++ dmabounce_unregister_dev(dev); ++ } ++ return 0; ++} ++ ++int dma_needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t size) ++{ ++ dev_dbg(dev, "%s: dma_addr %08x, size %08x\n", ++ __FUNCTION__, dma_addr, size); ++ return (dev->bus == &pci_bus_type ) && ++ ((dma_addr + size - PHYS_OFFSET) >= SZ_64M); ++} ++ ++/* ++ * Only first 64MB of memory can be accessed via PCI. ++ * We use GFP_DMA to allocate safe buffers to do map/unmap. ++ * This is really ugly and we need a better way of specifying ++ * DMA-capable regions of memory. ++ */ ++void __init it8152_adjust_zones(int node, unsigned long *zone_size, ++ unsigned long *zhole_size) ++{ ++ unsigned int sz = SZ_64M >> PAGE_SHIFT; ++ ++ /* ++ * Only adjust if > 64M on current system ++ */ ++ if (node || (zone_size[0] <= sz)) ++ return; ++ ++ zone_size[1] = zone_size[0] - sz; ++ zone_size[0] = sz; ++ zhole_size[1] = zhole_size[0]; ++ zhole_size[0] = 0; ++} ++ ++/* ++ * We override these so we properly do dmabounce otherwise drivers ++ * are able to set the dma_mask to 0xffffffff and we can no longer ++ * trap bounces. :( ++ * ++ * We just return true on everyhing except for < 64MB in which case ++ * we will fail miseralby and die since we can't handle that case. ++ */ ++int ++pci_set_dma_mask(struct pci_dev *dev, u64 mask) ++{ ++ printk(KERN_INFO "===> %s: %s %x\n", __FUNCTION__, dev->dev.bus_id, mask); ++ if (mask >= PHYS_OFFSET + SZ_64M - 1 ) ++ return 0; ++ ++ return -EIO; ++} ++ ++int ++pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask) ++{ ++ printk(KERN_INFO "===> %s: %s %x\n", __FUNCTION__, dev->dev.bus_id, mask); ++ if (mask >= PHYS_OFFSET + SZ_64M - 1 ) ++ return 0; ++ ++ return -EIO; ++} ++ ++EXPORT_SYMBOL(pci_set_dma_mask); ++EXPORT_SYMBOL(pci_set_consistent_dma_mask); ++ ++ ++int __init it8152_pci_setup(int nr, struct pci_sys_data *sys) ++{ ++ it8152_io.start = IT8152_IO_BASE + 0x12000; ++ it8152_io.end = IT8152_IO_BASE + 0x100000; ++ ++ if (request_resource(&ioport_resource, &it8152_io)) { ++ printk(KERN_ERR "PCI: unable to allocate IO region\n"); ++ return -EBUSY; ++ } ++ if (request_resource(&iomem_resource, &it8152_mem1)) { ++ printk(KERN_ERR "PCI: unable to allocate memory region\n"); ++ return -EBUSY; ++ } ++ ++ sys->resource[0] = &it8152_io; ++ sys->resource[1] = &it8152_mem1; ++ ++ if (platform_notify || platform_notify_remove) { ++ printk(KERN_ERR "PCI: Can't use platform_notify\n"); ++ return -EBUSY; ++ } ++ ++ platform_notify = it8152_pci_platform_notify; ++ platform_notify_remove = it8152_pci_platform_notify_remove; ++ ++ return 1; ++} ++ ++/* ++ * If we set up a device for bus mastering, we need to check the latency ++ * timer as we don't have even crappy BIOSes to set it properly. ++ * The implementation is from arch/i386/pci/i386.c ++ */ ++unsigned int pcibios_max_latency = 255; ++ ++void pcibios_set_master(struct pci_dev *dev) ++{ ++ u8 lat; ++ ++ pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat); ++ if (lat < 16) ++ lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency; ++ else if (lat > pcibios_max_latency) ++ lat = pcibios_max_latency; ++ else ++ return; ++ printk(KERN_DEBUG "PCI: Setting latency timer of device %s to %d\n", pci_name(dev), lat); ++ pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat); ++} ++ ++ ++struct pci_bus * __init it8152_pci_scan_bus(int nr, struct pci_sys_data *sys) ++{ ++ return pci_scan_bus(nr, &it8152_ops, sys); ++} ++ +diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c +index a2dd930..4dc5de4 100644 +--- a/arch/arm/kernel/bios32.c ++++ b/arch/arm/kernel/bios32.c +@@ -279,6 +279,25 @@ static void __devinit pci_fixup_cy82c693(struct pci_dev *dev) + } + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_CONTAQ, PCI_DEVICE_ID_CONTAQ_82C693, pci_fixup_cy82c693); + ++static void __init pci_fixup_it8152(struct pci_dev *dev) ++{ ++ int i; ++ /* fixup for ITE 8152 devices */ ++ /* FIXME: add defines for class 0x68000 and 0x80103 */ ++ if ((dev->class >> 8) == PCI_CLASS_BRIDGE_HOST || ++ dev->class == 0x68000 || ++ dev->class == 0x80103) { ++ for (i = 0; i < PCI_NUM_RESOURCES; i++) { ++ dev->resource[i].start = 0; ++ dev->resource[i].end = 0; ++ dev->resource[i].flags = 0; ++ } ++ } ++} ++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_8152, pci_fixup_it8152); ++ ++ ++ + void __devinit pcibios_update_irq(struct pci_dev *dev, int irq) + { + if (debug_pci) +@@ -292,9 +311,12 @@ void __devinit pcibios_update_irq(struct pci_dev *dev, int irq) + */ + static inline int pdev_bad_for_parity(struct pci_dev *dev) + { +- return (dev->vendor == PCI_VENDOR_ID_INTERG && +- (dev->device == PCI_DEVICE_ID_INTERG_2000 || +- dev->device == PCI_DEVICE_ID_INTERG_2010)); ++ return ((dev->vendor == PCI_VENDOR_ID_INTERG && ++ (dev->device == PCI_DEVICE_ID_INTERG_2000 || ++ dev->device == PCI_DEVICE_ID_INTERG_2010)) || ++ (dev->vendor == PCI_VENDOR_ID_ITE && ++ dev->device == PCI_DEVICE_ID_ITE_8152)); ++ + } + + /* +diff --git a/include/asm-arm/hardware/it8152.h b/include/asm-arm/hardware/it8152.h +new file mode 100644 +index 0000000..d28210d +--- /dev/null ++++ b/include/asm-arm/hardware/it8152.h +@@ -0,0 +1,104 @@ ++/* ++ * arch/arm/mach-pxa/it8152.h ++ * ++ * Compulab Ltd., 2006 ++ * ++ * ITE 8152 companion chip definitions ++ */ ++ ++ ++/* #define CMX270_IT8152_VIRT (CMX270_VIRT_BASE) */ ++ ++ ++extern unsigned long it8152_base_address; ++ ++#define IT8152_IO_BASE (it8152_base_address + 0x03e00000) ++#define IT8152_CFGREG_BASE (it8152_base_address + 0x03f00000) ++ ++/* #define IRQ_GPIO_IT8152_IRQ IRQ_GPIO(GPIO_IT8152_IRQ) */ ++ ++#define IT8152_SHORT_IO(x) (*((volatile unsigned short *)(IT8152_CFGREG_BASE+(x)))) ++#define IT8152_LONG_IO(x) (*((volatile unsigned long *)(IT8152_CFGREG_BASE+(x)))) ++ ++ ++#define IT8152_PCI_MEMBASE (*((volatile unsigned long *)(it8152_base_address))) ++/* #define IT8152_PCI_IOBASE (*((volatile unsigned long *)(it8152_base_address + 0x3e00000))) */ ++ ++#define IT8152_PCI_IACK (*((volatile unsigned long *)(it8152_base_address + 0x3f00808))) ++#define IT8152_PCI_CFG_ADDR (*((volatile unsigned long *)(it8152_base_address + 0x3f00800))) ++#define IT8152_PCI_CFG_DATA (*((volatile unsigned long *)(it8152_base_address + 0x3f00804))) ++ ++#define IT_BUSNUM_SHF 16 ++#define IT_DEVNUM_SHF 11 ++#define IT_FUNCNUM_SHF 8 ++#define IT_REGNUM_SHF 2 ++ ++/* Power management & PLL registers */ ++#define IT8152_PMPLL_DSR IT8152_LONG_IO(0x00) ++#define IT8152_PMPLL_DSSR IT8152_LONG_IO(0x04) ++#define IT8152_PMPLL_PLLCR IT8152_LONG_IO(0x20) ++#define IT8152_PMPLL_MFSR IT8152_LONG_IO(0x24) ++ ++/* Memory controller */ ++#define IT8152_MC_REG_OFFSET 0x100 ++ ++#define IT8152_MC_SDCR IT8152_LONG_IO(IT8152_MC_REG_OFFSET + 0x00) ++#define IT8152_MC_PCICR IT8152_LONG_IO(IT8152_MC_REG_OFFSET + 0x04) ++ ++/* Interrupt related definitions */ ++#define IT8152_INTC_REG_OFFSET 0x300 ++ ++#define IT8152_INTC_LDCNIRR IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x00) ++#define IT8152_INTC_LDPNIRR IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x04) ++#define IT8152_INTC_LDCNIMR IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x08) ++#define IT8152_INTC_LDPNIMR IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x0C) ++#define IT8152_INTC_LDNITR IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x10) ++#define IT8152_INTC_LDNIAR IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x14) ++#define IT8152_INTC_LPCNIRR IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x20) ++#define IT8152_INTC_LPPNIRR IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x24) ++#define IT8152_INTC_LPCNIMR IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x28) ++#define IT8152_INTC_LPPNIMR IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x2C) ++#define IT8152_INTC_LPNITR IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x30) ++#define IT8152_INTC_LPNIAR IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x34) ++#define IT8152_INTC_PDCNIRR IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x40) ++#define IT8152_INTC_PDPNIRR IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x44) ++#define IT8152_INTC_PDCNIMR IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x48) ++#define IT8152_INTC_PDPNIMR IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x4C) ++#define IT8152_INTC_PDNITR IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x50) ++#define IT8152_INTC_PDNIAR IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x54) ++#define IT8152_INTC_INTC_TYPER IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0xFC) ++ ++#define IT8152_UART_BASE IT8152_LONG_IO(0x200) ++ ++#define IT8152_GPIO_REG_OFFSET 0x500 ++ ++#define IT8152_GPIO_GPLR IT8152_LONG_IO(IT8152_GPIO_REG_OFFSET) ++#define IT8152_GPIO_GPCR12 IT8152_LONG_IO(IT8152_GPIO_REG_OFFSET + 0x04) ++#define IT8152_GPIO_GPCR34 IT8152_LONG_IO(IT8152_GPIO_REG_OFFSET + 0x08) ++ ++ ++/* Interrupt bit definitions */ ++#define PCISERR_BIT (1<<14) ++#define H2PTADR_BIT (1<<13) ++#define H2PMAR_BIT (1<<12) ++#define PCI_INTD_BIT (1<<11) ++#define PCI_INTC_BIT (1<<10) ++#define PCI_INTB_BIT (1<<9) ++#define PCI_INTA_BIT (1<<8) ++#define CDMA_INT_BIT (1<<2) ++#define USB_INT_BIT (1<<1) ++#define AUDIO_INT_BIT (1<<0) ++ ++/* IT8152 UART */ ++#define ITESER_BIT (1<<5) ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/include/asm-arm/pci.h b/include/asm-arm/pci.h +index ed3f898..75feb15 100644 +--- a/include/asm-arm/pci.h ++++ b/include/asm-arm/pci.h +@@ -8,10 +8,17 @@ + + #define pcibios_scan_all_fns(a, b) 0 + ++#ifdef CONFIG_PCI_HOST_ITE8152 ++/* ITE bridge requires setting latency timer to avoid early bus access ++ termination by PIC bus mater devices ++*/ ++extern void pcibios_set_master(struct pci_dev *dev); ++#else + static inline void pcibios_set_master(struct pci_dev *dev) + { + /* No special bus mastering setup handling */ + } ++#endif + + static inline void pcibios_penalize_isa_irq(int irq, int active) + { +diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h +index 55f307f..357390d 100644 +--- a/include/linux/pci_ids.h ++++ b/include/linux/pci_ids.h +@@ -1629,6 +1629,7 @@ + #define PCI_DEVICE_ID_ITE_8211 0x8211 + #define PCI_DEVICE_ID_ITE_8212 0x8212 + #define PCI_DEVICE_ID_ITE_8213 0x8213 ++#define PCI_DEVICE_ID_ITE_8152 0x8152 + #define PCI_DEVICE_ID_ITE_8872 0x8872 + #define PCI_DEVICE_ID_ITE_IT8330G_0 0xe886 + +-- +1.5.2.5 + diff --git a/packages/linux/linux-2.6.23/cm-x270/0005-cm-x270-pcmcia.patch b/packages/linux/linux-2.6.23/cm-x270/0005-cm-x270-pcmcia.patch new file mode 100644 index 0000000000..e1653063fd --- /dev/null +++ b/packages/linux/linux-2.6.23/cm-x270/0005-cm-x270-pcmcia.patch @@ -0,0 +1,228 @@ +From 3066303d1e7d8e847de2e46cf3ed04a103715e17 Mon Sep 17 00:00:00 2001 +From: Cliff Brake <cbrake@happy.dev.bec-systems.com> +Date: Fri, 20 Jul 2007 19:01:27 -0400 +Subject: [PATCH] cm-x270-pcmcia + +--- + drivers/pcmcia/Makefile | 1 + + drivers/pcmcia/pxa2xx_cm_x270.c | 198 +++++++++++++++++++++++++++++++++++++++ + 2 files changed, 199 insertions(+), 0 deletions(-) + create mode 100644 drivers/pcmcia/pxa2xx_cm_x270.c + +diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile +index 4276965..353d5b7 100644 +--- a/drivers/pcmcia/Makefile ++++ b/drivers/pcmcia/Makefile +@@ -69,4 +69,5 @@ sa1100_cs-$(CONFIG_SA1100_SIMPAD) += sa1100_simpad.o + pxa2xx_cs-$(CONFIG_ARCH_LUBBOCK) += pxa2xx_lubbock.o sa1111_generic.o + pxa2xx_cs-$(CONFIG_MACH_MAINSTONE) += pxa2xx_mainstone.o + pxa2xx_cs-$(CONFIG_PXA_SHARPSL) += pxa2xx_sharpsl.o ++pxa2xx_cs-$(CONFIG_MACH_ARMCORE) += pxa2xx_cm_x270.o + +diff --git a/drivers/pcmcia/pxa2xx_cm_x270.c b/drivers/pcmcia/pxa2xx_cm_x270.c +new file mode 100644 +index 0000000..25e369f +--- /dev/null ++++ b/drivers/pcmcia/pxa2xx_cm_x270.c +@@ -0,0 +1,198 @@ ++/* ++ * linux/drivers/pcmcia/pxa/pxa_armcore.c ++ * ++ * 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. ++ * ++ * Compulab Ltd., 2003 ++ * ++ */ ++ ++#include <linux/kernel.h> ++#include <linux/sched.h> ++#include <linux/platform_device.h> ++#include <linux/irq.h> ++ ++#include <pcmcia/ss.h> ++#include <asm/delay.h> ++#include <asm/hardware.h> ++ ++#include <asm/arch/pxa-regs.h> ++#include <asm/arch/cm-x270.h> ++ ++#include "soc_common.h" ++ ++ ++static struct pcmcia_irqs irqs[] = { ++ { 0, PCMCIA_S0_CD_VALID, "PCMCIA0 CD" }, ++ { 1, PCMCIA_S1_CD_VALID, "PCMCIA1 CD" }, ++}; ++ ++ ++static int ++cmx270_pcmcia_hw_init(struct soc_pcmcia_socket *skt) ++{ ++ int return_val=0; ++ ++ GPSR(GPIO48_nPOE) = GPIO_bit(GPIO48_nPOE) | ++ GPIO_bit(GPIO49_nPWE) | ++ GPIO_bit(GPIO50_nPIOR) | ++ GPIO_bit(GPIO51_nPIOW) | ++ GPIO_bit(GPIO85_nPCE_1) | ++ GPIO_bit(GPIO54_nPCE_2); ++ ++ pxa_gpio_mode(GPIO48_nPOE_MD); ++ pxa_gpio_mode(GPIO49_nPWE_MD); ++ pxa_gpio_mode(GPIO50_nPIOR_MD); ++ pxa_gpio_mode(GPIO51_nPIOW_MD); ++ pxa_gpio_mode(GPIO85_nPCE_1_MD); ++ pxa_gpio_mode(GPIO54_nPCE_2_MD); ++ //pxa_gpio_mode(GPIO79_pSKTSEL_MD); /* REVISIT: s/b dependent on num sockets (on ATX base not routed)*/ ++ pxa_gpio_mode(GPIO55_nPREG_MD); ++ pxa_gpio_mode(GPIO56_nPWAIT_MD); ++ pxa_gpio_mode(GPIO57_nIOIS16_MD); ++ ++ // Reset signal ++ GPDR(GPIO53_nPCE_2) |= GPIO_bit(GPIO53_nPCE_2); ++ GPCR(GPIO53_nPCE_2) = GPIO_bit(GPIO53_nPCE_2); ++ ++ GPDR(IRQ_TO_GPIO(PCMCIA_S0_CD_VALID)) &= ~GPIO_bit(IRQ_TO_GPIO(PCMCIA_S0_CD_VALID)); ++ GPDR(IRQ_TO_GPIO(PCMCIA_S1_CD_VALID)) &= ~GPIO_bit(IRQ_TO_GPIO(PCMCIA_S1_CD_VALID)); ++ ++ set_irq_type(PCMCIA_S0_CD_VALID, IRQ_TYPE_EDGE_BOTH); ++ set_irq_type(PCMCIA_S1_CD_VALID, IRQ_TYPE_EDGE_BOTH); ++ ++ //irq's for slots: ++ GPDR(IRQ_TO_GPIO(PCMCIA_S0_RDYINT)) &= ~GPIO_bit(IRQ_TO_GPIO(PCMCIA_S0_RDYINT)); ++ GPDR(IRQ_TO_GPIO(PCMCIA_S1_RDYINT)) &= ~GPIO_bit(IRQ_TO_GPIO(PCMCIA_S1_RDYINT)); ++ ++ set_irq_type(PCMCIA_S0_RDYINT, IRQ_TYPE_EDGE_FALLING); ++ set_irq_type(PCMCIA_S1_RDYINT, IRQ_TYPE_EDGE_FALLING); ++ ++ skt->irq = (skt->nr == 0) ? PCMCIA_S0_RDYINT : PCMCIA_S1_RDYINT; ++ return_val = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); ++ ++ return return_val; ++} ++ ++ ++static void cmx270_pcmcia_shutdown(struct soc_pcmcia_socket *skt) ++{ ++ soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs)); ++ ++ set_irq_type(IRQ_TO_GPIO(PCMCIA_S0_CD_VALID), IRQ_TYPE_NONE); ++ set_irq_type(IRQ_TO_GPIO(PCMCIA_S1_CD_VALID), IRQ_TYPE_NONE); ++ ++ set_irq_type(IRQ_TO_GPIO(PCMCIA_S0_RDYINT), IRQ_TYPE_NONE); ++ set_irq_type(IRQ_TO_GPIO(PCMCIA_S1_RDYINT), IRQ_TYPE_NONE); ++} ++ ++ ++static void cmx270_pcmcia_socket_state(struct soc_pcmcia_socket *skt, ++ struct pcmcia_state *state) ++{ ++ ++ state->detect = (PCC_DETECT(skt->nr) == 0) ? 1 : 0; ++ state->ready = (PCC_READY(skt->nr) == 0) ? 0 : 1; ++ state->bvd1 = 1; ++ state->bvd2 = 1; ++ state->vs_3v = 0; ++ state->vs_Xv = 0; ++ state->wrprot = 0; /* not available */ ++ ++} ++ ++ ++static int ++cmx270_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, ++ const socket_state_t *state) ++{ ++ ++ GPSR(GPIO49_nPWE) = GPIO_bit(GPIO49_nPWE); ++ pxa_gpio_mode(GPIO49_nPWE | GPIO_OUT); ++ //pxa_gpio_mode(GPIO79_pSKTSEL_MD | GPIO_OUT); /* For 2-socket mode */ ++ ++ switch(skt->nr){ ++ case 0: ++ if(state->flags & SS_RESET) { ++ //GPCR(GPIO79_pSKTSEL) = GPIO_bit(GPIO79_pSKTSEL); /* For 2-socket mode */ ++ //udelay(1); ++ GPCR(GPIO49_nPWE) = GPIO_bit(GPIO49_nPWE); ++ GPSR(GPIO53_nPCE_2) = GPIO_bit(GPIO53_nPCE_2); ++ udelay(10); ++ GPCR(GPIO53_nPCE_2) = GPIO_bit(GPIO53_nPCE_2); ++ GPSR(GPIO49_nPWE) = GPIO_bit(GPIO49_nPWE); ++ } ++ break; ++ case 1: ++ if(state->flags & SS_RESET) { ++ //GPCR(GPIO79_pSKTSEL) = GPIO_bit(GPIO79_pSKTSEL); /* For 2-socket mode */ ++ //udelay(1); ++ GPCR(GPIO49_nPWE) = GPIO_bit(GPIO49_nPWE); ++ GPSR(GPIO53_nPCE_2) = GPIO_bit(GPIO53_nPCE_2); ++ udelay(10); ++ GPCR(GPIO53_nPCE_2) = GPIO_bit(GPIO53_nPCE_2); ++ GPSR(GPIO49_nPWE) = GPIO_bit(GPIO49_nPWE); ++ } ++ break; ++ } ++ ++ pxa_gpio_mode(GPIO49_nPWE_MD); ++ //pxa_gpio_mode(GPIO79_pSKTSEL_MD); /* For 2-socket mode */ ++ ++ ++ return 0; ++} ++ ++static void cmx270_pcmcia_socket_init(struct soc_pcmcia_socket *skt) ++{ ++} ++ ++static void cmx270_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) ++{ ++} ++ ++ ++static struct pcmcia_low_level cmx270_pcmcia_ops = { ++ .owner = THIS_MODULE, ++ .hw_init = cmx270_pcmcia_hw_init, ++ .hw_shutdown = cmx270_pcmcia_shutdown, ++ .socket_state = cmx270_pcmcia_socket_state, ++ .configure_socket = cmx270_pcmcia_configure_socket, ++ .socket_init = cmx270_pcmcia_socket_init, ++ .socket_suspend = cmx270_pcmcia_socket_suspend, ++ .nr = 2, ++}; ++ ++static struct platform_device *cmx270_pcmcia_device; ++ ++static int __init cmx270_pcmcia_init(void) ++{ ++ int ret; ++ ++ cmx270_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1); ++ ++ if (!cmx270_pcmcia_device) ++ return -ENOMEM; ++ ++ cmx270_pcmcia_device->dev.platform_data = &cmx270_pcmcia_ops; ++ ++ printk ("Registering cm-x270 PCMCIA interface.\n"); ++ ret = platform_device_add(cmx270_pcmcia_device); ++ ++ if (ret) ++ platform_device_put(cmx270_pcmcia_device); ++ ++ return ret; ++} ++ ++static void __exit cmx270_pcmcia_exit(void) ++{ ++ platform_device_unregister(cmx270_pcmcia_device); ++} ++ ++module_init(cmx270_pcmcia_init); ++module_exit(cmx270_pcmcia_exit); ++ ++MODULE_LICENSE("GPL"); +-- +1.5.2.5 + diff --git a/packages/linux/linux-2.6.23/cm-x270/0006-ramdisk_load.patch b/packages/linux/linux-2.6.23/cm-x270/0006-ramdisk_load.patch new file mode 100644 index 0000000000..24599e58d0 --- /dev/null +++ b/packages/linux/linux-2.6.23/cm-x270/0006-ramdisk_load.patch @@ -0,0 +1,80 @@ +From cbad8cd18463f3b696a8a7df059825f42b497ccd Mon Sep 17 00:00:00 2001 +From: Cliff Brake <cbrake@happy.dev.bec-systems.com> +Date: Fri, 20 Jul 2007 19:01:50 -0400 +Subject: [PATCH] ramdisk_load + +--- + arch/arm/mach-pxa/cm-x270.c | 6 ++++++ + include/asm-arm/arch-pxa/cm-x270.h | 2 ++ + init/initramfs.c | 16 ++++++++++++++++ + 3 files changed, 24 insertions(+), 0 deletions(-) + +diff --git a/arch/arm/mach-pxa/cm-x270.c b/arch/arm/mach-pxa/cm-x270.c +index 7b4e288..598eef1 100644 +--- a/arch/arm/mach-pxa/cm-x270.c ++++ b/arch/arm/mach-pxa/cm-x270.c +@@ -308,6 +308,12 @@ static struct map_desc cmx270_io_desc[] __initdata = { + .length = PXA_CS_SIZE, + .type = MT_DEVICE + }, ++ [2] = { /* NOR flash */ ++ .virtual = CMX270_FLASH_VIRT, ++ .pfn = __phys_to_pfn(PXA_CS0_PHYS), ++ .length = (8<<20), /* up to 8 MByte flash */ ++ .type = MT_DEVICE ++ }, + }; + + /* +diff --git a/include/asm-arm/arch-pxa/cm-x270.h b/include/asm-arm/arch-pxa/cm-x270.h +index 24613a5..aad152e 100644 +--- a/include/asm-arm/arch-pxa/cm-x270.h ++++ b/include/asm-arm/arch-pxa/cm-x270.h +@@ -20,7 +20,9 @@ + + #define CMX270_IT8152_VIRT (CMX270_VIRT_BASE) + #define CMX270_IDE104_VIRT (CMX270_IT8152_VIRT + PXA_CS_SIZE) ++#define CMX270_FLASH_VIRT (CMX270_IDE104_VIRT + PXA_CS_SIZE) + ++#define CMX270_FLASH_RAMDISK_VIRT (CMX270_FLASH_VIRT + 0x1c0000) + + /* GPIO related definitions */ + #define GPIO_IT8152_IRQ (22) +diff --git a/init/initramfs.c b/init/initramfs.c +index 1db02a0..d875fbc 100644 +--- a/init/initramfs.c ++++ b/init/initramfs.c +@@ -7,6 +7,9 @@ + #include <linux/string.h> + #include <linux/syscalls.h> + ++// HACK for compulab cm-x270 ++#include <asm/arch/cm-x270.h> ++ + static __initdata char *message; + static void __init error(char *x) + { +@@ -550,7 +553,20 @@ static int __init populate_rootfs(void) + #ifdef CONFIG_BLK_DEV_INITRD + if (initrd_start) { + #ifdef CONFIG_BLK_DEV_RAM ++ ++ /* hack to make initramfs work because the ++ * compulab BL does not zero out the ++ * initrd memory. This only seems to affect loading ++ * initramfs (cpio.gz) archives. Does not seem to ++ * affect ramdisks. ++ */ ++ int initrd_size = *(int *)(CMX270_FLASH_RAMDISK_VIRT); + int fd; ++ ++ initrd_end = initrd_start + initrd_size; ++ //printk("CLIFF: initrd_start = 0x%x\n", initrd_start); ++ //printk("CLIFF: initrd_end = 0x%x\n", initrd_end); ++ + printk(KERN_INFO "checking if image is initramfs..."); + err = unpack_to_rootfs((char *)initrd_start, + initrd_end - initrd_start, 1); +-- +1.5.2.5 + diff --git a/packages/linux/linux-2.6.23/cm-x270/0007-mmcsd_large_cards-r0.patch b/packages/linux/linux-2.6.23/cm-x270/0007-mmcsd_large_cards-r0.patch new file mode 100644 index 0000000000..0f53fb445e --- /dev/null +++ b/packages/linux/linux-2.6.23/cm-x270/0007-mmcsd_large_cards-r0.patch @@ -0,0 +1,36 @@ +From 9fb3d9729cf908539a769b701d66c708658eff97 Mon Sep 17 00:00:00 2001 +From: Cliff Brake <cbrake@happy.dev.bec-systems.com> +Date: Fri, 20 Jul 2007 19:02:55 -0400 +Subject: [PATCH] mmcsd_large_cards-r0 + +--- + drivers/mmc/card/block.c | 6 ++++++ + 1 files changed, 6 insertions(+), 0 deletions(-) + +diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c +index 93fe2e5..7ce961f 100644 +--- a/drivers/mmc/card/block.c ++++ b/drivers/mmc/card/block.c +@@ -408,6 +408,7 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card) + { + struct mmc_blk_data *md; + int devidx, ret; ++ unsigned long cap; + + devidx = find_first_zero_bit(dev_use, MMC_NUM_MINORS); + if (devidx >= MMC_NUM_MINORS) +@@ -471,6 +472,11 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card) + + sprintf(md->disk->disk_name, "mmcblk%d", devidx); + ++ if (card->csd.read_blkbits > 9) ++ md->block_bits = 9; ++ else ++ md->block_bits = card->csd.read_blkbits; ++ + blk_queue_hardsect_size(md->queue.queue, 1 << md->block_bits); + + if (!mmc_card_sd(card) && mmc_card_blockaddr(card)) { +-- +1.5.2.5 + diff --git a/packages/linux/linux-2.6.23/cm-x270/0008-cm-x270-nand-simplify-name.patch b/packages/linux/linux-2.6.23/cm-x270/0008-cm-x270-nand-simplify-name.patch new file mode 100644 index 0000000000..58ed2a276b --- /dev/null +++ b/packages/linux/linux-2.6.23/cm-x270/0008-cm-x270-nand-simplify-name.patch @@ -0,0 +1,25 @@ +From 3069f49137668b467ba820ed55076df953127582 Mon Sep 17 00:00:00 2001 +From: Cliff Brake <cbrake@happy.dev.bec-systems.com> +Date: Fri, 20 Jul 2007 19:04:12 -0400 +Subject: [PATCH] cm-x270-nand-simplify-name + +--- + drivers/mtd/nand/cmx270_nand.c | 2 ++ + 1 files changed, 2 insertions(+), 0 deletions(-) + +diff --git a/drivers/mtd/nand/cmx270_nand.c b/drivers/mtd/nand/cmx270_nand.c +index cb663ef..3654ce4 100644 +--- a/drivers/mtd/nand/cmx270_nand.c ++++ b/drivers/mtd/nand/cmx270_nand.c +@@ -191,6 +191,8 @@ static int cmx270_init(void) + cmx270_nand_mtd->owner = THIS_MODULE; + cmx270_nand_mtd->priv = this; + ++ cmx270_nand_mtd->name = "cm-x270-nand"; ++ + /* insert callbacks */ + this->IO_ADDR_R = cmx270_nand_io; + this->IO_ADDR_W = cmx270_nand_io; +-- +1.5.2.5 + diff --git a/packages/linux/linux-2.6.23/cm-x270/defconfig b/packages/linux/linux-2.6.23/cm-x270/defconfig new file mode 100644 index 0000000000..273de85b0a --- /dev/null +++ b/packages/linux/linux-2.6.23/cm-x270/defconfig @@ -0,0 +1,1204 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.23 +# Thu Oct 11 15:47:57 2007 +# +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_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_ZONE_DMA=y +CONFIG_ARCH_MTD_XIP=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="-cm-x270" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_USER_NS is not set +# CONFIG_AUDIT is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_SYSFS_DEPRECATED=y +# CONFIG_RELAY is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_ANON_INODES=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set +# CONFIG_BLK_DEV_BSG is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" + +# +# 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_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IMX 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_KS8695 is not set +# CONFIG_ARCH_NS9XXX is not set +# CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_PNX4008 is not set +CONFIG_ARCH_PXA=y +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 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 + +# +# Intel PXA2xx Implementations +# +# CONFIG_ARCH_LUBBOCK is not set +# CONFIG_MACH_LOGICPD_PXA270 is not set +# CONFIG_MACH_MAINSTONE is not set +# CONFIG_ARCH_PXA_IDP is not set +# CONFIG_PXA_SHARPSL is not set +# CONFIG_MACH_TRIZEPS4 is not set +# CONFIG_MACH_EM_X270 is not set +CONFIG_MACH_ARMCORE=y +CONFIG_PXA27x=y + +# +# Boot options +# + +# +# Power management +# + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_XSCALE=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5T=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_OUTER_CACHE is not set +CONFIG_IWMMXT=y +CONFIG_XSCALE_PMU=y + +# +# Bus support +# +# CONFIG_PCI is not set +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +CONFIG_TICK_ONESHOT=y +# CONFIG_NO_HZ is not set +CONFIG_HIGH_RES_TIMERS=y +CONFIG_PREEMPT=y +CONFIG_HZ=100 +CONFIG_AEABI=y +CONFIG_OABI_COMPAT=y +# CONFIG_ARCH_DISCONTIGMEM_ENABLE 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_SPARSEMEM_STATIC is not set +CONFIG_SPLIT_PTLOCK_CPUS=4096 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=1 +CONFIG_BOUNCE=y +CONFIG_VIRT_TO_BUS=y +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="console=ttyS1,38400 monitor=8 bpp=16 mem=64M mtdparts=physmap-flash.0:256k(boot)ro,0x180000(kernel),-(root);cm-x270-nand:64m(app),-(data) rdinit=/sbin/init root=mtd3 rootfstype=jffs2" +# CONFIG_XIP_KERNEL is not set +# CONFIG_KEXEC is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +# CONFIG_FPE_NWFPE is not set +# CONFIG_FPE_FASTFPE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set + +# +# Power management options +# +# CONFIG_PM is not set +CONFIG_SUSPEND_UP_POSSIBLE=y + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# 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 is not set +# 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=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# 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_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL 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_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 + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +# CONFIG_WIRELESS_EXT is not set +# CONFIG_MAC80211 is not set +# CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_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 + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS 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_CFI_INTELEXT is not set +CONFIG_MTD_CFI_AMDSTD=y +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_XIP is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_START=0x0 +CONFIG_MTD_PHYSMAP_LEN=0x400000 +CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_SHARP_SL 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 is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +# CONFIG_MTD_NAND_H1900 is not set +CONFIG_MTD_NAND_IDS=y +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_SHARPSL is not set +CONFIG_MTD_NAND_CM_X270=y +# CONFIG_MTD_NAND_NANDSIM is not set +# CONFIG_MTD_NAND_PLATFORM is not set +# CONFIG_MTD_ONENAND 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=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +CONFIG_SCSI_LOWLEVEL=y +# CONFIG_ISCSI_TCP is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +CONFIG_NETDEVICES=y +# CONFIG_NETDEVICES_MULTIQUEUE is not set +# 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_PHYLIB is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_AX88796 is not set +# CONFIG_SMC91X is not set +CONFIG_DM9000=y +CONFIG_DM9000_NOEPROM=y +# CONFIG_SMC911X 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 + +# +# USB Network Adapters +# +CONFIG_USB_CATC=m +CONFIG_USB_KAWETH=m +CONFIG_USB_PEGASUS=m +CONFIG_USB_RTL8150=m +CONFIG_USB_USBNET_MII=m +CONFIG_USB_USBNET=m +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_CDCETHER=m +# CONFIG_USB_NET_DM9601 is not set +CONFIG_USB_NET_GL620A=m +CONFIG_USB_NET_NET1080=m +CONFIG_USB_NET_PLUSB=m +CONFIG_USB_NET_MCS7830=m +# CONFIG_USB_NET_RNDIS_HOST is not set +# CONFIG_USB_NET_CDC_SUBSET is not set +# CONFIG_USB_NET_ZAURUS is not set +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# 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=y +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_TSDEV is not set +CONFIG_INPUT_EVDEV=m +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# 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_PXA27x is not set +# CONFIG_KEYBOARD_GPIO is not set +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +# CONFIG_MOUSE_PS2_ALPS is not set +# CONFIG_MOUSE_PS2_LOGIPS2PP is not set +# CONFIG_MOUSE_PS2_SYNAPTICS is not set +# CONFIG_MOUSE_PS2_LIFEBOOK is not set +# CONFIG_MOUSE_PS2_TRACKPOINT is not set +# CONFIG_MOUSE_PS2_TOUCHKIT is not set +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_APPLETOUCH 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=y +# CONFIG_TOUCHSCREEN_FUJITSU is not set +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +# CONFIG_TOUCHSCREEN_PENMOUNT is not set +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set +CONFIG_TOUCHSCREEN_UCB1400=m +# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_PXA=y +CONFIG_SERIAL_PXA_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +# CONFIG_LEGACY_PTYS is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_WATCHDOG is not set +CONFIG_HW_RANDOM=y +# CONFIG_NVRAM is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +CONFIG_I2C=m +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=m + +# +# I2C Algorithms +# +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_GPIO is not set +CONFIG_I2C_PXA=m +# CONFIG_I2C_PXA_SLAVE is not set +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_TINY_USB is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_SENSORS_DS1337 is not set +# CONFIG_SENSORS_DS1374 is not set +# CONFIG_DS1682 is not set +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_MAX6875 is not set +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set +# CONFIG_W1 is not set +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_ABITUGURU is not set +# CONFIG_SENSORS_ABITUGURU3 is not set +# CONFIG_SENSORS_AD7418 is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1029 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_ATXP1 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_LM93 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_MAX6650 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_DME1737 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47M192 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_THMC50 is not set +# CONFIG_SENSORS_VT1211 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83791D is not set +# CONFIG_SENSORS_W83792D is not set +# CONFIG_SENSORS_W83793 is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set +# CONFIG_HWMON_DEBUG_CHIP is not set +CONFIG_MISC_DEVICES=y +# CONFIG_EEPROM_93CX6 is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y + +# +# LED drivers +# +CONFIG_LEDS_CM_X270=y +# CONFIG_LEDS_GPIO is not set + +# +# LED Triggers +# +# CONFIG_LEDS_TRIGGERS is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set +# CONFIG_DVB_CORE is not set +# CONFIG_DAB is not set + +# +# Graphics support +# +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set +# 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_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_SYS_FOPS is not set +CONFIG_FB_DEFERRED_IO=y +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_S1D13XXX is not set +CONFIG_FB_PXA=y +CONFIG_FB_PXA_PARAMETERS=y +# CONFIG_FB_MBX is not set +# CONFIG_FB_VIRTUAL 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 is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +# CONFIG_LOGO is not set + +# +# Sound +# +CONFIG_SOUND=m + +# +# Advanced Linux Sound Architecture +# +CONFIG_SND=m +CONFIG_SND_TIMER=m +CONFIG_SND_PCM=m +# CONFIG_SND_SEQUENCER is not set +# CONFIG_SND_MIXER_OSS is not set +# CONFIG_SND_PCM_OSS is not set +# CONFIG_SND_DYNAMIC_MINORS is not set +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set + +# +# Generic devices +# +CONFIG_SND_AC97_CODEC=m +# CONFIG_SND_DUMMY is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set + +# +# ALSA ARM devices +# +CONFIG_SND_PXA2XX_PCM=m +CONFIG_SND_PXA2XX_AC97=m + +# +# USB devices +# +# CONFIG_SND_USB_AUDIO is not set +# CONFIG_SND_USB_CAIAQ is not set + +# +# System on Chip audio support +# +# CONFIG_SND_SOC is not set + +# +# SoC Audio support for SuperH +# + +# +# Open Sound System +# +# CONFIG_SOUND_PRIME is not set +CONFIG_AC97_BUS=m +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +# CONFIG_HID_DEBUG is not set + +# +# USB Input Devices +# +CONFIG_USB_HID=y +# CONFIG_USB_HIDINPUT_POWERBOOK is not set +# CONFIG_HID_FF is not set +# CONFIG_USB_HIDDEV is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB_ARCH_HAS_EHCI is not set +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_DEVICE_CLASS is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_ISP116X_HCD is not set +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# may also be needed; see USB_STORAGE Help for more information +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_ONETOUCH is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set +CONFIG_USB_MON=y + +# +# USB port drivers +# + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_BERRY_CHARGE is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGET is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set + +# +# USB DSL modem support +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set +CONFIG_MMC=m +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_UNSAFE_RESUME is not set + +# +# MMC/SD Card Drivers +# +CONFIG_MMC_BLOCK=m +CONFIG_MMC_BLOCK_BOUNCE=y + +# +# MMC/SD Host Controller Drivers +# +CONFIG_MMC_PXA=m +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS is not set + +# +# DMA Engine support +# +# CONFIG_DMA_ENGINE is not set + +# +# DMA Clients +# + +# +# DMA Devices +# + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +# CONFIG_EXT4DEV_FS is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# 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_SUMMARY=y +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +# CONFIG_NFS_FS is not set +# CONFIG_NFSD 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 is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# 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 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=y +# 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 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Distributed Lock Manager +# +# CONFIG_DLM is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_MUST_CHECK=y +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_KERNEL is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_FRAME_POINTER=y +# CONFIG_DEBUG_USER is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_CRYPTO is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 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_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y diff --git a/packages/linux/linux-bd-neon-2.6-2.6.22/.mtn2git_empty b/packages/linux/linux-bd-neon-2.6-2.6.22/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/packages/linux/linux-bd-neon-2.6-2.6.22/.mtn2git_empty diff --git a/packages/linux/linux-bd-neon-2.6-2.6.22/neon-jffs2-config.patch b/packages/linux/linux-bd-neon-2.6-2.6.22/neon-jffs2-config.patch new file mode 100644 index 0000000000..958eda0200 --- /dev/null +++ b/packages/linux/linux-bd-neon-2.6-2.6.22/neon-jffs2-config.patch @@ -0,0 +1,33 @@ +--- linux-2.6.22/arch/arm/configs/neon_defconfig-o 2007-08-23 19:49:52.000000000 +0200 ++++ linux-2.6.22/arch/arm/configs/neon_defconfig 2007-08-23 19:50:16.000000000 +0200 +@@ -171,7 +171,8 @@ + # CONFIG_PREEMPT is not set + # CONFIG_NO_IDLE_HZ is not set + CONFIG_HZ=100 +-# CONFIG_AEABI is not set ++CONFIG_AEABI=y ++CONFIG_OABI_COMPAT=y + # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set + CONFIG_SELECT_MEMORY_MODEL=y + CONFIG_FLATMEM_MANUAL=y +@@ -1131,7 +1132,7 @@ + CONFIG_PROC_FS=y + CONFIG_PROC_SYSCTL=y + CONFIG_SYSFS=y +-# CONFIG_TMPFS is not set ++CONFIG_TMPFS=y + # CONFIG_HUGETLB_PAGE is not set + CONFIG_RAMFS=y + # CONFIG_CONFIGFS_FS is not set +@@ -1147,7 +1148,10 @@ + # CONFIG_BFS_FS is not set + # CONFIG_EFS_FS is not set + # CONFIG_JFFS_FS is not set +-# CONFIG_JFFS2_FS is not set ++CONFIG_JFFS2_FS=y ++CONFIG_JFFS2_FS_DEBUG=0 ++CONFIG_JFFS2_FS_WRITEBUFFER=y ++CONFIG_JFFS2_SUMMARY=y + CONFIG_CRAMFS=y + # CONFIG_VXFS_FS is not set + # CONFIG_HPFS_FS is not set diff --git a/packages/linux/linux-bd-neon-2.6_2.6.22.bb b/packages/linux/linux-bd-neon-2.6_2.6.22.bb new file mode 100644 index 0000000000..6d2472935f --- /dev/null +++ b/packages/linux/linux-bd-neon-2.6_2.6.22.bb @@ -0,0 +1,48 @@ +DESCRIPTION = "2.6 Linux Kernel for Boundary Devices NEON Board" +SECTION = "kernel" +HOMEPAGE = "N/A" +LICENSE = "GPL" +DEPENDS += "uboot-utils" + +PR = "r1" + +SRC_URI = "${KERNELORG_MIRROR}/pub/linux/kernel/v2.6/linux-2.6.22.tar.bz2 \ + http://www.boundarydevices.com/boundary-2.6.22-2007-07-22.patch.bz2;patch=1 \ + file://neon-jffs2-config.patch;patch=1" + +S = "${WORKDIR}/linux-2.6.22" + +inherit kernel + +KERNEL_IMAGETYPE = "zImage" +FILES_kernel-image = "" +ALLOW_EMPTY = "1" + +do_configure() { + cp arch/arm/configs/neon_defconfig .config || die "No default configuration for ${MACHINE} available." + +# if [ "${TARGET_OS}" == "linux-gnueabi" -o "${TARGET_OS}" == "linux-uclibcgnueabi" ]; then +# echo "CONFIG_AEABI=y" >> ${S}/.config +# echo "CONFIG_OABI_COMPAT=y" >> ${S}/.config +# else +# echo "# CONFIG_AEABI is not set" >> ${S}/.config +# echo "# CONFIG_OABI_COMPAT is not set" >> ${S}/.config +# fi + + yes '' | oe_runmake oldconfig +} + +do_deploy() { + install -d ${DEPLOY_DIR_IMAGE} + install -m 0644 arch/${ARCH}/boot/${KERNEL_IMAGETYPE} ${DEPLOY_DIR_IMAGE}/${KERNEL_IMAGETYPE}-${PV}-${PR}-${MACHINE}.bin + tar -cvzf ${DEPLOY_DIR_IMAGE}/modules-${KERNEL_RELEASE}-${PR}-${MACHINE}.tgz -C ${D} lib + ${OBJCOPY} -O binary -R .note -R .comment -S vmlinux linux.bin + rm -f linux.bin.gz + gzip -9 linux.bin + ${STAGING_BINDIR_NATIVE}/mkimage -A arm -O linux -T kernel -C gzip -a a0008000 -e a0008000 -n "Boundary Devices NEON" -d linux.bin.gz ${DEPLOY_DIR_IMAGE}/uImage-${PV}-${PR}-${MACHINE}.bin + rm -f linux.bin.gz +} + +do_deploy[dirs] = "${S}" + +addtask deploy before do_package after do_install diff --git a/packages/linux/linux-bfin/.mtn2git_empty b/packages/linux/linux-bfin/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/packages/linux/linux-bfin/.mtn2git_empty diff --git a/packages/linux/linux-bfin/adzs-bf548-ezlite/.mtn2git_empty b/packages/linux/linux-bfin/adzs-bf548-ezlite/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/packages/linux/linux-bfin/adzs-bf548-ezlite/.mtn2git_empty diff --git a/packages/linux/linux-bfin/adzs-bf548-ezlite/defconfig b/packages/linux/linux-bfin/adzs-bf548-ezlite/defconfig new file mode 100644 index 0000000000..43efcb02d5 --- /dev/null +++ b/packages/linux/linux-bfin/adzs-bf548-ezlite/defconfig @@ -0,0 +1,1989 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.22.10 +# Tue Oct 16 11:16:52 2007 +# +# CONFIG_MMU is not set +# CONFIG_FPU is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +CONFIG_BLACKFIN=y +CONFIG_ZONE_DMA=y +CONFIG_BFIN=y +CONFIG_SEMAPHORE_SLEEPERS=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +# CONFIG_GENERIC_TIME is not set +CONFIG_GENERIC_GPIO=y +CONFIG_FORCE_MAX_ZONEORDER=14 +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_IRQCHIP_DEMUX_GPIO=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=n +CONFIG_SYSVIPC=y +# CONFIG_IPC_NS is not set +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_POSIX_MQUEUE=y +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set +# CONFIG_TASKSTATS is not set +# CONFIG_UTS_NS is not set +# CONFIG_AUDIT is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_SYSFS_DEPRECATED=y +# CONFIG_RELAY is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS 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_ANON_INODES=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_EVENTFD=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLUB_DEBUG=y +CONFIG_BIG_ORDER_ALLOC_NOFAIL_MAGIC=3 +CONFIG_NP2=y +# CONFIG_SLAB is not set +CONFIG_SLUB=y +# CONFIG_SLOB is not set +CONFIG_RT_MUTEXES=y +CONFIG_TINY_SHMEM=y +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_MODVERSIONS=y +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y + +# +# Block layer +# +CONFIG_BLOCK=y +CONFIG_LBD=y +# CONFIG_BLK_DEV_IO_TRACE is not set +CONFIG_LSF=y + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +# CONFIG_IOSCHED_DEADLINE is not set +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_PREEMPT_NONE is not set +# CONFIG_PREEMPT_VOLUNTARY is not set +CONFIG_PREEMPT=y +CONFIG_PREEMPT_BKL=y + +# +# Blackfin Processor Options +# + +# +# Processor and Board Settings +# +# CONFIG_BF522 is not set +# CONFIG_BF525 is not set +# CONFIG_BF527 is not set +# CONFIG_BF531 is not set +# CONFIG_BF532 is not set +# CONFIG_BF533 is not set +# CONFIG_BF534 is not set +# CONFIG_BF536 is not set +# CONFIG_BF537 is not set +# CONFIG_BF542 is not set +# CONFIG_BF544 is not set +CONFIG_BF548=y +# CONFIG_BF549 is not set +# CONFIG_BF561 is not set +# CONFIG_BF_REV_0_0 is not set +# CONFIG_BF_REV_0_1 is not set +# CONFIG_BF_REV_0_2 is not set +# CONFIG_BF_REV_0_3 is not set +# CONFIG_BF_REV_0_4 is not set +# CONFIG_BF_REV_0_5 is not set +CONFIG_BF_REV_ANY=y +# CONFIG_BF_REV_NONE is not set +CONFIG_BF54x=y +CONFIG_BFIN_SINGLE_CORE=y +# CONFIG_BFIN527_EZKIT is not set +# CONFIG_BFIN533_EZKIT is not set +# CONFIG_BFIN533_STAMP is not set +# CONFIG_BFIN537_STAMP is not set +# CONFIG_BFIN533_BLUETECHNIX_CM is not set +# CONFIG_BFIN537_BLUETECHNIX_CM is not set +CONFIG_BFIN548_EZKIT=y +# CONFIG_BFIN561_BLUETECHNIX_CM is not set +# CONFIG_BFIN561_EZKIT is not set +# CONFIG_BFIN561_TEPLA is not set +# CONFIG_PNAV10 is not set +# CONFIG_GENERIC_BOARD is not set +CONFIG_IRQ_PLL_WAKEUP=7 +CONFIG_IRQ_RTC=8 +CONFIG_IRQ_SPORT0_RX=9 +CONFIG_IRQ_SPORT0_TX=9 +CONFIG_IRQ_SPORT1_RX=9 +CONFIG_IRQ_SPORT1_TX=9 +CONFIG_IRQ_UART0_RX=10 +CONFIG_IRQ_UART0_TX=10 +CONFIG_IRQ_UART1_RX=10 +CONFIG_IRQ_UART1_TX=10 +CONFIG_IRQ_CNT=8 +CONFIG_IRQ_USB_INT0=11 +CONFIG_IRQ_USB_INT1=11 +CONFIG_IRQ_USB_INT2=11 +CONFIG_IRQ_USB_DMA=11 +CONFIG_IRQ_TIMER0=11 +CONFIG_IRQ_TIMER1=11 +CONFIG_IRQ_TIMER2=11 +CONFIG_IRQ_TIMER3=11 +CONFIG_IRQ_TIMER4=11 +CONFIG_IRQ_TIMER5=11 +CONFIG_IRQ_TIMER6=11 +CONFIG_IRQ_TIMER7=11 +CONFIG_IRQ_TIMER8=11 +CONFIG_IRQ_TIMER9=11 +CONFIG_IRQ_TIMER10=11 + +# +# BF548 Specific Configuration +# +# CONFIG_DEB_DMA_URGENT is not set + +# +# Interrupt Priority Assignment +# + +# +# Priority +# +CONFIG_IRQ_DMAC0_ERR=7 +CONFIG_IRQ_EPPI0_ERR=7 +CONFIG_IRQ_SPORT0_ERR=7 +CONFIG_IRQ_SPORT1_ERR=7 +CONFIG_IRQ_SPI0_ERR=7 +CONFIG_IRQ_UART0_ERR=7 +CONFIG_IRQ_EPPI0=8 +CONFIG_IRQ_SPI0=10 +CONFIG_IRQ_PINT0=12 +CONFIG_IRQ_PINT1=12 +CONFIG_IRQ_MDMAS0=13 +CONFIG_IRQ_MDMAS1=13 +CONFIG_IRQ_WATCHDOG=13 +CONFIG_IRQ_DMAC1_ERR=7 +CONFIG_IRQ_SPORT2_ERR=7 +CONFIG_IRQ_SPORT3_ERR=7 +CONFIG_IRQ_MXVR_DATA=7 +CONFIG_IRQ_SPI1_ERR=7 +CONFIG_IRQ_SPI2_ERR=7 +CONFIG_IRQ_UART1_ERR=7 +CONFIG_IRQ_UART2_ERR=7 +CONFIG_IRQ_CAN0_ERR=7 +CONFIG_IRQ_SPORT2_RX=9 +CONFIG_IRQ_SPORT2_TX=9 +CONFIG_IRQ_SPORT3_RX=9 +CONFIG_IRQ_SPORT3_TX=9 +CONFIG_IRQ_EPPI1=9 +CONFIG_IRQ_EPPI2=9 +CONFIG_IRQ_SPI1=10 +CONFIG_IRQ_SPI2=10 +CONFIG_IRQ_ATAPI_RX=10 +CONFIG_IRQ_ATAPI_TX=10 +CONFIG_IRQ_TWI0=11 +CONFIG_IRQ_TWI1=11 +CONFIG_IRQ_CAN0_RX=11 +CONFIG_IRQ_CAN0_TX=11 +CONFIG_IRQ_MDMAS2=13 +CONFIG_IRQ_MDMAS3=13 +CONFIG_IRQ_MXVR_ERR=11 +CONFIG_IRQ_MXVR_MSG=11 +CONFIG_IRQ_MXVR_PKT=11 +CONFIG_IRQ_EPPI1_ERR=7 +CONFIG_IRQ_EPPI2_ERR=7 +CONFIG_IRQ_UART3_ERR=7 +CONFIG_IRQ_HOST_ERR=7 +CONFIG_IRQ_PIXC_ERR=7 +CONFIG_IRQ_NFC_ERR=7 +CONFIG_IRQ_ATAPI_ERR=7 +CONFIG_IRQ_CAN1_ERR=7 +CONFIG_IRQ_HS_DMA_ERR=7 +CONFIG_IRQ_PIXC_IN0=8 +CONFIG_IRQ_PIXC_IN1=8 +CONFIG_IRQ_PIXC_OUT=8 +CONFIG_IRQ_SDH=8 +CONFIG_IRQ_KEY=8 +CONFIG_IRQ_CAN1_RX=11 +CONFIG_IRQ_CAN1_TX=11 +CONFIG_IRQ_SDH_MASK0=11 +CONFIG_IRQ_SDH_MASK1=11 +CONFIG_IRQ_OTPSEC=11 +CONFIG_IRQ_PINT2=11 +CONFIG_IRQ_PINT3=11 + +# +# Pin Interrupt to Port Assignment +# + +# +# Assignment +# +CONFIG_PINTx_REASSIGN=y +CONFIG_PINT0_ASSIGN=0x00000101 +CONFIG_PINT1_ASSIGN=0x01010000 +CONFIG_PINT2_ASSIGN=0x07000101 +CONFIG_PINT3_ASSIGN=0x02020303 + +# +# Board customizations +# +# CONFIG_CMDLINE_BOOL is not set + +# +# Clock/PLL Setup +# +CONFIG_CLKIN_HZ=25000000 +# CONFIG_BFIN_KERNEL_CLOCK is not set +CONFIG_MIN_VCO_HZ=50000000 +CONFIG_MAX_SCLK_HZ=133000000 +CONFIG_MIN_SCLK_HZ=27000000 + +# +# Kernel Timer/Scheduler +# +# CONFIG_HZ_100 is not set +# CONFIG_HZ_250 is not set +CONFIG_HZ_300=y +# CONFIG_HZ_1000 is not set +CONFIG_HZ=300 + +# +# Memory Setup +# +CONFIG_MEM_SIZE=64 +CONFIG_MEM_ADD_WIDTH=10 +CONFIG_BOOT_LOAD=0x1000 +CONFIG_BFIN_SCRATCH_REG_RETN=y +# CONFIG_BFIN_SCRATCH_REG_RETE is not set +# CONFIG_BFIN_SCRATCH_REG_CYCLES is not set + +# +# Blackfin Kernel Optimizations +# + +# +# Memory Optimizations +# +CONFIG_I_ENTRY_L1=y +CONFIG_EXCPT_IRQ_SYSC_L1=y +CONFIG_DO_IRQ_L1=y +CONFIG_CORE_TIMER_IRQ_L1=y +CONFIG_IDLE_L1=y +# CONFIG_SCHEDULE_L1 is not set +CONFIG_ARITHMETIC_OPS_L1=y +CONFIG_ACCESS_OK_L1=y +# CONFIG_MEMSET_L1 is not set +# CONFIG_MEMCPY_L1 is not set +# CONFIG_SYS_BFIN_SPINLOCK_L1 is not set +# CONFIG_IP_CHECKSUM_L1 is not set +CONFIG_CACHELINE_ALIGNED_L1=y +# CONFIG_SYSCALL_TAB_L1 is not set +# CONFIG_CPLB_SWITCH_TAB_L1 is not set +CONFIG_RAMKERNEL=y +# CONFIG_ROMKERNEL 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_SPARSEMEM_STATIC is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=1 +CONFIG_LARGE_ALLOCS=y +CONFIG_BFIN_DMA_5XX=y +# CONFIG_DMA_UNCACHED_2M is not set +CONFIG_DMA_UNCACHED_1M=y +# CONFIG_DMA_UNCACHED_NONE is not set + +# +# Cache Support +# +CONFIG_BFIN_ICACHE=y +CONFIG_BFIN_DCACHE=y +# CONFIG_BFIN_DCACHE_BANKA is not set +# CONFIG_BFIN_ICACHE_LOCK is not set +# CONFIG_BFIN_WB is not set +CONFIG_BFIN_WT=y +CONFIG_L1_MAX_PIECE=16 + +# +# Asynchonous Memory Configuration +# + +# +# EBIU_AMGCTL Global Control +# +CONFIG_C_AMCKEN=y +# CONFIG_C_AMBEN is not set +# CONFIG_C_AMBEN_B0 is not set +# CONFIG_C_AMBEN_B0_B1 is not set +# CONFIG_C_AMBEN_B0_B1_B2 is not set +CONFIG_C_AMBEN_ALL=y + +# +# EBIU_AMBCTL Control +# +CONFIG_BANK_0=0x7BB0 +CONFIG_BANK_1=0x5554 +CONFIG_BANK_2=0x7BB0 +CONFIG_BANK_3=0x99B3 + +# +# Bus options (PCI, PCMCIA, EISA, MCA, ISA) +# +# CONFIG_PCI is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Executable file formats +# +CONFIG_BINFMT_ELF_FDPIC=y +CONFIG_BINFMT_FLAT=y +CONFIG_BINFMT_ZFLAT=y +CONFIG_BINFMT_SHARED_FLAT=y +CONFIG_BINFMT_MISC=m + +# +# Power management options +# +# CONFIG_PM is not set + +# +# CPU Frequency scaling +# +# CONFIG_CPU_FREQ is not set + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +CONFIG_XFRM=y +CONFIG_XFRM_USER=m +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# 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 is not set +# CONFIG_IP_PNP_BOOTP is not set +# 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=m +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IP_VS is not set +CONFIG_IPV6=m +# CONFIG_IPV6_PRIVACY is not set +# CONFIG_IPV6_ROUTER_PREF is not set +# CONFIG_IPV6_OPTIMISTIC_DAD is not set +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +CONFIG_IPV6_MIP6=y +CONFIG_INET6_XFRM_TUNNEL=m +CONFIG_INET6_TUNNEL=m +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +CONFIG_INET6_XFRM_MODE_BEET=m +# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set +CONFIG_IPV6_SIT=m +# CONFIG_IPV6_TUNNEL is not set +# CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_NETLABEL is not set +# CONFIG_NETWORK_SECMARK is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_BRIDGE_NETFILTER=y + +# +# Core Netfilter Configuration +# +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NF_CONNTRACK_ENABLED=m +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CT_ACCT=y +CONFIG_NF_CONNTRACK_MARK=y +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CT_PROTO_GRE=m +CONFIG_NF_CT_PROTO_SCTP=m +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_PPTP=m +CONFIG_NF_CONNTRACK_SANE=m +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NF_CT_NETLINK=m +CONFIG_NETFILTER_XTABLES=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +# CONFIG_NETFILTER_XT_TARGET_CONNMARK is not set +# CONFIG_NETFILTER_XT_TARGET_DSCP is not set +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +# CONFIG_NETFILTER_XT_TARGET_NOTRACK is not set +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +CONFIG_NETFILTER_XT_MATCH_DSCP=m +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m + +# +# IP: Netfilter Configuration +# +CONFIG_NF_CONNTRACK_IPV4=m +CONFIG_NF_CONNTRACK_PROC_COMPAT=y +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_IPRANGE=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_RECENT=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_NF_NAT=m +CONFIG_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_SAME=m +CONFIG_NF_NAT_SNMP_BASIC=m +CONFIG_NF_NAT_PROTO_GRE=m +CONFIG_NF_NAT_FTP=m +CONFIG_NF_NAT_IRC=m +CONFIG_NF_NAT_TFTP=m +CONFIG_NF_NAT_AMANDA=m +CONFIG_NF_NAT_PPTP=m +CONFIG_NF_NAT_H323=m +CONFIG_NF_NAT_SIP=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_TOS=m +CONFIG_IP_NF_TARGET_ECN=m +# CONFIG_IP_NF_TARGET_TTL is not set +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m + +# +# IPv6: Netfilter Configuration (EXPERIMENTAL) +# +CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_IP6_NF_QUEUE=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_OWNER=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_RAW=m + +# +# Bridge: Netfilter Configuration +# +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_802_3=m +CONFIG_BRIDGE_EBT_AMONG=m +CONFIG_BRIDGE_EBT_ARP=m +CONFIG_BRIDGE_EBT_IP=m +CONFIG_BRIDGE_EBT_LIMIT=m +CONFIG_BRIDGE_EBT_MARK=m +CONFIG_BRIDGE_EBT_PKTTYPE=m +CONFIG_BRIDGE_EBT_STP=m +CONFIG_BRIDGE_EBT_VLAN=m +CONFIG_BRIDGE_EBT_ARPREPLY=m +CONFIG_BRIDGE_EBT_DNAT=m +CONFIG_BRIDGE_EBT_MARK_T=m +CONFIG_BRIDGE_EBT_REDIRECT=m +CONFIG_BRIDGE_EBT_SNAT=m +CONFIG_BRIDGE_EBT_LOG=m +CONFIG_BRIDGE_EBT_ULOG=m +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +CONFIG_BRIDGE=m +CONFIG_VLAN_8021Q=m +# CONFIG_DECNET is not set +CONFIG_LLC=m +# 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 + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +CONFIG_NET_SCH_FIFO=y +CONFIG_NET_CLS_ROUTE=y + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +CONFIG_BT=m +CONFIG_BT_L2CAP=m +CONFIG_BT_SCO=m +CONFIG_BT_RFCOMM=m +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=m +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_HIDP=m + +# +# Bluetooth device drivers +# +CONFIG_BT_HCIUSB=m +CONFIG_BT_HCIUSB_SCO=y +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUART_BCSP=y +# CONFIG_BT_HCIBCM203X is not set +# CONFIG_BT_HCIBPA10X is not set +# CONFIG_BT_HCIBFUSB is not set +# CONFIG_BT_HCIVHCI is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +CONFIG_CFG80211=m +CONFIG_WIRELESS_EXT=y +CONFIG_MAC80211=m +# CONFIG_MAC80211_LEDS is not set +# CONFIG_MAC80211_DEBUGFS is not set +# CONFIG_MAC80211_DEBUG is not set +CONFIG_IEEE80211=m +# CONFIG_IEEE80211_DEBUG is not set +CONFIG_IEEE80211_CRYPT_WEP=m +CONFIG_IEEE80211_CRYPT_CCMP=m +CONFIG_IEEE80211_CRYPT_TKIP=m +CONFIG_IEEE80211_SOFTMAC=m +# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set +# CONFIG_RFKILL is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_SYS_HYPERVISOR is not set + +# +# Connector - unified userspace <-> kernelspace linker +# +# CONFIG_CONNECTOR is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y + +# +# 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 + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS 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_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +# CONFIG_MTD_MW320D is not set +CONFIG_MTD_CFI_UTIL=y +CONFIG_MTD_RAM=y +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +CONFIG_MTD_COMPLEX_MAPPINGS=y +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_START=0x20000000 +CONFIG_MTD_PHYSMAP_LEN=0x400000 +CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +# CONFIG_MTD_BF5xx is not set +# CONFIG_MTD_UCLINUX is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_DATAFLASH is not set +# CONFIG_MTD_M25P80 is not set +# 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 is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +# CONFIG_MTD_NAND_BFIN is not set +CONFIG_MTD_NAND_IDS=y +CONFIG_MTD_NAND_BF5XX=y +CONFIG_MTD_NAND_BF5XX_HWECC=y +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_NANDSIM is not set +# CONFIG_MTD_NAND_PLATFORM is not set +# CONFIG_MTD_ONENAND is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# +# CONFIG_PNPACPI is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set + +# +# Misc devices +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=y +# CONFIG_BLK_DEV_SR_VENDOR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set + +# +# SCSI low-level drivers +# +# CONFIG_ISCSI_TCP is not set +# CONFIG_SCSI_DEBUG is not set +CONFIG_ATA=y +# CONFIG_ATA_NONSTANDARD is not set +# CONFIG_PATA_PLATFORM is not set +CONFIG_PATA_BF54X=y +CONFIG_PATA_BF54X_DMA=y + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_PHYLIB is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_SMC91X is not set +CONFIG_SMSC911X=y +# CONFIG_DM9000 is not set +CONFIG_NETDEV_1000=y +CONFIG_NETDEV_10000=y + +# +# Wireless LAN +# +# CONFIG_WLAN_PRE80211 is not set +CONFIG_WLAN_80211=y +# CONFIG_LIBERTAS is not set +# CONFIG_HERMES is not set +# CONFIG_USB_ZD1201 is not set +# CONFIG_HOSTAP is not set +# CONFIG_ZD1211RW is not set + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET_MII is not set +# CONFIG_USB_USBNET is not set +# CONFIG_WAN is not set +CONFIG_PPP=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPP_FILTER=y +CONFIG_PPP_ASYNC=m +# CONFIG_PPP_SYNC_TTY is not set +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_MPPE=m +CONFIG_PPPOE=m +# CONFIG_SLIP is not set +CONFIG_SLHC=m +CONFIG_SHAPER=m +CONFIG_NETCONSOLE=m +CONFIG_NETPOLL=y +# CONFIG_NETPOLL_TRAP is not set +CONFIG_NET_POLL_CONTROLLER=y + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +CONFIG_INPUT_FF_MEMLESS=m +# CONFIG_INPUT_POLLDEV is not set + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +CONFIG_INPUT_EVDEV=m +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# 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 is not set +# CONFIG_KEYBOARD_BFIN is not set +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +CONFIG_MOUSE_PS2_ALPS=y +CONFIG_MOUSE_PS2_LOGIPS2PP=y +CONFIG_MOUSE_PS2_SYNAPTICS=y +CONFIG_MOUSE_PS2_LIFEBOOK=y +CONFIG_MOUSE_PS2_TRACKPOINT=y +# CONFIG_MOUSE_PS2_TOUCHKIT is not set +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_APPLETOUCH is not set +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_ADS7846=m +CONFIG_TOUCHSCREEN_AD7877=m +CONFIG_TOUCHSCREEN_GUNZE=m +CONFIG_TOUCHSCREEN_ELO=m +CONFIG_TOUCHSCREEN_MTOUCH=m +CONFIG_TOUCHSCREEN_MK712=m +CONFIG_TOUCHSCREEN_PENMOUNT=m +CONFIG_TOUCHSCREEN_TOUCHRIGHT=m +CONFIG_TOUCHSCREEN_TOUCHWIN=m +CONFIG_TOUCHSCREEN_UCB1400=m +CONFIG_TOUCHSCREEN_USB_COMPOSITE=m +CONFIG_TOUCHSCREEN_USB_EGALAX=y +CONFIG_TOUCHSCREEN_USB_PANJIT=y +CONFIG_TOUCHSCREEN_USB_3M=y +CONFIG_TOUCHSCREEN_USB_ITM=y +CONFIG_TOUCHSCREEN_USB_ETURBO=y +CONFIG_TOUCHSCREEN_USB_GUNZE=y +CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y +CONFIG_INPUT_MISC=y +# CONFIG_INPUT_ATI_REMOTE is not set +# CONFIG_INPUT_ATI_REMOTE2 is not set +# CONFIG_INPUT_KEYSPAN_REMOTE is not set +# CONFIG_INPUT_POWERMATE is not set +# CONFIG_INPUT_YEALINK is not set +# CONFIG_INPUT_UINPUT is not set +# CONFIG_BF53X_PFBUTTONS is not set +# CONFIG_TWI_KEYPAD is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +# CONFIG_AD9960 is not set +# CONFIG_SPI_ADC_BF533 is not set +# CONFIG_BF5xx_PFLAGS is not set +# CONFIG_BF5xx_PPIFCD is not set +# CONFIG_BF5xx_TIMERS is not set +# CONFIG_BF5xx_PPI is not set +# CONFIG_BFIN_SPORT is not set +# CONFIG_BFIN_TIMER_LATENCY is not set +# CONFIG_TWI_LCD is not set +# CONFIG_AD5304 is not set +# CONFIG_BF5xx_TEA5764 is not set +# CONFIG_BF5xx_FBDMA is not set +# CONFIG_VT is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_BFIN=y +CONFIG_SERIAL_BFIN_CONSOLE=y +# CONFIG_SERIAL_BFIN_DMA is not set +CONFIG_SERIAL_BFIN_PIO=y +# CONFIG_SERIAL_BFIN_UART0 is not set +CONFIG_SERIAL_BFIN_UART1=y +# CONFIG_BFIN_UART1_CTSRTS is not set +# CONFIG_SERIAL_BFIN_UART2 is not set +# CONFIG_SERIAL_BFIN_UART3 is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_BFIN_SPORT is not set +CONFIG_UNIX98_PTYS=y +# CONFIG_LEGACY_PTYS is not set + +# +# CAN, the car bus and industrial fieldbus +# +# CONFIG_CAN4LINUX is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_BFIN_WDT=y + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set +CONFIG_HW_RANDOM=y +# CONFIG_GEN_RTC is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=y + +# +# I2C Algorithms +# +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_BLACKFIN_GPIO is not set +CONFIG_I2C_BLACKFIN_TWI=y +CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=50 +# CONFIG_I2C_GPIO is not set +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_TINY_USB is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_SENSORS_DS1337 is not set +# CONFIG_SENSORS_DS1374 is not set +# CONFIG_SENSORS_AD5252 is not set +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCF8575 is not set +# CONFIG_SENSORS_PCA9543 is not set +# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_MAX6875 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# SPI support +# +CONFIG_SPI=y +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +CONFIG_SPI_BFIN=y +# CONFIG_SPI_BITBANG is not set + +# +# SPI Protocol Masters +# +# CONFIG_SPI_AT25 is not set +# CONFIG_SPI_SPIDEV is not set + +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_ABITUGURU is not set +# CONFIG_SENSORS_AD7418 is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1029 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_ATXP1 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM70 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_MAX6650 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47M192 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_VT1211 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83791D is not set +# CONFIG_SENSORS_W83792D is not set +# CONFIG_SENSORS_W83793 is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set + +# +# Multimedia devices +# +CONFIG_VIDEO_DEV=m +CONFIG_VIDEO_V4L1=y +CONFIG_VIDEO_V4L1_COMPAT=y +CONFIG_VIDEO_V4L2=y +CONFIG_VIDEO_CAPTURE_DRIVERS=y +# CONFIG_VIDEO_ADV_DEBUG is not set +CONFIG_VIDEO_HELPER_CHIPS_AUTO=y +# CONFIG_VIDEO_CPIA is not set +# CONFIG_VIDEO_CPIA2 is not set +# CONFIG_VIDEO_SAA5246A is not set +# CONFIG_VIDEO_SAA5249 is not set +# CONFIG_TUNER_3036 is not set +CONFIG_V4L_USB_DRIVERS=y +# CONFIG_VIDEO_PVRUSB2 is not set +# CONFIG_VIDEO_EM28XX is not set +# CONFIG_VIDEO_USBVISION is not set +# CONFIG_USB_VICAM is not set +# CONFIG_USB_IBMCAM is not set +# CONFIG_USB_KONICAWC is not set +# CONFIG_USB_QUICKCAM_MESSENGER is not set +# CONFIG_USB_ET61X251 is not set +# CONFIG_VIDEO_OVCAMCHIP is not set +# CONFIG_USB_W9968CF is not set +# CONFIG_USB_OV511 is not set +# CONFIG_USB_SE401 is not set +# CONFIG_USB_SN9C102 is not set +# CONFIG_USB_STV680 is not set +# CONFIG_USB_ZC0301 is not set +# CONFIG_USB_PWC is not set +# CONFIG_USB_ZR364XX is not set +# CONFIG_VIDEO_BLACKFIN_CAM is not set +# CONFIG_VIDEO_BLACKFIN_MT9M001 is not set + +# +# CMOS Camera Sensor Selection +# +CONFIG_RADIO_ADAPTERS=y +# CONFIG_USB_DSBR is not set +CONFIG_DVB_CORE=m +CONFIG_DVB_CORE_ATTACH=y +CONFIG_DVB_CAPTURE_DRIVERS=y + +# +# Supported USB Adapters +# +# CONFIG_DVB_USB is not set +# CONFIG_DVB_TTUSB_BUDGET is not set +# CONFIG_DVB_TTUSB_DEC is not set +# CONFIG_DVB_CINERGYT2 is not set + +# +# Supported FlexCopII (B2C2) Adapters +# +# CONFIG_DVB_B2C2_FLEXCOP is not set + +# +# Supported DVB Frontends +# + +# +# Customise DVB Frontends +# +# CONFIG_DVB_FE_CUSTOMISE is not set + +# +# DVB-S (satellite) frontends +# +# CONFIG_DVB_STV0299 is not set +# CONFIG_DVB_CX24110 is not set +# CONFIG_DVB_CX24123 is not set +# CONFIG_DVB_TDA8083 is not set +# CONFIG_DVB_MT312 is not set +# CONFIG_DVB_VES1X93 is not set +# CONFIG_DVB_S5H1420 is not set +# CONFIG_DVB_TDA10086 is not set + +# +# DVB-T (terrestrial) frontends +# +# CONFIG_DVB_SP8870 is not set +# CONFIG_DVB_SP887X is not set +# CONFIG_DVB_CX22700 is not set +# CONFIG_DVB_CX22702 is not set +# CONFIG_DVB_L64781 is not set +# CONFIG_DVB_TDA1004X is not set +# CONFIG_DVB_NXT6000 is not set +# CONFIG_DVB_MT352 is not set +# CONFIG_DVB_ZL10353 is not set +# CONFIG_DVB_DIB3000MB is not set +# CONFIG_DVB_DIB3000MC is not set +# CONFIG_DVB_DIB7000M is not set +# CONFIG_DVB_DIB7000P is not set + +# +# DVB-C (cable) frontends +# +# CONFIG_DVB_VES1820 is not set +# CONFIG_DVB_TDA10021 is not set +# CONFIG_DVB_TDA10023 is not set +# CONFIG_DVB_STV0297 is not set + +# +# ATSC (North American/Korean Terrestrial/Cable DTV) frontends +# +# CONFIG_DVB_NXT200X is not set +# CONFIG_DVB_OR51211 is not set +# CONFIG_DVB_OR51132 is not set +# CONFIG_DVB_BCM3510 is not set +# CONFIG_DVB_LGDT330X is not set + +# +# Tuners/PLL support +# +# CONFIG_DVB_PLL is not set +# CONFIG_DVB_TDA826X is not set +# CONFIG_DVB_TDA827X is not set +# CONFIG_DVB_TUNER_QT1010 is not set +# CONFIG_DVB_TUNER_MT2060 is not set + +# +# Miscellaneous devices +# +# CONFIG_DVB_LNBP21 is not set +# CONFIG_DVB_ISL6421 is not set +# CONFIG_DVB_TUA6100 is not set +CONFIG_DAB=y +CONFIG_USB_DABUSB=m + +# +# Graphics support +# +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_BACKLIGHT_CLASS_DEVICE=m +CONFIG_LCD_CLASS_DEVICE=m + +# +# Display device support +# +CONFIG_DISPLAY_SUPPORT=m + +# +# Display hardware drivers +# +# CONFIG_VGASTATE is not set +CONFIG_FB=y +CONFIG_FIRMWARE_EDID=y +# CONFIG_FB_DDC is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_SYS_FOPS is not set +CONFIG_FB_DEFERRED_IO=y +# 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_BFIN_7171 is not set +# CONFIG_FB_BFIN_7393 is not set +CONFIG_FB_BF54X_LQ043=y +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_LOGO is not set + +# +# Sound +# +# CONFIG_SOUND is not set +CONFIG_AC97_BUS=m + +# +# HID Devices +# +CONFIG_HID=m +# CONFIG_HID_DEBUG is not set + +# +# USB Input Devices +# +CONFIG_USB_HID=m +# CONFIG_USB_HIDINPUT_POWERBOOK is not set +# CONFIG_HID_FF is not set +# CONFIG_USB_HIDDEV is not set + +# +# USB HID Boot Protocol drivers +# +# CONFIG_USB_KBD is not set +# CONFIG_USB_MOUSE is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB_ARCH_HAS_EHCI is not set +CONFIG_USB=m +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +CONFIG_USB_DEVICE_CLASS=y +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG is not set + +# +# USB Host Controller Drivers +# +CONFIG_USB_ISP116X_HCD=m +# CONFIG_USB_ISP1362_HCD is not set +CONFIG_USB_ISP1760_HCD=m +CONFIG_USB_SL811_HCD=m +CONFIG_USB_BF54x_HCD=m +# CONFIG_USB_MUSB_HDRC is not set + +# +# USB Device Class drivers +# +CONFIG_USB_ACM=m +CONFIG_USB_PRINTER=m + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# may also be needed; see USB_STORAGE Help for more information +# +CONFIG_USB_STORAGE=m +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_ONETOUCH is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set +CONFIG_USB_MON=y + +# +# USB port drivers +# + +# +# USB Serial Converter support +# +CONFIG_USB_SERIAL=m +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_AIRCABLE=m +CONFIG_USB_SERIAL_AIRPRIME=m +CONFIG_USB_SERIAL_ARK3116=m +CONFIG_USB_SERIAL_BELKIN=m +CONFIG_USB_SERIAL_WHITEHEAT=m +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_SERIAL_CP2101=m +CONFIG_USB_SERIAL_CYPRESS_M8=m +CONFIG_USB_SERIAL_EMPEG=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_FUNSOFT=m +CONFIG_USB_SERIAL_VISOR=m +CONFIG_USB_SERIAL_IPAQ=m +CONFIG_USB_SERIAL_IR=m +CONFIG_USB_SERIAL_EDGEPORT=m +CONFIG_USB_SERIAL_EDGEPORT_TI=m +CONFIG_USB_SERIAL_GARMIN=m +CONFIG_USB_SERIAL_IPW=m +CONFIG_USB_SERIAL_KEYSPAN_PDA=m +CONFIG_USB_SERIAL_KEYSPAN=m +CONFIG_USB_SERIAL_KEYSPAN_MPR=y +CONFIG_USB_SERIAL_KEYSPAN_USA28=y +CONFIG_USB_SERIAL_KEYSPAN_USA28X=y +CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y +CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y +CONFIG_USB_SERIAL_KEYSPAN_USA19=y +CONFIG_USB_SERIAL_KEYSPAN_USA18X=y +CONFIG_USB_SERIAL_KEYSPAN_USA19W=y +CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y +CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y +CONFIG_USB_SERIAL_KEYSPAN_USA49W=y +CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y +CONFIG_USB_SERIAL_KLSI=m +CONFIG_USB_SERIAL_KOBIL_SCT=m +CONFIG_USB_SERIAL_MCT_U232=m +CONFIG_USB_SERIAL_MOS7720=m +CONFIG_USB_SERIAL_MOS7840=m +CONFIG_USB_SERIAL_NAVMAN=m +CONFIG_USB_SERIAL_PL2303=m +CONFIG_USB_SERIAL_HP4X=m +CONFIG_USB_SERIAL_SAFE=m +# CONFIG_USB_SERIAL_SAFE_PADDED is not set +CONFIG_USB_SERIAL_SIERRAWIRELESS=m +CONFIG_USB_SERIAL_TI=m +CONFIG_USB_SERIAL_CYBERJACK=m +CONFIG_USB_SERIAL_XIRCOM=m +# CONFIG_USB_SERIAL_OPTION is not set +CONFIG_USB_SERIAL_OMNINET=m +CONFIG_USB_SERIAL_DEBUG=m +CONFIG_USB_EZUSB=y + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_BERRY_CHARGE is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGET is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set + +# +# USB DSL modem support +# + +# +# USB Gadget Support +# +CONFIG_USB_GADGET=m +# CONFIG_USB_GADGET_DEBUG_FILES is not set +CONFIG_USB_GADGET_SELECTED=y +# CONFIG_USB_GADGET_FSL_USB2 is not set +CONFIG_USB_GADGET_NET2272=y +CONFIG_USB_NET2272=m +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_PXA2XX is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_DUMMY_HCD is not set +CONFIG_USB_GADGET_DUALSPEED=y +CONFIG_USB_ZERO=m +CONFIG_USB_ETH=m +CONFIG_USB_ETH_RNDIS=y +CONFIG_USB_GADGETFS=m +CONFIG_USB_FILE_STORAGE=m +CONFIG_USB_FILE_STORAGE_TEST=y +CONFIG_USB_G_SERIAL=m +# CONFIG_USB_MIDI_GADGET is not set +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +CONFIG_MMC_UNSAFE_RESUME=y + +# +# MMC/SD Card Drivers +# +CONFIG_MMC_BLOCK=y + +# +# MMC/SD Host Controller Drivers +# +# CONFIG_SDH_BFIN is not set +# CONFIG_SPI_MMC is not set + +# +# LED devices +# +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=m + +# +# LED drivers +# + +# +# LED Triggers +# +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_TIMER=m +CONFIG_LEDS_TRIGGER_HEARTBEAT=m + +# +# InfiniBand support +# + +# +# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) +# + +# +# Real Time Clock +# +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set + +# +# SPI RTC drivers +# +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_MAX6902 is not set + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# on-CPU RTC drivers +# +CONFIG_RTC_DRV_BFIN=y + +# +# DMA Engine support +# +CONFIG_DMA_ENGINE=y + +# +# DMA Clients +# +CONFIG_NET_DMA=y + +# +# DMA Devices +# + +# +# PBX support +# +# CONFIG_PBX is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +# CONFIG_EXT2_FS_POSIX_ACL is not set +# CONFIG_EXT2_FS_SECURITY is not set +CONFIG_EXT3_FS=m +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +# CONFIG_EXT4DEV_FS is not set +CONFIG_JBD=m +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +CONFIG_FS_POSIX_ACL=y +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +CONFIG_FUSE_FS=m + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=m +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +# CONFIG_MSDOS_FS is not set +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y +CONFIG_CONFIGFS_FS=m + +# +# Miscellaneous filesystems +# +# 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_YAFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +CONFIG_JFFS2_SUMMARY=y +# CONFIG_JFFS2_FS_XATTR is not set +CONFIG_JFFS2_COMPRESSION_OPTIONS=y +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_JFFS2_CMODE_NONE is not set +CONFIG_JFFS2_CMODE_PRIORITY=y +# CONFIG_JFFS2_CMODE_SIZE is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +CONFIG_NFS_V4=y +CONFIG_NFS_DIRECTIO=y +CONFIG_NFSD=m +CONFIG_NFSD_V2_ACL=y +CONFIG_NFSD_V3=y +CONFIG_NFSD_V3_ACL=y +CONFIG_NFSD_V4=y +CONFIG_NFSD_TCP=y +CONFIG_LOCKD=m +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=m +CONFIG_NFS_ACL_SUPPORT=m +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=m +CONFIG_SUNRPC_GSS=m +CONFIG_SUNRPC_BIND34=y +CONFIG_RPCSEC_GSS_KRB5=m +# CONFIG_RPCSEC_GSS_SPKM3 is not set +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +CONFIG_CIFS=m +CONFIG_CIFS_STATS=y +# CONFIG_CIFS_STATS2 is not set +# CONFIG_CIFS_WEAK_PW_HASH is not set +CONFIG_CIFS_XATTR=y +# CONFIG_CIFS_POSIX is not set +# CONFIG_CIFS_DEBUG2 is not set +# CONFIG_CIFS_EXPERIMENTAL is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +CONFIG_NLS=m +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# 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 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +# CONFIG_NLS_ISO8859_1 is not set +# 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 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Distributed Lock Manager +# +# CONFIG_DLM is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_KERNEL is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_DEBUG_MMRS=y +CONFIG_DEBUG_HUNT_FOR_ZERO=y +CONFIG_DEBUG_BFIN_HWTRACE_ON=y +CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_OFF=y +# CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_ONE is not set +# CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_TWO is not set +CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION=0 +# CONFIG_DEBUG_BFIN_HWTRACE_EXPAND is not set +# CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE is not set +CONFIG_EARLY_PRINTK=y +CONFIG_CPLB_INFO=y +CONFIG_ACCESS_CHECK=y + +# +# Security options +# +# CONFIG_KEYS is not set +CONFIG_SECURITY=y +# CONFIG_SECURITY_NETWORK is not set +CONFIG_SECURITY_CAPABILITIES=y +# CONFIG_SECURITY_ROOTPLUG is not set + +# +# Cryptographic options +# +CONFIG_CRYPTO=y +CONFIG_CRYPTO_ALGAPI=m +CONFIG_CRYPTO_BLKCIPHER=m +CONFIG_CRYPTO_HASH=m +CONFIG_CRYPTO_MANAGER=m +CONFIG_CRYPTO_HMAC=m +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=m +CONFIG_CRYPTO_SHA1=m +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_GF128MUL is not set +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_CBC=m +CONFIG_CRYPTO_PCBC=m +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_CRYPTD is not set +CONFIG_CRYPTO_DES=m +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_SERPENT is not set +CONFIG_CRYPTO_AES=m +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_TEA is not set +CONFIG_CRYPTO_ARC4=m +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set +CONFIG_CRYPTO_DEFLATE=m +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_CRC32C=m +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_CRC_CCITT=m +# CONFIG_CRC16 is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +CONFIG_LIBCRC32C=m +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_KMP=m +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y diff --git a/packages/linux/linux-bfin_svn.bb b/packages/linux/linux-bfin_svn.bb new file mode 100644 index 0000000000..ee5b04910f --- /dev/null +++ b/packages/linux/linux-bfin_svn.bb @@ -0,0 +1,15 @@ +require linux.inc + +PV = "2.6.22.10+svnr${SRCREV}" + +SRC_URI = "svn://sources.blackfin.uclinux.org/linux-kernel/;module=trunk \ + file://defconfig \ + " + +S = "${WORKDIR}/trunk" + +do_configure_prepend() { + rm localversion.adi || true +} + + diff --git a/packages/linux/linux-efika-2.6.20.20/.mtn2git_empty b/packages/linux/linux-efika-2.6.20.20/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/packages/linux/linux-efika-2.6.20.20/.mtn2git_empty diff --git a/packages/linux/linux-efika-2.6.20.11/sched-cfs-v9-v2.6.20.11.patch b/packages/linux/linux-efika-2.6.20.20/sched-cfs-v9-v2.6.20.11.patch index 29071a99ac..29071a99ac 100644 --- a/packages/linux/linux-efika-2.6.20.11/sched-cfs-v9-v2.6.20.11.patch +++ b/packages/linux/linux-efika-2.6.20.20/sched-cfs-v9-v2.6.20.11.patch diff --git a/packages/linux/linux-efika-2.6.20.20/weaken-div64_32-symbol.patch b/packages/linux/linux-efika-2.6.20.20/weaken-div64_32-symbol.patch new file mode 100644 index 0000000000..bd6fb98f61 --- /dev/null +++ b/packages/linux/linux-efika-2.6.20.20/weaken-div64_32-symbol.patch @@ -0,0 +1,23 @@ +2.6.20.20 with CFS fails to compile for powerpc, because this arch already has +its assembly-optimized __div64_32() implementation, so linking fails due to +two symbols. + +The same issue appeared on the s390 arch, so this patch is inspired by it. + +http://lkml.org/lkml/2007/4/11/24 + +Leon 'likewise' Woestenberg <leonw@mailcan.com> + +Index: linux-2.6.20/lib/div64.c +=================================================================== +--- linux-2.6.20.orig/lib/div64.c 2007-10-07 16:19:38.000000000 +0200 ++++ linux-2.6.20/lib/div64.c 2007-10-07 16:20:15.000000000 +0200 +@@ -23,7 +23,7 @@ + /* Not needed on 64bit architectures */ + #if BITS_PER_LONG == 32 + +-uint32_t __div64_32(uint64_t *n, uint32_t base) ++uint32_t __attribute__((weak)) __div64_32(uint64_t *n, uint32_t base) + { + uint64_t rem = *n; + uint64_t b = base; diff --git a/packages/linux/linux-efika-2.6.20/defconfig b/packages/linux/linux-efika-2.6.20/defconfig index fb7c9109bf..c68d7f1d1c 100644 --- a/packages/linux/linux-efika-2.6.20/defconfig +++ b/packages/linux/linux-efika-2.6.20/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.20 -# Tue Feb 27 05:45:18 2007 +# Linux kernel version: 2.6.20.20-cfs-v22 +# Sun Oct 7 15:39:14 2007 # # CONFIG_PPC64 is not set CONFIG_PPC32=y @@ -53,6 +53,7 @@ CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # CONFIG_EXPERIMENTAL=y CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y CONFIG_INIT_ENV_ARG_LIMIT=32 # @@ -69,6 +70,8 @@ CONFIG_POSIX_MQUEUE=y # CONFIG_UTS_NS is not set # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set +CONFIG_FAIR_GROUP_SCHED=y +CONFIG_FAIR_USER_SCHED=y # CONFIG_SYSFS_DEPRECATED is not set # CONFIG_RELAY is not set CONFIG_INITRAMFS_SOURCE="" @@ -165,9 +168,10 @@ CONFIG_USE_MDIO=y # CONFIG_HZ_300 is not set CONFIG_HZ_1000=y CONFIG_HZ=1000 -CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_NONE is not set # CONFIG_PREEMPT_VOLUNTARY is not set -# CONFIG_PREEMPT is not set +CONFIG_PREEMPT=y +CONFIG_PREEMPT_BKL=y CONFIG_BINFMT_ELF=y CONFIG_BINFMT_MISC=y CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y @@ -186,8 +190,13 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_PROC_DEVICETREE=y CONFIG_CMDLINE_BOOL=y CONFIG_CMDLINE="console=ttyS0,9600 console=ttyPSC0,115200" -# CONFIG_PM is not set -CONFIG_SECCOMP=y +CONFIG_PM=y +# CONFIG_PM_LEGACY is not set +CONFIG_PM_DEBUG=y +# CONFIG_DISABLE_CONSOLE_SUSPEND is not set +# CONFIG_PM_SYSFS_DEPRECATED is not set +# CONFIG_SOFTWARE_SUSPEND is not set +# CONFIG_SECCOMP is not set CONFIG_ISA_DMA_API=y # @@ -1118,7 +1127,115 @@ CONFIG_LOGO=y # # Sound # -# CONFIG_SOUND is not set +CONFIG_SOUND=m + +# +# Advanced Linux Sound Architecture +# +CONFIG_SND=m +CONFIG_SND_TIMER=m +CONFIG_SND_PCM=m +# CONFIG_SND_SEQUENCER is not set +# CONFIG_SND_MIXER_OSS is not set +# CONFIG_SND_PCM_OSS is not set +# CONFIG_SND_DYNAMIC_MINORS is not set +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +CONFIG_SND_DEBUG=y +# CONFIG_SND_DEBUG_DETECT is not set +CONFIG_SND_PCM_XRUN_DEBUG=y + +# +# Generic devices +# +CONFIG_SND_AC97_CODEC=m +# CONFIG_SND_DUMMY is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set + +# +# PCI devices +# +# CONFIG_SND_AD1889 is not set +# CONFIG_SND_ALS300 is not set +# CONFIG_SND_ALS4000 is not set +# CONFIG_SND_ALI5451 is not set +# CONFIG_SND_ATIIXP is not set +# CONFIG_SND_ATIIXP_MODEM is not set +# CONFIG_SND_AU8810 is not set +# CONFIG_SND_AU8820 is not set +# CONFIG_SND_AU8830 is not set +# CONFIG_SND_AZT3328 is not set +# CONFIG_SND_BT87X is not set +# CONFIG_SND_CA0106 is not set +# CONFIG_SND_CMIPCI is not set +# CONFIG_SND_CS4281 is not set +# CONFIG_SND_CS46XX is not set +# CONFIG_SND_DARLA20 is not set +# CONFIG_SND_GINA20 is not set +# CONFIG_SND_LAYLA20 is not set +# CONFIG_SND_DARLA24 is not set +# CONFIG_SND_GINA24 is not set +# CONFIG_SND_LAYLA24 is not set +# CONFIG_SND_MONA is not set +# CONFIG_SND_MIA is not set +# CONFIG_SND_ECHO3G is not set +# CONFIG_SND_INDIGO is not set +# CONFIG_SND_INDIGOIO is not set +# CONFIG_SND_INDIGODJ is not set +# CONFIG_SND_EMU10K1 is not set +# CONFIG_SND_EMU10K1X is not set +# CONFIG_SND_ENS1370 is not set +# CONFIG_SND_ENS1371 is not set +# CONFIG_SND_ES1938 is not set +# CONFIG_SND_ES1968 is not set +# CONFIG_SND_FM801 is not set +# CONFIG_SND_HDA_INTEL is not set +# CONFIG_SND_HDSP is not set +# CONFIG_SND_HDSPM is not set +# CONFIG_SND_ICE1712 is not set +# CONFIG_SND_ICE1724 is not set +# CONFIG_SND_INTEL8X0 is not set +# CONFIG_SND_INTEL8X0M is not set +# CONFIG_SND_KORG1212 is not set +# CONFIG_SND_MAESTRO3 is not set +# CONFIG_SND_MIXART is not set +# CONFIG_SND_NM256 is not set +# CONFIG_SND_PCXHR is not set +# CONFIG_SND_RIPTIDE is not set +# CONFIG_SND_RME32 is not set +# CONFIG_SND_RME96 is not set +# CONFIG_SND_RME9652 is not set +# CONFIG_SND_SONICVIBES is not set +# CONFIG_SND_TRIDENT is not set +# CONFIG_SND_VIA82XX is not set +# CONFIG_SND_VIA82XX_MODEM is not set +# CONFIG_SND_VX222 is not set +# CONFIG_SND_YMFPCI is not set +# CONFIG_SND_AC97_POWER_SAVE is not set + +# +# ALSA PowerMac devices +# + +# +# ALSA PPC devices +# +CONFIG_SND_PPC_MPC52xx_AC97=m + +# +# USB devices +# +# CONFIG_SND_USB_AUDIO is not set +# CONFIG_SND_USB_USX2Y is not set + +# +# Open Sound System +# +# CONFIG_SOUND_PRIME is not set +CONFIG_AC97_BUS=m # # HID Devices @@ -1140,6 +1257,7 @@ CONFIG_USB=y CONFIG_USB_DEVICEFS=y CONFIG_USB_BANDWIDTH=y CONFIG_USB_DYNAMIC_MINORS=y +# CONFIG_USB_SUSPEND is not set # CONFIG_USB_OTG is not set # @@ -1183,7 +1301,6 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_STORAGE_SDDR55 is not set # CONFIG_USB_STORAGE_JUMPSHOT is not set # CONFIG_USB_STORAGE_ALAUDA is not set -# CONFIG_USB_STORAGE_ONETOUCH is not set # CONFIG_USB_STORAGE_KARMA is not set # CONFIG_USB_LIBUSUAL is not set diff --git a/packages/linux/linux-efika_2.6.20.11.bb b/packages/linux/linux-efika_2.6.20.20.bb index 2113b27be9..b8877fa5c3 100644 --- a/packages/linux/linux-efika_2.6.20.11.bb +++ b/packages/linux/linux-efika_2.6.20.20.bb @@ -41,12 +41,12 @@ SRC_URI = "${KERNELORG_MIRROR}/pub/linux/kernel/v2.6/linux-2.6.20.tar.bz2 \ file://0032-POWERPC-EFIKA-Adds-missing-interrupts-from-bestcomm-node.txt;p=1;patch=1 \ file://0033-EFIKA-fullduplex-prpl_aln.txt;p=1;patch=1 \ file://v4l.diff;p=1;patch=1 \ - http://www.kernel.org/pub/linux/kernel/v2.6/patch-2.6.20.11.bz2;p=1;patch=1 \ - file://sched-cfs-v9-v2.6.20.11.patch;p=1;patch=1 \ + http://www.kernel.org/pub/linux/kernel/v2.6/patch-2.6.20.20.bz2;p=1;patch=1 \ + http://people.redhat.com/mingo/cfs-scheduler/sched-cfs-v2.6.20.20-v22.patch;p=1;patch=1 \ + file://weaken-div64_32-symbol.patch;patch=1 \ file://defconfig \ " - S = "${WORKDIR}/linux-2.6.20" inherit kernel @@ -71,8 +71,6 @@ do_stage_append () { cp -a include/asm-ppc ${STAGING_KERNEL_DIR}/include/ } - - do_deploy() { install -d ${DEPLOY_DIR_IMAGE} install -m 0644 arch/${ARCH}/boot/${KERNEL_IMAGETYPE} ${DEPLOY_DIR_IMAGE}/${KERNEL_IMAGETYPE}-${PV}-${MACHINE}-${DATETIME} diff --git a/packages/linux/linux-handhelds-2.6.inc b/packages/linux/linux-handhelds-2.6.inc index 47c32a4a24..d2256b5f27 100644 --- a/packages/linux/linux-handhelds-2.6.inc +++ b/packages/linux/linux-handhelds-2.6.inc @@ -3,7 +3,7 @@ DESCRIPTION = "handhelds.org Linux kernel 2.6 for PocketPCs and other consumer h LICENSE = "GPL" COMPATIBLE_HOST = "arm.*-linux" -COMPATIBLE_MACHINE ?= '(asus620|asus730|aximx50|aximx50v|h1910|h2200|h3600|h3800|h3900|h4000|h5000|htcalpine|htcapache|htcblueangel|htchermes|htchimalaya|htcuniversal|htcwallaby|hx4700|looxc550|jornada56x|magician|rx1950|rx3000)' +COMPATIBLE_MACHINE ?= '(asus620|asus730|aximx50|aximx50v|h1910|h2200|h3600|h3800|h3900|h4000|h5000|htcalpine|htcapache|htcblueangel|htchermes|htchimalaya|htcsable|htcuniversal|htcwallaby|hx4700|ghi270|looxc550|jornada56x|magician|rx1950|rx3000)' # SRC_URI *must* be overriden in includer, but this is a good reference SRC_URI ?= "${HANDHELDS_CVS};module=linux/kernel26;tag=${@'K' + bb.data.getVar('PV',d,1).replace('.', '-')} \ diff --git a/packages/linux/linux-handhelds-2.6/ghi270/.mtn2git_empty b/packages/linux/linux-handhelds-2.6/ghi270/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/packages/linux/linux-handhelds-2.6/ghi270/.mtn2git_empty diff --git a/packages/linux/linux-handhelds-2.6_2.6.21-hh11.bb b/packages/linux/linux-handhelds-2.6_2.6.21-hh11.bb new file mode 100644 index 0000000000..7e3f93c92e --- /dev/null +++ b/packages/linux/linux-handhelds-2.6_2.6.21-hh11.bb @@ -0,0 +1,13 @@ +SECTION = "kernel" +DESCRIPTION = "handhelds.org Linux kernel 2.6 for PocketPCs and other consumer handheld devices." +LICENSE = "GPL" +PR = "r1" + +DEFAULT_PREFERENCE = "-1" + +SRC_URI = "${HANDHELDS_CVS};module=linux/kernel26;tag=${@'K' + bb.data.getVar('PV',d,1).replace('.', '-')} \ + file://defconfig" + +SRC_URI_append_ghi270 = " file://ghi270-hh11.patch;patch=1" + +require linux-handhelds-2.6.inc diff --git a/packages/linux/linux-handhelds-2.6_2.6.21-hh17.bb b/packages/linux/linux-handhelds-2.6_2.6.21-hh17.bb new file mode 100644 index 0000000000..275602762d --- /dev/null +++ b/packages/linux/linux-handhelds-2.6_2.6.21-hh17.bb @@ -0,0 +1,11 @@ +SECTION = "kernel" +DESCRIPTION = "handhelds.org Linux kernel 2.6 for PocketPCs and other consumer handheld devices." +LICENSE = "GPL" +PR = "r2" + +DEFAULT_PREFERENCE = "-1" + +SRC_URI = "${HANDHELDS_CVS};module=linux/kernel26;tag=${@'K' + bb.data.getVar('PV',d,1).replace('.', '-')} \ + file://defconfig" + +require linux-handhelds-2.6.inc diff --git a/packages/linux/linux-openmoko-devel/defconfig b/packages/linux/linux-openmoko-devel/defconfig-2.6.23.1 index f7274016c8..2419f90981 100644 --- a/packages/linux/linux-openmoko-devel/defconfig +++ b/packages/linux/linux-openmoko-devel/defconfig-2.6.23.1 @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.22.1 -# Thu Jul 26 22:01:38 2007 +# Linux kernel version: 2.6.23-rc9 +# Tue Oct 9 15:27:11 2007 # CONFIG_ARM=y CONFIG_SYS_SUPPORTS_APM_EMULATION=y @@ -26,26 +26,21 @@ CONFIG_VECTORS_BASE=0xffff0000 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # -# Code maturity level options +# General setup # CONFIG_EXPERIMENTAL=y CONFIG_BROKEN_ON_SMP=y CONFIG_LOCK_KERNEL=y CONFIG_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# CONFIG_LOCALVERSION="-moko11" # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SWAP=y CONFIG_SYSVIPC=y -# CONFIG_IPC_NS is not set CONFIG_SYSVIPC_SYSCTL=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set -# CONFIG_UTS_NS is not set +# CONFIG_USER_NS is not set # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 @@ -70,7 +65,6 @@ CONFIG_FUTEX=y CONFIG_ANON_INODES=y CONFIG_EPOLL=y CONFIG_SIGNALFD=y -CONFIG_TIMERFD=y CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_VM_EVENT_COUNTERS=y @@ -80,24 +74,17 @@ CONFIG_SLAB=y CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 - -# -# Loadable module support -# CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_KMOD=y - -# -# Block layer -# CONFIG_BLOCK=y # CONFIG_LBD is not set # CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_LSF is not set +# CONFIG_BLK_DEV_BSG is not set # # IO Schedulers @@ -138,6 +125,7 @@ CONFIG_DEFAULT_IOSCHED="deadline" # CONFIG_ARCH_L7200 is not set # CONFIG_ARCH_KS8695 is not set # CONFIG_ARCH_NS9XXX is not set +# CONFIG_ARCH_MXC is not set # CONFIG_ARCH_PNX4008 is not set # CONFIG_ARCH_PXA is not set # CONFIG_ARCH_RPC is not set @@ -149,14 +137,25 @@ CONFIG_ARCH_S3C2410=y # CONFIG_ARCH_OMAP is not set CONFIG_PLAT_S3C24XX=y CONFIG_CPU_S3C244X=y -# CONFIG_S3C2410_BOOT_WATCHDOG is not set -CONFIG_S3C2410_BOOT_ERROR_RESET=y -CONFIG_S3C2410_PM_DEBUG=y -# CONFIG_S3C2410_PM_CHECK is not set -CONFIG_S3C2410_LOWLEVEL_UART_PORT=0 CONFIG_S3C2410_DMA=y # CONFIG_S3C2410_DMA_DEBUG is not set CONFIG_MACH_SMDK=y +CONFIG_PLAT_S3C=y +CONFIG_CPU_LLSERIAL_S3C2410=y +CONFIG_CPU_LLSERIAL_S3C2440=y + +# +# Boot options +# +# CONFIG_S3C_BOOT_WATCHDOG is not set +# CONFIG_S3C_BOOT_ERROR_RESET is not set + +# +# Power management +# +CONFIG_S3C2410_PM_DEBUG=y +# CONFIG_S3C2410_PM_CHECK is not set +CONFIG_S3C_LOWLEVEL_UART_PORT=0 # # S3C2400 Machines @@ -200,6 +199,7 @@ CONFIG_ARCH_S3C2440=y CONFIG_SMDK2440_CPU2440=y CONFIG_MACH_HXD8=y CONFIG_MACH_NEO1973_GTA02=y +CONFIG_CPU_S3C2442=y # # S3C2442 Machines @@ -237,6 +237,7 @@ CONFIG_ARM_THUMB=y # # Bus support # +# CONFIG_PCI_SYSCALL is not set # CONFIG_ARCH_SUPPORTS_MSI is not set # @@ -251,7 +252,8 @@ CONFIG_ARM_THUMB=y CONFIG_PREEMPT=y CONFIG_NO_IDLE_HZ=y CONFIG_HZ=200 -# CONFIG_AEABI is not set +CONFIG_AEABI=y +CONFIG_OABI_COMPAT=y # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set CONFIG_SELECT_MEMORY_MODEL=y CONFIG_FLATMEM_MANUAL=y @@ -263,6 +265,8 @@ CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_SPLIT_PTLOCK_CPUS=4096 # CONFIG_RESOURCES_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 +CONFIG_BOUNCE=y +CONFIG_VIRT_TO_BUS=y CONFIG_ALIGNMENT_TRAP=y # @@ -270,7 +274,7 @@ CONFIG_ALIGNMENT_TRAP=y # CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE="ip=192.168.1.2:192.168.1.10:192.168.1.10:255.255.255.0:ezx:usb0:off" +CONFIG_CMDLINE="unused -- bootloader passes ATAG list" # CONFIG_XIP_KERNEL is not set CONFIG_KEXEC=y @@ -282,6 +286,7 @@ CONFIG_KEXEC=y # At least one emulation must be selected # CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set # CONFIG_FPE_FASTFPE is not set # @@ -290,7 +295,6 @@ CONFIG_FPE_NWFPE=y CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_AOUT is not set # CONFIG_BINFMT_MISC is not set -# CONFIG_ARTHUR is not set # # Power management options @@ -298,8 +302,11 @@ CONFIG_BINFMT_ELF=y CONFIG_PM=y CONFIG_PM_LEGACY=y CONFIG_PM_DEBUG=y +# CONFIG_PM_VERBOSE is not set CONFIG_DISABLE_CONSOLE_SUSPEND=y -# CONFIG_PM_SYSFS_DEPRECATED is not set +CONFIG_PM_SLEEP=y +CONFIG_SUSPEND_UP_POSSIBLE=y +CONFIG_SUSPEND=y CONFIG_APM_EMULATION=y # @@ -388,6 +395,7 @@ CONFIG_NF_CONNTRACK_MARK=y CONFIG_NF_CONNTRACK_EVENTS=y CONFIG_NF_CT_PROTO_GRE=m CONFIG_NF_CT_PROTO_SCTP=m +# CONFIG_NF_CT_PROTO_UDPLITE is not set # CONFIG_NF_CONNTRACK_AMANDA is not set CONFIG_NF_CONNTRACK_FTP=m CONFIG_NF_CONNTRACK_H323=m @@ -408,6 +416,7 @@ CONFIG_NETFILTER_XT_TARGET_NFLOG=m CONFIG_NETFILTER_XT_TARGET_TCPMSS=m # CONFIG_NETFILTER_XT_MATCH_COMMENT is not set CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m CONFIG_NETFILTER_XT_MATCH_CONNMARK=m CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m CONFIG_NETFILTER_XT_MATCH_DCCP=m @@ -429,6 +438,7 @@ CONFIG_NETFILTER_XT_MATCH_STATE=m CONFIG_NETFILTER_XT_MATCH_STATISTIC=m CONFIG_NETFILTER_XT_MATCH_STRING=m CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_U32=m CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m # @@ -547,6 +557,7 @@ CONFIG_NET_SCH_CBQ=m CONFIG_NET_SCH_HTB=m CONFIG_NET_SCH_HFSC=m CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_RR=m CONFIG_NET_SCH_RED=m CONFIG_NET_SCH_SFQ=m CONFIG_NET_SCH_TEQL=m @@ -574,7 +585,6 @@ CONFIG_NET_CLS_RSVP6=m # CONFIG_NET_CLS_ACT is not set # CONFIG_NET_CLS_POLICE is not set # CONFIG_NET_CLS_IND is not set -CONFIG_NET_ESTIMATOR=y # # Network testing @@ -613,6 +623,7 @@ CONFIG_FIB_RULES=y # CONFIG_MAC80211 is not set # CONFIG_IEEE80211 is not set # CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set # # Device Drivers @@ -627,10 +638,6 @@ CONFIG_FW_LOADER=m # CONFIG_DEBUG_DRIVER is not set # CONFIG_DEBUG_DEVRES is not set # CONFIG_SYS_HYPERVISOR is not set - -# -# Connector - unified userspace <-> kernelspace linker -# CONFIG_CONNECTOR=m CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set @@ -712,20 +719,8 @@ CONFIG_MTD_NAND_S3C2410_CLKSTOP=y # UBI - Unsorted block images # # CONFIG_MTD_UBI is not set - -# -# Parallel port support -# # CONFIG_PARPORT is not set - -# -# Plug and Play support -# -# CONFIG_PNPACPI is not set - -# -# Block devices -# +CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=m # CONFIG_BLK_DEV_CRYPTOLOOP is not set @@ -744,6 +739,7 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=m +CONFIG_SCSI_DMA=y # CONFIG_SCSI_TGT is not set # CONFIG_SCSI_NETLINK is not set CONFIG_SCSI_PROC_FS=y @@ -774,19 +770,11 @@ CONFIG_SCSI_WAIT_SCAN=m # CONFIG_SCSI_SPI_ATTRS is not set # CONFIG_SCSI_FC_ATTRS is not set # CONFIG_SCSI_ISCSI_ATTRS is not set -# CONFIG_SCSI_SAS_ATTRS is not set # CONFIG_SCSI_SAS_LIBSAS is not set - -# -# SCSI low-level drivers -# +CONFIG_SCSI_LOWLEVEL=y # CONFIG_ISCSI_TCP is not set # CONFIG_SCSI_DEBUG is not set # CONFIG_ATA is not set - -# -# Multi-device support (RAID and LVM) -# CONFIG_MD=y # CONFIG_BLK_DEV_MD is not set CONFIG_BLK_DEV_DM=m @@ -797,22 +785,17 @@ CONFIG_DM_SNAPSHOT=m # CONFIG_DM_ZERO is not set # CONFIG_DM_MULTIPATH is not set # CONFIG_DM_DELAY is not set - -# -# Network device support -# CONFIG_NETDEVICES=y +# CONFIG_NETDEVICES_MULTIQUEUE is not set # CONFIG_DUMMY is not set # CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set # CONFIG_EQUALIZER is not set CONFIG_TUN=m # CONFIG_PHYLIB is not set - -# -# Ethernet (10 or 100Mbit) -# CONFIG_NET_ETHERNET=y CONFIG_MII=m +# CONFIG_AX88796 is not set # CONFIG_SMC91X is not set # CONFIG_DM9000 is not set CONFIG_NET_PCI=y @@ -861,16 +844,13 @@ CONFIG_PPP_DEFLATE=m CONFIG_PPP_BSDCOMP=m CONFIG_PPP_MPPE=m # CONFIG_PPPOE is not set +# CONFIG_PPPOL2TP is not set # CONFIG_SLIP is not set CONFIG_SLHC=m # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set # CONFIG_NET_POLL_CONTROLLER is not set - -# -# ISDN subsystem -# # CONFIG_ISDN is not set # @@ -910,10 +890,12 @@ CONFIG_INPUT_MOUSE=y # CONFIG_MOUSE_SERIAL is not set # CONFIG_MOUSE_APPLETOUCH 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=y # CONFIG_TOUCHSCREEN_ADS7846 is not set +# CONFIG_TOUCHSCREEN_FUJITSU is not set CONFIG_TOUCHSCREEN_S3C2410=y # CONFIG_TOUCHSCREEN_S3C2410_DEBUG is not set # CONFIG_TOUCHSCREEN_GUNZE is not set @@ -959,10 +941,6 @@ CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_UNIX98_PTYS=y # CONFIG_LEGACY_PTYS is not set - -# -# IPMI -# # CONFIG_IPMI_HANDLER is not set CONFIG_WATCHDOG=y # CONFIG_WATCHDOG_NOWAYOUT is not set @@ -981,10 +959,6 @@ CONFIG_S3C2410_WATCHDOG=m # CONFIG_NVRAM is not set # CONFIG_R3964 is not set # CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# # CONFIG_TCG_TPM is not set # CONFIG_TS0710_MUX is not set CONFIG_I2C=y @@ -1006,6 +980,7 @@ CONFIG_I2C_CHARDEV=y # CONFIG_I2C_PARPORT_LIGHT is not set CONFIG_I2C_S3C2410=y # CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_TAOS_EVM is not set # CONFIG_I2C_STUB is not set # CONFIG_I2C_TINY_USB is not set @@ -1014,6 +989,7 @@ CONFIG_I2C_S3C2410=y # # CONFIG_SENSORS_DS1337 is not set # CONFIG_SENSORS_DS1374 is not set +# CONFIG_DS1682 is not set # CONFIG_SENSORS_EEPROM is not set CONFIG_SENSORS_PCF50606=y CONFIG_SENSORS_PCF50633=y @@ -1021,6 +997,7 @@ CONFIG_SENSORS_PCF50633=y # CONFIG_SENSORS_PCA9539 is not set # CONFIG_SENSORS_PCF8591 is not set # CONFIG_SENSORS_MAX6875 is not set +# CONFIG_SENSORS_TSL2550 is not set CONFIG_SENSORS_TSL256X=m # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set @@ -1046,15 +1023,13 @@ CONFIG_SPI_S3C24XX_GPIO=y # # CONFIG_SPI_AT25 is not set # CONFIG_SPI_SPIDEV is not set +# CONFIG_SPI_TLE62X0 is not set CONFIG_SPI_SLAVE_JBT6K74=y - -# -# Dallas's 1-wire bus -# # CONFIG_W1 is not set CONFIG_HWMON=y # CONFIG_HWMON_VID is not set # CONFIG_SENSORS_ABITUGURU is not set +# CONFIG_SENSORS_ABITUGURU3 is not set # CONFIG_SENSORS_AD7418 is not set # CONFIG_SENSORS_ADM1021 is not set # CONFIG_SENSORS_ADM1025 is not set @@ -1082,13 +1057,16 @@ CONFIG_HWMON=y # CONFIG_SENSORS_LM87 is not set # CONFIG_SENSORS_LM90 is not set # CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_LM93 is not set # CONFIG_SENSORS_MAX1619 is not set # CONFIG_SENSORS_MAX6650 is not set # CONFIG_SENSORS_PC87360 is not set # CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_DME1737 is not set # CONFIG_SENSORS_SMSC47M1 is not set # CONFIG_SENSORS_SMSC47M192 is not set # CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_THMC50 is not set # CONFIG_SENSORS_VT1211 is not set # CONFIG_SENSORS_W83781D is not set # CONFIG_SENSORS_W83791D is not set @@ -1098,27 +1076,21 @@ CONFIG_HWMON=y # CONFIG_SENSORS_W83627HF is not set # CONFIG_SENSORS_W83627EHF is not set # CONFIG_HWMON_DEBUG_CHIP is not set - -# -# Misc devices -# +CONFIG_MISC_DEVICES=y +# CONFIG_EEPROM_93CX6 is not set # # Multifunction device drivers # # CONFIG_MFD_SM501 is not set - -# -# LED devices -# CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y # # LED drivers # -CONFIG_LEDS_S3C24XX=m -CONFIG_LEDS_GTA01=y +CONFIG_LEDS_S3C24XX=y +# CONFIG_LEDS_GPIO is not set # # LED Triggers @@ -1139,8 +1111,8 @@ CONFIG_DAB=y # Graphics support # CONFIG_BACKLIGHT_LCD_SUPPORT=y -CONFIG_BACKLIGHT_CLASS_DEVICE=y CONFIG_LCD_CLASS_DEVICE=y +CONFIG_BACKLIGHT_CLASS_DEVICE=y CONFIG_BACKLIGHT_GTA01=y # @@ -1148,6 +1120,7 @@ CONFIG_BACKLIGHT_GTA01=y # # CONFIG_DISPLAY_SUPPORT is not set # CONFIG_VGASTATE is not set +CONFIG_VIDEO_OUTPUT_CONTROL=m CONFIG_FB=y # CONFIG_FIRMWARE_EDID is not set # CONFIG_FB_DDC is not set @@ -1183,6 +1156,7 @@ CONFIG_FB_GLAMO_SPI=y # CONFIG_VGA_CONSOLE is not set CONFIG_DUMMY_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set # CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set CONFIG_FONTS=y # CONFIG_FONT_8x8 is not set @@ -1195,10 +1169,11 @@ CONFIG_FONT_6x11=y # CONFIG_FONT_SUN8x16 is not set # CONFIG_FONT_SUN12x22 is not set # CONFIG_FONT_10x18 is not set -# CONFIG_LOGO is not set +CONFIG_LOGO=y # CONFIG_LOGO_LINUX_MONO is not set # CONFIG_LOGO_LINUX_VGA16 is not set -# CONFIG_LOGO_LINUX_CLUT224 is not set +CONFIG_LOGO_LINUX_CLUT224=y +# CONFIG_LOGO_OPENMOKO_CLUT224 is not set # # Sound @@ -1246,23 +1221,20 @@ CONFIG_SND_USB_AUDIO=m # System on Chip audio support # CONFIG_SND_SOC=y -CONFIG_SND_S3C24XX_SOC=m -CONFIG_SND_S3C24XX_SOC_I2S=m -CONFIG_SND_S3C24XX_SOC_NEO1973_WM8753=m +CONFIG_SND_S3C24XX_SOC=y +CONFIG_SND_S3C24XX_SOC_I2S=y +CONFIG_SND_S3C24XX_SOC_NEO1973_WM8753=y # # SoC Audio support for SuperH # -CONFIG_SND_SOC_WM8753=m +CONFIG_SND_SOC_WM8753=y # # Open Sound System # # CONFIG_SOUND_PRIME is not set - -# -# HID Devices -# +CONFIG_HID_SUPPORT=y CONFIG_HID=y # CONFIG_HID_DEBUG is not set @@ -1279,10 +1251,7 @@ CONFIG_USB_HID=m # # CONFIG_USB_KBD is not set # CONFIG_USB_MOUSE is not set - -# -# USB support -# +CONFIG_USB_SUPPORT=y CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y # CONFIG_USB_ARCH_HAS_EHCI is not set @@ -1296,6 +1265,7 @@ CONFIG_USB_DEVICEFS=y CONFIG_USB_DEVICE_CLASS=y # CONFIG_USB_DYNAMIC_MINORS is not set # CONFIG_USB_SUSPEND is not set +# CONFIG_USB_PERSIST is not set # CONFIG_USB_OTG is not set # @@ -1307,6 +1277,7 @@ CONFIG_USB_OHCI_HCD=m # CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set CONFIG_USB_OHCI_LITTLE_ENDIAN=y # CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set # # USB Device Class drivers @@ -1389,6 +1360,7 @@ CONFIG_USB_SERIAL_MOS7720=m CONFIG_USB_SERIAL_MOS7840=m CONFIG_USB_SERIAL_NAVMAN=m CONFIG_USB_SERIAL_PL2303=m +CONFIG_USB_SERIAL_OTI6858=m CONFIG_USB_SERIAL_HP4X=m CONFIG_USB_SERIAL_SAFE=m CONFIG_USB_SERIAL_SAFE_PADDED=y @@ -1432,11 +1404,14 @@ CONFIG_USB_IOWARRIOR=m # USB Gadget Support # CONFIG_USB_GADGET=y +# CONFIG_USB_GADGET_DEBUG is not set # CONFIG_USB_GADGET_DEBUG_FILES is not set CONFIG_USB_GADGET_SELECTED=y +# CONFIG_USB_GADGET_AMD5536UDC is not set # CONFIG_USB_GADGET_FSL_USB2 is not set # CONFIG_USB_GADGET_NET2280 is not set # CONFIG_USB_GADGET_PXA2XX is not set +# CONFIG_USB_GADGET_M66592 is not set # CONFIG_USB_GADGET_GOKU is not set # CONFIG_USB_GADGET_LH7A40X is not set # CONFIG_USB_GADGET_OMAP is not set @@ -1461,15 +1436,12 @@ CONFIG_MMC_UNSAFE_RESUME=y # MMC/SD Card Drivers # CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_BOUNCE=y # # MMC/SD Host Controller Drivers # CONFIG_MMC_S3C=y - -# -# Real Time Clock -# CONFIG_RTC_LIB=y CONFIG_RTC_CLASS=y CONFIG_RTC_HCTOSYS=y @@ -1496,6 +1468,7 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_X1205 is not set # CONFIG_RTC_DRV_PCF8563 is not set # CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set # # SPI RTC drivers @@ -1508,8 +1481,10 @@ CONFIG_RTC_INTF_DEV=y # # CONFIG_RTC_DRV_CMOS is not set # CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set # CONFIG_RTC_DRV_DS1742 is not set # CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T59 is not set # CONFIG_RTC_DRV_V3020 is not set # @@ -1518,6 +1493,19 @@ CONFIG_RTC_INTF_DEV=y CONFIG_RTC_DRV_S3C=m # +# DMA Engine support +# +# CONFIG_DMA_ENGINE is not set + +# +# DMA Clients +# + +# +# DMA Devices +# + +# # File systems # CONFIG_EXT2_FS=m @@ -1586,6 +1574,7 @@ CONFIG_CONFIGFS_FS=m # CONFIG_EFS_FS is not set CONFIG_YAFFS_FS=y CONFIG_YAFFS_YAFFS1=y +# CONFIG_YAFFS_9BYTE_TAGS is not set # CONFIG_YAFFS_DOES_ECC is not set CONFIG_YAFFS_YAFFS2=y CONFIG_YAFFS_AUTO_YAFFS2=y @@ -1647,7 +1636,6 @@ CONFIG_CIFS_WEAK_PW_HASH=y # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set -# CONFIG_9P_FS is not set # # Partition Types @@ -1721,6 +1709,7 @@ CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_KERNEL=y # CONFIG_DEBUG_SHIRQ is not set CONFIG_DETECT_SOFTLOCKUP=y +CONFIG_SCHED_DEBUG=y # CONFIG_SCHEDSTATS is not set # CONFIG_TIMER_STATS is not set # CONFIG_DEBUG_SLAB is not set @@ -1731,6 +1720,7 @@ CONFIG_DEBUG_PREEMPT=y # 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 @@ -1746,18 +1736,14 @@ CONFIG_FORCED_INLINING=y CONFIG_DEBUG_ERRORS=y CONFIG_DEBUG_LL=y # CONFIG_DEBUG_ICEDCC is not set -CONFIG_DEBUG_S3C2410_PORT=y -CONFIG_DEBUG_S3C2410_UART=0 +CONFIG_DEBUG_S3C_PORT=y +CONFIG_DEBUG_S3C_UART=2 # # Security options # # CONFIG_KEYS is not set # CONFIG_SECURITY is not set - -# -# Cryptographic options -# CONFIG_CRYPTO=y CONFIG_CRYPTO_ALGAPI=y CONFIG_CRYPTO_BLKCIPHER=y @@ -1797,10 +1783,7 @@ CONFIG_CRYPTO_MICHAEL_MIC=m CONFIG_CRYPTO_CRC32C=m CONFIG_CRYPTO_CAMELLIA=m CONFIG_CRYPTO_TEST=m - -# -# Hardware crypto devices -# +CONFIG_CRYPTO_HW=y # # Library routines @@ -1810,6 +1793,7 @@ CONFIG_CRC_CCITT=m CONFIG_CRC16=m # CONFIG_CRC_ITU_T is not set CONFIG_CRC32=y +# CONFIG_CRC7 is not set CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff --git a/packages/linux/linux-openmoko-devel/hack-gta02-cpu.patch b/packages/linux/linux-openmoko-devel/hack-gta02-cpu.patch new file mode 100644 index 0000000000..ef4e939640 --- /dev/null +++ b/packages/linux/linux-openmoko-devel/hack-gta02-cpu.patch @@ -0,0 +1,21 @@ +Index: linux-2.6.22/arch/arm/mach-s3c2440/Kconfig +=================================================================== +--- linux-2.6.22.orig/arch/arm/mach-s3c2440/Kconfig ++++ linux-2.6.22/arch/arm/mach-s3c2440/Kconfig +@@ -69,14 +69,14 @@ + + config MACH_HXD8 + bool "FIC HXD8" +- select CPU_S3C2440 ++ select CPU_S3C2442 + select SENSORS_PCF50606 + help + Say Y here if you are using the FIC Neo1973 GSM Phone + + config MACH_NEO1973_GTA02 + bool "FIC Neo1973 GSM Phone (GTA02 Hardware)" +- select CPU_S3C2440 ++ select CPU_S3C2442 + select SENSORS_PCF50633 + help + Say Y here if you are using the FIC Neo1973 GSM Phone diff --git a/packages/linux/linux-openmoko-devel/printascii-2.6.23.patch b/packages/linux/linux-openmoko-devel/printascii-2.6.23.patch new file mode 100644 index 0000000000..4818ac6bfc --- /dev/null +++ b/packages/linux/linux-openmoko-devel/printascii-2.6.23.patch @@ -0,0 +1,21 @@ +Index: linux-2.6.22/kernel/printk.c +=================================================================== +--- linux-2.6.22.orig/kernel/printk.c ++++ linux-2.6.22/kernel/printk.c +@@ -519,6 +519,8 @@ + /* cpu currently holding logbuf_lock */ + static volatile unsigned int printk_cpu = UINT_MAX; + ++extern void printascii(const char *); ++ + asmlinkage int vprintk(const char *fmt, va_list args) + { + unsigned long flags; +@@ -541,6 +543,7 @@ + + /* Emit the output into the temporary buffer */ + printed_len = vscnprintf(printk_buf, sizeof(printk_buf), fmt, args); ++ printascii(printk_buf); + + /* + * Copy the output into log_buf. If the caller didn't provide diff --git a/packages/linux/linux-openmoko-devel/squashfs-2.6.23.patch b/packages/linux/linux-openmoko-devel/squashfs-2.6.23.patch new file mode 100644 index 0000000000..f4457a8715 --- /dev/null +++ b/packages/linux/linux-openmoko-devel/squashfs-2.6.23.patch @@ -0,0 +1,4395 @@ +Index: linux-2.6.22/fs/Kconfig +=================================================================== +--- linux-2.6.22.orig/fs/Kconfig ++++ linux-2.6.22/fs/Kconfig +@@ -1368,6 +1368,71 @@ + + If unsure, say N. + ++config SQUASHFS ++ tristate "SquashFS 3.2 - Squashed file system support" ++ select ZLIB_INFLATE ++ help ++ Saying Y here includes support for SquashFS 3.2 (a Compressed Read-Only File ++ System). Squashfs is a highly compressed read-only filesystem for Linux. ++ It uses zlib compression to compress both files, inodes and directories. ++ Inodes in the system are very small and all blocks are packed to minimise ++ data overhead. Block sizes greater than 4K are supported up to a maximum of 64K. ++ SquashFS 3.1 supports 64 bit filesystems and files (larger than 4GB), full ++ uid/gid information, hard links and timestamps. ++ ++ Squashfs is intended for general read-only filesystem use, for archival ++ use (i.e. in cases where a .tar.gz file may be used), and in embedded ++ systems where low overhead is needed. Further information and filesystem tools ++ are available from http://squashfs.sourceforge.net. ++ ++ If you want to compile this as a module ( = code which can be ++ inserted in and removed from the running kernel whenever you want), ++ say M here and read <file:Documentation/modules.txt>. The module ++ will be called squashfs. Note that the root file system (the one ++ containing the directory /) cannot be compiled as a module. ++ ++ If unsure, say N. ++ ++config SQUASHFS_EMBEDDED ++ ++ bool "Additional options for memory-constrained systems" ++ depends on SQUASHFS ++ default n ++ help ++ Saying Y here allows you to specify cache sizes and how Squashfs ++ allocates memory. This is only intended for memory constrained ++ systems. ++ ++ If unsure, say N. ++ ++config SQUASHFS_FRAGMENT_CACHE_SIZE ++ int "Number of fragments cached" if SQUASHFS_EMBEDDED ++ depends on SQUASHFS ++ default "3" ++ help ++ By default SquashFS caches the last 3 fragments read from ++ the filesystem. Increasing this amount may mean SquashFS ++ has to re-read fragments less often from disk, at the expense ++ of extra system memory. Decreasing this amount will mean ++ SquashFS uses less memory at the expense of extra reads from disk. ++ ++ Note there must be at least one cached fragment. Anything ++ much more than three will probably not make much difference. ++ ++config SQUASHFS_VMALLOC ++ bool "Use Vmalloc rather than Kmalloc" if SQUASHFS_EMBEDDED ++ depends on SQUASHFS ++ default n ++ help ++ By default SquashFS uses kmalloc to obtain fragment cache memory. ++ Kmalloc memory is the standard kernel allocator, but it can fail ++ on memory constrained systems. Because of the way Vmalloc works, ++ Vmalloc can succeed when kmalloc fails. Specifying this option ++ will make SquashFS always use Vmalloc to allocate the ++ fragment cache memory. ++ ++ If unsure, say N. ++ + config VXFS_FS + tristate "FreeVxFS file system support (VERITAS VxFS(TM) compatible)" + depends on BLOCK +Index: linux-2.6.22/fs/Makefile +=================================================================== +--- linux-2.6.22.orig/fs/Makefile ++++ linux-2.6.22/fs/Makefile +@@ -72,6 +72,7 @@ + obj-$(CONFIG_JBD2) += jbd2/ + obj-$(CONFIG_EXT2_FS) += ext2/ + obj-$(CONFIG_CRAMFS) += cramfs/ ++obj-$(CONFIG_SQUASHFS) += squashfs/ + obj-$(CONFIG_RAMFS) += ramfs/ + obj-$(CONFIG_HUGETLBFS) += hugetlbfs/ + obj-$(CONFIG_CODA_FS) += coda/ +Index: linux-2.6.22/fs/squashfs/inode.c +=================================================================== +--- /dev/null ++++ linux-2.6.22/fs/squashfs/inode.c +@@ -0,0 +1,2328 @@ ++/* ++ * Squashfs - a compressed read only filesystem for Linux ++ * ++ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007 ++ * Phillip Lougher <phillip@lougher.org.uk> ++ * ++ * 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, ++ * 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ * ++ * inode.c ++ */ ++ ++#include <linux/squashfs_fs.h> ++#include <linux/module.h> ++#include <linux/zlib.h> ++#include <linux/fs.h> ++#include <linux/squashfs_fs_sb.h> ++#include <linux/squashfs_fs_i.h> ++#include <linux/buffer_head.h> ++#include <linux/vfs.h> ++#include <linux/vmalloc.h> ++#include <linux/smp_lock.h> ++#include <linux/exportfs.h> ++ ++#include "squashfs.h" ++ ++static void vfs_read_inode(struct inode *i); ++static struct dentry *squashfs_get_parent(struct dentry *child); ++static int squashfs_read_inode(struct inode *i, squashfs_inode_t inode); ++static int squashfs_statfs(struct dentry *, struct kstatfs *); ++static int squashfs_symlink_readpage(struct file *file, struct page *page); ++static long long read_blocklist(struct inode *inode, int index, ++ int readahead_blks, char *block_list, ++ unsigned short **block_p, unsigned int *bsize); ++static int squashfs_readpage(struct file *file, struct page *page); ++static int squashfs_readpage4K(struct file *file, struct page *page); ++static int squashfs_readdir(struct file *, void *, filldir_t); ++static struct dentry *squashfs_lookup(struct inode *, struct dentry *, ++ struct nameidata *); ++static int squashfs_remount(struct super_block *s, int *flags, char *data); ++static void squashfs_put_super(struct super_block *); ++static int squashfs_get_sb(struct file_system_type *,int, const char *, void *, ++ struct vfsmount *); ++static struct inode *squashfs_alloc_inode(struct super_block *sb); ++static void squashfs_destroy_inode(struct inode *inode); ++static int init_inodecache(void); ++static void destroy_inodecache(void); ++ ++static struct file_system_type squashfs_fs_type = { ++ .owner = THIS_MODULE, ++ .name = "squashfs", ++ .get_sb = squashfs_get_sb, ++ .kill_sb = kill_block_super, ++ .fs_flags = FS_REQUIRES_DEV ++}; ++ ++static const unsigned char squashfs_filetype_table[] = { ++ DT_UNKNOWN, DT_DIR, DT_REG, DT_LNK, DT_BLK, DT_CHR, DT_FIFO, DT_SOCK ++}; ++ ++static struct super_operations squashfs_super_ops = { ++ .alloc_inode = squashfs_alloc_inode, ++ .destroy_inode = squashfs_destroy_inode, ++ .statfs = squashfs_statfs, ++ .put_super = squashfs_put_super, ++ .remount_fs = squashfs_remount ++}; ++ ++static struct super_operations squashfs_export_super_ops = { ++ .alloc_inode = squashfs_alloc_inode, ++ .destroy_inode = squashfs_destroy_inode, ++ .statfs = squashfs_statfs, ++ .put_super = squashfs_put_super, ++ .read_inode = vfs_read_inode ++}; ++ ++static struct export_operations squashfs_export_ops = { ++ .get_parent = squashfs_get_parent ++}; ++ ++SQSH_EXTERN const struct address_space_operations squashfs_symlink_aops = { ++ .readpage = squashfs_symlink_readpage ++}; ++ ++SQSH_EXTERN const struct address_space_operations squashfs_aops = { ++ .readpage = squashfs_readpage ++}; ++ ++SQSH_EXTERN const struct address_space_operations squashfs_aops_4K = { ++ .readpage = squashfs_readpage4K ++}; ++ ++static const struct file_operations squashfs_dir_ops = { ++ .read = generic_read_dir, ++ .readdir = squashfs_readdir ++}; ++ ++SQSH_EXTERN struct inode_operations squashfs_dir_inode_ops = { ++ .lookup = squashfs_lookup ++}; ++ ++ ++static struct buffer_head *get_block_length(struct super_block *s, ++ int *cur_index, int *offset, int *c_byte) ++{ ++ struct squashfs_sb_info *msblk = s->s_fs_info; ++ unsigned short temp; ++ struct buffer_head *bh; ++ ++ if (!(bh = sb_bread(s, *cur_index))) ++ goto out; ++ ++ if (msblk->devblksize - *offset == 1) { ++ if (msblk->swap) ++ ((unsigned char *) &temp)[1] = *((unsigned char *) ++ (bh->b_data + *offset)); ++ else ++ ((unsigned char *) &temp)[0] = *((unsigned char *) ++ (bh->b_data + *offset)); ++ brelse(bh); ++ if (!(bh = sb_bread(s, ++(*cur_index)))) ++ goto out; ++ if (msblk->swap) ++ ((unsigned char *) &temp)[0] = *((unsigned char *) ++ bh->b_data); ++ else ++ ((unsigned char *) &temp)[1] = *((unsigned char *) ++ bh->b_data); ++ *c_byte = temp; ++ *offset = 1; ++ } else { ++ if (msblk->swap) { ++ ((unsigned char *) &temp)[1] = *((unsigned char *) ++ (bh->b_data + *offset)); ++ ((unsigned char *) &temp)[0] = *((unsigned char *) ++ (bh->b_data + *offset + 1)); ++ } else { ++ ((unsigned char *) &temp)[0] = *((unsigned char *) ++ (bh->b_data + *offset)); ++ ((unsigned char *) &temp)[1] = *((unsigned char *) ++ (bh->b_data + *offset + 1)); ++ } ++ *c_byte = temp; ++ *offset += 2; ++ } ++ ++ if (SQUASHFS_CHECK_DATA(msblk->sblk.flags)) { ++ if (*offset == msblk->devblksize) { ++ brelse(bh); ++ if (!(bh = sb_bread(s, ++(*cur_index)))) ++ goto out; ++ *offset = 0; ++ } ++ if (*((unsigned char *) (bh->b_data + *offset)) != ++ SQUASHFS_MARKER_BYTE) { ++ ERROR("Metadata block marker corrupt @ %x\n", ++ *cur_index); ++ brelse(bh); ++ goto out; ++ } ++ (*offset)++; ++ } ++ return bh; ++ ++out: ++ return NULL; ++} ++ ++ ++SQSH_EXTERN unsigned int squashfs_read_data(struct super_block *s, char *buffer, ++ long long index, unsigned int length, ++ long long *next_index, int srclength) ++{ ++ struct squashfs_sb_info *msblk = s->s_fs_info; ++ struct squashfs_super_block *sblk = &msblk->sblk; ++ struct buffer_head *bh[((SQUASHFS_FILE_MAX_SIZE - 1) >> ++ msblk->devblksize_log2) + 2]; ++ unsigned int offset = index & ((1 << msblk->devblksize_log2) - 1); ++ unsigned int cur_index = index >> msblk->devblksize_log2; ++ int bytes, avail_bytes, b = 0, k = 0; ++ unsigned int compressed; ++ unsigned int c_byte = length; ++ ++ if (c_byte) { ++ bytes = msblk->devblksize - offset; ++ compressed = SQUASHFS_COMPRESSED_BLOCK(c_byte); ++ c_byte = SQUASHFS_COMPRESSED_SIZE_BLOCK(c_byte); ++ ++ TRACE("Block @ 0x%llx, %scompressed size %d, src size %d\n", index, compressed ++ ? "" : "un", (unsigned int) c_byte, srclength); ++ ++ if (c_byte > srclength || index < 0 || (index + c_byte) > sblk->bytes_used) ++ goto read_failure; ++ ++ if (!(bh[0] = sb_getblk(s, cur_index))) ++ goto block_release; ++ ++ for (b = 1; bytes < c_byte; b++) { ++ if (!(bh[b] = sb_getblk(s, ++cur_index))) ++ goto block_release; ++ bytes += msblk->devblksize; ++ } ++ ll_rw_block(READ, b, bh); ++ } else { ++ if (index < 0 || (index + 2) > sblk->bytes_used) ++ goto read_failure; ++ ++ if (!(bh[0] = get_block_length(s, &cur_index, &offset, ++ &c_byte))) ++ goto read_failure; ++ ++ bytes = msblk->devblksize - offset; ++ compressed = SQUASHFS_COMPRESSED(c_byte); ++ c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte); ++ ++ TRACE("Block @ 0x%llx, %scompressed size %d\n", index, compressed ++ ? "" : "un", (unsigned int) c_byte); ++ ++ if (c_byte > srclength || (index + c_byte) > sblk->bytes_used) ++ goto read_failure; ++ ++ for (b = 1; bytes < c_byte; b++) { ++ if (!(bh[b] = sb_getblk(s, ++cur_index))) ++ goto block_release; ++ bytes += msblk->devblksize; ++ } ++ ll_rw_block(READ, b - 1, bh + 1); ++ } ++ ++ if (compressed) { ++ int zlib_err = 0; ++ ++ /* ++ * uncompress block ++ */ ++ ++ mutex_lock(&msblk->read_data_mutex); ++ ++ msblk->stream.next_out = buffer; ++ msblk->stream.avail_out = srclength; ++ ++ for (bytes = 0; k < b; k++) { ++ avail_bytes = (c_byte - bytes) > (msblk->devblksize - offset) ? ++ msblk->devblksize - offset : ++ c_byte - bytes; ++ wait_on_buffer(bh[k]); ++ if (!buffer_uptodate(bh[k])) ++ goto release_mutex; ++ ++ msblk->stream.next_in = bh[k]->b_data + offset; ++ msblk->stream.avail_in = avail_bytes; ++ ++ if (k == 0) { ++ zlib_err = zlib_inflateInit(&msblk->stream); ++ if (zlib_err != Z_OK) { ++ ERROR("zlib_inflateInit returned unexpected result 0x%x, srclength %d\n", ++ zlib_err, srclength); ++ goto release_mutex; ++ } ++ ++ if (avail_bytes == 0) { ++ offset = 0; ++ brelse(bh[k]); ++ continue; ++ } ++ } ++ ++ zlib_err = zlib_inflate(&msblk->stream, Z_NO_FLUSH); ++ if (zlib_err != Z_OK && zlib_err != Z_STREAM_END) { ++ ERROR("zlib_inflate returned unexpected result 0x%x, srclength %d, avail_in %d, avail_out %d\n", ++ zlib_err, srclength, msblk->stream.avail_in, msblk->stream.avail_out); ++ goto release_mutex; ++ } ++ ++ bytes += avail_bytes; ++ offset = 0; ++ brelse(bh[k]); ++ } ++ ++ if (zlib_err != Z_STREAM_END) ++ goto release_mutex; ++ ++ zlib_err = zlib_inflateEnd(&msblk->stream); ++ if (zlib_err != Z_OK) { ++ ERROR("zlib_inflateEnd returned unexpected result 0x%x, srclength %d\n", ++ zlib_err, srclength); ++ goto release_mutex; ++ } ++ bytes = msblk->stream.total_out; ++ mutex_unlock(&msblk->read_data_mutex); ++ } else { ++ int i; ++ ++ for(i = 0; i < b; i++) { ++ wait_on_buffer(bh[i]); ++ if(!buffer_uptodate(bh[i])) ++ goto block_release; ++ } ++ ++ for (bytes = 0; k < b; k++) { ++ avail_bytes = (c_byte - bytes) > (msblk->devblksize - offset) ? ++ msblk->devblksize - offset : ++ c_byte - bytes; ++ memcpy(buffer + bytes, bh[k]->b_data + offset, avail_bytes); ++ bytes += avail_bytes; ++ offset = 0; ++ brelse(bh[k]); ++ } ++ } ++ ++ if (next_index) ++ *next_index = index + c_byte + (length ? 0 : ++ (SQUASHFS_CHECK_DATA(msblk->sblk.flags) ++ ? 3 : 2)); ++ return bytes; ++ ++release_mutex: ++ mutex_unlock(&msblk->read_data_mutex); ++ ++block_release: ++ for (; k < b; k++) ++ brelse(bh[k]); ++ ++read_failure: ++ ERROR("sb_bread failed reading block 0x%x\n", cur_index); ++ return 0; ++} ++ ++ ++SQSH_EXTERN int squashfs_get_cached_block(struct super_block *s, char *buffer, ++ long long block, unsigned int offset, ++ int length, long long *next_block, ++ unsigned int *next_offset) ++{ ++ struct squashfs_sb_info *msblk = s->s_fs_info; ++ int n, i, bytes, return_length = length; ++ long long next_index; ++ ++ TRACE("Entered squashfs_get_cached_block [%llx:%x]\n", block, offset); ++ ++ while ( 1 ) { ++ for (i = 0; i < SQUASHFS_CACHED_BLKS; i++) ++ if (msblk->block_cache[i].block == block) ++ break; ++ ++ mutex_lock(&msblk->block_cache_mutex); ++ ++ if (i == SQUASHFS_CACHED_BLKS) { ++ /* read inode header block */ ++ for (i = msblk->next_cache, n = SQUASHFS_CACHED_BLKS; ++ n ; n --, i = (i + 1) % ++ SQUASHFS_CACHED_BLKS) ++ if (msblk->block_cache[i].block != ++ SQUASHFS_USED_BLK) ++ break; ++ ++ if (n == 0) { ++ wait_queue_t wait; ++ ++ init_waitqueue_entry(&wait, current); ++ add_wait_queue(&msblk->waitq, &wait); ++ set_current_state(TASK_UNINTERRUPTIBLE); ++ mutex_unlock(&msblk->block_cache_mutex); ++ schedule(); ++ set_current_state(TASK_RUNNING); ++ remove_wait_queue(&msblk->waitq, &wait); ++ continue; ++ } ++ msblk->next_cache = (i + 1) % SQUASHFS_CACHED_BLKS; ++ ++ if (msblk->block_cache[i].block == ++ SQUASHFS_INVALID_BLK) { ++ if (!(msblk->block_cache[i].data = ++ kmalloc(SQUASHFS_METADATA_SIZE, ++ GFP_KERNEL))) { ++ ERROR("Failed to allocate cache" ++ "block\n"); ++ mutex_unlock(&msblk->block_cache_mutex); ++ goto out; ++ } ++ } ++ ++ msblk->block_cache[i].block = SQUASHFS_USED_BLK; ++ mutex_unlock(&msblk->block_cache_mutex); ++ ++ msblk->block_cache[i].length = squashfs_read_data(s, ++ msblk->block_cache[i].data, block, 0, &next_index, SQUASHFS_METADATA_SIZE); ++ if (msblk->block_cache[i].length == 0) { ++ ERROR("Unable to read cache block [%llx:%x]\n", ++ block, offset); ++ mutex_lock(&msblk->block_cache_mutex); ++ msblk->block_cache[i].block = SQUASHFS_INVALID_BLK; ++ kfree(msblk->block_cache[i].data); ++ wake_up(&msblk->waitq); ++ mutex_unlock(&msblk->block_cache_mutex); ++ goto out; ++ } ++ ++ mutex_lock(&msblk->block_cache_mutex); ++ wake_up(&msblk->waitq); ++ msblk->block_cache[i].block = block; ++ msblk->block_cache[i].next_index = next_index; ++ TRACE("Read cache block [%llx:%x]\n", block, offset); ++ } ++ ++ if (msblk->block_cache[i].block != block) { ++ mutex_unlock(&msblk->block_cache_mutex); ++ continue; ++ } ++ ++ bytes = msblk->block_cache[i].length - offset; ++ ++ if (bytes < 1) { ++ mutex_unlock(&msblk->block_cache_mutex); ++ goto out; ++ } else if (bytes >= length) { ++ if (buffer) ++ memcpy(buffer, msblk->block_cache[i].data + ++ offset, length); ++ if (msblk->block_cache[i].length - offset == length) { ++ *next_block = msblk->block_cache[i].next_index; ++ *next_offset = 0; ++ } else { ++ *next_block = block; ++ *next_offset = offset + length; ++ } ++ mutex_unlock(&msblk->block_cache_mutex); ++ goto finish; ++ } else { ++ if (buffer) { ++ memcpy(buffer, msblk->block_cache[i].data + ++ offset, bytes); ++ buffer += bytes; ++ } ++ block = msblk->block_cache[i].next_index; ++ mutex_unlock(&msblk->block_cache_mutex); ++ length -= bytes; ++ offset = 0; ++ } ++ } ++ ++finish: ++ return return_length; ++out: ++ return 0; ++} ++ ++ ++static int get_fragment_location(struct super_block *s, unsigned int fragment, ++ long long *fragment_start_block, ++ unsigned int *fragment_size) ++{ ++ struct squashfs_sb_info *msblk = s->s_fs_info; ++ long long start_block = ++ msblk->fragment_index[SQUASHFS_FRAGMENT_INDEX(fragment)]; ++ int offset = SQUASHFS_FRAGMENT_INDEX_OFFSET(fragment); ++ struct squashfs_fragment_entry fragment_entry; ++ ++ if (msblk->swap) { ++ struct squashfs_fragment_entry sfragment_entry; ++ ++ if (!squashfs_get_cached_block(s, (char *) &sfragment_entry, ++ start_block, offset, ++ sizeof(sfragment_entry), &start_block, ++ &offset)) ++ goto out; ++ SQUASHFS_SWAP_FRAGMENT_ENTRY(&fragment_entry, &sfragment_entry); ++ } else ++ if (!squashfs_get_cached_block(s, (char *) &fragment_entry, ++ start_block, offset, ++ sizeof(fragment_entry), &start_block, ++ &offset)) ++ goto out; ++ ++ *fragment_start_block = fragment_entry.start_block; ++ *fragment_size = fragment_entry.size; ++ ++ return 1; ++ ++out: ++ return 0; ++} ++ ++ ++SQSH_EXTERN void release_cached_fragment(struct squashfs_sb_info *msblk, struct ++ squashfs_fragment_cache *fragment) ++{ ++ mutex_lock(&msblk->fragment_mutex); ++ fragment->locked --; ++ wake_up(&msblk->fragment_wait_queue); ++ mutex_unlock(&msblk->fragment_mutex); ++} ++ ++ ++SQSH_EXTERN struct squashfs_fragment_cache *get_cached_fragment(struct super_block ++ *s, long long start_block, ++ int length) ++{ ++ int i, n; ++ struct squashfs_sb_info *msblk = s->s_fs_info; ++ struct squashfs_super_block *sblk = &msblk->sblk; ++ ++ while ( 1 ) { ++ mutex_lock(&msblk->fragment_mutex); ++ ++ for (i = 0; i < SQUASHFS_CACHED_FRAGMENTS && ++ msblk->fragment[i].block != start_block; i++); ++ ++ if (i == SQUASHFS_CACHED_FRAGMENTS) { ++ for (i = msblk->next_fragment, n = ++ SQUASHFS_CACHED_FRAGMENTS; n && ++ msblk->fragment[i].locked; n--, i = (i + 1) % ++ SQUASHFS_CACHED_FRAGMENTS); ++ ++ if (n == 0) { ++ wait_queue_t wait; ++ ++ init_waitqueue_entry(&wait, current); ++ add_wait_queue(&msblk->fragment_wait_queue, ++ &wait); ++ set_current_state(TASK_UNINTERRUPTIBLE); ++ mutex_unlock(&msblk->fragment_mutex); ++ schedule(); ++ set_current_state(TASK_RUNNING); ++ remove_wait_queue(&msblk->fragment_wait_queue, ++ &wait); ++ continue; ++ } ++ msblk->next_fragment = (msblk->next_fragment + 1) % ++ SQUASHFS_CACHED_FRAGMENTS; ++ ++ if (msblk->fragment[i].data == NULL) ++ if (!(msblk->fragment[i].data = SQUASHFS_ALLOC ++ (SQUASHFS_FILE_MAX_SIZE))) { ++ ERROR("Failed to allocate fragment " ++ "cache block\n"); ++ mutex_unlock(&msblk->fragment_mutex); ++ goto out; ++ } ++ ++ msblk->fragment[i].block = SQUASHFS_INVALID_BLK; ++ msblk->fragment[i].locked = 1; ++ mutex_unlock(&msblk->fragment_mutex); ++ ++ if (!(msblk->fragment[i].length = squashfs_read_data(s, ++ msblk->fragment[i].data, ++ start_block, length, NULL, sblk->block_size))) { ++ ERROR("Unable to read fragment cache block " ++ "[%llx]\n", start_block); ++ msblk->fragment[i].locked = 0; ++ smp_mb(); ++ goto out; ++ } ++ ++ mutex_lock(&msblk->fragment_mutex); ++ msblk->fragment[i].block = start_block; ++ TRACE("New fragment %d, start block %lld, locked %d\n", ++ i, msblk->fragment[i].block, ++ msblk->fragment[i].locked); ++ mutex_unlock(&msblk->fragment_mutex); ++ break; ++ } ++ ++ msblk->fragment[i].locked++; ++ mutex_unlock(&msblk->fragment_mutex); ++ TRACE("Got fragment %d, start block %lld, locked %d\n", i, ++ msblk->fragment[i].block, ++ msblk->fragment[i].locked); ++ break; ++ } ++ ++ return &msblk->fragment[i]; ++ ++out: ++ return NULL; ++} ++ ++ ++static void squashfs_new_inode(struct squashfs_sb_info *msblk, struct inode *i, ++ struct squashfs_base_inode_header *inodeb) ++{ ++ i->i_ino = inodeb->inode_number; ++ i->i_mtime.tv_sec = inodeb->mtime; ++ i->i_atime.tv_sec = inodeb->mtime; ++ i->i_ctime.tv_sec = inodeb->mtime; ++ i->i_uid = msblk->uid[inodeb->uid]; ++ i->i_mode = inodeb->mode; ++ i->i_size = 0; ++ if (inodeb->guid == SQUASHFS_GUIDS) ++ i->i_gid = i->i_uid; ++ else ++ i->i_gid = msblk->guid[inodeb->guid]; ++} ++ ++ ++static squashfs_inode_t squashfs_inode_lookup(struct super_block *s, int ino) ++{ ++ struct squashfs_sb_info *msblk = s->s_fs_info; ++ long long start = msblk->inode_lookup_table[SQUASHFS_LOOKUP_BLOCK(ino - 1)]; ++ int offset = SQUASHFS_LOOKUP_BLOCK_OFFSET(ino - 1); ++ squashfs_inode_t inode; ++ ++ TRACE("Entered squashfs_inode_lookup, inode_number = %d\n", ino); ++ ++ if (msblk->swap) { ++ squashfs_inode_t sinode; ++ ++ if (!squashfs_get_cached_block(s, (char *) &sinode, start, offset, ++ sizeof(sinode), &start, &offset)) ++ goto out; ++ SQUASHFS_SWAP_INODE_T((&inode), &sinode); ++ } else if (!squashfs_get_cached_block(s, (char *) &inode, start, offset, ++ sizeof(inode), &start, &offset)) ++ goto out; ++ ++ TRACE("squashfs_inode_lookup, inode = 0x%llx\n", inode); ++ ++ return inode; ++ ++out: ++ return SQUASHFS_INVALID_BLK; ++} ++ ++ ++static void vfs_read_inode(struct inode *i) ++{ ++ struct squashfs_sb_info *msblk = i->i_sb->s_fs_info; ++ squashfs_inode_t inode = squashfs_inode_lookup(i->i_sb, i->i_ino); ++ ++ TRACE("Entered vfs_read_inode\n"); ++ ++ if(inode != SQUASHFS_INVALID_BLK) ++ (msblk->read_inode)(i, inode); ++} ++ ++ ++static struct dentry *squashfs_get_parent(struct dentry *child) ++{ ++ struct inode *i = child->d_inode; ++ struct inode *parent = iget(i->i_sb, SQUASHFS_I(i)->u.s2.parent_inode); ++ struct dentry *rv; ++ ++ TRACE("Entered squashfs_get_parent\n"); ++ ++ if(parent == NULL) { ++ rv = ERR_PTR(-EACCES); ++ goto out; ++ } ++ ++ rv = d_alloc_anon(parent); ++ if(rv == NULL) ++ rv = ERR_PTR(-ENOMEM); ++ ++out: ++ return rv; ++} ++ ++ ++SQSH_EXTERN struct inode *squashfs_iget(struct super_block *s, squashfs_inode_t inode, unsigned int inode_number) ++{ ++ struct squashfs_sb_info *msblk = s->s_fs_info; ++ struct inode *i = iget_locked(s, inode_number); ++ ++ TRACE("Entered squashfs_iget\n"); ++ ++ if(i && (i->i_state & I_NEW)) { ++ (msblk->read_inode)(i, inode); ++ unlock_new_inode(i); ++ } ++ ++ return i; ++} ++ ++ ++static int squashfs_read_inode(struct inode *i, squashfs_inode_t inode) ++{ ++ struct super_block *s = i->i_sb; ++ struct squashfs_sb_info *msblk = s->s_fs_info; ++ struct squashfs_super_block *sblk = &msblk->sblk; ++ long long block = SQUASHFS_INODE_BLK(inode) + ++ sblk->inode_table_start; ++ unsigned int offset = SQUASHFS_INODE_OFFSET(inode); ++ long long next_block; ++ unsigned int next_offset; ++ union squashfs_inode_header id, sid; ++ struct squashfs_base_inode_header *inodeb = &id.base, ++ *sinodeb = &sid.base; ++ ++ TRACE("Entered squashfs_read_inode\n"); ++ ++ if (msblk->swap) { ++ if (!squashfs_get_cached_block(s, (char *) sinodeb, block, ++ offset, sizeof(*sinodeb), &next_block, ++ &next_offset)) ++ goto failed_read; ++ SQUASHFS_SWAP_BASE_INODE_HEADER(inodeb, sinodeb, ++ sizeof(*sinodeb)); ++ } else ++ if (!squashfs_get_cached_block(s, (char *) inodeb, block, ++ offset, sizeof(*inodeb), &next_block, ++ &next_offset)) ++ goto failed_read; ++ ++ squashfs_new_inode(msblk, i, inodeb); ++ ++ switch(inodeb->inode_type) { ++ case SQUASHFS_FILE_TYPE: { ++ unsigned int frag_size; ++ long long frag_blk; ++ struct squashfs_reg_inode_header *inodep = &id.reg; ++ struct squashfs_reg_inode_header *sinodep = &sid.reg; ++ ++ if (msblk->swap) { ++ if (!squashfs_get_cached_block(s, (char *) ++ sinodep, block, offset, ++ sizeof(*sinodep), &next_block, ++ &next_offset)) ++ goto failed_read; ++ SQUASHFS_SWAP_REG_INODE_HEADER(inodep, sinodep); ++ } else ++ if (!squashfs_get_cached_block(s, (char *) ++ inodep, block, offset, ++ sizeof(*inodep), &next_block, ++ &next_offset)) ++ goto failed_read; ++ ++ frag_blk = SQUASHFS_INVALID_BLK; ++ if (inodep->fragment != SQUASHFS_INVALID_FRAG && ++ !get_fragment_location(s, ++ inodep->fragment, &frag_blk, &frag_size)) ++ goto failed_read; ++ ++ i->i_nlink = 1; ++ i->i_size = inodep->file_size; ++ i->i_fop = &generic_ro_fops; ++ i->i_mode |= S_IFREG; ++ i->i_blocks = ((i->i_size - 1) >> 9) + 1; ++ SQUASHFS_I(i)->u.s1.fragment_start_block = frag_blk; ++ SQUASHFS_I(i)->u.s1.fragment_size = frag_size; ++ SQUASHFS_I(i)->u.s1.fragment_offset = inodep->offset; ++ SQUASHFS_I(i)->start_block = inodep->start_block; ++ SQUASHFS_I(i)->u.s1.block_list_start = next_block; ++ SQUASHFS_I(i)->offset = next_offset; ++ if (sblk->block_size > 4096) ++ i->i_data.a_ops = &squashfs_aops; ++ else ++ i->i_data.a_ops = &squashfs_aops_4K; ++ ++ TRACE("File inode %x:%x, start_block %llx, " ++ "block_list_start %llx, offset %x\n", ++ SQUASHFS_INODE_BLK(inode), offset, ++ inodep->start_block, next_block, ++ next_offset); ++ break; ++ } ++ case SQUASHFS_LREG_TYPE: { ++ unsigned int frag_size; ++ long long frag_blk; ++ struct squashfs_lreg_inode_header *inodep = &id.lreg; ++ struct squashfs_lreg_inode_header *sinodep = &sid.lreg; ++ ++ if (msblk->swap) { ++ if (!squashfs_get_cached_block(s, (char *) ++ sinodep, block, offset, ++ sizeof(*sinodep), &next_block, ++ &next_offset)) ++ goto failed_read; ++ SQUASHFS_SWAP_LREG_INODE_HEADER(inodep, sinodep); ++ } else ++ if (!squashfs_get_cached_block(s, (char *) ++ inodep, block, offset, ++ sizeof(*inodep), &next_block, ++ &next_offset)) ++ goto failed_read; ++ ++ frag_blk = SQUASHFS_INVALID_BLK; ++ if (inodep->fragment != SQUASHFS_INVALID_FRAG && ++ !get_fragment_location(s, ++ inodep->fragment, &frag_blk, &frag_size)) ++ goto failed_read; ++ ++ i->i_nlink = inodep->nlink; ++ i->i_size = inodep->file_size; ++ i->i_fop = &generic_ro_fops; ++ i->i_mode |= S_IFREG; ++ i->i_blocks = ((i->i_size - 1) >> 9) + 1; ++ SQUASHFS_I(i)->u.s1.fragment_start_block = frag_blk; ++ SQUASHFS_I(i)->u.s1.fragment_size = frag_size; ++ SQUASHFS_I(i)->u.s1.fragment_offset = inodep->offset; ++ SQUASHFS_I(i)->start_block = inodep->start_block; ++ SQUASHFS_I(i)->u.s1.block_list_start = next_block; ++ SQUASHFS_I(i)->offset = next_offset; ++ if (sblk->block_size > 4096) ++ i->i_data.a_ops = &squashfs_aops; ++ else ++ i->i_data.a_ops = &squashfs_aops_4K; ++ ++ TRACE("File inode %x:%x, start_block %llx, " ++ "block_list_start %llx, offset %x\n", ++ SQUASHFS_INODE_BLK(inode), offset, ++ inodep->start_block, next_block, ++ next_offset); ++ break; ++ } ++ case SQUASHFS_DIR_TYPE: { ++ struct squashfs_dir_inode_header *inodep = &id.dir; ++ struct squashfs_dir_inode_header *sinodep = &sid.dir; ++ ++ if (msblk->swap) { ++ if (!squashfs_get_cached_block(s, (char *) ++ sinodep, block, offset, ++ sizeof(*sinodep), &next_block, ++ &next_offset)) ++ goto failed_read; ++ SQUASHFS_SWAP_DIR_INODE_HEADER(inodep, sinodep); ++ } else ++ if (!squashfs_get_cached_block(s, (char *) ++ inodep, block, offset, ++ sizeof(*inodep), &next_block, ++ &next_offset)) ++ goto failed_read; ++ ++ i->i_nlink = inodep->nlink; ++ i->i_size = inodep->file_size; ++ i->i_op = &squashfs_dir_inode_ops; ++ i->i_fop = &squashfs_dir_ops; ++ i->i_mode |= S_IFDIR; ++ SQUASHFS_I(i)->start_block = inodep->start_block; ++ SQUASHFS_I(i)->offset = inodep->offset; ++ SQUASHFS_I(i)->u.s2.directory_index_count = 0; ++ SQUASHFS_I(i)->u.s2.parent_inode = inodep->parent_inode; ++ ++ TRACE("Directory inode %x:%x, start_block %x, offset " ++ "%x\n", SQUASHFS_INODE_BLK(inode), ++ offset, inodep->start_block, ++ inodep->offset); ++ break; ++ } ++ case SQUASHFS_LDIR_TYPE: { ++ struct squashfs_ldir_inode_header *inodep = &id.ldir; ++ struct squashfs_ldir_inode_header *sinodep = &sid.ldir; ++ ++ if (msblk->swap) { ++ if (!squashfs_get_cached_block(s, (char *) ++ sinodep, block, offset, ++ sizeof(*sinodep), &next_block, ++ &next_offset)) ++ goto failed_read; ++ SQUASHFS_SWAP_LDIR_INODE_HEADER(inodep, ++ sinodep); ++ } else ++ if (!squashfs_get_cached_block(s, (char *) ++ inodep, block, offset, ++ sizeof(*inodep), &next_block, ++ &next_offset)) ++ goto failed_read; ++ ++ i->i_nlink = inodep->nlink; ++ i->i_size = inodep->file_size; ++ i->i_op = &squashfs_dir_inode_ops; ++ i->i_fop = &squashfs_dir_ops; ++ i->i_mode |= S_IFDIR; ++ SQUASHFS_I(i)->start_block = inodep->start_block; ++ SQUASHFS_I(i)->offset = inodep->offset; ++ SQUASHFS_I(i)->u.s2.directory_index_start = next_block; ++ SQUASHFS_I(i)->u.s2.directory_index_offset = ++ next_offset; ++ SQUASHFS_I(i)->u.s2.directory_index_count = ++ inodep->i_count; ++ SQUASHFS_I(i)->u.s2.parent_inode = inodep->parent_inode; ++ ++ TRACE("Long directory inode %x:%x, start_block %x, " ++ "offset %x\n", ++ SQUASHFS_INODE_BLK(inode), offset, ++ inodep->start_block, inodep->offset); ++ break; ++ } ++ case SQUASHFS_SYMLINK_TYPE: { ++ struct squashfs_symlink_inode_header *inodep = ++ &id.symlink; ++ struct squashfs_symlink_inode_header *sinodep = ++ &sid.symlink; ++ ++ if (msblk->swap) { ++ if (!squashfs_get_cached_block(s, (char *) ++ sinodep, block, offset, ++ sizeof(*sinodep), &next_block, ++ &next_offset)) ++ goto failed_read; ++ SQUASHFS_SWAP_SYMLINK_INODE_HEADER(inodep, ++ sinodep); ++ } else ++ if (!squashfs_get_cached_block(s, (char *) ++ inodep, block, offset, ++ sizeof(*inodep), &next_block, ++ &next_offset)) ++ goto failed_read; ++ ++ i->i_nlink = inodep->nlink; ++ i->i_size = inodep->symlink_size; ++ i->i_op = &page_symlink_inode_operations; ++ i->i_data.a_ops = &squashfs_symlink_aops; ++ i->i_mode |= S_IFLNK; ++ SQUASHFS_I(i)->start_block = next_block; ++ SQUASHFS_I(i)->offset = next_offset; ++ ++ TRACE("Symbolic link inode %x:%x, start_block %llx, " ++ "offset %x\n", ++ SQUASHFS_INODE_BLK(inode), offset, ++ next_block, next_offset); ++ break; ++ } ++ case SQUASHFS_BLKDEV_TYPE: ++ case SQUASHFS_CHRDEV_TYPE: { ++ struct squashfs_dev_inode_header *inodep = &id.dev; ++ struct squashfs_dev_inode_header *sinodep = &sid.dev; ++ ++ if (msblk->swap) { ++ if (!squashfs_get_cached_block(s, (char *) ++ sinodep, block, offset, ++ sizeof(*sinodep), &next_block, ++ &next_offset)) ++ goto failed_read; ++ SQUASHFS_SWAP_DEV_INODE_HEADER(inodep, sinodep); ++ } else ++ if (!squashfs_get_cached_block(s, (char *) ++ inodep, block, offset, ++ sizeof(*inodep), &next_block, ++ &next_offset)) ++ goto failed_read; ++ ++ i->i_nlink = inodep->nlink; ++ i->i_mode |= (inodeb->inode_type == ++ SQUASHFS_CHRDEV_TYPE) ? S_IFCHR : ++ S_IFBLK; ++ init_special_inode(i, i->i_mode, ++ old_decode_dev(inodep->rdev)); ++ ++ TRACE("Device inode %x:%x, rdev %x\n", ++ SQUASHFS_INODE_BLK(inode), offset, ++ inodep->rdev); ++ break; ++ } ++ case SQUASHFS_FIFO_TYPE: ++ case SQUASHFS_SOCKET_TYPE: { ++ struct squashfs_ipc_inode_header *inodep = &id.ipc; ++ struct squashfs_ipc_inode_header *sinodep = &sid.ipc; ++ ++ if (msblk->swap) { ++ if (!squashfs_get_cached_block(s, (char *) ++ sinodep, block, offset, ++ sizeof(*sinodep), &next_block, ++ &next_offset)) ++ goto failed_read; ++ SQUASHFS_SWAP_IPC_INODE_HEADER(inodep, sinodep); ++ } else ++ if (!squashfs_get_cached_block(s, (char *) ++ inodep, block, offset, ++ sizeof(*inodep), &next_block, ++ &next_offset)) ++ goto failed_read; ++ ++ i->i_nlink = inodep->nlink; ++ i->i_mode |= (inodeb->inode_type == SQUASHFS_FIFO_TYPE) ++ ? S_IFIFO : S_IFSOCK; ++ init_special_inode(i, i->i_mode, 0); ++ break; ++ } ++ default: ++ ERROR("Unknown inode type %d in squashfs_iget!\n", ++ inodeb->inode_type); ++ goto failed_read1; ++ } ++ ++ return 1; ++ ++failed_read: ++ ERROR("Unable to read inode [%llx:%x]\n", block, offset); ++ ++failed_read1: ++ make_bad_inode(i); ++ return 0; ++} ++ ++ ++static int read_inode_lookup_table(struct super_block *s) ++{ ++ struct squashfs_sb_info *msblk = s->s_fs_info; ++ struct squashfs_super_block *sblk = &msblk->sblk; ++ unsigned int length = SQUASHFS_LOOKUP_BLOCK_BYTES(sblk->inodes); ++ ++ TRACE("In read_inode_lookup_table, length %d\n", length); ++ ++ /* Allocate inode lookup table */ ++ if (!(msblk->inode_lookup_table = kmalloc(length, GFP_KERNEL))) { ++ ERROR("Failed to allocate inode lookup table\n"); ++ return 0; ++ } ++ ++ if (!squashfs_read_data(s, (char *) msblk->inode_lookup_table, ++ sblk->lookup_table_start, length | ++ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, length)) { ++ ERROR("unable to read inode lookup table\n"); ++ return 0; ++ } ++ ++ if (msblk->swap) { ++ int i; ++ long long block; ++ ++ for (i = 0; i < SQUASHFS_LOOKUP_BLOCKS(sblk->inodes); i++) { ++ SQUASHFS_SWAP_LOOKUP_BLOCKS((&block), ++ &msblk->inode_lookup_table[i], 1); ++ msblk->inode_lookup_table[i] = block; ++ } ++ } ++ ++ return 1; ++} ++ ++ ++static int read_fragment_index_table(struct super_block *s) ++{ ++ struct squashfs_sb_info *msblk = s->s_fs_info; ++ struct squashfs_super_block *sblk = &msblk->sblk; ++ unsigned int length = SQUASHFS_FRAGMENT_INDEX_BYTES(sblk->fragments); ++ ++ if(length == 0) ++ return 1; ++ ++ /* Allocate fragment index table */ ++ if (!(msblk->fragment_index = kmalloc(length, GFP_KERNEL))) { ++ ERROR("Failed to allocate fragment index table\n"); ++ return 0; ++ } ++ ++ if (!squashfs_read_data(s, (char *) msblk->fragment_index, ++ sblk->fragment_table_start, length | ++ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, length)) { ++ ERROR("unable to read fragment index table\n"); ++ return 0; ++ } ++ ++ if (msblk->swap) { ++ int i; ++ long long fragment; ++ ++ for (i = 0; i < SQUASHFS_FRAGMENT_INDEXES(sblk->fragments); i++) { ++ SQUASHFS_SWAP_FRAGMENT_INDEXES((&fragment), ++ &msblk->fragment_index[i], 1); ++ msblk->fragment_index[i] = fragment; ++ } ++ } ++ ++ return 1; ++} ++ ++ ++static int supported_squashfs_filesystem(struct squashfs_sb_info *msblk, int silent) ++{ ++ struct squashfs_super_block *sblk = &msblk->sblk; ++ ++ msblk->read_inode = squashfs_read_inode; ++ msblk->read_blocklist = read_blocklist; ++ msblk->read_fragment_index_table = read_fragment_index_table; ++ ++ if (sblk->s_major == 1) { ++ if (!squashfs_1_0_supported(msblk)) { ++ SERROR("Major/Minor mismatch, Squashfs 1.0 filesystems " ++ "are unsupported\n"); ++ SERROR("Please recompile with " ++ "Squashfs 1.0 support enabled\n"); ++ return 0; ++ } ++ } else if (sblk->s_major == 2) { ++ if (!squashfs_2_0_supported(msblk)) { ++ SERROR("Major/Minor mismatch, Squashfs 2.0 filesystems " ++ "are unsupported\n"); ++ SERROR("Please recompile with " ++ "Squashfs 2.0 support enabled\n"); ++ return 0; ++ } ++ } else if(sblk->s_major != SQUASHFS_MAJOR || sblk->s_minor > ++ SQUASHFS_MINOR) { ++ SERROR("Major/Minor mismatch, trying to mount newer %d.%d " ++ "filesystem\n", sblk->s_major, sblk->s_minor); ++ SERROR("Please update your kernel\n"); ++ return 0; ++ } ++ ++ return 1; ++} ++ ++ ++static int squashfs_fill_super(struct super_block *s, void *data, int silent) ++{ ++ struct squashfs_sb_info *msblk; ++ struct squashfs_super_block *sblk; ++ int i; ++ char b[BDEVNAME_SIZE]; ++ struct inode *root; ++ ++ TRACE("Entered squashfs_read_superblock\n"); ++ ++ if (!(s->s_fs_info = kmalloc(sizeof(struct squashfs_sb_info), ++ GFP_KERNEL))) { ++ ERROR("Failed to allocate superblock\n"); ++ goto failure; ++ } ++ memset(s->s_fs_info, 0, sizeof(struct squashfs_sb_info)); ++ msblk = s->s_fs_info; ++ if (!(msblk->stream.workspace = vmalloc(zlib_inflate_workspacesize()))) { ++ ERROR("Failed to allocate zlib workspace\n"); ++ goto failure; ++ } ++ sblk = &msblk->sblk; ++ ++ msblk->devblksize = sb_min_blocksize(s, BLOCK_SIZE); ++ msblk->devblksize_log2 = ffz(~msblk->devblksize); ++ ++ mutex_init(&msblk->read_data_mutex); ++ mutex_init(&msblk->read_page_mutex); ++ mutex_init(&msblk->block_cache_mutex); ++ mutex_init(&msblk->fragment_mutex); ++ mutex_init(&msblk->meta_index_mutex); ++ ++ init_waitqueue_head(&msblk->waitq); ++ init_waitqueue_head(&msblk->fragment_wait_queue); ++ ++ sblk->bytes_used = sizeof(struct squashfs_super_block); ++ if (!squashfs_read_data(s, (char *) sblk, SQUASHFS_START, ++ sizeof(struct squashfs_super_block) | ++ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, sizeof(struct squashfs_super_block))) { ++ SERROR("unable to read superblock\n"); ++ goto failed_mount; ++ } ++ ++ /* Check it is a SQUASHFS superblock */ ++ msblk->swap = 0; ++ if ((s->s_magic = sblk->s_magic) != SQUASHFS_MAGIC) { ++ if (sblk->s_magic == SQUASHFS_MAGIC_SWAP) { ++ struct squashfs_super_block ssblk; ++ ++ WARNING("Mounting a different endian SQUASHFS " ++ "filesystem on %s\n", bdevname(s->s_bdev, b)); ++ ++ SQUASHFS_SWAP_SUPER_BLOCK(&ssblk, sblk); ++ memcpy(sblk, &ssblk, sizeof(struct squashfs_super_block)); ++ msblk->swap = 1; ++ } else { ++ SERROR("Can't find a SQUASHFS superblock on %s\n", ++ bdevname(s->s_bdev, b)); ++ goto failed_mount; ++ } ++ } ++ ++ /* Check the MAJOR & MINOR versions */ ++ if(!supported_squashfs_filesystem(msblk, silent)) ++ goto failed_mount; ++ ++ /* Check the filesystem does not extend beyond the end of the ++ block device */ ++ if(sblk->bytes_used < 0 || sblk->bytes_used > i_size_read(s->s_bdev->bd_inode)) ++ goto failed_mount; ++ ++ /* Check the root inode for sanity */ ++ if (SQUASHFS_INODE_OFFSET(sblk->root_inode) > SQUASHFS_METADATA_SIZE) ++ goto failed_mount; ++ ++ TRACE("Found valid superblock on %s\n", bdevname(s->s_bdev, b)); ++ TRACE("Inodes are %scompressed\n", ++ SQUASHFS_UNCOMPRESSED_INODES ++ (sblk->flags) ? "un" : ""); ++ TRACE("Data is %scompressed\n", ++ SQUASHFS_UNCOMPRESSED_DATA(sblk->flags) ++ ? "un" : ""); ++ TRACE("Check data is %s present in the filesystem\n", ++ SQUASHFS_CHECK_DATA(sblk->flags) ? ++ "" : "not"); ++ TRACE("Filesystem size %lld bytes\n", sblk->bytes_used); ++ TRACE("Block size %d\n", sblk->block_size); ++ TRACE("Number of inodes %d\n", sblk->inodes); ++ if (sblk->s_major > 1) ++ TRACE("Number of fragments %d\n", sblk->fragments); ++ TRACE("Number of uids %d\n", sblk->no_uids); ++ TRACE("Number of gids %d\n", sblk->no_guids); ++ TRACE("sblk->inode_table_start %llx\n", sblk->inode_table_start); ++ TRACE("sblk->directory_table_start %llx\n", sblk->directory_table_start); ++ if (sblk->s_major > 1) ++ TRACE("sblk->fragment_table_start %llx\n", ++ sblk->fragment_table_start); ++ TRACE("sblk->uid_start %llx\n", sblk->uid_start); ++ ++ s->s_flags |= MS_RDONLY; ++ s->s_op = &squashfs_super_ops; ++ ++ /* Init inode_table block pointer array */ ++ if (!(msblk->block_cache = kmalloc(sizeof(struct squashfs_cache) * ++ SQUASHFS_CACHED_BLKS, GFP_KERNEL))) { ++ ERROR("Failed to allocate block cache\n"); ++ goto failed_mount; ++ } ++ ++ for (i = 0; i < SQUASHFS_CACHED_BLKS; i++) ++ msblk->block_cache[i].block = SQUASHFS_INVALID_BLK; ++ ++ msblk->next_cache = 0; ++ ++ /* Allocate read_page block */ ++ if (!(msblk->read_page = kmalloc(sblk->block_size, GFP_KERNEL))) { ++ ERROR("Failed to allocate read_page block\n"); ++ goto failed_mount; ++ } ++ ++ /* Allocate uid and gid tables */ ++ if (!(msblk->uid = kmalloc((sblk->no_uids + sblk->no_guids) * ++ sizeof(unsigned int), GFP_KERNEL))) { ++ ERROR("Failed to allocate uid/gid table\n"); ++ goto failed_mount; ++ } ++ msblk->guid = msblk->uid + sblk->no_uids; ++ ++ if (msblk->swap) { ++ unsigned int suid[sblk->no_uids + sblk->no_guids]; ++ ++ if (!squashfs_read_data(s, (char *) &suid, sblk->uid_start, ++ ((sblk->no_uids + sblk->no_guids) * ++ sizeof(unsigned int)) | ++ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, (sblk->no_uids + sblk->no_guids) * sizeof(unsigned int))) { ++ ERROR("unable to read uid/gid table\n"); ++ goto failed_mount; ++ } ++ ++ SQUASHFS_SWAP_DATA(msblk->uid, suid, (sblk->no_uids + ++ sblk->no_guids), (sizeof(unsigned int) * 8)); ++ } else ++ if (!squashfs_read_data(s, (char *) msblk->uid, sblk->uid_start, ++ ((sblk->no_uids + sblk->no_guids) * ++ sizeof(unsigned int)) | ++ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, (sblk->no_uids + sblk->no_guids) * sizeof(unsigned int))) { ++ ERROR("unable to read uid/gid table\n"); ++ goto failed_mount; ++ } ++ ++ ++ if (sblk->s_major == 1 && squashfs_1_0_supported(msblk)) ++ goto allocate_root; ++ ++ if (!(msblk->fragment = kmalloc(sizeof(struct squashfs_fragment_cache) * ++ SQUASHFS_CACHED_FRAGMENTS, GFP_KERNEL))) { ++ ERROR("Failed to allocate fragment block cache\n"); ++ goto failed_mount; ++ } ++ ++ for (i = 0; i < SQUASHFS_CACHED_FRAGMENTS; i++) { ++ msblk->fragment[i].locked = 0; ++ msblk->fragment[i].block = SQUASHFS_INVALID_BLK; ++ msblk->fragment[i].data = NULL; ++ } ++ ++ msblk->next_fragment = 0; ++ ++ /* Allocate and read fragment index table */ ++ if (msblk->read_fragment_index_table(s) == 0) ++ goto failed_mount; ++ ++ if(sblk->s_major < 3 || sblk->lookup_table_start == SQUASHFS_INVALID_BLK) ++ goto allocate_root; ++ ++ /* Allocate and read inode lookup table */ ++ if (read_inode_lookup_table(s) == 0) ++ goto failed_mount; ++ ++ s->s_op = &squashfs_export_super_ops; ++ s->s_export_op = &squashfs_export_ops; ++ ++allocate_root: ++ root = new_inode(s); ++ if ((msblk->read_inode)(root, sblk->root_inode) == 0) ++ goto failed_mount; ++ insert_inode_hash(root); ++ ++ if ((s->s_root = d_alloc_root(root)) == NULL) { ++ ERROR("Root inode create failed\n"); ++ iput(root); ++ goto failed_mount; ++ } ++ ++ TRACE("Leaving squashfs_read_super\n"); ++ return 0; ++ ++failed_mount: ++ kfree(msblk->inode_lookup_table); ++ kfree(msblk->fragment_index); ++ kfree(msblk->fragment); ++ kfree(msblk->uid); ++ kfree(msblk->read_page); ++ kfree(msblk->block_cache); ++ kfree(msblk->fragment_index_2); ++ vfree(msblk->stream.workspace); ++ kfree(s->s_fs_info); ++ s->s_fs_info = NULL; ++ return -EINVAL; ++ ++failure: ++ return -ENOMEM; ++} ++ ++ ++static int squashfs_statfs(struct dentry *dentry, struct kstatfs *buf) ++{ ++ struct squashfs_sb_info *msblk = dentry->d_sb->s_fs_info; ++ struct squashfs_super_block *sblk = &msblk->sblk; ++ ++ TRACE("Entered squashfs_statfs\n"); ++ ++ buf->f_type = SQUASHFS_MAGIC; ++ buf->f_bsize = sblk->block_size; ++ buf->f_blocks = ((sblk->bytes_used - 1) >> sblk->block_log) + 1; ++ buf->f_bfree = buf->f_bavail = 0; ++ buf->f_files = sblk->inodes; ++ buf->f_ffree = 0; ++ buf->f_namelen = SQUASHFS_NAME_LEN; ++ ++ return 0; ++} ++ ++ ++static int squashfs_symlink_readpage(struct file *file, struct page *page) ++{ ++ struct inode *inode = page->mapping->host; ++ int index = page->index << PAGE_CACHE_SHIFT, length, bytes; ++ long long block = SQUASHFS_I(inode)->start_block; ++ int offset = SQUASHFS_I(inode)->offset; ++ void *pageaddr = kmap(page); ++ ++ TRACE("Entered squashfs_symlink_readpage, page index %ld, start block " ++ "%llx, offset %x\n", page->index, ++ SQUASHFS_I(inode)->start_block, ++ SQUASHFS_I(inode)->offset); ++ ++ for (length = 0; length < index; length += bytes) { ++ if (!(bytes = squashfs_get_cached_block(inode->i_sb, NULL, ++ block, offset, PAGE_CACHE_SIZE, &block, ++ &offset))) { ++ ERROR("Unable to read symbolic link [%llx:%x]\n", block, ++ offset); ++ goto skip_read; ++ } ++ } ++ ++ if (length != index) { ++ ERROR("(squashfs_symlink_readpage) length != index\n"); ++ bytes = 0; ++ goto skip_read; ++ } ++ ++ bytes = (i_size_read(inode) - length) > PAGE_CACHE_SIZE ? PAGE_CACHE_SIZE : ++ i_size_read(inode) - length; ++ ++ if (!(bytes = squashfs_get_cached_block(inode->i_sb, pageaddr, block, ++ offset, bytes, &block, &offset))) ++ ERROR("Unable to read symbolic link [%llx:%x]\n", block, offset); ++ ++skip_read: ++ memset(pageaddr + bytes, 0, PAGE_CACHE_SIZE - bytes); ++ kunmap(page); ++ flush_dcache_page(page); ++ SetPageUptodate(page); ++ unlock_page(page); ++ ++ return 0; ++} ++ ++ ++struct meta_index *locate_meta_index(struct inode *inode, int index, int offset) ++{ ++ struct meta_index *meta = NULL; ++ struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info; ++ int i; ++ ++ mutex_lock(&msblk->meta_index_mutex); ++ ++ TRACE("locate_meta_index: index %d, offset %d\n", index, offset); ++ ++ if(msblk->meta_index == NULL) ++ goto not_allocated; ++ ++ for (i = 0; i < SQUASHFS_META_NUMBER; i ++) ++ if (msblk->meta_index[i].inode_number == inode->i_ino && ++ msblk->meta_index[i].offset >= offset && ++ msblk->meta_index[i].offset <= index && ++ msblk->meta_index[i].locked == 0) { ++ TRACE("locate_meta_index: entry %d, offset %d\n", i, ++ msblk->meta_index[i].offset); ++ meta = &msblk->meta_index[i]; ++ offset = meta->offset; ++ } ++ ++ if (meta) ++ meta->locked = 1; ++ ++not_allocated: ++ mutex_unlock(&msblk->meta_index_mutex); ++ ++ return meta; ++} ++ ++ ++struct meta_index *empty_meta_index(struct inode *inode, int offset, int skip) ++{ ++ struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info; ++ struct meta_index *meta = NULL; ++ int i; ++ ++ mutex_lock(&msblk->meta_index_mutex); ++ ++ TRACE("empty_meta_index: offset %d, skip %d\n", offset, skip); ++ ++ if(msblk->meta_index == NULL) { ++ if (!(msblk->meta_index = kmalloc(sizeof(struct meta_index) * ++ SQUASHFS_META_NUMBER, GFP_KERNEL))) { ++ ERROR("Failed to allocate meta_index\n"); ++ goto failed; ++ } ++ for(i = 0; i < SQUASHFS_META_NUMBER; i++) { ++ msblk->meta_index[i].inode_number = 0; ++ msblk->meta_index[i].locked = 0; ++ } ++ msblk->next_meta_index = 0; ++ } ++ ++ for(i = SQUASHFS_META_NUMBER; i && ++ msblk->meta_index[msblk->next_meta_index].locked; i --) ++ msblk->next_meta_index = (msblk->next_meta_index + 1) % ++ SQUASHFS_META_NUMBER; ++ ++ if(i == 0) { ++ TRACE("empty_meta_index: failed!\n"); ++ goto failed; ++ } ++ ++ TRACE("empty_meta_index: returned meta entry %d, %p\n", ++ msblk->next_meta_index, ++ &msblk->meta_index[msblk->next_meta_index]); ++ ++ meta = &msblk->meta_index[msblk->next_meta_index]; ++ msblk->next_meta_index = (msblk->next_meta_index + 1) % ++ SQUASHFS_META_NUMBER; ++ ++ meta->inode_number = inode->i_ino; ++ meta->offset = offset; ++ meta->skip = skip; ++ meta->entries = 0; ++ meta->locked = 1; ++ ++failed: ++ mutex_unlock(&msblk->meta_index_mutex); ++ return meta; ++} ++ ++ ++void release_meta_index(struct inode *inode, struct meta_index *meta) ++{ ++ meta->locked = 0; ++ smp_mb(); ++} ++ ++ ++static int read_block_index(struct super_block *s, int blocks, char *block_list, ++ long long *start_block, int *offset) ++{ ++ struct squashfs_sb_info *msblk = s->s_fs_info; ++ unsigned int *block_listp; ++ int block = 0; ++ ++ if (msblk->swap) { ++ char sblock_list[blocks << 2]; ++ ++ if (!squashfs_get_cached_block(s, sblock_list, *start_block, ++ *offset, blocks << 2, start_block, offset)) { ++ ERROR("Unable to read block list [%llx:%x]\n", ++ *start_block, *offset); ++ goto failure; ++ } ++ SQUASHFS_SWAP_INTS(((unsigned int *)block_list), ++ ((unsigned int *)sblock_list), blocks); ++ } else ++ if (!squashfs_get_cached_block(s, block_list, *start_block, ++ *offset, blocks << 2, start_block, offset)) { ++ ERROR("Unable to read block list [%llx:%x]\n", ++ *start_block, *offset); ++ goto failure; ++ } ++ ++ for (block_listp = (unsigned int *) block_list; blocks; ++ block_listp++, blocks --) ++ block += SQUASHFS_COMPRESSED_SIZE_BLOCK(*block_listp); ++ ++ return block; ++ ++failure: ++ return -1; ++} ++ ++ ++#define SIZE 256 ++ ++static inline int calculate_skip(int blocks) { ++ int skip = (blocks - 1) / ((SQUASHFS_SLOTS * SQUASHFS_META_ENTRIES + 1) * SQUASHFS_META_INDEXES); ++ return skip >= 7 ? 7 : skip + 1; ++} ++ ++ ++static int get_meta_index(struct inode *inode, int index, ++ long long *index_block, int *index_offset, ++ long long *data_block, char *block_list) ++{ ++ struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info; ++ struct squashfs_super_block *sblk = &msblk->sblk; ++ int skip = calculate_skip(i_size_read(inode) >> sblk->block_log); ++ int offset = 0; ++ struct meta_index *meta; ++ struct meta_entry *meta_entry; ++ long long cur_index_block = SQUASHFS_I(inode)->u.s1.block_list_start; ++ int cur_offset = SQUASHFS_I(inode)->offset; ++ long long cur_data_block = SQUASHFS_I(inode)->start_block; ++ int i; ++ ++ index /= SQUASHFS_META_INDEXES * skip; ++ ++ while ( offset < index ) { ++ meta = locate_meta_index(inode, index, offset + 1); ++ ++ if (meta == NULL) { ++ if ((meta = empty_meta_index(inode, offset + 1, ++ skip)) == NULL) ++ goto all_done; ++ } else { ++ if(meta->entries == 0) ++ goto failed; ++ offset = index < meta->offset + meta->entries ? index : ++ meta->offset + meta->entries - 1; ++ meta_entry = &meta->meta_entry[offset - meta->offset]; ++ cur_index_block = meta_entry->index_block + sblk->inode_table_start; ++ cur_offset = meta_entry->offset; ++ cur_data_block = meta_entry->data_block; ++ TRACE("get_meta_index: offset %d, meta->offset %d, " ++ "meta->entries %d\n", offset, meta->offset, ++ meta->entries); ++ TRACE("get_meta_index: index_block 0x%llx, offset 0x%x" ++ " data_block 0x%llx\n", cur_index_block, ++ cur_offset, cur_data_block); ++ } ++ ++ for (i = meta->offset + meta->entries; i <= index && ++ i < meta->offset + SQUASHFS_META_ENTRIES; i++) { ++ int blocks = skip * SQUASHFS_META_INDEXES; ++ ++ while (blocks) { ++ int block = blocks > (SIZE >> 2) ? (SIZE >> 2) : ++ blocks; ++ int res = read_block_index(inode->i_sb, block, ++ block_list, &cur_index_block, ++ &cur_offset); ++ ++ if (res == -1) ++ goto failed; ++ ++ cur_data_block += res; ++ blocks -= block; ++ } ++ ++ meta_entry = &meta->meta_entry[i - meta->offset]; ++ meta_entry->index_block = cur_index_block - sblk->inode_table_start; ++ meta_entry->offset = cur_offset; ++ meta_entry->data_block = cur_data_block; ++ meta->entries ++; ++ offset ++; ++ } ++ ++ TRACE("get_meta_index: meta->offset %d, meta->entries %d\n", ++ meta->offset, meta->entries); ++ ++ release_meta_index(inode, meta); ++ } ++ ++all_done: ++ *index_block = cur_index_block; ++ *index_offset = cur_offset; ++ *data_block = cur_data_block; ++ ++ return offset * SQUASHFS_META_INDEXES * skip; ++ ++failed: ++ release_meta_index(inode, meta); ++ return -1; ++} ++ ++ ++static long long read_blocklist(struct inode *inode, int index, ++ int readahead_blks, char *block_list, ++ unsigned short **block_p, unsigned int *bsize) ++{ ++ long long block_ptr; ++ int offset; ++ long long block; ++ int res = get_meta_index(inode, index, &block_ptr, &offset, &block, ++ block_list); ++ ++ TRACE("read_blocklist: res %d, index %d, block_ptr 0x%llx, offset" ++ " 0x%x, block 0x%llx\n", res, index, block_ptr, offset, ++ block); ++ ++ if(res == -1) ++ goto failure; ++ ++ index -= res; ++ ++ while ( index ) { ++ int blocks = index > (SIZE >> 2) ? (SIZE >> 2) : index; ++ int res = read_block_index(inode->i_sb, blocks, block_list, ++ &block_ptr, &offset); ++ if (res == -1) ++ goto failure; ++ block += res; ++ index -= blocks; ++ } ++ ++ if (read_block_index(inode->i_sb, 1, block_list, ++ &block_ptr, &offset) == -1) ++ goto failure; ++ *bsize = *((unsigned int *) block_list); ++ ++ return block; ++ ++failure: ++ return 0; ++} ++ ++ ++static int squashfs_readpage(struct file *file, struct page *page) ++{ ++ struct inode *inode = page->mapping->host; ++ struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info; ++ struct squashfs_super_block *sblk = &msblk->sblk; ++ unsigned char *block_list; ++ long long block; ++ unsigned int bsize, i = 0, bytes = 0, byte_offset = 0; ++ int index = page->index >> (sblk->block_log - PAGE_CACHE_SHIFT); ++ void *pageaddr; ++ struct squashfs_fragment_cache *fragment = NULL; ++ char *data_ptr = msblk->read_page; ++ ++ int mask = (1 << (sblk->block_log - PAGE_CACHE_SHIFT)) - 1; ++ int start_index = page->index & ~mask; ++ int end_index = start_index | mask; ++ ++ TRACE("Entered squashfs_readpage, page index %lx, start block %llx\n", ++ page->index, ++ SQUASHFS_I(inode)->start_block); ++ ++ if (!(block_list = kmalloc(SIZE, GFP_KERNEL))) { ++ ERROR("Failed to allocate block_list\n"); ++ goto skip_read; ++ } ++ ++ if (page->index >= ((i_size_read(inode) + PAGE_CACHE_SIZE - 1) >> ++ PAGE_CACHE_SHIFT)) ++ goto skip_read; ++ ++ if (SQUASHFS_I(inode)->u.s1.fragment_start_block == SQUASHFS_INVALID_BLK ++ || index < (i_size_read(inode) >> ++ sblk->block_log)) { ++ if ((block = (msblk->read_blocklist)(inode, index, 1, ++ block_list, NULL, &bsize)) == 0) ++ goto skip_read; ++ ++ mutex_lock(&msblk->read_page_mutex); ++ ++ if (!(bytes = squashfs_read_data(inode->i_sb, msblk->read_page, ++ block, bsize, NULL, sblk->block_size))) { ++ ERROR("Unable to read page, block %llx, size %x\n", block, ++ bsize); ++ mutex_unlock(&msblk->read_page_mutex); ++ goto skip_read; ++ } ++ } else { ++ if ((fragment = get_cached_fragment(inode->i_sb, ++ SQUASHFS_I(inode)-> ++ u.s1.fragment_start_block, ++ SQUASHFS_I(inode)->u.s1.fragment_size)) ++ == NULL) { ++ ERROR("Unable to read page, block %llx, size %x\n", ++ SQUASHFS_I(inode)-> ++ u.s1.fragment_start_block, ++ (int) SQUASHFS_I(inode)-> ++ u.s1.fragment_size); ++ goto skip_read; ++ } ++ bytes = SQUASHFS_I(inode)->u.s1.fragment_offset + ++ (i_size_read(inode) & (sblk->block_size ++ - 1)); ++ byte_offset = SQUASHFS_I(inode)->u.s1.fragment_offset; ++ data_ptr = fragment->data; ++ } ++ ++ for (i = start_index; i <= end_index && byte_offset < bytes; ++ i++, byte_offset += PAGE_CACHE_SIZE) { ++ struct page *push_page; ++ int avail = (bytes - byte_offset) > PAGE_CACHE_SIZE ? ++ PAGE_CACHE_SIZE : bytes - byte_offset; ++ ++ TRACE("bytes %d, i %d, byte_offset %d, available_bytes %d\n", ++ bytes, i, byte_offset, avail); ++ ++ push_page = (i == page->index) ? page : ++ grab_cache_page_nowait(page->mapping, i); ++ ++ if (!push_page) ++ continue; ++ ++ if (PageUptodate(push_page)) ++ goto skip_page; ++ ++ pageaddr = kmap_atomic(push_page, KM_USER0); ++ memcpy(pageaddr, data_ptr + byte_offset, avail); ++ memset(pageaddr + avail, 0, PAGE_CACHE_SIZE - avail); ++ kunmap_atomic(pageaddr, KM_USER0); ++ flush_dcache_page(push_page); ++ SetPageUptodate(push_page); ++skip_page: ++ unlock_page(push_page); ++ if(i != page->index) ++ page_cache_release(push_page); ++ } ++ ++ if (SQUASHFS_I(inode)->u.s1.fragment_start_block == SQUASHFS_INVALID_BLK ++ || index < (i_size_read(inode) >> ++ sblk->block_log)) ++ mutex_unlock(&msblk->read_page_mutex); ++ else ++ release_cached_fragment(msblk, fragment); ++ ++ kfree(block_list); ++ return 0; ++ ++skip_read: ++ pageaddr = kmap_atomic(page, KM_USER0); ++ memset(pageaddr + bytes, 0, PAGE_CACHE_SIZE - bytes); ++ kunmap_atomic(pageaddr, KM_USER0); ++ flush_dcache_page(page); ++ SetPageUptodate(page); ++ unlock_page(page); ++ ++ kfree(block_list); ++ return 0; ++} ++ ++ ++static int squashfs_readpage4K(struct file *file, struct page *page) ++{ ++ struct inode *inode = page->mapping->host; ++ struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info; ++ struct squashfs_super_block *sblk = &msblk->sblk; ++ unsigned char *block_list; ++ long long block; ++ unsigned int bsize, bytes = 0; ++ void *pageaddr; ++ ++ TRACE("Entered squashfs_readpage4K, page index %lx, start block %llx\n", ++ page->index, ++ SQUASHFS_I(inode)->start_block); ++ ++ if (page->index >= ((i_size_read(inode) + PAGE_CACHE_SIZE - 1) >> ++ PAGE_CACHE_SHIFT)) { ++ block_list = NULL; ++ goto skip_read; ++ } ++ ++ if (!(block_list = kmalloc(SIZE, GFP_KERNEL))) { ++ ERROR("Failed to allocate block_list\n"); ++ goto skip_read; ++ } ++ ++ if (SQUASHFS_I(inode)->u.s1.fragment_start_block == SQUASHFS_INVALID_BLK ++ || page->index < (i_size_read(inode) >> ++ sblk->block_log)) { ++ block = (msblk->read_blocklist)(inode, page->index, 1, ++ block_list, NULL, &bsize); ++ if(block == 0) ++ goto skip_read; ++ ++ mutex_lock(&msblk->read_page_mutex); ++ bytes = squashfs_read_data(inode->i_sb, msblk->read_page, block, ++ bsize, NULL, sblk->block_size); ++ if (bytes) { ++ pageaddr = kmap_atomic(page, KM_USER0); ++ memcpy(pageaddr, msblk->read_page, bytes); ++ kunmap_atomic(pageaddr, KM_USER0); ++ } else ++ ERROR("Unable to read page, block %llx, size %x\n", ++ block, bsize); ++ mutex_unlock(&msblk->read_page_mutex); ++ } else { ++ struct squashfs_fragment_cache *fragment = ++ get_cached_fragment(inode->i_sb, ++ SQUASHFS_I(inode)-> ++ u.s1.fragment_start_block, ++ SQUASHFS_I(inode)-> u.s1.fragment_size); ++ if (fragment) { ++ bytes = i_size_read(inode) & (sblk->block_size - 1); ++ pageaddr = kmap_atomic(page, KM_USER0); ++ memcpy(pageaddr, fragment->data + SQUASHFS_I(inode)-> ++ u.s1.fragment_offset, bytes); ++ kunmap_atomic(pageaddr, KM_USER0); ++ release_cached_fragment(msblk, fragment); ++ } else ++ ERROR("Unable to read page, block %llx, size %x\n", ++ SQUASHFS_I(inode)-> ++ u.s1.fragment_start_block, (int) ++ SQUASHFS_I(inode)-> u.s1.fragment_size); ++ } ++ ++skip_read: ++ pageaddr = kmap_atomic(page, KM_USER0); ++ memset(pageaddr + bytes, 0, PAGE_CACHE_SIZE - bytes); ++ kunmap_atomic(pageaddr, KM_USER0); ++ flush_dcache_page(page); ++ SetPageUptodate(page); ++ unlock_page(page); ++ ++ kfree(block_list); ++ return 0; ++} ++ ++ ++static int get_dir_index_using_offset(struct super_block *s, long long ++ *next_block, unsigned int *next_offset, ++ long long index_start, ++ unsigned int index_offset, int i_count, ++ long long f_pos) ++{ ++ struct squashfs_sb_info *msblk = s->s_fs_info; ++ struct squashfs_super_block *sblk = &msblk->sblk; ++ int i, length = 0; ++ struct squashfs_dir_index index; ++ ++ TRACE("Entered get_dir_index_using_offset, i_count %d, f_pos %d\n", ++ i_count, (unsigned int) f_pos); ++ ++ f_pos =- 3; ++ if (f_pos == 0) ++ goto finish; ++ ++ for (i = 0; i < i_count; i++) { ++ if (msblk->swap) { ++ struct squashfs_dir_index sindex; ++ squashfs_get_cached_block(s, (char *) &sindex, ++ index_start, index_offset, ++ sizeof(sindex), &index_start, ++ &index_offset); ++ SQUASHFS_SWAP_DIR_INDEX(&index, &sindex); ++ } else ++ squashfs_get_cached_block(s, (char *) &index, ++ index_start, index_offset, ++ sizeof(index), &index_start, ++ &index_offset); ++ ++ if (index.index > f_pos) ++ break; ++ ++ squashfs_get_cached_block(s, NULL, index_start, index_offset, ++ index.size + 1, &index_start, ++ &index_offset); ++ ++ length = index.index; ++ *next_block = index.start_block + sblk->directory_table_start; ++ } ++ ++ *next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE; ++ ++finish: ++ return length + 3; ++} ++ ++ ++static int get_dir_index_using_name(struct super_block *s, long long ++ *next_block, unsigned int *next_offset, ++ long long index_start, ++ unsigned int index_offset, int i_count, ++ const char *name, int size) ++{ ++ struct squashfs_sb_info *msblk = s->s_fs_info; ++ struct squashfs_super_block *sblk = &msblk->sblk; ++ int i, length = 0; ++ struct squashfs_dir_index *index; ++ char *str; ++ ++ TRACE("Entered get_dir_index_using_name, i_count %d\n", i_count); ++ ++ if (!(str = kmalloc(sizeof(struct squashfs_dir_index) + ++ (SQUASHFS_NAME_LEN + 1) * 2, GFP_KERNEL))) { ++ ERROR("Failed to allocate squashfs_dir_index\n"); ++ goto failure; ++ } ++ ++ index = (struct squashfs_dir_index *) (str + SQUASHFS_NAME_LEN + 1); ++ strncpy(str, name, size); ++ str[size] = '\0'; ++ ++ for (i = 0; i < i_count; i++) { ++ if (msblk->swap) { ++ struct squashfs_dir_index sindex; ++ squashfs_get_cached_block(s, (char *) &sindex, ++ index_start, index_offset, ++ sizeof(sindex), &index_start, ++ &index_offset); ++ SQUASHFS_SWAP_DIR_INDEX(index, &sindex); ++ } else ++ squashfs_get_cached_block(s, (char *) index, ++ index_start, index_offset, ++ sizeof(struct squashfs_dir_index), ++ &index_start, &index_offset); ++ ++ squashfs_get_cached_block(s, index->name, index_start, ++ index_offset, index->size + 1, ++ &index_start, &index_offset); ++ ++ index->name[index->size + 1] = '\0'; ++ ++ if (strcmp(index->name, str) > 0) ++ break; ++ ++ length = index->index; ++ *next_block = index->start_block + sblk->directory_table_start; ++ } ++ ++ *next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE; ++ kfree(str); ++failure: ++ return length + 3; ++} ++ ++ ++static int squashfs_readdir(struct file *file, void *dirent, filldir_t filldir) ++{ ++ struct inode *i = file->f_dentry->d_inode; ++ struct squashfs_sb_info *msblk = i->i_sb->s_fs_info; ++ struct squashfs_super_block *sblk = &msblk->sblk; ++ long long next_block = SQUASHFS_I(i)->start_block + ++ sblk->directory_table_start; ++ int next_offset = SQUASHFS_I(i)->offset, length = 0, ++ dir_count; ++ struct squashfs_dir_header dirh; ++ struct squashfs_dir_entry *dire; ++ ++ TRACE("Entered squashfs_readdir [%llx:%x]\n", next_block, next_offset); ++ ++ if (!(dire = kmalloc(sizeof(struct squashfs_dir_entry) + ++ SQUASHFS_NAME_LEN + 1, GFP_KERNEL))) { ++ ERROR("Failed to allocate squashfs_dir_entry\n"); ++ goto finish; ++ } ++ ++ while(file->f_pos < 3) { ++ char *name; ++ int size, i_ino; ++ ++ if(file->f_pos == 0) { ++ name = "."; ++ size = 1; ++ i_ino = i->i_ino; ++ } else { ++ name = ".."; ++ size = 2; ++ i_ino = SQUASHFS_I(i)->u.s2.parent_inode; ++ } ++ TRACE("Calling filldir(%x, %s, %d, %d, %d, %d)\n", ++ (unsigned int) dirent, name, size, (int) ++ file->f_pos, i_ino, ++ squashfs_filetype_table[1]); ++ ++ if (filldir(dirent, name, size, ++ file->f_pos, i_ino, ++ squashfs_filetype_table[1]) < 0) { ++ TRACE("Filldir returned less than 0\n"); ++ goto finish; ++ } ++ file->f_pos += size; ++ } ++ ++ length = get_dir_index_using_offset(i->i_sb, &next_block, &next_offset, ++ SQUASHFS_I(i)->u.s2.directory_index_start, ++ SQUASHFS_I(i)->u.s2.directory_index_offset, ++ SQUASHFS_I(i)->u.s2.directory_index_count, ++ file->f_pos); ++ ++ while (length < i_size_read(i)) { ++ /* read directory header */ ++ if (msblk->swap) { ++ struct squashfs_dir_header sdirh; ++ ++ if (!squashfs_get_cached_block(i->i_sb, (char *) &sdirh, ++ next_block, next_offset, sizeof(sdirh), ++ &next_block, &next_offset)) ++ goto failed_read; ++ ++ length += sizeof(sdirh); ++ SQUASHFS_SWAP_DIR_HEADER(&dirh, &sdirh); ++ } else { ++ if (!squashfs_get_cached_block(i->i_sb, (char *) &dirh, ++ next_block, next_offset, sizeof(dirh), ++ &next_block, &next_offset)) ++ goto failed_read; ++ ++ length += sizeof(dirh); ++ } ++ ++ dir_count = dirh.count + 1; ++ while (dir_count--) { ++ if (msblk->swap) { ++ struct squashfs_dir_entry sdire; ++ if (!squashfs_get_cached_block(i->i_sb, (char *) ++ &sdire, next_block, next_offset, ++ sizeof(sdire), &next_block, ++ &next_offset)) ++ goto failed_read; ++ ++ length += sizeof(sdire); ++ SQUASHFS_SWAP_DIR_ENTRY(dire, &sdire); ++ } else { ++ if (!squashfs_get_cached_block(i->i_sb, (char *) ++ dire, next_block, next_offset, ++ sizeof(*dire), &next_block, ++ &next_offset)) ++ goto failed_read; ++ ++ length += sizeof(*dire); ++ } ++ ++ if (!squashfs_get_cached_block(i->i_sb, dire->name, ++ next_block, next_offset, ++ dire->size + 1, &next_block, ++ &next_offset)) ++ goto failed_read; ++ ++ length += dire->size + 1; ++ ++ if (file->f_pos >= length) ++ continue; ++ ++ dire->name[dire->size + 1] = '\0'; ++ ++ TRACE("Calling filldir(%x, %s, %d, %d, %x:%x, %d, %d)\n", ++ (unsigned int) dirent, dire->name, ++ dire->size + 1, (int) file->f_pos, ++ dirh.start_block, dire->offset, ++ dirh.inode_number + dire->inode_number, ++ squashfs_filetype_table[dire->type]); ++ ++ if (filldir(dirent, dire->name, dire->size + 1, ++ file->f_pos, ++ dirh.inode_number + dire->inode_number, ++ squashfs_filetype_table[dire->type]) ++ < 0) { ++ TRACE("Filldir returned less than 0\n"); ++ goto finish; ++ } ++ file->f_pos = length; ++ } ++ } ++ ++finish: ++ kfree(dire); ++ return 0; ++ ++failed_read: ++ ERROR("Unable to read directory block [%llx:%x]\n", next_block, ++ next_offset); ++ kfree(dire); ++ return 0; ++} ++ ++ ++static struct dentry *squashfs_lookup(struct inode *i, struct dentry *dentry, ++ struct nameidata *nd) ++{ ++ const unsigned char *name = dentry->d_name.name; ++ int len = dentry->d_name.len; ++ struct inode *inode = NULL; ++ struct squashfs_sb_info *msblk = i->i_sb->s_fs_info; ++ struct squashfs_super_block *sblk = &msblk->sblk; ++ long long next_block = SQUASHFS_I(i)->start_block + ++ sblk->directory_table_start; ++ int next_offset = SQUASHFS_I(i)->offset, length = 0, ++ dir_count; ++ struct squashfs_dir_header dirh; ++ struct squashfs_dir_entry *dire; ++ ++ TRACE("Entered squashfs_lookup [%llx:%x]\n", next_block, next_offset); ++ ++ if (!(dire = kmalloc(sizeof(struct squashfs_dir_entry) + ++ SQUASHFS_NAME_LEN + 1, GFP_KERNEL))) { ++ ERROR("Failed to allocate squashfs_dir_entry\n"); ++ goto exit_lookup; ++ } ++ ++ if (len > SQUASHFS_NAME_LEN) ++ goto exit_lookup; ++ ++ length = get_dir_index_using_name(i->i_sb, &next_block, &next_offset, ++ SQUASHFS_I(i)->u.s2.directory_index_start, ++ SQUASHFS_I(i)->u.s2.directory_index_offset, ++ SQUASHFS_I(i)->u.s2.directory_index_count, name, ++ len); ++ ++ while (length < i_size_read(i)) { ++ /* read directory header */ ++ if (msblk->swap) { ++ struct squashfs_dir_header sdirh; ++ if (!squashfs_get_cached_block(i->i_sb, (char *) &sdirh, ++ next_block, next_offset, sizeof(sdirh), ++ &next_block, &next_offset)) ++ goto failed_read; ++ ++ length += sizeof(sdirh); ++ SQUASHFS_SWAP_DIR_HEADER(&dirh, &sdirh); ++ } else { ++ if (!squashfs_get_cached_block(i->i_sb, (char *) &dirh, ++ next_block, next_offset, sizeof(dirh), ++ &next_block, &next_offset)) ++ goto failed_read; ++ ++ length += sizeof(dirh); ++ } ++ ++ dir_count = dirh.count + 1; ++ while (dir_count--) { ++ if (msblk->swap) { ++ struct squashfs_dir_entry sdire; ++ if (!squashfs_get_cached_block(i->i_sb, (char *) ++ &sdire, next_block,next_offset, ++ sizeof(sdire), &next_block, ++ &next_offset)) ++ goto failed_read; ++ ++ length += sizeof(sdire); ++ SQUASHFS_SWAP_DIR_ENTRY(dire, &sdire); ++ } else { ++ if (!squashfs_get_cached_block(i->i_sb, (char *) ++ dire, next_block,next_offset, ++ sizeof(*dire), &next_block, ++ &next_offset)) ++ goto failed_read; ++ ++ length += sizeof(*dire); ++ } ++ ++ if (!squashfs_get_cached_block(i->i_sb, dire->name, ++ next_block, next_offset, dire->size + 1, ++ &next_block, &next_offset)) ++ goto failed_read; ++ ++ length += dire->size + 1; ++ ++ if (name[0] < dire->name[0]) ++ goto exit_lookup; ++ ++ if ((len == dire->size + 1) && !strncmp(name, dire->name, len)) { ++ squashfs_inode_t ino = SQUASHFS_MKINODE(dirh.start_block, ++ dire->offset); ++ ++ TRACE("calling squashfs_iget for directory " ++ "entry %s, inode %x:%x, %d\n", name, ++ dirh.start_block, dire->offset, ++ dirh.inode_number + dire->inode_number); ++ ++ inode = squashfs_iget(i->i_sb, ino, dirh.inode_number + dire->inode_number); ++ ++ goto exit_lookup; ++ } ++ } ++ } ++ ++exit_lookup: ++ kfree(dire); ++ if (inode) ++ return d_splice_alias(inode, dentry); ++ d_add(dentry, inode); ++ return ERR_PTR(0); ++ ++failed_read: ++ ERROR("Unable to read directory block [%llx:%x]\n", next_block, ++ next_offset); ++ goto exit_lookup; ++} ++ ++ ++static int squashfs_remount(struct super_block *s, int *flags, char *data) ++{ ++ *flags |= MS_RDONLY; ++ return 0; ++} ++ ++ ++static void squashfs_put_super(struct super_block *s) ++{ ++ int i; ++ ++ if (s->s_fs_info) { ++ struct squashfs_sb_info *sbi = s->s_fs_info; ++ if (sbi->block_cache) ++ for (i = 0; i < SQUASHFS_CACHED_BLKS; i++) ++ if (sbi->block_cache[i].block != ++ SQUASHFS_INVALID_BLK) ++ kfree(sbi->block_cache[i].data); ++ if (sbi->fragment) ++ for (i = 0; i < SQUASHFS_CACHED_FRAGMENTS; i++) ++ SQUASHFS_FREE(sbi->fragment[i].data); ++ kfree(sbi->fragment); ++ kfree(sbi->block_cache); ++ kfree(sbi->read_page); ++ kfree(sbi->uid); ++ kfree(sbi->fragment_index); ++ kfree(sbi->fragment_index_2); ++ kfree(sbi->meta_index); ++ vfree(sbi->stream.workspace); ++ kfree(s->s_fs_info); ++ s->s_fs_info = NULL; ++ } ++} ++ ++ ++static int squashfs_get_sb(struct file_system_type *fs_type, int flags, ++ const char *dev_name, void *data, ++ struct vfsmount *mnt) ++{ ++ return get_sb_bdev(fs_type, flags, dev_name, data, squashfs_fill_super, ++ mnt); ++} ++ ++ ++static int __init init_squashfs_fs(void) ++{ ++ int err = init_inodecache(); ++ if (err) ++ goto out; ++ ++ printk(KERN_INFO "squashfs: version 3.2-r2 (2007/01/15) " ++ "Phillip Lougher\n"); ++ ++ if ((err = register_filesystem(&squashfs_fs_type))) ++ destroy_inodecache(); ++ ++out: ++ return err; ++} ++ ++ ++static void __exit exit_squashfs_fs(void) ++{ ++ unregister_filesystem(&squashfs_fs_type); ++ destroy_inodecache(); ++} ++ ++ ++static struct kmem_cache * squashfs_inode_cachep; ++ ++ ++static struct inode *squashfs_alloc_inode(struct super_block *sb) ++{ ++ struct squashfs_inode_info *ei; ++ ei = kmem_cache_alloc(squashfs_inode_cachep, GFP_KERNEL); ++ if (!ei) ++ return NULL; ++ return &ei->vfs_inode; ++} ++ ++ ++static void squashfs_destroy_inode(struct inode *inode) ++{ ++ kmem_cache_free(squashfs_inode_cachep, SQUASHFS_I(inode)); ++} ++ ++ ++static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) ++{ ++ struct squashfs_inode_info *ei = foo; ++ ++ inode_init_once(&ei->vfs_inode); ++} ++ ++ ++static int __init init_inodecache(void) ++{ ++ squashfs_inode_cachep = kmem_cache_create("squashfs_inode_cache", ++ sizeof(struct squashfs_inode_info), ++ 0, SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT, ++ init_once); ++ if (squashfs_inode_cachep == NULL) ++ return -ENOMEM; ++ return 0; ++} ++ ++ ++static void destroy_inodecache(void) ++{ ++ kmem_cache_destroy(squashfs_inode_cachep); ++} ++ ++ ++module_init(init_squashfs_fs); ++module_exit(exit_squashfs_fs); ++MODULE_DESCRIPTION("squashfs 3.2-r2, a compressed read-only filesystem"); ++MODULE_AUTHOR("Phillip Lougher <phillip@lougher.org.uk>"); ++MODULE_LICENSE("GPL"); +Index: linux-2.6.22/fs/squashfs/Makefile +=================================================================== +--- /dev/null ++++ linux-2.6.22/fs/squashfs/Makefile +@@ -0,0 +1,7 @@ ++# ++# Makefile for the linux squashfs routines. ++# ++ ++obj-$(CONFIG_SQUASHFS) += squashfs.o ++squashfs-y += inode.o ++squashfs-y += squashfs2_0.o +Index: linux-2.6.22/fs/squashfs/squashfs2_0.c +=================================================================== +--- /dev/null ++++ linux-2.6.22/fs/squashfs/squashfs2_0.c +@@ -0,0 +1,742 @@ ++/* ++ * Squashfs - a compressed read only filesystem for Linux ++ * ++ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007 ++ * Phillip Lougher <phillip@lougher.org.uk> ++ * ++ * 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, ++ * 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ * ++ * squashfs2_0.c ++ */ ++ ++#include <linux/squashfs_fs.h> ++#include <linux/module.h> ++#include <linux/zlib.h> ++#include <linux/fs.h> ++#include <linux/squashfs_fs_sb.h> ++#include <linux/squashfs_fs_i.h> ++ ++#include "squashfs.h" ++static int squashfs_readdir_2(struct file *file, void *dirent, filldir_t filldir); ++static struct dentry *squashfs_lookup_2(struct inode *, struct dentry *, ++ struct nameidata *); ++ ++static struct file_operations squashfs_dir_ops_2 = { ++ .read = generic_read_dir, ++ .readdir = squashfs_readdir_2 ++}; ++ ++static struct inode_operations squashfs_dir_inode_ops_2 = { ++ .lookup = squashfs_lookup_2 ++}; ++ ++static unsigned char squashfs_filetype_table[] = { ++ DT_UNKNOWN, DT_DIR, DT_REG, DT_LNK, DT_BLK, DT_CHR, DT_FIFO, DT_SOCK ++}; ++ ++static int read_fragment_index_table_2(struct super_block *s) ++{ ++ struct squashfs_sb_info *msblk = s->s_fs_info; ++ struct squashfs_super_block *sblk = &msblk->sblk; ++ ++ if (!(msblk->fragment_index_2 = kmalloc(SQUASHFS_FRAGMENT_INDEX_BYTES_2 ++ (sblk->fragments), GFP_KERNEL))) { ++ ERROR("Failed to allocate uid/gid table\n"); ++ return 0; ++ } ++ ++ if (SQUASHFS_FRAGMENT_INDEX_BYTES_2(sblk->fragments) && ++ !squashfs_read_data(s, (char *) ++ msblk->fragment_index_2, ++ sblk->fragment_table_start, ++ SQUASHFS_FRAGMENT_INDEX_BYTES_2 ++ (sblk->fragments) | ++ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, SQUASHFS_FRAGMENT_INDEX_BYTES_2(sblk->fragments))) { ++ ERROR("unable to read fragment index table\n"); ++ return 0; ++ } ++ ++ if (msblk->swap) { ++ int i; ++ unsigned int fragment; ++ ++ for (i = 0; i < SQUASHFS_FRAGMENT_INDEXES_2(sblk->fragments); ++ i++) { ++ SQUASHFS_SWAP_FRAGMENT_INDEXES_2((&fragment), ++ &msblk->fragment_index_2[i], 1); ++ msblk->fragment_index_2[i] = fragment; ++ } ++ } ++ ++ return 1; ++} ++ ++ ++static int get_fragment_location_2(struct super_block *s, unsigned int fragment, ++ long long *fragment_start_block, ++ unsigned int *fragment_size) ++{ ++ struct squashfs_sb_info *msblk = s->s_fs_info; ++ long long start_block = ++ msblk->fragment_index_2[SQUASHFS_FRAGMENT_INDEX_2(fragment)]; ++ int offset = SQUASHFS_FRAGMENT_INDEX_OFFSET_2(fragment); ++ struct squashfs_fragment_entry_2 fragment_entry; ++ ++ if (msblk->swap) { ++ struct squashfs_fragment_entry_2 sfragment_entry; ++ ++ if (!squashfs_get_cached_block(s, (char *) &sfragment_entry, ++ start_block, offset, ++ sizeof(sfragment_entry), &start_block, ++ &offset)) ++ goto out; ++ SQUASHFS_SWAP_FRAGMENT_ENTRY_2(&fragment_entry, &sfragment_entry); ++ } else ++ if (!squashfs_get_cached_block(s, (char *) &fragment_entry, ++ start_block, offset, ++ sizeof(fragment_entry), &start_block, ++ &offset)) ++ goto out; ++ ++ *fragment_start_block = fragment_entry.start_block; ++ *fragment_size = fragment_entry.size; ++ ++ return 1; ++ ++out: ++ return 0; ++} ++ ++ ++static void squashfs_new_inode(struct squashfs_sb_info *msblk, struct inode *i, ++ struct squashfs_base_inode_header_2 *inodeb, unsigned int ino) ++{ ++ struct squashfs_super_block *sblk = &msblk->sblk; ++ ++ i->i_ino = ino; ++ i->i_mtime.tv_sec = sblk->mkfs_time; ++ i->i_atime.tv_sec = sblk->mkfs_time; ++ i->i_ctime.tv_sec = sblk->mkfs_time; ++ i->i_uid = msblk->uid[inodeb->uid]; ++ i->i_mode = inodeb->mode; ++ i->i_nlink = 1; ++ i->i_size = 0; ++ if (inodeb->guid == SQUASHFS_GUIDS) ++ i->i_gid = i->i_uid; ++ else ++ i->i_gid = msblk->guid[inodeb->guid]; ++} ++ ++ ++static int squashfs_read_inode_2(struct inode *i, squashfs_inode_t inode) ++{ ++ struct super_block *s = i->i_sb; ++ struct squashfs_sb_info *msblk = s->s_fs_info; ++ struct squashfs_super_block *sblk = &msblk->sblk; ++ unsigned int block = SQUASHFS_INODE_BLK(inode) + ++ sblk->inode_table_start; ++ unsigned int offset = SQUASHFS_INODE_OFFSET(inode); ++ unsigned int ino = i->i_ino; ++ long long next_block; ++ unsigned int next_offset; ++ union squashfs_inode_header_2 id, sid; ++ struct squashfs_base_inode_header_2 *inodeb = &id.base, ++ *sinodeb = &sid.base; ++ ++ TRACE("Entered squashfs_iget\n"); ++ ++ if (msblk->swap) { ++ if (!squashfs_get_cached_block(s, (char *) sinodeb, block, ++ offset, sizeof(*sinodeb), &next_block, ++ &next_offset)) ++ goto failed_read; ++ SQUASHFS_SWAP_BASE_INODE_HEADER_2(inodeb, sinodeb, ++ sizeof(*sinodeb)); ++ } else ++ if (!squashfs_get_cached_block(s, (char *) inodeb, block, ++ offset, sizeof(*inodeb), &next_block, ++ &next_offset)) ++ goto failed_read; ++ ++ squashfs_new_inode(msblk, i, inodeb, ino); ++ ++ switch(inodeb->inode_type) { ++ case SQUASHFS_FILE_TYPE: { ++ struct squashfs_reg_inode_header_2 *inodep = &id.reg; ++ struct squashfs_reg_inode_header_2 *sinodep = &sid.reg; ++ long long frag_blk; ++ unsigned int frag_size = 0; ++ ++ if (msblk->swap) { ++ if (!squashfs_get_cached_block(s, (char *) ++ sinodep, block, offset, ++ sizeof(*sinodep), &next_block, ++ &next_offset)) ++ goto failed_read; ++ SQUASHFS_SWAP_REG_INODE_HEADER_2(inodep, sinodep); ++ } else ++ if (!squashfs_get_cached_block(s, (char *) ++ inodep, block, offset, ++ sizeof(*inodep), &next_block, ++ &next_offset)) ++ goto failed_read; ++ ++ frag_blk = SQUASHFS_INVALID_BLK; ++ if (inodep->fragment != SQUASHFS_INVALID_FRAG && ++ !get_fragment_location_2(s, ++ inodep->fragment, &frag_blk, &frag_size)) ++ goto failed_read; ++ ++ i->i_size = inodep->file_size; ++ i->i_fop = &generic_ro_fops; ++ i->i_mode |= S_IFREG; ++ i->i_mtime.tv_sec = inodep->mtime; ++ i->i_atime.tv_sec = inodep->mtime; ++ i->i_ctime.tv_sec = inodep->mtime; ++ i->i_blocks = ((i->i_size - 1) >> 9) + 1; ++ SQUASHFS_I(i)->u.s1.fragment_start_block = frag_blk; ++ SQUASHFS_I(i)->u.s1.fragment_size = frag_size; ++ SQUASHFS_I(i)->u.s1.fragment_offset = inodep->offset; ++ SQUASHFS_I(i)->start_block = inodep->start_block; ++ SQUASHFS_I(i)->u.s1.block_list_start = next_block; ++ SQUASHFS_I(i)->offset = next_offset; ++ if (sblk->block_size > 4096) ++ i->i_data.a_ops = &squashfs_aops; ++ else ++ i->i_data.a_ops = &squashfs_aops_4K; ++ ++ TRACE("File inode %x:%x, start_block %x, " ++ "block_list_start %llx, offset %x\n", ++ SQUASHFS_INODE_BLK(inode), offset, ++ inodep->start_block, next_block, ++ next_offset); ++ break; ++ } ++ case SQUASHFS_DIR_TYPE: { ++ struct squashfs_dir_inode_header_2 *inodep = &id.dir; ++ struct squashfs_dir_inode_header_2 *sinodep = &sid.dir; ++ ++ if (msblk->swap) { ++ if (!squashfs_get_cached_block(s, (char *) ++ sinodep, block, offset, ++ sizeof(*sinodep), &next_block, ++ &next_offset)) ++ goto failed_read; ++ SQUASHFS_SWAP_DIR_INODE_HEADER_2(inodep, sinodep); ++ } else ++ if (!squashfs_get_cached_block(s, (char *) ++ inodep, block, offset, ++ sizeof(*inodep), &next_block, ++ &next_offset)) ++ goto failed_read; ++ ++ i->i_size = inodep->file_size; ++ i->i_op = &squashfs_dir_inode_ops_2; ++ i->i_fop = &squashfs_dir_ops_2; ++ i->i_mode |= S_IFDIR; ++ i->i_mtime.tv_sec = inodep->mtime; ++ i->i_atime.tv_sec = inodep->mtime; ++ i->i_ctime.tv_sec = inodep->mtime; ++ SQUASHFS_I(i)->start_block = inodep->start_block; ++ SQUASHFS_I(i)->offset = inodep->offset; ++ SQUASHFS_I(i)->u.s2.directory_index_count = 0; ++ SQUASHFS_I(i)->u.s2.parent_inode = 0; ++ ++ TRACE("Directory inode %x:%x, start_block %x, offset " ++ "%x\n", SQUASHFS_INODE_BLK(inode), ++ offset, inodep->start_block, ++ inodep->offset); ++ break; ++ } ++ case SQUASHFS_LDIR_TYPE: { ++ struct squashfs_ldir_inode_header_2 *inodep = &id.ldir; ++ struct squashfs_ldir_inode_header_2 *sinodep = &sid.ldir; ++ ++ if (msblk->swap) { ++ if (!squashfs_get_cached_block(s, (char *) ++ sinodep, block, offset, ++ sizeof(*sinodep), &next_block, ++ &next_offset)) ++ goto failed_read; ++ SQUASHFS_SWAP_LDIR_INODE_HEADER_2(inodep, ++ sinodep); ++ } else ++ if (!squashfs_get_cached_block(s, (char *) ++ inodep, block, offset, ++ sizeof(*inodep), &next_block, ++ &next_offset)) ++ goto failed_read; ++ ++ i->i_size = inodep->file_size; ++ i->i_op = &squashfs_dir_inode_ops_2; ++ i->i_fop = &squashfs_dir_ops_2; ++ i->i_mode |= S_IFDIR; ++ i->i_mtime.tv_sec = inodep->mtime; ++ i->i_atime.tv_sec = inodep->mtime; ++ i->i_ctime.tv_sec = inodep->mtime; ++ SQUASHFS_I(i)->start_block = inodep->start_block; ++ SQUASHFS_I(i)->offset = inodep->offset; ++ SQUASHFS_I(i)->u.s2.directory_index_start = next_block; ++ SQUASHFS_I(i)->u.s2.directory_index_offset = ++ next_offset; ++ SQUASHFS_I(i)->u.s2.directory_index_count = ++ inodep->i_count; ++ SQUASHFS_I(i)->u.s2.parent_inode = 0; ++ ++ TRACE("Long directory inode %x:%x, start_block %x, " ++ "offset %x\n", ++ SQUASHFS_INODE_BLK(inode), offset, ++ inodep->start_block, inodep->offset); ++ break; ++ } ++ case SQUASHFS_SYMLINK_TYPE: { ++ struct squashfs_symlink_inode_header_2 *inodep = ++ &id.symlink; ++ struct squashfs_symlink_inode_header_2 *sinodep = ++ &sid.symlink; ++ ++ if (msblk->swap) { ++ if (!squashfs_get_cached_block(s, (char *) ++ sinodep, block, offset, ++ sizeof(*sinodep), &next_block, ++ &next_offset)) ++ goto failed_read; ++ SQUASHFS_SWAP_SYMLINK_INODE_HEADER_2(inodep, ++ sinodep); ++ } else ++ if (!squashfs_get_cached_block(s, (char *) ++ inodep, block, offset, ++ sizeof(*inodep), &next_block, ++ &next_offset)) ++ goto failed_read; ++ ++ i->i_size = inodep->symlink_size; ++ i->i_op = &page_symlink_inode_operations; ++ i->i_data.a_ops = &squashfs_symlink_aops; ++ i->i_mode |= S_IFLNK; ++ SQUASHFS_I(i)->start_block = next_block; ++ SQUASHFS_I(i)->offset = next_offset; ++ ++ TRACE("Symbolic link inode %x:%x, start_block %llx, " ++ "offset %x\n", ++ SQUASHFS_INODE_BLK(inode), offset, ++ next_block, next_offset); ++ break; ++ } ++ case SQUASHFS_BLKDEV_TYPE: ++ case SQUASHFS_CHRDEV_TYPE: { ++ struct squashfs_dev_inode_header_2 *inodep = &id.dev; ++ struct squashfs_dev_inode_header_2 *sinodep = &sid.dev; ++ ++ if (msblk->swap) { ++ if (!squashfs_get_cached_block(s, (char *) ++ sinodep, block, offset, ++ sizeof(*sinodep), &next_block, ++ &next_offset)) ++ goto failed_read; ++ SQUASHFS_SWAP_DEV_INODE_HEADER_2(inodep, sinodep); ++ } else ++ if (!squashfs_get_cached_block(s, (char *) ++ inodep, block, offset, ++ sizeof(*inodep), &next_block, ++ &next_offset)) ++ goto failed_read; ++ ++ i->i_mode |= (inodeb->inode_type == ++ SQUASHFS_CHRDEV_TYPE) ? S_IFCHR : ++ S_IFBLK; ++ init_special_inode(i, i->i_mode, ++ old_decode_dev(inodep->rdev)); ++ ++ TRACE("Device inode %x:%x, rdev %x\n", ++ SQUASHFS_INODE_BLK(inode), offset, ++ inodep->rdev); ++ break; ++ } ++ case SQUASHFS_FIFO_TYPE: ++ case SQUASHFS_SOCKET_TYPE: { ++ ++ i->i_mode |= (inodeb->inode_type == SQUASHFS_FIFO_TYPE) ++ ? S_IFIFO : S_IFSOCK; ++ init_special_inode(i, i->i_mode, 0); ++ break; ++ } ++ default: ++ ERROR("Unknown inode type %d in squashfs_iget!\n", ++ inodeb->inode_type); ++ goto failed_read1; ++ } ++ ++ return 1; ++ ++failed_read: ++ ERROR("Unable to read inode [%x:%x]\n", block, offset); ++ ++failed_read1: ++ return 0; ++} ++ ++ ++static int get_dir_index_using_offset(struct super_block *s, long long ++ *next_block, unsigned int *next_offset, ++ long long index_start, ++ unsigned int index_offset, int i_count, ++ long long f_pos) ++{ ++ struct squashfs_sb_info *msblk = s->s_fs_info; ++ struct squashfs_super_block *sblk = &msblk->sblk; ++ int i, length = 0; ++ struct squashfs_dir_index_2 index; ++ ++ TRACE("Entered get_dir_index_using_offset, i_count %d, f_pos %d\n", ++ i_count, (unsigned int) f_pos); ++ ++ if (f_pos == 0) ++ goto finish; ++ ++ for (i = 0; i < i_count; i++) { ++ if (msblk->swap) { ++ struct squashfs_dir_index_2 sindex; ++ squashfs_get_cached_block(s, (char *) &sindex, ++ index_start, index_offset, ++ sizeof(sindex), &index_start, ++ &index_offset); ++ SQUASHFS_SWAP_DIR_INDEX_2(&index, &sindex); ++ } else ++ squashfs_get_cached_block(s, (char *) &index, ++ index_start, index_offset, ++ sizeof(index), &index_start, ++ &index_offset); ++ ++ if (index.index > f_pos) ++ break; ++ ++ squashfs_get_cached_block(s, NULL, index_start, index_offset, ++ index.size + 1, &index_start, ++ &index_offset); ++ ++ length = index.index; ++ *next_block = index.start_block + sblk->directory_table_start; ++ } ++ ++ *next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE; ++ ++finish: ++ return length; ++} ++ ++ ++static int get_dir_index_using_name(struct super_block *s, long long ++ *next_block, unsigned int *next_offset, ++ long long index_start, ++ unsigned int index_offset, int i_count, ++ const char *name, int size) ++{ ++ struct squashfs_sb_info *msblk = s->s_fs_info; ++ struct squashfs_super_block *sblk = &msblk->sblk; ++ int i, length = 0; ++ struct squashfs_dir_index_2 *index; ++ char *str; ++ ++ TRACE("Entered get_dir_index_using_name, i_count %d\n", i_count); ++ ++ if (!(str = kmalloc(sizeof(struct squashfs_dir_index) + ++ (SQUASHFS_NAME_LEN + 1) * 2, GFP_KERNEL))) { ++ ERROR("Failed to allocate squashfs_dir_index\n"); ++ goto failure; ++ } ++ ++ index = (struct squashfs_dir_index_2 *) (str + SQUASHFS_NAME_LEN + 1); ++ strncpy(str, name, size); ++ str[size] = '\0'; ++ ++ for (i = 0; i < i_count; i++) { ++ if (msblk->swap) { ++ struct squashfs_dir_index_2 sindex; ++ squashfs_get_cached_block(s, (char *) &sindex, ++ index_start, index_offset, ++ sizeof(sindex), &index_start, ++ &index_offset); ++ SQUASHFS_SWAP_DIR_INDEX_2(index, &sindex); ++ } else ++ squashfs_get_cached_block(s, (char *) index, ++ index_start, index_offset, ++ sizeof(struct squashfs_dir_index_2), ++ &index_start, &index_offset); ++ ++ squashfs_get_cached_block(s, index->name, index_start, ++ index_offset, index->size + 1, ++ &index_start, &index_offset); ++ ++ index->name[index->size + 1] = '\0'; ++ ++ if (strcmp(index->name, str) > 0) ++ break; ++ ++ length = index->index; ++ *next_block = index->start_block + sblk->directory_table_start; ++ } ++ ++ *next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE; ++ kfree(str); ++failure: ++ return length; ++} ++ ++ ++static int squashfs_readdir_2(struct file *file, void *dirent, filldir_t filldir) ++{ ++ struct inode *i = file->f_dentry->d_inode; ++ struct squashfs_sb_info *msblk = i->i_sb->s_fs_info; ++ struct squashfs_super_block *sblk = &msblk->sblk; ++ long long next_block = SQUASHFS_I(i)->start_block + ++ sblk->directory_table_start; ++ int next_offset = SQUASHFS_I(i)->offset, length = 0, ++ dir_count; ++ struct squashfs_dir_header_2 dirh; ++ struct squashfs_dir_entry_2 *dire; ++ ++ TRACE("Entered squashfs_readdir_2 [%llx:%x]\n", next_block, next_offset); ++ ++ if (!(dire = kmalloc(sizeof(struct squashfs_dir_entry) + ++ SQUASHFS_NAME_LEN + 1, GFP_KERNEL))) { ++ ERROR("Failed to allocate squashfs_dir_entry\n"); ++ goto finish; ++ } ++ ++ length = get_dir_index_using_offset(i->i_sb, &next_block, &next_offset, ++ SQUASHFS_I(i)->u.s2.directory_index_start, ++ SQUASHFS_I(i)->u.s2.directory_index_offset, ++ SQUASHFS_I(i)->u.s2.directory_index_count, ++ file->f_pos); ++ ++ while (length < i_size_read(i)) { ++ /* read directory header */ ++ if (msblk->swap) { ++ struct squashfs_dir_header_2 sdirh; ++ ++ if (!squashfs_get_cached_block(i->i_sb, (char *) &sdirh, ++ next_block, next_offset, sizeof(sdirh), ++ &next_block, &next_offset)) ++ goto failed_read; ++ ++ length += sizeof(sdirh); ++ SQUASHFS_SWAP_DIR_HEADER_2(&dirh, &sdirh); ++ } else { ++ if (!squashfs_get_cached_block(i->i_sb, (char *) &dirh, ++ next_block, next_offset, sizeof(dirh), ++ &next_block, &next_offset)) ++ goto failed_read; ++ ++ length += sizeof(dirh); ++ } ++ ++ dir_count = dirh.count + 1; ++ while (dir_count--) { ++ if (msblk->swap) { ++ struct squashfs_dir_entry_2 sdire; ++ if (!squashfs_get_cached_block(i->i_sb, (char *) ++ &sdire, next_block, next_offset, ++ sizeof(sdire), &next_block, ++ &next_offset)) ++ goto failed_read; ++ ++ length += sizeof(sdire); ++ SQUASHFS_SWAP_DIR_ENTRY_2(dire, &sdire); ++ } else { ++ if (!squashfs_get_cached_block(i->i_sb, (char *) ++ dire, next_block, next_offset, ++ sizeof(*dire), &next_block, ++ &next_offset)) ++ goto failed_read; ++ ++ length += sizeof(*dire); ++ } ++ ++ if (!squashfs_get_cached_block(i->i_sb, dire->name, ++ next_block, next_offset, ++ dire->size + 1, &next_block, ++ &next_offset)) ++ goto failed_read; ++ ++ length += dire->size + 1; ++ ++ if (file->f_pos >= length) ++ continue; ++ ++ dire->name[dire->size + 1] = '\0'; ++ ++ TRACE("Calling filldir(%x, %s, %d, %d, %x:%x, %d)\n", ++ (unsigned int) dirent, dire->name, ++ dire->size + 1, (int) file->f_pos, ++ dirh.start_block, dire->offset, ++ squashfs_filetype_table[dire->type]); ++ ++ if (filldir(dirent, dire->name, dire->size + 1, ++ file->f_pos, SQUASHFS_MK_VFS_INODE( ++ dirh.start_block, dire->offset), ++ squashfs_filetype_table[dire->type]) ++ < 0) { ++ TRACE("Filldir returned less than 0\n"); ++ goto finish; ++ } ++ file->f_pos = length; ++ } ++ } ++ ++finish: ++ kfree(dire); ++ return 0; ++ ++failed_read: ++ ERROR("Unable to read directory block [%llx:%x]\n", next_block, ++ next_offset); ++ kfree(dire); ++ return 0; ++} ++ ++ ++static struct dentry *squashfs_lookup_2(struct inode *i, struct dentry *dentry, ++ struct nameidata *nd) ++{ ++ const unsigned char *name = dentry->d_name.name; ++ int len = dentry->d_name.len; ++ struct inode *inode = NULL; ++ struct squashfs_sb_info *msblk = i->i_sb->s_fs_info; ++ struct squashfs_super_block *sblk = &msblk->sblk; ++ long long next_block = SQUASHFS_I(i)->start_block + ++ sblk->directory_table_start; ++ int next_offset = SQUASHFS_I(i)->offset, length = 0, ++ dir_count; ++ struct squashfs_dir_header_2 dirh; ++ struct squashfs_dir_entry_2 *dire; ++ int sorted = sblk->s_major == 2 && sblk->s_minor >= 1; ++ ++ TRACE("Entered squashfs_lookup_2 [%llx:%x]\n", next_block, next_offset); ++ ++ if (!(dire = kmalloc(sizeof(struct squashfs_dir_entry) + ++ SQUASHFS_NAME_LEN + 1, GFP_KERNEL))) { ++ ERROR("Failed to allocate squashfs_dir_entry\n"); ++ goto exit_loop; ++ } ++ ++ if (len > SQUASHFS_NAME_LEN) ++ goto exit_loop; ++ ++ length = get_dir_index_using_name(i->i_sb, &next_block, &next_offset, ++ SQUASHFS_I(i)->u.s2.directory_index_start, ++ SQUASHFS_I(i)->u.s2.directory_index_offset, ++ SQUASHFS_I(i)->u.s2.directory_index_count, name, ++ len); ++ ++ while (length < i_size_read(i)) { ++ /* read directory header */ ++ if (msblk->swap) { ++ struct squashfs_dir_header_2 sdirh; ++ if (!squashfs_get_cached_block(i->i_sb, (char *) &sdirh, ++ next_block, next_offset, sizeof(sdirh), ++ &next_block, &next_offset)) ++ goto failed_read; ++ ++ length += sizeof(sdirh); ++ SQUASHFS_SWAP_DIR_HEADER_2(&dirh, &sdirh); ++ } else { ++ if (!squashfs_get_cached_block(i->i_sb, (char *) &dirh, ++ next_block, next_offset, sizeof(dirh), ++ &next_block, &next_offset)) ++ goto failed_read; ++ ++ length += sizeof(dirh); ++ } ++ ++ dir_count = dirh.count + 1; ++ while (dir_count--) { ++ if (msblk->swap) { ++ struct squashfs_dir_entry_2 sdire; ++ if (!squashfs_get_cached_block(i->i_sb, (char *) ++ &sdire, next_block,next_offset, ++ sizeof(sdire), &next_block, ++ &next_offset)) ++ goto failed_read; ++ ++ length += sizeof(sdire); ++ SQUASHFS_SWAP_DIR_ENTRY_2(dire, &sdire); ++ } else { ++ if (!squashfs_get_cached_block(i->i_sb, (char *) ++ dire, next_block,next_offset, ++ sizeof(*dire), &next_block, ++ &next_offset)) ++ goto failed_read; ++ ++ length += sizeof(*dire); ++ } ++ ++ if (!squashfs_get_cached_block(i->i_sb, dire->name, ++ next_block, next_offset, dire->size + 1, ++ &next_block, &next_offset)) ++ goto failed_read; ++ ++ length += dire->size + 1; ++ ++ if (sorted && name[0] < dire->name[0]) ++ goto exit_loop; ++ ++ if ((len == dire->size + 1) && !strncmp(name, ++ dire->name, len)) { ++ squashfs_inode_t ino = ++ SQUASHFS_MKINODE(dirh.start_block, ++ dire->offset); ++ unsigned int inode_number = SQUASHFS_MK_VFS_INODE(dirh.start_block, ++ dire->offset); ++ ++ TRACE("calling squashfs_iget for directory " ++ "entry %s, inode %x:%x, %lld\n", name, ++ dirh.start_block, dire->offset, ino); ++ ++ inode = squashfs_iget(i->i_sb, ino, inode_number); ++ ++ goto exit_loop; ++ } ++ } ++ } ++ ++exit_loop: ++ kfree(dire); ++ d_add(dentry, inode); ++ return ERR_PTR(0); ++ ++failed_read: ++ ERROR("Unable to read directory block [%llx:%x]\n", next_block, ++ next_offset); ++ goto exit_loop; ++} ++ ++ ++int squashfs_2_0_supported(struct squashfs_sb_info *msblk) ++{ ++ struct squashfs_super_block *sblk = &msblk->sblk; ++ ++ msblk->read_inode = squashfs_read_inode_2; ++ msblk->read_fragment_index_table = read_fragment_index_table_2; ++ ++ sblk->bytes_used = sblk->bytes_used_2; ++ sblk->uid_start = sblk->uid_start_2; ++ sblk->guid_start = sblk->guid_start_2; ++ sblk->inode_table_start = sblk->inode_table_start_2; ++ sblk->directory_table_start = sblk->directory_table_start_2; ++ sblk->fragment_table_start = sblk->fragment_table_start_2; ++ ++ return 1; ++} +Index: linux-2.6.22/fs/squashfs/squashfs.h +=================================================================== +--- /dev/null ++++ linux-2.6.22/fs/squashfs/squashfs.h +@@ -0,0 +1,87 @@ ++/* ++ * Squashfs - a compressed read only filesystem for Linux ++ * ++ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007 ++ * Phillip Lougher <phillip@lougher.org.uk> ++ * ++ * 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, ++ * 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ * ++ * squashfs.h ++ */ ++ ++#ifdef CONFIG_SQUASHFS_1_0_COMPATIBILITY ++#undef CONFIG_SQUASHFS_1_0_COMPATIBILITY ++#endif ++ ++#ifdef SQUASHFS_TRACE ++#define TRACE(s, args...) printk(KERN_NOTICE "SQUASHFS: "s, ## args) ++#else ++#define TRACE(s, args...) {} ++#endif ++ ++#define ERROR(s, args...) printk(KERN_ERR "SQUASHFS error: "s, ## args) ++ ++#define SERROR(s, args...) do { \ ++ if (!silent) \ ++ printk(KERN_ERR "SQUASHFS error: "s, ## args);\ ++ } while(0) ++ ++#define WARNING(s, args...) printk(KERN_WARNING "SQUASHFS: "s, ## args) ++ ++static inline struct squashfs_inode_info *SQUASHFS_I(struct inode *inode) ++{ ++ return list_entry(inode, struct squashfs_inode_info, vfs_inode); ++} ++ ++#if defined(CONFIG_SQUASHFS_1_0_COMPATIBILITY ) || defined(CONFIG_SQUASHFS_2_0_COMPATIBILITY) ++#define SQSH_EXTERN ++extern unsigned int squashfs_read_data(struct super_block *s, char *buffer, ++ long long index, unsigned int length, ++ long long *next_index, int srclength); ++extern int squashfs_get_cached_block(struct super_block *s, char *buffer, ++ long long block, unsigned int offset, ++ int length, long long *next_block, ++ unsigned int *next_offset); ++extern void release_cached_fragment(struct squashfs_sb_info *msblk, struct ++ squashfs_fragment_cache *fragment); ++extern struct squashfs_fragment_cache *get_cached_fragment(struct super_block ++ *s, long long start_block, ++ int length); ++extern struct inode *squashfs_iget(struct super_block *s, squashfs_inode_t inode, unsigned int inode_number); ++extern const struct address_space_operations squashfs_symlink_aops; ++extern const struct address_space_operations squashfs_aops; ++extern const struct address_space_operations squashfs_aops_4K; ++extern struct inode_operations squashfs_dir_inode_ops; ++#else ++#define SQSH_EXTERN static ++#endif ++ ++#ifdef CONFIG_SQUASHFS_1_0_COMPATIBILITY ++extern int squashfs_1_0_supported(struct squashfs_sb_info *msblk); ++#else ++static inline int squashfs_1_0_supported(struct squashfs_sb_info *msblk) ++{ ++ return 0; ++} ++#endif ++ ++#ifdef CONFIG_SQUASHFS_2_0_COMPATIBILITY ++extern int squashfs_2_0_supported(struct squashfs_sb_info *msblk); ++#else ++static inline int squashfs_2_0_supported(struct squashfs_sb_info *msblk) ++{ ++ return 0; ++} ++#endif +Index: linux-2.6.22/include/linux/squashfs_fs.h +=================================================================== +--- /dev/null ++++ linux-2.6.22/include/linux/squashfs_fs.h +@@ -0,0 +1,934 @@ ++#ifndef SQUASHFS_FS ++#define SQUASHFS_FS ++ ++/* ++ * Squashfs ++ * ++ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007 ++ * Phillip Lougher <phillip@lougher.org.uk> ++ * ++ * 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, ++ * 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ * ++ * squashfs_fs.h ++ */ ++ ++#ifndef CONFIG_SQUASHFS_2_0_COMPATIBILITY ++#define CONFIG_SQUASHFS_2_0_COMPATIBILITY ++#endif ++ ++#ifdef CONFIG_SQUASHFS_VMALLOC ++#define SQUASHFS_ALLOC(a) vmalloc(a) ++#define SQUASHFS_FREE(a) vfree(a) ++#else ++#define SQUASHFS_ALLOC(a) kmalloc(a, GFP_KERNEL) ++#define SQUASHFS_FREE(a) kfree(a) ++#endif ++#define SQUASHFS_CACHED_FRAGMENTS CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE ++#define SQUASHFS_MAJOR 3 ++#define SQUASHFS_MINOR 0 ++#define SQUASHFS_MAGIC 0x73717368 ++#define SQUASHFS_MAGIC_SWAP 0x68737173 ++#define SQUASHFS_START 0 ++ ++/* size of metadata (inode and directory) blocks */ ++#define SQUASHFS_METADATA_SIZE 8192 ++#define SQUASHFS_METADATA_LOG 13 ++ ++/* default size of data blocks */ ++#define SQUASHFS_FILE_SIZE 65536 ++#define SQUASHFS_FILE_LOG 16 ++ ++#define SQUASHFS_FILE_MAX_SIZE 65536 ++ ++/* Max number of uids and gids */ ++#define SQUASHFS_UIDS 256 ++#define SQUASHFS_GUIDS 255 ++ ++/* Max length of filename (not 255) */ ++#define SQUASHFS_NAME_LEN 256 ++ ++#define SQUASHFS_INVALID ((long long) 0xffffffffffff) ++#define SQUASHFS_INVALID_FRAG ((unsigned int) 0xffffffff) ++#define SQUASHFS_INVALID_BLK ((long long) -1) ++#define SQUASHFS_USED_BLK ((long long) -2) ++ ++/* Filesystem flags */ ++#define SQUASHFS_NOI 0 ++#define SQUASHFS_NOD 1 ++#define SQUASHFS_CHECK 2 ++#define SQUASHFS_NOF 3 ++#define SQUASHFS_NO_FRAG 4 ++#define SQUASHFS_ALWAYS_FRAG 5 ++#define SQUASHFS_DUPLICATE 6 ++#define SQUASHFS_EXPORT 7 ++ ++#define SQUASHFS_BIT(flag, bit) ((flag >> bit) & 1) ++ ++#define SQUASHFS_UNCOMPRESSED_INODES(flags) SQUASHFS_BIT(flags, \ ++ SQUASHFS_NOI) ++ ++#define SQUASHFS_UNCOMPRESSED_DATA(flags) SQUASHFS_BIT(flags, \ ++ SQUASHFS_NOD) ++ ++#define SQUASHFS_UNCOMPRESSED_FRAGMENTS(flags) SQUASHFS_BIT(flags, \ ++ SQUASHFS_NOF) ++ ++#define SQUASHFS_NO_FRAGMENTS(flags) SQUASHFS_BIT(flags, \ ++ SQUASHFS_NO_FRAG) ++ ++#define SQUASHFS_ALWAYS_FRAGMENTS(flags) SQUASHFS_BIT(flags, \ ++ SQUASHFS_ALWAYS_FRAG) ++ ++#define SQUASHFS_DUPLICATES(flags) SQUASHFS_BIT(flags, \ ++ SQUASHFS_DUPLICATE) ++ ++#define SQUASHFS_EXPORTABLE(flags) SQUASHFS_BIT(flags, \ ++ SQUASHFS_EXPORT) ++ ++#define SQUASHFS_CHECK_DATA(flags) SQUASHFS_BIT(flags, \ ++ SQUASHFS_CHECK) ++ ++#define SQUASHFS_MKFLAGS(noi, nod, check_data, nof, no_frag, always_frag, \ ++ duplicate_checking, exortable) (noi | (nod << 1) | (check_data << 2) \ ++ | (nof << 3) | (no_frag << 4) | (always_frag << 5) | \ ++ (duplicate_checking << 6) | (exportable << 7)) ++ ++/* Max number of types and file types */ ++#define SQUASHFS_DIR_TYPE 1 ++#define SQUASHFS_FILE_TYPE 2 ++#define SQUASHFS_SYMLINK_TYPE 3 ++#define SQUASHFS_BLKDEV_TYPE 4 ++#define SQUASHFS_CHRDEV_TYPE 5 ++#define SQUASHFS_FIFO_TYPE 6 ++#define SQUASHFS_SOCKET_TYPE 7 ++#define SQUASHFS_LDIR_TYPE 8 ++#define SQUASHFS_LREG_TYPE 9 ++ ++/* 1.0 filesystem type definitions */ ++#define SQUASHFS_TYPES 5 ++#define SQUASHFS_IPC_TYPE 0 ++ ++/* Flag whether block is compressed or uncompressed, bit is set if block is ++ * uncompressed */ ++#define SQUASHFS_COMPRESSED_BIT (1 << 15) ++ ++#define SQUASHFS_COMPRESSED_SIZE(B) (((B) & ~SQUASHFS_COMPRESSED_BIT) ? \ ++ (B) & ~SQUASHFS_COMPRESSED_BIT : SQUASHFS_COMPRESSED_BIT) ++ ++#define SQUASHFS_COMPRESSED(B) (!((B) & SQUASHFS_COMPRESSED_BIT)) ++ ++#define SQUASHFS_COMPRESSED_BIT_BLOCK (1 << 24) ++ ++#define SQUASHFS_COMPRESSED_SIZE_BLOCK(B) (((B) & \ ++ ~SQUASHFS_COMPRESSED_BIT_BLOCK) ? (B) & \ ++ ~SQUASHFS_COMPRESSED_BIT_BLOCK : SQUASHFS_COMPRESSED_BIT_BLOCK) ++ ++#define SQUASHFS_COMPRESSED_BLOCK(B) (!((B) & SQUASHFS_COMPRESSED_BIT_BLOCK)) ++ ++/* ++ * Inode number ops. Inodes consist of a compressed block number, and an ++ * uncompressed offset within that block ++ */ ++#define SQUASHFS_INODE_BLK(a) ((unsigned int) ((a) >> 16)) ++ ++#define SQUASHFS_INODE_OFFSET(a) ((unsigned int) ((a) & 0xffff)) ++ ++#define SQUASHFS_MKINODE(A, B) ((squashfs_inode_t)(((squashfs_inode_t) (A)\ ++ << 16) + (B))) ++ ++/* Compute 32 bit VFS inode number from squashfs inode number */ ++#define SQUASHFS_MK_VFS_INODE(a, b) ((unsigned int) (((a) << 8) + \ ++ ((b) >> 2) + 1)) ++/* XXX */ ++ ++/* Translate between VFS mode and squashfs mode */ ++#define SQUASHFS_MODE(a) ((a) & 0xfff) ++ ++/* fragment and fragment table defines */ ++#define SQUASHFS_FRAGMENT_BYTES(A) ((A) * sizeof(struct squashfs_fragment_entry)) ++ ++#define SQUASHFS_FRAGMENT_INDEX(A) (SQUASHFS_FRAGMENT_BYTES(A) / \ ++ SQUASHFS_METADATA_SIZE) ++ ++#define SQUASHFS_FRAGMENT_INDEX_OFFSET(A) (SQUASHFS_FRAGMENT_BYTES(A) % \ ++ SQUASHFS_METADATA_SIZE) ++ ++#define SQUASHFS_FRAGMENT_INDEXES(A) ((SQUASHFS_FRAGMENT_BYTES(A) + \ ++ SQUASHFS_METADATA_SIZE - 1) / \ ++ SQUASHFS_METADATA_SIZE) ++ ++#define SQUASHFS_FRAGMENT_INDEX_BYTES(A) (SQUASHFS_FRAGMENT_INDEXES(A) *\ ++ sizeof(long long)) ++ ++/* inode lookup table defines */ ++#define SQUASHFS_LOOKUP_BYTES(A) ((A) * sizeof(squashfs_inode_t)) ++ ++#define SQUASHFS_LOOKUP_BLOCK(A) (SQUASHFS_LOOKUP_BYTES(A) / \ ++ SQUASHFS_METADATA_SIZE) ++ ++#define SQUASHFS_LOOKUP_BLOCK_OFFSET(A) (SQUASHFS_LOOKUP_BYTES(A) % \ ++ SQUASHFS_METADATA_SIZE) ++ ++#define SQUASHFS_LOOKUP_BLOCKS(A) ((SQUASHFS_LOOKUP_BYTES(A) + \ ++ SQUASHFS_METADATA_SIZE - 1) / \ ++ SQUASHFS_METADATA_SIZE) ++ ++#define SQUASHFS_LOOKUP_BLOCK_BYTES(A) (SQUASHFS_LOOKUP_BLOCKS(A) *\ ++ sizeof(long long)) ++ ++/* cached data constants for filesystem */ ++#define SQUASHFS_CACHED_BLKS 8 ++ ++#define SQUASHFS_MAX_FILE_SIZE_LOG 64 ++ ++#define SQUASHFS_MAX_FILE_SIZE ((long long) 1 << \ ++ (SQUASHFS_MAX_FILE_SIZE_LOG - 2)) ++ ++#define SQUASHFS_MARKER_BYTE 0xff ++ ++/* meta index cache */ ++#define SQUASHFS_META_INDEXES (SQUASHFS_METADATA_SIZE / sizeof(unsigned int)) ++#define SQUASHFS_META_ENTRIES 31 ++#define SQUASHFS_META_NUMBER 8 ++#define SQUASHFS_SLOTS 4 ++ ++struct meta_entry { ++ long long data_block; ++ unsigned int index_block; ++ unsigned short offset; ++ unsigned short pad; ++}; ++ ++struct meta_index { ++ unsigned int inode_number; ++ unsigned int offset; ++ unsigned short entries; ++ unsigned short skip; ++ unsigned short locked; ++ unsigned short pad; ++ struct meta_entry meta_entry[SQUASHFS_META_ENTRIES]; ++}; ++ ++ ++/* ++ * definitions for structures on disk ++ */ ++ ++typedef long long squashfs_block_t; ++typedef long long squashfs_inode_t; ++ ++struct squashfs_super_block { ++ unsigned int s_magic; ++ unsigned int inodes; ++ unsigned int bytes_used_2; ++ unsigned int uid_start_2; ++ unsigned int guid_start_2; ++ unsigned int inode_table_start_2; ++ unsigned int directory_table_start_2; ++ unsigned int s_major:16; ++ unsigned int s_minor:16; ++ unsigned int block_size_1:16; ++ unsigned int block_log:16; ++ unsigned int flags:8; ++ unsigned int no_uids:8; ++ unsigned int no_guids:8; ++ unsigned int mkfs_time /* time of filesystem creation */; ++ squashfs_inode_t root_inode; ++ unsigned int block_size; ++ unsigned int fragments; ++ unsigned int fragment_table_start_2; ++ long long bytes_used; ++ long long uid_start; ++ long long guid_start; ++ long long inode_table_start; ++ long long directory_table_start; ++ long long fragment_table_start; ++ long long lookup_table_start; ++} __attribute__ ((packed)); ++ ++struct squashfs_dir_index { ++ unsigned int index; ++ unsigned int start_block; ++ unsigned char size; ++ unsigned char name[0]; ++} __attribute__ ((packed)); ++ ++#define SQUASHFS_BASE_INODE_HEADER \ ++ unsigned int inode_type:4; \ ++ unsigned int mode:12; \ ++ unsigned int uid:8; \ ++ unsigned int guid:8; \ ++ unsigned int mtime; \ ++ unsigned int inode_number; ++ ++struct squashfs_base_inode_header { ++ SQUASHFS_BASE_INODE_HEADER; ++} __attribute__ ((packed)); ++ ++struct squashfs_ipc_inode_header { ++ SQUASHFS_BASE_INODE_HEADER; ++ unsigned int nlink; ++} __attribute__ ((packed)); ++ ++struct squashfs_dev_inode_header { ++ SQUASHFS_BASE_INODE_HEADER; ++ unsigned int nlink; ++ unsigned short rdev; ++} __attribute__ ((packed)); ++ ++struct squashfs_symlink_inode_header { ++ SQUASHFS_BASE_INODE_HEADER; ++ unsigned int nlink; ++ unsigned short symlink_size; ++ char symlink[0]; ++} __attribute__ ((packed)); ++ ++struct squashfs_reg_inode_header { ++ SQUASHFS_BASE_INODE_HEADER; ++ squashfs_block_t start_block; ++ unsigned int fragment; ++ unsigned int offset; ++ unsigned int file_size; ++ unsigned short block_list[0]; ++} __attribute__ ((packed)); ++ ++struct squashfs_lreg_inode_header { ++ SQUASHFS_BASE_INODE_HEADER; ++ unsigned int nlink; ++ squashfs_block_t start_block; ++ unsigned int fragment; ++ unsigned int offset; ++ long long file_size; ++ unsigned short block_list[0]; ++} __attribute__ ((packed)); ++ ++struct squashfs_dir_inode_header { ++ SQUASHFS_BASE_INODE_HEADER; ++ unsigned int nlink; ++ unsigned int file_size:19; ++ unsigned int offset:13; ++ unsigned int start_block; ++ unsigned int parent_inode; ++} __attribute__ ((packed)); ++ ++struct squashfs_ldir_inode_header { ++ SQUASHFS_BASE_INODE_HEADER; ++ unsigned int nlink; ++ unsigned int file_size:27; ++ unsigned int offset:13; ++ unsigned int start_block; ++ unsigned int i_count:16; ++ unsigned int parent_inode; ++ struct squashfs_dir_index index[0]; ++} __attribute__ ((packed)); ++ ++union squashfs_inode_header { ++ struct squashfs_base_inode_header base; ++ struct squashfs_dev_inode_header dev; ++ struct squashfs_symlink_inode_header symlink; ++ struct squashfs_reg_inode_header reg; ++ struct squashfs_lreg_inode_header lreg; ++ struct squashfs_dir_inode_header dir; ++ struct squashfs_ldir_inode_header ldir; ++ struct squashfs_ipc_inode_header ipc; ++}; ++ ++struct squashfs_dir_entry { ++ unsigned int offset:13; ++ unsigned int type:3; ++ unsigned int size:8; ++ int inode_number:16; ++ char name[0]; ++} __attribute__ ((packed)); ++ ++struct squashfs_dir_header { ++ unsigned int count:8; ++ unsigned int start_block; ++ unsigned int inode_number; ++} __attribute__ ((packed)); ++ ++struct squashfs_fragment_entry { ++ long long start_block; ++ unsigned int size; ++ unsigned int pending; ++} __attribute__ ((packed)); ++ ++extern int squashfs_uncompress_block(void *d, int dstlen, void *s, int srclen); ++extern int squashfs_uncompress_init(void); ++extern int squashfs_uncompress_exit(void); ++ ++/* ++ * macros to convert each packed bitfield structure from little endian to big ++ * endian and vice versa. These are needed when creating or using a filesystem ++ * on a machine with different byte ordering to the target architecture. ++ * ++ */ ++ ++#define SQUASHFS_SWAP_START \ ++ int bits;\ ++ int b_pos;\ ++ unsigned long long val;\ ++ unsigned char *s;\ ++ unsigned char *d; ++ ++#define SQUASHFS_SWAP_SUPER_BLOCK(s, d) {\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_super_block));\ ++ SQUASHFS_SWAP((s)->s_magic, d, 0, 32);\ ++ SQUASHFS_SWAP((s)->inodes, d, 32, 32);\ ++ SQUASHFS_SWAP((s)->bytes_used_2, d, 64, 32);\ ++ SQUASHFS_SWAP((s)->uid_start_2, d, 96, 32);\ ++ SQUASHFS_SWAP((s)->guid_start_2, d, 128, 32);\ ++ SQUASHFS_SWAP((s)->inode_table_start_2, d, 160, 32);\ ++ SQUASHFS_SWAP((s)->directory_table_start_2, d, 192, 32);\ ++ SQUASHFS_SWAP((s)->s_major, d, 224, 16);\ ++ SQUASHFS_SWAP((s)->s_minor, d, 240, 16);\ ++ SQUASHFS_SWAP((s)->block_size_1, d, 256, 16);\ ++ SQUASHFS_SWAP((s)->block_log, d, 272, 16);\ ++ SQUASHFS_SWAP((s)->flags, d, 288, 8);\ ++ SQUASHFS_SWAP((s)->no_uids, d, 296, 8);\ ++ SQUASHFS_SWAP((s)->no_guids, d, 304, 8);\ ++ SQUASHFS_SWAP((s)->mkfs_time, d, 312, 32);\ ++ SQUASHFS_SWAP((s)->root_inode, d, 344, 64);\ ++ SQUASHFS_SWAP((s)->block_size, d, 408, 32);\ ++ SQUASHFS_SWAP((s)->fragments, d, 440, 32);\ ++ SQUASHFS_SWAP((s)->fragment_table_start_2, d, 472, 32);\ ++ SQUASHFS_SWAP((s)->bytes_used, d, 504, 64);\ ++ SQUASHFS_SWAP((s)->uid_start, d, 568, 64);\ ++ SQUASHFS_SWAP((s)->guid_start, d, 632, 64);\ ++ SQUASHFS_SWAP((s)->inode_table_start, d, 696, 64);\ ++ SQUASHFS_SWAP((s)->directory_table_start, d, 760, 64);\ ++ SQUASHFS_SWAP((s)->fragment_table_start, d, 824, 64);\ ++ SQUASHFS_SWAP((s)->lookup_table_start, d, 888, 64);\ ++} ++ ++#define SQUASHFS_SWAP_BASE_INODE_CORE(s, d, n)\ ++ SQUASHFS_MEMSET(s, d, n);\ ++ SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\ ++ SQUASHFS_SWAP((s)->mode, d, 4, 12);\ ++ SQUASHFS_SWAP((s)->uid, d, 16, 8);\ ++ SQUASHFS_SWAP((s)->guid, d, 24, 8);\ ++ SQUASHFS_SWAP((s)->mtime, d, 32, 32);\ ++ SQUASHFS_SWAP((s)->inode_number, d, 64, 32); ++ ++#define SQUASHFS_SWAP_BASE_INODE_HEADER(s, d, n) {\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, n)\ ++} ++ ++#define SQUASHFS_SWAP_IPC_INODE_HEADER(s, d) {\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \ ++ sizeof(struct squashfs_ipc_inode_header))\ ++ SQUASHFS_SWAP((s)->nlink, d, 96, 32);\ ++} ++ ++#define SQUASHFS_SWAP_DEV_INODE_HEADER(s, d) {\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \ ++ sizeof(struct squashfs_dev_inode_header)); \ ++ SQUASHFS_SWAP((s)->nlink, d, 96, 32);\ ++ SQUASHFS_SWAP((s)->rdev, d, 128, 16);\ ++} ++ ++#define SQUASHFS_SWAP_SYMLINK_INODE_HEADER(s, d) {\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \ ++ sizeof(struct squashfs_symlink_inode_header));\ ++ SQUASHFS_SWAP((s)->nlink, d, 96, 32);\ ++ SQUASHFS_SWAP((s)->symlink_size, d, 128, 16);\ ++} ++ ++#define SQUASHFS_SWAP_REG_INODE_HEADER(s, d) {\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \ ++ sizeof(struct squashfs_reg_inode_header));\ ++ SQUASHFS_SWAP((s)->start_block, d, 96, 64);\ ++ SQUASHFS_SWAP((s)->fragment, d, 160, 32);\ ++ SQUASHFS_SWAP((s)->offset, d, 192, 32);\ ++ SQUASHFS_SWAP((s)->file_size, d, 224, 32);\ ++} ++ ++#define SQUASHFS_SWAP_LREG_INODE_HEADER(s, d) {\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \ ++ sizeof(struct squashfs_lreg_inode_header));\ ++ SQUASHFS_SWAP((s)->nlink, d, 96, 32);\ ++ SQUASHFS_SWAP((s)->start_block, d, 128, 64);\ ++ SQUASHFS_SWAP((s)->fragment, d, 192, 32);\ ++ SQUASHFS_SWAP((s)->offset, d, 224, 32);\ ++ SQUASHFS_SWAP((s)->file_size, d, 256, 64);\ ++} ++ ++#define SQUASHFS_SWAP_DIR_INODE_HEADER(s, d) {\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \ ++ sizeof(struct squashfs_dir_inode_header));\ ++ SQUASHFS_SWAP((s)->nlink, d, 96, 32);\ ++ SQUASHFS_SWAP((s)->file_size, d, 128, 19);\ ++ SQUASHFS_SWAP((s)->offset, d, 147, 13);\ ++ SQUASHFS_SWAP((s)->start_block, d, 160, 32);\ ++ SQUASHFS_SWAP((s)->parent_inode, d, 192, 32);\ ++} ++ ++#define SQUASHFS_SWAP_LDIR_INODE_HEADER(s, d) {\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \ ++ sizeof(struct squashfs_ldir_inode_header));\ ++ SQUASHFS_SWAP((s)->nlink, d, 96, 32);\ ++ SQUASHFS_SWAP((s)->file_size, d, 128, 27);\ ++ SQUASHFS_SWAP((s)->offset, d, 155, 13);\ ++ SQUASHFS_SWAP((s)->start_block, d, 168, 32);\ ++ SQUASHFS_SWAP((s)->i_count, d, 200, 16);\ ++ SQUASHFS_SWAP((s)->parent_inode, d, 216, 32);\ ++} ++ ++#define SQUASHFS_SWAP_DIR_INDEX(s, d) {\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_index));\ ++ SQUASHFS_SWAP((s)->index, d, 0, 32);\ ++ SQUASHFS_SWAP((s)->start_block, d, 32, 32);\ ++ SQUASHFS_SWAP((s)->size, d, 64, 8);\ ++} ++ ++#define SQUASHFS_SWAP_DIR_HEADER(s, d) {\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_header));\ ++ SQUASHFS_SWAP((s)->count, d, 0, 8);\ ++ SQUASHFS_SWAP((s)->start_block, d, 8, 32);\ ++ SQUASHFS_SWAP((s)->inode_number, d, 40, 32);\ ++} ++ ++#define SQUASHFS_SWAP_DIR_ENTRY(s, d) {\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_entry));\ ++ SQUASHFS_SWAP((s)->offset, d, 0, 13);\ ++ SQUASHFS_SWAP((s)->type, d, 13, 3);\ ++ SQUASHFS_SWAP((s)->size, d, 16, 8);\ ++ SQUASHFS_SWAP((s)->inode_number, d, 24, 16);\ ++} ++ ++#define SQUASHFS_SWAP_FRAGMENT_ENTRY(s, d) {\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_fragment_entry));\ ++ SQUASHFS_SWAP((s)->start_block, d, 0, 64);\ ++ SQUASHFS_SWAP((s)->size, d, 64, 32);\ ++} ++ ++#define SQUASHFS_SWAP_INODE_T(s, d) SQUASHFS_SWAP_LONG_LONGS(s, d, 1) ++ ++#define SQUASHFS_SWAP_SHORTS(s, d, n) {\ ++ int entry;\ ++ int bit_position;\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_MEMSET(s, d, n * 2);\ ++ for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \ ++ 16)\ ++ SQUASHFS_SWAP(s[entry], d, bit_position, 16);\ ++} ++ ++#define SQUASHFS_SWAP_INTS(s, d, n) {\ ++ int entry;\ ++ int bit_position;\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_MEMSET(s, d, n * 4);\ ++ for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \ ++ 32)\ ++ SQUASHFS_SWAP(s[entry], d, bit_position, 32);\ ++} ++ ++#define SQUASHFS_SWAP_LONG_LONGS(s, d, n) {\ ++ int entry;\ ++ int bit_position;\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_MEMSET(s, d, n * 8);\ ++ for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \ ++ 64)\ ++ SQUASHFS_SWAP(s[entry], d, bit_position, 64);\ ++} ++ ++#define SQUASHFS_SWAP_DATA(s, d, n, bits) {\ ++ int entry;\ ++ int bit_position;\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_MEMSET(s, d, n * bits / 8);\ ++ for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \ ++ bits)\ ++ SQUASHFS_SWAP(s[entry], d, bit_position, bits);\ ++} ++ ++#define SQUASHFS_SWAP_FRAGMENT_INDEXES(s, d, n) SQUASHFS_SWAP_LONG_LONGS(s, d, n) ++#define SQUASHFS_SWAP_LOOKUP_BLOCKS(s, d, n) SQUASHFS_SWAP_LONG_LONGS(s, d, n) ++ ++#ifdef CONFIG_SQUASHFS_1_0_COMPATIBILITY ++ ++struct squashfs_base_inode_header_1 { ++ unsigned int inode_type:4; ++ unsigned int mode:12; /* protection */ ++ unsigned int uid:4; /* index into uid table */ ++ unsigned int guid:4; /* index into guid table */ ++} __attribute__ ((packed)); ++ ++struct squashfs_ipc_inode_header_1 { ++ unsigned int inode_type:4; ++ unsigned int mode:12; /* protection */ ++ unsigned int uid:4; /* index into uid table */ ++ unsigned int guid:4; /* index into guid table */ ++ unsigned int type:4; ++ unsigned int offset:4; ++} __attribute__ ((packed)); ++ ++struct squashfs_dev_inode_header_1 { ++ unsigned int inode_type:4; ++ unsigned int mode:12; /* protection */ ++ unsigned int uid:4; /* index into uid table */ ++ unsigned int guid:4; /* index into guid table */ ++ unsigned short rdev; ++} __attribute__ ((packed)); ++ ++struct squashfs_symlink_inode_header_1 { ++ unsigned int inode_type:4; ++ unsigned int mode:12; /* protection */ ++ unsigned int uid:4; /* index into uid table */ ++ unsigned int guid:4; /* index into guid table */ ++ unsigned short symlink_size; ++ char symlink[0]; ++} __attribute__ ((packed)); ++ ++struct squashfs_reg_inode_header_1 { ++ unsigned int inode_type:4; ++ unsigned int mode:12; /* protection */ ++ unsigned int uid:4; /* index into uid table */ ++ unsigned int guid:4; /* index into guid table */ ++ unsigned int mtime; ++ unsigned int start_block; ++ unsigned int file_size:32; ++ unsigned short block_list[0]; ++} __attribute__ ((packed)); ++ ++struct squashfs_dir_inode_header_1 { ++ unsigned int inode_type:4; ++ unsigned int mode:12; /* protection */ ++ unsigned int uid:4; /* index into uid table */ ++ unsigned int guid:4; /* index into guid table */ ++ unsigned int file_size:19; ++ unsigned int offset:13; ++ unsigned int mtime; ++ unsigned int start_block:24; ++} __attribute__ ((packed)); ++ ++#define SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, n) \ ++ SQUASHFS_MEMSET(s, d, n);\ ++ SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\ ++ SQUASHFS_SWAP((s)->mode, d, 4, 12);\ ++ SQUASHFS_SWAP((s)->uid, d, 16, 4);\ ++ SQUASHFS_SWAP((s)->guid, d, 20, 4); ++ ++#define SQUASHFS_SWAP_BASE_INODE_HEADER_1(s, d, n) {\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, n)\ ++} ++ ++#define SQUASHFS_SWAP_IPC_INODE_HEADER_1(s, d) {\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \ ++ sizeof(struct squashfs_ipc_inode_header_1));\ ++ SQUASHFS_SWAP((s)->type, d, 24, 4);\ ++ SQUASHFS_SWAP((s)->offset, d, 28, 4);\ ++} ++ ++#define SQUASHFS_SWAP_DEV_INODE_HEADER_1(s, d) {\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \ ++ sizeof(struct squashfs_dev_inode_header_1));\ ++ SQUASHFS_SWAP((s)->rdev, d, 24, 16);\ ++} ++ ++#define SQUASHFS_SWAP_SYMLINK_INODE_HEADER_1(s, d) {\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \ ++ sizeof(struct squashfs_symlink_inode_header_1));\ ++ SQUASHFS_SWAP((s)->symlink_size, d, 24, 16);\ ++} ++ ++#define SQUASHFS_SWAP_REG_INODE_HEADER_1(s, d) {\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \ ++ sizeof(struct squashfs_reg_inode_header_1));\ ++ SQUASHFS_SWAP((s)->mtime, d, 24, 32);\ ++ SQUASHFS_SWAP((s)->start_block, d, 56, 32);\ ++ SQUASHFS_SWAP((s)->file_size, d, 88, 32);\ ++} ++ ++#define SQUASHFS_SWAP_DIR_INODE_HEADER_1(s, d) {\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \ ++ sizeof(struct squashfs_dir_inode_header_1));\ ++ SQUASHFS_SWAP((s)->file_size, d, 24, 19);\ ++ SQUASHFS_SWAP((s)->offset, d, 43, 13);\ ++ SQUASHFS_SWAP((s)->mtime, d, 56, 32);\ ++ SQUASHFS_SWAP((s)->start_block, d, 88, 24);\ ++} ++ ++#endif ++ ++#ifdef CONFIG_SQUASHFS_2_0_COMPATIBILITY ++ ++struct squashfs_dir_index_2 { ++ unsigned int index:27; ++ unsigned int start_block:29; ++ unsigned char size; ++ unsigned char name[0]; ++} __attribute__ ((packed)); ++ ++struct squashfs_base_inode_header_2 { ++ unsigned int inode_type:4; ++ unsigned int mode:12; /* protection */ ++ unsigned int uid:8; /* index into uid table */ ++ unsigned int guid:8; /* index into guid table */ ++} __attribute__ ((packed)); ++ ++struct squashfs_ipc_inode_header_2 { ++ unsigned int inode_type:4; ++ unsigned int mode:12; /* protection */ ++ unsigned int uid:8; /* index into uid table */ ++ unsigned int guid:8; /* index into guid table */ ++} __attribute__ ((packed)); ++ ++struct squashfs_dev_inode_header_2 { ++ unsigned int inode_type:4; ++ unsigned int mode:12; /* protection */ ++ unsigned int uid:8; /* index into uid table */ ++ unsigned int guid:8; /* index into guid table */ ++ unsigned short rdev; ++} __attribute__ ((packed)); ++ ++struct squashfs_symlink_inode_header_2 { ++ unsigned int inode_type:4; ++ unsigned int mode:12; /* protection */ ++ unsigned int uid:8; /* index into uid table */ ++ unsigned int guid:8; /* index into guid table */ ++ unsigned short symlink_size; ++ char symlink[0]; ++} __attribute__ ((packed)); ++ ++struct squashfs_reg_inode_header_2 { ++ unsigned int inode_type:4; ++ unsigned int mode:12; /* protection */ ++ unsigned int uid:8; /* index into uid table */ ++ unsigned int guid:8; /* index into guid table */ ++ unsigned int mtime; ++ unsigned int start_block; ++ unsigned int fragment; ++ unsigned int offset; ++ unsigned int file_size:32; ++ unsigned short block_list[0]; ++} __attribute__ ((packed)); ++ ++struct squashfs_dir_inode_header_2 { ++ unsigned int inode_type:4; ++ unsigned int mode:12; /* protection */ ++ unsigned int uid:8; /* index into uid table */ ++ unsigned int guid:8; /* index into guid table */ ++ unsigned int file_size:19; ++ unsigned int offset:13; ++ unsigned int mtime; ++ unsigned int start_block:24; ++} __attribute__ ((packed)); ++ ++struct squashfs_ldir_inode_header_2 { ++ unsigned int inode_type:4; ++ unsigned int mode:12; /* protection */ ++ unsigned int uid:8; /* index into uid table */ ++ unsigned int guid:8; /* index into guid table */ ++ unsigned int file_size:27; ++ unsigned int offset:13; ++ unsigned int mtime; ++ unsigned int start_block:24; ++ unsigned int i_count:16; ++ struct squashfs_dir_index_2 index[0]; ++} __attribute__ ((packed)); ++ ++union squashfs_inode_header_2 { ++ struct squashfs_base_inode_header_2 base; ++ struct squashfs_dev_inode_header_2 dev; ++ struct squashfs_symlink_inode_header_2 symlink; ++ struct squashfs_reg_inode_header_2 reg; ++ struct squashfs_dir_inode_header_2 dir; ++ struct squashfs_ldir_inode_header_2 ldir; ++ struct squashfs_ipc_inode_header_2 ipc; ++}; ++ ++struct squashfs_dir_header_2 { ++ unsigned int count:8; ++ unsigned int start_block:24; ++} __attribute__ ((packed)); ++ ++struct squashfs_dir_entry_2 { ++ unsigned int offset:13; ++ unsigned int type:3; ++ unsigned int size:8; ++ char name[0]; ++} __attribute__ ((packed)); ++ ++struct squashfs_fragment_entry_2 { ++ unsigned int start_block; ++ unsigned int size; ++} __attribute__ ((packed)); ++ ++#define SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, n)\ ++ SQUASHFS_MEMSET(s, d, n);\ ++ SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\ ++ SQUASHFS_SWAP((s)->mode, d, 4, 12);\ ++ SQUASHFS_SWAP((s)->uid, d, 16, 8);\ ++ SQUASHFS_SWAP((s)->guid, d, 24, 8);\ ++ ++#define SQUASHFS_SWAP_BASE_INODE_HEADER_2(s, d, n) {\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, n)\ ++} ++ ++#define SQUASHFS_SWAP_IPC_INODE_HEADER_2(s, d) \ ++ SQUASHFS_SWAP_BASE_INODE_HEADER_2(s, d, sizeof(struct squashfs_ipc_inode_header_2)) ++ ++#define SQUASHFS_SWAP_DEV_INODE_HEADER_2(s, d) {\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \ ++ sizeof(struct squashfs_dev_inode_header_2)); \ ++ SQUASHFS_SWAP((s)->rdev, d, 32, 16);\ ++} ++ ++#define SQUASHFS_SWAP_SYMLINK_INODE_HEADER_2(s, d) {\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \ ++ sizeof(struct squashfs_symlink_inode_header_2));\ ++ SQUASHFS_SWAP((s)->symlink_size, d, 32, 16);\ ++} ++ ++#define SQUASHFS_SWAP_REG_INODE_HEADER_2(s, d) {\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \ ++ sizeof(struct squashfs_reg_inode_header_2));\ ++ SQUASHFS_SWAP((s)->mtime, d, 32, 32);\ ++ SQUASHFS_SWAP((s)->start_block, d, 64, 32);\ ++ SQUASHFS_SWAP((s)->fragment, d, 96, 32);\ ++ SQUASHFS_SWAP((s)->offset, d, 128, 32);\ ++ SQUASHFS_SWAP((s)->file_size, d, 160, 32);\ ++} ++ ++#define SQUASHFS_SWAP_DIR_INODE_HEADER_2(s, d) {\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \ ++ sizeof(struct squashfs_dir_inode_header_2));\ ++ SQUASHFS_SWAP((s)->file_size, d, 32, 19);\ ++ SQUASHFS_SWAP((s)->offset, d, 51, 13);\ ++ SQUASHFS_SWAP((s)->mtime, d, 64, 32);\ ++ SQUASHFS_SWAP((s)->start_block, d, 96, 24);\ ++} ++ ++#define SQUASHFS_SWAP_LDIR_INODE_HEADER_2(s, d) {\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \ ++ sizeof(struct squashfs_ldir_inode_header_2));\ ++ SQUASHFS_SWAP((s)->file_size, d, 32, 27);\ ++ SQUASHFS_SWAP((s)->offset, d, 59, 13);\ ++ SQUASHFS_SWAP((s)->mtime, d, 72, 32);\ ++ SQUASHFS_SWAP((s)->start_block, d, 104, 24);\ ++ SQUASHFS_SWAP((s)->i_count, d, 128, 16);\ ++} ++ ++#define SQUASHFS_SWAP_DIR_INDEX_2(s, d) {\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_index_2));\ ++ SQUASHFS_SWAP((s)->index, d, 0, 27);\ ++ SQUASHFS_SWAP((s)->start_block, d, 27, 29);\ ++ SQUASHFS_SWAP((s)->size, d, 56, 8);\ ++} ++#define SQUASHFS_SWAP_DIR_HEADER_2(s, d) {\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_header_2));\ ++ SQUASHFS_SWAP((s)->count, d, 0, 8);\ ++ SQUASHFS_SWAP((s)->start_block, d, 8, 24);\ ++} ++ ++#define SQUASHFS_SWAP_DIR_ENTRY_2(s, d) {\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_entry_2));\ ++ SQUASHFS_SWAP((s)->offset, d, 0, 13);\ ++ SQUASHFS_SWAP((s)->type, d, 13, 3);\ ++ SQUASHFS_SWAP((s)->size, d, 16, 8);\ ++} ++ ++#define SQUASHFS_SWAP_FRAGMENT_ENTRY_2(s, d) {\ ++ SQUASHFS_SWAP_START\ ++ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_fragment_entry_2));\ ++ SQUASHFS_SWAP((s)->start_block, d, 0, 32);\ ++ SQUASHFS_SWAP((s)->size, d, 32, 32);\ ++} ++ ++#define SQUASHFS_SWAP_FRAGMENT_INDEXES_2(s, d, n) SQUASHFS_SWAP_INTS(s, d, n) ++ ++/* fragment and fragment table defines */ ++#define SQUASHFS_FRAGMENT_BYTES_2(A) (A * sizeof(struct squashfs_fragment_entry_2)) ++ ++#define SQUASHFS_FRAGMENT_INDEX_2(A) (SQUASHFS_FRAGMENT_BYTES_2(A) / \ ++ SQUASHFS_METADATA_SIZE) ++ ++#define SQUASHFS_FRAGMENT_INDEX_OFFSET_2(A) (SQUASHFS_FRAGMENT_BYTES_2(A) % \ ++ SQUASHFS_METADATA_SIZE) ++ ++#define SQUASHFS_FRAGMENT_INDEXES_2(A) ((SQUASHFS_FRAGMENT_BYTES_2(A) + \ ++ SQUASHFS_METADATA_SIZE - 1) / \ ++ SQUASHFS_METADATA_SIZE) ++ ++#define SQUASHFS_FRAGMENT_INDEX_BYTES_2(A) (SQUASHFS_FRAGMENT_INDEXES_2(A) *\ ++ sizeof(int)) ++ ++#endif ++ ++#ifdef __KERNEL__ ++ ++/* ++ * macros used to swap each structure entry, taking into account ++ * bitfields and different bitfield placing conventions on differing ++ * architectures ++ */ ++ ++#include <asm/byteorder.h> ++ ++#ifdef __BIG_ENDIAN ++ /* convert from little endian to big endian */ ++#define SQUASHFS_SWAP(value, p, pos, tbits) _SQUASHFS_SWAP(value, p, pos, \ ++ tbits, b_pos) ++#else ++ /* convert from big endian to little endian */ ++#define SQUASHFS_SWAP(value, p, pos, tbits) _SQUASHFS_SWAP(value, p, pos, \ ++ tbits, 64 - tbits - b_pos) ++#endif ++ ++#define _SQUASHFS_SWAP(value, p, pos, tbits, SHIFT) {\ ++ b_pos = pos % 8;\ ++ val = 0;\ ++ s = (unsigned char *)p + (pos / 8);\ ++ d = ((unsigned char *) &val) + 7;\ ++ for(bits = 0; bits < (tbits + b_pos); bits += 8) \ ++ *d-- = *s++;\ ++ value = (val >> (SHIFT))/* & ((1 << tbits) - 1)*/;\ ++} ++ ++#define SQUASHFS_MEMSET(s, d, n) memset(s, 0, n); ++ ++#endif ++#endif +Index: linux-2.6.22/include/linux/squashfs_fs_i.h +=================================================================== +--- /dev/null ++++ linux-2.6.22/include/linux/squashfs_fs_i.h +@@ -0,0 +1,45 @@ ++#ifndef SQUASHFS_FS_I ++#define SQUASHFS_FS_I ++/* ++ * Squashfs ++ * ++ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007 ++ * Phillip Lougher <phillip@lougher.org.uk> ++ * ++ * 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, ++ * 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ * ++ * squashfs_fs_i.h ++ */ ++ ++struct squashfs_inode_info { ++ long long start_block; ++ unsigned int offset; ++ union { ++ struct { ++ long long fragment_start_block; ++ unsigned int fragment_size; ++ unsigned int fragment_offset; ++ long long block_list_start; ++ } s1; ++ struct { ++ long long directory_index_start; ++ unsigned int directory_index_offset; ++ unsigned int directory_index_count; ++ unsigned int parent_inode; ++ } s2; ++ } u; ++ struct inode vfs_inode; ++}; ++#endif +Index: linux-2.6.22/include/linux/squashfs_fs_sb.h +=================================================================== +--- /dev/null ++++ linux-2.6.22/include/linux/squashfs_fs_sb.h +@@ -0,0 +1,74 @@ ++#ifndef SQUASHFS_FS_SB ++#define SQUASHFS_FS_SB ++/* ++ * Squashfs ++ * ++ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007 ++ * Phillip Lougher <phillip@lougher.org.uk> ++ * ++ * 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, ++ * 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ * ++ * squashfs_fs_sb.h ++ */ ++ ++#include <linux/squashfs_fs.h> ++ ++struct squashfs_cache { ++ long long block; ++ int length; ++ long long next_index; ++ char *data; ++}; ++ ++struct squashfs_fragment_cache { ++ long long block; ++ int length; ++ unsigned int locked; ++ char *data; ++}; ++ ++struct squashfs_sb_info { ++ struct squashfs_super_block sblk; ++ int devblksize; ++ int devblksize_log2; ++ int swap; ++ struct squashfs_cache *block_cache; ++ struct squashfs_fragment_cache *fragment; ++ int next_cache; ++ int next_fragment; ++ int next_meta_index; ++ unsigned int *uid; ++ unsigned int *guid; ++ long long *fragment_index; ++ unsigned int *fragment_index_2; ++ char *read_page; ++ struct mutex read_data_mutex; ++ struct mutex read_page_mutex; ++ struct mutex block_cache_mutex; ++ struct mutex fragment_mutex; ++ struct mutex meta_index_mutex; ++ wait_queue_head_t waitq; ++ wait_queue_head_t fragment_wait_queue; ++ struct meta_index *meta_index; ++ z_stream stream; ++ long long *inode_lookup_table; ++ int (*read_inode)(struct inode *i, squashfs_inode_t \ ++ inode); ++ long long (*read_blocklist)(struct inode *inode, int \ ++ index, int readahead_blks, char *block_list, \ ++ unsigned short **block_p, unsigned int *bsize); ++ int (*read_fragment_index_table)(struct super_block *s); ++}; ++#endif +Index: linux-2.6.22/init/do_mounts_rd.c +=================================================================== +--- linux-2.6.22.orig/init/do_mounts_rd.c ++++ linux-2.6.22/init/do_mounts_rd.c +@@ -5,6 +5,7 @@ + #include <linux/ext2_fs.h> + #include <linux/romfs_fs.h> + #include <linux/cramfs_fs.h> ++#include <linux/squashfs_fs.h> + #include <linux/initrd.h> + #include <linux/string.h> + +@@ -39,6 +40,7 @@ + * numbers could not be found. + * + * We currently check for the following magic numbers: ++ * squashfs + * minix + * ext2 + * romfs +@@ -53,6 +55,7 @@ + struct ext2_super_block *ext2sb; + struct romfs_super_block *romfsb; + struct cramfs_super *cramfsb; ++ struct squashfs_super_block *squashfsb; + int nblocks = -1; + unsigned char *buf; + +@@ -64,6 +67,7 @@ + ext2sb = (struct ext2_super_block *) buf; + romfsb = (struct romfs_super_block *) buf; + cramfsb = (struct cramfs_super *) buf; ++ squashfsb = (struct squashfs_super_block *) buf; + memset(buf, 0xe5, size); + + /* +@@ -101,6 +105,18 @@ + goto done; + } + ++ /* squashfs is at block zero too */ ++ if (squashfsb->s_magic == SQUASHFS_MAGIC) { ++ printk(KERN_NOTICE ++ "RAMDISK: squashfs filesystem found at block %d\n", ++ start_block); ++ if (squashfsb->s_major < 3) ++ nblocks = (squashfsb->bytes_used_2+BLOCK_SIZE-1)>>BLOCK_SIZE_BITS; ++ else ++ nblocks = (squashfsb->bytes_used+BLOCK_SIZE-1)>>BLOCK_SIZE_BITS; ++ goto done; ++ } ++ + /* + * Read block 1 to test for minix and ext2 superblock + */ diff --git a/packages/linux/linux-openmoko-devel_svn.bb b/packages/linux/linux-openmoko-devel_svn+2.6.23.1.bb index 6fae5da9ef..e1686eada9 100644 --- a/packages/linux/linux-openmoko-devel_svn.bb +++ b/packages/linux/linux-openmoko-devel_svn+2.6.23.1.bb @@ -1,24 +1,34 @@ +require linux.inc + DESCRIPTION = "Linux 2.6.x (development) kernel for FIC SmartPhones shipping w/ OpenMoko" -VANILLA_VERSION = "2.6.22.5" -PV = "${VANILLA_VERSION}-moko11+svnr${SRCREV}" +VANILLA_VERSION = "2.6.23" +#KERNEL_VERSION = "2.6.23-rc9" +KERNEL_RELEASE = "2.6.23.1" + +# If you use a rc, you will need to use this: +#PV = "${VANILLA_VERSION}+${KERNEL_RELEASE}-moko11+svnr${SRCREV}" + +KERNEL_VERSION = "${KERNEL_RELEASE}" +PV = "${KERNEL_RELEASE}+svnr${SRCREV}" PR = "r1" KERNEL_IMAGETYPE = "uImage" UBOOT_ENTRYPOINT = "30008000" -require linux.inc - ############################################################## # source and patches # SRCREV_FORMAT = "patches" +SRCREV = "3140" SRC_URI = "${KERNELORG_MIRROR}/pub/linux/kernel/v2.6/linux-${VANILLA_VERSION}.tar.bz2 \ - svn://svn.openmoko.org/trunk/src/target/kernel;module=patches;proto=http;name=patches \ - file://squashfs.patch;patch=1 \ + ${KERNELORG_MIRROR}/pub/linux/kernel/v2.6/patch-${KERNEL_VERSION}.bz2;patch=1 \ + svn://svn.openmoko.org/branches/src/target/kernel/2.6.23.x;module=patches;proto=http;name=patches \ + file://squashfs-2.6.23.patch;patch=1 \ file://fix-EVIOCGRAB-semantics-2.6.22.5.patch;patch=1 \ -# file://printascii.patch;patch=1 \ - file://defconfig \ +# file://printascii-2.6.23.patch;patch=1 \ + file://hack-gta02-cpu.patch;patch=1 \ + file://defconfig-2.6.23.1 \ file://logo_linux_clut224.ppm" S = "${WORKDIR}/linux-${VANILLA_VERSION}" @@ -50,6 +60,7 @@ do_prepatch() { mv ${WORKDIR}/patches ${S}/patches && cd ${S} && quilt push -av mv patches patches.openmoko mv .pc .pc.old + mv ${WORKDIR}/defconfig-${KERNEL_VERSION} ${WORKDIR}/defconfig } addtask prepatch after do_unpack before do_patch diff --git a/packages/linux/linux-openmoko.inc b/packages/linux/linux-openmoko.inc index d6b464c301..e6e41cfc08 100644 --- a/packages/linux/linux-openmoko.inc +++ b/packages/linux/linux-openmoko.inc @@ -83,13 +83,13 @@ do_configure() { # do_deploy() { install -d ${DEPLOY_DIR_IMAGE} - install -m 0644 arch/${ARCH}/boot/${KERNEL_IMAGETYPE} ${DEPLOY_DIR_IMAGE}/${KERNEL_IMAGETYPE}-${PV}-${PR}-${MACHINE}.bin - tar -cvzf ${DEPLOY_DIR_IMAGE}/modules-${KERNEL_RELEASE}-${PR}-${MACHINE}.tgz -C ${D} lib + install -m 0644 arch/${ARCH}/boot/${KERNEL_IMAGETYPE} ${DEPLOY_DIR_IMAGE}/${KERNEL_IMAGETYPE}-${PV}-${PR}-${MACHINE_CLASS}.bin + tar -cvzf ${DEPLOY_DIR_IMAGE}/modules-${KERNEL_RELEASE}-${PR}-${MACHINE_CLASS}.tgz -C ${D} lib ${OBJCOPY} -O binary -R .note -R .comment -S vmlinux linux.bin rm -f linux.bin.gz gzip -9 linux.bin - ${STAGING_BINDIR_NATIVE}/uboot-mkimage -A arm -O linux -T kernel -C gzip -a 30008000 -e 30008000 -n "OpenMoko Kernel Image Neo1973(GTA01)" -d linux.bin.gz ${DEPLOY_DIR_IMAGE}/uImage-${PV}-${PR}-${MACHINE}.bin - ln -sf ${DEPLOY_DIR_IMAGE}/uImage-${PV}-${PR}-${MACHINE}.bin ${DEPLOY_DIR_IMAGE}/uImage-${MACHINE}-latest.bin + ${STAGING_BINDIR_NATIVE}/uboot-mkimage -A arm -O linux -T kernel -C gzip -a 30008000 -e 30008000 -n "OpenMoko Kernel Image Neo1973(GTA01/2)" -d linux.bin.gz ${DEPLOY_DIR_IMAGE}/uImage-${PV}-${PR}-${MACHINE_CLASS}.bin + ln -sf ${DEPLOY_DIR_IMAGE}/uImage-${PV}-${PR}-${MACHINE_CLASS}.bin ${DEPLOY_DIR_IMAGE}/uImage-${MACHINE_CLASS}-latest.bin rm -f linux.bin.gz } diff --git a/packages/linux/linux-openmoko/defconfig-2.6.22.5-fic-gta01 b/packages/linux/linux-openmoko/defconfig-2.6.22.5-fic-gta01 index 1d12b6ec36..7aa23df77c 100644 --- a/packages/linux/linux-openmoko/defconfig-2.6.22.5-fic-gta01 +++ b/packages/linux/linux-openmoko/defconfig-2.6.22.5-fic-gta01 @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.22.1 -# Thu Jul 26 22:01:38 2007 +# Linux kernel version: 2.6.22.5 +# Wed Oct 3 13:55:25 2007 # CONFIG_ARM=y CONFIG_SYS_SUPPORTS_APM_EMULATION=y @@ -200,11 +200,12 @@ CONFIG_ARCH_S3C2440=y CONFIG_SMDK2440_CPU2440=y CONFIG_MACH_HXD8=y CONFIG_MACH_NEO1973_GTA02=y +CONFIG_CPU_S3C2442=y # # S3C2442 Machines # -# CONFIG_SMDK2440_CPU2442 is not set +CONFIG_SMDK2440_CPU2442=y # # S3C2443 Machines @@ -282,6 +283,7 @@ CONFIG_KEXEC=y # At least one emulation must be selected # CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set # CONFIG_FPE_FASTFPE is not set # @@ -1196,9 +1198,6 @@ CONFIG_FONT_6x11=y # CONFIG_FONT_SUN12x22 is not set # CONFIG_FONT_10x18 is not set # CONFIG_LOGO is not set -# CONFIG_LOGO_LINUX_MONO is not set -# CONFIG_LOGO_LINUX_VGA16 is not set -# CONFIG_LOGO_LINUX_CLUT224 is not set # # Sound @@ -1586,7 +1585,7 @@ CONFIG_CONFIGFS_FS=m # CONFIG_EFS_FS is not set CONFIG_YAFFS_FS=y CONFIG_YAFFS_YAFFS1=y -# CONFIG_YAFFS_DOES_ECC is not set +CONFIG_YAFFS_9BYTE_TAGS=y CONFIG_YAFFS_YAFFS2=y CONFIG_YAFFS_AUTO_YAFFS2=y # CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set diff --git a/packages/linux/linux-openmoko/defconfig-2.6.22.5-fic-gta02 b/packages/linux/linux-openmoko/defconfig-2.6.22.5-fic-gta02 index 1d12b6ec36..7aa23df77c 100644 --- a/packages/linux/linux-openmoko/defconfig-2.6.22.5-fic-gta02 +++ b/packages/linux/linux-openmoko/defconfig-2.6.22.5-fic-gta02 @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.22.1 -# Thu Jul 26 22:01:38 2007 +# Linux kernel version: 2.6.22.5 +# Wed Oct 3 13:55:25 2007 # CONFIG_ARM=y CONFIG_SYS_SUPPORTS_APM_EMULATION=y @@ -200,11 +200,12 @@ CONFIG_ARCH_S3C2440=y CONFIG_SMDK2440_CPU2440=y CONFIG_MACH_HXD8=y CONFIG_MACH_NEO1973_GTA02=y +CONFIG_CPU_S3C2442=y # # S3C2442 Machines # -# CONFIG_SMDK2440_CPU2442 is not set +CONFIG_SMDK2440_CPU2442=y # # S3C2443 Machines @@ -282,6 +283,7 @@ CONFIG_KEXEC=y # At least one emulation must be selected # CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set # CONFIG_FPE_FASTFPE is not set # @@ -1196,9 +1198,6 @@ CONFIG_FONT_6x11=y # CONFIG_FONT_SUN12x22 is not set # CONFIG_FONT_10x18 is not set # CONFIG_LOGO is not set -# CONFIG_LOGO_LINUX_MONO is not set -# CONFIG_LOGO_LINUX_VGA16 is not set -# CONFIG_LOGO_LINUX_CLUT224 is not set # # Sound @@ -1586,7 +1585,7 @@ CONFIG_CONFIGFS_FS=m # CONFIG_EFS_FS is not set CONFIG_YAFFS_FS=y CONFIG_YAFFS_YAFFS1=y -# CONFIG_YAFFS_DOES_ECC is not set +CONFIG_YAFFS_9BYTE_TAGS=y CONFIG_YAFFS_YAFFS2=y CONFIG_YAFFS_AUTO_YAFFS2=y # CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set diff --git a/packages/linux/linux-openmoko_2.6.22.5.bb b/packages/linux/linux-openmoko_2.6.22.5.bb index e4608a7565..290f475130 100644 --- a/packages/linux/linux-openmoko_2.6.22.5.bb +++ b/packages/linux/linux-openmoko_2.6.22.5.bb @@ -8,4 +8,4 @@ SRC_URI += "file://fix-EVIOCGRAB-semantics-2.6.22.5.patch;patch=1" VANILLA_VERSION = "2.6.22.5" MOKOR = "moko11+svnr${SRCREV}" PV = "${VANILLA_VERSION}-${MOKOR}" -PR = "r2" +PR = "r3" diff --git a/packages/linux/linux-rp_2.6.22.bb b/packages/linux/linux-rp_2.6.22.bb index b36189d9fb..50ee894ee9 100644 --- a/packages/linux/linux-rp_2.6.22.bb +++ b/packages/linux/linux-rp_2.6.22.bb @@ -1,6 +1,6 @@ require linux-rp.inc -PR = "r9" +PR = "r10" # Handy URLs # git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git;protocol=git;tag=ef7d1b244fa6c94fb76d5f787b8629df64ea4046 @@ -37,6 +37,7 @@ SRC_URI = "http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.22.tar.bz2 \ ${RPSRC}/poodle_pm-r4.patch;patch=1 \ ${RPSRC}/pxa27x_overlay-r5.patch;patch=1 \ ${RPSRC}/w100_extaccel-r1.patch;patch=1 \ + ${RPSRC}/w100_extmem-r1.patch;patch=1 \ file://hostap-monitor-mode.patch;patch=1 \ file://serial-add-support-for-non-standard-xtals-to-16c950-driver.patch;patch=1 \ ${RPSRC}/logo_oh-r0.patch.bz2;patch=1;status=unmergable \ diff --git a/packages/linux/linux.inc b/packages/linux/linux.inc index 7579481005..6568049113 100644 --- a/packages/linux/linux.inc +++ b/packages/linux/linux.inc @@ -18,6 +18,8 @@ DEPENDS_append_fic-gta01 = " u-boot-mkimage-openmoko-native " DEPENDS_append_fic-gta02 = " u-boot-mkimage-openmoko-native " +RPSRC = "http://www.rpsys.net/openzaurus/patches/archive" + # Specify the commandline for your device #boot from mmc @@ -40,7 +42,7 @@ do_configure_prepend() { # # oabi / eabi support # - if [ "${TARGET_OS}" == "linux-gnueabi" -o "${TARGET_OS}" == "linux-uclibcgnueabi" ]; then + if [ "${TARGET_OS}" = "linux-gnueabi" -o "${TARGET_OS}" = "linux-uclibcgnueabi" ]; then echo "CONFIG_AEABI=y" >> ${S}/.config echo "CONFIG_OABI_COMPAT=y" >> ${S}/.config else @@ -104,11 +106,16 @@ do_install_prepend() { if test -e arch/${ARCH}/boot/images/uImage ; then ln -f arch/${ARCH}/boot/images/uImage arch/${ARCH}/boot/uImage fi + + if test -e arch/${ARCH}/kernel/vmlinux.lds ; then + ln -f arch/${ARCH}/kernel/vmlinux.lds arch/${ARCH}/boot/vmlinux + fi } UBOOT_ENTRYPOINT ?= "20008000" -KERNEL_IMAGE_BASE_NAME = ${KERNEL_IMAGETYPE}-${PV}-${PR}-${MACHINE}-${DATETIME} +KERNEL_IMAGE_BASE_NAME = "${KERNEL_IMAGETYPE}-${PV}-${PR}-${MACHINE}-${DATETIME}" +KERNEL_IMAGE_SYMLINK_NAME = "${KERNEL_IMAGETYPE}-${MACHINE}" do_deploy() { install -d ${DEPLOY_DIR_IMAGE} @@ -128,6 +135,10 @@ do_deploy() { rm -f linux.bin.gz fi fi + + cd ${DEPLOY_DIR_IMAGE} + rm -f ${KERNEL_IMAGE_SYMLINK_NAME}.bin + ln -sf ${KERNEL_IMAGE_BASE_NAME}.bin ${KERNEL_IMAGE_SYMLINK_NAME}.bin } do_deploy[dirs] = "${S}" diff --git a/packages/linux/linux_2.6.21.bb b/packages/linux/linux_2.6.21.bb index 0848bcd71a..f2ab2116be 100644 --- a/packages/linux/linux_2.6.21.bb +++ b/packages/linux/linux_2.6.21.bb @@ -4,10 +4,12 @@ DEFAULT_PREFERENCE_at91sam9263ek = "-1" DEFAULT_PREFERENCE_gumstix-connex = "1" DEFAULT_PREFERENCE_gumstix-verdex = "1" -PR = "r9" +PR = "r11" SRC_URI = "${KERNELORG_MIRROR}/pub/linux/kernel/v2.6/linux-${PV}.tar.bz2 \ - file://defconfig \ + file://tsc2003.c \ + file://tsc2003-config.diff;patch=1 \ + file://defconfig \ " SRC_URI_append_simpad = "\ @@ -69,8 +71,15 @@ GUMSTIX_PATCHES = "\ file://uImage-in-own-partition.patch;patch=1 \ file://pxa-regs-fixup.patch;patch=1 \ file://gumstix-fb-logo.patch;patch=1 \ - file://pxafb-18bpp-mode.patch;patch=1 \ + file://gumstix-pxa270-mmc.patch;patch=1 \ + ${RPSRC}/pxa27x_overlay-r5.patch;patch=1 \ + file://smc911x-fixup.patch;patch=1 \ " SRC_URI_append_gumstix-verdex = "${GUMSTIX_PATCHES}" SRC_URI_append_gumstix-connex = "${GUMSTIX_PATCHES}" + + +do_configure_prepend() { + cp ${WORKDIR}/tsc2003.c ${S}/drivers/i2c/chips/ +} diff --git a/packages/linux/linux_2.6.22.bb b/packages/linux/linux_2.6.22.bb index 64b57d3076..03d945adbf 100644 --- a/packages/linux/linux_2.6.22.bb +++ b/packages/linux/linux_2.6.22.bb @@ -2,12 +2,64 @@ require linux.inc # Mark archs/machines that this kernel supports DEFAULT_PREFERENCE = "-1" -DEFAULT_PREFERENCE_avr32 = "1" +DEFAULT_PREFERENCE_cm-x270 = "-1" +DEFAULT_PREFERENCE_bd-neon = "0" -PR = "r3" +PR = "r4" SRC_URI = "${KERNELORG_MIRROR}/pub/linux/kernel/v2.6/linux-2.6.22.tar.bz2 \ file://defconfig \ " -SRC_URI_append_avr32 = "http://avr32linux.org/twiki/pub/Main/LinuxPatches/linux-2.6.22.atmel.3.patch.bz2;patch=1" +SRC_URI_append_cm-x270 = "\ + file://0001-cm-x270-base2.patch;patch=1 \ + file://0002-cm-x270-match-type.patch;patch=1 \ + file://0003-cm-x270-ide.patch;patch=1 \ + file://0004-cm-x270-it8152.patch;patch=1 \ + file://0005-cm-x270-pcmcia.patch;patch=1 \ + file://0006-ramdisk_load.patch;patch=1 \ + file://0007-mmcsd_large_cards-r0.patch;patch=1 \ + file://0008-cm-x270-nand-simplify-name.patch;patch=1" + +CMDLINE_cm-x270 = "console=${CMX270_CONSOLE_SERIAL_PORT},38400 monitor=8 bpp=16 mem=64M mtdparts=physmap-flash.0:256k(boot)ro,0x180000(kernel),-(root);cm-x270-nand:64m(app),-(data) rdinit=/sbin/init root=mtd3 rootfstype=jffs2" + +FILES_kernel-image_cm-x270 = "" + +SRC_URI_append_bd-neon = " http://www.boundarydevices.com/boundary-2.6.22-2007-07-22.patch.bz2;patch=1" + +python do_compulab_image() { + import os + import os.path + import struct + + machine = bb.data.getVar('MACHINE', d, 1) + if machine == "cm-x270": + deploy_dir = bb.data.getVar('DEPLOY_DIR_IMAGE', d, 1) + kernel_file = os.path.join(deploy_dir, bb.data.expand('${KERNEL_IMAGE_BASE_NAME}', d) + '.bin') + img_file = os.path.join(deploy_dir, bb.data.expand('${KERNEL_IMAGE_BASE_NAME}', d) + '.cmx270') + + fo = open(img_file, 'wb') + + image_data = open(kernel_file, 'rb').read() + + # first write size into first 4 bytes + size_s = struct.pack('i', len(image_data)) + + # truncate size if we are running on a 64-bit host + size_s = size_s[:4] + + fo.write(size_s) + fo.write(image_data) + fo.close() + + os.chdir(deploy_dir) + link_file = bb.data.expand('${KERNEL_IMAGE_SYMLINK_NAME}', d) + '.cmx270' + img_file = bb.data.expand('${KERNEL_IMAGE_BASE_NAME}', d) + '.cmx270' + try: + os.unlink(link_file) + except: + pass + os.symlink(img_file, link_file) +} + +addtask compulab_image after do_deploy before do_package diff --git a/packages/linux/linux_2.6.23.bb b/packages/linux/linux_2.6.23.bb new file mode 100644 index 0000000000..b73e9a71fa --- /dev/null +++ b/packages/linux/linux_2.6.23.bb @@ -0,0 +1,63 @@ +require linux.inc + +# Mark archs/machines that this kernel supports +DEFAULT_PREFERENCE = "-1" +DEFAULT_PREFERENCE_cm-x270 = "1" + +PR = "r0" + +SRC_URI = "${KERNELORG_MIRROR}/pub/linux/kernel/v2.6/linux-2.6.23.tar.bz2 \ + file://binutils-buildid-arm.patch;patch=1 \ + file://defconfig \ + " + +SRC_URI_append_cm-x270 = "\ + file://0001-cm-x270-base2.patch;patch=1 \ + file://0002-cm-x270-match-type.patch;patch=1 \ + file://0003-cm-x270-ide.patch;patch=1 \ + file://0004-cm-x270-it8152.patch;patch=1 \ + file://0005-cm-x270-pcmcia.patch;patch=1 \ + file://0006-ramdisk_load.patch;patch=1 \ + file://0007-mmcsd_large_cards-r0.patch;patch=1 \ + file://0008-cm-x270-nand-simplify-name.patch;patch=1" + +CMDLINE_cm-x270 = "console=${CMX270_CONSOLE_SERIAL_PORT},38400 monitor=8 bpp=16 mem=64M mtdparts=physmap-flash.0:256k(boot)ro,0x180000(kernel),-(root);cm-x270-nand:64m(app),-(data) rdinit=/sbin/init root=mtd3 rootfstype=jffs2" + +FILES_kernel-image_cm-x270 = "" + +python do_compulab_image() { + import os + import os.path + import struct + + machine = bb.data.getVar('MACHINE', d, 1) + if machine == "cm-x270": + deploy_dir = bb.data.getVar('DEPLOY_DIR_IMAGE', d, 1) + kernel_file = os.path.join(deploy_dir, bb.data.expand('${KERNEL_IMAGE_BASE_NAME}', d) + '.bin') + img_file = os.path.join(deploy_dir, bb.data.expand('${KERNEL_IMAGE_BASE_NAME}', d) + '.cmx270') + + fo = open(img_file, 'wb') + + image_data = open(kernel_file, 'rb').read() + + # first write size into first 4 bytes + size_s = struct.pack('i', len(image_data)) + + # truncate size if we are running on a 64-bit host + size_s = size_s[:4] + + fo.write(size_s) + fo.write(image_data) + fo.close() + + os.chdir(deploy_dir) + link_file = bb.data.expand('${KERNEL_IMAGE_SYMLINK_NAME}', d) + '.cmx270' + img_file = bb.data.expand('${KERNEL_IMAGE_BASE_NAME}', d) + '.cmx270' + try: + os.unlink(link_file) + except: + pass + os.symlink(img_file, link_file) +} + +addtask compulab_image after do_deploy before do_package |