aboutsummaryrefslogtreecommitdiffstats
path: root/recipes/linux/linux
diff options
context:
space:
mode:
authorDenys Dmytriyenko <denis@denix.org>2009-03-17 14:32:59 -0400
committerDenys Dmytriyenko <denis@denix.org>2009-03-17 14:32:59 -0400
commit709c4d66e0b107ca606941b988bad717c0b45d9b (patch)
tree37ee08b1eb308f3b2b6426d5793545c38396b838 /recipes/linux/linux
parentfa6cd5a3b993f16c27de4ff82b42684516d433ba (diff)
downloadopenembedded-709c4d66e0b107ca606941b988bad717c0b45d9b.tar.gz
rename packages/ to recipes/ per earlier agreement
See links below for more details: http://thread.gmane.org/gmane.comp.handhelds.openembedded/21326 http://thread.gmane.org/gmane.comp.handhelds.openembedded/21816 Signed-off-by: Denys Dmytriyenko <denis@denix.org> Acked-by: Mike Westerhof <mwester@dls.net> Acked-by: Philip Balister <philip@balister.org> Acked-by: Khem Raj <raj.khem@gmail.com> Acked-by: Marcin Juszkiewicz <hrw@openembedded.org> Acked-by: Koen Kooi <koen@openembedded.org> Acked-by: Frans Meulenbroeks <fransmeulenbroeks@gmail.com>
Diffstat (limited to 'recipes/linux/linux')
-rw-r--r--recipes/linux/linux/acern30/defconfig1199
-rw-r--r--recipes/linux/linux/acern30/gcc4-fixes.patch97
-rw-r--r--recipes/linux/linux/acern30/gpio-sysfs.patch252
-rw-r--r--recipes/linux/linux/acern30/mmc-plus.patch17
-rw-r--r--recipes/linux/linux/acern30/n30-apm.patch73
-rw-r--r--recipes/linux/linux/acern30/n30-backlight.patch97
-rw-r--r--recipes/linux/linux/acern30/n30-batt.patch242
-rw-r--r--recipes/linux/linux/acern30/n30-buttons.patch100
-rw-r--r--recipes/linux/linux/acern30/n30-cleanup.patch30
-rw-r--r--recipes/linux/linux/acern30/n30-hardcode.patch158
-rw-r--r--recipes/linux/linux/acern30/n30-lcd.patch66
-rw-r--r--recipes/linux/linux/acern30/n30-mmc-power.patch24
-rw-r--r--recipes/linux/linux/acern30/n30-mmc-wprotect.patch54
-rw-r--r--recipes/linux/linux/acern30/n30-mmc.patch53
-rw-r--r--recipes/linux/linux/acern30/n30-nand-hack.patch32
-rw-r--r--recipes/linux/linux/acern30/n30-nand.patch97
-rw-r--r--recipes/linux/linux/acern30/n30-pm.patch296
-rw-r--r--recipes/linux/linux/acern30/n30-ts.patch43
-rw-r--r--recipes/linux/linux/acern30/n30-usbstart.patch59
-rw-r--r--recipes/linux/linux/acern30/n35.patch80
-rw-r--r--recipes/linux/linux/acern30/regdump.patch279
-rw-r--r--recipes/linux/linux/acern30/s3c2410-nand-pm.patch53
-rw-r--r--recipes/linux/linux/acern30/s3c2410_lcd-pm.c80
-rw-r--r--recipes/linux/linux/acern30/s3c2410_ts-pm.patch73
-rw-r--r--recipes/linux/linux/acern30/s3c2410fb-resume.patch13
-rw-r--r--recipes/linux/linux/acern30/s3c2410mci-pm.patch84
-rw-r--r--recipes/linux/linux/acern30/series27
-rw-r--r--recipes/linux/linux/acern30/spi.patch121
-rw-r--r--recipes/linux/linux/acern30/wingel-hacking.patch1146
-rw-r--r--recipes/linux/linux/alix/defconfig1776
-rw-r--r--recipes/linux/linux/alix/geode-mfgpt-clock-event-device-support.patch237
-rw-r--r--recipes/linux/linux/alix/geode-mfgpt-support-for-geode-class-machines.patch311
-rw-r--r--recipes/linux/linux/at32stk1000/defconfig849
-rw-r--r--recipes/linux/linux/at91sam9263ek/defconfig1184
-rw-r--r--recipes/linux/linux/atngw100/defconfig849
-rw-r--r--recipes/linux/linux/defconfig989
-rw-r--r--recipes/linux/linux/ep93xx/defconfig1176
-rw-r--r--recipes/linux/linux/i586-generic/defconfig2705
-rw-r--r--recipes/linux/linux/i686-generic/defconfig2705
-rw-r--r--recipes/linux/linux/kb9202/defconfig780
-rw-r--r--recipes/linux/linux/n2100/defconfig1843
-rw-r--r--recipes/linux/linux/n2100/n2100-r8169-parity.patch39
-rw-r--r--recipes/linux/linux/n2100/rtc-rs5c372-n2100.patch13
-rw-r--r--recipes/linux/linux/patch-2.6.28-gc32569
-rw-r--r--recipes/linux/linux/progear/defconfig1832
-rw-r--r--recipes/linux/linux/sarge-at91/2.6.21-sarge-kernel.patch238
-rw-r--r--recipes/linux/linux/sarge-at91/2.6.21-sarge-mmc.patch87
-rw-r--r--recipes/linux/linux/sarge-at91/2.6.21-sarge-phy.patch400
-rw-r--r--recipes/linux/linux/sarge-at91/defconfig1909
-rw-r--r--recipes/linux/linux/simpad/collie-kexec.patch13
-rw-r--r--recipes/linux/linux/simpad/connectplus-remove-ide-HACK.patch12
-rw-r--r--recipes/linux/linux/simpad/export_atags-r2.patch320
-rw-r--r--recipes/linux/linux/simpad/linux-2.6.21-SIMpad-GPIO-MMC-mod.patch1650
-rw-r--r--recipes/linux/linux/simpad/linux-2.6.21-SIMpad-battery-old-way-but-also-with-sysfs.patch571
-rw-r--r--recipes/linux/linux/simpad/linux-2.6.21-SIMpad-cs3-simpad.patch184
-rw-r--r--recipes/linux/linux/simpad/linux-2.6.21-SIMpad-mq200.patch2511
-rw-r--r--recipes/linux/linux/simpad/linux-2.6.21-SIMpad-net-shared-irq.patch63
-rw-r--r--recipes/linux/linux/simpad/linux-2.6.21-SIMpad-pcmcia.patch162
-rw-r--r--recipes/linux/linux/simpad/linux-2.6.21-SIMpad-serial-gpio_keys-and-cs3-ro.patch332
-rw-r--r--recipes/linux/linux/simpad/linux-2.6.21-SIMpad-ucb1x00-switches.patch359
-rw-r--r--recipes/linux/linux/simpad/linux-2.6.21-SIMpad-ucb1x00-ts-supend-and-accuracy.patch121
-rw-r--r--recipes/linux/linux/simpad/linux-2.6.21-SIMpad-usb-gadget.patch3329
-rw-r--r--recipes/linux/linux/simpad/linux-2.6.24-SIMpad-GPIO-MMC-mod.patch1699
-rw-r--r--recipes/linux/linux/simpad/linux-2.6.24-SIMpad-battery-old-way-but-also-with-sysfs.patch571
-rw-r--r--recipes/linux/linux/simpad/linux-2.6.24-SIMpad-cs3-simpad.patch184
-rw-r--r--recipes/linux/linux/simpad/linux-2.6.24-SIMpad-hostap_cs-shared-irq.patch106
-rw-r--r--recipes/linux/linux/simpad/linux-2.6.24-SIMpad-mq200.patch2513
-rw-r--r--recipes/linux/linux/simpad/linux-2.6.24-SIMpad-orinoco_cs-shared-irq.patch21
-rw-r--r--recipes/linux/linux/simpad/linux-2.6.24-SIMpad-pcmcia.patch209
-rw-r--r--recipes/linux/linux/simpad/linux-2.6.24-SIMpad-rtc-sa1100.patch68
-rw-r--r--recipes/linux/linux/simpad/linux-2.6.24-SIMpad-serial-gpio_keys-and-cs3-ro.patch.v2358
-rw-r--r--recipes/linux/linux/simpad/linux-2.6.24-SIMpad-ucb1x00-audio.patch1622
-rw-r--r--recipes/linux/linux/simpad/linux-2.6.24-SIMpad-ucb1x00-switches.patch359
-rw-r--r--recipes/linux/linux/simpad/linux-2.6.24-SIMpad-ucb1x00-ts-supend-and-accuracy.patch121
-rw-r--r--recipes/linux/linux/simpad/linux-2.6.27-SIMpad-GPIO-MMC-mod.patch1701
-rw-r--r--recipes/linux/linux/simpad/linux-2.6.27-SIMpad-battery-old-way-but-also-with-sysfs.patch577
-rw-r--r--recipes/linux/linux/simpad/linux-2.6.27-SIMpad-cs3-simpad.patch192
-rw-r--r--recipes/linux/linux/simpad/linux-2.6.27-SIMpad-mq200.patch2640
-rw-r--r--recipes/linux/linux/simpad/linux-2.6.27-SIMpad-pcmcia.patch226
-rw-r--r--recipes/linux/linux/simpad/linux-2.6.27-SIMpad-serial-gpio_keys-and-cs3-ro.patch.v2358
-rw-r--r--recipes/linux/linux/simpad/linux-2.6.27-SIMpad-ucb1x00-switches.patch362
-rw-r--r--recipes/linux/linux/simpad/linux-2.6.27-SIMpad-ucb1x00-ts-supend-and-accuracy.patch105
-rw-r--r--recipes/linux/linux/tosa/defconfig1988
-rw-r--r--recipes/linux/linux/ts72xx/defconfig1184
-rw-r--r--recipes/linux/linux/vmware/defconfig1242
-rw-r--r--recipes/linux/linux/vortex86sx/defconfig2130
-rw-r--r--recipes/linux/linux/x86/defconfig3283
87 files changed, 90882 insertions, 0 deletions
diff --git a/recipes/linux/linux/acern30/defconfig b/recipes/linux/linux/acern30/defconfig
new file mode 100644
index 0000000000..860dc9b12c
--- /dev/null
+++ b/recipes/linux/linux/acern30/defconfig
@@ -0,0 +1,1199 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.14-h1940
+# Mon Jan 9 17:37:51 2006
+#
+CONFIG_ARM=y
+CONFIG_MMU=y
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+# CONFIG_BASE_FULL is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_SHMEM is not set
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_TINY_SHMEM=y
+CONFIG_BASE_SMALL=1
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# System Type
+#
+# 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_CAMELOT is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_IOP3XX is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+CONFIG_ARCH_S3C2410=y
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_AAEC2000 is not set
+
+#
+# S3C24XX Implementations
+#
+# CONFIG_MACH_ANUBIS is not set
+# CONFIG_ARCH_BAST is not set
+CONFIG_ARCH_H1940=y
+CONFIG_MACH_N30=y
+CONFIG_MACH_N35=y
+# CONFIG_ARCH_SMDK2410 is not set
+# CONFIG_ARCH_S3C2440 is not set
+# CONFIG_MACH_VR1000 is not set
+# CONFIG_MACH_RX3715 is not set
+# CONFIG_MACH_OTOM is not set
+# CONFIG_MACH_NEXCODER_2440 is not set
+CONFIG_CPU_S3C2410=y
+
+#
+# S3C2410 Boot
+#
+
+#
+# S3C2410 Setup
+#
+CONFIG_S3C2410_DMA=y
+# CONFIG_S3C2410_DMA_DEBUG is not set
+CONFIG_S3C2410_PM_DEBUG=y
+CONFIG_S3C2410_PM_CHECK=y
+CONFIG_S3C2410_PM_CHECK_CHUNKSIZE=64
+CONFIG_S3C2410_LOWLEVEL_UART_PORT=0
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM920T=y
+CONFIG_CPU_32v4=y
+CONFIG_CPU_ABRT_EV4T=y
+CONFIG_CPU_CACHE_V4WT=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+
+#
+# Processor Features
+#
+# CONFIG_ARM_THUMB is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+
+#
+# Bus support
+#
+CONFIG_ISA_DMA_API=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_PREEMPT is not set
+CONFIG_NO_IDLE_HZ=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_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="rw root=/dev/ram console=tty0 console=ttySAC2,115200n8 verbose panic=30"
+# 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=y
+CONFIG_APM=y
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 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
+# 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_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+CONFIG_IRDA=y
+
+#
+# IrDA protocols
+#
+CONFIG_IRLAN=y
+CONFIG_IRCOMM=y
+# CONFIG_IRDA_ULTRA is not set
+
+#
+# IrDA options
+#
+CONFIG_IRDA_CACHE_LAST_LSAP=y
+CONFIG_IRDA_FAST_RR=y
+CONFIG_IRDA_DEBUG=y
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+CONFIG_IRTTY_SIR=y
+
+#
+# Dongle support
+#
+# CONFIG_DONGLE is not set
+
+#
+# Old SIR device drivers
+#
+# CONFIG_IRPORT_SIR is not set
+
+#
+# Old Serial dongle support
+#
+
+#
+# FIR device drivers
+#
+# CONFIG_USB_IRDA is not set
+# CONFIG_SIGMATEL_FIR is not set
+# CONFIG_NSC_FIR is not set
+# CONFIG_WINBOND_FIR is not set
+# CONFIG_SMC_IRCC_FIR is not set
+# CONFIG_ALI_FIR is not set
+# CONFIG_VIA_FIR is not set
+CONFIG_BT=y
+CONFIG_BT_L2CAP=y
+CONFIG_BT_SCO=y
+CONFIG_BT_RFCOMM=y
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=y
+# CONFIG_BT_BNEP_MC_FILTER is not set
+# CONFIG_BT_BNEP_PROTO_FILTER is not set
+CONFIG_BT_HIDP=y
+
+#
+# Bluetooth device drivers
+#
+# CONFIG_BT_HCIUSB is not set
+CONFIG_BT_HCIUART=y
+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_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER 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 is not set
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD 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=y
+CONFIG_MTD_NAND_VERIFY_WRITE=y
+CONFIG_MTD_NAND_IDS=y
+CONFIG_MTD_NAND_S3C2410=y
+# CONFIG_MTD_NAND_S3C2410_DEBUG is not set
+CONFIG_MTD_NAND_S3C2410_HWECC=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_NANDSIM 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 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_INITRD=y
+# CONFIG_CDROM_PKTCDVD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# 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 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=y
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# PHY device support
+#
+
+#
+# Ethernet (10 or 100Mbit)
+#
+# CONFIG_NET_ETHERNET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO 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
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=320
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=240
+# 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_S3C2410_BUTTONS=y
+CONFIG_INPUT_MOUSE=y
+# CONFIG_MOUSE_PS2 is not set
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_INPUT_JOYSTICK is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_S3C2410=y
+# CONFIG_TOUCHSCREEN_S3C2410_DEBUG 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_INPUT_MISC=y
+CONFIG_INPUT_UINPUT=y
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_LIBPS2 is not set
+# 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_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_S3C2410=y
+CONFIG_SERIAL_S3C2410_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=10
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+CONFIG_S3C2410_RTC=y
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+
+#
+# I2C support
+#
+CONFIG_I2C=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_PARPORT_LIGHT is not set
+CONFIG_I2C_S3C2410=y
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_PCA_ISA is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 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_RTC8564 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_RTC_X1205_I2C 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
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 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_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_MAX1619 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83792D 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
+
+#
+# Misc devices
+#
+
+#
+# Multimedia Capabilities Port drivers
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+CONFIG_FB_SOFT_CURSOR=y
+# CONFIG_FB_MACMODES is not set
+CONFIG_FB_MODE_HELPERS=y
+# CONFIG_FB_TILEBLITTING is not set
+# CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_S3C2410=y
+# CONFIG_FB_S3C2410_DEBUG 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_FONTS=y
+# CONFIG_FONT_8x8 is not set
+# CONFIG_FONT_8x16 is not set
+# 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_CLEAN_4x6 is not set
+CONFIG_FONT_CLEAN_5x8=y
+# 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=y
+CONFIG_LOGO_LINUX_CLUT224=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_DEVICE=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_LCD_DEVICE=y
+CONFIG_BACKLIGHT_S3C2410=y
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+CONFIG_SND_SEQUENCER=y
+# CONFIG_SND_SEQ_DUMMY is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+CONFIG_SND_SEQUENCER_OSS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_VIRMIDI 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
+#
+
+#
+# USB devices
+#
+# CONFIG_SND_USB_AUDIO is not set
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+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_SUSPEND=y
+# 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 is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_SL811_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set
+# 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 is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+CONFIG_USB_HIDINPUT=y
+# 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_MTOUCH is not set
+# CONFIG_USB_ITMTOUCH is not set
+# CONFIG_USB_EGALAX is not set
+# CONFIG_USB_YEALINK is not set
+# CONFIG_USB_XPAD is not set
+# CONFIG_USB_ATI_REMOTE 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
+
+#
+# USB Multimedia devices
+#
+# CONFIG_USB_DABUSB is not set
+
+#
+# Video4Linux support is needed for USB Multimedia device support
+#
+
+#
+# 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 is not set
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+CONFIG_USB_SERIAL=y
+# CONFIG_USB_SERIAL_CONSOLE is not set
+CONFIG_USB_SERIAL_GENERIC=y
+# CONFIG_USB_SERIAL_AIRPRIME 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_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 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_NOKIA_DKU2 is not set
+CONFIG_USB_SERIAL_PL2303=y
+# CONFIG_USB_SERIAL_HP4X is not set
+# CONFIG_USB_SERIAL_SAFE 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_OMNINET is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 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_CYTHERM is not set
+# CONFIG_USB_PHIDGETKIT is not set
+# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_LD 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 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_S3C2410=y
+CONFIG_USB_S3C2410=y
+# CONFIG_USB_S3C2410_DEBUG 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=y
+CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
+
+#
+# MMC/SD Card support
+#
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_BLOCK=y
+# CONFIG_MMC_WBSD is not set
+CONFIG_MMC_S3C2410=y
+
+#
+# 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_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_FS_XATTR 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_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=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_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_RELAYFS_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_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_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=y
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 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=y
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOG_BUF_SHIFT=16
+# CONFIG_DETECT_SOFTLOCKUP is not set
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_FS is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_WAITQ is not set
+# CONFIG_DEBUG_ERRORS is not set
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_ICEDCC is not set
+CONFIG_DEBUG_S3C2410_PORT=y
+CONFIG_DEBUG_S3C2410_UART=0
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=y
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
diff --git a/recipes/linux/linux/acern30/gcc4-fixes.patch b/recipes/linux/linux/acern30/gcc4-fixes.patch
new file mode 100644
index 0000000000..722bca7c73
--- /dev/null
+++ b/recipes/linux/linux/acern30/gcc4-fixes.patch
@@ -0,0 +1,97 @@
+--- linux-2.6.14/arch/arm/mm/alignment.c.org 2007-03-06 22:50:23.000000000 +0000
++++ linux-2.6.14/arch/arm/mm/alignment.c 2007-03-06 22:49:21.000000000 +0000
+@@ -110,7 +110,7 @@
+ return len;
+ }
+
+-static int proc_alignment_write(struct file *file, const char __user *buffer,
++static int proc_alignment_write(struct file *file, /*const*/ char __user *buffer,
+ unsigned long count, void *data)
+ {
+ char mode;
+--- linux-2.6.14/lib/bitmap.c.org 2005-10-28 00:02:08.000000000 +0000
++++ linux-2.6.14/lib/bitmap.c 2007-03-07 00:49:39.000000000 +0000
+@@ -345,11 +345,12 @@
+ * characters and for grouping errors such as "1,,5", ",44", "," and "".
+ * Leading and trailing whitespace accepted, but not embedded whitespace.
+ */
+-int bitmap_parse(const char __user *ubuf, unsigned int ubuflen,
++int bitmap_parse(const char __user *_ubuf, unsigned int ubuflen,
+ unsigned long *maskp, int nmaskbits)
+ {
+ int c, old_c, totaldigits, ndigits, nchunks, nbits;
+ u32 chunk;
++ char __user *ubuf = _ubuf;
+
+ bitmap_zero(maskp, nmaskbits);
+
+--- linux-2.6.14/arch/arm/nwfpe/fpa11_cpdt.c.org 2005-10-28 00:02:08.000000000 +0000
++++ linux-2.6.14/arch/arm/nwfpe/fpa11_cpdt.c 2007-03-06 22:52:09.000000000 +0000
+@@ -29,14 +29,14 @@
+
+ #include <asm/uaccess.h>
+
+-static inline void loadSingle(const unsigned int Fn, const unsigned int __user *pMem)
++static inline void loadSingle(const unsigned int Fn, /*const*/ unsigned int __user *pMem)
+ {
+ FPA11 *fpa11 = GET_FPA11();
+ fpa11->fType[Fn] = typeSingle;
+ get_user(fpa11->fpreg[Fn].fSingle, pMem);
+ }
+
+-static inline void loadDouble(const unsigned int Fn, const unsigned int __user *pMem)
++static inline void loadDouble(const unsigned int Fn, /*const*/ unsigned int __user *pMem)
+ {
+ FPA11 *fpa11 = GET_FPA11();
+ unsigned int *p;
+@@ -52,7 +52,7 @@
+ }
+
+ #ifdef CONFIG_FPE_NWFPE_XP
+-static inline void loadExtended(const unsigned int Fn, const unsigned int __user *pMem)
++static inline void loadExtended(const unsigned int Fn, /*const*/ unsigned int __user *pMem)
+ {
+ FPA11 *fpa11 = GET_FPA11();
+ unsigned int *p;
+@@ -64,7 +64,7 @@
+ }
+ #endif
+
+-static inline void loadMultiple(const unsigned int Fn, const unsigned int __user *pMem)
++static inline void loadMultiple(const unsigned int Fn, /*const*/ unsigned int __user *pMem)
+ {
+ FPA11 *fpa11 = GET_FPA11();
+ register unsigned int *p;
+--- linux-2.6.14/fs/proc/proc_misc.c.org 2005-10-28 00:02:08.000000000 +0000
++++ linux-2.6.14/fs/proc/proc_misc.c 2007-03-06 23:17:01.000000000 +0000
+@@ -535,7 +535,7 @@
+ /*
+ * writing 'C' to /proc/sysrq-trigger is like sysrq-C
+ */
+-static ssize_t write_sysrq_trigger(struct file *file, const char __user *buf,
++static ssize_t write_sysrq_trigger(struct file *file, /*const*/ char __user *buf,
+ size_t count, loff_t *ppos)
+ {
+ if (count) {
+--- linux-2.6.14/drivers/char/vc_screen.c.org 2007-03-06 22:43:07.000000000 +0000
++++ linux-2.6.14/drivers/char/vc_screen.c 2007-03-07 00:02:25.000000000 +0000
+@@ -419,7 +419,7 @@
+ while (this_round > 1) {
+ unsigned short w;
+
+- w = get_unaligned(((const unsigned short *)con_buf0));
++ w = get_unaligned(((/*const*/ unsigned short *)con_buf0));
+ vcs_scr_writew(vc, w, org++);
+ con_buf0 += 2;
+ this_round -= 2;
+--- linux-2.6.14/drivers/input/mousedev.c.org 2007-03-07 01:28:18.000000000 +0000
++++ linux-2.6.14/drivers/input/mousedev.c 2007-03-07 01:37:01.000000000 +0000
+@@ -495,7 +495,7 @@
+ }
+
+
+-static ssize_t mousedev_write(struct file * file, const char __user * buffer, size_t count, loff_t *ppos)
++static ssize_t mousedev_write(struct file * file, /*const*/ char __user * buffer, size_t count, loff_t *ppos)
+ {
+ struct mousedev_list *list = file->private_data;
+ unsigned char c;
diff --git a/recipes/linux/linux/acern30/gpio-sysfs.patch b/recipes/linux/linux/acern30/gpio-sysfs.patch
new file mode 100644
index 0000000000..b3fde0f9d6
--- /dev/null
+++ b/recipes/linux/linux/acern30/gpio-sysfs.patch
@@ -0,0 +1,252 @@
+This patch adds a lot of sysfs entries for the different GPIO lines.
+It allows me to poke at different parts of the hardware to see what
+happens. This allowed me to discover the Bluetooth cutoff switch for
+example.
+
+Index: linux-2.6.14/arch/arm/mach-s3c2410/Makefile
+===================================================================
+--- linux-2.6.14.orig/arch/arm/mach-s3c2410/Makefile
++++ linux-2.6.14/arch/arm/mach-s3c2410/Makefile
+@@ -42,3 +42,5 @@ obj-$(CONFIG_MACH_VR1000) += mach-vr1000
+ obj-$(CONFIG_MACH_RX3715) += mach-rx3715.o
+ obj-$(CONFIG_MACH_OTOM) += mach-otom.o
+ obj-$(CONFIG_MACH_NEXCODER_2440) += mach-nexcoder.o
++
++obj-y += gpio-sysfs.o
+Index: linux-2.6.14/arch/arm/mach-s3c2410/gpio-sysfs.c
+===================================================================
+--- /dev/null
++++ linux-2.6.14/arch/arm/mach-s3c2410/gpio-sysfs.c
+@@ -0,0 +1,232 @@
++#include <linux/version.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/device.h>
++#include <linux/backlight.h>
++#include <linux/notifier.h>
++#include <linux/ctype.h>
++#include <linux/err.h>
++#include <linux/fb.h>
++#include <asm/bug.h>
++
++#include <asm/arch/regs-gpio.h>
++
++#include <asm/arch/regs-clock.h>
++
++static ssize_t s3c2410_gpio_name_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct platform_device *pdev = to_platform_device(dev);
++
++ return snprintf(buf, PAGE_SIZE, "%d\n", pdev->id);
++}
++
++static ssize_t s3c2410_gpio_val_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct platform_device *pdev = to_platform_device(dev);
++
++ return snprintf(buf, PAGE_SIZE, "%d\n",
++ s3c2410_gpio_getpin(pdev->id) ? 1 : 0);
++}
++
++static ssize_t s3c2410_gpio_val_store(struct device *dev,
++ struct device_attribute *attr,
++ const char *buf, size_t count)
++{
++ struct platform_device *pdev = to_platform_device(dev);
++ int val;
++ char *endp;
++
++ val = simple_strtoul(buf, &endp, 0);
++ if (*endp && !isspace(*endp))
++ return -EINVAL;
++
++ s3c2410_gpio_setpin(pdev->id, val ? 1 : 0);
++
++ return count;
++}
++
++static DEVICE_ATTR(name, 0444,
++ s3c2410_gpio_name_show,
++ NULL);
++
++static DEVICE_ATTR(val, 0666,
++ s3c2410_gpio_val_show,
++ s3c2410_gpio_val_store);
++
++
++static int __init s3c2410_gpio_probe(struct device *dev)
++{
++ device_create_file(dev, &dev_attr_name);
++ device_create_file(dev, &dev_attr_val);
++ return 0;
++}
++
++static int s3c2410_gpio_remove(struct device *dev)
++{
++ return 0;
++}
++
++static struct device_driver s3c2410_gpio_driver = {
++ .name = "s3c2410-gpio",
++ .bus = &platform_bus_type,
++ .probe = s3c2410_gpio_probe,
++ .remove = s3c2410_gpio_remove,
++};
++
++static struct platform_device s3c_device_gpio[32 * 8];
++
++static ssize_t s3c2410_clkslow_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ unsigned long clkslow = __raw_readl(S3C2410_CLKSLOW);
++
++ return snprintf(buf, PAGE_SIZE, "0x%08lx\n", clkslow);
++}
++
++static ssize_t s3c2410_clkslow_store(struct device *dev,
++ struct device_attribute *attr,
++ const char *buf, size_t count)
++{
++ unsigned long val;
++ char *endp;
++
++ val = simple_strtoul(buf, &endp, 0);
++ if (*endp && !isspace(*endp))
++ return -EINVAL;
++
++ printk("CLKSLOW <= 0x%lx\n", val);
++
++ __raw_writel(val, S3C2410_CLKSLOW);
++
++ return count;
++}
++
++static DEVICE_ATTR(clkslow, 0666,
++ s3c2410_clkslow_show,
++ s3c2410_clkslow_store);
++
++static ssize_t s3c2410_clkcon_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ unsigned long clkclkcon = __raw_readl(S3C2410_CLKCON);
++
++ return snprintf(buf, PAGE_SIZE, "0x%08lx\n", clkclkcon);
++}
++
++static ssize_t s3c2410_clkcon_store(struct device *dev,
++ struct device_attribute *attr,
++ const char *buf, size_t count)
++{
++ unsigned long val;
++ char *endp;
++
++ val = simple_strtoul(buf, &endp, 0);
++ if (*endp && !isspace(*endp))
++ return -EINVAL;
++
++ printk("CLKCON <= 0x%lx\n", val);
++
++ __raw_writel(val, S3C2410_CLKCON);
++
++ return count;
++}
++
++static DEVICE_ATTR(clkcon, 0666,
++ s3c2410_clkcon_show,
++ s3c2410_clkcon_store);
++
++static ssize_t s3c2410_misccr_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ unsigned long misccr = __raw_readl(S3C2410_MISCCR);
++
++ return snprintf(buf, PAGE_SIZE, "0x%08lx\n", misccr);
++}
++
++static ssize_t s3c2410_misccr_store(struct device *dev,
++ struct device_attribute *attr,
++ const char *buf, size_t count)
++{
++ unsigned long val;
++ char *endp;
++
++ val = simple_strtoul(buf, &endp, 0);
++ if (*endp && !isspace(*endp))
++ return -EINVAL;
++
++ printk("MISCCR <= 0x%lx\n", val);
++
++ __raw_writel(val, S3C2410_MISCCR);
++
++ return count;
++}
++
++static DEVICE_ATTR(misccr, 0666,
++ s3c2410_misccr_show,
++ s3c2410_misccr_store);
++
++static int __init s3c2410_regs_probe(struct device *dev)
++{
++ device_create_file(dev, &dev_attr_clkslow);
++ device_create_file(dev, &dev_attr_clkcon);
++ device_create_file(dev, &dev_attr_misccr);
++ return 0;
++}
++
++static int s3c2410_regs_remove(struct device *dev)
++{
++ return 0;
++}
++
++
++static struct device_driver s3c2410_regs_driver = {
++ .name = "s3c2410-regs",
++ .bus = &platform_bus_type,
++ .probe = s3c2410_regs_probe,
++ .remove = s3c2410_regs_remove,
++};
++
++static struct platform_device s3c_device_regs = {
++ .name = "s3c2410-regs",
++ .id = -1,
++};
++
++static int __init s3c2410_gpio_init(void)
++{
++ int i;
++
++ for (i = 0; i < ARRAY_SIZE(s3c_device_gpio); i++) {
++ s3c_device_gpio[i].name = "s3c2410-gpio";
++ s3c_device_gpio[i].id = i;
++ platform_device_register(&s3c_device_gpio[i]);
++ }
++
++ driver_register(&s3c2410_gpio_driver);
++ driver_register(&s3c2410_regs_driver);
++
++ platform_device_register(&s3c_device_regs);
++
++ return 0;
++}
++
++static void __exit s3c2410_gpio_cleanup(void)
++{
++ driver_unregister(&s3c2410_regs_driver);
++ driver_unregister(&s3c2410_gpio_driver);
++}
++
++module_init(s3c2410_gpio_init);
++module_exit(s3c2410_gpio_cleanup);
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Christer Weinigel <christer@weinigel.se>");
++MODULE_DESCRIPTION("S3C2410 GPIO Driver");
++
++/*
++ Local variables:
++ compile-command: "make -k -C ../../../.. linux "
++ c-basic-offset: 8
++ End:
++*/
diff --git a/recipes/linux/linux/acern30/mmc-plus.patch b/recipes/linux/linux/acern30/mmc-plus.patch
new file mode 100644
index 0000000000..d88ac531cf
--- /dev/null
+++ b/recipes/linux/linux/acern30/mmc-plus.patch
@@ -0,0 +1,17 @@
+Treat MMCA version 4 cards a version 3 cards. It seem to work for me,
+but it may break things horribly.
+
+So you may not want to use this patch.
+
+Index: linux-2.6.14/drivers/mmc/mmc.c
+===================================================================
+--- linux-2.6.14.orig/drivers/mmc/mmc.c
++++ linux-2.6.14/drivers/mmc/mmc.c
+@@ -495,6 +495,7 @@ static void mmc_decode_cid(struct mmc_ca
+
+ case 2: /* MMC v2.0 - v2.2 */
+ case 3: /* MMC v3.1 - v3.3 */
++ case 4: /* MMC Plus? */
+ card->cid.manfid = UNSTUFF_BITS(resp, 120, 8);
+ card->cid.oemid = UNSTUFF_BITS(resp, 104, 16);
+ card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8);
diff --git a/recipes/linux/linux/acern30/n30-apm.patch b/recipes/linux/linux/acern30/n30-apm.patch
new file mode 100644
index 0000000000..00b34c9a46
--- /dev/null
+++ b/recipes/linux/linux/acern30/n30-apm.patch
@@ -0,0 +1,73 @@
+Implement a apm_get_power_status handler for the n30. The handler
+gets the battery charge from the msp430 chip using i2c and sets the ac
+line information based on GPG1 (charger power) and GPC7 (usb power).
+
+Index: linux-2.6.14/arch/arm/mach-s3c2410/mach-n30.c
+===================================================================
+--- linux-2.6.14.orig/arch/arm/mach-s3c2410/mach-n30.c
++++ linux-2.6.14/arch/arm/mach-s3c2410/mach-n30.c
+@@ -31,6 +31,7 @@
+ #include <linux/delay.h>
+ #include <linux/device.h>
+ #include <linux/kthread.h>
++#include <linux/i2c.h>
+
+ #include <linux/mmc/protocol.h>
+ #include <linux/mtd/mtd.h>
+@@ -44,6 +45,7 @@
+ #include <asm/hardware/iomd.h>
+ #include <asm/io.h>
+ #include <asm/irq.h>
++#include <asm/apm.h>
+ #include <asm/mach-types.h>
+
+ #include <asm/arch/regs-serial.h>
+@@ -527,6 +529,37 @@ static int n30_usbstart_thread(void *unu
+ return 0;
+ }
+
++#ifdef CONFIG_APM
++static void n30_get_power_status(struct apm_power_info *info)
++{
++#ifdef CONFIG_I2C_S3C2410
++ u8 charge;
++ struct i2c_adapter *adap;
++ struct i2c_msg msg[] = {
++ { .addr = 0x0b, .flags = I2C_M_RD, .buf = &charge, .len = 1 }
++ };
++
++ if ((adap = i2c_get_adapter(0)) != NULL) {
++ if (i2c_transfer(adap, msg, 1) == 1)
++ info->battery_life = charge;
++ i2c_put_adapter(adap);
++ }
++#endif
++
++ if (s3c2410_gpio_getpin(S3C2410_GPC7))
++ info->ac_line_status = 0x01; /* on charger power */
++ else if (s3c2410_gpio_getpin(S3C2410_GPG1))
++ info->ac_line_status = 0x02; /* on USB power */
++ else
++ info->ac_line_status = 0x00; /* on battery power */
++
++ /* TODO I could put some values in these variables based on
++ * the battery life and the ac_line_status. --wingel */
++ info->battery_status = 0xff;
++ info->battery_flag = 0xff;
++}
++#endif
++
+ static void __init n30_init(void)
+ {
+ s3c24xx_fb_set_platdata(&n30_lcdcfg);
+@@ -550,6 +583,10 @@ static void __init n30_init(void)
+ s3c2410_gpio_setpin(S3C2410_GPC5, 1);
+
+ kthread_run(n30_usbstart_thread, NULL, "n30_usbstart");
++
++#ifdef CONFIG_APM
++ apm_get_power_status = n30_get_power_status;
++#endif
+ }
+
+ MACHINE_START(N30, "Acer-N30")
diff --git a/recipes/linux/linux/acern30/n30-backlight.patch b/recipes/linux/linux/acern30/n30-backlight.patch
new file mode 100644
index 0000000000..2b339960f7
--- /dev/null
+++ b/recipes/linux/linux/acern30/n30-backlight.patch
@@ -0,0 +1,97 @@
+This patch adds a few functions to control the backlight on the n30.
+
+Index: linux-2.6.14/arch/arm/mach-s3c2410/mach-n30.c
+===================================================================
+--- linux-2.6.14.orig/arch/arm/mach-s3c2410/mach-n30.c
++++ linux-2.6.14/arch/arm/mach-s3c2410/mach-n30.c
+@@ -45,8 +45,10 @@
+ #include <asm/arch/regs-serial.h>
+ #include <asm/arch/regs-gpio.h>
+ #include <asm/arch/regs-lcd.h>
++#include <asm/arch/regs-timer.h>
+ #include <asm/arch/iic.h>
+ #include <asm/arch/fb.h>
++#include <asm/arch/lcd.h>
+
+ #include <linux/serial_core.h>
+
+@@ -121,9 +123,71 @@ static struct s3c2410fb_mach_info n30_lc
+ .bpp= {16,16,16},
+ };
+
++static void n30_backlight_power(int on)
++{
++ s3c2410_gpio_pullup(S3C2410_GPB1, 1);
++ s3c2410_gpio_cfgpin(S3C2410_GPB1, S3C2410_GPB1_OUTP);
++ s3c2410_gpio_setpin(S3C2410_GPB1, on);
++}
++
++static void n30_lcd_power(int on)
++{
++ /* Turning these off will save about 10mA */
++ s3c2410_gpio_setpin(S3C2410_GPB8, on); /* CLOCK driver? */
++ s3c2410_gpio_setpin(S3C2410_GPB9, on); /* VSYNC driver? */
++ s3c2410_gpio_setpin(S3C2410_GPB10, on); /* HSYYNC driver? */
++}
++
++#define BRIGHTNESS_MAX 28
++#define BRIGHTNESS_OFFSET 5
++
++static void n30_set_brightness(int level)
++{
++ unsigned long tcmpb0;
++ unsigned long tcon;
++
++ if (level < 0)
++ level = 0;
++
++ if (level > BRIGHTNESS_MAX)
++ level = BRIGHTNESS_MAX;
++
++ tcmpb0 = level ? level + BRIGHTNESS_OFFSET : 0;
++
++ printk("brightness level %d, tcmpb0 %lu\n", level, tcmpb0);
++
++ /* configure power on/off */
++ n30_backlight_power(level ? 1 : 0);
++
++ writel(34, S3C2410_TCNTB(0));
++
++ tcon = readl(S3C2410_TCON);
++ tcon &= ~0x0F;
++ tcon |= S3C2410_TCON_T0RELOAD;
++ tcon |= S3C2410_TCON_T0MANUALUPD;
++
++ writel(tcon, S3C2410_TCON);
++ writel(0x22, S3C2410_TCNTB(0));
++ writel(tcmpb0, S3C2410_TCMPB(0));
++
++ /* start the timer running */
++ tcon |= S3C2410_TCON_T0START;
++ tcon &= ~S3C2410_TCON_T0MANUALUPD;
++ writel(tcon, S3C2410_TCON);
++}
++
++static struct s3c2410_bl_mach_info n30_blcfg __initdata = {
++ .backlight_max = BRIGHTNESS_MAX,
++ .backlight_default = BRIGHTNESS_MAX / 2,
++ .backlight_power = n30_backlight_power,
++ .set_brightness = n30_set_brightness,
++ .lcd_power = n30_lcd_power
++};
++
+ static struct platform_device *n30_devices[] __initdata = {
+ &s3c_device_usb,
+ &s3c_device_lcd,
++ &s3c_device_bl,
+ &s3c_device_wdt,
+ &s3c_device_i2c,
+ &s3c_device_iis,
+@@ -160,6 +224,7 @@ static void __init n30_init_irq(void)
+ static void __init n30_init(void)
+ {
+ s3c24xx_fb_set_platdata(&n30_lcdcfg);
++ set_s3c2410bl_info(&n30_blcfg);
+
+ s3c_device_i2c.dev.platform_data = &n30_i2ccfg;
+
diff --git a/recipes/linux/linux/acern30/n30-batt.patch b/recipes/linux/linux/acern30/n30-batt.patch
new file mode 100644
index 0000000000..e5eb9e7812
--- /dev/null
+++ b/recipes/linux/linux/acern30/n30-batt.patch
@@ -0,0 +1,242 @@
+A battery controller i2c driver for the n30.
+
+I don't use this driver any more, it was much nicer to use the ARM APM
+emulation to expose this data.
+
+Index: linux-2.6.14/drivers/hwmon/Kconfig
+===================================================================
+--- linux-2.6.14.orig/drivers/hwmon/Kconfig
++++ linux-2.6.14/drivers/hwmon/Kconfig
+@@ -290,6 +290,16 @@
+ This driver can also be built as a module. If so, the module
+ will be called max1619.
+
++config SENSORS_N30_BATT
++ tristate "Acer N30 Battery Controller"
++ depends on HWMON && I2C && MACH_N30
++ help
++ If you say yes here you get support for the battery controller
++ found inside the Acer N30 PDA.
++
++ This driver can also be built as a module. If so, the module
++ will be called n30_batt.
++
+ config SENSORS_PC87360
+ tristate "National Semiconductor PC87360 family"
+ depends on HWMON && I2C && EXPERIMENTAL
+Index: linux-2.6.14/drivers/hwmon/Makefile
+===================================================================
+--- linux-2.6.14.orig/drivers/hwmon/Makefile
++++ linux-2.6.14/drivers/hwmon/Makefile
+@@ -35,6 +35,7 @@
+ obj-$(CONFIG_SENSORS_LM90) += lm90.o
+ obj-$(CONFIG_SENSORS_LM92) += lm92.o
+ obj-$(CONFIG_SENSORS_MAX1619) += max1619.o
++obj-$(CONFIG_SENSORS_N30_BATT) += n30_batt.o
+ obj-$(CONFIG_SENSORS_PC87360) += pc87360.o
+ obj-$(CONFIG_SENSORS_SIS5595) += sis5595.o
+ obj-$(CONFIG_SENSORS_SMSC47B397)+= smsc47b397.o
+Index: linux-2.6.14/drivers/hwmon/n30_batt.c
+===================================================================
+--- linux-2.6.14.orig/drivers/hwmon/n30_batt.c
++++ linux-2.6.14/drivers/hwmon/n30_batt.c
+@@ -0,0 +1,199 @@
++/*
++ * n30_batt.c - Support for the Acer N30 Battery Controller
++ * Copyright (c) 2005 Christer Weinigel <christer@weinigel.se>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++*/
++
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/slab.h>
++#include <linux/i2c.h>
++#include <linux/hwmon.h>
++#include <asm/mach-types.h>
++#include <asm/apm.h>
++
++static unsigned short normal_i2c[] = { I2C_CLIENT_END, I2C_CLIENT_END };
++static unsigned short probe[] = { I2C_CLIENT_END, I2C_CLIENT_END };
++static unsigned short ignore[] = { I2C_CLIENT_END, I2C_CLIENT_END };
++static unsigned short force[] = { -1, 0x0b, I2C_CLIENT_END, I2C_CLIENT_END };
++static unsigned short *forces[] = { force, NULL };
++
++static struct i2c_client_address_data addr_data = {
++ .normal_i2c = normal_i2c,
++ .probe = probe,
++ .ignore = ignore,
++ .forces = forces,
++};
++
++struct n30_batt_data {
++ struct i2c_client client;
++ struct semaphore update_lock;
++ unsigned long last_updated; /* last update in jiffies */
++ u8 charge;
++};
++
++static struct n30_batt_data *n30_batt_update_device(struct device *dev)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ struct n30_batt_data *data = i2c_get_clientdata(client);
++
++ down(&data->update_lock);
++
++ if (time_after(jiffies, data->last_updated + 3 * HZ)) {
++ int value;
++
++ value = i2c_smbus_read_byte(client);
++
++ if (value == -1)
++ printk(KERN_WARNING "n30-batt: unable to read charge\n");
++ else
++ data->charge = value;
++ data->last_updated = jiffies;
++ }
++
++ up(&data->update_lock);
++
++ return data;
++}
++
++static ssize_t show_charge(struct device *dev, struct device_attribute *attr, char *buf)
++{
++ struct n30_batt_data *data = n30_batt_update_device(dev);
++ return sprintf(buf, "%d\n", data->charge);
++}
++
++static DEVICE_ATTR(charge, S_IRUGO, show_charge, NULL);
++
++static struct i2c_driver n30_batt_driver;
++
++static struct device *n30_batt_dev;
++
++static int n30_batt_detect(struct i2c_adapter *adapter, int address, int kind)
++{
++ struct i2c_client *new_client;
++ struct n30_batt_data *data;
++ int err = 0;
++ int value;
++
++ printk(KERN_INFO "detect n30 Battery controller\n");
++
++ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
++ goto exit;
++
++ printk(KERN_INFO "kmalloc n30 Battery controller\n");
++
++ if (!(data = kmalloc(sizeof(struct n30_batt_data), GFP_KERNEL))) {
++ err = -ENOMEM;
++ goto exit;
++ }
++ memset(data, 0, sizeof(struct n30_batt_data));
++
++ new_client = &data->client;
++ i2c_set_clientdata(new_client, data);
++ new_client->addr = address;
++ new_client->adapter = adapter;
++ new_client->driver = &n30_batt_driver;
++ new_client->flags = 0;
++ strlcpy(new_client->name, "n30_batt", I2C_NAME_SIZE);
++
++ if ((value = i2c_smbus_read_byte(new_client)) == -1) {
++ printk(KERN_ERR "n30_batt: unable to read charge value\n");
++ err = -ENXIO;
++ goto exit_free;
++ }
++
++ init_MUTEX(&data->update_lock);
++ data->charge = value;
++ data->last_updated = jiffies;
++
++ printk(KERN_DEBUG "n30_batt: battery charge is %d%%\n", data->charge);
++
++ if ((err = i2c_attach_client(new_client)))
++ goto exit_free;
++
++ device_create_file(&new_client->dev, &dev_attr_charge);
++
++ n30_batt_dev = &new_client->dev;
++
++ return 0;
++
++exit_free:
++ kfree(data);
++exit:
++ return err;
++}
++
++static int n30_batt_attach_adapter(struct i2c_adapter *adapter)
++{
++ printk(KERN_INFO "attaching n30 Battery controller\n");
++ return i2c_probe(adapter, &addr_data, n30_batt_detect);
++}
++
++static int n30_batt_detach_client(struct i2c_client *client)
++{
++ n30_batt_dev = NULL;
++ i2c_detach_client(client);
++ kfree(i2c_get_clientdata(client));
++ return 0;
++}
++
++static struct i2c_driver n30_batt_driver = {
++ .owner = THIS_MODULE,
++ .name = "n30_batt",
++ .flags = I2C_DF_NOTIFY,
++ .attach_adapter = n30_batt_attach_adapter,
++ .detach_client = n30_batt_detach_client,
++};
++
++static void n30_get_power_status(struct apm_power_info *info)
++{
++ if (n30_batt_dev) {
++ struct n30_batt_data *data = n30_batt_update_device(n30_batt_dev);
++
++ info->ac_line_status = 0xff;
++ info->battery_status = 0xff;
++ info->battery_flag = 0xff;
++ info->battery_life = data->charge;
++ info->time = -1;
++ info->units = -1;
++ }
++}
++
++static int __init sensors_n30_batt_init(void)
++{
++ printk(KERN_INFO "n30 Battery controller\n");
++
++ if (!machine_is_n30())
++ return -ENODEV;
++ printk(KERN_INFO "adding n30 Battery controller\n");
++
++ apm_get_power_status = n30_get_power_status;
++
++ return i2c_add_driver(&n30_batt_driver);
++}
++
++static void __exit sensors_n30_batt_exit(void)
++{
++ i2c_del_driver(&n30_batt_driver);
++}
++
++MODULE_AUTHOR("Christer Weinigel <christer@weinigel.se>");
++MODULE_DESCRIPTION("Acer n30 Battery Controller");
++MODULE_LICENSE("GPL");
++
++module_init(sensors_n30_batt_init);
++module_exit(sensors_n30_batt_exit);
diff --git a/recipes/linux/linux/acern30/n30-buttons.patch b/recipes/linux/linux/acern30/n30-buttons.patch
new file mode 100644
index 0000000000..ff1214e698
--- /dev/null
+++ b/recipes/linux/linux/acern30/n30-buttons.patch
@@ -0,0 +1,100 @@
+Add support for the buttons on the n30.
+
+Index: linux-2.6.14/arch/arm/mach-s3c2410/mach-n30.c
+===================================================================
+--- linux-2.6.14.orig/arch/arm/mach-s3c2410/mach-n30.c
++++ linux-2.6.14/arch/arm/mach-s3c2410/mach-n30.c
+@@ -46,10 +46,12 @@
+ #include <asm/arch/regs-gpio.h>
+ #include <asm/arch/regs-lcd.h>
+ #include <asm/arch/regs-timer.h>
++#include <asm/arch/irqs.h>
+ #include <asm/arch/iic.h>
+ #include <asm/arch/fb.h>
+ #include <asm/arch/lcd.h>
+ #include <asm/arch/ts.h>
++#include <asm/arch/buttons.h>
+
+ #include <linux/serial_core.h>
+
+@@ -194,11 +196,68 @@ static struct s3c2410_ts_mach_info n30_t
+ .oversampling_shift = 6,
+ };
+
++static struct s3c2410_button n30_buttons[] = {
++ { IRQ_EINT0, S3C2410_GPF0, S3C2410_GPF0_EINT0, KEY_POWER,
++ "Power", 0 },
++
++ { IRQ_EINT17, S3C2410_GPG9, S3C2410_GPG9_EINT17, KEY_UP,
++ "Up_arrow", 0 },
++ { IRQ_EINT16, S3C2410_GPG8, S3C2410_GPG8_EINT16, KEY_DOWN,
++ "Down_arrow", 0 },
++ { IRQ_EINT15, S3C2410_GPG7, S3C2410_GPG7_EINT15, KEY_ENTER,
++ "Select", 0 },
++
++ { IRQ_EINT7, S3C2410_GPF7, S3C2410_GPF7_EINT7, KEY_HOMEPAGE,
++ "Home", 0 },
++ { IRQ_EINT6, S3C2410_GPF6, S3C2410_GPF6_EINT6, KEY_CALENDAR,
++ "Calendar", 0 },
++ { IRQ_EINT5, S3C2410_GPF5, S3C2410_GPF5_EINT5, KEY_COFFEE,
++ "Contacts", 0 }, /* TODO: find a better key :P */
++ { IRQ_EINT4, S3C2410_GPF4, S3C2410_GPF4_EINT4, KEY_MAIL,
++ "Mail", 0 },
++};
++
++static struct s3c2410_butt_mach_info n30_buttons_cfg __initdata = {
++ .buttons = n30_buttons,
++ .size = ARRAY_SIZE(n30_buttons),
++};
++
++static struct s3c2410_button n35_buttons[] = {
++ { IRQ_EINT0, S3C2410_GPF0, S3C2410_GPF0_EINT0, KEY_POWER,
++ "Power", 0 },
++
++ { IRQ_EINT13, S3C2410_GPG5, S3C2410_GPG5_EINT13, KEY_LEFT,
++ "Left_arrow", 0 },
++ { IRQ_EINT14, S3C2410_GPG6, S3C2410_GPG6_EINT14, KEY_RIGHT,
++ "Right_arrow", 0 },
++ { IRQ_EINT17, S3C2410_GPG9, S3C2410_GPG9_EINT17, KEY_UP,
++ "Up_arrow", 0 },
++ { IRQ_EINT16, S3C2410_GPG8, S3C2410_GPG8_EINT16, KEY_DOWN,
++ "Down_arrow", 0 },
++ { IRQ_EINT15, S3C2410_GPG7, S3C2410_GPG7_EINT15, KEY_ENTER,
++ "Select", 0 },
++
++ { IRQ_EINT7, S3C2410_GPF7, S3C2410_GPF7_EINT7, KEY_HOMEPAGE,
++ "Home", 0 },
++ { IRQ_EINT6, S3C2410_GPF6, S3C2410_GPF6_EINT6, KEY_CALENDAR,
++ "Calendar", 0 },
++ { IRQ_EINT5, S3C2410_GPF5, S3C2410_GPF5_EINT5, KEY_COFFEE,
++ "Contacts", 0 }, /* TODO: find a better key :P */
++ { IRQ_EINT4, S3C2410_GPF4, S3C2410_GPF4_EINT4, KEY_MAIL,
++ "Mail", 0 },
++};
++
++static struct s3c2410_butt_mach_info n35_buttons_cfg __initdata = {
++ .buttons = n35_buttons,
++ .size = ARRAY_SIZE(n35_buttons),
++};
++
+ static struct platform_device *n30_devices[] __initdata = {
+ &s3c_device_usb,
+ &s3c_device_lcd,
+ &s3c_device_bl,
+ &s3c_device_ts,
++ &s3c_device_buttons,
+ &s3c_device_wdt,
+ &s3c_device_i2c,
+ &s3c_device_iis,
+@@ -238,6 +297,11 @@ static void __init n30_init(void)
+ set_s3c2410bl_info(&n30_blcfg);
+ set_s3c2410ts_info(&n30_ts_cfg);
+
++ if (machine_is_n30())
++ s3c24xx_butt_set_platdata(&n30_buttons_cfg);
++ if (machine_is_n35())
++ s3c24xx_butt_set_platdata(&n35_buttons_cfg);
++
+ s3c_device_i2c.dev.platform_data = &n30_i2ccfg;
+
+ /* Turn off suspend on both USB ports, and switch the
diff --git a/recipes/linux/linux/acern30/n30-cleanup.patch b/recipes/linux/linux/acern30/n30-cleanup.patch
new file mode 100644
index 0000000000..ea1c966ae9
--- /dev/null
+++ b/recipes/linux/linux/acern30/n30-cleanup.patch
@@ -0,0 +1,30 @@
+Clean up some junk from the official kernel.
+
+The s3c2410.h include isn't needed.
+
+The compile-command is something that's only useful for me personally
+and doesn't belong in the mainstream kernel.
+
+Index: linux-2.6.14/arch/arm/mach-s3c2410/mach-n30.c
+===================================================================
+--- linux-2.6.14.orig/arch/arm/mach-s3c2410/mach-n30.c
++++ linux-2.6.14/arch/arm/mach-s3c2410/mach-n30.c
+@@ -39,7 +39,6 @@
+
+ #include <linux/serial_core.h>
+
+-#include "s3c2410.h"
+ #include "clock.h"
+ #include "devs.h"
+ #include "cpu.h"
+@@ -137,10 +136,3 @@ MACHINE_START(N30, "Acer-N30")
+ .init_irq = n30_init_irq,
+ .map_io = n30_map_io,
+ MACHINE_END
+-
+-/*
+- Local variables:
+- compile-command: "make ARCH=arm CROSS_COMPILE=/usr/local/arm/3.3.2/bin/arm-linux- -k -C ../../.."
+- c-basic-offset: 8
+- End:
+-*/
diff --git a/recipes/linux/linux/acern30/n30-hardcode.patch b/recipes/linux/linux/acern30/n30-hardcode.patch
new file mode 100644
index 0000000000..735e18ca4c
--- /dev/null
+++ b/recipes/linux/linux/acern30/n30-hardcode.patch
@@ -0,0 +1,158 @@
+This patch hardcodes a lot of register settings so that I can boot
+directly from flash on the n30.
+
+Is there a nicer way of doing this?
+
+Index: linux-2.6.14/arch/arm/mach-s3c2410/mach-n30.c
+===================================================================
+--- linux-2.6.14.orig/arch/arm/mach-s3c2410/mach-n30.c
++++ linux-2.6.14/arch/arm/mach-s3c2410/mach-n30.c
+@@ -349,9 +349,148 @@ static struct s3c24xx_board n30_board __
+ .devices_count = ARRAY_SIZE(n30_devices)
+ };
+
++/* Lots of hardcoded stuff, but it sets up the hardware in a useful
++ * state so that we can boot Linux directly from flash. */
++static void __init n30_hwinit(void)
++{
++ /* GPA0-11 special functions -- unknown what they do
++ * GPA12 N30 special function -- unknown what it does
++ * N35/PiN output -- unknown what it does
++ *
++ * A12 is nGCS1 on the N30 and an output on the N35/PiN. I
++ * don't think it does anything useful on the N30, so I ought
++ * to make it an output there too since it always driven to 0
++ * as far as I can tell. */
++ if (machine_is_n30())
++ __raw_writel(0x007fffff, S3C2410_GPACON);
++ if (machine_is_n35())
++ __raw_writel(0x007fefff, S3C2410_GPACON);
++ __raw_writel(0x00000000, S3C2410_GPADAT);
++
++ /* GPB0 TOUT0 backlight level
++ * GPB1 output 1=backlight on
++ * GPB2 output IrDA enable 0=transceiver enabled, 1=disabled
++ * GPB3 output USB D+ pull up 0=disabled, 1=enabled
++ * GPB4 N30 output -- unknown function
++ * N30/PiN GPS control 0=GPS enabled, 1=GPS disabled
++ * GPB5 output -- unknown function
++ * GPB6 input -- unknown function
++ * GPB7 output -- unknown function
++ * GPB8 output -- probably LCD driver enable
++ * GPB9 output -- probably LCD VSYNC driver enable
++ * GPB10 output -- probably LCD HSYNC driver enable
++ */
++ __raw_writel(0x00154556, S3C2410_GPBCON);
++ __raw_writel(0x00000750, S3C2410_GPBDAT);
++ __raw_writel(0x0000007d, S3C2410_GPBUP);
++
++ /* GPC0 input RS232 DCD/DSR/RI
++ * GPC1 LCD
++ * GPC2 output RS232 DTR?
++ * GPC3 input RS232 DCD/DSR/RI
++ * GPC4 LCD
++ * GPC5 output 0=NAND write enabled, 1=NAND write protect
++ * GPC6 input -- unknown function
++ * GPC7 input charger status 0=charger connected
++ * this input can be triggered by power on the USB device
++ * port too, but will go back to disconnected soon after.
++ * GPC8 N30/N35 output -- unknown function, always driven to 1
++ * PiN input -- unknown function, always read as 1
++ * Make it an input with a pull up for all models.
++ * GPC9-15 LCD
++ */
++ __raw_writel(0xaaa80618, S3C2410_GPCCON);
++ __raw_writel(0x0000014c, S3C2410_GPCDAT);
++ __raw_writel(0x0000fef2, S3C2410_GPCUP);
++
++ /* GPD0 input -- unknown function
++ * GPD1-D7 LCD
++ * GPD8 N30 output -- unknown function
++ * N35/PiN output 1=GPS LED on
++ * GPD9 output 0=power led blinks red, 1=normal power led function
++ * GPD10 output -- unknown function
++ * GPD11-15 LCD drivers
++ */
++ __raw_writel(0xaa95aaa4, S3C2410_GPDCON);
++ __raw_writel(0x00000601, S3C2410_GPDDAT);
++ __raw_writel(0x0000fbfe, S3C2410_GPDUP);
++
++ /* GPE0-4 I2S audio bus
++ * GPE5-10 SD/MMC bus
++ * E11-13 outputs -- unknown function, probably power management
++ * E14-15 I2C bus connected to the battery controller
++ */
++ __raw_writel(0xa56aaaaa, S3C2410_GPECON);
++ __raw_writel(0x0000efc5, S3C2410_GPEDAT);
++ __raw_writel(0x0000f81f, S3C2410_GPEUP);
++
++ /* GPF0 input 0=power button pressed
++ * GPF1 input SD/MMC switch 0=card present
++ * GPF2 N30 1=reset button pressed (inverted compared to the rest)
++ * N35/PiN 0=reset button pressed
++ * GPF3 N30/PiN input -- unknown function
++ * N35 input GPS antenna position, 0=antenna closed, 1=open
++ * GPF4 input 0=button 4 pressed
++ * GPF5 input 0=button 3 pressed
++ * GPF6 input 0=button 2 pressed
++ * GPF7 input 0=button 1 pressed
++ */
++ __raw_writel(0x0000aaaa, S3C2410_GPFCON);
++ __raw_writel(0x00000000, S3C2410_GPFDAT);
++ __raw_writel(0x000000ff, S3C2410_GPFUP);
++
++ /* GPG0 input RS232 DCD/DSR/RI
++ * GPG1 input 1=USB gadget port has power from a host
++ * GPG2 N30 input -- unknown function
++ * N35/PiN input 0=headphones plugged in, 1=not plugged in
++ * GPG3 N30 output -- unknown function
++ * N35/PiN input with unknown function
++ * GPG4 N30 output 0=MMC enabled, 1=MMC disabled
++ * GPG5 N30 output 0=BlueTooth chip disabled, 1=enabled
++ * N35/PiN input joystick right
++ * GPG6 N30 output 0=blue led on, 1=off
++ * N35/PiN input joystick left
++ * GPG7 input 0=thumbwheel pressed
++ * GPG8 input 0=thumbwheel down
++ * GPG9 input 0=thumbwheel up
++ * GPG10 input SD/MMC write protect switch
++ * GPG11 N30 input -- unknown function
++ * N35 output 0=GPS antenna powered, 1=not powered
++ * PiN output -- unknown function
++ * GPG12-15 touch screen functions
++ *
++ * The pullups differ between the models, so enable all
++ * pullups that are enabled on any of the models.
++ */
++ if (machine_is_n30())
++ __raw_writel(0xff0a956a, S3C2410_GPGCON);
++ if (machine_is_n35())
++ __raw_writel(0xff4aa92a, S3C2410_GPGCON);
++ __raw_writel(0x0000e800, S3C2410_GPGDAT);
++ __raw_writel(0x0000f86f, S3C2410_GPGUP);
++
++ /* GPH0/1/2/3 RS232 serial port
++ * GPH4/5 IrDA serial port
++ * GPH6/7 N30 BlueTooth serial port
++ * N35/PiN GPS receiver
++ * GPH8 input -- unknown function
++ * GPH9 CLKOUT0 HCLK -- unknown use
++ * GPH10 CLKOUT1 FCLK -- unknown use
++ *
++ * The pull ups for H6/H7 are enabled on N30 but not on the
++ * N35/PiN. I suppose is useful for a budget model of the N30
++ * with no bluetooh. It doesn't hurt to have the pull ups
++ * enable, so leave them enabled for all models.
++ */
++ __raw_writel(0x0028aaaa, S3C2410_GPHCON);
++ __raw_writel(0x000005ef, S3C2410_GPHDAT);
++ __raw_writel(0x0000063f, S3C2410_GPHUP);
++}
++
+ static void __init n30_map_io(void)
+ {
+ s3c24xx_init_io(n30_iodesc, ARRAY_SIZE(n30_iodesc));
++ n30_hwinit();
+ s3c24xx_init_clocks(0);
+ s3c24xx_init_uarts(n30_uartcfgs, ARRAY_SIZE(n30_uartcfgs));
+ s3c24xx_set_board(&n30_board);
diff --git a/recipes/linux/linux/acern30/n30-lcd.patch b/recipes/linux/linux/acern30/n30-lcd.patch
new file mode 100644
index 0000000000..c56ad5aadc
--- /dev/null
+++ b/recipes/linux/linux/acern30/n30-lcd.patch
@@ -0,0 +1,66 @@
+This patch adds the configuration needed for the LCD display on the n30.
+
+Index: linux-2.6.14/arch/arm/mach-s3c2410/mach-n30.c
+===================================================================
+--- linux-2.6.14.orig/arch/arm/mach-s3c2410/mach-n30.c
++++ linux-2.6.14/arch/arm/mach-s3c2410/mach-n30.c
+@@ -44,7 +44,9 @@
+
+ #include <asm/arch/regs-serial.h>
+ #include <asm/arch/regs-gpio.h>
++#include <asm/arch/regs-lcd.h>
+ #include <asm/arch/iic.h>
++#include <asm/arch/fb.h>
+
+ #include <linux/serial_core.h>
+
+@@ -85,6 +87,40 @@ static struct s3c2410_uartcfg n30_uartcf
+ },
+ };
+
++static struct s3c2410fb_mach_info n30_lcdcfg __initdata = {
++ .fixed_syncs= 1,
++ .regs={
++ .lcdcon1= S3C2410_LCDCON1_TFT16BPP |
++ S3C2410_LCDCON1_TFT |
++ S3C2410_LCDCON1_CLKVAL(0x0A),
++
++ .lcdcon2= S3C2410_LCDCON2_VBPD(1) |
++ S3C2410_LCDCON2_LINEVAL(319) |
++ S3C2410_LCDCON2_VFPD(2) |
++ S3C2410_LCDCON2_VSPW(1),
++
++ .lcdcon3= S3C2410_LCDCON3_HBPD(39) |
++ S3C2410_LCDCON3_HOZVAL(239) |
++ S3C2410_LCDCON3_HFPD(2),
++
++ .lcdcon4= S3C2410_LCDCON4_MVAL(13) |
++ S3C2410_LCDCON4_HSPW(39),
++
++ .lcdcon5= S3C2410_LCDCON5_FRM565 |
++ S3C2410_LCDCON5_INVVLINE |
++ S3C2410_LCDCON5_INVVFRAME |
++ S3C2410_LCDCON5_PWREN |
++ S3C2410_LCDCON5_HWSWP,
++ },
++ .lpcsel= 0x06,
++
++ .width= 240,
++ .height= 320,
++ .xres= {240,240,240},
++ .yres= {320,320,320},
++ .bpp= {16,16,16},
++};
++
+ static struct platform_device *n30_devices[] __initdata = {
+ &s3c_device_usb,
+ &s3c_device_lcd,
+@@ -123,6 +159,8 @@ static void __init n30_init_irq(void)
+
+ static void __init n30_init(void)
+ {
++ s3c24xx_fb_set_platdata(&n30_lcdcfg);
++
+ s3c_device_i2c.dev.platform_data = &n30_i2ccfg;
+
+ /* Turn off suspend on both USB ports, and switch the
diff --git a/recipes/linux/linux/acern30/n30-mmc-power.patch b/recipes/linux/linux/acern30/n30-mmc-power.patch
new file mode 100644
index 0000000000..cacb2fafd6
--- /dev/null
+++ b/recipes/linux/linux/acern30/n30-mmc-power.patch
@@ -0,0 +1,24 @@
+This patch adds power management for the mmc port on the n30.
+
+Index: linux-2.6.14/arch/arm/mach-s3c2410/mach-n30.c
+===================================================================
+--- linux-2.6.14.orig/arch/arm/mach-s3c2410/mach-n30.c
++++ linux-2.6.14/arch/arm/mach-s3c2410/mach-n30.c
+@@ -261,9 +261,16 @@ static struct s3c2410_butt_mach_info n35
+ .size = ARRAY_SIZE(n35_buttons),
+ };
+
++static void n30_mmc_set_power(unsigned int to)
++{
++ /* TODO This may not be correct. This needs testing. */
++ if (machine_is_n30())
++ s3c2410_gpio_setpin(S3C2410_GPG4, !to);
++}
++
+ static struct s3c24xx_mmc_platdata n30_mmc_cfg = {
+ .gpio_detect = S3C2410_GPF1,
+- .set_power = NULL,
++ .set_power = n30_mmc_set_power,
+ .f_max = 3000000,
+ .ocr_avail = MMC_VDD_32_33,
+ };
diff --git a/recipes/linux/linux/acern30/n30-mmc-wprotect.patch b/recipes/linux/linux/acern30/n30-mmc-wprotect.patch
new file mode 100644
index 0000000000..e319432c6c
--- /dev/null
+++ b/recipes/linux/linux/acern30/n30-mmc-wprotect.patch
@@ -0,0 +1,54 @@
+This adds support for the write protect switch on the n30.
+
+It also adds some code to the generic s3c2410sdi driver so that the
+write protect switch actually does something.
+
+But I'm not sure if I want to add support for the write protect switch
+since it really protect against anything. Using the switch is
+entirely up to software, and saying that the card is write protected
+when it really isn't sounds like a bad idea. "Secure" Digital indeed.
+
+Index: linux-2.6.14/arch/arm/mach-s3c2410/mach-n30.c
+===================================================================
+--- linux-2.6.14.orig/arch/arm/mach-s3c2410/mach-n30.c
++++ linux-2.6.14/arch/arm/mach-s3c2410/mach-n30.c
+@@ -270,6 +270,7 @@ static void n30_mmc_set_power(unsigned i
+
+ static struct s3c24xx_mmc_platdata n30_mmc_cfg = {
+ .gpio_detect = S3C2410_GPF1,
++ .gpio_wprotect = S3C2410_GPG10,
+ .set_power = n30_mmc_set_power,
+ .f_max = 3000000,
+ .ocr_avail = MMC_VDD_32_33,
+Index: linux-2.6.14/drivers/mmc/s3c2410mci.c
+===================================================================
+--- linux-2.6.14.orig/drivers/mmc/s3c2410mci.c
++++ linux-2.6.14/drivers/mmc/s3c2410mci.c
+@@ -515,6 +515,17 @@ static void s3c2410sdi_set_ios(struct mm
+
+ }
+
++static int s3c2410sdi_get_ro(struct mmc_host* mmc)
++{
++ struct s3c2410sdi_host *host = mmc_priv(mmc);
++ int r;
++
++ r = s3c2410_gpio_getpin(host->pdata->gpio_wprotect);
++ if (host->pdata->wprotect_polarity)
++ r = !r;
++ return r;
++}
++
+ static struct mmc_host_ops s3c2410sdi_ops = {
+ .request = s3c2410sdi_request,
+ .set_ios = s3c2410sdi_set_ios,
+@@ -643,6 +654,9 @@ static int s3c2410sdi_probe(struct devic
+ mmc->f_max = clk_get_rate(host->clk) / 2;
+ mmc->caps = MMC_CAP_4_BIT_DATA;
+
++ if (host->pdata->gpio_wprotect)
++ mmc->ops->get_ro = s3c2410sdi_get_ro;
++
+ /* HACK: There seems to be a hardware bug in TomTom GO. */
+ /*if(mmc->f_max>3000000) mmc->f_max=3000000;*/
+
diff --git a/recipes/linux/linux/acern30/n30-mmc.patch b/recipes/linux/linux/acern30/n30-mmc.patch
new file mode 100644
index 0000000000..6fb58f142b
--- /dev/null
+++ b/recipes/linux/linux/acern30/n30-mmc.patch
@@ -0,0 +1,53 @@
+This patch adds configuration for the SD/MMC port on the n30.
+
+Index: linux-2.6.14/arch/arm/mach-s3c2410/mach-n30.c
+===================================================================
+--- linux-2.6.14.orig/arch/arm/mach-s3c2410/mach-n30.c
++++ linux-2.6.14/arch/arm/mach-s3c2410/mach-n30.c
+@@ -32,6 +32,8 @@
+ #include <linux/device.h>
+ #include <linux/kthread.h>
+
++#include <linux/mmc/protocol.h>
++
+ #include <asm/mach/arch.h>
+ #include <asm/mach/map.h>
+ #include <asm/mach/irq.h>
+@@ -52,6 +54,7 @@
+ #include <asm/arch/lcd.h>
+ #include <asm/arch/ts.h>
+ #include <asm/arch/buttons.h>
++#include <asm/arch/mmc.h>
+
+ #include <linux/serial_core.h>
+
+@@ -258,6 +261,13 @@ static struct s3c2410_butt_mach_info n35
+ .size = ARRAY_SIZE(n35_buttons),
+ };
+
++static struct s3c24xx_mmc_platdata n30_mmc_cfg = {
++ .gpio_detect = S3C2410_GPF1,
++ .set_power = NULL,
++ .f_max = 3000000,
++ .ocr_avail = MMC_VDD_32_33,
++};
++
+ static struct platform_device *n30_devices[] __initdata = {
+ &s3c_device_usb,
+ &s3c_device_lcd,
+@@ -268,6 +278,7 @@ static struct platform_device *n30_devic
+ &s3c_device_i2c,
+ &s3c_device_iis,
+ &s3c_device_usbgadget,
++ &s3c_device_sdi,
+ };
+
+ static struct s3c2410_platform_i2c n30_i2ccfg = {
+@@ -309,6 +320,7 @@ static void __init n30_init(void)
+ s3c24xx_butt_set_platdata(&n35_buttons_cfg);
+
+ s3c_device_i2c.dev.platform_data = &n30_i2ccfg;
++ s3c_device_sdi.dev.platform_data = &n30_mmc_cfg;
+
+ /* Turn off suspend on both USB ports, and switch the
+ * selectable USB port to USB device mode. */
diff --git a/recipes/linux/linux/acern30/n30-nand-hack.patch b/recipes/linux/linux/acern30/n30-nand-hack.patch
new file mode 100644
index 0000000000..d606f2b47c
--- /dev/null
+++ b/recipes/linux/linux/acern30/n30-nand-hack.patch
@@ -0,0 +1,32 @@
+The flash is locked on the n30 and needs to be unlocked before every
+write. It should be possible to do one big unlock operation outside
+of the erase and write functions but for some strange reason that
+doesn't seem to work any more, so do this ugly workaround for now.
+
+Index: linux-2.6.14/drivers/mtd/nand/nand_base.c
+===================================================================
+--- linux-2.6.14.orig/drivers/mtd/nand/nand_base.c
++++ linux-2.6.14/drivers/mtd/nand/nand_base.c
+@@ -866,6 +866,10 @@ static int nand_write_page (struct mtd_i
+ /* FIXME: Enable cached programming */
+ cached = 0;
+
++ /* unlock the page */
++ this->cmdfunc (mtd, 0x23, -1, page);
++ this->cmdfunc (mtd, 0x24, -1, page);
++
+ /* Send command to begin auto page programming */
+ this->cmdfunc (mtd, NAND_CMD_SEQIN, 0x00, page);
+
+@@ -2037,6 +2041,11 @@ out:
+ static void single_erase_cmd (struct mtd_info *mtd, int page)
+ {
+ struct nand_chip *this = mtd->priv;
++
++ /* unlock the page */
++ this->cmdfunc (mtd, 0x23, -1, page);
++ this->cmdfunc (mtd, 0x24, -1, page);
++
+ /* Send commands to erase a block */
+ this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page);
+ this->cmdfunc (mtd, NAND_CMD_ERASE2, -1, -1);
diff --git a/recipes/linux/linux/acern30/n30-nand.patch b/recipes/linux/linux/acern30/n30-nand.patch
new file mode 100644
index 0000000000..d3ac8c557a
--- /dev/null
+++ b/recipes/linux/linux/acern30/n30-nand.patch
@@ -0,0 +1,97 @@
+This patch adds a nand flash configuration for the n30.
+
+Index: linux-2.6.14/arch/arm/mach-s3c2410/mach-n30.c
+===================================================================
+--- linux-2.6.14.orig/arch/arm/mach-s3c2410/mach-n30.c
++++ linux-2.6.14/arch/arm/mach-s3c2410/mach-n30.c
+@@ -33,6 +33,8 @@
+ #include <linux/kthread.h>
+
+ #include <linux/mmc/protocol.h>
++#include <linux/mtd/mtd.h>
++#include <linux/mtd/partitions.h>
+
+ #include <asm/mach/arch.h>
+ #include <asm/mach/map.h>
+@@ -55,6 +57,7 @@
+ #include <asm/arch/ts.h>
+ #include <asm/arch/buttons.h>
+ #include <asm/arch/mmc.h>
++#include <asm/arch/nand.h>
+
+ #include <linux/serial_core.h>
+
+@@ -276,6 +279,50 @@ static struct s3c24xx_mmc_platdata n30_m
+ .ocr_avail = MMC_VDD_32_33,
+ };
+
++static int chip0_map[] = { 0 };
++
++struct mtd_partition n30_default_nand_part[] = {
++ {
++ .name = "Whole flash",
++ .offset = 0,
++ .size = MTDPART_SIZ_FULL,
++ .mask_flags = MTD_WRITEABLE,
++ },
++ {
++ .name = "Partition Table",
++ .offset = 0x28000,
++ .size = 0x8000,
++ },
++ {
++ .name = "Kernel",
++ .offset = 0x30000,
++ .size = 0x4d0000,
++ },
++ {
++ .name = "Root",
++ .offset = 0x500000,
++ .size = MTDPART_SIZ_FULL,
++ },
++};
++
++static struct s3c2410_nand_set n30_nand_sets[] = {
++ {
++ .name = "chip0",
++ .nr_chips = 1,
++ .nr_map = chip0_map,
++ .nr_partitions = ARRAY_SIZE(n30_default_nand_part),
++ .partitions = n30_default_nand_part
++ },
++};
++
++static struct s3c2410_platform_nand n30_nand_info = {
++ .tacls = 80,
++ .twrph0 = 80,
++ .twrph1 = 80,
++ .nr_sets = ARRAY_SIZE(n30_nand_sets),
++ .sets = n30_nand_sets,
++};
++
+ static struct platform_device *n30_devices[] __initdata = {
+ &s3c_device_usb,
+ &s3c_device_lcd,
+@@ -287,6 +334,7 @@ static struct platform_device *n30_devic
+ &s3c_device_iis,
+ &s3c_device_usbgadget,
+ &s3c_device_sdi,
++ &s3c_device_nand,
+ };
+
+ static struct s3c2410_platform_i2c n30_i2ccfg = {
+@@ -329,6 +377,14 @@ static void __init n30_init(void)
+
+ s3c_device_i2c.dev.platform_data = &n30_i2ccfg;
+ s3c_device_sdi.dev.platform_data = &n30_mmc_cfg;
++ s3c_device_nand.dev.platform_data = &n30_nand_info;
++
++ /* Clear any locks and write protects on the flash. */
++ s3c2410_gpio_setpin(S3C2410_GPC5, 1);
++ msleep(1);
++ s3c2410_gpio_setpin(S3C2410_GPC5, 0);
++ msleep(1);
++ s3c2410_gpio_setpin(S3C2410_GPC5, 1);
+
+ /* Turn off suspend on both USB ports, and switch the
+ * selectable USB port to USB device mode. */
diff --git a/recipes/linux/linux/acern30/n30-pm.patch b/recipes/linux/linux/acern30/n30-pm.patch
new file mode 100644
index 0000000000..014043b55b
--- /dev/null
+++ b/recipes/linux/linux/acern30/n30-pm.patch
@@ -0,0 +1,296 @@
+Add suspend/resume support for the Acer N30.
+
+Index: linux-2.6.14/arch/arm/mach-s3c2410/mach-n30.c
+===================================================================
+--- linux-2.6.14.orig/arch/arm/mach-s3c2410/mach-n30.c
++++ linux-2.6.14/arch/arm/mach-s3c2410/mach-n30.c
+@@ -66,11 +66,46 @@
+ #include "clock.h"
+ #include "devs.h"
+ #include "cpu.h"
++#include "pm.h"
+
+ static struct map_desc n30_iodesc[] __initdata = {
+ /* nothing here yet */
+ };
+
++/* This code is copied to physical address SDRAM_PA + 0x201000. The
++ * bootloader will jump there on a watchdog reset or when resuming
++ * from suspend to ram. */
++
++#define N30_RESUME_VA __va(S3C2410_SDRAM_PA + 0x201000)
++
++static void __init n30_resume(void) __attribute__((naked));
++static void __init n30_resume(void)
++{
++ asm(
++ "mov r1, #0x56000000 \n\t"
++
++ /* load GSTATUS2 and check for a wake from suspend */
++ "ldr r0, [r1, #0xb4] \n\t" /* GSTATUS2 */
++ "ands r0, r0, #2 \n\t" /* OFFRST */
++ "beq 1f \n\t"
++
++ /* it is a wake reset, so jump to the resume function
++ * pointed to by GSTATUS3 */
++ "ldr pc, [r1, #0xb8] \n\t" /* GSTATUS3 */
++
++ /* Probably a watchdog reset, so fake a power on reset
++ * by writing PWRST to GSTATUS2 and then jump back to
++ * the bootloader. */
++ "1: \n\t"
++ "mov r0, #1 \n\t" /* PWRST */
++ "str r0, [r1, #0xb4] \n\t" /* GSTATUS2 */
++ "mov pc, #0 \n\t"
++
++ "n30_resume_end: \n\t"
++ );
++}
++extern void n30_resume_end;
++
+ static struct s3c2410_uartcfg n30_uartcfgs[] = {
+ /* Normal serial port */
+ [0] = {
+@@ -483,6 +518,154 @@ static void __init n30_hwinit(void)
+ __raw_writel(0x0000063f, S3C2410_GPHUP);
+ }
+
++void n30_pm_gpio(void)
++{
++ if (machine_is_n35()) {
++ /* Prepare for suspend to ram. This is what WinCE
++ * apparently does. I know where some of these pins
++ * are connected and ought to be moved to code related
++ * that hardware, but some stuff is magic so far. */
++
++ /* All this is magic. WinCE does this and it brings
++ * the power consumption in sleep mode down. */
++
++ /* Drive ADDR0, ADDR16..ADDR23, and ADDR26 low.
++ * ADDR24 and ADDR 25 are still working.
++ * nGCS1..nGCS5 are driven low.
++ * CLE, ALE, nFWE, nFRE, nRSTOUT and nFCW are working. */
++ __raw_writel(0x007e0600, S3C2410_GPACON);
++ __raw_writel(0x00000000, S3C2410_GPADAT);
++ __raw_writel(0x00015556, S3C2410_GPBCON);
++ __raw_writel(0x00000011, S3C2410_GPBDAT);
++ __raw_writel(0x000007ff, S3C2410_GPBUP);
++ __raw_writel(0xaa950618, S3C2410_GPCCON);
++ __raw_writel(0x0000024c, S3C2410_GPCDAT);
++ __raw_writel(0x0000ffb6, S3C2410_GPCUP);
++ __raw_writel(0xaa95aaa5, S3C2410_GPDCON);
++ __raw_writel(0x00000202, S3C2410_GPDDAT);
++ __raw_writel(0x0000fffd, S3C2410_GPDUP);
++ __raw_writel(0xa56aaaaa, S3C2410_GPECON);
++ __raw_writel(0x0000c7c1, S3C2410_GPEDAT);
++ __raw_writel(0x0000ffff, S3C2410_GPEUP);
++ __raw_writel(0x0000aa22, S3C2410_GPFCON);
++ __raw_writel(0x000000f5, S3C2410_GPFDAT);
++ __raw_writel(0x000000fd, S3C2410_GPFUP);
++ __raw_writel(0xff40010a, S3C2410_GPGCON);
++ __raw_writel(0x0000abf5, S3C2410_GPGDAT);
++ __raw_writel(0x0000fcef, S3C2410_GPGUP);
++ __raw_writel(0x0014aaaa, S3C2410_GPHCON);
++ __raw_writel(0x0000062f, S3C2410_GPHDAT);
++ __raw_writel(0x000007ff, S3C2410_GPHUP);
++
++ /* Turn GPB6 into an output and drive it low. */
++ s3c2410_gpio_cfgpin(S3C2410_GPB6, S3C2410_GPB6_OUTP);
++ s3c2410_gpio_setpin(S3C2410_GPB6, 0);
++
++ /* Turn off the pull up on GPB7. */
++ s3c2410_gpio_pullup(S3C2410_GPB7, 1);
++
++ /* Drive GPC8 low */
++ s3c2410_gpio_cfgpin(S3C2410_GPC8, S3C2410_GPC8_OUTP);
++ s3c2410_gpio_setpin(S3C2410_GPC8, 0);
++ s3c2410_gpio_pullup(S3C2410_GPC8, 1);
++
++ /* Drive GPC9/VD[1] high. */
++ s3c2410_gpio_cfgpin(S3C2410_GPC9, S3C2410_GPC9_OUTP);
++ s3c2410_gpio_setpin(S3C2410_GPC9, 1);
++
++ /* Drive GPC10/VD[2] low. */
++ s3c2410_gpio_cfgpin(S3C2410_GPC10, S3C2410_GPC10_OUTP);
++ s3c2410_gpio_setpin(S3C2410_GPC10, 0);
++
++ /* Disable pull up on RS232 DTR? */
++ s3c2410_gpio_pullup(S3C2410_GPC2, 1);
++
++ /* Enable pull up on GPC6. */
++ s3c2410_gpio_pullup(S3C2410_GPC6, 0);
++
++ /* Turn GPD0 into an output and drive it low. */
++ s3c2410_gpio_cfgpin(S3C2410_GPD0, S3C2410_GPD0_OUTP);
++ s3c2410_gpio_setpin(S3C2410_GPD0, 0);
++ s3c2410_gpio_pullup(S3C2410_GPD0, 1);
++
++ /* Drive VD[9] high and enable the pull up. */
++ s3c2410_gpio_cfgpin(S3C2410_GPD1, S3C2410_GPD1_OUTP);
++ s3c2410_gpio_setpin(S3C2410_GPD1, 1);
++ s3c2410_gpio_pullup(S3C2410_GPD1, 0);
++
++ /* Drive DPD10 low. */
++ s3c2410_gpio_setpin(S3C2410_GPD10, 0);
++ s3c2410_gpio_pullup(S3C2410_GPD10, 1);
++
++ /* This may do something about the power planes. */
++ s3c2410_gpio_setpin(S3C2410_GPE11, 0);
++ s3c2410_gpio_setpin(S3C2410_GPE12, 0);
++ s3c2410_gpio_setpin(S3C2410_GPE13, 0);
++
++ /* Disable pull ups on H8. Don't know why. */
++ s3c2410_gpio_pullup(S3C2410_GPH8, 1);
++
++ /* LCD stuff, ought to be moved to n30_lcd_power.
++ * GPB8 is still an output and drives 0.
++ * GPB9 and GPB10 are turned into inputs.
++ * All pull ups are disabled. */
++ s3c2410_gpio_setpin(S3C2410_GPB8, 0);
++ s3c2410_gpio_pullup(S3C2410_GPB8, 1);
++ s3c2410_gpio_cfgpin(S3C2410_GPB9, S3C2410_GPB9_INP);
++ s3c2410_gpio_pullup(S3C2410_GPB9, 1);
++ s3c2410_gpio_cfgpin(S3C2410_GPB10, S3C2410_GPB10_INP);
++ s3c2410_gpio_pullup(S3C2410_GPB10, 1);
++
++ /* Disable IrDA (not done by WinCE). */
++ s3c2410_gpio_setpin(S3C2410_GPB2, 1);
++
++ /* Disable the GPS. */
++ s3c2410_gpio_setpin(S3C2410_GPB4, 1);
++ s3c2410_gpio_setpin(S3C2410_GPG11, 1);
++
++ /* Turn on flash write protect. */
++ s3c2410_gpio_setpin(S3C2410_GPC5, 0);
++
++ /* Disable pull ups on the SD/MMC port. This should
++ * maybe be done after power has been removed from the
++ * SD/MMC port. */
++ s3c2410_gpio_pullup(S3C2410_GPE5, 1);
++ s3c2410_gpio_pullup(S3C2410_GPE6, 1);
++ s3c2410_gpio_pullup(S3C2410_GPE7, 1);
++ s3c2410_gpio_pullup(S3C2410_GPE8, 1);
++ s3c2410_gpio_pullup(S3C2410_GPE9, 1);
++ s3c2410_gpio_pullup(S3C2410_GPE10, 1);
++
++ /* Disable MMC? On the N30 this makes a difference,
++ * on the N35, maybe not. */
++ s3c2410_gpio_setpin(S3C2410_GPG4, 1);
++
++ /* Enable pull up on SD/MMC switch. */
++ s3c2410_gpio_pullup(S3C2410_GPF1, 0);
++
++ /* Disable pull up on thumbwheel. Why not on the
++ * other inputs too? */
++ s3c2410_gpio_pullup(S3C2410_GPG7, 1);
++
++ /* Disable pull up on SD write protect switch. */
++ s3c2410_gpio_pullup(S3C2410_GPG10, 1);
++
++ /* Disable pull ups on the bluetooth/gps port. */
++ s3c2410_gpio_pullup(S3C2410_GPH6, 1);
++ s3c2410_gpio_pullup(S3C2410_GPH7, 1);
++
++ /* Drive CLKOUT0 high while sleeping. */
++ s3c2410_gpio_cfgpin(S3C2410_GPH9, S3C2410_GPH9_OUTP);
++ s3c2410_gpio_setpin(S3C2410_GPH9, 1);
++
++ /* Drive CLKOUT1 high while sleeping. */
++ s3c2410_gpio_cfgpin(S3C2410_GPH10, S3C2410_GPH10_OUTP);
++ s3c2410_gpio_setpin(S3C2410_GPH10, 1);
++
++ s3c2410_capture_regs();
++ }
++}
++
+ static void __init n30_map_io(void)
+ {
+ s3c24xx_init_io(n30_iodesc, ARRAY_SIZE(n30_iodesc));
+@@ -569,6 +752,12 @@ static void __init n30_init(void)
+ s3c_device_sdi.dev.platform_data = &n30_mmc_cfg;
+ s3c_device_nand.dev.platform_data = &n30_nand_info;
+
++ s3c2410_pm_init();
++ enable_irq_wake(IRQ_EINT0);
++
++ memcpy_toio(N30_RESUME_VA, (void *)n30_resume,
++ &n30_resume_end - (void *)n30_resume);
++
+ /* Clear any locks and write protects on the flash. */
+ s3c2410_gpio_setpin(S3C2410_GPC5, 1);
+ msleep(1);
+Index: linux-2.6.14/arch/arm/mach-s3c2410/pm.c
+===================================================================
+--- linux-2.6.14.orig/arch/arm/mach-s3c2410/pm.c
++++ linux-2.6.14/arch/arm/mach-s3c2410/pm.c
+@@ -565,6 +565,8 @@ static int s3c2410_pm_enter(suspend_stat
+ s3c2410_pm_do_save(core_save, ARRAY_SIZE(core_save));
+ s3c2410_pm_do_save(uart_save, ARRAY_SIZE(uart_save));
+
++ n30_pm_gpio();
++
+ /* set the irq configuration for wake */
+
+ s3c2410_pm_configure_extint();
+@@ -601,6 +603,8 @@ static int s3c2410_pm_enter(suspend_stat
+ tmp &= S3C2410_GSTATUS2_OFFRESET;
+ __raw_writel(tmp, S3C2410_GSTATUS2);
+
++ s3c2410_capture_regs();
++
+ /* restore the system state */
+
+ s3c2410_pm_do_restore_core(core_save, ARRAY_SIZE(core_save));
+Index: linux-2.6.14/arch/arm/mach-s3c2410/sleep.S
+===================================================================
+--- linux-2.6.14.orig/arch/arm/mach-s3c2410/sleep.S
++++ linux-2.6.14/arch/arm/mach-s3c2410/sleep.S
+@@ -80,6 +80,7 @@ ENTRY(s3c2410_cpu_suspend)
+
+ orr r7, r7, #S3C2410_REFRESH_SELF @ SDRAM sleep command
+ orr r8, r8, #S3C2410_MISCCR_SDSLEEP @ SDRAM power-down signals
++ orr r8, r8, #3 @ turn on data pull ups
+ orr r9, r9, #S3C2410_CLKCON_POWER @ power down command
+
+ teq pc, #0 @ first as a trial-run to load cache
+Index: linux-2.6.14/arch/arm/Makefile
+===================================================================
+--- linux-2.6.14.orig/arch/arm/Makefile
++++ linux-2.6.14/arch/arm/Makefile
+@@ -99,6 +99,10 @@ textaddr-$(CONFIG_ARCH_FORTUNET) := 0x
+ machine-$(CONFIG_ARCH_IMX) := imx
+ machine-$(CONFIG_ARCH_H720X) := h720x
+ machine-$(CONFIG_ARCH_AAEC2000) := aaec2000
++# The Acer N30/N35 needs to put some code at 0xc0201000 to handle
++# the watchdog interrupt and resume from suspend.
++textaddr-$(CONFIG_MACH_N30) := 0xc0208000
++textaddr-$(CONFIG_MACH_N35) := 0xc0208000
+
+ ifeq ($(CONFIG_ARCH_EBSA110),y)
+ # This is what happens if you forget the IOCS16 line.
+Index: linux-2.6.14/arch/arm/mm/init.c
+===================================================================
+--- linux-2.6.14.orig/arch/arm/mm/init.c
++++ linux-2.6.14/arch/arm/mm/init.c
+@@ -230,6 +230,9 @@ static __init void reserve_node_zero(pg_
+ #endif
+ if (res_size)
+ reserve_bootmem_node(pgdat, PHYS_OFFSET, res_size);
++
++ if (machine_is_n30() || machine_is_n35())
++ reserve_bootmem_node(pgdat, 0x30201000, PAGE_SIZE);
+ }
+
+ void __init build_mem_type_table(void);
+Index: linux-2.6.14/arch/arm/mach-s3c2410/Makefile.boot
+===================================================================
+--- linux-2.6.14.orig/arch/arm/mach-s3c2410/Makefile.boot
++++ linux-2.6.14/arch/arm/mach-s3c2410/Makefile.boot
+@@ -1,3 +1,7 @@
+ zreladdr-y := 0x30008000
+ params_phys-y := 0x30000100
+
++# The N30/N35 needs 0x30201000 for the bootloader interface. So place
++# the kernel after that.
++zreladdr-$(CONFIG_MACH_N30) := 0x30208000
++zreladdr-$(CONFIG_MACH_N35) := 0x30208000
diff --git a/recipes/linux/linux/acern30/n30-ts.patch b/recipes/linux/linux/acern30/n30-ts.patch
new file mode 100644
index 0000000000..bc619ed2f3
--- /dev/null
+++ b/recipes/linux/linux/acern30/n30-ts.patch
@@ -0,0 +1,43 @@
+This patch adds the touch screen configuration for the n30.
+
+Index: linux-2.6.14/arch/arm/mach-s3c2410/mach-n30.c
+===================================================================
+--- linux-2.6.14.orig/arch/arm/mach-s3c2410/mach-n30.c
++++ linux-2.6.14/arch/arm/mach-s3c2410/mach-n30.c
+@@ -49,6 +49,7 @@
+ #include <asm/arch/iic.h>
+ #include <asm/arch/fb.h>
+ #include <asm/arch/lcd.h>
++#include <asm/arch/ts.h>
+
+ #include <linux/serial_core.h>
+
+@@ -184,10 +185,20 @@ static struct s3c2410_bl_mach_info n30_b
+ .lcd_power = n30_lcd_power
+ };
+
++/* The touch is very noisy on the n30 so sample often and average many
++ * samples before passing them on to userspace. */
++
++static struct s3c2410_ts_mach_info n30_ts_cfg __initdata = {
++ .delay = 1800,
++ .presc = 49,
++ .oversampling_shift = 6,
++};
++
+ static struct platform_device *n30_devices[] __initdata = {
+ &s3c_device_usb,
+ &s3c_device_lcd,
+ &s3c_device_bl,
++ &s3c_device_ts,
+ &s3c_device_wdt,
+ &s3c_device_i2c,
+ &s3c_device_iis,
+@@ -225,6 +236,7 @@ static void __init n30_init(void)
+ {
+ s3c24xx_fb_set_platdata(&n30_lcdcfg);
+ set_s3c2410bl_info(&n30_blcfg);
++ set_s3c2410ts_info(&n30_ts_cfg);
+
+ s3c_device_i2c.dev.platform_data = &n30_i2ccfg;
+
diff --git a/recipes/linux/linux/acern30/n30-usbstart.patch b/recipes/linux/linux/acern30/n30-usbstart.patch
new file mode 100644
index 0000000000..b7479b50e4
--- /dev/null
+++ b/recipes/linux/linux/acern30/n30-usbstart.patch
@@ -0,0 +1,59 @@
+This patch tries to start the USB gadget in a nice way by
+disconnecting and then reconnecting the pull up.
+
+I ought to use the same callback and configuration as RTP does in
+mach-h1940.
+
+Index: linux-2.6.14/arch/arm/mach-s3c2410/mach-n30.c
+===================================================================
+--- linux-2.6.14.orig/arch/arm/mach-s3c2410/mach-n30.c
++++ linux-2.6.14/arch/arm/mach-s3c2410/mach-n30.c
+@@ -356,7 +356,33 @@ static void __init n30_init_irq(void)
+ s3c24xx_init_irq();
+ }
+
+-/* GPB3 is the line that controls the pull-up for the USB D+ line */
++static int n30_usbstart_thread(void *unused)
++{
++ /* Disable both USB ports */
++ s3c2410_modify_misccr(S3C2410_MISCCR_USBSUSPND0 |
++ S3C2410_MISCCR_USBSUSPND1,
++ S3C2410_MISCCR_USBSUSPND0 |
++ S3C2410_MISCCR_USBSUSPND1);
++
++ /* Turn off the D+ pull up for a few second so that the USB
++ * host at the other end will do a rescan of the USB bus. */
++ s3c2410_gpio_setpin(S3C2410_GPB3, 0);
++
++ msleep_interruptible(1 * 1000);
++
++ /* Enable the USB host port if this is a n30 */
++ if (machine_is_n30())
++ s3c2410_modify_misccr(S3C2410_MISCCR_USBSUSPND0, 0);
++
++ /* Turn off suspend on USB device port and switch it to device
++ * mode. */
++ s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
++ S3C2410_MISCCR_USBSUSPND1, 0x0);
++
++ s3c2410_gpio_setpin(S3C2410_GPB3, 1);
++
++ return 0;
++}
+
+ static void __init n30_init(void)
+ {
+@@ -380,12 +406,7 @@ static void __init n30_init(void)
+ msleep(1);
+ s3c2410_gpio_setpin(S3C2410_GPC5, 1);
+
+- /* Turn off suspend on both USB ports, and switch the
+- * selectable USB port to USB device mode. */
+-
+- s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
+- S3C2410_MISCCR_USBSUSPND0 |
+- S3C2410_MISCCR_USBSUSPND1, 0x0);
++ kthread_run(n30_usbstart_thread, NULL, "n30_usbstart");
+ }
+
+ MACHINE_START(N30, "Acer-N30")
diff --git a/recipes/linux/linux/acern30/n35.patch b/recipes/linux/linux/acern30/n35.patch
new file mode 100644
index 0000000000..75f1818eee
--- /dev/null
+++ b/recipes/linux/linux/acern30/n35.patch
@@ -0,0 +1,80 @@
+Index: linux-2.6.14/arch/arm/tools/mach-types
+===================================================================
+--- linux-2.6.14.orig/arch/arm/tools/mach-types
++++ linux-2.6.14/arch/arm/tools/mach-types
+@@ -869,3 +869,4 @@ davinci_dvdp MACH_DAVINCI_DVDP DAVINCI_
+ htcuniversal MACH_HTCUNIVERSAL HTCUNIVERSAL 855
+ tpad MACH_TPAD TPAD 856
+ roverp3 MACH_ROVERP3 ROVERP3 857
++n35 MACH_N35 N35 927
+Index: linux-2.6.14/arch/arm/mach-s3c2410/mach-n30.c
+===================================================================
+--- linux-2.6.14.orig/arch/arm/mach-s3c2410/mach-n30.c
++++ linux-2.6.14/arch/arm/mach-s3c2410/mach-n30.c
+@@ -1,5 +1,14 @@
+ /* linux/arch/arm/mach-s3c2410/mach-n30.c
+ *
++ * Machine specific code for the following PDAs:
++ *
++ * Acer N30
++ *
++ * Acer N35
++ * Navman PiN 570
++ * Yakumo AlphaX (untested)
++ * Airis NC05 (untested)
++ *
+ * Copyright (c) 2003-2005 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+@@ -65,7 +74,8 @@ static struct s3c2410_uartcfg n30_uartcf
+ .ulcon = 0x43,
+ .ufcon = 0x51,
+ },
+- /* The BlueTooth controller is connected to port 2 */
++ /* On the N30 the bluetooth controller is connected here.
++ * On the N35 and variants the GPS receiver is connected here. */
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+@@ -136,3 +146,16 @@ MACHINE_START(N30, "Acer-N30")
+ .init_irq = n30_init_irq,
+ .map_io = n30_map_io,
+ MACHINE_END
++
++MACHINE_START(N35, "Acer-N35")
++ /* Maintainer: Christer Weinigel <christer@weinigel.se>
++ */
++ .phys_ram = S3C2410_SDRAM_PA,
++ .phys_io = S3C2410_PA_UART,
++ .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
++ .boot_params = S3C2410_SDRAM_PA + 0x100,
++ .timer = &s3c24xx_timer,
++ .init_machine = n30_init,
++ .init_irq = n30_init_irq,
++ .map_io = n30_map_io,
++MACHINE_END
+Index: linux-2.6.14/arch/arm/mach-s3c2410/Kconfig
+===================================================================
+--- linux-2.6.14.orig/arch/arm/mach-s3c2410/Kconfig
++++ linux-2.6.14/arch/arm/mach-s3c2410/Kconfig
+@@ -39,9 +39,18 @@ config MACH_N30
+ bool "Acer N30"
+ select CPU_S3C2410
+ help
+- Say Y here if you are using the Acer N30
++ Say Y here if you want support for the Acer N30 PDA.
+
+- <http://zoo.weinigel.se/n30>.
++ <http://www.handhelds.org/moin/moin.cgi/AcerN30>.
++
++config MACH_N35
++ bool "Acer N35/Navman PiN 570"
++ select CPU_S3C2410
++ help
++ Say Y here if you want support for the Acer N35 or
++ Navman PiN 570 PDAs.
++
++ <http://www.handhelds.org/moin/moin.cgi/AcerN30>.
+
+ config ARCH_SMDK2410
+ bool "SMDK2410/A9M2410"
diff --git a/recipes/linux/linux/acern30/regdump.patch b/recipes/linux/linux/acern30/regdump.patch
new file mode 100644
index 0000000000..9e5ffe370d
--- /dev/null
+++ b/recipes/linux/linux/acern30/regdump.patch
@@ -0,0 +1,279 @@
+Add some code to dump most registers. It's a good way to find in what
+state the bootloader or Windows has left the device.
+
+Index: linux-2.6.14/arch/arm/mach-s3c2410/regdump.c
+===================================================================
+--- /dev/null
++++ linux-2.6.14/arch/arm/mach-s3c2410/regdump.c
+@@ -0,0 +1,261 @@
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/interrupt.h>
++#include <linux/ioport.h>
++
++#include <asm/hardware.h>
++#include <asm/irq.h>
++#include <asm/io.h>
++
++#include <asm/arch/map.h>
++#include <asm/arch/regs-adc.h>
++#include <asm/arch/regs-clock.h>
++#include <asm/arch/regs-gpio.h>
++#include <asm/arch/regs-iic.h>
++#include <asm/arch/regs-iis.h>
++#include <asm/arch/regs-irq.h>
++#include <asm/arch/regs-lcd.h>
++#include <asm/arch/regs-mem.h>
++#include <asm/arch/regs-nand.h>
++#include <asm/arch/regs-rtc.h>
++#include <asm/arch/regs-timer.h>
++#include <asm/arch/regs-udc.h>
++#include <asm/arch/regs-watchdog.h>
++
++#define REGV(reg) { #reg, (reg) }
++#define REGI(va, reg) { #reg, (va) + (reg) }
++
++static struct reginfo {
++ const char *name;
++ void *va;
++} reginfo[] = {
++ /* ADC */
++ REGI(S3C24XX_VA_ADC, S3C2410_ADCCON),
++ REGI(S3C24XX_VA_ADC, S3C2410_ADCTSC),
++ REGI(S3C24XX_VA_ADC, S3C2410_ADCDLY),
++ REGI(S3C24XX_VA_ADC, S3C2410_ADCDAT0),
++ REGI(S3C24XX_VA_ADC, S3C2410_ADCDAT1),
++
++ /* Clocks */
++ REGV(S3C2410_LOCKTIME),
++ REGV(S3C2410_MPLLCON),
++ REGV(S3C2410_UPLLCON),
++ REGV(S3C2410_CLKCON),
++ REGV(S3C2410_CLKSLOW),
++ REGV(S3C2410_CLKDIVN),
++
++ /* GPIO */
++ REGV(S3C2410_GPACON),
++ REGV(S3C2410_GPADAT),
++ REGV(S3C2410_GPBCON),
++ REGV(S3C2410_GPBDAT),
++ REGV(S3C2410_GPBUP),
++ REGV(S3C2410_GPCCON),
++ REGV(S3C2410_GPCDAT),
++ REGV(S3C2410_GPCUP),
++ REGV(S3C2410_GPDCON),
++ REGV(S3C2410_GPDDAT),
++ REGV(S3C2410_GPDUP),
++ REGV(S3C2410_GPECON),
++ REGV(S3C2410_GPEDAT),
++ REGV(S3C2410_GPEUP),
++ REGV(S3C2410_GPFCON),
++ REGV(S3C2410_GPFDAT),
++ REGV(S3C2410_GPFUP),
++ REGV(S3C2410_GPGCON),
++ REGV(S3C2410_GPGDAT),
++ REGV(S3C2410_GPGUP),
++ REGV(S3C2410_GPHCON),
++ REGV(S3C2410_GPHDAT),
++ REGV(S3C2410_GPHUP),
++ REGV(S3C2410_MISCCR),
++ REGV(S3C2410_DCLKCON),
++ REGV(S3C2410_EXTINT0),
++ REGV(S3C2410_EXTINT1),
++ REGV(S3C2410_EXTINT2),
++ REGV(S3C2410_EINFLT0),
++ REGV(S3C2410_EINFLT1),
++ REGV(S3C2410_EINFLT2),
++ REGV(S3C2410_EINFLT3),
++ REGV(S3C2410_GSTATUS0),
++ REGV(S3C2410_GSTATUS1),
++ REGV(S3C2410_GSTATUS2),
++ REGV(S3C2410_GSTATUS3),
++ REGV(S3C2410_GSTATUS4),
++
++#if 0
++ /* IIC */
++ REGI(S3C24XX_VA_IIC, S3C2410_IICCON),
++ REGI(S3C24XX_VA_IIC, S3C2410_IICSTAT),
++ REGI(S3C24XX_VA_IIC, S3C2410_IICADD),
++ REGI(S3C24XX_VA_IIC, S3C2410_IICDS),
++
++ /* IIS */
++ REGI(S3C24XX_VA_IIS, S3C2410_IISCON),
++ REGI(S3C24XX_VA_IIS, S3C2410_IISMOD),
++ REGI(S3C24XX_VA_IIS, S3C2410_IISPSR),
++ REGI(S3C24XX_VA_IIS, S3C2410_IISFCON),
++ REGI(S3C24XX_VA_IIS, S3C2410_IISFIFO),
++#endif
++
++ /* IRQ */
++ REGV(S3C2410_SRCPND),
++ REGV(S3C2410_INTMOD),
++ REGV(S3C2410_INTMSK),
++ REGV(S3C2410_PRIORITY),
++ REGV(S3C2410_INTPND),
++ REGV(S3C2410_INTOFFSET),
++ REGV(S3C2410_SUBSRCPND),
++ REGV(S3C2410_INTSUBMSK),
++ REGV(S3C2410_EINTMASK),
++ REGV(S3C2410_EINTPEND),
++
++ /* LCD */
++ REGV(S3C2410_LCDCON1),
++ REGV(S3C2410_LCDCON2),
++ REGV(S3C2410_LCDCON3),
++ REGV(S3C2410_LCDCON4),
++ REGV(S3C2410_LCDCON5),
++ REGV(S3C2410_LCDSADDR1),
++ REGV(S3C2410_LCDSADDR2),
++ REGV(S3C2410_LCDSADDR3),
++ REGV(S3C2410_REDLUT),
++ REGV(S3C2410_GREENLUT),
++ REGV(S3C2410_BLUELUT),
++ REGV(S3C2410_DITHMODE),
++ REGV(S3C2410_TPAL),
++ REGV(S3C2410_LCDINTPND),
++ REGV(S3C2410_LCDSRCPND),
++ REGV(S3C2410_LCDINTMSK),
++ REGV(S3C2410_LPCSEL),
++
++ // REGV(S3C2410_TFTPAL(x)),
++
++#if 0
++ /* Memory controller */
++ REGV(S3C2410_BWSCON),
++ REGV(S3C2410_BANKCON0),
++ REGV(S3C2410_BANKCON1),
++ REGV(S3C2410_BANKCON2),
++ REGV(S3C2410_BANKCON3),
++ REGV(S3C2410_BANKCON4),
++ REGV(S3C2410_BANKCON5),
++ REGV(S3C2410_BANKCON6),
++ REGV(S3C2410_BANKCON7),
++ REGV(S3C2410_REFRESH),
++ REGV(S3C2410_BANKSIZE),
++ REGV(S3C2410_MRSRB6),
++ REGV(S3C2410_MRSRB7),
++
++ /* Nand flash */
++ REGI(S3C24XX_VA_NAND, S3C2410_NFCONF),
++ REGI(S3C24XX_VA_NAND, S3C2410_NFCMD),
++ REGI(S3C24XX_VA_NAND, S3C2410_NFADDR),
++ REGI(S3C24XX_VA_NAND, S3C2410_NFDATA),
++ REGI(S3C24XX_VA_NAND, S3C2410_NFSTAT),
++ REGI(S3C24XX_VA_NAND, S3C2410_NFECC),
++
++ /* RTC */
++ REGV(S3C2410_RTCCON),
++ REGV(S3C2410_TICNT),
++ REGV(S3C2410_RTCALM),
++ REGV(S3C2410_ALMSEC),
++ REGV(S3C2410_ALMMIN),
++ REGV(S3C2410_ALMHOUR),
++ REGV(S3C2410_ALMDATE),
++ REGV(S3C2410_ALMMON),
++ REGV(S3C2410_ALMYEAR),
++ REGV(S3C2410_RTCRST),
++ REGV(S3C2410_RTCSEC),
++ REGV(S3C2410_RTCMIN),
++ REGV(S3C2410_RTCHOUR),
++ REGV(S3C2410_RTCDATE),
++ REGV(S3C2410_RTCDAY),
++ REGV(S3C2410_RTCMON),
++ REGV(S3C2410_RTCYEAR),
++#endif
++
++ /* Timer */
++ REGV(S3C2410_TCFG0),
++ REGV(S3C2410_TCFG1),
++ REGV(S3C2410_TCON),
++
++ /* USB Device */
++ REGI(S3C24XX_VA_USBDEV, S3C2410_UDC_FUNC_ADDR_REG),
++ REGI(S3C24XX_VA_USBDEV, S3C2410_UDC_PWR_REG),
++ REGI(S3C24XX_VA_USBDEV, S3C2410_UDC_EP_INT_REG),
++ REGI(S3C24XX_VA_USBDEV, S3C2410_UDC_USB_INT_REG),
++ REGI(S3C24XX_VA_USBDEV, S3C2410_UDC_EP_INT_EN_REG),
++ REGI(S3C24XX_VA_USBDEV, S3C2410_UDC_USB_INT_EN_REG),
++ REGI(S3C24XX_VA_USBDEV, S3C2410_UDC_FRAME_NUM1_REG),
++ REGI(S3C24XX_VA_USBDEV, S3C2410_UDC_FRAME_NUM2_REG),
++ REGI(S3C24XX_VA_USBDEV, S3C2410_UDC_EP0_FIFO_REG),
++ REGI(S3C24XX_VA_USBDEV, S3C2410_UDC_EP1_FIFO_REG),
++ REGI(S3C24XX_VA_USBDEV, S3C2410_UDC_EP2_FIFO_REG),
++ REGI(S3C24XX_VA_USBDEV, S3C2410_UDC_EP3_FIFO_REG),
++ REGI(S3C24XX_VA_USBDEV, S3C2410_UDC_EP4_FIFO_REG),
++ REGI(S3C24XX_VA_USBDEV, S3C2410_UDC_EP1_DMA_CON),
++ REGI(S3C24XX_VA_USBDEV, S3C2410_UDC_EP1_DMA_UNIT),
++ REGI(S3C24XX_VA_USBDEV, S3C2410_UDC_EP1_DMA_FIFO),
++ REGI(S3C24XX_VA_USBDEV, S3C2410_UDC_EP1_DMA_TTC_L),
++ REGI(S3C24XX_VA_USBDEV, S3C2410_UDC_EP1_DMA_TTC_M),
++ REGI(S3C24XX_VA_USBDEV, S3C2410_UDC_EP1_DMA_TTC_H),
++ REGI(S3C24XX_VA_USBDEV, S3C2410_UDC_EP2_DMA_CON),
++ REGI(S3C24XX_VA_USBDEV, S3C2410_UDC_EP2_DMA_UNIT),
++ REGI(S3C24XX_VA_USBDEV, S3C2410_UDC_EP2_DMA_FIFO),
++ REGI(S3C24XX_VA_USBDEV, S3C2410_UDC_EP2_DMA_TTC_L),
++ REGI(S3C24XX_VA_USBDEV, S3C2410_UDC_EP2_DMA_TTC_M),
++ REGI(S3C24XX_VA_USBDEV, S3C2410_UDC_EP2_DMA_TTC_H),
++ REGI(S3C24XX_VA_USBDEV, S3C2410_UDC_EP3_DMA_CON),
++ REGI(S3C24XX_VA_USBDEV, S3C2410_UDC_EP3_DMA_UNIT),
++ REGI(S3C24XX_VA_USBDEV, S3C2410_UDC_EP3_DMA_FIFO),
++ REGI(S3C24XX_VA_USBDEV, S3C2410_UDC_EP3_DMA_TTC_L),
++ REGI(S3C24XX_VA_USBDEV, S3C2410_UDC_EP3_DMA_TTC_M),
++ REGI(S3C24XX_VA_USBDEV, S3C2410_UDC_EP3_DMA_TTC_H),
++ REGI(S3C24XX_VA_USBDEV, S3C2410_UDC_EP4_DMA_CON),
++ REGI(S3C24XX_VA_USBDEV, S3C2410_UDC_EP4_DMA_UNIT),
++ REGI(S3C24XX_VA_USBDEV, S3C2410_UDC_EP4_DMA_FIFO),
++ REGI(S3C24XX_VA_USBDEV, S3C2410_UDC_EP4_DMA_TTC_L),
++ REGI(S3C24XX_VA_USBDEV, S3C2410_UDC_EP4_DMA_TTC_M),
++ REGI(S3C24XX_VA_USBDEV, S3C2410_UDC_EP4_DMA_TTC_H),
++ REGI(S3C24XX_VA_USBDEV, S3C2410_UDC_INDEX_REG),
++ REGI(S3C24XX_VA_USBDEV, S3C2410_UDC_MAXP_REG),
++ REGI(S3C24XX_VA_USBDEV, S3C2410_UDC_EP0_CSR_REG),
++ REGI(S3C24XX_VA_USBDEV, S3C2410_UDC_IN_CSR1_REG),
++ REGI(S3C24XX_VA_USBDEV, S3C2410_UDC_IN_CSR2_REG),
++ REGI(S3C24XX_VA_USBDEV, S3C2410_UDC_OUT_CSR1_REG),
++ REGI(S3C24XX_VA_USBDEV, S3C2410_UDC_OUT_CSR2_REG),
++ REGI(S3C24XX_VA_USBDEV, S3C2410_UDC_OUT_FIFO_CNT1_REG),
++ REGI(S3C24XX_VA_USBDEV, S3C2410_UDC_OUT_FIFO_CNT2_REG),
++
++ /* Watchdog */
++ REGV(S3C2410_WTCON),
++ REGV(S3C2410_WTDAT),
++ REGV(S3C2410_WTCNT),
++};
++
++static u32 regval[ARRAY_SIZE(reginfo)];
++
++void s3c2410_capture_regs(void)
++{
++ int i;
++
++ for (i = 0; i < ARRAY_SIZE(reginfo); i++)
++ regval[i] = readl(reginfo[i].va);
++}
++
++void s3c2410_dump_regs(void)
++{
++ int i;
++
++ for (i = 0; i < ARRAY_SIZE(reginfo); i++)
++ printk("%-20s = 0x%08x\n", reginfo[i].name, regval[i]);
++}
++
++/*
++ Local variables:
++ compile-command: "make -k -C ../../../.. linux "
++ c-basic-offset: 8
++ End:
++*/
+Index: linux-2.6.14/arch/arm/mach-s3c2410/Makefile
+===================================================================
+--- linux-2.6.14.orig/arch/arm/mach-s3c2410/Makefile
++++ linux-2.6.14/arch/arm/mach-s3c2410/Makefile
+@@ -44,3 +44,5 @@ obj-$(CONFIG_MACH_OTOM) += mach-otom.o
+ obj-$(CONFIG_MACH_NEXCODER_2440) += mach-nexcoder.o
+
+ obj-y += gpio-sysfs.o
++obj-y += regdump.o
++
diff --git a/recipes/linux/linux/acern30/s3c2410-nand-pm.patch b/recipes/linux/linux/acern30/s3c2410-nand-pm.patch
new file mode 100644
index 0000000000..b53a2f2760
--- /dev/null
+++ b/recipes/linux/linux/acern30/s3c2410-nand-pm.patch
@@ -0,0 +1,53 @@
+Index: linux-2.6.14/drivers/mtd/nand/s3c2410.c
+===================================================================
+--- linux-2.6.14.orig/drivers/mtd/nand/s3c2410.c
++++ linux-2.6.14/drivers/mtd/nand/s3c2410.c
+@@ -692,11 +692,39 @@ static int s3c2440_nand_probe(struct dev
+ return s3c24xx_nand_probe(dev, 1);
+ }
+
++#ifdef CONFIG_PM
++
++static int s3c2410_nand_suspend(struct device *dev, pm_message_t state)
++{
++ struct s3c2410_nand_info *info = to_nand_info(dev);
++
++ clk_disable(info->clk);
++
++ return 0;
++}
++
++static int s3c2410_nand_resume(struct device *dev)
++{
++ struct s3c2410_nand_info *info = to_nand_info(dev);
++
++ clk_enable(info->clk);
++ msleep(1);
++
++ return s3c2410_nand_inithw(info, dev);
++}
++
++#else
++#define s3c2410_nand_suspend NULL
++#define s3c2410_nand_resume NULL
++#endif
++
+ static struct device_driver s3c2410_nand_driver = {
+ .name = "s3c2410-nand",
+ .bus = &platform_bus_type,
+ .probe = s3c2410_nand_probe,
+ .remove = s3c2410_nand_remove,
++ .suspend = s3c2410_nand_suspend,
++ .resume = s3c2410_nand_resume,
+ };
+
+ static struct device_driver s3c2440_nand_driver = {
+@@ -704,6 +732,8 @@ static struct device_driver s3c2440_nand
+ .bus = &platform_bus_type,
+ .probe = s3c2440_nand_probe,
+ .remove = s3c2410_nand_remove,
++ .suspend = s3c2410_nand_suspend,
++ .resume = s3c2410_nand_resume,
+ };
+
+ static int __init s3c2410_nand_init(void)
diff --git a/recipes/linux/linux/acern30/s3c2410_lcd-pm.c b/recipes/linux/linux/acern30/s3c2410_lcd-pm.c
new file mode 100644
index 0000000000..304baf385c
--- /dev/null
+++ b/recipes/linux/linux/acern30/s3c2410_lcd-pm.c
@@ -0,0 +1,80 @@
+Index: linux-2.6.14/drivers/video/backlight/s3c2410_lcd.c
+===================================================================
+--- linux-2.6.14.orig/drivers/video/backlight/s3c2410_lcd.c
++++ linux-2.6.14/drivers/video/backlight/s3c2410_lcd.c
+@@ -248,10 +248,75 @@ static int s3c2410bl_remove(struct devic
+
+ }
+
++#ifdef CONFIG_PM
++
++static int s3c2410bl_suspend(struct device *dev, pm_message_t state)
++{
++ struct s3c2410_bl_mach_info *info =
++ (struct s3c2410_bl_mach_info *)dev->platform_data;
++
++ if (info) {
++ if (info->backlight_power)
++ info->backlight_power(0);
++ if (info->lcd_power)
++ info->lcd_power(0);
++ }
++
++ return 0;
++}
++
++static int s3c2410bl_resume(struct device *dev)
++{
++ struct s3c2410_bl_mach_info *info =
++ (struct s3c2410_bl_mach_info *)dev->platform_data;
++
++ if (info) {
++ if (info->lcd_power) {
++ switch(info->lcd_power_value) {
++ case FB_BLANK_NORMAL:
++ case FB_BLANK_POWERDOWN:
++ info->lcd_power(0);
++ break;
++ default:
++ case FB_BLANK_VSYNC_SUSPEND:
++ case FB_BLANK_HSYNC_SUSPEND:
++ case FB_BLANK_UNBLANK:
++ info->lcd_power(1);
++ break;
++ }
++ }
++ if (info->backlight_power) {
++ switch(info->backlight_power_value) {
++ case FB_BLANK_NORMAL:
++ case FB_BLANK_VSYNC_SUSPEND:
++ case FB_BLANK_HSYNC_SUSPEND:
++ case FB_BLANK_POWERDOWN:
++ info->backlight_power(0);
++ break;
++ default:
++ case FB_BLANK_UNBLANK:
++ info->backlight_power(1);
++ break;
++ }
++ }
++ if (info->set_brightness)
++ info->set_brightness(info->brightness_value);
++ }
++
++ return 0;
++}
++
++#else
++#define s3c2410bl_suspend NULL
++#define s3c2410bl_resume NULL
++#endif
++
+ static struct device_driver s3c2410bl_driver = {
+ .name = "s3c2410-bl",
+ .bus = &platform_bus_type,
+ .probe = s3c2410bl_probe,
++ .suspend = s3c2410bl_suspend,
++ .resume = s3c2410bl_resume,
+ .remove = s3c2410bl_remove,
+ };
+
diff --git a/recipes/linux/linux/acern30/s3c2410_ts-pm.patch b/recipes/linux/linux/acern30/s3c2410_ts-pm.patch
new file mode 100644
index 0000000000..ef89f7042f
--- /dev/null
+++ b/recipes/linux/linux/acern30/s3c2410_ts-pm.patch
@@ -0,0 +1,73 @@
+Index: linux-2.6.14/drivers/input/touchscreen/s3c2410_ts.c
+===================================================================
+--- linux-2.6.14.orig/drivers/input/touchscreen/s3c2410_ts.c
++++ linux-2.6.14/drivers/input/touchscreen/s3c2410_ts.c
+@@ -56,6 +56,8 @@
+ /* For ts.dev.id.version */
+ #define S3C2410TSVERSION 0x0101
+
++#define TSC_SLEEP (S3C2410_ADCTSC_PULL_UP_DISABLE | S3C2410_ADCTSC_XY_PST(0))
++
+ #define WAIT4INT(x) (((x)<<8) | \
+ S3C2410_ADCTSC_YM_SEN | S3C2410_ADCTSC_YP_SEN | S3C2410_ADCTSC_XP_SEN | \
+ S3C2410_ADCTSC_XY_PST(3))
+@@ -321,10 +323,59 @@ static int s3c2410ts_remove(struct devic
+ return 0;
+ }
+
++#ifdef CONFIG_PM
++
++static int s3c2410ts_suspend(struct device *dev, pm_message_t state)
++{
++ writel(TSC_SLEEP, base_addr+S3C2410_ADCTSC);
++ writel(readl(base_addr+S3C2410_ADCCON) | S3C2410_ADCCON_STDBM,
++ base_addr+S3C2410_ADCCON);
++
++ disable_irq(IRQ_ADC);
++ disable_irq(IRQ_TC);
++
++ clk_disable(adc_clock);
++
++ return 0;
++}
++
++static int s3c2410ts_resume(struct device *dev)
++{
++ struct s3c2410_ts_mach_info *info =
++ (struct s3c2410_ts_mach_info *)dev->platform_data;
++
++ clk_enable(adc_clock);
++ msleep(1);
++
++ enable_irq(IRQ_ADC);
++ enable_irq(IRQ_TC);
++
++ if ((info->presc&0xff) > 0)
++ writel(S3C2410_ADCCON_PRSCEN | S3C2410_ADCCON_PRSCVL(info->presc&0xFF),\
++ base_addr+S3C2410_ADCCON);
++ else
++ writel(0,base_addr+S3C2410_ADCCON);
++
++ /* Initialise registers */
++ if ((info->delay&0xffff) > 0)
++ writel(info->delay & 0xffff, base_addr+S3C2410_ADCDLY);
++
++ writel(WAIT4INT(0), base_addr+S3C2410_ADCTSC);
++
++ return 0;
++}
++
++#else
++#define s3c2410ts_suspend NULL
++#define s3c2410ts_resume NULL
++#endif
++
+ static struct device_driver s3c2410ts_driver = {
+ .name = "s3c2410-ts",
+ .bus = &platform_bus_type,
+ .probe = s3c2410ts_probe,
++ .suspend = s3c2410ts_suspend,
++ .resume = s3c2410ts_resume,
+ .remove = s3c2410ts_remove,
+ };
+
diff --git a/recipes/linux/linux/acern30/s3c2410fb-resume.patch b/recipes/linux/linux/acern30/s3c2410fb-resume.patch
new file mode 100644
index 0000000000..b4727454cf
--- /dev/null
+++ b/recipes/linux/linux/acern30/s3c2410fb-resume.patch
@@ -0,0 +1,13 @@
+Index: linux-2.6.14/drivers/video/s3c2410fb.c
+===================================================================
+--- linux-2.6.14.orig/drivers/video/s3c2410fb.c
++++ linux-2.6.14/drivers/video/s3c2410fb.c
+@@ -569,7 +569,7 @@ int s3c2410fb_init_registers(struct s3c2
+
+ local_irq_restore(flags);
+
+- writel(fbi->regs.lcdcon1, S3C2410_LCDCON1);
++ writel(fbi->regs.lcdcon1 & ~S3C2410_LCDCON1_ENVID, S3C2410_LCDCON1);
+ writel(fbi->regs.lcdcon2, S3C2410_LCDCON2);
+ writel(fbi->regs.lcdcon3, S3C2410_LCDCON3);
+ writel(fbi->regs.lcdcon4, S3C2410_LCDCON4);
diff --git a/recipes/linux/linux/acern30/s3c2410mci-pm.patch b/recipes/linux/linux/acern30/s3c2410mci-pm.patch
new file mode 100644
index 0000000000..33a88713cb
--- /dev/null
+++ b/recipes/linux/linux/acern30/s3c2410mci-pm.patch
@@ -0,0 +1,84 @@
+Index: linux-2.6.14/drivers/mmc/s3c2410mci.c
+===================================================================
+--- linux-2.6.14.orig/drivers/mmc/s3c2410mci.c
++++ linux-2.6.14/drivers/mmc/s3c2410mci.c
+@@ -614,7 +614,8 @@ static int s3c2410sdi_probe(struct devic
+ goto probe_iounmap;
+ }
+
+- s3c2410_gpio_cfgpin(S3C2410_GPF5, S3C2410_GPF5_EINT5);
++ // This should be parametrised
++ // s3c2410_gpio_cfgpin(S3C2410_GPF5, S3C2410_GPF5_EINT5);
+ set_irq_type(host->irq_cd, IRQT_BOTHEDGE);
+
+ if(request_irq(host->irq_cd, s3c2410sdi_irq_cd, 0, DRIVER_NAME, host)) {
+@@ -732,12 +733,57 @@ static int s3c2410sdi_remove(struct devi
+ return 0;
+ }
+
++#ifdef CONFIG_PM
++static int s3c2410mci_suspend(struct device *dev, pm_message_t state)
++{
++ struct mmc_host *mmc = dev_get_drvdata(dev);
++ int ret = 0;
++
++ if (mmc) {
++ struct s3c2410sdi_host *host = mmc_priv(mmc);
++
++ ret = mmc_suspend_host(mmc, state);
++
++ clk_disable(host->clk);
++
++ disable_irq(host->irq_cd);
++ disable_irq(host->irq);
++ }
++
++ return ret;
++}
++
++static int s3c2410mci_resume(struct device *dev)
++{
++ struct mmc_host *mmc = dev_get_drvdata(dev);
++ int ret = 0;
++
++ if (mmc) {
++ struct s3c2410sdi_host *host = mmc_priv(mmc);
++
++ enable_irq(host->irq_cd);
++ enable_irq(host->irq);
++
++ clk_enable(host->clk);
++
++ ret = mmc_resume_host(mmc);
++ }
++
++ return ret;
++}
++#else
++#define s3c2410mci_suspend NULL
++#define s3c2410mci_resume NULL
++#endif
++
+ static struct device_driver s3c2410sdi_driver =
+ {
+ .name = "s3c2410-sdi",
+ .bus = &platform_bus_type,
+ .probe = s3c2410sdi_probe,
+ .remove = s3c2410sdi_remove,
++ .suspend = s3c2410mci_suspend,
++ .resume = s3c2410mci_resume,
+ };
+
+ static int __init s3c2410sdi_init(void)
+Index: linux-2.6.14/drivers/mmc/mmc.c
+===================================================================
+--- linux-2.6.14.orig/drivers/mmc/mmc.c
++++ linux-2.6.14/drivers/mmc/mmc.c
+@@ -1263,6 +1263,7 @@ EXPORT_SYMBOL(mmc_suspend_host);
+ */
+ int mmc_resume_host(struct mmc_host *host)
+ {
++ mmc_power_up(host);
+ mmc_detect_change(host, 0);
+
+ return 0;
diff --git a/recipes/linux/linux/acern30/series b/recipes/linux/linux/acern30/series
new file mode 100644
index 0000000000..16b58a1144
--- /dev/null
+++ b/recipes/linux/linux/acern30/series
@@ -0,0 +1,27 @@
+v2.6.14-gitcurrent.patch
+v2.6.14-full.patch
+n30-cleanup.patch
+n35.patch
+n30-lcd.patch
+n30-backlight.patch
+n30-ts.patch
+n30-buttons.patch
+n30-mmc.patch
+n30-mmc-power.patch
+n30-mmc-wprotect.patch
+n30-nand.patch
+n30-usbstart.patch
+n30-hardcode.patch
+n30-apm.patch
+s3c2410fb-resume.patch
+s3c2410_ts-pm.patch
+s3c2410_lcd-pm.c
+s3c2410mci-pm.patch
+s3c2410-nand-pm.patch
+n30-nand-hack.patch
+mmc-plus.patch
+gpio-sysfs.patch
+regdump.patch
+n30-pm.patch
+spi.patch
+wingel-hacking.patch
diff --git a/recipes/linux/linux/acern30/spi.patch b/recipes/linux/linux/acern30/spi.patch
new file mode 100644
index 0000000000..f835f82d32
--- /dev/null
+++ b/recipes/linux/linux/acern30/spi.patch
@@ -0,0 +1,121 @@
+Index: linux-2.6.14/arch/arm/mach-s3c2410/mach-n30.c
+===================================================================
+--- linux-2.6.14.orig/arch/arm/mach-s3c2410/mach-n30.c
++++ linux-2.6.14/arch/arm/mach-s3c2410/mach-n30.c
+@@ -52,6 +52,7 @@
+ #include <asm/arch/regs-gpio.h>
+ #include <asm/arch/regs-lcd.h>
+ #include <asm/arch/regs-timer.h>
++#include <asm/arch/regs-spi.h>
+ #include <asm/arch/irqs.h>
+ #include <asm/arch/iic.h>
+ #include <asm/arch/fb.h>
+@@ -372,6 +373,7 @@ static struct platform_device *n30_devic
+ &s3c_device_usbgadget,
+ &s3c_device_sdi,
+ &s3c_device_nand,
++ &s3c_device_spi1,
+ };
+
+ static struct s3c2410_platform_i2c n30_i2ccfg = {
+@@ -712,6 +714,90 @@ static int n30_usbstart_thread(void *unu
+ return 0;
+ }
+
++static int spi_thread(void *regs)
++{
++ unsigned sptdat1 = ~0, sprdat1 = ~0, spsta1 = ~0;
++ unsigned value;
++
++ writel(0x01, regs + S3C2410_SPCON);
++ writel(0x02, regs + S3C2410_SPPIN);
++
++ s3c2410_gpio_cfgpin(S3C2410_GPG6, S3C2410_GPG6_SPIMOSI1);
++ s3c2410_gpio_cfgpin(S3C2410_GPG7, S3C2410_GPG7_SPICLK1);
++
++ s3c2410_gpio_cfgpin(S3C2410_GPG3, 0x3 << 6);
++
++ printk("GPGCON=0x%x\n", readl(S3C2410_GPGCON));
++
++ msleep(10);
++
++ while (1) {
++ value = readl(regs + S3C2410_SPTDAT);
++ if (sptdat1 != value) {
++ printk(KERN_INFO "SPTDAT1=0x%x\n", value);
++ sptdat1 = value;
++ }
++ value = readl(regs + S3C2410_SPRDAT);
++ if (sprdat1 != value) {
++ printk(KERN_INFO "SPRDAT1=0x%x\n", value);
++ sprdat1 = value;
++ }
++ value = readl(regs + S3C2410_SPSTA);
++ if (spsta1 != value) {
++ printk(KERN_INFO "SPSTA1=0x%x\n", value);
++ spsta1 = value;
++ }
++
++ msleep(10);
++ }
++}
++
++static int s3c24xx_spi_probe(struct device *dev)
++{
++ struct platform_device *pdev = to_platform_device(dev);
++ struct resource *res;
++ int ret;
++ void *regs;
++ struct resource *ioarea;
++
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ if (res == NULL) {
++ dev_err(dev, "cannot find IO resource\n");
++ ret = -ENOENT;
++ goto out;
++ }
++
++ ioarea = request_mem_region(res->start, (res->end-res->start)+1,
++ pdev->name);
++ if (ioarea == NULL) {
++ dev_err(dev, "cannot request IO\n");
++ ret = -ENXIO;
++ goto out;
++ }
++
++ regs = ioremap(res->start, (res->end-res->start)+1);
++ if (regs == NULL) {
++ dev_err(dev, "cannot map IO\n");
++ ret = -ENXIO;
++ goto out;
++ }
++
++ dev_info(dev, "registers %p (%p, %p)\n", regs, ioarea, res);
++
++ kthread_run(spi_thread, regs, "spi_debug");
++
++ ret = 0;
++
++ out:
++ return ret;
++}
++
++static struct device_driver s3c24xx_spi_driver = {
++ .name = "s3c2410-spi",
++ .bus = &platform_bus_type,
++ .probe = s3c24xx_spi_probe,
++};
++
+ #ifdef CONFIG_APM
+ static void n30_get_power_status(struct apm_power_info *info)
+ {
+@@ -764,6 +850,9 @@ static void __init n30_init(void)
+ memcpy_toio(N30_RESUME_VA, (void *)n30_resume,
+ &n30_resume_end - (void *)n30_resume);
+
++ if (driver_register(&s3c24xx_spi_driver) < 0)
++ printk(KERN_ERR "failed to register spi driver\n");
++
+ /* Clear any locks and write protects on the flash. */
+ s3c2410_gpio_setpin(S3C2410_GPC5, 1);
+ msleep(1);
diff --git a/recipes/linux/linux/acern30/wingel-hacking.patch b/recipes/linux/linux/acern30/wingel-hacking.patch
new file mode 100644
index 0000000000..e87de5a460
--- /dev/null
+++ b/recipes/linux/linux/acern30/wingel-hacking.patch
@@ -0,0 +1,1146 @@
+This patch contains some hacks that I'm playing around with right now.
+
+This isn't anything that should be merged into the official kernel.
+
+Index: linux-2.6.14/arch/arm/mach-s3c2410/mach-n30.c
+===================================================================
+--- linux-2.6.14.orig/arch/arm/mach-s3c2410/mach-n30.c
++++ linux-2.6.14/arch/arm/mach-s3c2410/mach-n30.c
+@@ -22,6 +22,12 @@
+ * published by the Free Software Foundation.
+ */
+
++// #define USBHACK 1
++#define SPIHACK 1
++
++void s3c2410_capture_regs(void);
++void s3c2410_dump_regs(void);
++
+ #include <linux/kernel.h>
+ #include <linux/types.h>
+ #include <linux/interrupt.h>
+@@ -272,14 +278,18 @@ static struct s3c2410_button n35_buttons
+
+ { IRQ_EINT13, S3C2410_GPG5, S3C2410_GPG5_EINT13, KEY_LEFT,
+ "Left_arrow", 0 },
++#ifndef SPIHACK
+ { IRQ_EINT14, S3C2410_GPG6, S3C2410_GPG6_EINT14, KEY_RIGHT,
+ "Right_arrow", 0 },
++#endif
+ { IRQ_EINT17, S3C2410_GPG9, S3C2410_GPG9_EINT17, KEY_UP,
+ "Up_arrow", 0 },
+ { IRQ_EINT16, S3C2410_GPG8, S3C2410_GPG8_EINT16, KEY_DOWN,
+ "Down_arrow", 0 },
++#ifndef SPIHACK
+ { IRQ_EINT15, S3C2410_GPG7, S3C2410_GPG7_EINT15, KEY_ENTER,
+ "Select", 0 },
++#endif
+
+ { IRQ_EINT7, S3C2410_GPF7, S3C2410_GPF7_EINT7, KEY_HOMEPAGE,
+ "Home", 0 },
+@@ -367,7 +377,6 @@ static struct platform_device *n30_devic
+ &s3c_device_usbgadget,
+ &s3c_device_sdi,
+ &s3c_device_nand,
+- &s3c_device_spi1,
+ };
+
+ static struct s3c2410_platform_i2c n30_i2ccfg = {
+@@ -382,6 +391,27 @@ static struct s3c24xx_board n30_board __
+ .devices_count = ARRAY_SIZE(n30_devices)
+ };
+
++static struct platform_device *n35_devices[] __initdata = {
++ &s3c_device_lcd,
++ &s3c_device_bl,
++ &s3c_device_ts,
++ &s3c_device_buttons,
++ &s3c_device_wdt,
++ &s3c_device_i2c,
++ &s3c_device_iis,
++ &s3c_device_usbgadget,
++ &s3c_device_sdi,
++ &s3c_device_nand,
++#ifdef SPIHACK
++ &s3c_device_spi1,
++#endif
++};
++
++static struct s3c24xx_board n35_board __initdata = {
++ .devices = n35_devices,
++ .devices_count = ARRAY_SIZE(n35_devices)
++};
++
+ /* Lots of hardcoded stuff, but it sets up the hardware in a useful
+ * state so that we can boot Linux directly from flash. */
+ static void __init n30_hwinit(void)
+@@ -674,7 +704,10 @@ static void __init n30_map_io(void)
+ n30_hwinit();
+ s3c24xx_init_clocks(0);
+ s3c24xx_init_uarts(n30_uartcfgs, ARRAY_SIZE(n30_uartcfgs));
+- s3c24xx_set_board(&n30_board);
++ if (machine_is_n30())
++ s3c24xx_set_board(&n30_board);
++ if (machine_is_n35())
++ s3c24xx_set_board(&n35_board);
+ }
+
+ static void __init n30_init_irq(void)
+@@ -710,90 +743,6 @@ static int n30_usbstart_thread(void *unu
+ return 0;
+ }
+
+-static int spi_thread(void *regs)
+-{
+- unsigned sptdat1 = ~0, sprdat1 = ~0, spsta1 = ~0;
+- unsigned value;
+-
+- writel(0x01, regs + S3C2410_SPCON);
+- writel(0x02, regs + S3C2410_SPPIN);
+-
+- s3c2410_gpio_cfgpin(S3C2410_GPG6, S3C2410_GPG6_SPIMOSI1);
+- s3c2410_gpio_cfgpin(S3C2410_GPG7, S3C2410_GPG7_SPICLK1);
+-
+- s3c2410_gpio_cfgpin(S3C2410_GPG3, 0x3 << 6);
+-
+- printk("GPGCON=0x%x\n", readl(S3C2410_GPGCON));
+-
+- msleep(10);
+-
+- while (1) {
+- value = readl(regs + S3C2410_SPTDAT);
+- if (sptdat1 != value) {
+- printk(KERN_INFO "SPTDAT1=0x%x\n", value);
+- sptdat1 = value;
+- }
+- value = readl(regs + S3C2410_SPRDAT);
+- if (sprdat1 != value) {
+- printk(KERN_INFO "SPRDAT1=0x%x\n", value);
+- sprdat1 = value;
+- }
+- value = readl(regs + S3C2410_SPSTA);
+- if (spsta1 != value) {
+- printk(KERN_INFO "SPSTA1=0x%x\n", value);
+- spsta1 = value;
+- }
+-
+- msleep(10);
+- }
+-}
+-
+-static int s3c24xx_spi_probe(struct device *dev)
+-{
+- struct platform_device *pdev = to_platform_device(dev);
+- struct resource *res;
+- int ret;
+- void *regs;
+- struct resource *ioarea;
+-
+- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+- if (res == NULL) {
+- dev_err(dev, "cannot find IO resource\n");
+- ret = -ENOENT;
+- goto out;
+- }
+-
+- ioarea = request_mem_region(res->start, (res->end-res->start)+1,
+- pdev->name);
+- if (ioarea == NULL) {
+- dev_err(dev, "cannot request IO\n");
+- ret = -ENXIO;
+- goto out;
+- }
+-
+- regs = ioremap(res->start, (res->end-res->start)+1);
+- if (regs == NULL) {
+- dev_err(dev, "cannot map IO\n");
+- ret = -ENXIO;
+- goto out;
+- }
+-
+- dev_info(dev, "registers %p (%p, %p)\n", regs, ioarea, res);
+-
+- kthread_run(spi_thread, regs, "spi_debug");
+-
+- ret = 0;
+-
+- out:
+- return ret;
+-}
+-
+-static struct device_driver s3c24xx_spi_driver = {
+- .name = "s3c2410-spi",
+- .bus = &platform_bus_type,
+- .probe = s3c24xx_spi_probe,
+-};
+-
+ #ifdef CONFIG_APM
+ static void n30_get_power_status(struct apm_power_info *info)
+ {
+@@ -825,6 +774,128 @@ static void n30_get_power_status(struct
+ }
+ #endif
+
++#define DEBUG_GPIO 1
++
++#ifdef DEBUG_GPIO
++static int n30_debug_thread(void *unused)
++{
++ int i;
++#define PIN(x) { x, #x }
++ static struct pin {
++ unsigned int pin;
++ const char *name;
++ } pins[] = {
++ PIN(S3C2410_GPA12),
++ PIN(S3C2410_GPB2),
++ PIN(S3C2410_GPB4),
++ PIN(S3C2410_GPB5),
++ PIN(S3C2410_GPB6),
++ PIN(S3C2410_GPB7),
++ PIN(S3C2410_GPC0),
++ PIN(S3C2410_GPC3),
++ PIN(S3C2410_GPC6),
++ PIN(S3C2410_GPC7),
++ PIN(S3C2410_GPC8),
++ PIN(S3C2410_GPD0),
++ PIN(S3C2410_GPD8),
++ PIN(S3C2410_GPD9),
++ PIN(S3C2410_GPD10),
++ PIN(S3C2410_GPE11),
++ PIN(S3C2410_GPE12),
++ PIN(S3C2410_GPE13),
++ PIN(S3C2410_GPF0),
++ PIN(S3C2410_GPF1),
++ PIN(S3C2410_GPF2),
++ PIN(S3C2410_GPF3),
++ PIN(S3C2410_GPG0),
++ PIN(S3C2410_GPG1),
++ PIN(S3C2410_GPG2),
++ PIN(S3C2410_GPG3),
++ PIN(S3C2410_GPG4),
++ PIN(S3C2410_GPH8),
++ };
++#undef PIN
++ enum { PIN_CNT = (sizeof(pins) / sizeof(struct pin)) };
++ static int values[PIN_CNT];
++ static int changes[PIN_CNT];
++
++ set_current_state(TASK_INTERRUPTIBLE);
++ schedule_timeout(1 * HZ);
++
++// s3c2410_dump_regs();
++
++ printk("AFTER\n");
++
++ s3c2410_capture_regs();
++
++// s3c2410_dump_regs();
++
++ for (i = 0; i < PIN_CNT; i++)
++ values[i] = s3c2410_gpio_getpin(pins[i].pin) ? 1 : 0;
++
++ printk("MISCCR=0x%08x\n", readl(S3C2410_MISCCR));
++
++ while (!kthread_should_stop()) {
++ for (i = 0; i < PIN_CNT; i++) {
++ int value = s3c2410_gpio_getpin(pins[i].pin) ? 1 : 0;
++
++ if (values[i] != value && changes[i] < 100) {
++ changes[i]++;
++ values[i] = value;
++ printk(KERN_CRIT "%s: %d (%d)\n", pins[i].name, value, changes[i]);
++ }
++ }
++
++ if (0) {
++ s3c2410_gpio_pullup(S3C2410_GPE15, 1);
++ s3c2410_gpio_cfgpin(S3C2410_GPE15, S3C2410_GPE15_OUTP);
++ s3c2410_gpio_setpin(S3C2410_GPE15, !s3c2410_gpio_getpin(S3C2410_GPE15));
++ }
++
++ if (0)
++ s3c2410_gpio_setpin(S3C2410_GPB3, !s3c2410_gpio_getpin(S3C2410_GPB3));
++
++ if (1) {
++ static int last_f0;
++ int f0 = s3c2410_gpio_getpin(S3C2410_GPF0);
++
++ if (last_f0 != f0) {
++ last_f0 = f0;
++ if (!f0) {
++ int r;
++ printk("entering suspend\n");
++ r = pm_suspend(PM_SUSPEND_MEM);
++ printk("after suspend %d\n", r);
++ }
++ }
++ }
++
++
++ if (0) {
++ static int last_f6;
++ int f6 = s3c2410_gpio_getpin(S3C2410_GPF6);
++
++ if (last_f6 != f6) {
++ last_f6 = f6;
++ if (!f6) {
++ if (s3c2410_gpio_getcfg(S3C2410_GPB6) != S3C2410_GPB6_OUTP) {
++ printk("B6 configured as output");
++ s3c2410_gpio_cfgpin(S3C2410_GPB6, S3C2410_GPB6_OUTP);
++ } else {
++ printk("B6 configured as input");
++ s3c2410_gpio_cfgpin(S3C2410_GPB6, S3C2410_GPB6_INP);
++ }
++ }
++ }
++ }
++
++ msleep(10);
++ }
++
++ return 0;
++}
++#endif
++
+ static void __init n30_init(void)
+ {
+ s3c24xx_fb_set_platdata(&n30_lcdcfg);
+@@ -846,9 +917,6 @@ static void __init n30_init(void)
+ memcpy_toio(N30_RESUME_VA, (void *)n30_resume,
+ &n30_resume_end - (void *)n30_resume);
+
+- if (driver_register(&s3c24xx_spi_driver) < 0)
+- printk(KERN_ERR "failed to register spi driver\n");
+-
+ /* Clear any locks and write protects on the flash. */
+ s3c2410_gpio_setpin(S3C2410_GPC5, 1);
+ msleep(1);
+@@ -861,6 +929,8 @@ static void __init n30_init(void)
+ #ifdef CONFIG_APM
+ apm_get_power_status = n30_get_power_status;
+ #endif
++
++ kthread_run(n30_debug_thread, NULL, "n30_debug");
+ }
+
+ MACHINE_START(N30, "Acer-N30")
+Index: linux-2.6.14/arch/arm/mach-s3c2410/Makefile
+===================================================================
+--- linux-2.6.14.orig/arch/arm/mach-s3c2410/Makefile
++++ linux-2.6.14/arch/arm/mach-s3c2410/Makefile
+@@ -46,3 +46,5 @@ obj-$(CONFIG_MACH_NEXCODER_2440) += mach
+ obj-y += gpio-sysfs.o
+ obj-y += regdump.o
+
++obj-m += spi-int.o
++obj-m += spi-dma.o
+Index: linux-2.6.14/arch/arm/mach-s3c2410/spi-int.c
+===================================================================
+--- /dev/null
++++ linux-2.6.14/arch/arm/mach-s3c2410/spi-int.c
+@@ -0,0 +1,261 @@
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/types.h>
++#include <linux/interrupt.h>
++#include <linux/init.h>
++#include <linux/device.h>
++#include <linux/kthread.h>
++#include <linux/delay.h>
++
++#include <asm/io.h>
++#include <asm/irq.h>
++
++#include <asm/hardware/clock.h>
++
++#include <asm/arch/regs-gpio.h>
++#include <asm/arch/regs-spi.h>
++#include <asm/arch/regs-irq.h>
++
++struct spi_info {
++ void *regs;
++ struct device *dev;
++ struct clk *clk;
++ struct resource *ioarea;
++ struct resource *irq;
++ struct task_struct *debug_thread;
++};
++
++static int spi_debug_thread(void *data)
++{
++ struct spi_info *info = data;
++ unsigned sptdat1 = ~0, sprdat1 = ~0, spsta1 = ~0;
++ unsigned value;
++
++ while (!kthread_should_stop()) {
++ if (1) {
++ value = readl(info->regs + S3C2410_SPTDAT);
++ if (sptdat1 != value) {
++ printk(KERN_INFO "SPTDAT1=0x%x\n", value);
++ sptdat1 = value;
++ }
++ value = readl(info->regs + S3C2410_SPRDAT);
++ if (sprdat1 != value) {
++ printk(KERN_INFO "SPRDAT1=0x%x\n", value);
++ sprdat1 = value;
++ }
++ value = readl(info->regs + S3C2410_SPSTA);
++ if (spsta1 != value) {
++ printk("SRCPND=0x%08x\n", readl(S3C2410_SRCPND));
++ printk("INTMOD=0x%08x\n", readl(S3C2410_INTMOD));
++ printk("INTMSK=0x%08x\n", readl(S3C2410_INTMSK));
++ printk("INTPND=0x%08x\n", readl(S3C2410_INTPND));
++
++ printk(KERN_INFO "SPSTA1=0x%x\n", value);
++ spsta1 = value;
++ }
++ }
++ if (1) {
++ if (readl(info->regs + S3C2410_SPSTA) & S3C2410_SPSTA_READY) {
++ value = readl(info->regs + S3C2410_SPRDAT);
++ printk("DAT=0x%02x\n", value);
++ writel(1, info->regs + S3C2410_SPTDAT);
++ }
++ }
++
++ msleep(1);
++ }
++
++ return 0;
++}
++
++static irqreturn_t spi_int_irq(int irq, void *dev_id, struct pt_regs *regs)
++{
++ struct spi_info *info = dev_id;
++ unsigned long status;
++
++ status = readl(info->regs + S3C2410_SPSTA);
++
++ if (status & S3C2410_SPSTA_READY) {
++ printk("INT %02x\n", readb(info->regs + S3C2410_SPRDAT));
++ writeb(0xff, info->regs + S3C2410_SPTDAT);
++ }
++
++ return IRQ_HANDLED;
++}
++
++static void spi_int_free(struct spi_info *info)
++{
++ if (!info)
++ return;
++
++ if (info->debug_thread)
++ kthread_stop(info->debug_thread);
++ if (info->irq)
++ free_irq(info->irq->start, info);
++ if (info->regs)
++ iounmap(info->regs);
++ if (info->ioarea) {
++ release_resource(info->ioarea);
++ kfree(info->ioarea);
++ }
++ if (info->clk) {
++ clk_unuse(info->clk);
++ clk_disable(info->clk);
++ }
++ kfree(info);
++}
++
++static int spi_int_probe(struct device *dev)
++{
++ struct platform_device *pdev = to_platform_device(dev);
++ int ret;
++ struct spi_info *info;
++ struct resource *res;
++
++ printk("spi_int_probe\n");
++
++ info = kmalloc(sizeof(struct spi_info), GFP_KERNEL);
++ if (!info) {
++ dev_err(dev, "failed to allocate info structure\n");
++ ret = -ENOMEM;
++ goto out;
++ }
++ memset(info, 0, sizeof(*info));
++ info->dev = dev;
++
++ dev_info(dev, "got info %p\n", info);
++
++ info->clk = clk_get(dev, "spi");
++ if (IS_ERR(info->clk)) {
++ dev_err(dev, "clk_get failed\n");
++ ret = -ENOENT;
++ goto out;
++ }
++
++ dev_dbg(dev, "clk %p\n", info->clk);
++
++ clk_use(info->clk);
++ clk_enable(info->clk);
++
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ if (!res) {
++ dev_err(dev, "unable to find registers\n");
++ ret = -ENOENT;
++ goto out;
++ }
++
++ dev_info(dev, "got res %p\n", res);
++
++ info->ioarea = request_mem_region(res->start,
++ (res->end-res->start)+1,
++ pdev->name);
++ if (!info->ioarea) {
++ dev_err(dev, "request_mem_region failed\n");
++ ret = -ENXIO;
++ goto out;
++ }
++
++ dev_info(dev, "got ioarea %p\n", info->ioarea);
++
++ info->regs = ioremap(res->start, (res->end-res->start)+1);
++ if (!info->regs) {
++ dev_err(dev, "ioremap failed\n");
++ ret = -ENXIO;
++ goto out;
++ }
++
++ dev_info(dev, "got regs %p\n", info->regs);
++
++ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
++ if (!res) {
++ dev_err(dev, "unable to find irq\n");
++ ret = -ENOENT;
++ goto out;
++ }
++
++ writel(S3C2410_SPCON_SMOD_INT /* | S3C2410_SPCON_TAGD */,
++ info->regs + S3C2410_SPCON);
++ writel(S3C2410_SPPIN_RESERVED, info->regs + S3C2410_SPPIN);
++
++ s3c2410_gpio_cfgpin(S3C2410_GPG5, S3C2410_GPG5_SPIMISO1);
++ s3c2410_gpio_cfgpin(S3C2410_GPG6, S3C2410_GPG6_SPIMOSI1);
++ s3c2410_gpio_cfgpin(S3C2410_GPG7, S3C2410_GPG7_SPICLK1);
++
++ s3c2410_gpio_cfgpin(S3C2410_GPG3, 0x3 << 6);
++
++ ret = request_irq(res->start, spi_int_irq, 0, pdev->name, info);
++ if (ret) {
++ dev_err(dev, "request_irq failed\n");
++ goto out;
++ }
++ info->irq = res;
++
++ dev_info(dev, "got irq %ld\n", info->irq->start);
++
++ dev_info(dev, "SPI driver active\n");
++
++ dev_set_drvdata(dev, info);
++ ret = 0;
++
++ writeb(0x00, info->regs + S3C2410_SPTDAT);
++
++ if (0) {
++ info->debug_thread = kthread_run(spi_debug_thread, info,
++ "spi_debug_thread");
++ }
++
++ printk("SRCPND=0x%08x\n", readl(S3C2410_SRCPND));
++ printk("INTMOD=0x%08x\n", readl(S3C2410_INTMOD));
++ printk("INTMSK=0x%08x\n", readl(S3C2410_INTMSK));
++ printk("INTPND=0x%08x\n", readl(S3C2410_INTPND));
++ printk("EINTMASK=0x%08x\n", readl(S3C2410_EINTMASK));
++
++ printk("SPCON=0x%08x\n", readl(info->regs + S3C2410_SPCON));
++ __raw_writel(S3C2410_SPCON_SMOD_INT | S3C2410_SPCON_TAGD,
++ info->regs + S3C2410_SPCON);
++ printk("SPCON=0x%08x\n", readl(info->regs + S3C2410_SPCON));
++ printk("FOO=0x%08x\n", S3C2410_SPCON_SMOD_INT);
++
++ out:
++ if (ret)
++ spi_int_free(info);
++
++ return ret;
++}
++
++static int spi_int_remove(struct device *dev)
++{
++ struct spi_info *info = dev_get_drvdata(dev);
++
++ dev_set_drvdata(dev, NULL);
++
++ spi_int_free(info);
++
++ return 0;
++}
++
++static struct device_driver spi_int_driver = {
++ .name = "s3c2410-spi",
++ .bus = &platform_bus_type,
++ .probe = spi_int_probe,
++ .remove = spi_int_remove,
++};
++
++static int __init spi_int_init(void)
++{
++ printk("SPI interrput driver loaded\n");
++
++ return driver_register(&spi_int_driver);
++}
++
++static void __exit spi_int_exit(void)
++{
++ driver_unregister(&spi_int_driver);
++}
++
++module_init(spi_int_init);
++module_exit(spi_int_exit);
++
++MODULE_DESCRIPTION("S3C2410 interrupt driven SPI driver");
++MODULE_AUTHOR("Christer Weinigel <christer@weinigel.se>");
++MODULE_LICENSE("GPL");
+Index: linux-2.6.14/arch/arm/mach-s3c2410/devs.c
+===================================================================
+--- linux-2.6.14.orig/arch/arm/mach-s3c2410/devs.c
++++ linux-2.6.14/arch/arm/mach-s3c2410/devs.c
+@@ -400,11 +400,17 @@ static struct resource s3c_spi0_resource
+
+ };
+
++static u64 s3c_device_spi0_dmamask = 0xffffffffUL;
++
+ struct platform_device s3c_device_spi0 = {
+ .name = "s3c2410-spi",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s3c_spi0_resource),
+ .resource = s3c_spi0_resource,
++ .dev = {
++ .dma_mask = &s3c_device_spi0_dmamask,
++ .coherent_dma_mask = 0xffffffffUL
++ }
+ };
+
+ EXPORT_SYMBOL(s3c_device_spi0);
+@@ -425,11 +431,17 @@ static struct resource s3c_spi1_resource
+
+ };
+
++static u64 s3c_device_spi1_dmamask = 0xffffffffUL;
++
+ struct platform_device s3c_device_spi1 = {
+ .name = "s3c2410-spi",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(s3c_spi1_resource),
+ .resource = s3c_spi1_resource,
++ .dev = {
++ .dma_mask = &s3c_device_spi1_dmamask,
++ .coherent_dma_mask = 0xffffffffUL
++ }
+ };
+
+ EXPORT_SYMBOL(s3c_device_spi1);
+Index: linux-2.6.14/arch/arm/mach-s3c2410/spi-dma.c
+===================================================================
+--- /dev/null
++++ linux-2.6.14/arch/arm/mach-s3c2410/spi-dma.c
+@@ -0,0 +1,498 @@
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/types.h>
++#include <linux/interrupt.h>
++#include <linux/init.h>
++#include <linux/device.h>
++#include <linux/kthread.h>
++#include <linux/delay.h>
++#include <linux/dma-mapping.h>
++#include <linux/spinlock.h>
++
++#include <asm/uaccess.h>
++#include <asm/dma.h>
++#include <asm/io.h>
++#include <asm/irq.h>
++
++#include <asm/hardware/clock.h>
++
++#include <asm/arch/dma.h>
++#include <asm/arch/regs-gpio.h>
++#include <asm/arch/regs-spi.h>
++
++#define BUFFER_SIZE (1024*1024)
++#define CHUNK_SIZE (64*1024)
++#define NUM_CHUNKS (BUFFER_SIZE / CHUNK_SIZE)
++
++static char spi_dma_name[] = "s3c2410-spi-dma-reader";
++
++static struct s3c2410_dma_client spi_dma_client = {
++ .name = spi_dma_name,
++};
++
++struct spi_dma_state {
++ struct spi_dma_info *info;
++ int status; /* 0=inactive, 1=running, <0 = -errno */
++ unsigned tail;
++};
++
++struct spi_chunk {
++ int index;
++ dma_addr_t handle;
++ struct spi_dma_info *info;
++};
++
++struct spi_dma_info {
++ void *cpu_addr;
++ dma_addr_t handle;
++ size_t size;
++
++ spinlock_t head_lock;
++ unsigned head;
++ wait_queue_head_t wait_q;
++
++ void *regs;
++
++ struct device *dev;
++ struct clk *clk;
++ struct resource *iomem;
++ int major;
++ dmach_t dmach;
++ int dcon;
++ int flushing;
++ char have_dma;
++ struct spi_chunk chunks[NUM_CHUNKS];
++};
++
++static void spi_queue_dma(struct spi_chunk *chunk)
++{
++ s3c2410_dma_enqueue(chunk->info->dmach,
++ chunk, chunk->handle, CHUNK_SIZE);
++}
++
++static void spi_dma_done_callback(s3c2410_dma_chan_t *dma_ch, void *buf_id,
++ int size, s3c2410_dma_buffresult_t result)
++{
++ struct spi_chunk *chunk = buf_id;
++ struct spi_dma_info *info = chunk->info;
++
++ if (info->flushing)
++ return;
++
++ spin_lock(&info->head_lock);
++ if ((info->head / CHUNK_SIZE) % NUM_CHUNKS != chunk->index)
++ dev_warn(info->dev, "out of sync, head=0x%x, index=0x%x\n",
++ info->head, chunk->index);
++
++ info->head += size;
++ spin_unlock(&info->head_lock);
++
++ wake_up_interruptible(&info->wait_q);
++
++ spi_queue_dma(chunk);
++}
++
++static struct spi_dma_info *global_info;
++
++static ssize_t spi_dma_read(struct file *file, char __user *buf,
++ size_t len, loff_t *ppos)
++{
++ DECLARE_WAITQUEUE(wait, current);
++ struct spi_dma_state *state = file->private_data;
++ struct spi_dma_info *info = state->info;
++ unsigned head;
++ ssize_t start, end;
++ ssize_t n;
++
++ if (state->status <= 0) {
++ if (state->status) {
++ state->status = 0;
++ return state->status;
++ }
++ state->tail = info->head;
++ state->status = 1;
++ }
++
++ add_wait_queue(&info->wait_q, &wait);
++ while (1) {
++ set_current_state(TASK_INTERRUPTIBLE);
++ if ((head = info->head) != state->tail)
++ break;
++ if (signal_pending(current))
++ break;
++ schedule();
++ }
++ remove_wait_queue(&info->wait_q, &wait);
++ set_current_state(TASK_RUNNING);
++
++ if (signal_pending(current))
++ return -EINTR;
++
++ if ((head - state->tail) > BUFFER_SIZE)
++ return -ENOBUFS;
++
++ start = state->tail % BUFFER_SIZE;
++ end = head % BUFFER_SIZE;
++
++ if (end > start)
++ n = end - start;
++ else
++ n = BUFFER_SIZE - start;
++
++ if (n > len)
++ n = len;
++
++ if (copy_to_user(buf, info->cpu_addr + start, n))
++ return -EFAULT;
++
++ state->tail += n;
++
++ return n;
++}
++
++static int spi_dma_mmap(struct file *file, struct vm_area_struct *vma)
++{
++ struct spi_dma_state *state = file->private_data;
++ struct spi_dma_info *info = state->info;
++
++ return dma_mmap_coherent(info->dev, vma,
++ info->cpu_addr, info->handle, info->size);
++}
++
++static int spi_dma_get_pos(struct spi_dma_info *info, unsigned *arg)
++{
++ if (put_user(info->head, arg))
++ return -EFAULT;
++
++ return 0;
++}
++
++static int spi_dma_wait_pos(struct spi_dma_info *info, unsigned *arg)
++{
++ DECLARE_WAITQUEUE(wait, current);
++ unsigned pos;
++ int diff;
++
++ if (get_user(pos, arg))
++ return -EFAULT;
++
++ add_wait_queue(&info->wait_q, &wait);
++ while (1) {
++ set_current_state(TASK_INTERRUPTIBLE);
++ if ((diff = info->head - pos) > 0)
++ break;
++ if (signal_pending(current))
++ break;
++ schedule();
++ }
++ remove_wait_queue(&info->wait_q, &wait);
++ set_current_state(TASK_RUNNING);
++
++ if (signal_pending(current))
++ return -EINTR;
++
++ if (diff > BUFFER_SIZE)
++ return -ENOBUFS;
++
++ if (put_user(info->head, arg))
++ return -EFAULT;
++
++ return 0;
++}
++
++#define SPI_DMA_IOCTL_BASE ('N' ^ 'M')
++#define SPI_DMA_GET_BUFFER_SIZE _IOR(SPI_DMA_IOCTL_BASE, 0, unsigned)
++#define SPI_DMA_GET_POS _IOR(SPI_DMA_IOCTL_BASE, 1, unsigned)
++#define SPI_DMA_WAIT_POS _IOWR(SPI_DMA_IOCTL_BASE, 2, unsigned)
++
++static int spi_dma_ioctl(struct inode *inode, struct file *file,
++ unsigned int cmd, unsigned long arg)
++{
++ struct spi_dma_state *state = file->private_data;
++ struct spi_dma_info *info = state->info;
++
++ switch (cmd) {
++ case SPI_DMA_GET_BUFFER_SIZE:
++ if (put_user((unsigned)BUFFER_SIZE, (unsigned *)arg))
++ return -EFAULT;
++ return 0;
++
++ case SPI_DMA_GET_POS:
++ return spi_dma_get_pos(info, (unsigned *)arg);
++
++ case SPI_DMA_WAIT_POS:
++ return spi_dma_wait_pos(info, (unsigned *)arg);
++
++ default:
++ return -EINVAL;
++ }
++}
++
++static int spi_dma_open(struct inode *inode, struct file *file)
++{
++ struct spi_dma_info *info = global_info;
++ struct spi_dma_state *state;
++ int ret;
++
++ state = kmalloc(sizeof(struct spi_dma_state), GFP_KERNEL);
++ if (!state)
++ return -ENOMEM;
++ state->info = info;
++ state->status = 0;
++ file->private_data = state;
++
++ ret = nonseekable_open(inode, file);
++
++ if (ret)
++ kfree(state);
++
++ return ret;
++}
++
++static int spi_dma_release(struct inode *inode, struct file *file)
++{
++ kfree(file->private_data);
++ return 0;
++}
++
++static struct file_operations spi_dma_fops = {
++ .owner = THIS_MODULE,
++ .read = spi_dma_read,
++ .open = spi_dma_open,
++ .release = spi_dma_release,
++ .mmap = spi_dma_mmap,
++ .ioctl = spi_dma_ioctl,
++};
++
++static void spi_dma_free(struct spi_dma_info *info)
++{
++ if (!info)
++ return;
++
++ if (info->major)
++ unregister_chrdev(info->major, "s3c2410-spi");
++ if (info->have_dma) {
++ int value;
++
++ printk("flush\n");
++ info->flushing = 1;
++ s3c2410_dma_ctrl(info->dmach, S3C2410_DMAOP_FLUSH);
++ msleep(100);
++ printk("stop\n");
++ s3c2410_dma_ctrl(info->dmach, S3C2410_DMAOP_STOP);
++ msleep(100);
++
++ printk("poll\n");
++ writel(S3C2410_SPCON_SMOD_POLL, info->regs + S3C2410_SPCON);
++ value = readb(info->regs + S3C2410_SPRDAT);
++ printk("%02x\n", value);
++
++ s3c2410_dma_free(info->dmach, &spi_dma_client);
++ }
++ if (info->regs)
++ iounmap(info->regs);
++ if (info->iomem) {
++ release_resource(info->iomem);
++ kfree(info->iomem);
++ }
++ if (info->clk) {
++ clk_unuse(info->clk);
++ clk_disable(info->clk);
++ }
++ if (info->cpu_addr) {
++ dma_free_coherent(info->dev,
++ info->size, info->cpu_addr,
++ info->handle);
++
++ }
++ kfree(info);
++}
++
++static int spi_dma_probe(struct device *dev)
++{
++ struct platform_device *pdev = to_platform_device(dev);
++ struct spi_dma_info *info;
++ struct resource *res;
++ int ret;
++ int i;
++
++ printk("spi_dma_probe\n");
++
++ info = kmalloc(sizeof(struct spi_dma_info), GFP_KERNEL);
++ if (!info) {
++ dev_err(dev, "failed to allocate info structure\n");
++ ret = -ENOMEM;
++ goto out;
++ }
++ memset(info, 0, sizeof(*info));
++ info->dev = dev;
++
++ dev_info(dev, "got info %p\n", info);
++
++ // TODO figure this out in a better way
++ info->dmach = 3;
++ info->dcon = S3C2410_DCON_CH3_SPI;
++ info->size = BUFFER_SIZE;
++
++ spin_lock_init(&info->head_lock);
++ init_waitqueue_head(&info->wait_q);
++
++ info->cpu_addr = dma_alloc_coherent(dev, info->size, &info->handle, GFP_KERNEL);
++ if (!info->cpu_addr) {
++ dev_err(dev, "failed to allocate DMA buffer\n");
++ ret = -ENOMEM;
++ goto out;
++ }
++
++ dev_info(dev, "got DMA buffer at %p, handle 0x%08lx, size %d\n",
++ info->cpu_addr, (long)info->handle,
++ info->size);
++
++ info->clk = clk_get(dev, "spi");
++ if (IS_ERR(info->clk)) {
++ dev_err(dev, "clk_get failed\n");
++ ret = -ENOENT;
++ goto out;
++ }
++
++ dev_dbg(dev, "clk %p\n", info->clk);
++
++ clk_use(info->clk);
++ clk_enable(info->clk);
++
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ if (!res) {
++ dev_err(dev, "unable to find registers\n");
++ ret = -ENOENT;
++ goto out;
++ }
++
++ dev_info(dev, "got iomem %p\n", res);
++
++ info->iomem = request_mem_region(res->start,
++ (res->end-res->start)+1,
++ pdev->name);
++ if (!info->iomem) {
++ dev_err(dev, "request_mem_region failed\n");
++ ret = -ENXIO;
++ goto out;
++ }
++
++ dev_info(dev, "got iomem %p\n", info->iomem);
++
++ dev_info(dev, "res->start=0x%lx, res->end=0x%lx\n", res->start, res->end);
++ dev_info(dev, "iomem->start=0x%lx, iomem->end=0x%lx\n", info->iomem->start, info->iomem->end);
++
++ info->regs = ioremap(res->start, (res->end-res->start)+1);
++ if (!info->regs) {
++ dev_err(dev, "ioremap failed\n");
++ ret = -ENXIO;
++ goto out;
++ }
++
++ dev_info(dev, "got regs %p\n", info->regs);
++
++ if (s3c2410_dma_request(info->dmach, &spi_dma_client, NULL)) {
++ dev_err(dev, "unable to allocate dma channel\n");
++ ret = -ENOENT;
++ goto out;
++ }
++ info->have_dma = 1;
++
++ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
++ if (!res) {
++ dev_err(dev, "unable to find irq\n");
++ ret = -ENOENT;
++ goto out;
++ }
++
++ ret = register_chrdev(0, "s3c2410-spi", &spi_dma_fops);
++ if (ret < 0) {
++ dev_err(dev, "unable to register character device\n");
++ goto out;
++ }
++ info->major = ret;
++ global_info = info;
++
++ dev_info(dev, "SPI driver active\n");
++
++ dev_set_drvdata(dev, info);
++
++ writel(S3C2410_SPCON_SMOD_DMA | S3C2410_SPCON_TAGD,
++ info->regs + S3C2410_SPCON);
++ writel(S3C2410_SPPIN_RESERVED, info->regs + S3C2410_SPPIN);
++
++ // s3c2410_gpio_cfgpin(S3C2410_GPG5, S3C2410_GPG5_SPIMISO1);
++ s3c2410_gpio_cfgpin(S3C2410_GPG6, S3C2410_GPG6_SPIMOSI1);
++ s3c2410_gpio_cfgpin(S3C2410_GPG7, S3C2410_GPG7_SPICLK1);
++
++ s3c2410_gpio_cfgpin(S3C2410_GPG3, 0x3 << 6);
++
++ s3c2410_dma_devconfig(info->dmach, S3C2410_DMASRC_HW,
++ S3C2410_DISRCC_INC | S3C2410_DISRCC_APB,
++ info->iomem->start + S3C2410_SPRDAT);
++
++ s3c2410_dma_config(info->dmach, 1, info->dcon);
++
++ s3c2410_dma_set_buffdone_fn(info->dmach, spi_dma_done_callback);
++ s3c2410_dma_setflags(info->dmach, S3C2410_DMAF_AUTOSTART);
++
++ writeb(0, info->regs + S3C2410_SPTDAT);
++ msleep(10);
++
++ for (i = 0; i < NUM_CHUNKS; i++) {
++ int offset = i * CHUNK_SIZE;
++ info->chunks[i].index = i;
++ info->chunks[i].handle = info->handle + offset;
++ info->chunks[i].info = info;
++ }
++
++ for (i = 0; i < NUM_CHUNKS; i++) {
++ spi_queue_dma(&info->chunks[i]);
++ }
++
++ ret = 0;
++
++ out:
++ if (ret)
++ spi_dma_free(info);
++
++ return ret;
++}
++
++static int spi_dma_remove(struct device *dev)
++{
++ struct spi_dma_info *info = dev_get_drvdata(dev);
++
++ dev_set_drvdata(dev, NULL);
++
++ spi_dma_free(info);
++
++ return 0;
++}
++
++static struct device_driver spi_dma_driver = {
++ .name = "s3c2410-spi",
++ .bus = &platform_bus_type,
++ .probe = spi_dma_probe,
++ .remove = spi_dma_remove,
++};
++
++static int __init spi_dma_init(void)
++{
++ printk("SPI dma driver loaded\n");
++
++ return driver_register(&spi_dma_driver);
++}
++
++static void __exit spi_dma_exit(void)
++{
++ driver_unregister(&spi_dma_driver);
++}
++
++module_init(spi_dma_init);
++module_exit(spi_dma_exit);
++
++MODULE_DESCRIPTION("S3C2410 DMA driven SPI driver");
++MODULE_AUTHOR("Christer Weinigel <christer@weinigel.se>");
++MODULE_LICENSE("GPL");
diff --git a/recipes/linux/linux/alix/defconfig b/recipes/linux/linux/alix/defconfig
new file mode 100644
index 0000000000..9cffb883a9
--- /dev/null
+++ b/recipes/linux/linux/alix/defconfig
@@ -0,0 +1,1776 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.23-rc3
+# Mon Aug 27 14:49:39 2007
+#
+CONFIG_X86_32=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_CLOCKSOURCE_WATCHDOG=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_SEMAPHORE_SLEEPERS=y
+CONFIG_X86=y
+CONFIG_MMU=y
+CONFIG_ZONE_DMA=y
+CONFIG_QUICKLIST=y
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_GENERIC_IOMAP=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_DMI=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+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_USER_NS is not set
+CONFIG_AUDIT=y
+# CONFIG_AUDITSYSCALL is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_SYSFS_DEPRECATED is not set
+# CONFIG_RELAY is not set
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+# CONFIG_EMBEDDED is not set
+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_TIMERFD=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=y
+# 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 is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+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"
+
+#
+# Processor type and features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+# CONFIG_SMP is not set
+CONFIG_X86_PC=y
+# CONFIG_X86_ELAN is not set
+# CONFIG_X86_VOYAGER is not set
+# CONFIG_X86_NUMAQ is not set
+# CONFIG_X86_SUMMIT is not set
+# CONFIG_X86_BIGSMP is not set
+# CONFIG_X86_VISWS is not set
+# CONFIG_X86_GENERICARCH is not set
+# CONFIG_X86_ES7000 is not set
+# CONFIG_PARAVIRT is not set
+# CONFIG_M386 is not set
+# CONFIG_M486 is not set
+# CONFIG_M586 is not set
+# CONFIG_M586TSC is not set
+# CONFIG_M586MMX is not set
+# CONFIG_M686 is not set
+# CONFIG_MPENTIUMII is not set
+# CONFIG_MPENTIUMIII is not set
+# CONFIG_MPENTIUMM is not set
+# CONFIG_MCORE2 is not set
+# CONFIG_MPENTIUM4 is not set
+# CONFIG_MK6 is not set
+# CONFIG_MK7 is not set
+# CONFIG_MK8 is not set
+# CONFIG_MCRUSOE is not set
+# CONFIG_MEFFICEON is not set
+# CONFIG_MWINCHIPC6 is not set
+# CONFIG_MWINCHIP2 is not set
+# CONFIG_MWINCHIP3D is not set
+# CONFIG_MGEODEGX1 is not set
+CONFIG_MGEODE_LX=y
+# CONFIG_MCYRIXIII is not set
+# CONFIG_MVIAC3_2 is not set
+# CONFIG_MVIAC7 is not set
+# CONFIG_X86_GENERIC is not set
+CONFIG_X86_CMPXCHG=y
+CONFIG_X86_L1_CACHE_SHIFT=5
+CONFIG_X86_XADD=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_X86_WP_WORKS_OK=y
+CONFIG_X86_INVLPG=y
+CONFIG_X86_BSWAP=y
+CONFIG_X86_POPAD_OK=y
+CONFIG_X86_USE_PPRO_CHECKSUM=y
+CONFIG_X86_USE_3DNOW=y
+CONFIG_X86_TSC=y
+CONFIG_X86_MINIMUM_CPU_FAMILY=4
+CONFIG_HPET_TIMER=y
+CONFIG_HPET_EMULATE_RTC=y
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_PREEMPT_BKL=y
+CONFIG_X86_UP_APIC=y
+CONFIG_X86_UP_IOAPIC=y
+CONFIG_X86_LOCAL_APIC=y
+CONFIG_X86_IO_APIC=y
+# CONFIG_X86_MCE is not set
+CONFIG_VM86=y
+# CONFIG_TOSHIBA is not set
+# CONFIG_I8K is not set
+CONFIG_X86_REBOOTFIXUPS=y
+# CONFIG_MICROCODE is not set
+CONFIG_X86_MSR=m
+# CONFIG_X86_CPUID is not set
+
+#
+# Firmware Drivers
+#
+# CONFIG_EDD is not set
+# CONFIG_DELL_RBU is not set
+# CONFIG_DCDBAS is not set
+# CONFIG_DMIID is not set
+CONFIG_NOHIGHMEM=y
+# CONFIG_HIGHMEM4G is not set
+# CONFIG_HIGHMEM64G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+# CONFIG_X86_PAE is not set
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+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=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_NR_QUICK=1
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_MATH_EMULATION is not set
+# CONFIG_MTRR is not set
+# CONFIG_EFI is not set
+CONFIG_SECCOMP=y
+# CONFIG_HZ_100 is not set
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_300 is not set
+CONFIG_HZ_1000=y
+CONFIG_HZ=1000
+# CONFIG_KEXEC is not set
+CONFIG_PHYSICAL_START=0x100000
+# CONFIG_RELOCATABLE is not set
+CONFIG_PHYSICAL_ALIGN=0x100000
+# CONFIG_COMPAT_VDSO is not set
+
+#
+# Power management options (ACPI, APM)
+#
+CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
+# CONFIG_PM_DEBUG is not set
+# CONFIG_SUSPEND is not set
+# CONFIG_HIBERNATION is not set
+CONFIG_ACPI=y
+# CONFIG_ACPI_PROCFS is not set
+# CONFIG_ACPI_AC is not set
+# CONFIG_ACPI_BATTERY is not set
+# CONFIG_ACPI_BUTTON is not set
+# CONFIG_ACPI_FAN is not set
+# CONFIG_ACPI_DOCK is not set
+# CONFIG_ACPI_PROCESSOR is not set
+# CONFIG_ACPI_ASUS is not set
+# CONFIG_ACPI_TOSHIBA is not set
+CONFIG_ACPI_BLACKLIST_YEAR=0
+# CONFIG_ACPI_DEBUG is not set
+CONFIG_ACPI_EC=y
+CONFIG_ACPI_POWER=y
+CONFIG_ACPI_SYSTEM=y
+CONFIG_X86_PM_TIMER=y
+# CONFIG_ACPI_CONTAINER is not set
+# CONFIG_ACPI_SBS is not set
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+#
+CONFIG_PCI=y
+# CONFIG_PCI_GOBIOS is not set
+# CONFIG_PCI_GOMMCONFIG is not set
+# CONFIG_PCI_GODIRECT is not set
+CONFIG_PCI_GOANY=y
+CONFIG_PCI_BIOS=y
+CONFIG_PCI_DIRECT=y
+CONFIG_PCI_MMCONFIG=y
+# CONFIG_PCIEPORTBUS is not set
+CONFIG_ARCH_SUPPORTS_MSI=y
+# CONFIG_PCI_MSI is not set
+# CONFIG_PCI_DEBUG is not set
+# CONFIG_HT_IRQ is not set
+CONFIG_ISA_DMA_API=y
+# CONFIG_ISA is not set
+# CONFIG_MCA is not set
+# CONFIG_SCx200 is not set
+CONFIG_GEODE_MFGPT_TIMER=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_MISC=m
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IP_VS 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=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_CT_PROTO_UDPLITE=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_TRACE 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_CONNLIMIT=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_MULTIPORT=m
+# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set
+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_U32=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=m
+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
+
+#
+# Bridge: Netfilter Configuration
+#
+# CONFIG_BRIDGE_NF_EBTABLES 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=m
+# CONFIG_VLAN_8021Q is not set
+# 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 is not set
+# 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_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
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=m
+# 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 is not set
+CONFIG_PARPORT=m
+CONFIG_PARPORT_PC=m
+# CONFIG_PARPORT_SERIAL is not set
+# CONFIG_PARPORT_PC_FIFO is not set
+# CONFIG_PARPORT_PC_SUPERIO is not set
+# CONFIG_PARPORT_GSC is not set
+CONFIG_PARPORT_AX88796=m
+CONFIG_PARPORT_1284=y
+CONFIG_PARPORT_NOT_PC=y
+CONFIG_PNP=y
+# CONFIG_PNP_DEBUG is not set
+
+#
+# Protocols
+#
+CONFIG_PNPACPI=y
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_PARIDE is not set
+# 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=m
+# 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 is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MISC_DEVICES 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=m
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+CONFIG_CHR_DEV_SG=m
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+# 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 is not set
+CONFIG_ATA=y
+# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_ATA_ACPI=y
+# CONFIG_SATA_AHCI is not set
+# CONFIG_SATA_SVW is not set
+# CONFIG_ATA_PIIX is not set
+# CONFIG_SATA_MV is not set
+# CONFIG_SATA_NV is not set
+# CONFIG_PDC_ADMA is not set
+# CONFIG_SATA_QSTOR is not set
+# CONFIG_SATA_PROMISE is not set
+# CONFIG_SATA_SX4 is not set
+# CONFIG_SATA_SIL is not set
+# CONFIG_SATA_SIL24 is not set
+# CONFIG_SATA_SIS is not set
+# CONFIG_SATA_ULI is not set
+# CONFIG_SATA_VIA is not set
+# CONFIG_SATA_VITESSE is not set
+# CONFIG_SATA_INIC162X is not set
+# CONFIG_PATA_ALI is not set
+CONFIG_PATA_AMD=y
+# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATIIXP is not set
+# CONFIG_PATA_CMD640_PCI is not set
+# CONFIG_PATA_CMD64X is not set
+# CONFIG_PATA_CS5520 is not set
+# CONFIG_PATA_CS5530 is not set
+# CONFIG_PATA_CS5535 is not set
+# CONFIG_PATA_CYPRESS is not set
+# CONFIG_PATA_EFAR is not set
+# CONFIG_ATA_GENERIC is not set
+# CONFIG_PATA_HPT366 is not set
+# CONFIG_PATA_HPT37X is not set
+# CONFIG_PATA_HPT3X2N is not set
+# CONFIG_PATA_HPT3X3 is not set
+# CONFIG_PATA_IT821X is not set
+# CONFIG_PATA_IT8213 is not set
+# CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_TRIFLEX is not set
+# CONFIG_PATA_MARVELL is not set
+# CONFIG_PATA_MPIIX is not set
+# CONFIG_PATA_OLDPIIX is not set
+# CONFIG_PATA_NETCELL is not set
+# CONFIG_PATA_NS87410 is not set
+# CONFIG_PATA_OPTI is not set
+# CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC_OLD is not set
+# CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RZ1000 is not set
+# CONFIG_PATA_SC1200 is not set
+# CONFIG_PATA_SERVERWORKS is not set
+# CONFIG_PATA_PDC2027X is not set
+# CONFIG_PATA_SIL680 is not set
+# CONFIG_PATA_SIS is not set
+# CONFIG_PATA_VIA is not set
+# CONFIG_PATA_WINBOND is not set
+# 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_FIREWIRE is not set
+# CONFIG_IEEE1394 is not set
+# CONFIG_I2O is not set
+# CONFIG_MACINTOSH_DRIVERS 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_NET_SB1000 is not set
+# CONFIG_ARCNET is not set
+# CONFIG_PHYLIB is not set
+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_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 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=y
+CONFIG_VIA_RHINE_MMIO=y
+CONFIG_VIA_RHINE_NAPI=y
+# CONFIG_SC92031 is not set
+# CONFIG_NET_POCKET is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_TR is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+CONFIG_WLAN_80211=y
+# CONFIG_IPW2100 is not set
+# CONFIG_IPW2200 is not set
+# CONFIG_LIBERTAS is not set
+# CONFIG_AIRO is not set
+# CONFIG_HERMES is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+CONFIG_USB_ZD1201=m
+# CONFIG_RTL8187 is not set
+# CONFIG_HOSTAP is not set
+CONFIG_BCM43XX=m
+CONFIG_BCM43XX_DEBUG=y
+CONFIG_BCM43XX_DMA=y
+CONFIG_BCM43XX_PIO=y
+CONFIG_BCM43XX_DMA_AND_PIO_MODE=y
+# CONFIG_BCM43XX_DMA_MODE is not set
+# CONFIG_BCM43XX_PIO_MODE is not set
+CONFIG_ZD1211RW=m
+# CONFIG_ZD1211RW_DEBUG 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=m
+CONFIG_USB_USBNET=m
+# CONFIG_USB_NET_AX8817X is not set
+CONFIG_USB_NET_CDCETHER=m
+CONFIG_USB_NET_DM9601=m
+# CONFIG_USB_NET_GL620A is not set
+# CONFIG_USB_NET_NET1080 is not set
+# CONFIG_USB_NET_PLUSB is not set
+# CONFIG_USB_NET_MCS7830 is not set
+# CONFIG_USB_NET_RNDIS_HOST is not set
+CONFIG_USB_NET_CDC_SUBSET=m
+# CONFIG_USB_ALI_M5632 is not set
+# CONFIG_USB_AN2720 is not set
+# CONFIG_USB_BELKIN is not set
+CONFIG_USB_ARMLINUX=y
+# CONFIG_USB_EPSON2888 is not set
+# CONFIG_USB_KC2190 is not set
+# CONFIG_USB_NET_ZAURUS is not set
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP 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
+# CONFIG_ISDN is not set
+# CONFIG_PHONE 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=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 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 is not set
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_PCSPKR=y
+# CONFIG_INPUT_WISTRON_BTNS is not set
+# CONFIG_INPUT_ATLAS_BTNS is not set
+# 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
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_PARKBD is not set
+# CONFIG_SERIO_PCIPS2 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=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_FIX_EARLYCON_MEM=y
+CONFIG_SERIAL_8250_PCI=y
+CONFIG_SERIAL_8250_PNP=y
+CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_PRINTER is not set
+# CONFIG_PPDEV is not set
+# CONFIG_TIPAR is not set
+# 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_ACQUIRE_WDT is not set
+# CONFIG_ADVANTECH_WDT is not set
+# CONFIG_ALIM1535_WDT is not set
+# CONFIG_ALIM7101_WDT is not set
+# CONFIG_SC520_WDT is not set
+# CONFIG_EUROTECH_WDT is not set
+# CONFIG_IB700_WDT is not set
+# CONFIG_IBMASR is not set
+# CONFIG_WAFER_WDT is not set
+# CONFIG_I6300ESB_WDT is not set
+# CONFIG_ITCO_WDT is not set
+# CONFIG_SC1200_WDT is not set
+# CONFIG_PC87413_WDT is not set
+# CONFIG_60XX_WDT is not set
+# CONFIG_SBC8360_WDT is not set
+# CONFIG_CPU5_WDT is not set
+# CONFIG_SMSC37B787_WDT is not set
+# CONFIG_W83627HF_WDT is not set
+# CONFIG_W83697HF_WDT is not set
+# CONFIG_W83877F_WDT is not set
+# CONFIG_W83977F_WDT is not set
+# CONFIG_MACHZ_WDT is not set
+# CONFIG_SBC_EPX_C3_WATCHDOG is not set
+
+#
+# PCI-based Watchdog Cards
+#
+# CONFIG_PCIPCWATCHDOG is not set
+# CONFIG_WDTPCI is not set
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_INTEL is not set
+# CONFIG_HW_RANDOM_AMD is not set
+CONFIG_HW_RANDOM_GEODE=y
+# CONFIG_HW_RANDOM_VIA is not set
+# CONFIG_NVRAM is not set
+CONFIG_RTC=y
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_SONYPI is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+# CONFIG_MWAVE is not set
+# CONFIG_PC8736x_GPIO is not set
+CONFIG_NSC_GPIO=m
+CONFIG_CS5535_GPIO=m
+# CONFIG_RAW_DRIVER is not set
+CONFIG_HPET=y
+# CONFIG_HPET_RTC_IRQ is not set
+CONFIG_HPET_MMAP=y
+CONFIG_HANGCHECK_TIMER=m
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+CONFIG_DEVPORT=y
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=m
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=y
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PARPORT is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_PROSAVAGE is not set
+# CONFIG_I2C_SAVAGE4 is not set
+# CONFIG_I2C_SIMTEC is not set
+CONFIG_SCx200_ACB=m
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_TINY_USB is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+# CONFIG_I2C_VOODOO3 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_POWER_SUPPLY is not set
+CONFIG_HWMON=m
+CONFIG_HWMON_VID=m
+# 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_K8TEMP 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_CORETEMP 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_SIS5595 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_VIA686A is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_VT8231 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=m
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_SENSORS_HDAPS is not set
+# CONFIG_SENSORS_APPLESMC is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 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=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_CIRRUS is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_ARC is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_VGA16 is not set
+# CONFIG_FB_VESA is not set
+# CONFIG_FB_HECUBA is not set
+# CONFIG_FB_HGA is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_NVIDIA is not set
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_I810 is not set
+# CONFIG_FB_LE80578 is not set
+# CONFIG_FB_INTEL 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_VT8623 is not set
+# CONFIG_FB_CYBLA is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_ARK is not set
+# CONFIG_FB_PM3 is not set
+CONFIG_FB_GEODE=y
+CONFIG_FB_GEODE_LX=y
+# CONFIG_FB_GEODE_GX is not set
+# CONFIG_FB_GEODE_GX1 is not set
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+CONFIG_VGA_CONSOLE=y
+# CONFIG_VGACON_SOFT_SCROLLBACK is not set
+CONFIG_VIDEO_SELECT=y
+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
+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
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+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_RTCTIMER=m
+# CONFIG_SND_DYNAMIC_MINORS is not set
+# CONFIG_SND_SUPPORT_OLD_API is not set
+# CONFIG_SND_VERBOSE_PROCFS is not set
+# 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_MTS64 is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+# CONFIG_SND_PORTMAN2X4 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_CS5530 is not set
+CONFIG_SND_CS5535AUDIO=m
+# 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
+
+#
+# USB devices
+#
+# CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_USX2Y 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=y
+CONFIG_USB_SUPPORT=y
+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_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+CONFIG_USB_SUSPEND=y
+# CONFIG_USB_PERSIST is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_SPLIT_ISO=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+# 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
+# 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=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_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 is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_USS720 is not set
+
+#
+# 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_SISUSBVGA 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 is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_INFINIBAND is not set
+# CONFIG_EDAC is not set
+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 is not set
+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=y
+# 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
+
+#
+# on-CPU RTC drivers
+#
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+# CONFIG_AUXDISPLAY is not set
+CONFIG_VIRTUALIZATION=y
+# CONFIG_KVM is not set
+
+#
+# Userspace I/O
+#
+# CONFIG_UIO 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_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=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=m
+# CONFIG_NTFS_DEBUG is not set
+# CONFIG_NTFS_RW is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLBFS 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_CRAMFS=m
+# 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=y
+CONFIG_NFS_V4=y
+# CONFIG_NFS_DIRECTIO is not set
+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 is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+# CONFIG_CIFS_DEBUG2 is not set
+CONFIG_CIFS_EXPERIMENTAL=y
+# CONFIG_NCP_FS is not set
+CONFIG_CODA_FS=m
+# CONFIG_CODA_FS_OLD_API 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="utf-8"
+CONFIG_NLS_CODEPAGE_437=m
+# 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=m
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+CONFIG_NLS_CODEPAGE_1250=m
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+# 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
+CONFIG_INSTRUMENTATION=y
+# CONFIG_PROFILING is not set
+# CONFIG_KPROBES is not set
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_PRINTK_TIME=y
+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_DETECT_SOFTLOCKUP is not set
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+CONFIG_TIMER_STATS=y
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_PREEMPT is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_FRAME_POINTER is not set
+CONFIG_FORCED_INLINING=y
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
+CONFIG_EARLY_PRINTK=y
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_PAGEALLOC is not set
+# CONFIG_DEBUG_RODATA is not set
+CONFIG_4KSTACKS=y
+CONFIG_X86_FIND_SMP_CONFIG=y
+CONFIG_X86_MPPARSE=y
+CONFIG_DOUBLEFAULT=y
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ABLKCIPHER=m
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_HASH=m
+CONFIG_CRYPTO_MANAGER=m
+CONFIG_CRYPTO_HMAC=m
+CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_GF128MUL=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_CRYPTD=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
+CONFIG_CRYPTO_TWOFISH_586=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_AES_586=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_CAMELLIA=m
+CONFIG_CRYPTO_TEST=m
+CONFIG_CRYPTO_HW=y
+# CONFIG_CRYPTO_DEV_PADLOCK is not set
+CONFIG_CRYPTO_DEV_GEODE=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=m
+CONFIG_AUDIT_GENERIC=y
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
+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
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_X86_BIOS_REBOOT=y
+CONFIG_KTIME_SCALAR=y
diff --git a/recipes/linux/linux/alix/geode-mfgpt-clock-event-device-support.patch b/recipes/linux/linux/alix/geode-mfgpt-clock-event-device-support.patch
new file mode 100644
index 0000000000..6f0b10a0bd
--- /dev/null
+++ b/recipes/linux/linux/alix/geode-mfgpt-clock-event-device-support.patch
@@ -0,0 +1,237 @@
+From: Andres Salomon <dilinger@queued.net>
+
+Add support for an MFGPT clock event device; this allows us to use MFGPTs as
+the basis for high-resolution timers.
+
+Signed-off-by: Jordan Crouse <jordan.crouse@amd.com>
+Signed-off-by: Andres Salomon <dilinger@debian.org>
+Cc: Andi Kleen <ak@suse.de>
+Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
+Cc: john stultz <johnstul@us.ibm.com>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Ingo Molnar <mingo@elte.hu>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+---
+
+ Documentation/kernel-parameters.txt | 4
+ arch/i386/Kconfig | 10 +
+ arch/i386/kernel/mfgpt.c | 165 ++++++++++++++++++++++++++
+ 3 files changed, 179 insertions(+)
+
+--- linux-2.6.22.orig/Documentation/kernel-parameters.txt
++++ linux-2.6.22/Documentation/kernel-parameters.txt
+@@ -1012,6 +1012,10 @@
+ meye.*= [HW] Set MotionEye Camera parameters
+ See Documentation/video4linux/meye.txt.
+
++ mfgpt_irq= [IA-32] Specify the IRQ to use for the
++ Multi-Function General Purpose Timers on AMD Geode
++ platforms.
++
+ mga= [HW,DRM]
+
+ migration_cost=
+--- linux-2.6.22.orig/arch/i386/Kconfig
++++ linux-2.6.22/arch/i386/Kconfig
+@@ -1190,6 +1190,16 @@
+ processor goes idle (as is done by the scheduler). The
+ other workaround is idle=poll boot option.
+
++config GEODE_MFGPT_TIMER
++ bool "Geode Multi-Function General Purpose Timer (MFGPT) events"
++ depends on MGEODE_LX && GENERIC_TIME && GENERIC_CLOCKEVENTS
++ default y
++ help
++ This driver provides a clock event source based on the MFGPT
++ timer(s) in the CS5535 and CS5536 companion chip for the geode.
++ MFGPTs have a better resolution and max interval than the
++ generic PIT, and are suitable for use as high-res timers.
++
+ config K8_NB
+ def_bool y
+ depends on AGP_AMD64
+--- linux-2.6.22.orig/arch/i386/kernel/mfgpt.c
++++ linux-2.6.22/arch/i386/kernel/mfgpt.c
+@@ -48,6 +48,12 @@
+ #define MFGPT_HZ (32000 / MFGPT_DIVISOR)
+ #define MFGPT_PERIODIC (MFGPT_HZ / HZ)
+
++#ifdef CONFIG_GEODE_MFGPT_TIMER
++static int __init mfgpt_timer_setup(void);
++#else
++#define mfgpt_timer_setup() (0)
++#endif
++
+ /* Allow for disabling of MFGPTs */
+ static int disable;
+ static int __init mfgpt_disable(char *s)
+@@ -82,6 +88,9 @@
+ }
+ }
+
++ /* set up clock event device, if desired */
++ i = mfgpt_timer_setup();
++
+ return count;
+ }
+
+@@ -197,3 +206,159 @@
+ return -1;
+ }
+ EXPORT_SYMBOL(geode_mfgpt_alloc_timer);
++
++#ifdef CONFIG_GEODE_MFGPT_TIMER
++
++/*
++ * The MFPGT timers on the CS5536 provide us with suitable timers to use
++ * as clock event sources - not as good as a HPET or APIC, but certainly
++ * better then the PIT. This isn't a general purpose MFGPT driver, but
++ * a simplified one designed specifically to act as a clock event source.
++ * For full details about the MFGPT, please consult the CS5536 data sheet.
++ */
++
++#include <linux/clocksource.h>
++#include <linux/clockchips.h>
++
++static unsigned int mfgpt_tick_mode = CLOCK_EVT_MODE_SHUTDOWN;
++static u16 mfgpt_event_clock;
++
++static int irq = 7;
++static int __init mfgpt_setup(char *str)
++{
++ get_option(&str, &irq);
++ return 1;
++}
++__setup("mfgpt_irq=", mfgpt_setup);
++
++static inline void mfgpt_disable_timer(u16 clock)
++{
++ u16 val = geode_mfgpt_read(clock, MFGPT_REG_SETUP);
++ geode_mfgpt_write(clock, MFGPT_REG_SETUP, val & ~MFGPT_SETUP_CNTEN);
++}
++
++static int mfgpt_next_event(unsigned long, struct clock_event_device *);
++static void mfgpt_set_mode(enum clock_event_mode, struct clock_event_device *);
++
++static struct clock_event_device mfgpt_clockevent = {
++ .name = "mfgpt-timer",
++ .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
++ .set_mode = mfgpt_set_mode,
++ .set_next_event = mfgpt_next_event,
++ .rating = 250,
++ .cpumask = CPU_MASK_ALL,
++ .shift = 32
++};
++
++static inline void mfgpt_start_timer(u16 clock, u16 delta)
++{
++ geode_mfgpt_write(mfgpt_event_clock, MFGPT_REG_CMP2, (u16) delta);
++ geode_mfgpt_write(mfgpt_event_clock, MFGPT_REG_COUNTER, 0);
++
++ geode_mfgpt_write(mfgpt_event_clock, MFGPT_REG_SETUP,
++ MFGPT_SETUP_CNTEN | MFGPT_SETUP_CMP2);
++}
++
++static void mfgpt_set_mode(enum clock_event_mode mode,
++ struct clock_event_device *evt)
++{
++ mfgpt_disable_timer(mfgpt_event_clock);
++
++ if (mode == CLOCK_EVT_MODE_PERIODIC)
++ mfgpt_start_timer(mfgpt_event_clock, MFGPT_PERIODIC);
++
++ mfgpt_tick_mode = mode;
++}
++
++static int mfgpt_next_event(unsigned long delta, struct clock_event_device *evt)
++{
++ mfgpt_start_timer(mfgpt_event_clock, delta);
++ return 0;
++}
++
++/* Assume (foolishly?), that this interrupt was due to our tick */
++
++static irqreturn_t mfgpt_tick(int irq, void *dev_id)
++{
++ if (mfgpt_tick_mode == CLOCK_EVT_MODE_SHUTDOWN)
++ return IRQ_HANDLED;
++
++ /* Turn off the clock */
++ mfgpt_disable_timer(mfgpt_event_clock);
++
++ /* Clear the counter */
++ geode_mfgpt_write(mfgpt_event_clock, MFGPT_REG_COUNTER, 0);
++
++ /* Restart the clock in periodic mode */
++
++ if (mfgpt_tick_mode == CLOCK_EVT_MODE_PERIODIC) {
++ geode_mfgpt_write(mfgpt_event_clock, MFGPT_REG_SETUP,
++ MFGPT_SETUP_CNTEN | MFGPT_SETUP_CMP2);
++ }
++
++ mfgpt_clockevent.event_handler(&mfgpt_clockevent);
++ return IRQ_HANDLED;
++}
++
++static struct irqaction mfgptirq = {
++ .handler = mfgpt_tick,
++ .flags = IRQF_DISABLED | IRQF_NOBALANCING,
++ .mask = CPU_MASK_NONE,
++ .name = "mfgpt-timer"
++};
++
++static int __init mfgpt_timer_setup(void)
++{
++ int timer, ret;
++ u16 val;
++
++ timer = geode_mfgpt_alloc_timer(MFGPT_TIMER_ANY, MFGPT_DOMAIN_WORKING,
++ THIS_MODULE);
++ if (timer < 0) {
++ printk(KERN_ERR "mfgpt-timer: Could not allocate a MFPGT "
++ "timer\n");
++ return -ENODEV;
++ }
++
++ mfgpt_event_clock = timer;
++ /* Set the clock scale and enable the event mode for CMP2 */
++ val = MFGPT_SCALE | (3 << 8);
++
++ geode_mfgpt_write(mfgpt_event_clock, MFGPT_REG_SETUP, val);
++
++ /* Set up the IRQ on the MFGPT side */
++ if (geode_mfgpt_setup_irq(mfgpt_event_clock, MFGPT_CMP2, irq)) {
++ printk(KERN_ERR "mfgpt-timer: Could not set up IRQ %d\n", irq);
++ return -EIO;
++ }
++
++ /* And register it with the kernel */
++ ret = setup_irq(irq, &mfgptirq);
++
++ if (ret) {
++ printk(KERN_ERR "mfgpt-timer: Unable to set up the "
++ "interrupt.\n");
++ goto err;
++ }
++
++ /* Set up the clock event */
++ mfgpt_clockevent.mult = div_sc(MFGPT_HZ, NSEC_PER_SEC, 32);
++ mfgpt_clockevent.min_delta_ns = clockevent_delta2ns(0xF,
++ &mfgpt_clockevent);
++ mfgpt_clockevent.max_delta_ns = clockevent_delta2ns(0xFFFE,
++ &mfgpt_clockevent);
++
++ printk(KERN_INFO "mfgpt-timer: registering the MFGT timer as a "
++ "clock event.\n");
++ clockevents_register_device(&mfgpt_clockevent);
++
++ return 0;
++
++err:
++ geode_mfgpt_release_irq(mfgpt_event_clock, MFGPT_CMP2, irq);
++ printk(KERN_ERR "mfgpt-timer: Unable to set up the MFGPT clock "
++ "source\n");
++ return -EIO;
++}
++
++#endif
diff --git a/recipes/linux/linux/alix/geode-mfgpt-support-for-geode-class-machines.patch b/recipes/linux/linux/alix/geode-mfgpt-support-for-geode-class-machines.patch
new file mode 100644
index 0000000000..533412c483
--- /dev/null
+++ b/recipes/linux/linux/alix/geode-mfgpt-support-for-geode-class-machines.patch
@@ -0,0 +1,311 @@
+From: Andres Salomon <dilinger@queued.net>
+
+This adds support for Multi-Function General Purpose Timers. It detects the
+available timers during southbridge init, and provides an API for allocating
+and setting the timers. They're higher resolution than the standard PIT, so
+the MFGPTs come in handy for quite a few things.
+
+Note that we never clobber the timers that the BIOS might have opted to use;
+we just check for unused timers.
+
+Signed-off-by: Jordan Crouse <jordan.crouse@amd.com>
+Signed-off-by: Andres Salomon <dilinger@debian.org>
+Cc: Andi Kleen <ak@suse.de>
+Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+---
+
+ Documentation/kernel-parameters.txt | 3
+ arch/i386/kernel/Makefile | 2
+ arch/i386/kernel/geode.c | 4
+ arch/i386/kernel/mfgpt.c | 199 ++++++++++++++++++++++++++
+ include/asm-i386/geode.h | 50 ++++++
+ 5 files changed, 257 insertions(+), 1 deletion(-)
+
+--- linux-2.6.22.orig/arch/i386/kernel/Makefile
++++ linux-2.6.22/arch/i386/kernel/Makefile
+@@ -40,7 +40,7 @@
+ obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
+ obj-$(CONFIG_HPET_TIMER) += hpet.o
+ obj-$(CONFIG_K8_NB) += k8.o
+-obj-$(CONFIG_MGEODE_LX) += geode.o
++obj-$(CONFIG_MGEODE_LX) += geode.o mfgpt.o
+
+ obj-$(CONFIG_VMI) += vmi.o vmiclock.o
+ obj-$(CONFIG_PARAVIRT) += paravirt.o
+--- linux-2.6.22.orig/arch/i386/kernel/geode.c
++++ linux-2.6.22/arch/i386/kernel/geode.c
+@@ -146,10 +146,14 @@
+
+ static int __init geode_southbridge_init(void)
+ {
++ int timers;
++
+ if (!is_geode())
+ return -ENODEV;
+
+ init_lbars();
++ timers = geode_mfgpt_detect();
++ printk(KERN_INFO "geode: %d MFGPT timers available.\n", timers);
+ return 0;
+ }
+
+--- /dev/null
++++ linux-2.6.22/arch/i386/kernel/mfgpt.c
+@@ -0,0 +1,199 @@
++/*
++ * Driver/API for AMD Geode Multi-Function General Purpose Timers (MFGPT)
++ *
++ * Copyright (C) 2006, Advanced Micro Devices, Inc.
++ * Copyright (C) 2007, Andres Salomon <dilinger@debian.org>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of version 2 of the GNU General Public License
++ * as published by the Free Software Foundation.
++ *
++ * The MFGPTs are documented in AMD Geode CS5536 Companion Device Data Book.
++ */
++
++/*
++ * We are using the 32Khz input clock - its the only one that has the
++ * ranges we find desirable. The following table lists the suitable
++ * divisors and the associated hz, minimum interval
++ * and the maximum interval:
++ *
++ * Divisor Hz Min Delta (S) Max Delta (S)
++ * 1 32000 .0005 2.048
++ * 2 16000 .001 4.096
++ * 4 8000 .002 8.192
++ * 8 4000 .004 16.384
++ * 16 2000 .008 32.768
++ * 32 1000 .016 65.536
++ * 64 500 .032 131.072
++ * 128 250 .064 262.144
++ * 256 125 .128 524.288
++ */
++
++#include <linux/kernel.h>
++#include <linux/interrupt.h>
++#include <linux/module.h>
++#include <asm/geode.h>
++
++#define F_AVAIL 0x01
++
++static struct mfgpt_timer_t {
++ int flags;
++ struct module *owner;
++} mfgpt_timers[MFGPT_MAX_TIMERS];
++
++/* Selected from the table above */
++
++#define MFGPT_DIVISOR 16
++#define MFGPT_SCALE 4 /* divisor = 2^(scale) */
++#define MFGPT_HZ (32000 / MFGPT_DIVISOR)
++#define MFGPT_PERIODIC (MFGPT_HZ / HZ)
++
++/* Allow for disabling of MFGPTs */
++static int disable;
++static int __init mfgpt_disable(char *s)
++{
++ disable = 1;
++ return 1;
++}
++__setup("nomfgpt", mfgpt_disable);
++
++/*
++ * Check whether any MFGPTs are available for the kernel to use. In most
++ * cases, firmware that uses AMD's VSA code will claim all timers during
++ * bootup; we certainly don't want to take them if they're already in use.
++ * In other cases (such as with VSAless OpenFirmware), the system firmware
++ * leaves timers available for us to use.
++ */
++int __init geode_mfgpt_detect(void)
++{
++ int count = 0, i;
++ u16 val;
++
++ if (disable) {
++ printk(KERN_INFO "geode-mfgpt: Skipping MFGPT setup\n");
++ return 0;
++ }
++
++ for (i = 0; i < MFGPT_MAX_TIMERS; i++) {
++ val = geode_mfgpt_read(i, MFGPT_REG_SETUP);
++ if (!(val & MFGPT_SETUP_SETUP)) {
++ mfgpt_timers[i].flags = F_AVAIL;
++ count++;
++ }
++ }
++
++ return count;
++}
++
++int geode_mfgpt_toggle_event(int timer, int cmp, int event, int enable)
++{
++ u32 msr, mask, value, dummy;
++ int shift = (cmp == MFGPT_CMP1) ? 0 : 8;
++
++ if (timer < 0 || timer >= MFGPT_MAX_TIMERS)
++ return -EIO;
++
++ /*
++ * The register maps for these are described in sections 6.17.1.x of
++ * the AMD Geode CS5536 Companion Device Data Book.
++ */
++ switch (event) {
++ case MFGPT_EVENT_RESET:
++ /*
++ * XXX: According to the docs, we cannot reset timers above
++ * 6; that is, resets for 7 and 8 will be ignored. Is this
++ * a problem? -dilinger
++ */
++ msr = MFGPT_NR_MSR;
++ mask = 1 << (timer + 24);
++ break;
++
++ case MFGPT_EVENT_NMI:
++ msr = MFGPT_NR_MSR;
++ mask = 1 << (timer + shift);
++ break;
++
++ case MFGPT_EVENT_IRQ:
++ msr = MFGPT_IRQ_MSR;
++ mask = 1 << (timer + shift);
++ break;
++
++ default:
++ return -EIO;
++ }
++
++ rdmsr(msr, value, dummy);
++
++ if (enable)
++ value |= mask;
++ else
++ value &= ~mask;
++
++ wrmsr(msr, value, dummy);
++ return 0;
++}
++EXPORT_SYMBOL(geode_mfgpt_toggle_event);
++
++int geode_mfgpt_set_irq(int timer, int cmp, int irq, int enable)
++{
++ u32 val, dummy;
++ int offset;
++
++ if (timer < 0 || timer >= MFGPT_MAX_TIMERS)
++ return -EIO;
++
++ if (geode_mfgpt_toggle_event(timer, cmp, MFGPT_EVENT_IRQ, enable))
++ return -EIO;
++
++ rdmsr(0x51400022, val, dummy);
++
++ offset = (timer % 4) * 4;
++
++ val &= ~((0xF << offset) | (0xF << (offset + 16)));
++
++ if (enable) {
++ val |= (irq & 0x0F) << (offset);
++ val |= (irq & 0x0F) << (offset + 16);
++ }
++
++ wrmsr(0x51400022, val, dummy);
++ return 0;
++}
++EXPORT_SYMBOL(geode_mfgpt_set_irq);
++
++static int mfgpt_get(int timer, struct module *owner)
++{
++ mfgpt_timers[timer].flags &= ~F_AVAIL;
++ mfgpt_timers[timer].owner = owner;
++ printk(KERN_INFO "geode-mfgpt: Registered timer %d\n", timer);
++ return timer;
++}
++
++int geode_mfgpt_alloc_timer(int timer, int domain, struct module *owner)
++{
++ int i;
++
++ if (!geode_get_dev_base(GEODE_DEV_MFGPT))
++ return -ENODEV;
++ if (timer >= MFGPT_MAX_TIMERS)
++ return -EIO;
++
++ if (timer < 0) {
++ /* Try to find an available timer */
++ for (i = 0; i < MFGPT_MAX_TIMERS; i++) {
++ if (mfgpt_timers[i].flags & F_AVAIL)
++ return mfgpt_get(i, owner);
++
++ if (i == 5 && domain == MFGPT_DOMAIN_WORKING)
++ break;
++ }
++ } else {
++ /* If they requested a specific timer, try to honor that */
++ if (mfgpt_timers[timer].flags & F_AVAIL)
++ return mfgpt_get(timer, owner);
++ }
++
++ /* No timers available - too bad */
++ return -1;
++}
++EXPORT_SYMBOL(geode_mfgpt_alloc_timer);
+--- linux-2.6.22.orig/include/asm-i386/geode.h
++++ linux-2.6.22/include/asm-i386/geode.h
+@@ -156,4 +156,54 @@
+ return (is_geode_gx() || is_geode_lx());
+ }
+
++/* MFGPTs */
++
++#define MFGPT_MAX_TIMERS 8
++#define MFGPT_TIMER_ANY -1
++
++#define MFGPT_DOMAIN_WORKING 1
++#define MFGPT_DOMAIN_STANDBY 2
++#define MFGPT_DOMAIN_ANY (MFGPT_DOMAIN_WORKING | MFGPT_DOMAIN_STANDBY)
++
++#define MFGPT_CMP1 0
++#define MFGPT_CMP2 1
++
++#define MFGPT_EVENT_IRQ 0
++#define MFGPT_EVENT_NMI 1
++#define MFGPT_EVENT_RESET 3
++
++#define MFGPT_REG_CMP1 0
++#define MFGPT_REG_CMP2 2
++#define MFGPT_REG_COUNTER 4
++#define MFGPT_REG_SETUP 6
++
++#define MFGPT_SETUP_CNTEN (1 << 15)
++#define MFGPT_SETUP_CMP2 (1 << 14)
++#define MFGPT_SETUP_CMP1 (1 << 13)
++#define MFGPT_SETUP_SETUP (1 << 12)
++#define MFGPT_SETUP_STOPEN (1 << 11)
++#define MFGPT_SETUP_EXTEN (1 << 10)
++#define MFGPT_SETUP_REVEN (1 << 5)
++#define MFGPT_SETUP_CLKSEL (1 << 4)
++
++static inline void geode_mfgpt_write(int timer, u16 reg, u16 value)
++{
++ u32 base = geode_get_dev_base(GEODE_DEV_MFGPT);
++ outw(value, base + reg + (timer * 8));
++}
++
++static inline u16 geode_mfgpt_read(int timer, u16 reg)
++{
++ u32 base = geode_get_dev_base(GEODE_DEV_MFGPT);
++ return inw(base + reg + (timer * 8));
++}
++
++extern int __init geode_mfgpt_detect(void);
++extern int geode_mfgpt_toggle_event(int timer, int cmp, int event, int enable);
++extern int geode_mfgpt_set_irq(int timer, int cmp, int irq, int enable);
++extern int geode_mfgpt_alloc_timer(int timer, int domain, struct module *owner);
++
++#define geode_mfgpt_setup_irq(t, c, i) geode_mfgpt_set_irq((t), (c), (i), 1)
++#define geode_mfgpt_release_irq(t, c, i) geode_mfgpt_set_irq((t), (c), (i), 0)
++
+ #endif
diff --git a/recipes/linux/linux/at32stk1000/defconfig b/recipes/linux/linux/at32stk1000/defconfig
new file mode 100644
index 0000000000..290dce50c5
--- /dev/null
+++ b/recipes/linux/linux/at32stk1000/defconfig
@@ -0,0 +1,849 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.21
+# Sat Jun 2 10:40:44 2007
+#
+CONFIG_AVR32=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_TIME=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_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=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+# CONFIG_TASK_XACCT is not set
+# CONFIG_UTS_NS is not set
+CONFIG_AUDIT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_RELAY=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+# CONFIG_SYSCTL_SYSCALL is not set
+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 is not set
+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=1
+# 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 is not set
+
+#
+# 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 is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_NOOP=y
+CONFIG_DEFAULT_IOSCHED="noop"
+
+#
+# System Type and features
+#
+CONFIG_SUBARCH_AVR32B=y
+CONFIG_MMU=y
+CONFIG_PERFORMANCE_COUNTERS=y
+CONFIG_PLATFORM_AT32AP=y
+CONFIG_CPU_AT32AP7000=y
+CONFIG_BOARD_ATSTK1002=y
+CONFIG_BOARD_ATSTK1000=y
+CONFIG_LOADER_U_BOOT=y
+CONFIG_LOAD_ADDRESS=0x10000000
+CONFIG_ENTRY_ADDRESS=0x90000000
+CONFIG_PHYS_OFFSET=0x10000000
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+# CONFIG_HAVE_ARCH_BOOTMEM_NODE is not set
+# CONFIG_ARCH_HAVE_MEMORY_PRESENT is not set
+# CONFIG_NEED_NODE_MEMMAP_SIZE is not set
+CONFIG_ARCH_FLATMEM_ENABLE=y
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+# CONFIG_ARCH_SPARSEMEM_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=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+# CONFIG_OWNERSHIP_TRACE is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_CMDLINE=""
+
+#
+# Bus options
+#
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP 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 is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+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 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# CONFIG_FW_LOADER is not set
+# 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=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 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_OBSOLETE_CHIPS is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_START=0x8000000
+CONFIG_MTD_PHYSMAP_LEN=0x0
+CONFIG_MTD_PHYSMAP_BANKWIDTH=2
+# 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
+#
+# CONFIG_PNPACPI is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_RAM=m
+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
+#
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK 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=y
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+CONFIG_TUN=m
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_MACB=y
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# 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 is not set
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+# CONFIG_PPP_MPPE is not set
+# CONFIG_PPPOE 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
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+# CONFIG_INPUT is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# 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_ATMEL=y
+CONFIG_SERIAL_ATMEL_CONSOLE=y
+# CONFIG_SERIAL_ATMEL_TTYAT is not set
+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
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 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
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# InfiniBand support
+#
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=m
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
+# 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=m
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_DNOTIFY is not set
+# 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=m
+CONFIG_MSDOS_FS=m
+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_KCORE=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_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_SUMMARY is not set
+# 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
+# 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=m
+# 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=m
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=m
+
+#
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# 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_LOG_BUF_SHIFT=14
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+CONFIG_TIMER_STATS=y
+# 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=y
+# CONFIG_DEBUG_INFO is not set
+# 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_KPROBES is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_CRC_CCITT=m
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_AUDIT_GENERIC=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/recipes/linux/linux/at91sam9263ek/defconfig b/recipes/linux/linux/at91sam9263ek/defconfig
new file mode 100644
index 0000000000..c72ab82873
--- /dev/null
+++ b/recipes/linux/linux/at91sam9263ek/defconfig
@@ -0,0 +1,1184 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.20-rc1
+# Mon Jan 8 16:06:54 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_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_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 is not set
+CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS 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 is not set
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+# CONFIG_EMBEDDED is not set
+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_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 is not set
+# CONFIG_IOSCHED_CFQ is not set
+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=y
+# 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_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# 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
+
+#
+# Atmel AT91 System-on-Chip
+#
+# CONFIG_ARCH_AT91RM9200 is not set
+# CONFIG_ARCH_AT91SAM9260 is not set
+# CONFIG_ARCH_AT91SAM9261 is not set
+CONFIG_ARCH_AT91SAM9263=y
+
+#
+# AT91SAM9263 Board Type
+#
+CONFIG_MACH_AT91SAM9263EK=y
+
+#
+# AT91 Board Options
+#
+CONFIG_MTD_AT91_DATAFLASH_CARD=y
+# CONFIG_MTD_NAND_AT91_BUSWIDTH_16 is not set
+
+#
+# AT91 Feature Selections
+#
+# CONFIG_AT91_PROGRAMMABLE_CLOCKS is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM926T=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5TJ=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+# CONFIG_ARM_THUMB is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+
+#
+# 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 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_LEDS is not set
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="mem=64M console=ttyS0,115200 initrd=0x21100000,3145728 root=/dev/ram0 rw"
+# 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
+# CONFIG_VFP 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_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=y
+CONFIG_IP_PNP_RARP=y
+# 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 is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_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 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER 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=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 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_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+CONFIG_MTD_DATAFLASH=y
+# 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
+
+#
+# NAND Flash Device Drivers
+#
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+CONFIG_MTD_NAND_AT91=y
+# 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
+#
+
+#
+# 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
+
+#
+# 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 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=y
+# 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_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 is not set
+# CONFIG_DM9000 is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO 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 is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_TSDEV=y
+CONFIG_INPUT_TSDEV_SCREEN_X=240
+CONFIG_INPUT_TSDEV_SCREEN_Y=320
+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_ADS7846=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 is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_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_ATMEL=y
+CONFIG_SERIAL_ATMEL_CONSOLE=y
+# CONFIG_SERIAL_ATMEL_TTYAT is not set
+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
+
+#
+# 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
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=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_AT91=y
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_PCA is not set
+# CONFIG_I2C_PCA_ISA is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 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_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_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_ATMEL=y
+# CONFIG_SPI_BITBANG is not set
+
+#
+# SPI Protocol Masters
+#
+
+#
+# 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_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 is not set
+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_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE is not set
+
+#
+# Logo configuration
+#
+# CONFIG_LOGO is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# HID Devices
+#
+CONFIG_HID=y
+
+#
+# USB support
+#
+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_BANDWIDTH is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_MULTITHREAD_PROBE 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 is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# 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_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Input Devices
+#
+# CONFIG_USB_HID is not set
+
+#
+# USB HID Boot Protocol drivers
+#
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE 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
+
+#
+# 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_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 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=y
+CONFIG_USB_AT91=y
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+# CONFIG_USB_GADGET_DUALSPEED is not set
+CONFIG_USB_ZERO=m
+# CONFIG_USB_ETH is not set
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_FILE_STORAGE=m
+# CONFIG_USB_FILE_STORAGE_TEST is not set
+CONFIG_USB_G_SERIAL=m
+# 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_AT91=m
+# 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 is not set
+# CONFIG_EXT4DEV_FS is not set
+# 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 is not set
+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 is not set
+# 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=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=y
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 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=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 is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_RWSEMS is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
+CONFIG_FRAME_POINTER=y
+CONFIG_FORCED_INLINING=y
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_ERRORS is not set
+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 is not set
+
+#
+# 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_ZLIB_INFLATE=y
+CONFIG_PLIST=y
+CONFIG_IOMAP_COPY=y
diff --git a/recipes/linux/linux/atngw100/defconfig b/recipes/linux/linux/atngw100/defconfig
new file mode 100644
index 0000000000..290dce50c5
--- /dev/null
+++ b/recipes/linux/linux/atngw100/defconfig
@@ -0,0 +1,849 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.21
+# Sat Jun 2 10:40:44 2007
+#
+CONFIG_AVR32=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_TIME=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_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=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+# CONFIG_TASK_XACCT is not set
+# CONFIG_UTS_NS is not set
+CONFIG_AUDIT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_RELAY=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+# CONFIG_SYSCTL_SYSCALL is not set
+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 is not set
+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=1
+# 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 is not set
+
+#
+# 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 is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_NOOP=y
+CONFIG_DEFAULT_IOSCHED="noop"
+
+#
+# System Type and features
+#
+CONFIG_SUBARCH_AVR32B=y
+CONFIG_MMU=y
+CONFIG_PERFORMANCE_COUNTERS=y
+CONFIG_PLATFORM_AT32AP=y
+CONFIG_CPU_AT32AP7000=y
+CONFIG_BOARD_ATSTK1002=y
+CONFIG_BOARD_ATSTK1000=y
+CONFIG_LOADER_U_BOOT=y
+CONFIG_LOAD_ADDRESS=0x10000000
+CONFIG_ENTRY_ADDRESS=0x90000000
+CONFIG_PHYS_OFFSET=0x10000000
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+# CONFIG_HAVE_ARCH_BOOTMEM_NODE is not set
+# CONFIG_ARCH_HAVE_MEMORY_PRESENT is not set
+# CONFIG_NEED_NODE_MEMMAP_SIZE is not set
+CONFIG_ARCH_FLATMEM_ENABLE=y
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+# CONFIG_ARCH_SPARSEMEM_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=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+# CONFIG_OWNERSHIP_TRACE is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_CMDLINE=""
+
+#
+# Bus options
+#
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP 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 is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+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 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# CONFIG_FW_LOADER is not set
+# 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=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 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_OBSOLETE_CHIPS is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_START=0x8000000
+CONFIG_MTD_PHYSMAP_LEN=0x0
+CONFIG_MTD_PHYSMAP_BANKWIDTH=2
+# 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
+#
+# CONFIG_PNPACPI is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_RAM=m
+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
+#
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK 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=y
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+CONFIG_TUN=m
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_MACB=y
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# 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 is not set
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+# CONFIG_PPP_MPPE is not set
+# CONFIG_PPPOE 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
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+# CONFIG_INPUT is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# 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_ATMEL=y
+CONFIG_SERIAL_ATMEL_CONSOLE=y
+# CONFIG_SERIAL_ATMEL_TTYAT is not set
+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
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 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
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# InfiniBand support
+#
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=m
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
+# 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=m
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_DNOTIFY is not set
+# 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=m
+CONFIG_MSDOS_FS=m
+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_KCORE=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_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_SUMMARY is not set
+# 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
+# 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=m
+# 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=m
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=m
+
+#
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# 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_LOG_BUF_SHIFT=14
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+CONFIG_TIMER_STATS=y
+# 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=y
+# CONFIG_DEBUG_INFO is not set
+# 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_KPROBES is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_CRC_CCITT=m
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_AUDIT_GENERIC=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/recipes/linux/linux/defconfig b/recipes/linux/linux/defconfig
new file mode 100644
index 0000000000..7e3e549061
--- /dev/null
+++ b/recipes/linux/linux/defconfig
@@ -0,0 +1,989 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.28
+# Mon Jan 12 20:23:50 2009
+#
+# CONFIG_PPC64 is not set
+
+#
+# Processor support
+#
+CONFIG_6xx=y
+# CONFIG_PPC_85xx is not set
+# CONFIG_PPC_8xx is not set
+# CONFIG_40x is not set
+# CONFIG_44x is not set
+# CONFIG_E200 is not set
+CONFIG_PPC_FPU=y
+# CONFIG_ALTIVEC is not set
+CONFIG_PPC_STD_MMU=y
+CONFIG_PPC_STD_MMU_32=y
+# CONFIG_PPC_MM_SLICES is not set
+# CONFIG_SMP is not set
+CONFIG_NOT_COHERENT_CACHE=y
+CONFIG_PPC32=y
+CONFIG_WORD_SIZE=32
+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
+CONFIG_MMU=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+CONFIG_IRQ_PER_CPU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_ARCH_HAS_ILOG2_U32=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+# CONFIG_ARCH_NO_VIRT_TO_BUS is not set
+CONFIG_PPC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_PPC_OF=y
+CONFIG_OF=y
+# CONFIG_PPC_UDBG_16550 is not set
+# CONFIG_GENERIC_TBSYNC is not set
+CONFIG_AUDIT_ARCH=y
+CONFIG_GENERIC_BUG=y
+# CONFIG_DEFAULT_UIMAGE is not set
+# CONFIG_PPC_DCR_NATIVE is not set
+# CONFIG_PPC_DCR_MMIO is not set
+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="-isobel-gcn"
+CONFIG_LOCALVERSION_AUTO=y
+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_AUDIT is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+CONFIG_GROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+# CONFIG_ELF_CORE is not set
+CONFIG_COMPAT_BRK=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+# CONFIG_VM_EVENT_COUNTERS is not set
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_TRACEPOINTS=y
+CONFIG_MARKERS=y
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+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=y
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_CLASSIC_RCU=y
+# CONFIG_FREEZER is not set
+
+#
+# Platform support
+#
+CONFIG_PPC_MULTIPLATFORM=y
+CONFIG_CLASSIC32=y
+# CONFIG_PPC_CHRP is not set
+# CONFIG_MPC5121_ADS is not set
+# CONFIG_MPC5121_GENERIC is not set
+# CONFIG_PPC_MPC52xx is not set
+# CONFIG_PPC_PMAC is not set
+# CONFIG_PPC_CELL is not set
+# CONFIG_PPC_CELL_NATIVE is not set
+# CONFIG_PPC_82xx is not set
+# CONFIG_PQ2ADS is not set
+# CONFIG_PPC_83xx is not set
+# CONFIG_PPC_86xx is not set
+CONFIG_EMBEDDED6xx=y
+# CONFIG_LINKSTATION is not set
+# CONFIG_STORCENTER is not set
+# CONFIG_MPC7448HPC2 is not set
+# CONFIG_PPC_HOLLY is not set
+# CONFIG_PPC_PRPMC2800 is not set
+# CONFIG_PPC_C2K is not set
+CONFIG_GAMECUBE=y
+# CONFIG_WII is not set
+CONFIG_FLIPPER_PIC=y
+CONFIG_GAMECUBE_COMMON=y
+CONFIG_GAMECUBE_RSW=y
+CONFIG_GAMECUBE_UDBG=y
+CONFIG_USBGECKO_UDBG=y
+# CONFIG_GAMECUBE_VIDEO_UDBG is not set
+# CONFIG_IPIC is not set
+# CONFIG_MPIC is not set
+# CONFIG_MPIC_WEIRD is not set
+# CONFIG_PPC_I8259 is not set
+# CONFIG_PPC_RTAS is not set
+# CONFIG_MMIO_NVRAM is not set
+# CONFIG_PPC_MPC106 is not set
+# CONFIG_PPC_970_NAP is not set
+# CONFIG_PPC_INDIRECT_IO is not set
+# CONFIG_GENERIC_IOMAP is not set
+# CONFIG_CPU_FREQ is not set
+# CONFIG_TAU is not set
+# CONFIG_FSL_ULI1575 is not set
+
+#
+# Kernel options
+#
+# CONFIG_HIGHMEM is not set
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_SCHED_HRTICK is not set
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+# CONFIG_PREEMPT_RCU is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
+CONFIG_BINFMT_MISC=m
+# CONFIG_IOMMU_HELPER is not set
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_HAS_WALK_MEMORY=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_KEXEC=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_MIGRATION is not set
+# CONFIG_RESOURCES_64BIT is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
+CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_CMDLINE_BOOL is not set
+CONFIG_EXTRA_TARGETS=""
+# CONFIG_PM is not set
+# CONFIG_SECCOMP is not set
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_ZONE_DMA=y
+CONFIG_GENERIC_ISA_DMA=y
+# CONFIG_PCI is not set
+# CONFIG_PCI_DOMAINS is not set
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+# CONFIG_HAS_RAPIDIO is not set
+
+#
+# Advanced setup
+#
+CONFIG_ADVANCED_OPTIONS=y
+# CONFIG_LOWMEM_SIZE_BOOL is not set
+CONFIG_LOWMEM_SIZE=0x30000000
+# CONFIG_PAGE_OFFSET_BOOL is not set
+CONFIG_PAGE_OFFSET=0xc0000000
+# CONFIG_KERNEL_START_BOOL is not set
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_PHYSICAL_START=0x00000000
+# CONFIG_TASK_SIZE_BOOL is not set
+CONFIG_TASK_SIZE=0xc0000000
+# CONFIG_CONSISTENT_START_BOOL is not set
+CONFIG_CONSISTENT_START=0xff100000
+# CONFIG_CONSISTENT_SIZE_BOOL is not set
+CONFIG_CONSISTENT_SIZE=0x00200000
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+# 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 is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_PHONET is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_STANDALONE is not set
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# 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 is not set
+CONFIG_OF_DEVICE=y
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_FD is not set
+CONFIG_GAMECUBE_DI=y
+CONFIG_GAMECUBE_ARAM=y
+CONFIG_GAMECUBE_SD=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=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=2
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_MISC_DEVICES=y
+CONFIG_GAMECUBE_GQR=y
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_C2PORT is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_MACINTOSH_DRIVERS is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+CONFIG_GAMECUBE_BBA=y
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_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
+# CONFIG_IWLWIFI_LEDS is not set
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP 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
+# CONFIG_PHONE 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 is not set
+CONFIG_INPUT_JOYDEV=y
+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_INPUT_MOUSE 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_ZHENHUA is not set
+# CONFIG_JOYSTICK_JOYDUMP is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_LIBPS2 is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO_XILINX_XPS_PS2 is not set
+# CONFIG_GAMEPORT is not set
+CONFIG_GAMECUBE_SI=y
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+# CONFIG_DEVKMEM is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_UARTLITE is not set
+# CONFIG_SERIAL_USBGECKO is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=64
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_NVRAM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_I2C is not set
+
+#
+# EXI support
+#
+CONFIG_GAMECUBE_EXI=y
+# CONFIG_SPI is not set
+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
+# CONFIG_GPIOLIB is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_REGULATOR is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_OF is not set
+# CONFIG_FB_VGA16 is not set
+# CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_GAMECUBE=y
+# CONFIG_FB_IBM_GXT4500 is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY 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 is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+# CONFIG_LOGO_LINUX_CLUT224 is not set
+CONFIG_LOGO_GAMECUBE_CLUT224=y
+CONFIG_SOUND=y
+CONFIG_SOUND_OSS_CORE=y
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+CONFIG_SND_SEQUENCER=y
+# CONFIG_SND_SEQ_DUMMY 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_SEQUENCER_OSS=y
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+# CONFIG_SND_VERBOSE_PROCFS is not set
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+CONFIG_SND_DRIVERS=y
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_VIRMIDI is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+CONFIG_SND_PPC=y
+CONFIG_SND_GAMECUBE=y
+CONFIG_SND_GAMECUBE_MIC=m
+# CONFIG_SND_SOC is not set
+# CONFIG_SOUND_PRIME is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
+# CONFIG_HID_PID is not set
+
+#
+# Special HID drivers
+#
+CONFIG_HID_COMPAT=y
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_EDAC is not set
+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
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+CONFIG_RTC_DRV_GCN=y
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_RTC_DRV_PPC is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FILE_LOCKING=y
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+# CONFIG_ZISOFS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_GCDVD_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_KCORE=y
+CONFIG_PROC_SYSCTL=y
+# CONFIG_PROC_PAGE_MONITOR is not set
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# 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_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_REGISTER_V4 is not set
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+CONFIG_CIFS=y
+# CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
+# CONFIG_CIFS_XATTR 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
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+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
+# CONFIG_DLM is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_CRC_CCITT=y
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_HAVE_LMB=y
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# 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=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+CONFIG_SCHEDSTATS=y
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS 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_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+CONFIG_STACKTRACE=y
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_FAULT_INJECTION is not set
+CONFIG_LATENCYTOP=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_RING_BUFFER=y
+CONFIG_TRACING=y
+
+#
+# Tracers
+#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_PREEMPT_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+CONFIG_CONTEXT_SWITCH_TRACER=y
+CONFIG_BOOT_TRACER=y
+# CONFIG_STACK_TRACER is not set
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_PAGEALLOC is not set
+# CONFIG_CODE_PATCHING_SELFTEST is not set
+# CONFIG_FTR_FIXUP_SELFTEST is not set
+# CONFIG_MSI_BITMAP_SELFTEST is not set
+# CONFIG_XMON is not set
+# CONFIG_IRQSTACKS is not set
+# CONFIG_VIRQ_DEBUG is not set
+# CONFIG_BDI_SWITCH is not set
+# CONFIG_BOOTX_TEXT is not set
+CONFIG_PPC_EARLY_DEBUG=y
+# CONFIG_PPC_EARLY_DEBUG_LPAR is not set
+# CONFIG_PPC_EARLY_DEBUG_G5 is not set
+# CONFIG_PPC_EARLY_DEBUG_RTAS_PANEL is not set
+# CONFIG_PPC_EARLY_DEBUG_RTAS_CONSOLE is not set
+# CONFIG_PPC_EARLY_DEBUG_MAPLE is not set
+# CONFIG_PPC_EARLY_DEBUG_ISERIES is not set
+# CONFIG_PPC_EARLY_DEBUG_PAS_REALMODE is not set
+# CONFIG_PPC_EARLY_DEBUG_BEAT is not set
+# CONFIG_PPC_EARLY_DEBUG_44x is not set
+# CONFIG_PPC_EARLY_DEBUG_40x is not set
+# CONFIG_PPC_EARLY_DEBUG_CPM is not set
+CONFIG_PPC_EARLY_DEBUG_USBGECKO=y
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_CRYPTO is not set
+# CONFIG_PPC_CLOCK is not set
+# CONFIG_VIRTUALIZATION is not set
diff --git a/recipes/linux/linux/ep93xx/defconfig b/recipes/linux/linux/ep93xx/defconfig
new file mode 100644
index 0000000000..e42a804b5a
--- /dev/null
+++ b/recipes/linux/linux/ep93xx/defconfig
@@ -0,0 +1,1176 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.18-rc1-git9
+# Sat Jul 15 20:13:41 2006
+#
+CONFIG_ARM=y
+CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=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_VECTORS_BASE=0xffff0000
+CONFIG_RUNTIME_PHYS_OFFSET=y
+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=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_UID16=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_EMBEDDED=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_RT_MUTEXES=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SHMEM=y
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=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_BLK_DEV_IO_TRACE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+CONFIG_IOSCHED_DEADLINE=y
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_DEFAULT_AS is not set
+CONFIG_DEFAULT_DEADLINE=y
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="deadline"
+
+#
+# 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=y
+# 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_IOP3XX 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 is not set
+# 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
+
+#
+# Cirrus EP93xx Implementation Options
+#
+CONFIG_CRUNCH=y
+
+#
+# EP93xx Platforms
+#
+CONFIG_MACH_EDB9302=y
+CONFIG_MACH_EDB9315=y
+CONFIG_MACH_EDB9315A=y
+CONFIG_MACH_GESBC9312=y
+# CONFIG_MACH_MICRO9 is not set
+CONFIG_MACH_TS72XX=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM920T=y
+CONFIG_CPU_32v4=y
+CONFIG_CPU_ABRT_EV4T=y
+CONFIG_CPU_CACHE_V4WT=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+CONFIG_ARM_VIC=y
+
+#
+# Bus support
+#
+CONFIG_ARM_AMBA=y
+
+#
+# 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="console=ttyAM0,57600 root=/dev/nfs ip=bootp"
+# CONFIG_XIP_KERNEL is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+CONFIG_FPE_NWFPE_XP=y
+# 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_APM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+CONFIG_IPV6=y
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+CONFIG_INET6_XFRM_MODE_TRANSPORT=y
+CONFIG_INET6_XFRM_MODE_TUNNEL=y
+# CONFIG_IPV6_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_NET_DIVERT 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 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER 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=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_REDBOOT_PARTS=y
+CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
+# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
+# CONFIG_MTD_REDBOOT_PARTS_READONLY 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_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL 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=y
+CONFIG_MTD_CFI_NOSWAP=y
+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_GEOMETRY 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_OTP 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=y
+# 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_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_START=0x0
+CONFIG_MTD_PHYSMAP_LEN=0x0
+CONFIG_MTD_PHYSMAP_BANKWIDTH=1
+# CONFIG_MTD_ARM_INTEGRATOR 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=y
+CONFIG_MTD_NAND_VERIFY_WRITE=y
+# CONFIG_MTD_NAND_ECC_SMC is not set
+CONFIG_MTD_NAND_TS7250=y
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# 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
+#
+
+#
+# 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 is not set
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+# 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
+
+#
+# SCSI Transport Attributes
+#
+# 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
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_DEBUG 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_EP93XX_ETH=y
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO 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 is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# 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_AMBA_PL010=y
+CONFIG_SERIAL_AMBA_PL010_CONSOLE=y
+# CONFIG_SERIAL_AMBA_PL011 is not set
+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
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_EP93XX_WATCHDOG=y
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+# CONFIG_HW_RANDOM is not set
+# 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
+# CONFIG_TELCLOCK is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=y
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_PCA_ISA is not set
+# CONFIG_I2C_EP93XX is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 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_I2C_DEBUG_CORE=y
+CONFIG_I2C_DEBUG_ALGO=y
+CONFIG_I2C_DEBUG_BUS=y
+CONFIG_I2C_DEBUG_CHIP=y
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 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_MAX1619 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D 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
+
+#
+# Misc devices
+#
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+# CONFIG_USB_DABUSB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+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=y
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_BANDWIDTH is not set
+CONFIG_USB_DYNAMIC_MINORS=y
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_OHCI_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_LIBUSUAL is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+
+#
+# Input core support is needed for USB HID input layer or HIDBP support
+#
+# CONFIG_USB_HIDDEV 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 is not set
+# CONFIG_USB_MON is not set
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+CONFIG_USB_SERIAL=y
+CONFIG_USB_SERIAL_CONSOLE=y
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_AIRPRIME is not set
+# CONFIG_USB_SERIAL_ANYDATA 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 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_NAVMAN is not set
+CONFIG_USB_SERIAL_PL2303=y
+# 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
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 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_PHIDGETKIT is not set
+# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD 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 is not set
+
+#
+# Real Time Clock
+#
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+
+#
+# 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_X1205 is not set
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+CONFIG_RTC_DRV_M48T86=y
+CONFIG_RTC_DRV_EP93XX=y
+# CONFIG_RTC_DRV_PL031 is not set
+# CONFIG_RTC_DRV_TEST is not set
+# CONFIG_RTC_DRV_V3020 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 is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+# 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_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 is not set
+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_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 is not set
+# 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_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=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+
+#
+# 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
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+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=y
+# CONFIG_DEBUG_SLAB_LEAK 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 is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_DEBUG_VM is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_UNWIND_INFO is not set
+CONFIG_FORCED_INLINING=y
+# 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 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_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
diff --git a/recipes/linux/linux/i586-generic/defconfig b/recipes/linux/linux/i586-generic/defconfig
new file mode 100644
index 0000000000..b06f535e7b
--- /dev/null
+++ b/recipes/linux/linux/i586-generic/defconfig
@@ -0,0 +1,2705 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.20
+# Sat May 26 01:56:02 2007
+#
+CONFIG_X86_32=y
+CONFIG_GENERIC_TIME=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_SEMAPHORE_SLEEPERS=y
+CONFIG_X86=y
+CONFIG_MMU=y
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_GENERIC_IOMAP=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_DMI=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_POSIX_MQUEUE=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
+CONFIG_AUDIT=y
+CONFIG_AUDITSYSCALL=y
+# CONFIG_IKCONFIG is not set
+# CONFIG_CPUSETS is not set
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+# CONFIG_EMBEDDED is not set
+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_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=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+CONFIG_STOP_MACHINE=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"
+
+#
+# Processor type and features
+#
+CONFIG_SMP=y
+CONFIG_X86_PC=y
+# CONFIG_X86_ELAN is not set
+# CONFIG_X86_VOYAGER is not set
+# CONFIG_X86_NUMAQ is not set
+# CONFIG_X86_SUMMIT is not set
+# CONFIG_X86_BIGSMP is not set
+# CONFIG_X86_VISWS is not set
+# CONFIG_X86_GENERICARCH is not set
+# CONFIG_X86_ES7000 is not set
+# CONFIG_PARAVIRT is not set
+# CONFIG_M386 is not set
+# CONFIG_M486 is not set
+CONFIG_M586=y
+# CONFIG_M586TSC is not set
+# CONFIG_M586MMX is not set
+# CONFIG_M686 is not set
+# CONFIG_MPENTIUMII is not set
+# CONFIG_MPENTIUMIII is not set
+# CONFIG_MPENTIUMM is not set
+# CONFIG_MCORE2 is not set
+# CONFIG_MPENTIUM4 is not set
+# CONFIG_MK6 is not set
+# CONFIG_MK7 is not set
+# CONFIG_MK8 is not set
+# CONFIG_MCRUSOE is not set
+# CONFIG_MEFFICEON is not set
+# CONFIG_MWINCHIPC6 is not set
+# CONFIG_MWINCHIP2 is not set
+# CONFIG_MWINCHIP3D is not set
+# CONFIG_MGEODEGX1 is not set
+# CONFIG_MGEODE_LX is not set
+# CONFIG_MCYRIXIII is not set
+# CONFIG_MVIAC3_2 is not set
+# CONFIG_X86_GENERIC is not set
+CONFIG_X86_CMPXCHG=y
+CONFIG_X86_XADD=y
+CONFIG_X86_L1_CACHE_SHIFT=5
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_X86_PPRO_FENCE=y
+CONFIG_X86_F00F_BUG=y
+CONFIG_X86_WP_WORKS_OK=y
+CONFIG_X86_INVLPG=y
+CONFIG_X86_BSWAP=y
+CONFIG_X86_POPAD_OK=y
+CONFIG_X86_CMPXCHG64=y
+CONFIG_X86_ALIGNMENT_16=y
+CONFIG_HPET_TIMER=y
+CONFIG_NR_CPUS=8
+CONFIG_SCHED_SMT=y
+CONFIG_SCHED_MC=y
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_PREEMPT_BKL=y
+CONFIG_X86_LOCAL_APIC=y
+CONFIG_X86_IO_APIC=y
+CONFIG_X86_MCE=y
+# CONFIG_X86_MCE_NONFATAL is not set
+# CONFIG_X86_MCE_P4THERMAL is not set
+CONFIG_VM86=y
+# CONFIG_TOSHIBA is not set
+# CONFIG_I8K is not set
+# CONFIG_X86_REBOOTFIXUPS is not set
+# CONFIG_MICROCODE is not set
+# CONFIG_X86_MSR is not set
+# CONFIG_X86_CPUID is not set
+
+#
+# Firmware Drivers
+#
+# CONFIG_EDD is not set
+# CONFIG_DELL_RBU is not set
+# CONFIG_DCDBAS is not set
+# CONFIG_NOHIGHMEM is not set
+CONFIG_HIGHMEM4G=y
+# CONFIG_HIGHMEM64G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_HIGHMEM=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+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=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_RESOURCES_64BIT=y
+# CONFIG_HIGHPTE is not set
+# CONFIG_MATH_EMULATION is not set
+CONFIG_MTRR=y
+# CONFIG_EFI is not set
+CONFIG_IRQBALANCE=y
+CONFIG_SECCOMP=y
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_KEXEC is not set
+# CONFIG_CRASH_DUMP is not set
+CONFIG_PHYSICAL_START=0x100000
+# CONFIG_RELOCATABLE is not set
+CONFIG_PHYSICAL_ALIGN=0x100000
+# CONFIG_HOTPLUG_CPU is not set
+CONFIG_COMPAT_VDSO=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+
+#
+# Power management options (ACPI, APM)
+#
+CONFIG_PM=y
+CONFIG_PM_LEGACY=y
+# CONFIG_PM_DEBUG is not set
+# CONFIG_PM_SYSFS_DEPRECATED is not set
+
+#
+# ACPI (Advanced Configuration and Power Interface) Support
+#
+CONFIG_ACPI=y
+CONFIG_ACPI_AC=y
+CONFIG_ACPI_BATTERY=y
+CONFIG_ACPI_BUTTON=y
+CONFIG_ACPI_VIDEO=m
+# CONFIG_ACPI_HOTKEY is not set
+CONFIG_ACPI_FAN=y
+# CONFIG_ACPI_DOCK is not set
+CONFIG_ACPI_PROCESSOR=y
+CONFIG_ACPI_THERMAL=y
+# CONFIG_ACPI_ASUS is not set
+CONFIG_ACPI_IBM=m
+# CONFIG_ACPI_IBM_DOCK is not set
+# CONFIG_ACPI_TOSHIBA is not set
+CONFIG_ACPI_BLACKLIST_YEAR=0
+# CONFIG_ACPI_DEBUG is not set
+CONFIG_ACPI_EC=y
+CONFIG_ACPI_POWER=y
+CONFIG_ACPI_SYSTEM=y
+CONFIG_X86_PM_TIMER=y
+CONFIG_ACPI_CONTAINER=m
+CONFIG_ACPI_SBS=m
+
+#
+# APM (Advanced Power Management) BIOS Support
+#
+CONFIG_APM=y
+# CONFIG_APM_IGNORE_USER_SUSPEND is not set
+# CONFIG_APM_DO_ENABLE is not set
+# CONFIG_APM_CPU_IDLE is not set
+# CONFIG_APM_DISPLAY_BLANK is not set
+# CONFIG_APM_RTC_IS_GMT is not set
+# CONFIG_APM_ALLOW_INTS is not set
+# CONFIG_APM_REAL_MODE_POWER_OFF is not set
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+#
+CONFIG_PCI=y
+# CONFIG_PCI_GOBIOS is not set
+# CONFIG_PCI_GOMMCONFIG is not set
+# CONFIG_PCI_GODIRECT is not set
+CONFIG_PCI_GOANY=y
+CONFIG_PCI_BIOS=y
+CONFIG_PCI_DIRECT=y
+CONFIG_PCI_MMCONFIG=y
+CONFIG_PCIEPORTBUS=y
+# CONFIG_HOTPLUG_PCI_PCIE is not set
+CONFIG_PCIEAER=y
+# CONFIG_PCI_MSI is not set
+CONFIG_HT_IRQ=y
+CONFIG_ISA_DMA_API=y
+# CONFIG_ISA is not set
+# CONFIG_MCA is not set
+CONFIG_SCx200=m
+CONFIG_SCx200HR_TIMER=m
+CONFIG_K8_NB=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+CONFIG_PCCARD=m
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=m
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
+CONFIG_CARDBUS=y
+
+#
+# PC-card bridges
+#
+CONFIG_YENTA=m
+CONFIG_YENTA_O2=y
+CONFIG_YENTA_RICOH=y
+CONFIG_YENTA_TI=y
+CONFIG_YENTA_ENE_TUNE=y
+CONFIG_YENTA_TOSHIBA=y
+CONFIG_PD6729=m
+CONFIG_I82092=m
+CONFIG_PCCARD_NONSTATIC=m
+
+#
+# PCI Hotplug Support
+#
+CONFIG_HOTPLUG_PCI=m
+CONFIG_HOTPLUG_PCI_FAKE=m
+CONFIG_HOTPLUG_PCI_COMPAQ=m
+# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set
+CONFIG_HOTPLUG_PCI_IBM=m
+CONFIG_HOTPLUG_PCI_ACPI=m
+CONFIG_HOTPLUG_PCI_ACPI_IBM=m
+# CONFIG_HOTPLUG_PCI_CPCI is not set
+CONFIG_HOTPLUG_PCI_SHPC=m
+# CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_MISC=y
+
+#
+# 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=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE 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
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS 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=y
+# CONFIG_NETFILTER_DEBUG is not set
+
+#
+# Core Netfilter Configuration
+#
+# CONFIG_NETFILTER_NETLINK is not set
+# CONFIG_NF_CONNTRACK_ENABLED is not set
+# CONFIG_NETFILTER_XTABLES is not set
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_IP_NF_QUEUE=y
+
+#
+# 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 is not set
+# 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=m
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=m
+# CONFIG_MTD_PARTITIONS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+CONFIG_FTL=m
+CONFIG_NFTL=m
+# CONFIG_NFTL_RW is not set
+CONFIG_INFTL=m
+CONFIG_RFD_FTL=m
+CONFIG_SSFDC=y
+
+#
+# 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=y
+CONFIG_MTD_ROM=y
+CONFIG_MTD_ABSENT=y
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_SC520CDP is not set
+# CONFIG_MTD_TS5500 is not set
+# CONFIG_MTD_AMD76XROM is not set
+# CONFIG_MTD_ICHXROM is not set
+# CONFIG_MTD_ESB2ROM is not set
+# CONFIG_MTD_CK804XROM is not set
+# CONFIG_MTD_SCB2_FLASH is not set
+# CONFIG_MTD_L440GX is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+CONFIG_MTD_PMC551=m
+# CONFIG_MTD_PMC551_BUGFIX is not set
+# CONFIG_MTD_PMC551_DEBUG is not set
+CONFIG_MTD_DATAFLASH=m
+CONFIG_MTD_M25P80=m
+CONFIG_MTD_SLRAM=m
+CONFIG_MTD_PHRAM=m
+# CONFIG_MTD_MTDRAM is not set
+CONFIG_MTD_BLOCK2MTD=y
+
+#
+# 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=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+CONFIG_MTD_NAND_IDS=y
+CONFIG_MTD_NAND_DISKONCHIP=y
+# CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set
+CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0
+# CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE is not set
+CONFIG_MTD_NAND_CAFE=y
+CONFIG_MTD_NAND_CS553X=y
+
+#
+# OneNAND Flash Device Drivers
+#
+CONFIG_MTD_ONENAND=m
+# CONFIG_MTD_ONENAND_VERIFY_WRITE is not set
+# CONFIG_MTD_ONENAND_OTP is not set
+
+#
+# Parallel port support
+#
+CONFIG_PARPORT=y
+CONFIG_PARPORT_PC=y
+# CONFIG_PARPORT_SERIAL is not set
+# CONFIG_PARPORT_PC_FIFO is not set
+# CONFIG_PARPORT_PC_SUPERIO is not set
+# CONFIG_PARPORT_PC_PCMCIA is not set
+# CONFIG_PARPORT_GSC is not set
+CONFIG_PARPORT_AX88796=m
+# CONFIG_PARPORT_1284 is not set
+CONFIG_PARPORT_NOT_PC=y
+
+#
+# Plug and Play support
+#
+CONFIG_PNP=y
+# CONFIG_PNP_DEBUG is not set
+
+#
+# Protocols
+#
+CONFIG_PNPACPI=y
+
+#
+# Block devices
+#
+CONFIG_BLK_DEV_FD=y
+CONFIG_PARIDE=m
+CONFIG_PARIDE_PARPORT=y
+
+#
+# Parallel IDE high-level drivers
+#
+CONFIG_PARIDE_PD=m
+CONFIG_PARIDE_PCD=m
+CONFIG_PARIDE_PF=m
+CONFIG_PARIDE_PT=m
+CONFIG_PARIDE_PG=m
+
+#
+# Parallel IDE protocol modules
+#
+CONFIG_PARIDE_ATEN=m
+CONFIG_PARIDE_BPCK=m
+CONFIG_PARIDE_BPCK6=m
+CONFIG_PARIDE_COMM=m
+CONFIG_PARIDE_DSTR=m
+CONFIG_PARIDE_FIT2=m
+CONFIG_PARIDE_FIT3=m
+CONFIG_PARIDE_EPAT=m
+# CONFIG_PARIDE_EPATC8 is not set
+CONFIG_PARIDE_EPIA=m
+CONFIG_PARIDE_FRIQ=m
+CONFIG_PARIDE_FRPW=m
+CONFIG_PARIDE_KBIC=m
+CONFIG_PARIDE_KTTI=m
+CONFIG_PARIDE_ON20=m
+CONFIG_PARIDE_ON26=m
+CONFIG_BLK_CPQ_DA=m
+CONFIG_BLK_CPQ_CISS_DA=m
+# CONFIG_CISS_SCSI_TAPE is not set
+CONFIG_BLK_DEV_DAC960=m
+CONFIG_BLK_DEV_UMEM=m
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_SX8=m
+CONFIG_BLK_DEV_UB=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+CONFIG_ATA_OVER_ETH=m
+
+#
+# Misc devices
+#
+# CONFIG_IBM_ASM is not set
+# CONFIG_SGI_IOC4 is not set
+CONFIG_TIFM_CORE=m
+CONFIG_TIFM_7XX1=m
+# CONFIG_MSI_LAPTOP is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+# CONFIG_BLK_DEV_HD_IDE is not set
+CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_IDEDISK_MULTI_MODE=y
+# CONFIG_BLK_DEV_IDECS is not set
+CONFIG_BLK_DEV_IDECD=y
+# 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=y
+CONFIG_BLK_DEV_CMD640=y
+# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
+# CONFIG_BLK_DEV_IDEPNP is not set
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_IDEPCI_SHARE_IRQ=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+CONFIG_BLK_DEV_RZ1000=y
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+CONFIG_IDEDMA_PCI_AUTO=y
+# CONFIG_IDEDMA_ONLYDISK is not set
+CONFIG_BLK_DEV_AEC62XX=y
+CONFIG_BLK_DEV_ALI15X3=y
+# CONFIG_WDC_ALI15X3 is not set
+CONFIG_BLK_DEV_AMD74XX=y
+CONFIG_BLK_DEV_ATIIXP=y
+CONFIG_BLK_DEV_CMD64X=y
+CONFIG_BLK_DEV_TRIFLEX=y
+CONFIG_BLK_DEV_CY82C693=y
+CONFIG_BLK_DEV_CS5520=y
+CONFIG_BLK_DEV_CS5530=y
+CONFIG_BLK_DEV_CS5535=y
+CONFIG_BLK_DEV_HPT34X=y
+# CONFIG_HPT34X_AUTODMA is not set
+CONFIG_BLK_DEV_HPT366=y
+CONFIG_BLK_DEV_JMICRON=y
+CONFIG_BLK_DEV_SC1200=y
+CONFIG_BLK_DEV_PIIX=y
+CONFIG_BLK_DEV_IT821X=y
+CONFIG_BLK_DEV_NS87415=y
+CONFIG_BLK_DEV_PDC202XX_OLD=y
+# CONFIG_PDC202XX_BURST is not set
+CONFIG_BLK_DEV_PDC202XX_NEW=y
+CONFIG_BLK_DEV_SVWKS=y
+CONFIG_BLK_DEV_SIIMAGE=y
+CONFIG_BLK_DEV_SIS5513=y
+CONFIG_BLK_DEV_SLC90E66=y
+CONFIG_BLK_DEV_TRM290=y
+CONFIG_BLK_DEV_VIA82CXXX=y
+# CONFIG_IDE_ARM is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+CONFIG_IDEDMA_AUTO=y
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_TGT=m
+CONFIG_SCSI_NETLINK=y
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+CONFIG_CHR_DEV_SG=y
+CONFIG_CHR_DEV_SCH=m
+
+#
+# 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=m
+CONFIG_SCSI_FC_ATTRS=m
+CONFIG_SCSI_ISCSI_ATTRS=m
+CONFIG_SCSI_SAS_ATTRS=m
+CONFIG_SCSI_SAS_LIBSAS=m
+CONFIG_SCSI_SAS_LIBSAS_DEBUG=y
+
+#
+# SCSI low-level drivers
+#
+CONFIG_ISCSI_TCP=m
+CONFIG_BLK_DEV_3W_XXXX_RAID=m
+CONFIG_SCSI_3W_9XXX=m
+CONFIG_SCSI_ACARD=m
+CONFIG_SCSI_AACRAID=m
+CONFIG_SCSI_AIC7XXX=m
+CONFIG_AIC7XXX_CMDS_PER_DEVICE=32
+CONFIG_AIC7XXX_RESET_DELAY_MS=5000
+CONFIG_AIC7XXX_DEBUG_ENABLE=y
+CONFIG_AIC7XXX_DEBUG_MASK=0
+CONFIG_AIC7XXX_REG_PRETTY_PRINT=y
+CONFIG_SCSI_AIC7XXX_OLD=m
+CONFIG_SCSI_AIC79XX=m
+CONFIG_AIC79XX_CMDS_PER_DEVICE=32
+CONFIG_AIC79XX_RESET_DELAY_MS=5000
+# CONFIG_AIC79XX_ENABLE_RD_STRM is not set
+CONFIG_AIC79XX_DEBUG_ENABLE=y
+CONFIG_AIC79XX_DEBUG_MASK=0
+CONFIG_AIC79XX_REG_PRETTY_PRINT=y
+CONFIG_SCSI_AIC94XX=m
+CONFIG_AIC94XX_DEBUG=y
+CONFIG_SCSI_DPT_I2O=m
+CONFIG_SCSI_ADVANSYS=m
+CONFIG_SCSI_ARCMSR=m
+# CONFIG_MEGARAID_NEWGEN is not set
+CONFIG_MEGARAID_LEGACY=m
+CONFIG_MEGARAID_SAS=m
+CONFIG_SCSI_HPTIOP=m
+CONFIG_SCSI_BUSLOGIC=m
+# CONFIG_SCSI_OMIT_FLASHPOINT is not set
+CONFIG_SCSI_DMX3191D=m
+CONFIG_SCSI_EATA=m
+# CONFIG_SCSI_EATA_TAGGED_QUEUE is not set
+# CONFIG_SCSI_EATA_LINKED_COMMANDS is not set
+CONFIG_SCSI_EATA_MAX_TAGS=16
+CONFIG_SCSI_FUTURE_DOMAIN=m
+CONFIG_SCSI_GDTH=m
+CONFIG_SCSI_IPS=m
+CONFIG_SCSI_INITIO=m
+CONFIG_SCSI_INIA100=m
+CONFIG_SCSI_PPA=m
+CONFIG_SCSI_IMM=m
+# CONFIG_SCSI_IZIP_EPP16 is not set
+# CONFIG_SCSI_IZIP_SLOW_CTR is not set
+CONFIG_SCSI_STEX=m
+CONFIG_SCSI_SYM53C8XX_2=m
+CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
+CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
+CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
+CONFIG_SCSI_SYM53C8XX_MMIO=y
+# CONFIG_SCSI_IPR is not set
+CONFIG_SCSI_QLOGIC_1280=m
+CONFIG_SCSI_QLA_FC=m
+CONFIG_SCSI_QLA_ISCSI=m
+CONFIG_SCSI_LPFC=m
+CONFIG_SCSI_DC395x=m
+CONFIG_SCSI_DC390T=m
+CONFIG_SCSI_NSP32=m
+CONFIG_SCSI_DEBUG=m
+CONFIG_SCSI_SRP=m
+
+#
+# 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=y
+# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_SATA_AHCI=y
+CONFIG_SATA_SVW=y
+CONFIG_ATA_PIIX=y
+CONFIG_SATA_MV=y
+CONFIG_SATA_NV=y
+CONFIG_PDC_ADMA=y
+CONFIG_SATA_QSTOR=y
+CONFIG_SATA_PROMISE=y
+CONFIG_SATA_SX4=y
+CONFIG_SATA_SIL=y
+CONFIG_SATA_SIL24=y
+CONFIG_SATA_SIS=y
+CONFIG_SATA_ULI=y
+CONFIG_SATA_VIA=y
+CONFIG_SATA_VITESSE=y
+CONFIG_SATA_INTEL_COMBINED=y
+CONFIG_PATA_ALI=y
+CONFIG_PATA_AMD=y
+CONFIG_PATA_ARTOP=y
+CONFIG_PATA_ATIIXP=y
+CONFIG_PATA_CMD64X=y
+CONFIG_PATA_CS5520=y
+CONFIG_PATA_CS5530=y
+CONFIG_PATA_CS5535=y
+CONFIG_PATA_CYPRESS=y
+CONFIG_PATA_EFAR=y
+CONFIG_ATA_GENERIC=y
+CONFIG_PATA_HPT366=y
+CONFIG_PATA_HPT37X=y
+CONFIG_PATA_HPT3X2N=y
+CONFIG_PATA_HPT3X3=y
+CONFIG_PATA_IT821X=y
+CONFIG_PATA_JMICRON=y
+CONFIG_PATA_TRIFLEX=y
+CONFIG_PATA_MARVELL=y
+CONFIG_PATA_MPIIX=y
+CONFIG_PATA_OLDPIIX=y
+CONFIG_PATA_NETCELL=y
+CONFIG_PATA_NS87410=y
+CONFIG_PATA_OPTI=y
+CONFIG_PATA_OPTIDMA=y
+# CONFIG_PATA_PCMCIA is not set
+CONFIG_PATA_PDC_OLD=y
+CONFIG_PATA_RADISYS=y
+CONFIG_PATA_RZ1000=y
+CONFIG_PATA_SC1200=y
+CONFIG_PATA_SERVERWORKS=y
+CONFIG_PATA_PDC2027X=y
+CONFIG_PATA_SIL680=y
+CONFIG_PATA_SIS=y
+CONFIG_PATA_VIA=y
+CONFIG_PATA_WINBOND=y
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=m
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID456=m
+CONFIG_MD_RAID5_RESHAPE=y
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+# CONFIG_DM_DEBUG is not set
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_EMC=m
+
+#
+# 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=y
+
+#
+# Subsystem Options
+#
+# CONFIG_IEEE1394_VERBOSEDEBUG is not set
+# CONFIG_IEEE1394_OUI_DB is not set
+CONFIG_IEEE1394_EXTRA_CONFIG_ROMS=y
+CONFIG_IEEE1394_CONFIG_ROM_IP1394=y
+# CONFIG_IEEE1394_EXPORT_FULL_API is not set
+
+#
+# Device Drivers
+#
+CONFIG_IEEE1394_PCILYNX=m
+CONFIG_IEEE1394_OHCI1394=y
+
+#
+# Protocol Drivers
+#
+CONFIG_IEEE1394_VIDEO1394=m
+CONFIG_IEEE1394_SBP2=m
+# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set
+CONFIG_IEEE1394_ETH1394=m
+CONFIG_IEEE1394_DV1394=m
+CONFIG_IEEE1394_RAWIO=y
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+CONFIG_EQUALIZER=m
+CONFIG_TUN=m
+CONFIG_NET_SB1000=m
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+CONFIG_VITESSE_PHY=m
+CONFIG_SMSC_PHY=m
+CONFIG_BROADCOM_PHY=m
+CONFIG_FIXED_PHY=m
+# CONFIG_FIXED_MII_10_FDX is not set
+# CONFIG_FIXED_MII_100_FDX 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=y
+CONFIG_VORTEX=m
+CONFIG_TYPHOON=m
+
+#
+# Tulip family network device support
+#
+CONFIG_NET_TULIP=y
+CONFIG_DE2104X=m
+CONFIG_TULIP=m
+# CONFIG_TULIP_MWI is not set
+# CONFIG_TULIP_MMIO is not set
+# CONFIG_TULIP_NAPI is not set
+CONFIG_DE4X5=m
+CONFIG_WINBOND_840=m
+CONFIG_DM9102=m
+CONFIG_ULI526X=m
+# CONFIG_PCMCIA_XIRCOM is not set
+# CONFIG_HP100 is not set
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=m
+# CONFIG_PCNET32_NAPI is not set
+CONFIG_AMD8111_ETH=m
+# CONFIG_AMD8111E_NAPI is not set
+CONFIG_ADAPTEC_STARFIRE=m
+# CONFIG_ADAPTEC_STARFIRE_NAPI is not set
+CONFIG_B44=m
+CONFIG_FORCEDETH=m
+# CONFIG_FORCEDETH_NAPI is not set
+CONFIG_DGRS=m
+CONFIG_EEPRO100=m
+CONFIG_E100=m
+CONFIG_FEALNX=m
+CONFIG_NATSEMI=m
+CONFIG_NE2K_PCI=m
+CONFIG_8139CP=m
+CONFIG_8139TOO=y
+CONFIG_8139TOO_PIO=y
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_OLD_RX_RESET is not set
+CONFIG_SIS900=m
+CONFIG_EPIC100=m
+CONFIG_SUNDANCE=m
+# CONFIG_SUNDANCE_MMIO is not set
+CONFIG_TLAN=m
+CONFIG_VIA_RHINE=m
+# CONFIG_VIA_RHINE_MMIO is not set
+# CONFIG_VIA_RHINE_NAPI is not set
+CONFIG_NET_POCKET=y
+CONFIG_ATP=m
+CONFIG_DE600=m
+CONFIG_DE620=m
+
+#
+# Ethernet (1000 Mbit)
+#
+CONFIG_ACENIC=m
+# CONFIG_ACENIC_OMIT_TIGON_I is not set
+CONFIG_DL2K=m
+CONFIG_E1000=m
+# CONFIG_E1000_NAPI is not set
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
+CONFIG_NS83820=m
+CONFIG_HAMACHI=m
+CONFIG_YELLOWFIN=m
+CONFIG_R8169=m
+# CONFIG_R8169_NAPI is not set
+CONFIG_SIS190=m
+CONFIG_SKGE=m
+CONFIG_SKY2=m
+CONFIG_SK98LIN=m
+CONFIG_VIA_VELOCITY=m
+CONFIG_TIGON3=m
+CONFIG_BNX2=m
+CONFIG_QLA3XXX=m
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_IXGB is not set
+CONFIG_S2IO=m
+# CONFIG_S2IO_NAPI 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=m
+# CONFIG_IPW2100_MONITOR is not set
+# CONFIG_IPW2100_DEBUG is not set
+CONFIG_IPW2200=m
+# CONFIG_IPW2200_MONITOR is not set
+CONFIG_IPW2200_QOS=y
+# CONFIG_IPW2200_DEBUG is not set
+CONFIG_AIRO=m
+CONFIG_HERMES=m
+CONFIG_PLX_HERMES=m
+CONFIG_TMD_HERMES=m
+CONFIG_NORTEL_HERMES=m
+CONFIG_PCI_HERMES=m
+CONFIG_ATMEL=m
+# CONFIG_PCI_ATMEL is not set
+
+#
+# Wireless 802.11b Pcmcia/Cardbus cards support
+#
+# CONFIG_PCMCIA_HERMES is not set
+# CONFIG_PCMCIA_SPECTRUM is not set
+# CONFIG_AIRO_CS is not set
+# CONFIG_PCMCIA_ATMEL 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=m
+CONFIG_HOSTAP=m
+CONFIG_HOSTAP_FIRMWARE=y
+CONFIG_HOSTAP_FIRMWARE_NVRAM=y
+CONFIG_HOSTAP_PLX=m
+CONFIG_HOSTAP_PCI=m
+# CONFIG_HOSTAP_CS is not set
+CONFIG_NET_WIRELESS=y
+
+#
+# PCMCIA network device support
+#
+# CONFIG_NET_PCMCIA is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+# CONFIG_SLIP is not set
+CONFIG_SLHC=m
+# 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=m
+
+#
+# Old ISDN4Linux
+#
+# CONFIG_ISDN_I4L is not set
+
+#
+# CAPI subsystem
+#
+CONFIG_ISDN_CAPI=m
+# CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON is not set
+# CONFIG_ISDN_CAPI_MIDDLEWARE is not set
+CONFIG_ISDN_CAPI_CAPI20=m
+
+#
+# CAPI hardware drivers
+#
+
+#
+# Active AVM cards
+#
+CONFIG_CAPI_AVM=y
+CONFIG_ISDN_DRV_AVMB1_B1PCI=m
+CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y
+CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m
+# CONFIG_ISDN_DRV_AVMB1_AVM_CS is not set
+CONFIG_ISDN_DRV_AVMB1_T1PCI=m
+CONFIG_ISDN_DRV_AVMB1_C4=m
+
+#
+# Active Eicon DIVA Server cards
+#
+CONFIG_CAPI_EICON=y
+CONFIG_ISDN_DIVAS=m
+# CONFIG_ISDN_DIVAS_BRIPCI is not set
+# CONFIG_ISDN_DIVAS_PRIPCI is not set
+CONFIG_ISDN_DIVAS_DIVACAPI=m
+CONFIG_ISDN_DIVAS_USERIDI=m
+CONFIG_ISDN_DIVAS_MAINT=m
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+CONFIG_INPUT_FF_MEMLESS=y
+
+#
+# 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 is not set
+# 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 is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_PARKBD is not set
+# CONFIG_SERIO_PCIPS2 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=y
+# CONFIG_SERIAL_8250_CONSOLE is not set
+CONFIG_SERIAL_8250_PCI=y
+CONFIG_SERIAL_8250_PNP=y
+# CONFIG_SERIAL_8250_CS is not set
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+CONFIG_PRINTER=y
+# CONFIG_LP_CONSOLE is not set
+# CONFIG_PPDEV is not set
+# CONFIG_TIPAR is not set
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+CONFIG_HW_RANDOM=m
+CONFIG_HW_RANDOM_INTEL=m
+CONFIG_HW_RANDOM_AMD=m
+CONFIG_HW_RANDOM_GEODE=m
+CONFIG_HW_RANDOM_VIA=m
+# CONFIG_NVRAM is not set
+CONFIG_RTC=m
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_SONYPI is not set
+CONFIG_AGP=y
+CONFIG_AGP_ALI=m
+CONFIG_AGP_ATI=m
+CONFIG_AGP_AMD=m
+CONFIG_AGP_AMD64=y
+CONFIG_AGP_INTEL=y
+CONFIG_AGP_NVIDIA=m
+CONFIG_AGP_SIS=m
+CONFIG_AGP_SWORKS=m
+CONFIG_AGP_VIA=m
+CONFIG_AGP_EFFICEON=m
+CONFIG_DRM=y
+# CONFIG_DRM_TDFX is not set
+CONFIG_DRM_R128=m
+CONFIG_DRM_RADEON=m
+CONFIG_DRM_I810=m
+CONFIG_DRM_I830=m
+CONFIG_DRM_I915=m
+CONFIG_DRM_MGA=m
+CONFIG_DRM_SIS=m
+CONFIG_DRM_VIA=m
+CONFIG_DRM_SAVAGE=m
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+# CONFIG_CARDMAN_4000 is not set
+# CONFIG_CARDMAN_4040 is not set
+CONFIG_MWAVE=m
+# CONFIG_SCx200_GPIO is not set
+CONFIG_PC8736x_GPIO=m
+CONFIG_NSC_GPIO=m
+CONFIG_CS5535_GPIO=m
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_HPET is not set
+CONFIG_HANGCHECK_TIMER=m
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+CONFIG_TELCLOCK=m
+
+#
+# I2C support
+#
+CONFIG_I2C=m
+CONFIG_I2C_CHARDEV=m
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=m
+CONFIG_I2C_ALGOPCF=m
+CONFIG_I2C_ALGOPCA=m
+
+#
+# I2C Hardware Bus support
+#
+CONFIG_I2C_ALI1535=m
+CONFIG_I2C_ALI1563=m
+CONFIG_I2C_ALI15X3=m
+CONFIG_I2C_AMD756=m
+CONFIG_I2C_AMD756_S4882=m
+CONFIG_I2C_AMD8111=m
+CONFIG_I2C_I801=m
+CONFIG_I2C_I810=m
+CONFIG_I2C_PIIX4=m
+CONFIG_I2C_ISA=m
+CONFIG_I2C_NFORCE2=m
+CONFIG_I2C_OCORES=m
+CONFIG_I2C_PARPORT=m
+CONFIG_I2C_PARPORT_LIGHT=m
+CONFIG_I2C_PROSAVAGE=m
+CONFIG_I2C_SAVAGE4=m
+CONFIG_SCx200_ACB=m
+CONFIG_I2C_SIS5595=m
+CONFIG_I2C_SIS630=m
+CONFIG_I2C_SIS96X=m
+CONFIG_I2C_STUB=m
+CONFIG_I2C_VIA=m
+CONFIG_I2C_VIAPRO=m
+CONFIG_I2C_VOODOO3=m
+CONFIG_I2C_PCA_ISA=m
+
+#
+# Miscellaneous I2C Chip support
+#
+CONFIG_SENSORS_DS1337=m
+CONFIG_SENSORS_DS1374=m
+CONFIG_SENSORS_EEPROM=m
+CONFIG_SENSORS_PCF8574=m
+CONFIG_SENSORS_PCA9539=m
+CONFIG_SENSORS_PCF8591=m
+CONFIG_SENSORS_MAX6875=m
+# 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_BITBANG=m
+CONFIG_SPI_BUTTERFLY=m
+
+#
+# SPI Protocol Masters
+#
+
+#
+# Dallas's 1-wire bus
+#
+CONFIG_W1=m
+
+#
+# 1-wire Bus Masters
+#
+CONFIG_W1_MASTER_MATROX=m
+CONFIG_W1_MASTER_DS2490=m
+CONFIG_W1_MASTER_DS2482=m
+
+#
+# 1-wire Slaves
+#
+CONFIG_W1_SLAVE_THERM=m
+CONFIG_W1_SLAVE_SMEM=m
+CONFIG_W1_SLAVE_DS2433=m
+# CONFIG_W1_SLAVE_DS2433_CRC is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+CONFIG_HWMON_VID=m
+CONFIG_SENSORS_ABITUGURU=m
+CONFIG_SENSORS_ADM1021=m
+CONFIG_SENSORS_ADM1025=m
+CONFIG_SENSORS_ADM1026=m
+CONFIG_SENSORS_ADM1031=m
+CONFIG_SENSORS_ADM9240=m
+CONFIG_SENSORS_K8TEMP=m
+CONFIG_SENSORS_ASB100=m
+CONFIG_SENSORS_ATXP1=m
+CONFIG_SENSORS_DS1621=m
+CONFIG_SENSORS_F71805F=m
+CONFIG_SENSORS_FSCHER=m
+CONFIG_SENSORS_FSCPOS=m
+CONFIG_SENSORS_GL518SM=m
+CONFIG_SENSORS_GL520SM=m
+CONFIG_SENSORS_IT87=m
+CONFIG_SENSORS_LM63=m
+CONFIG_SENSORS_LM70=m
+CONFIG_SENSORS_LM75=m
+CONFIG_SENSORS_LM77=m
+CONFIG_SENSORS_LM78=m
+CONFIG_SENSORS_LM80=m
+CONFIG_SENSORS_LM83=m
+CONFIG_SENSORS_LM85=m
+CONFIG_SENSORS_LM87=m
+CONFIG_SENSORS_LM90=m
+CONFIG_SENSORS_LM92=m
+CONFIG_SENSORS_MAX1619=m
+CONFIG_SENSORS_PC87360=m
+CONFIG_SENSORS_PC87427=m
+CONFIG_SENSORS_SIS5595=m
+CONFIG_SENSORS_SMSC47M1=m
+CONFIG_SENSORS_SMSC47M192=m
+CONFIG_SENSORS_SMSC47B397=m
+CONFIG_SENSORS_VIA686A=m
+CONFIG_SENSORS_VT1211=m
+CONFIG_SENSORS_VT8231=m
+CONFIG_SENSORS_W83781D=m
+CONFIG_SENSORS_W83791D=m
+CONFIG_SENSORS_W83792D=m
+CONFIG_SENSORS_W83793=m
+CONFIG_SENSORS_W83L785TS=m
+CONFIG_SENSORS_W83627HF=m
+CONFIG_SENSORS_W83627EHF=m
+CONFIG_SENSORS_HDAPS=m
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Multimedia devices
+#
+CONFIG_VIDEO_DEV=m
+CONFIG_VIDEO_V4L1=y
+CONFIG_VIDEO_V4L1_COMPAT=y
+CONFIG_VIDEO_V4L2=y
+
+#
+# Video Capture Adapters
+#
+
+#
+# Video Capture Adapters
+#
+# CONFIG_VIDEO_ADV_DEBUG is not set
+CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
+CONFIG_VIDEO_TVAUDIO=m
+CONFIG_VIDEO_TDA7432=m
+CONFIG_VIDEO_TDA9840=m
+CONFIG_VIDEO_TDA9875=m
+CONFIG_VIDEO_TEA6415C=m
+CONFIG_VIDEO_TEA6420=m
+CONFIG_VIDEO_MSP3400=m
+CONFIG_VIDEO_BT819=m
+CONFIG_VIDEO_BT856=m
+CONFIG_VIDEO_KS0127=m
+CONFIG_VIDEO_OV7670=m
+CONFIG_VIDEO_SAA7110=m
+CONFIG_VIDEO_SAA7111=m
+CONFIG_VIDEO_SAA7114=m
+CONFIG_VIDEO_SAA711X=m
+CONFIG_VIDEO_TVP5150=m
+CONFIG_VIDEO_VPX3220=m
+CONFIG_VIDEO_CX2341X=m
+CONFIG_VIDEO_SAA7185=m
+CONFIG_VIDEO_ADV7170=m
+CONFIG_VIDEO_ADV7175=m
+CONFIG_VIDEO_VIVI=m
+CONFIG_VIDEO_BT848=m
+# CONFIG_VIDEO_BT848_DVB is not set
+CONFIG_VIDEO_SAA6588=m
+CONFIG_VIDEO_BWQCAM=m
+CONFIG_VIDEO_CQCAM=m
+CONFIG_VIDEO_CPIA=m
+CONFIG_VIDEO_CPIA_USB=m
+CONFIG_VIDEO_CPIA2=m
+CONFIG_VIDEO_SAA5246A=m
+CONFIG_VIDEO_SAA5249=m
+CONFIG_TUNER_3036=m
+CONFIG_VIDEO_STRADIS=m
+CONFIG_VIDEO_ZORAN_ZR36060=m
+CONFIG_VIDEO_ZORAN=m
+CONFIG_VIDEO_ZORAN_BUZ=m
+CONFIG_VIDEO_ZORAN_DC10=m
+CONFIG_VIDEO_ZORAN_DC30=m
+CONFIG_VIDEO_ZORAN_LML33=m
+CONFIG_VIDEO_ZORAN_LML33R10=m
+CONFIG_VIDEO_ZORAN_AVS6EYES=m
+CONFIG_VIDEO_SAA7134=m
+CONFIG_VIDEO_SAA7134_ALSA=m
+# CONFIG_VIDEO_SAA7134_OSS is not set
+# CONFIG_VIDEO_SAA7134_DVB is not set
+CONFIG_VIDEO_MXB=m
+CONFIG_VIDEO_DPC=m
+CONFIG_VIDEO_HEXIUM_ORION=m
+CONFIG_VIDEO_HEXIUM_GEMINI=m
+CONFIG_VIDEO_CX88=m
+CONFIG_VIDEO_CX88_ALSA=m
+CONFIG_VIDEO_CX88_BLACKBIRD=m
+# CONFIG_VIDEO_CX88_DVB is not set
+CONFIG_VIDEO_CAFE_CCIC=m
+
+#
+# V4L USB devices
+#
+CONFIG_VIDEO_PVRUSB2=m
+# CONFIG_VIDEO_PVRUSB2_29XXX is not set
+# CONFIG_VIDEO_PVRUSB2_24XXX is not set
+CONFIG_VIDEO_PVRUSB2_SYSFS=y
+# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set
+CONFIG_VIDEO_EM28XX=m
+CONFIG_VIDEO_USBVISION=m
+CONFIG_VIDEO_USBVIDEO=m
+CONFIG_USB_VICAM=m
+CONFIG_USB_IBMCAM=m
+CONFIG_USB_KONICAWC=m
+CONFIG_USB_QUICKCAM_MESSENGER=m
+CONFIG_USB_ET61X251=m
+CONFIG_VIDEO_OVCAMCHIP=m
+CONFIG_USB_W9968CF=m
+CONFIG_USB_OV511=m
+CONFIG_USB_SE401=m
+CONFIG_USB_SN9C102=m
+CONFIG_USB_STV680=m
+CONFIG_USB_ZC0301=m
+CONFIG_USB_PWC=m
+# CONFIG_USB_PWC_DEBUG is not set
+
+#
+# Radio Adapters
+#
+CONFIG_RADIO_GEMTEK_PCI=m
+CONFIG_RADIO_MAXIRADIO=m
+CONFIG_RADIO_MAESTRO=m
+CONFIG_USB_DSBR=m
+
+#
+# Digital Video Broadcasting Devices
+#
+CONFIG_DVB=y
+CONFIG_DVB_CORE=m
+# CONFIG_DVB_CORE_ATTACH is not set
+
+#
+# Supported SAA7146 based PCI Adapters
+#
+CONFIG_DVB_AV7110=m
+CONFIG_DVB_AV7110_OSD=y
+CONFIG_DVB_BUDGET=m
+CONFIG_DVB_BUDGET_CI=m
+CONFIG_DVB_BUDGET_AV=m
+CONFIG_DVB_BUDGET_PATCH=m
+
+#
+# Supported USB Adapters
+#
+CONFIG_DVB_USB=m
+# CONFIG_DVB_USB_DEBUG is not set
+CONFIG_DVB_USB_A800=m
+CONFIG_DVB_USB_DIBUSB_MB=m
+# CONFIG_DVB_USB_DIBUSB_MB_FAULTY is not set
+CONFIG_DVB_USB_DIBUSB_MC=m
+CONFIG_DVB_USB_DIB0700=m
+CONFIG_DVB_USB_UMT_010=m
+CONFIG_DVB_USB_CXUSB=m
+CONFIG_DVB_USB_DIGITV=m
+CONFIG_DVB_USB_VP7045=m
+CONFIG_DVB_USB_VP702X=m
+CONFIG_DVB_USB_GP8PSK=m
+CONFIG_DVB_USB_NOVA_T_USB2=m
+CONFIG_DVB_USB_TTUSB2=m
+CONFIG_DVB_USB_DTT200U=m
+CONFIG_DVB_TTUSB_BUDGET=m
+CONFIG_DVB_TTUSB_DEC=m
+CONFIG_DVB_CINERGYT2=m
+# CONFIG_DVB_CINERGYT2_TUNING is not set
+
+#
+# Supported FlexCopII (B2C2) Adapters
+#
+CONFIG_DVB_B2C2_FLEXCOP=m
+CONFIG_DVB_B2C2_FLEXCOP_PCI=m
+CONFIG_DVB_B2C2_FLEXCOP_USB=m
+# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set
+
+#
+# Supported BT878 Adapters
+#
+CONFIG_DVB_BT8XX=m
+
+#
+# Supported Pluto2 Adapters
+#
+CONFIG_DVB_PLUTO2=m
+
+#
+# Supported DVB Frontends
+#
+
+#
+# Customise DVB Frontends
+#
+CONFIG_DVB_FE_CUSTOMISE=y
+
+#
+# DVB-S (satellite) frontends
+#
+CONFIG_DVB_STV0299=m
+CONFIG_DVB_CX24110=m
+CONFIG_DVB_CX24123=m
+CONFIG_DVB_TDA8083=m
+CONFIG_DVB_MT312=m
+CONFIG_DVB_VES1X93=m
+CONFIG_DVB_S5H1420=m
+CONFIG_DVB_TDA10086=m
+
+#
+# DVB-T (terrestrial) frontends
+#
+CONFIG_DVB_SP8870=m
+CONFIG_DVB_SP887X=m
+CONFIG_DVB_CX22700=m
+CONFIG_DVB_CX22702=m
+CONFIG_DVB_L64781=m
+CONFIG_DVB_TDA1004X=m
+CONFIG_DVB_NXT6000=m
+CONFIG_DVB_MT352=m
+CONFIG_DVB_ZL10353=m
+CONFIG_DVB_DIB3000MB=m
+CONFIG_DVB_DIB3000MC=m
+CONFIG_DVB_DIB7000M=m
+CONFIG_DVB_DIB7000P=m
+
+#
+# DVB-C (cable) frontends
+#
+CONFIG_DVB_VES1820=m
+CONFIG_DVB_TDA10021=m
+CONFIG_DVB_STV0297=m
+
+#
+# ATSC (North American/Korean Terrestrial/Cable DTV) frontends
+#
+CONFIG_DVB_NXT200X=m
+CONFIG_DVB_OR51211=m
+CONFIG_DVB_OR51132=m
+CONFIG_DVB_BCM3510=m
+CONFIG_DVB_LGDT330X=m
+
+#
+# Tuners/PLL support
+#
+CONFIG_DVB_PLL=m
+CONFIG_DVB_TDA826X=m
+CONFIG_DVB_TUNER_MT2060=m
+CONFIG_DVB_TUNER_LGH06XF=m
+
+#
+# Miscellaneous devices
+#
+CONFIG_DVB_LNBP21=m
+CONFIG_DVB_ISL6421=m
+CONFIG_DVB_TUA6100=m
+CONFIG_VIDEO_SAA7146=m
+CONFIG_VIDEO_SAA7146_VV=m
+CONFIG_VIDEO_VIDEOBUF=m
+CONFIG_VIDEO_TUNER=m
+CONFIG_VIDEO_BUF=m
+CONFIG_VIDEO_BTCX=m
+CONFIG_VIDEO_IR=m
+CONFIG_VIDEO_TVEEPROM=m
+CONFIG_USB_DABUSB=m
+
+#
+# Graphics support
+#
+CONFIG_FIRMWARE_EDID=y
+CONFIG_FB=y
+CONFIG_FB_DDC=m
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_TILEBLITTING=y
+# CONFIG_FB_CIRRUS is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_ARC is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+CONFIG_FB_VGA16=y
+CONFIG_FB_VESA=y
+CONFIG_FB_HGA=m
+# CONFIG_FB_HGA_ACCEL is not set
+CONFIG_FB_S1D13XXX=m
+CONFIG_FB_NVIDIA=m
+# CONFIG_FB_NVIDIA_I2C is not set
+CONFIG_FB_RIVA=m
+# CONFIG_FB_RIVA_I2C is not set
+# CONFIG_FB_RIVA_DEBUG is not set
+CONFIG_FB_I810=m
+# CONFIG_FB_I810_GTF is not set
+CONFIG_FB_INTEL=m
+# CONFIG_FB_INTEL_DEBUG is not set
+CONFIG_FB_INTEL_I2C=y
+CONFIG_FB_MATROX=m
+# CONFIG_FB_MATROX_MILLENIUM is not set
+# CONFIG_FB_MATROX_MYSTIQUE is not set
+# CONFIG_FB_MATROX_G is not set
+CONFIG_FB_MATROX_I2C=m
+# CONFIG_FB_MATROX_MULTIHEAD is not set
+CONFIG_FB_RADEON=m
+CONFIG_FB_RADEON_I2C=y
+# CONFIG_FB_RADEON_DEBUG is not set
+CONFIG_FB_ATY128=m
+CONFIG_FB_ATY=m
+# CONFIG_FB_ATY_CT is not set
+# CONFIG_FB_ATY_GX is not set
+CONFIG_FB_SAVAGE=m
+# CONFIG_FB_SAVAGE_I2C is not set
+# CONFIG_FB_SAVAGE_ACCEL is not set
+CONFIG_FB_SIS=m
+# CONFIG_FB_SIS_300 is not set
+# CONFIG_FB_SIS_315 is not set
+CONFIG_FB_NEOMAGIC=m
+CONFIG_FB_KYRO=m
+CONFIG_FB_3DFX=m
+# CONFIG_FB_3DFX_ACCEL is not set
+CONFIG_FB_VOODOO1=m
+CONFIG_FB_CYBLA=m
+CONFIG_FB_TRIDENT=m
+# CONFIG_FB_TRIDENT_ACCEL is not set
+CONFIG_FB_GEODE=y
+CONFIG_FB_GEODE_GX=m
+# CONFIG_FB_GEODE_GX_SET_FBSIZE is not set
+CONFIG_FB_GEODE_GX1=m
+CONFIG_FB_VIRTUAL=m
+
+#
+# Console display driver support
+#
+CONFIG_VGA_CONSOLE=y
+# CONFIG_VGACON_SOFT_SCROLLBACK is not set
+CONFIG_VIDEO_SELECT=y
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+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=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=m
+CONFIG_BACKLIGHT_DEVICE=y
+CONFIG_LCD_CLASS_DEVICE=m
+CONFIG_LCD_DEVICE=y
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+CONFIG_SND_HWDEP=m
+CONFIG_SND_RAWMIDI=m
+CONFIG_SND_SEQUENCER=y
+# CONFIG_SND_SEQ_DUMMY 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_SEQUENCER_OSS=y
+CONFIG_SND_RTCTIMER=m
+CONFIG_SND_SEQ_RTCTIMER_DEFAULT=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_MPU401_UART=m
+CONFIG_SND_OPL3_LIB=m
+CONFIG_SND_VX_LIB=m
+CONFIG_SND_AC97_CODEC=y
+CONFIG_SND_DUMMY=m
+CONFIG_SND_VIRMIDI=m
+CONFIG_SND_MTPAV=m
+CONFIG_SND_MTS64=m
+CONFIG_SND_SERIAL_U16550=m
+CONFIG_SND_MPU401=m
+
+#
+# PCI devices
+#
+CONFIG_SND_AD1889=m
+CONFIG_SND_ALS300=m
+CONFIG_SND_ALS4000=m
+CONFIG_SND_ALI5451=m
+CONFIG_SND_ATIIXP=m
+CONFIG_SND_ATIIXP_MODEM=m
+CONFIG_SND_AU8810=m
+CONFIG_SND_AU8820=m
+CONFIG_SND_AU8830=m
+CONFIG_SND_AZT3328=m
+CONFIG_SND_BT87X=m
+# CONFIG_SND_BT87X_OVERCLOCK is not set
+CONFIG_SND_CA0106=m
+CONFIG_SND_CMIPCI=m
+CONFIG_SND_CS4281=m
+CONFIG_SND_CS46XX=m
+CONFIG_SND_CS46XX_NEW_DSP=y
+CONFIG_SND_CS5535AUDIO=m
+CONFIG_SND_DARLA20=m
+CONFIG_SND_GINA20=m
+CONFIG_SND_LAYLA20=m
+CONFIG_SND_DARLA24=m
+CONFIG_SND_GINA24=m
+CONFIG_SND_LAYLA24=m
+CONFIG_SND_MONA=m
+CONFIG_SND_MIA=m
+CONFIG_SND_ECHO3G=m
+CONFIG_SND_INDIGO=m
+CONFIG_SND_INDIGOIO=m
+CONFIG_SND_INDIGODJ=m
+CONFIG_SND_EMU10K1=m
+CONFIG_SND_EMU10K1X=m
+CONFIG_SND_ENS1370=m
+CONFIG_SND_ENS1371=m
+CONFIG_SND_ES1938=m
+CONFIG_SND_ES1968=m
+CONFIG_SND_FM801=m
+# CONFIG_SND_FM801_TEA575X_BOOL is not set
+CONFIG_SND_HDA_INTEL=m
+CONFIG_SND_HDSP=m
+CONFIG_SND_HDSPM=m
+CONFIG_SND_ICE1712=m
+CONFIG_SND_ICE1724=m
+CONFIG_SND_INTEL8X0=y
+CONFIG_SND_INTEL8X0M=m
+CONFIG_SND_KORG1212=m
+CONFIG_SND_MAESTRO3=m
+CONFIG_SND_MIXART=m
+CONFIG_SND_NM256=m
+CONFIG_SND_PCXHR=m
+CONFIG_SND_RIPTIDE=m
+CONFIG_SND_RME32=m
+CONFIG_SND_RME96=m
+CONFIG_SND_RME9652=m
+CONFIG_SND_SONICVIBES=m
+CONFIG_SND_TRIDENT=m
+CONFIG_SND_VIA82XX=m
+CONFIG_SND_VIA82XX_MODEM=m
+CONFIG_SND_VX222=m
+CONFIG_SND_YMFPCI=m
+# CONFIG_SND_AC97_POWER_SAVE is not set
+
+#
+# USB devices
+#
+CONFIG_SND_USB_AUDIO=m
+CONFIG_SND_USB_USX2Y=m
+
+#
+# PCMCIA devices
+#
+# CONFIG_SND_VXPOCKET is not set
+# CONFIG_SND_PDAUDIOCF is not set
+
+#
+# Open Sound System
+#
+CONFIG_SOUND_PRIME=y
+CONFIG_SOUND_BT878=m
+CONFIG_SOUND_ES1371=m
+CONFIG_SOUND_ICH=m
+CONFIG_SOUND_TRIDENT=m
+CONFIG_SOUND_MSNDCLAS=m
+CONFIG_MSNDCLAS_INIT_FILE="/etc/sound/msndinit.bin"
+CONFIG_MSNDCLAS_PERM_FILE="/etc/sound/msndperm.bin"
+CONFIG_SOUND_MSNDPIN=m
+CONFIG_MSNDPIN_INIT_FILE="/etc/sound/pndspini.bin"
+CONFIG_MSNDPIN_PERM_FILE="/etc/sound/pndsperm.bin"
+CONFIG_SOUND_VIA82CXXX=m
+# CONFIG_MIDI_VIA82CXXX is not set
+CONFIG_SOUND_OSS=m
+# CONFIG_SOUND_TRACEINIT is not set
+# CONFIG_SOUND_DMAP is not set
+CONFIG_SOUND_CS4232=m
+CONFIG_SOUND_SSCAPE=m
+CONFIG_SOUND_VMIDI=m
+CONFIG_SOUND_TRIX=m
+CONFIG_SOUND_MSS=m
+CONFIG_SOUND_MPU401=m
+CONFIG_SOUND_PAS=m
+CONFIG_SOUND_PSS=m
+# CONFIG_PSS_MIXER is not set
+CONFIG_SOUND_SB=m
+CONFIG_SOUND_YM3812=m
+CONFIG_SOUND_UART6850=m
+CONFIG_SOUND_AEDSP16=m
+# CONFIG_SC6600 is not set
+# CONFIG_AEDSP16_MSS is not set
+# CONFIG_AEDSP16_SBPRO is not set
+# CONFIG_AEDSP16_MPU401 is not set
+CONFIG_SOUND_TVMIXER=m
+CONFIG_SOUND_KAHLUA=m
+CONFIG_AC97_BUS=y
+
+#
+# HID Devices
+#
+CONFIG_HID=y
+
+#
+# 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_BANDWIDTH is not set
+# 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=y
+# CONFIG_USB_EHCI_SPLIT_ISO is not set
+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+CONFIG_USB_ISP116X_HCD=y
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+CONFIG_USB_UHCI_HCD=y
+# CONFIG_USB_U132_HCD is not set
+CONFIG_USB_SL811_HCD=y
+# CONFIG_USB_SL811_CS 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=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_DPCM=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_STORAGE_ALAUDA=y
+CONFIG_USB_STORAGE_KARMA=y
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+CONFIG_USB_HIDINPUT_POWERBOOK=y
+CONFIG_HID_FF=y
+CONFIG_HID_PID=y
+CONFIG_LOGITECH_FF=y
+CONFIG_THRUSTMASTER_FF=y
+CONFIG_ZEROPLUS_FF=y
+CONFIG_USB_HIDDEV=y
+CONFIG_USB_AIPTEK=m
+CONFIG_USB_WACOM=m
+CONFIG_USB_ACECAD=m
+CONFIG_USB_KBTAB=m
+CONFIG_USB_POWERMATE=m
+CONFIG_USB_TOUCHSCREEN=m
+CONFIG_USB_TOUCHSCREEN_EGALAX=y
+CONFIG_USB_TOUCHSCREEN_PANJIT=y
+CONFIG_USB_TOUCHSCREEN_3M=y
+CONFIG_USB_TOUCHSCREEN_ITM=y
+CONFIG_USB_TOUCHSCREEN_ETURBO=y
+CONFIG_USB_TOUCHSCREEN_GUNZE=y
+CONFIG_USB_TOUCHSCREEN_DMC_TSC10=y
+CONFIG_USB_YEALINK=m
+CONFIG_USB_XPAD=m
+CONFIG_USB_ATI_REMOTE=m
+CONFIG_USB_ATI_REMOTE2=m
+CONFIG_USB_KEYSPAN_REMOTE=m
+CONFIG_USB_APPLETOUCH=m
+
+#
+# USB Imaging devices
+#
+CONFIG_USB_MDC800=m
+CONFIG_USB_MICROTEK=m
+
+#
+# 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_GL620A=m
+CONFIG_USB_NET_NET1080=m
+CONFIG_USB_NET_PLUSB=m
+CONFIG_USB_NET_MCS7830=m
+CONFIG_USB_NET_RNDIS_HOST=m
+CONFIG_USB_NET_CDC_SUBSET=m
+CONFIG_USB_ALI_M5632=y
+CONFIG_USB_AN2720=y
+CONFIG_USB_BELKIN=y
+CONFIG_USB_ARMLINUX=y
+CONFIG_USB_EPSON2888=y
+CONFIG_USB_NET_ZAURUS=m
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+CONFIG_USB_USS720=m
+
+#
+# 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=m
+CONFIG_USB_SERIAL_OMNINET=m
+CONFIG_USB_SERIAL_DEBUG=m
+CONFIG_USB_EZUSB=y
+
+#
+# USB Miscellaneous drivers
+#
+CONFIG_USB_EMI62=m
+CONFIG_USB_EMI26=m
+CONFIG_USB_ADUTUX=m
+CONFIG_USB_AUERSWALD=m
+CONFIG_USB_RIO500=m
+CONFIG_USB_LEGOTOWER=m
+CONFIG_USB_LCD=m
+CONFIG_USB_LED=m
+CONFIG_USB_CYPRESS_CY7C63=m
+CONFIG_USB_CYTHERM=m
+CONFIG_USB_PHIDGET=m
+CONFIG_USB_PHIDGETKIT=m
+CONFIG_USB_PHIDGETMOTORCONTROL=m
+CONFIG_USB_PHIDGETSERVO=m
+CONFIG_USB_IDMOUSE=m
+CONFIG_USB_FTDI_ELAN=m
+CONFIG_USB_APPLEDISPLAY=m
+CONFIG_USB_SISUSBVGA=m
+# CONFIG_USB_SISUSBVGA_CON is not set
+CONFIG_USB_LD=m
+CONFIG_USB_TRANCEVIBRATOR=m
+CONFIG_USB_TEST=m
+
+#
+# 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_NET2280=y
+CONFIG_USB_NET2280=m
+# 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 is not set
+CONFIG_USB_G_SERIAL=m
+CONFIG_USB_MIDI_GADGET=m
+
+#
+# MMC/SD Card support
+#
+CONFIG_MMC=m
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_BLOCK=m
+CONFIG_MMC_SDHCI=m
+CONFIG_MMC_WBSD=m
+CONFIG_MMC_TIFM_SD=m
+
+#
+# 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_IDE_DISK=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=m
+
+#
+# InfiniBand support
+#
+CONFIG_INFINIBAND=m
+CONFIG_INFINIBAND_USER_MAD=m
+CONFIG_INFINIBAND_USER_ACCESS=m
+CONFIG_INFINIBAND_ADDR_TRANS=y
+CONFIG_INFINIBAND_MTHCA=m
+CONFIG_INFINIBAND_MTHCA_DEBUG=y
+CONFIG_INFINIBAND_AMSO1100=m
+# CONFIG_INFINIBAND_AMSO1100_DEBUG is not set
+CONFIG_INFINIBAND_IPOIB=m
+CONFIG_INFINIBAND_IPOIB_DEBUG=y
+# CONFIG_INFINIBAND_IPOIB_DEBUG_DATA is not set
+CONFIG_INFINIBAND_SRP=m
+CONFIG_INFINIBAND_ISER=m
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+CONFIG_EDAC=m
+
+#
+# Reporting subsystems
+#
+# CONFIG_EDAC_DEBUG is not set
+CONFIG_EDAC_MM_EDAC=m
+CONFIG_EDAC_AMD76X=m
+CONFIG_EDAC_E7XXX=m
+CONFIG_EDAC_E752X=m
+CONFIG_EDAC_I82875P=m
+CONFIG_EDAC_I82860=m
+CONFIG_EDAC_R82600=m
+CONFIG_EDAC_POLL=y
+
+#
+# Real Time Clock
+#
+CONFIG_RTC_LIB=m
+CONFIG_RTC_CLASS=m
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=m
+CONFIG_RTC_INTF_PROC=m
+CONFIG_RTC_INTF_DEV=m
+CONFIG_RTC_INTF_DEV_UIE_EMUL=y
+
+#
+# RTC drivers
+#
+CONFIG_RTC_DRV_X1205=m
+CONFIG_RTC_DRV_DS1307=m
+CONFIG_RTC_DRV_DS1553=m
+CONFIG_RTC_DRV_ISL1208=m
+CONFIG_RTC_DRV_DS1672=m
+CONFIG_RTC_DRV_DS1742=m
+CONFIG_RTC_DRV_PCF8563=m
+CONFIG_RTC_DRV_PCF8583=m
+CONFIG_RTC_DRV_RS5C348=m
+CONFIG_RTC_DRV_RS5C372=m
+CONFIG_RTC_DRV_M48T86=m
+CONFIG_RTC_DRV_TEST=m
+CONFIG_RTC_DRV_MAX6902=m
+CONFIG_RTC_DRV_V3020=m
+
+#
+# DMA Engine support
+#
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+CONFIG_NET_DMA=y
+
+#
+# DMA Devices
+#
+CONFIG_INTEL_IOATDMA=m
+
+#
+# Virtualization
+#
+# CONFIG_KVM 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=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=y
+CONFIG_FUSE_FS=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+# CONFIG_ZISOFS is not set
+CONFIG_UDF_FS=y
+CONFIG_UDF_NLS=y
+
+#
+# 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_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLBFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+CONFIG_CONFIGFS_FS=m
+
+#
+# Miscellaneous filesystems
+#
+CONFIG_ADFS_FS=m
+# CONFIG_ADFS_FS_RW is not set
+CONFIG_AFFS_FS=m
+CONFIG_HFS_FS=m
+CONFIG_HFSPLUS_FS=m
+CONFIG_BEFS_FS=m
+# CONFIG_BEFS_DEBUG is not set
+CONFIG_BFS_FS=m
+CONFIG_EFS_FS=m
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_SUMMARY is not set
+# 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=m
+CONFIG_VXFS_FS=m
+CONFIG_HPFS_FS=m
+CONFIG_QNX4FS_FS=m
+CONFIG_SYSV_FS=m
+CONFIG_UFS_FS=m
+# CONFIG_UFS_FS_WRITE is not set
+# CONFIG_UFS_DEBUG is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_DIRECTIO=y
+CONFIG_NFSD=y
+CONFIG_NFSD_V2_ACL=y
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_NFSD_TCP=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=y
+CONFIG_NFS_ACL_SUPPORT=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+CONFIG_RPCSEC_GSS_SPKM3=m
+CONFIG_SMB_FS=m
+# CONFIG_SMB_NLS_DEFAULT is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
+# CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
+CONFIG_NCP_FS=m
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+CONFIG_CODA_FS=m
+# CONFIG_CODA_FS_OLD_API is not set
+CONFIG_AFS_FS=m
+CONFIG_RXRPC=m
+CONFIG_9P_FS=m
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+
+#
+# Distributed Lock Manager
+#
+CONFIG_DLM=m
+CONFIG_DLM_TCP=y
+# CONFIG_DLM_SCTP is not set
+# CONFIG_DLM_DEBUG is not set
+
+#
+# Instrumentation Support
+#
+# CONFIG_PROFILING is not set
+# CONFIG_KPROBES is not set
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_UNUSED_SYMBOLS=y
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=15
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_X86_FIND_SMP_CONFIG=y
+CONFIG_X86_MPPARSE=y
+CONFIG_DOUBLEFAULT=y
+
+#
+# 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_HASH=m
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_HMAC=m
+CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_GF128MUL=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
+CONFIG_CRYPTO_TWOFISH_586=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_AES_586=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_TEST=m
+
+#
+# Hardware crypto devices
+#
+CONFIG_CRYPTO_DEV_PADLOCK=m
+CONFIG_CRYPTO_DEV_PADLOCK_AES=m
+CONFIG_CRYPTO_DEV_PADLOCK_SHA=m
+CONFIG_CRYPTO_DEV_GEODE=m
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_AUDIT_GENERIC=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_REED_SOLOMON=y
+CONFIG_REED_SOLOMON_DEC16=y
+CONFIG_PLIST=y
+CONFIG_IOMAP_COPY=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_PENDING_IRQ=y
+CONFIG_X86_SMP=y
+CONFIG_X86_HT=y
+CONFIG_X86_BIOS_REBOOT=y
+CONFIG_X86_TRAMPOLINE=y
+CONFIG_KTIME_SCALAR=y
diff --git a/recipes/linux/linux/i686-generic/defconfig b/recipes/linux/linux/i686-generic/defconfig
new file mode 100644
index 0000000000..b06f535e7b
--- /dev/null
+++ b/recipes/linux/linux/i686-generic/defconfig
@@ -0,0 +1,2705 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.20
+# Sat May 26 01:56:02 2007
+#
+CONFIG_X86_32=y
+CONFIG_GENERIC_TIME=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_SEMAPHORE_SLEEPERS=y
+CONFIG_X86=y
+CONFIG_MMU=y
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_GENERIC_IOMAP=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_DMI=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_POSIX_MQUEUE=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
+CONFIG_AUDIT=y
+CONFIG_AUDITSYSCALL=y
+# CONFIG_IKCONFIG is not set
+# CONFIG_CPUSETS is not set
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+# CONFIG_EMBEDDED is not set
+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_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=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+CONFIG_STOP_MACHINE=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"
+
+#
+# Processor type and features
+#
+CONFIG_SMP=y
+CONFIG_X86_PC=y
+# CONFIG_X86_ELAN is not set
+# CONFIG_X86_VOYAGER is not set
+# CONFIG_X86_NUMAQ is not set
+# CONFIG_X86_SUMMIT is not set
+# CONFIG_X86_BIGSMP is not set
+# CONFIG_X86_VISWS is not set
+# CONFIG_X86_GENERICARCH is not set
+# CONFIG_X86_ES7000 is not set
+# CONFIG_PARAVIRT is not set
+# CONFIG_M386 is not set
+# CONFIG_M486 is not set
+CONFIG_M586=y
+# CONFIG_M586TSC is not set
+# CONFIG_M586MMX is not set
+# CONFIG_M686 is not set
+# CONFIG_MPENTIUMII is not set
+# CONFIG_MPENTIUMIII is not set
+# CONFIG_MPENTIUMM is not set
+# CONFIG_MCORE2 is not set
+# CONFIG_MPENTIUM4 is not set
+# CONFIG_MK6 is not set
+# CONFIG_MK7 is not set
+# CONFIG_MK8 is not set
+# CONFIG_MCRUSOE is not set
+# CONFIG_MEFFICEON is not set
+# CONFIG_MWINCHIPC6 is not set
+# CONFIG_MWINCHIP2 is not set
+# CONFIG_MWINCHIP3D is not set
+# CONFIG_MGEODEGX1 is not set
+# CONFIG_MGEODE_LX is not set
+# CONFIG_MCYRIXIII is not set
+# CONFIG_MVIAC3_2 is not set
+# CONFIG_X86_GENERIC is not set
+CONFIG_X86_CMPXCHG=y
+CONFIG_X86_XADD=y
+CONFIG_X86_L1_CACHE_SHIFT=5
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_X86_PPRO_FENCE=y
+CONFIG_X86_F00F_BUG=y
+CONFIG_X86_WP_WORKS_OK=y
+CONFIG_X86_INVLPG=y
+CONFIG_X86_BSWAP=y
+CONFIG_X86_POPAD_OK=y
+CONFIG_X86_CMPXCHG64=y
+CONFIG_X86_ALIGNMENT_16=y
+CONFIG_HPET_TIMER=y
+CONFIG_NR_CPUS=8
+CONFIG_SCHED_SMT=y
+CONFIG_SCHED_MC=y
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_PREEMPT_BKL=y
+CONFIG_X86_LOCAL_APIC=y
+CONFIG_X86_IO_APIC=y
+CONFIG_X86_MCE=y
+# CONFIG_X86_MCE_NONFATAL is not set
+# CONFIG_X86_MCE_P4THERMAL is not set
+CONFIG_VM86=y
+# CONFIG_TOSHIBA is not set
+# CONFIG_I8K is not set
+# CONFIG_X86_REBOOTFIXUPS is not set
+# CONFIG_MICROCODE is not set
+# CONFIG_X86_MSR is not set
+# CONFIG_X86_CPUID is not set
+
+#
+# Firmware Drivers
+#
+# CONFIG_EDD is not set
+# CONFIG_DELL_RBU is not set
+# CONFIG_DCDBAS is not set
+# CONFIG_NOHIGHMEM is not set
+CONFIG_HIGHMEM4G=y
+# CONFIG_HIGHMEM64G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_HIGHMEM=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+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=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_RESOURCES_64BIT=y
+# CONFIG_HIGHPTE is not set
+# CONFIG_MATH_EMULATION is not set
+CONFIG_MTRR=y
+# CONFIG_EFI is not set
+CONFIG_IRQBALANCE=y
+CONFIG_SECCOMP=y
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_KEXEC is not set
+# CONFIG_CRASH_DUMP is not set
+CONFIG_PHYSICAL_START=0x100000
+# CONFIG_RELOCATABLE is not set
+CONFIG_PHYSICAL_ALIGN=0x100000
+# CONFIG_HOTPLUG_CPU is not set
+CONFIG_COMPAT_VDSO=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+
+#
+# Power management options (ACPI, APM)
+#
+CONFIG_PM=y
+CONFIG_PM_LEGACY=y
+# CONFIG_PM_DEBUG is not set
+# CONFIG_PM_SYSFS_DEPRECATED is not set
+
+#
+# ACPI (Advanced Configuration and Power Interface) Support
+#
+CONFIG_ACPI=y
+CONFIG_ACPI_AC=y
+CONFIG_ACPI_BATTERY=y
+CONFIG_ACPI_BUTTON=y
+CONFIG_ACPI_VIDEO=m
+# CONFIG_ACPI_HOTKEY is not set
+CONFIG_ACPI_FAN=y
+# CONFIG_ACPI_DOCK is not set
+CONFIG_ACPI_PROCESSOR=y
+CONFIG_ACPI_THERMAL=y
+# CONFIG_ACPI_ASUS is not set
+CONFIG_ACPI_IBM=m
+# CONFIG_ACPI_IBM_DOCK is not set
+# CONFIG_ACPI_TOSHIBA is not set
+CONFIG_ACPI_BLACKLIST_YEAR=0
+# CONFIG_ACPI_DEBUG is not set
+CONFIG_ACPI_EC=y
+CONFIG_ACPI_POWER=y
+CONFIG_ACPI_SYSTEM=y
+CONFIG_X86_PM_TIMER=y
+CONFIG_ACPI_CONTAINER=m
+CONFIG_ACPI_SBS=m
+
+#
+# APM (Advanced Power Management) BIOS Support
+#
+CONFIG_APM=y
+# CONFIG_APM_IGNORE_USER_SUSPEND is not set
+# CONFIG_APM_DO_ENABLE is not set
+# CONFIG_APM_CPU_IDLE is not set
+# CONFIG_APM_DISPLAY_BLANK is not set
+# CONFIG_APM_RTC_IS_GMT is not set
+# CONFIG_APM_ALLOW_INTS is not set
+# CONFIG_APM_REAL_MODE_POWER_OFF is not set
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+#
+CONFIG_PCI=y
+# CONFIG_PCI_GOBIOS is not set
+# CONFIG_PCI_GOMMCONFIG is not set
+# CONFIG_PCI_GODIRECT is not set
+CONFIG_PCI_GOANY=y
+CONFIG_PCI_BIOS=y
+CONFIG_PCI_DIRECT=y
+CONFIG_PCI_MMCONFIG=y
+CONFIG_PCIEPORTBUS=y
+# CONFIG_HOTPLUG_PCI_PCIE is not set
+CONFIG_PCIEAER=y
+# CONFIG_PCI_MSI is not set
+CONFIG_HT_IRQ=y
+CONFIG_ISA_DMA_API=y
+# CONFIG_ISA is not set
+# CONFIG_MCA is not set
+CONFIG_SCx200=m
+CONFIG_SCx200HR_TIMER=m
+CONFIG_K8_NB=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+CONFIG_PCCARD=m
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=m
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
+CONFIG_CARDBUS=y
+
+#
+# PC-card bridges
+#
+CONFIG_YENTA=m
+CONFIG_YENTA_O2=y
+CONFIG_YENTA_RICOH=y
+CONFIG_YENTA_TI=y
+CONFIG_YENTA_ENE_TUNE=y
+CONFIG_YENTA_TOSHIBA=y
+CONFIG_PD6729=m
+CONFIG_I82092=m
+CONFIG_PCCARD_NONSTATIC=m
+
+#
+# PCI Hotplug Support
+#
+CONFIG_HOTPLUG_PCI=m
+CONFIG_HOTPLUG_PCI_FAKE=m
+CONFIG_HOTPLUG_PCI_COMPAQ=m
+# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set
+CONFIG_HOTPLUG_PCI_IBM=m
+CONFIG_HOTPLUG_PCI_ACPI=m
+CONFIG_HOTPLUG_PCI_ACPI_IBM=m
+# CONFIG_HOTPLUG_PCI_CPCI is not set
+CONFIG_HOTPLUG_PCI_SHPC=m
+# CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_MISC=y
+
+#
+# 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=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE 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
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS 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=y
+# CONFIG_NETFILTER_DEBUG is not set
+
+#
+# Core Netfilter Configuration
+#
+# CONFIG_NETFILTER_NETLINK is not set
+# CONFIG_NF_CONNTRACK_ENABLED is not set
+# CONFIG_NETFILTER_XTABLES is not set
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_IP_NF_QUEUE=y
+
+#
+# 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 is not set
+# 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=m
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=m
+# CONFIG_MTD_PARTITIONS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+CONFIG_FTL=m
+CONFIG_NFTL=m
+# CONFIG_NFTL_RW is not set
+CONFIG_INFTL=m
+CONFIG_RFD_FTL=m
+CONFIG_SSFDC=y
+
+#
+# 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=y
+CONFIG_MTD_ROM=y
+CONFIG_MTD_ABSENT=y
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_SC520CDP is not set
+# CONFIG_MTD_TS5500 is not set
+# CONFIG_MTD_AMD76XROM is not set
+# CONFIG_MTD_ICHXROM is not set
+# CONFIG_MTD_ESB2ROM is not set
+# CONFIG_MTD_CK804XROM is not set
+# CONFIG_MTD_SCB2_FLASH is not set
+# CONFIG_MTD_L440GX is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+CONFIG_MTD_PMC551=m
+# CONFIG_MTD_PMC551_BUGFIX is not set
+# CONFIG_MTD_PMC551_DEBUG is not set
+CONFIG_MTD_DATAFLASH=m
+CONFIG_MTD_M25P80=m
+CONFIG_MTD_SLRAM=m
+CONFIG_MTD_PHRAM=m
+# CONFIG_MTD_MTDRAM is not set
+CONFIG_MTD_BLOCK2MTD=y
+
+#
+# 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=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+CONFIG_MTD_NAND_IDS=y
+CONFIG_MTD_NAND_DISKONCHIP=y
+# CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set
+CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0
+# CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE is not set
+CONFIG_MTD_NAND_CAFE=y
+CONFIG_MTD_NAND_CS553X=y
+
+#
+# OneNAND Flash Device Drivers
+#
+CONFIG_MTD_ONENAND=m
+# CONFIG_MTD_ONENAND_VERIFY_WRITE is not set
+# CONFIG_MTD_ONENAND_OTP is not set
+
+#
+# Parallel port support
+#
+CONFIG_PARPORT=y
+CONFIG_PARPORT_PC=y
+# CONFIG_PARPORT_SERIAL is not set
+# CONFIG_PARPORT_PC_FIFO is not set
+# CONFIG_PARPORT_PC_SUPERIO is not set
+# CONFIG_PARPORT_PC_PCMCIA is not set
+# CONFIG_PARPORT_GSC is not set
+CONFIG_PARPORT_AX88796=m
+# CONFIG_PARPORT_1284 is not set
+CONFIG_PARPORT_NOT_PC=y
+
+#
+# Plug and Play support
+#
+CONFIG_PNP=y
+# CONFIG_PNP_DEBUG is not set
+
+#
+# Protocols
+#
+CONFIG_PNPACPI=y
+
+#
+# Block devices
+#
+CONFIG_BLK_DEV_FD=y
+CONFIG_PARIDE=m
+CONFIG_PARIDE_PARPORT=y
+
+#
+# Parallel IDE high-level drivers
+#
+CONFIG_PARIDE_PD=m
+CONFIG_PARIDE_PCD=m
+CONFIG_PARIDE_PF=m
+CONFIG_PARIDE_PT=m
+CONFIG_PARIDE_PG=m
+
+#
+# Parallel IDE protocol modules
+#
+CONFIG_PARIDE_ATEN=m
+CONFIG_PARIDE_BPCK=m
+CONFIG_PARIDE_BPCK6=m
+CONFIG_PARIDE_COMM=m
+CONFIG_PARIDE_DSTR=m
+CONFIG_PARIDE_FIT2=m
+CONFIG_PARIDE_FIT3=m
+CONFIG_PARIDE_EPAT=m
+# CONFIG_PARIDE_EPATC8 is not set
+CONFIG_PARIDE_EPIA=m
+CONFIG_PARIDE_FRIQ=m
+CONFIG_PARIDE_FRPW=m
+CONFIG_PARIDE_KBIC=m
+CONFIG_PARIDE_KTTI=m
+CONFIG_PARIDE_ON20=m
+CONFIG_PARIDE_ON26=m
+CONFIG_BLK_CPQ_DA=m
+CONFIG_BLK_CPQ_CISS_DA=m
+# CONFIG_CISS_SCSI_TAPE is not set
+CONFIG_BLK_DEV_DAC960=m
+CONFIG_BLK_DEV_UMEM=m
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_SX8=m
+CONFIG_BLK_DEV_UB=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+CONFIG_ATA_OVER_ETH=m
+
+#
+# Misc devices
+#
+# CONFIG_IBM_ASM is not set
+# CONFIG_SGI_IOC4 is not set
+CONFIG_TIFM_CORE=m
+CONFIG_TIFM_7XX1=m
+# CONFIG_MSI_LAPTOP is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+# CONFIG_BLK_DEV_HD_IDE is not set
+CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_IDEDISK_MULTI_MODE=y
+# CONFIG_BLK_DEV_IDECS is not set
+CONFIG_BLK_DEV_IDECD=y
+# 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=y
+CONFIG_BLK_DEV_CMD640=y
+# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
+# CONFIG_BLK_DEV_IDEPNP is not set
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_IDEPCI_SHARE_IRQ=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+CONFIG_BLK_DEV_RZ1000=y
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+CONFIG_IDEDMA_PCI_AUTO=y
+# CONFIG_IDEDMA_ONLYDISK is not set
+CONFIG_BLK_DEV_AEC62XX=y
+CONFIG_BLK_DEV_ALI15X3=y
+# CONFIG_WDC_ALI15X3 is not set
+CONFIG_BLK_DEV_AMD74XX=y
+CONFIG_BLK_DEV_ATIIXP=y
+CONFIG_BLK_DEV_CMD64X=y
+CONFIG_BLK_DEV_TRIFLEX=y
+CONFIG_BLK_DEV_CY82C693=y
+CONFIG_BLK_DEV_CS5520=y
+CONFIG_BLK_DEV_CS5530=y
+CONFIG_BLK_DEV_CS5535=y
+CONFIG_BLK_DEV_HPT34X=y
+# CONFIG_HPT34X_AUTODMA is not set
+CONFIG_BLK_DEV_HPT366=y
+CONFIG_BLK_DEV_JMICRON=y
+CONFIG_BLK_DEV_SC1200=y
+CONFIG_BLK_DEV_PIIX=y
+CONFIG_BLK_DEV_IT821X=y
+CONFIG_BLK_DEV_NS87415=y
+CONFIG_BLK_DEV_PDC202XX_OLD=y
+# CONFIG_PDC202XX_BURST is not set
+CONFIG_BLK_DEV_PDC202XX_NEW=y
+CONFIG_BLK_DEV_SVWKS=y
+CONFIG_BLK_DEV_SIIMAGE=y
+CONFIG_BLK_DEV_SIS5513=y
+CONFIG_BLK_DEV_SLC90E66=y
+CONFIG_BLK_DEV_TRM290=y
+CONFIG_BLK_DEV_VIA82CXXX=y
+# CONFIG_IDE_ARM is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+CONFIG_IDEDMA_AUTO=y
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_TGT=m
+CONFIG_SCSI_NETLINK=y
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+CONFIG_CHR_DEV_SG=y
+CONFIG_CHR_DEV_SCH=m
+
+#
+# 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=m
+CONFIG_SCSI_FC_ATTRS=m
+CONFIG_SCSI_ISCSI_ATTRS=m
+CONFIG_SCSI_SAS_ATTRS=m
+CONFIG_SCSI_SAS_LIBSAS=m
+CONFIG_SCSI_SAS_LIBSAS_DEBUG=y
+
+#
+# SCSI low-level drivers
+#
+CONFIG_ISCSI_TCP=m
+CONFIG_BLK_DEV_3W_XXXX_RAID=m
+CONFIG_SCSI_3W_9XXX=m
+CONFIG_SCSI_ACARD=m
+CONFIG_SCSI_AACRAID=m
+CONFIG_SCSI_AIC7XXX=m
+CONFIG_AIC7XXX_CMDS_PER_DEVICE=32
+CONFIG_AIC7XXX_RESET_DELAY_MS=5000
+CONFIG_AIC7XXX_DEBUG_ENABLE=y
+CONFIG_AIC7XXX_DEBUG_MASK=0
+CONFIG_AIC7XXX_REG_PRETTY_PRINT=y
+CONFIG_SCSI_AIC7XXX_OLD=m
+CONFIG_SCSI_AIC79XX=m
+CONFIG_AIC79XX_CMDS_PER_DEVICE=32
+CONFIG_AIC79XX_RESET_DELAY_MS=5000
+# CONFIG_AIC79XX_ENABLE_RD_STRM is not set
+CONFIG_AIC79XX_DEBUG_ENABLE=y
+CONFIG_AIC79XX_DEBUG_MASK=0
+CONFIG_AIC79XX_REG_PRETTY_PRINT=y
+CONFIG_SCSI_AIC94XX=m
+CONFIG_AIC94XX_DEBUG=y
+CONFIG_SCSI_DPT_I2O=m
+CONFIG_SCSI_ADVANSYS=m
+CONFIG_SCSI_ARCMSR=m
+# CONFIG_MEGARAID_NEWGEN is not set
+CONFIG_MEGARAID_LEGACY=m
+CONFIG_MEGARAID_SAS=m
+CONFIG_SCSI_HPTIOP=m
+CONFIG_SCSI_BUSLOGIC=m
+# CONFIG_SCSI_OMIT_FLASHPOINT is not set
+CONFIG_SCSI_DMX3191D=m
+CONFIG_SCSI_EATA=m
+# CONFIG_SCSI_EATA_TAGGED_QUEUE is not set
+# CONFIG_SCSI_EATA_LINKED_COMMANDS is not set
+CONFIG_SCSI_EATA_MAX_TAGS=16
+CONFIG_SCSI_FUTURE_DOMAIN=m
+CONFIG_SCSI_GDTH=m
+CONFIG_SCSI_IPS=m
+CONFIG_SCSI_INITIO=m
+CONFIG_SCSI_INIA100=m
+CONFIG_SCSI_PPA=m
+CONFIG_SCSI_IMM=m
+# CONFIG_SCSI_IZIP_EPP16 is not set
+# CONFIG_SCSI_IZIP_SLOW_CTR is not set
+CONFIG_SCSI_STEX=m
+CONFIG_SCSI_SYM53C8XX_2=m
+CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
+CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
+CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
+CONFIG_SCSI_SYM53C8XX_MMIO=y
+# CONFIG_SCSI_IPR is not set
+CONFIG_SCSI_QLOGIC_1280=m
+CONFIG_SCSI_QLA_FC=m
+CONFIG_SCSI_QLA_ISCSI=m
+CONFIG_SCSI_LPFC=m
+CONFIG_SCSI_DC395x=m
+CONFIG_SCSI_DC390T=m
+CONFIG_SCSI_NSP32=m
+CONFIG_SCSI_DEBUG=m
+CONFIG_SCSI_SRP=m
+
+#
+# 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=y
+# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_SATA_AHCI=y
+CONFIG_SATA_SVW=y
+CONFIG_ATA_PIIX=y
+CONFIG_SATA_MV=y
+CONFIG_SATA_NV=y
+CONFIG_PDC_ADMA=y
+CONFIG_SATA_QSTOR=y
+CONFIG_SATA_PROMISE=y
+CONFIG_SATA_SX4=y
+CONFIG_SATA_SIL=y
+CONFIG_SATA_SIL24=y
+CONFIG_SATA_SIS=y
+CONFIG_SATA_ULI=y
+CONFIG_SATA_VIA=y
+CONFIG_SATA_VITESSE=y
+CONFIG_SATA_INTEL_COMBINED=y
+CONFIG_PATA_ALI=y
+CONFIG_PATA_AMD=y
+CONFIG_PATA_ARTOP=y
+CONFIG_PATA_ATIIXP=y
+CONFIG_PATA_CMD64X=y
+CONFIG_PATA_CS5520=y
+CONFIG_PATA_CS5530=y
+CONFIG_PATA_CS5535=y
+CONFIG_PATA_CYPRESS=y
+CONFIG_PATA_EFAR=y
+CONFIG_ATA_GENERIC=y
+CONFIG_PATA_HPT366=y
+CONFIG_PATA_HPT37X=y
+CONFIG_PATA_HPT3X2N=y
+CONFIG_PATA_HPT3X3=y
+CONFIG_PATA_IT821X=y
+CONFIG_PATA_JMICRON=y
+CONFIG_PATA_TRIFLEX=y
+CONFIG_PATA_MARVELL=y
+CONFIG_PATA_MPIIX=y
+CONFIG_PATA_OLDPIIX=y
+CONFIG_PATA_NETCELL=y
+CONFIG_PATA_NS87410=y
+CONFIG_PATA_OPTI=y
+CONFIG_PATA_OPTIDMA=y
+# CONFIG_PATA_PCMCIA is not set
+CONFIG_PATA_PDC_OLD=y
+CONFIG_PATA_RADISYS=y
+CONFIG_PATA_RZ1000=y
+CONFIG_PATA_SC1200=y
+CONFIG_PATA_SERVERWORKS=y
+CONFIG_PATA_PDC2027X=y
+CONFIG_PATA_SIL680=y
+CONFIG_PATA_SIS=y
+CONFIG_PATA_VIA=y
+CONFIG_PATA_WINBOND=y
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=m
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID456=m
+CONFIG_MD_RAID5_RESHAPE=y
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+# CONFIG_DM_DEBUG is not set
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_EMC=m
+
+#
+# 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=y
+
+#
+# Subsystem Options
+#
+# CONFIG_IEEE1394_VERBOSEDEBUG is not set
+# CONFIG_IEEE1394_OUI_DB is not set
+CONFIG_IEEE1394_EXTRA_CONFIG_ROMS=y
+CONFIG_IEEE1394_CONFIG_ROM_IP1394=y
+# CONFIG_IEEE1394_EXPORT_FULL_API is not set
+
+#
+# Device Drivers
+#
+CONFIG_IEEE1394_PCILYNX=m
+CONFIG_IEEE1394_OHCI1394=y
+
+#
+# Protocol Drivers
+#
+CONFIG_IEEE1394_VIDEO1394=m
+CONFIG_IEEE1394_SBP2=m
+# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set
+CONFIG_IEEE1394_ETH1394=m
+CONFIG_IEEE1394_DV1394=m
+CONFIG_IEEE1394_RAWIO=y
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+CONFIG_EQUALIZER=m
+CONFIG_TUN=m
+CONFIG_NET_SB1000=m
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+CONFIG_VITESSE_PHY=m
+CONFIG_SMSC_PHY=m
+CONFIG_BROADCOM_PHY=m
+CONFIG_FIXED_PHY=m
+# CONFIG_FIXED_MII_10_FDX is not set
+# CONFIG_FIXED_MII_100_FDX 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=y
+CONFIG_VORTEX=m
+CONFIG_TYPHOON=m
+
+#
+# Tulip family network device support
+#
+CONFIG_NET_TULIP=y
+CONFIG_DE2104X=m
+CONFIG_TULIP=m
+# CONFIG_TULIP_MWI is not set
+# CONFIG_TULIP_MMIO is not set
+# CONFIG_TULIP_NAPI is not set
+CONFIG_DE4X5=m
+CONFIG_WINBOND_840=m
+CONFIG_DM9102=m
+CONFIG_ULI526X=m
+# CONFIG_PCMCIA_XIRCOM is not set
+# CONFIG_HP100 is not set
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=m
+# CONFIG_PCNET32_NAPI is not set
+CONFIG_AMD8111_ETH=m
+# CONFIG_AMD8111E_NAPI is not set
+CONFIG_ADAPTEC_STARFIRE=m
+# CONFIG_ADAPTEC_STARFIRE_NAPI is not set
+CONFIG_B44=m
+CONFIG_FORCEDETH=m
+# CONFIG_FORCEDETH_NAPI is not set
+CONFIG_DGRS=m
+CONFIG_EEPRO100=m
+CONFIG_E100=m
+CONFIG_FEALNX=m
+CONFIG_NATSEMI=m
+CONFIG_NE2K_PCI=m
+CONFIG_8139CP=m
+CONFIG_8139TOO=y
+CONFIG_8139TOO_PIO=y
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_OLD_RX_RESET is not set
+CONFIG_SIS900=m
+CONFIG_EPIC100=m
+CONFIG_SUNDANCE=m
+# CONFIG_SUNDANCE_MMIO is not set
+CONFIG_TLAN=m
+CONFIG_VIA_RHINE=m
+# CONFIG_VIA_RHINE_MMIO is not set
+# CONFIG_VIA_RHINE_NAPI is not set
+CONFIG_NET_POCKET=y
+CONFIG_ATP=m
+CONFIG_DE600=m
+CONFIG_DE620=m
+
+#
+# Ethernet (1000 Mbit)
+#
+CONFIG_ACENIC=m
+# CONFIG_ACENIC_OMIT_TIGON_I is not set
+CONFIG_DL2K=m
+CONFIG_E1000=m
+# CONFIG_E1000_NAPI is not set
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
+CONFIG_NS83820=m
+CONFIG_HAMACHI=m
+CONFIG_YELLOWFIN=m
+CONFIG_R8169=m
+# CONFIG_R8169_NAPI is not set
+CONFIG_SIS190=m
+CONFIG_SKGE=m
+CONFIG_SKY2=m
+CONFIG_SK98LIN=m
+CONFIG_VIA_VELOCITY=m
+CONFIG_TIGON3=m
+CONFIG_BNX2=m
+CONFIG_QLA3XXX=m
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_IXGB is not set
+CONFIG_S2IO=m
+# CONFIG_S2IO_NAPI 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=m
+# CONFIG_IPW2100_MONITOR is not set
+# CONFIG_IPW2100_DEBUG is not set
+CONFIG_IPW2200=m
+# CONFIG_IPW2200_MONITOR is not set
+CONFIG_IPW2200_QOS=y
+# CONFIG_IPW2200_DEBUG is not set
+CONFIG_AIRO=m
+CONFIG_HERMES=m
+CONFIG_PLX_HERMES=m
+CONFIG_TMD_HERMES=m
+CONFIG_NORTEL_HERMES=m
+CONFIG_PCI_HERMES=m
+CONFIG_ATMEL=m
+# CONFIG_PCI_ATMEL is not set
+
+#
+# Wireless 802.11b Pcmcia/Cardbus cards support
+#
+# CONFIG_PCMCIA_HERMES is not set
+# CONFIG_PCMCIA_SPECTRUM is not set
+# CONFIG_AIRO_CS is not set
+# CONFIG_PCMCIA_ATMEL 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=m
+CONFIG_HOSTAP=m
+CONFIG_HOSTAP_FIRMWARE=y
+CONFIG_HOSTAP_FIRMWARE_NVRAM=y
+CONFIG_HOSTAP_PLX=m
+CONFIG_HOSTAP_PCI=m
+# CONFIG_HOSTAP_CS is not set
+CONFIG_NET_WIRELESS=y
+
+#
+# PCMCIA network device support
+#
+# CONFIG_NET_PCMCIA is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+# CONFIG_SLIP is not set
+CONFIG_SLHC=m
+# 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=m
+
+#
+# Old ISDN4Linux
+#
+# CONFIG_ISDN_I4L is not set
+
+#
+# CAPI subsystem
+#
+CONFIG_ISDN_CAPI=m
+# CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON is not set
+# CONFIG_ISDN_CAPI_MIDDLEWARE is not set
+CONFIG_ISDN_CAPI_CAPI20=m
+
+#
+# CAPI hardware drivers
+#
+
+#
+# Active AVM cards
+#
+CONFIG_CAPI_AVM=y
+CONFIG_ISDN_DRV_AVMB1_B1PCI=m
+CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y
+CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m
+# CONFIG_ISDN_DRV_AVMB1_AVM_CS is not set
+CONFIG_ISDN_DRV_AVMB1_T1PCI=m
+CONFIG_ISDN_DRV_AVMB1_C4=m
+
+#
+# Active Eicon DIVA Server cards
+#
+CONFIG_CAPI_EICON=y
+CONFIG_ISDN_DIVAS=m
+# CONFIG_ISDN_DIVAS_BRIPCI is not set
+# CONFIG_ISDN_DIVAS_PRIPCI is not set
+CONFIG_ISDN_DIVAS_DIVACAPI=m
+CONFIG_ISDN_DIVAS_USERIDI=m
+CONFIG_ISDN_DIVAS_MAINT=m
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+CONFIG_INPUT_FF_MEMLESS=y
+
+#
+# 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 is not set
+# 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 is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_PARKBD is not set
+# CONFIG_SERIO_PCIPS2 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=y
+# CONFIG_SERIAL_8250_CONSOLE is not set
+CONFIG_SERIAL_8250_PCI=y
+CONFIG_SERIAL_8250_PNP=y
+# CONFIG_SERIAL_8250_CS is not set
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+CONFIG_PRINTER=y
+# CONFIG_LP_CONSOLE is not set
+# CONFIG_PPDEV is not set
+# CONFIG_TIPAR is not set
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+CONFIG_HW_RANDOM=m
+CONFIG_HW_RANDOM_INTEL=m
+CONFIG_HW_RANDOM_AMD=m
+CONFIG_HW_RANDOM_GEODE=m
+CONFIG_HW_RANDOM_VIA=m
+# CONFIG_NVRAM is not set
+CONFIG_RTC=m
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_SONYPI is not set
+CONFIG_AGP=y
+CONFIG_AGP_ALI=m
+CONFIG_AGP_ATI=m
+CONFIG_AGP_AMD=m
+CONFIG_AGP_AMD64=y
+CONFIG_AGP_INTEL=y
+CONFIG_AGP_NVIDIA=m
+CONFIG_AGP_SIS=m
+CONFIG_AGP_SWORKS=m
+CONFIG_AGP_VIA=m
+CONFIG_AGP_EFFICEON=m
+CONFIG_DRM=y
+# CONFIG_DRM_TDFX is not set
+CONFIG_DRM_R128=m
+CONFIG_DRM_RADEON=m
+CONFIG_DRM_I810=m
+CONFIG_DRM_I830=m
+CONFIG_DRM_I915=m
+CONFIG_DRM_MGA=m
+CONFIG_DRM_SIS=m
+CONFIG_DRM_VIA=m
+CONFIG_DRM_SAVAGE=m
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+# CONFIG_CARDMAN_4000 is not set
+# CONFIG_CARDMAN_4040 is not set
+CONFIG_MWAVE=m
+# CONFIG_SCx200_GPIO is not set
+CONFIG_PC8736x_GPIO=m
+CONFIG_NSC_GPIO=m
+CONFIG_CS5535_GPIO=m
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_HPET is not set
+CONFIG_HANGCHECK_TIMER=m
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+CONFIG_TELCLOCK=m
+
+#
+# I2C support
+#
+CONFIG_I2C=m
+CONFIG_I2C_CHARDEV=m
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=m
+CONFIG_I2C_ALGOPCF=m
+CONFIG_I2C_ALGOPCA=m
+
+#
+# I2C Hardware Bus support
+#
+CONFIG_I2C_ALI1535=m
+CONFIG_I2C_ALI1563=m
+CONFIG_I2C_ALI15X3=m
+CONFIG_I2C_AMD756=m
+CONFIG_I2C_AMD756_S4882=m
+CONFIG_I2C_AMD8111=m
+CONFIG_I2C_I801=m
+CONFIG_I2C_I810=m
+CONFIG_I2C_PIIX4=m
+CONFIG_I2C_ISA=m
+CONFIG_I2C_NFORCE2=m
+CONFIG_I2C_OCORES=m
+CONFIG_I2C_PARPORT=m
+CONFIG_I2C_PARPORT_LIGHT=m
+CONFIG_I2C_PROSAVAGE=m
+CONFIG_I2C_SAVAGE4=m
+CONFIG_SCx200_ACB=m
+CONFIG_I2C_SIS5595=m
+CONFIG_I2C_SIS630=m
+CONFIG_I2C_SIS96X=m
+CONFIG_I2C_STUB=m
+CONFIG_I2C_VIA=m
+CONFIG_I2C_VIAPRO=m
+CONFIG_I2C_VOODOO3=m
+CONFIG_I2C_PCA_ISA=m
+
+#
+# Miscellaneous I2C Chip support
+#
+CONFIG_SENSORS_DS1337=m
+CONFIG_SENSORS_DS1374=m
+CONFIG_SENSORS_EEPROM=m
+CONFIG_SENSORS_PCF8574=m
+CONFIG_SENSORS_PCA9539=m
+CONFIG_SENSORS_PCF8591=m
+CONFIG_SENSORS_MAX6875=m
+# 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_BITBANG=m
+CONFIG_SPI_BUTTERFLY=m
+
+#
+# SPI Protocol Masters
+#
+
+#
+# Dallas's 1-wire bus
+#
+CONFIG_W1=m
+
+#
+# 1-wire Bus Masters
+#
+CONFIG_W1_MASTER_MATROX=m
+CONFIG_W1_MASTER_DS2490=m
+CONFIG_W1_MASTER_DS2482=m
+
+#
+# 1-wire Slaves
+#
+CONFIG_W1_SLAVE_THERM=m
+CONFIG_W1_SLAVE_SMEM=m
+CONFIG_W1_SLAVE_DS2433=m
+# CONFIG_W1_SLAVE_DS2433_CRC is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+CONFIG_HWMON_VID=m
+CONFIG_SENSORS_ABITUGURU=m
+CONFIG_SENSORS_ADM1021=m
+CONFIG_SENSORS_ADM1025=m
+CONFIG_SENSORS_ADM1026=m
+CONFIG_SENSORS_ADM1031=m
+CONFIG_SENSORS_ADM9240=m
+CONFIG_SENSORS_K8TEMP=m
+CONFIG_SENSORS_ASB100=m
+CONFIG_SENSORS_ATXP1=m
+CONFIG_SENSORS_DS1621=m
+CONFIG_SENSORS_F71805F=m
+CONFIG_SENSORS_FSCHER=m
+CONFIG_SENSORS_FSCPOS=m
+CONFIG_SENSORS_GL518SM=m
+CONFIG_SENSORS_GL520SM=m
+CONFIG_SENSORS_IT87=m
+CONFIG_SENSORS_LM63=m
+CONFIG_SENSORS_LM70=m
+CONFIG_SENSORS_LM75=m
+CONFIG_SENSORS_LM77=m
+CONFIG_SENSORS_LM78=m
+CONFIG_SENSORS_LM80=m
+CONFIG_SENSORS_LM83=m
+CONFIG_SENSORS_LM85=m
+CONFIG_SENSORS_LM87=m
+CONFIG_SENSORS_LM90=m
+CONFIG_SENSORS_LM92=m
+CONFIG_SENSORS_MAX1619=m
+CONFIG_SENSORS_PC87360=m
+CONFIG_SENSORS_PC87427=m
+CONFIG_SENSORS_SIS5595=m
+CONFIG_SENSORS_SMSC47M1=m
+CONFIG_SENSORS_SMSC47M192=m
+CONFIG_SENSORS_SMSC47B397=m
+CONFIG_SENSORS_VIA686A=m
+CONFIG_SENSORS_VT1211=m
+CONFIG_SENSORS_VT8231=m
+CONFIG_SENSORS_W83781D=m
+CONFIG_SENSORS_W83791D=m
+CONFIG_SENSORS_W83792D=m
+CONFIG_SENSORS_W83793=m
+CONFIG_SENSORS_W83L785TS=m
+CONFIG_SENSORS_W83627HF=m
+CONFIG_SENSORS_W83627EHF=m
+CONFIG_SENSORS_HDAPS=m
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Multimedia devices
+#
+CONFIG_VIDEO_DEV=m
+CONFIG_VIDEO_V4L1=y
+CONFIG_VIDEO_V4L1_COMPAT=y
+CONFIG_VIDEO_V4L2=y
+
+#
+# Video Capture Adapters
+#
+
+#
+# Video Capture Adapters
+#
+# CONFIG_VIDEO_ADV_DEBUG is not set
+CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
+CONFIG_VIDEO_TVAUDIO=m
+CONFIG_VIDEO_TDA7432=m
+CONFIG_VIDEO_TDA9840=m
+CONFIG_VIDEO_TDA9875=m
+CONFIG_VIDEO_TEA6415C=m
+CONFIG_VIDEO_TEA6420=m
+CONFIG_VIDEO_MSP3400=m
+CONFIG_VIDEO_BT819=m
+CONFIG_VIDEO_BT856=m
+CONFIG_VIDEO_KS0127=m
+CONFIG_VIDEO_OV7670=m
+CONFIG_VIDEO_SAA7110=m
+CONFIG_VIDEO_SAA7111=m
+CONFIG_VIDEO_SAA7114=m
+CONFIG_VIDEO_SAA711X=m
+CONFIG_VIDEO_TVP5150=m
+CONFIG_VIDEO_VPX3220=m
+CONFIG_VIDEO_CX2341X=m
+CONFIG_VIDEO_SAA7185=m
+CONFIG_VIDEO_ADV7170=m
+CONFIG_VIDEO_ADV7175=m
+CONFIG_VIDEO_VIVI=m
+CONFIG_VIDEO_BT848=m
+# CONFIG_VIDEO_BT848_DVB is not set
+CONFIG_VIDEO_SAA6588=m
+CONFIG_VIDEO_BWQCAM=m
+CONFIG_VIDEO_CQCAM=m
+CONFIG_VIDEO_CPIA=m
+CONFIG_VIDEO_CPIA_USB=m
+CONFIG_VIDEO_CPIA2=m
+CONFIG_VIDEO_SAA5246A=m
+CONFIG_VIDEO_SAA5249=m
+CONFIG_TUNER_3036=m
+CONFIG_VIDEO_STRADIS=m
+CONFIG_VIDEO_ZORAN_ZR36060=m
+CONFIG_VIDEO_ZORAN=m
+CONFIG_VIDEO_ZORAN_BUZ=m
+CONFIG_VIDEO_ZORAN_DC10=m
+CONFIG_VIDEO_ZORAN_DC30=m
+CONFIG_VIDEO_ZORAN_LML33=m
+CONFIG_VIDEO_ZORAN_LML33R10=m
+CONFIG_VIDEO_ZORAN_AVS6EYES=m
+CONFIG_VIDEO_SAA7134=m
+CONFIG_VIDEO_SAA7134_ALSA=m
+# CONFIG_VIDEO_SAA7134_OSS is not set
+# CONFIG_VIDEO_SAA7134_DVB is not set
+CONFIG_VIDEO_MXB=m
+CONFIG_VIDEO_DPC=m
+CONFIG_VIDEO_HEXIUM_ORION=m
+CONFIG_VIDEO_HEXIUM_GEMINI=m
+CONFIG_VIDEO_CX88=m
+CONFIG_VIDEO_CX88_ALSA=m
+CONFIG_VIDEO_CX88_BLACKBIRD=m
+# CONFIG_VIDEO_CX88_DVB is not set
+CONFIG_VIDEO_CAFE_CCIC=m
+
+#
+# V4L USB devices
+#
+CONFIG_VIDEO_PVRUSB2=m
+# CONFIG_VIDEO_PVRUSB2_29XXX is not set
+# CONFIG_VIDEO_PVRUSB2_24XXX is not set
+CONFIG_VIDEO_PVRUSB2_SYSFS=y
+# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set
+CONFIG_VIDEO_EM28XX=m
+CONFIG_VIDEO_USBVISION=m
+CONFIG_VIDEO_USBVIDEO=m
+CONFIG_USB_VICAM=m
+CONFIG_USB_IBMCAM=m
+CONFIG_USB_KONICAWC=m
+CONFIG_USB_QUICKCAM_MESSENGER=m
+CONFIG_USB_ET61X251=m
+CONFIG_VIDEO_OVCAMCHIP=m
+CONFIG_USB_W9968CF=m
+CONFIG_USB_OV511=m
+CONFIG_USB_SE401=m
+CONFIG_USB_SN9C102=m
+CONFIG_USB_STV680=m
+CONFIG_USB_ZC0301=m
+CONFIG_USB_PWC=m
+# CONFIG_USB_PWC_DEBUG is not set
+
+#
+# Radio Adapters
+#
+CONFIG_RADIO_GEMTEK_PCI=m
+CONFIG_RADIO_MAXIRADIO=m
+CONFIG_RADIO_MAESTRO=m
+CONFIG_USB_DSBR=m
+
+#
+# Digital Video Broadcasting Devices
+#
+CONFIG_DVB=y
+CONFIG_DVB_CORE=m
+# CONFIG_DVB_CORE_ATTACH is not set
+
+#
+# Supported SAA7146 based PCI Adapters
+#
+CONFIG_DVB_AV7110=m
+CONFIG_DVB_AV7110_OSD=y
+CONFIG_DVB_BUDGET=m
+CONFIG_DVB_BUDGET_CI=m
+CONFIG_DVB_BUDGET_AV=m
+CONFIG_DVB_BUDGET_PATCH=m
+
+#
+# Supported USB Adapters
+#
+CONFIG_DVB_USB=m
+# CONFIG_DVB_USB_DEBUG is not set
+CONFIG_DVB_USB_A800=m
+CONFIG_DVB_USB_DIBUSB_MB=m
+# CONFIG_DVB_USB_DIBUSB_MB_FAULTY is not set
+CONFIG_DVB_USB_DIBUSB_MC=m
+CONFIG_DVB_USB_DIB0700=m
+CONFIG_DVB_USB_UMT_010=m
+CONFIG_DVB_USB_CXUSB=m
+CONFIG_DVB_USB_DIGITV=m
+CONFIG_DVB_USB_VP7045=m
+CONFIG_DVB_USB_VP702X=m
+CONFIG_DVB_USB_GP8PSK=m
+CONFIG_DVB_USB_NOVA_T_USB2=m
+CONFIG_DVB_USB_TTUSB2=m
+CONFIG_DVB_USB_DTT200U=m
+CONFIG_DVB_TTUSB_BUDGET=m
+CONFIG_DVB_TTUSB_DEC=m
+CONFIG_DVB_CINERGYT2=m
+# CONFIG_DVB_CINERGYT2_TUNING is not set
+
+#
+# Supported FlexCopII (B2C2) Adapters
+#
+CONFIG_DVB_B2C2_FLEXCOP=m
+CONFIG_DVB_B2C2_FLEXCOP_PCI=m
+CONFIG_DVB_B2C2_FLEXCOP_USB=m
+# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set
+
+#
+# Supported BT878 Adapters
+#
+CONFIG_DVB_BT8XX=m
+
+#
+# Supported Pluto2 Adapters
+#
+CONFIG_DVB_PLUTO2=m
+
+#
+# Supported DVB Frontends
+#
+
+#
+# Customise DVB Frontends
+#
+CONFIG_DVB_FE_CUSTOMISE=y
+
+#
+# DVB-S (satellite) frontends
+#
+CONFIG_DVB_STV0299=m
+CONFIG_DVB_CX24110=m
+CONFIG_DVB_CX24123=m
+CONFIG_DVB_TDA8083=m
+CONFIG_DVB_MT312=m
+CONFIG_DVB_VES1X93=m
+CONFIG_DVB_S5H1420=m
+CONFIG_DVB_TDA10086=m
+
+#
+# DVB-T (terrestrial) frontends
+#
+CONFIG_DVB_SP8870=m
+CONFIG_DVB_SP887X=m
+CONFIG_DVB_CX22700=m
+CONFIG_DVB_CX22702=m
+CONFIG_DVB_L64781=m
+CONFIG_DVB_TDA1004X=m
+CONFIG_DVB_NXT6000=m
+CONFIG_DVB_MT352=m
+CONFIG_DVB_ZL10353=m
+CONFIG_DVB_DIB3000MB=m
+CONFIG_DVB_DIB3000MC=m
+CONFIG_DVB_DIB7000M=m
+CONFIG_DVB_DIB7000P=m
+
+#
+# DVB-C (cable) frontends
+#
+CONFIG_DVB_VES1820=m
+CONFIG_DVB_TDA10021=m
+CONFIG_DVB_STV0297=m
+
+#
+# ATSC (North American/Korean Terrestrial/Cable DTV) frontends
+#
+CONFIG_DVB_NXT200X=m
+CONFIG_DVB_OR51211=m
+CONFIG_DVB_OR51132=m
+CONFIG_DVB_BCM3510=m
+CONFIG_DVB_LGDT330X=m
+
+#
+# Tuners/PLL support
+#
+CONFIG_DVB_PLL=m
+CONFIG_DVB_TDA826X=m
+CONFIG_DVB_TUNER_MT2060=m
+CONFIG_DVB_TUNER_LGH06XF=m
+
+#
+# Miscellaneous devices
+#
+CONFIG_DVB_LNBP21=m
+CONFIG_DVB_ISL6421=m
+CONFIG_DVB_TUA6100=m
+CONFIG_VIDEO_SAA7146=m
+CONFIG_VIDEO_SAA7146_VV=m
+CONFIG_VIDEO_VIDEOBUF=m
+CONFIG_VIDEO_TUNER=m
+CONFIG_VIDEO_BUF=m
+CONFIG_VIDEO_BTCX=m
+CONFIG_VIDEO_IR=m
+CONFIG_VIDEO_TVEEPROM=m
+CONFIG_USB_DABUSB=m
+
+#
+# Graphics support
+#
+CONFIG_FIRMWARE_EDID=y
+CONFIG_FB=y
+CONFIG_FB_DDC=m
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_TILEBLITTING=y
+# CONFIG_FB_CIRRUS is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_ARC is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+CONFIG_FB_VGA16=y
+CONFIG_FB_VESA=y
+CONFIG_FB_HGA=m
+# CONFIG_FB_HGA_ACCEL is not set
+CONFIG_FB_S1D13XXX=m
+CONFIG_FB_NVIDIA=m
+# CONFIG_FB_NVIDIA_I2C is not set
+CONFIG_FB_RIVA=m
+# CONFIG_FB_RIVA_I2C is not set
+# CONFIG_FB_RIVA_DEBUG is not set
+CONFIG_FB_I810=m
+# CONFIG_FB_I810_GTF is not set
+CONFIG_FB_INTEL=m
+# CONFIG_FB_INTEL_DEBUG is not set
+CONFIG_FB_INTEL_I2C=y
+CONFIG_FB_MATROX=m
+# CONFIG_FB_MATROX_MILLENIUM is not set
+# CONFIG_FB_MATROX_MYSTIQUE is not set
+# CONFIG_FB_MATROX_G is not set
+CONFIG_FB_MATROX_I2C=m
+# CONFIG_FB_MATROX_MULTIHEAD is not set
+CONFIG_FB_RADEON=m
+CONFIG_FB_RADEON_I2C=y
+# CONFIG_FB_RADEON_DEBUG is not set
+CONFIG_FB_ATY128=m
+CONFIG_FB_ATY=m
+# CONFIG_FB_ATY_CT is not set
+# CONFIG_FB_ATY_GX is not set
+CONFIG_FB_SAVAGE=m
+# CONFIG_FB_SAVAGE_I2C is not set
+# CONFIG_FB_SAVAGE_ACCEL is not set
+CONFIG_FB_SIS=m
+# CONFIG_FB_SIS_300 is not set
+# CONFIG_FB_SIS_315 is not set
+CONFIG_FB_NEOMAGIC=m
+CONFIG_FB_KYRO=m
+CONFIG_FB_3DFX=m
+# CONFIG_FB_3DFX_ACCEL is not set
+CONFIG_FB_VOODOO1=m
+CONFIG_FB_CYBLA=m
+CONFIG_FB_TRIDENT=m
+# CONFIG_FB_TRIDENT_ACCEL is not set
+CONFIG_FB_GEODE=y
+CONFIG_FB_GEODE_GX=m
+# CONFIG_FB_GEODE_GX_SET_FBSIZE is not set
+CONFIG_FB_GEODE_GX1=m
+CONFIG_FB_VIRTUAL=m
+
+#
+# Console display driver support
+#
+CONFIG_VGA_CONSOLE=y
+# CONFIG_VGACON_SOFT_SCROLLBACK is not set
+CONFIG_VIDEO_SELECT=y
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+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=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=m
+CONFIG_BACKLIGHT_DEVICE=y
+CONFIG_LCD_CLASS_DEVICE=m
+CONFIG_LCD_DEVICE=y
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+CONFIG_SND_HWDEP=m
+CONFIG_SND_RAWMIDI=m
+CONFIG_SND_SEQUENCER=y
+# CONFIG_SND_SEQ_DUMMY 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_SEQUENCER_OSS=y
+CONFIG_SND_RTCTIMER=m
+CONFIG_SND_SEQ_RTCTIMER_DEFAULT=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_MPU401_UART=m
+CONFIG_SND_OPL3_LIB=m
+CONFIG_SND_VX_LIB=m
+CONFIG_SND_AC97_CODEC=y
+CONFIG_SND_DUMMY=m
+CONFIG_SND_VIRMIDI=m
+CONFIG_SND_MTPAV=m
+CONFIG_SND_MTS64=m
+CONFIG_SND_SERIAL_U16550=m
+CONFIG_SND_MPU401=m
+
+#
+# PCI devices
+#
+CONFIG_SND_AD1889=m
+CONFIG_SND_ALS300=m
+CONFIG_SND_ALS4000=m
+CONFIG_SND_ALI5451=m
+CONFIG_SND_ATIIXP=m
+CONFIG_SND_ATIIXP_MODEM=m
+CONFIG_SND_AU8810=m
+CONFIG_SND_AU8820=m
+CONFIG_SND_AU8830=m
+CONFIG_SND_AZT3328=m
+CONFIG_SND_BT87X=m
+# CONFIG_SND_BT87X_OVERCLOCK is not set
+CONFIG_SND_CA0106=m
+CONFIG_SND_CMIPCI=m
+CONFIG_SND_CS4281=m
+CONFIG_SND_CS46XX=m
+CONFIG_SND_CS46XX_NEW_DSP=y
+CONFIG_SND_CS5535AUDIO=m
+CONFIG_SND_DARLA20=m
+CONFIG_SND_GINA20=m
+CONFIG_SND_LAYLA20=m
+CONFIG_SND_DARLA24=m
+CONFIG_SND_GINA24=m
+CONFIG_SND_LAYLA24=m
+CONFIG_SND_MONA=m
+CONFIG_SND_MIA=m
+CONFIG_SND_ECHO3G=m
+CONFIG_SND_INDIGO=m
+CONFIG_SND_INDIGOIO=m
+CONFIG_SND_INDIGODJ=m
+CONFIG_SND_EMU10K1=m
+CONFIG_SND_EMU10K1X=m
+CONFIG_SND_ENS1370=m
+CONFIG_SND_ENS1371=m
+CONFIG_SND_ES1938=m
+CONFIG_SND_ES1968=m
+CONFIG_SND_FM801=m
+# CONFIG_SND_FM801_TEA575X_BOOL is not set
+CONFIG_SND_HDA_INTEL=m
+CONFIG_SND_HDSP=m
+CONFIG_SND_HDSPM=m
+CONFIG_SND_ICE1712=m
+CONFIG_SND_ICE1724=m
+CONFIG_SND_INTEL8X0=y
+CONFIG_SND_INTEL8X0M=m
+CONFIG_SND_KORG1212=m
+CONFIG_SND_MAESTRO3=m
+CONFIG_SND_MIXART=m
+CONFIG_SND_NM256=m
+CONFIG_SND_PCXHR=m
+CONFIG_SND_RIPTIDE=m
+CONFIG_SND_RME32=m
+CONFIG_SND_RME96=m
+CONFIG_SND_RME9652=m
+CONFIG_SND_SONICVIBES=m
+CONFIG_SND_TRIDENT=m
+CONFIG_SND_VIA82XX=m
+CONFIG_SND_VIA82XX_MODEM=m
+CONFIG_SND_VX222=m
+CONFIG_SND_YMFPCI=m
+# CONFIG_SND_AC97_POWER_SAVE is not set
+
+#
+# USB devices
+#
+CONFIG_SND_USB_AUDIO=m
+CONFIG_SND_USB_USX2Y=m
+
+#
+# PCMCIA devices
+#
+# CONFIG_SND_VXPOCKET is not set
+# CONFIG_SND_PDAUDIOCF is not set
+
+#
+# Open Sound System
+#
+CONFIG_SOUND_PRIME=y
+CONFIG_SOUND_BT878=m
+CONFIG_SOUND_ES1371=m
+CONFIG_SOUND_ICH=m
+CONFIG_SOUND_TRIDENT=m
+CONFIG_SOUND_MSNDCLAS=m
+CONFIG_MSNDCLAS_INIT_FILE="/etc/sound/msndinit.bin"
+CONFIG_MSNDCLAS_PERM_FILE="/etc/sound/msndperm.bin"
+CONFIG_SOUND_MSNDPIN=m
+CONFIG_MSNDPIN_INIT_FILE="/etc/sound/pndspini.bin"
+CONFIG_MSNDPIN_PERM_FILE="/etc/sound/pndsperm.bin"
+CONFIG_SOUND_VIA82CXXX=m
+# CONFIG_MIDI_VIA82CXXX is not set
+CONFIG_SOUND_OSS=m
+# CONFIG_SOUND_TRACEINIT is not set
+# CONFIG_SOUND_DMAP is not set
+CONFIG_SOUND_CS4232=m
+CONFIG_SOUND_SSCAPE=m
+CONFIG_SOUND_VMIDI=m
+CONFIG_SOUND_TRIX=m
+CONFIG_SOUND_MSS=m
+CONFIG_SOUND_MPU401=m
+CONFIG_SOUND_PAS=m
+CONFIG_SOUND_PSS=m
+# CONFIG_PSS_MIXER is not set
+CONFIG_SOUND_SB=m
+CONFIG_SOUND_YM3812=m
+CONFIG_SOUND_UART6850=m
+CONFIG_SOUND_AEDSP16=m
+# CONFIG_SC6600 is not set
+# CONFIG_AEDSP16_MSS is not set
+# CONFIG_AEDSP16_SBPRO is not set
+# CONFIG_AEDSP16_MPU401 is not set
+CONFIG_SOUND_TVMIXER=m
+CONFIG_SOUND_KAHLUA=m
+CONFIG_AC97_BUS=y
+
+#
+# HID Devices
+#
+CONFIG_HID=y
+
+#
+# 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_BANDWIDTH is not set
+# 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=y
+# CONFIG_USB_EHCI_SPLIT_ISO is not set
+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+CONFIG_USB_ISP116X_HCD=y
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+CONFIG_USB_UHCI_HCD=y
+# CONFIG_USB_U132_HCD is not set
+CONFIG_USB_SL811_HCD=y
+# CONFIG_USB_SL811_CS 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=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_DPCM=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_STORAGE_ALAUDA=y
+CONFIG_USB_STORAGE_KARMA=y
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+CONFIG_USB_HIDINPUT_POWERBOOK=y
+CONFIG_HID_FF=y
+CONFIG_HID_PID=y
+CONFIG_LOGITECH_FF=y
+CONFIG_THRUSTMASTER_FF=y
+CONFIG_ZEROPLUS_FF=y
+CONFIG_USB_HIDDEV=y
+CONFIG_USB_AIPTEK=m
+CONFIG_USB_WACOM=m
+CONFIG_USB_ACECAD=m
+CONFIG_USB_KBTAB=m
+CONFIG_USB_POWERMATE=m
+CONFIG_USB_TOUCHSCREEN=m
+CONFIG_USB_TOUCHSCREEN_EGALAX=y
+CONFIG_USB_TOUCHSCREEN_PANJIT=y
+CONFIG_USB_TOUCHSCREEN_3M=y
+CONFIG_USB_TOUCHSCREEN_ITM=y
+CONFIG_USB_TOUCHSCREEN_ETURBO=y
+CONFIG_USB_TOUCHSCREEN_GUNZE=y
+CONFIG_USB_TOUCHSCREEN_DMC_TSC10=y
+CONFIG_USB_YEALINK=m
+CONFIG_USB_XPAD=m
+CONFIG_USB_ATI_REMOTE=m
+CONFIG_USB_ATI_REMOTE2=m
+CONFIG_USB_KEYSPAN_REMOTE=m
+CONFIG_USB_APPLETOUCH=m
+
+#
+# USB Imaging devices
+#
+CONFIG_USB_MDC800=m
+CONFIG_USB_MICROTEK=m
+
+#
+# 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_GL620A=m
+CONFIG_USB_NET_NET1080=m
+CONFIG_USB_NET_PLUSB=m
+CONFIG_USB_NET_MCS7830=m
+CONFIG_USB_NET_RNDIS_HOST=m
+CONFIG_USB_NET_CDC_SUBSET=m
+CONFIG_USB_ALI_M5632=y
+CONFIG_USB_AN2720=y
+CONFIG_USB_BELKIN=y
+CONFIG_USB_ARMLINUX=y
+CONFIG_USB_EPSON2888=y
+CONFIG_USB_NET_ZAURUS=m
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+CONFIG_USB_USS720=m
+
+#
+# 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=m
+CONFIG_USB_SERIAL_OMNINET=m
+CONFIG_USB_SERIAL_DEBUG=m
+CONFIG_USB_EZUSB=y
+
+#
+# USB Miscellaneous drivers
+#
+CONFIG_USB_EMI62=m
+CONFIG_USB_EMI26=m
+CONFIG_USB_ADUTUX=m
+CONFIG_USB_AUERSWALD=m
+CONFIG_USB_RIO500=m
+CONFIG_USB_LEGOTOWER=m
+CONFIG_USB_LCD=m
+CONFIG_USB_LED=m
+CONFIG_USB_CYPRESS_CY7C63=m
+CONFIG_USB_CYTHERM=m
+CONFIG_USB_PHIDGET=m
+CONFIG_USB_PHIDGETKIT=m
+CONFIG_USB_PHIDGETMOTORCONTROL=m
+CONFIG_USB_PHIDGETSERVO=m
+CONFIG_USB_IDMOUSE=m
+CONFIG_USB_FTDI_ELAN=m
+CONFIG_USB_APPLEDISPLAY=m
+CONFIG_USB_SISUSBVGA=m
+# CONFIG_USB_SISUSBVGA_CON is not set
+CONFIG_USB_LD=m
+CONFIG_USB_TRANCEVIBRATOR=m
+CONFIG_USB_TEST=m
+
+#
+# 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_NET2280=y
+CONFIG_USB_NET2280=m
+# 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 is not set
+CONFIG_USB_G_SERIAL=m
+CONFIG_USB_MIDI_GADGET=m
+
+#
+# MMC/SD Card support
+#
+CONFIG_MMC=m
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_BLOCK=m
+CONFIG_MMC_SDHCI=m
+CONFIG_MMC_WBSD=m
+CONFIG_MMC_TIFM_SD=m
+
+#
+# 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_IDE_DISK=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=m
+
+#
+# InfiniBand support
+#
+CONFIG_INFINIBAND=m
+CONFIG_INFINIBAND_USER_MAD=m
+CONFIG_INFINIBAND_USER_ACCESS=m
+CONFIG_INFINIBAND_ADDR_TRANS=y
+CONFIG_INFINIBAND_MTHCA=m
+CONFIG_INFINIBAND_MTHCA_DEBUG=y
+CONFIG_INFINIBAND_AMSO1100=m
+# CONFIG_INFINIBAND_AMSO1100_DEBUG is not set
+CONFIG_INFINIBAND_IPOIB=m
+CONFIG_INFINIBAND_IPOIB_DEBUG=y
+# CONFIG_INFINIBAND_IPOIB_DEBUG_DATA is not set
+CONFIG_INFINIBAND_SRP=m
+CONFIG_INFINIBAND_ISER=m
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+CONFIG_EDAC=m
+
+#
+# Reporting subsystems
+#
+# CONFIG_EDAC_DEBUG is not set
+CONFIG_EDAC_MM_EDAC=m
+CONFIG_EDAC_AMD76X=m
+CONFIG_EDAC_E7XXX=m
+CONFIG_EDAC_E752X=m
+CONFIG_EDAC_I82875P=m
+CONFIG_EDAC_I82860=m
+CONFIG_EDAC_R82600=m
+CONFIG_EDAC_POLL=y
+
+#
+# Real Time Clock
+#
+CONFIG_RTC_LIB=m
+CONFIG_RTC_CLASS=m
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=m
+CONFIG_RTC_INTF_PROC=m
+CONFIG_RTC_INTF_DEV=m
+CONFIG_RTC_INTF_DEV_UIE_EMUL=y
+
+#
+# RTC drivers
+#
+CONFIG_RTC_DRV_X1205=m
+CONFIG_RTC_DRV_DS1307=m
+CONFIG_RTC_DRV_DS1553=m
+CONFIG_RTC_DRV_ISL1208=m
+CONFIG_RTC_DRV_DS1672=m
+CONFIG_RTC_DRV_DS1742=m
+CONFIG_RTC_DRV_PCF8563=m
+CONFIG_RTC_DRV_PCF8583=m
+CONFIG_RTC_DRV_RS5C348=m
+CONFIG_RTC_DRV_RS5C372=m
+CONFIG_RTC_DRV_M48T86=m
+CONFIG_RTC_DRV_TEST=m
+CONFIG_RTC_DRV_MAX6902=m
+CONFIG_RTC_DRV_V3020=m
+
+#
+# DMA Engine support
+#
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+CONFIG_NET_DMA=y
+
+#
+# DMA Devices
+#
+CONFIG_INTEL_IOATDMA=m
+
+#
+# Virtualization
+#
+# CONFIG_KVM 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=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=y
+CONFIG_FUSE_FS=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+# CONFIG_ZISOFS is not set
+CONFIG_UDF_FS=y
+CONFIG_UDF_NLS=y
+
+#
+# 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_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLBFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+CONFIG_CONFIGFS_FS=m
+
+#
+# Miscellaneous filesystems
+#
+CONFIG_ADFS_FS=m
+# CONFIG_ADFS_FS_RW is not set
+CONFIG_AFFS_FS=m
+CONFIG_HFS_FS=m
+CONFIG_HFSPLUS_FS=m
+CONFIG_BEFS_FS=m
+# CONFIG_BEFS_DEBUG is not set
+CONFIG_BFS_FS=m
+CONFIG_EFS_FS=m
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_SUMMARY is not set
+# 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=m
+CONFIG_VXFS_FS=m
+CONFIG_HPFS_FS=m
+CONFIG_QNX4FS_FS=m
+CONFIG_SYSV_FS=m
+CONFIG_UFS_FS=m
+# CONFIG_UFS_FS_WRITE is not set
+# CONFIG_UFS_DEBUG is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_DIRECTIO=y
+CONFIG_NFSD=y
+CONFIG_NFSD_V2_ACL=y
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_NFSD_TCP=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=y
+CONFIG_NFS_ACL_SUPPORT=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+CONFIG_RPCSEC_GSS_SPKM3=m
+CONFIG_SMB_FS=m
+# CONFIG_SMB_NLS_DEFAULT is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
+# CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
+CONFIG_NCP_FS=m
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+CONFIG_CODA_FS=m
+# CONFIG_CODA_FS_OLD_API is not set
+CONFIG_AFS_FS=m
+CONFIG_RXRPC=m
+CONFIG_9P_FS=m
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+
+#
+# Distributed Lock Manager
+#
+CONFIG_DLM=m
+CONFIG_DLM_TCP=y
+# CONFIG_DLM_SCTP is not set
+# CONFIG_DLM_DEBUG is not set
+
+#
+# Instrumentation Support
+#
+# CONFIG_PROFILING is not set
+# CONFIG_KPROBES is not set
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_UNUSED_SYMBOLS=y
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=15
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_X86_FIND_SMP_CONFIG=y
+CONFIG_X86_MPPARSE=y
+CONFIG_DOUBLEFAULT=y
+
+#
+# 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_HASH=m
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_HMAC=m
+CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_GF128MUL=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
+CONFIG_CRYPTO_TWOFISH_586=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_AES_586=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_TEST=m
+
+#
+# Hardware crypto devices
+#
+CONFIG_CRYPTO_DEV_PADLOCK=m
+CONFIG_CRYPTO_DEV_PADLOCK_AES=m
+CONFIG_CRYPTO_DEV_PADLOCK_SHA=m
+CONFIG_CRYPTO_DEV_GEODE=m
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_AUDIT_GENERIC=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_REED_SOLOMON=y
+CONFIG_REED_SOLOMON_DEC16=y
+CONFIG_PLIST=y
+CONFIG_IOMAP_COPY=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_PENDING_IRQ=y
+CONFIG_X86_SMP=y
+CONFIG_X86_HT=y
+CONFIG_X86_BIOS_REBOOT=y
+CONFIG_X86_TRAMPOLINE=y
+CONFIG_KTIME_SCALAR=y
diff --git a/recipes/linux/linux/kb9202/defconfig b/recipes/linux/linux/kb9202/defconfig
new file mode 100644
index 0000000000..c16537d9d6
--- /dev/null
+++ b/recipes/linux/linux/kb9202/defconfig
@@ -0,0 +1,780 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.13-rc2
+# Sun Aug 14 19:26:59 2005
+#
+CONFIG_ARM=y
+CONFIG_MMU=y
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+
+#
+# Code maturity level options
+#
+# CONFIG_EXPERIMENTAL is not set
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+# CONFIG_SWAP is not set
+# CONFIG_SYSVIPC is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+# CONFIG_KOBJECT_UEVENT is not set
+# CONFIG_IKCONFIG is not set
+# CONFIG_EMBEDDED is not set
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# System Type
+#
+# 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_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_IOP3XX is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_PXA is not set
+# 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_ARCH_VERSATILE is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_AAEC2000 is not set
+CONFIG_ARCH_AT91=y
+CONFIG_ARCH_AT91RM9200=y
+
+#
+# AT91RM9200 Implementations
+#
+# CONFIG_ARCH_AT91RM9200DK is not set
+# CONFIG_MACH_AT91RM9200EK is not set
+# CONFIG_MACH_CSB337 is not set
+# CONFIG_MACH_CSB637 is not set
+# CONFIG_MACH_CARMEVA is not set
+CONFIG_MACH_KB9200=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM920T=y
+CONFIG_CPU_32v4=y
+CONFIG_CPU_ABRT_EV4T=y
+CONFIG_CPU_CACHE_V4WT=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+
+#
+# Bus support
+#
+CONFIG_ISA_DMA_API=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_NO_IDLE_HZ is not set
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_LEDS is not set
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x10000000
+CONFIG_ZBOOT_ROM_BSS=0x20040000
+CONFIG_ZBOOT_ROM=y
+CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/ram rw initrd=0x20210000,654933"
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_AOUT=y
+CONFIG_BINFMT_MISC=y
+# CONFIG_ARTHUR is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+CONFIG_DEBUG_DRIVER=y
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD 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=y
+# 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_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CDROM_PKTCDVD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI=y
+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=y
+# 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 Transport Attributes
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_DEBUG 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
+#
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# 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_IP_MROUTE 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_TUNNEL is not set
+# CONFIG_IP_TCPDIAG is not set
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER 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
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_ARM_AT91_ETHER=y
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# 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 is not set
+# 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 is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_SERPORT is not set
+# 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_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_ATMEL=y
+CONFIG_SERIAL_ATMEL_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 is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_AT91RM9200_RTC 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_AT91_SPI is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB=y
+CONFIG_USB_DEBUG=y
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_ISP116X_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_SL811_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_BLUETOOTH_TTY is not set
+# 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=y
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+
+#
+# USB Input Devices
+#
+# CONFIG_USB_HID is not set
+
+#
+# USB HID Boot Protocol drivers
+#
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE 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_MTOUCH is not set
+# CONFIG_USB_ITMTOUCH is not set
+# CONFIG_USB_EGALAX is not set
+# CONFIG_USB_XPAD is not set
+# CONFIG_USB_ATI_REMOTE is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB Multimedia devices
+#
+# CONFIG_USB_DABUSB is not set
+
+#
+# Video4Linux support is needed for USB Multimedia device support
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS 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 is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGETKIT is not set
+# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_IDMOUSE is not set
+
+#
+# USB DSL modem support
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC 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_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_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+
+#
+# XFS support
+#
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=y
+CONFIG_AUTOFS4_FS=y
+
+#
+# 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_SYSFS=y
+CONFIG_DEVPTS_FS_XATTR=y
+# CONFIG_DEVPTS_FS_SECURITY is not set
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_XATTR is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_HFSPLUS_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_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_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="utf8"
+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=y
+# 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
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_FS is not set
+CONFIG_FRAME_POINTER=y
+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 is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
diff --git a/recipes/linux/linux/n2100/defconfig b/recipes/linux/linux/n2100/defconfig
new file mode 100644
index 0000000000..26c07e9c99
--- /dev/null
+++ b/recipes/linux/linux/n2100/defconfig
@@ -0,0 +1,1843 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.20.2
+# Wed Mar 14 01:43:59 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_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_VECTORS_BASE=0xffff0000
+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="-foonas"
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS 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=m
+CONFIG_IKCONFIG_PROC=y
+# CONFIG_SYSFS_DEPRECATED is not set
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+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_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=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+CONFIG_BLOCK=y
+CONFIG_LBD=y
+# 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 is not set
+CONFIG_DEFAULT_DEADLINE=y
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="deadline"
+
+#
+# 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=y
+# 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_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# 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
+
+#
+# IOP32x Implementation Options
+#
+
+#
+# IOP32x Platform Types
+#
+# CONFIG_MACH_GLANTANK is not set
+# CONFIG_ARCH_IQ80321 is not set
+# CONFIG_ARCH_IQ31244 is not set
+CONFIG_MACH_N2100=y
+CONFIG_PLAT_IOP=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_IWMMXT is not set
+CONFIG_XSCALE_PMU=y
+
+#
+# Bus support
+#
+CONFIG_PCI=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_PREEMPT=y
+CONFIG_NO_IDLE_HZ=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_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_CMDLINE="console=ttyS0,115200n8 root=/dev/mtdblock3 rootfstype=jffs2 rs5c372.probe=0,0x32"
+# 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=m
+CONFIG_BINFMT_MISC=m
+
+#
+# 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=y
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP 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 is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+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=m
+
+#
+# IrDA protocols
+#
+CONFIG_IRLAN=m
+# CONFIG_IRNET is not set
+CONFIG_IRCOMM=m
+# CONFIG_IRDA_ULTRA is not set
+
+#
+# IrDA options
+#
+CONFIG_IRDA_CACHE_LAST_LSAP=y
+CONFIG_IRDA_FAST_RR=y
+# CONFIG_IRDA_DEBUG is not set
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+CONFIG_IRTTY_SIR=m
+
+#
+# Dongle support
+#
+# CONFIG_DONGLE is not set
+
+#
+# Old SIR device drivers
+#
+# CONFIG_IRPORT_SIR is not set
+
+#
+# Old Serial dongle support
+#
+
+#
+# FIR device drivers
+#
+CONFIG_USB_IRDA=m
+CONFIG_SIGMATEL_FIR=m
+# CONFIG_TOSHIBA_FIR is not set
+# CONFIG_VLSI_FIR is not set
+CONFIG_MCS_FIR=m
+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 is not set
+CONFIG_BT_HCIBCM203X=m
+CONFIG_BT_HCIBPA10X=m
+CONFIG_BT_HCIBFUSB=m
+# CONFIG_BT_HCIVHCI 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=m
+# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set
+CONFIG_WIRELESS_EXT=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=m
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR 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_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=y
+# 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_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_START=0xFF000000
+CONFIG_MTD_PHYSMAP_LEN=0x01000000
+CONFIG_MTD_PHYSMAP_BANKWIDTH=1
+# CONFIG_MTD_ARM_INTEGRATOR 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 is not set
+# CONFIG_MTD_NAND_CAFE 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_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=m
+# 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=40960
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+CONFIG_ATA_OVER_ETH=m
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# 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=m
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+CONFIG_CHR_DEV_SG=m
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+# 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=m
+# 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_IPR 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
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+CONFIG_ATA=y
+# CONFIG_ATA_NONSTANDARD is not set
+# CONFIG_SATA_AHCI is not set
+# CONFIG_SATA_SVW is not set
+# CONFIG_ATA_PIIX is not set
+# CONFIG_SATA_MV is not set
+# CONFIG_SATA_NV is not set
+# CONFIG_PDC_ADMA is not set
+# CONFIG_SATA_QSTOR is not set
+# CONFIG_SATA_PROMISE is not set
+# CONFIG_SATA_SX4 is not set
+CONFIG_SATA_SIL=y
+# CONFIG_SATA_SIL24 is not set
+# CONFIG_SATA_SIS is not set
+# CONFIG_SATA_ULI is not set
+# CONFIG_SATA_VIA is not set
+# CONFIG_SATA_VITESSE is not set
+# CONFIG_PATA_ALI is not set
+# CONFIG_PATA_AMD is not set
+# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATIIXP is not set
+# CONFIG_PATA_CMD64X is not set
+# CONFIG_PATA_CS5520 is not set
+# CONFIG_PATA_CS5530 is not set
+# CONFIG_PATA_CYPRESS is not set
+# CONFIG_PATA_EFAR is not set
+# CONFIG_ATA_GENERIC is not set
+# CONFIG_PATA_HPT366 is not set
+# CONFIG_PATA_HPT37X is not set
+# CONFIG_PATA_HPT3X2N is not set
+# CONFIG_PATA_HPT3X3 is not set
+# CONFIG_PATA_IT821X is not set
+# CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_TRIFLEX is not set
+# CONFIG_PATA_MARVELL is not set
+# CONFIG_PATA_MPIIX is not set
+# CONFIG_PATA_OLDPIIX is not set
+# CONFIG_PATA_NETCELL is not set
+# CONFIG_PATA_NS87410 is not set
+# CONFIG_PATA_OPTI is not set
+# CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC_OLD is not set
+# CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RZ1000 is not set
+# CONFIG_PATA_SC1200 is not set
+# CONFIG_PATA_SERVERWORKS is not set
+# CONFIG_PATA_PDC2027X is not set
+# CONFIG_PATA_SIL680 is not set
+# CONFIG_PATA_SIS is not set
+# CONFIG_PATA_VIA is not set
+# CONFIG_PATA_WINBOND is not set
+# CONFIG_PATA_PLATFORM is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=m
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID456=m
+CONFIG_MD_RAID5_RESHAPE=y
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_MD_FAULTY is not set
+CONFIG_BLK_DEV_DM=m
+# CONFIG_DM_DEBUG is not set
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+# CONFIG_DM_MULTIPATH 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=y
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+CONFIG_TUN=m
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+
+#
+# Ethernet (10 or 100Mbit)
+#
+# CONFIG_NET_ETHERNET is not set
+CONFIG_MII=m
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+CONFIG_E1000=y
+# CONFIG_E1000_NAPI is not set
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+CONFIG_R1000=y
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_CHELSIO_T1 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
+
+#
+# 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
+
+#
+# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
+#
+# CONFIG_PRISM54 is not set
+CONFIG_USB_ZD1201=m
+# CONFIG_HOSTAP is not set
+# CONFIG_BCM43XX is not set
+CONFIG_ZD1211RW=m
+# CONFIG_ZD1211RW_DEBUG is not set
+CONFIG_NET_WIRELESS=y
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLHC=m
+CONFIG_SLIP_SMART=y
+CONFIG_SLIP_MODE_SLIP6=y
+# CONFIG_NET_FC is not set
+# CONFIG_SHAPER is not set
+CONFIG_NETCONSOLE=m
+CONFIG_NETPOLL=y
+# CONFIG_NETPOLL_RX is not set
+# CONFIG_NETPOLL_TRAP is not set
+CONFIG_NET_POLL_CONTROLLER=y
+
+#
+# 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 is not set
+# 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 is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+# 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=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PCI=y
+CONFIG_SERIAL_8250_NR_UARTS=1
+CONFIG_SERIAL_8250_RUNTIME_UARTS=1
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+CONFIG_HW_RANDOM=m
+CONFIG_NVRAM=m
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=m
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=m
+CONFIG_I2C_ALGOPCF=m
+CONFIG_I2C_ALGOPCA=m
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
+CONFIG_I2C_IOP3XX=y
+CONFIG_I2C_ISA=m
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_PROSAVAGE is not set
+# CONFIG_I2C_SAVAGE4 is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+# CONFIG_I2C_VOODOO3 is not set
+# CONFIG_I2C_PCA_ISA is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+# CONFIG_SENSORS_EEPROM is not set
+CONFIG_SENSORS_PCF8574=m
+CONFIG_SENSORS_PCA9539=m
+CONFIG_SENSORS_PCF8591=m
+CONFIG_SENSORS_MAX6875=m
+# 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
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+CONFIG_HWMON_VID=m
+CONFIG_SENSORS_ABITUGURU=m
+CONFIG_SENSORS_ADM1021=m
+CONFIG_SENSORS_ADM1025=m
+CONFIG_SENSORS_ADM1026=m
+CONFIG_SENSORS_ADM1031=m
+CONFIG_SENSORS_ADM9240=m
+CONFIG_SENSORS_ASB100=m
+CONFIG_SENSORS_ATXP1=m
+CONFIG_SENSORS_DS1621=m
+CONFIG_SENSORS_F71805F=m
+CONFIG_SENSORS_FSCHER=m
+CONFIG_SENSORS_FSCPOS=m
+CONFIG_SENSORS_GL518SM=m
+CONFIG_SENSORS_GL520SM=m
+CONFIG_SENSORS_IT87=m
+CONFIG_SENSORS_LM63=m
+CONFIG_SENSORS_LM75=m
+CONFIG_SENSORS_LM77=m
+CONFIG_SENSORS_LM78=m
+CONFIG_SENSORS_LM80=m
+CONFIG_SENSORS_LM83=m
+CONFIG_SENSORS_LM85=m
+CONFIG_SENSORS_LM87=m
+CONFIG_SENSORS_LM90=m
+CONFIG_SENSORS_LM92=m
+CONFIG_SENSORS_MAX1619=m
+CONFIG_SENSORS_PC87360=m
+CONFIG_SENSORS_PC87427=m
+CONFIG_SENSORS_SIS5595=m
+CONFIG_SENSORS_SMSC47M1=m
+CONFIG_SENSORS_SMSC47M192=m
+CONFIG_SENSORS_SMSC47B397=m
+CONFIG_SENSORS_VIA686A=m
+CONFIG_SENSORS_VT1211=m
+CONFIG_SENSORS_VT8231=m
+CONFIG_SENSORS_W83781D=m
+CONFIG_SENSORS_W83791D=m
+CONFIG_SENSORS_W83792D=m
+CONFIG_SENSORS_W83793=m
+CONFIG_SENSORS_W83L785TS=m
+CONFIG_SENSORS_W83627HF=m
+CONFIG_SENSORS_W83627EHF=m
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Misc devices
+#
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+
+#
+# LED devices
+#
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+
+#
+# Multimedia devices
+#
+CONFIG_VIDEO_DEV=m
+# CONFIG_VIDEO_V4L1 is not set
+CONFIG_VIDEO_V4L1_COMPAT=y
+CONFIG_VIDEO_V4L2=y
+
+#
+# Video Capture Adapters
+#
+
+#
+# Video Capture Adapters
+#
+# CONFIG_VIDEO_ADV_DEBUG is not set
+CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
+CONFIG_VIDEO_MSP3400=m
+CONFIG_VIDEO_WM8775=m
+CONFIG_VIDEO_SAA711X=m
+CONFIG_VIDEO_CX25840=m
+CONFIG_VIDEO_CX2341X=m
+# CONFIG_VIDEO_VIVI is not set
+# CONFIG_VIDEO_SAA5246A is not set
+# CONFIG_VIDEO_SAA5249 is not set
+# CONFIG_VIDEO_SAA7134 is not set
+# CONFIG_VIDEO_HEXIUM_ORION is not set
+# CONFIG_VIDEO_HEXIUM_GEMINI is not set
+# CONFIG_VIDEO_CX88 is not set
+# CONFIG_VIDEO_CAFE_CCIC is not set
+
+#
+# V4L USB devices
+#
+CONFIG_VIDEO_PVRUSB2=m
+CONFIG_VIDEO_PVRUSB2_29XXX=y
+CONFIG_VIDEO_PVRUSB2_24XXX=y
+CONFIG_VIDEO_PVRUSB2_SYSFS=y
+# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set
+CONFIG_VIDEO_USBVISION=m
+
+#
+# Radio Adapters
+#
+# CONFIG_RADIO_GEMTEK_PCI is not set
+# CONFIG_RADIO_MAXIRADIO is not set
+# CONFIG_RADIO_MAESTRO is not set
+CONFIG_USB_DSBR=m
+
+#
+# Digital Video Broadcasting Devices
+#
+CONFIG_DVB=y
+CONFIG_DVB_CORE=m
+# CONFIG_DVB_CORE_ATTACH is not set
+
+#
+# Supported SAA7146 based PCI Adapters
+#
+
+#
+# Supported USB Adapters
+#
+CONFIG_DVB_USB=m
+# CONFIG_DVB_USB_DEBUG is not set
+CONFIG_DVB_USB_A800=m
+CONFIG_DVB_USB_DIBUSB_MB=m
+CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y
+CONFIG_DVB_USB_DIBUSB_MC=m
+CONFIG_DVB_USB_DIB0700=m
+CONFIG_DVB_USB_UMT_010=m
+CONFIG_DVB_USB_CXUSB=m
+CONFIG_DVB_USB_DIGITV=m
+CONFIG_DVB_USB_VP7045=m
+CONFIG_DVB_USB_VP702X=m
+CONFIG_DVB_USB_GP8PSK=m
+CONFIG_DVB_USB_NOVA_T_USB2=m
+CONFIG_DVB_USB_TTUSB2=m
+CONFIG_DVB_USB_DTT200U=m
+CONFIG_DVB_TTUSB_BUDGET=m
+CONFIG_DVB_TTUSB_DEC=m
+CONFIG_DVB_CINERGYT2=m
+# CONFIG_DVB_CINERGYT2_TUNING is not set
+
+#
+# Supported FlexCopII (B2C2) Adapters
+#
+# CONFIG_DVB_B2C2_FLEXCOP is not set
+
+#
+# Supported BT878 Adapters
+#
+
+#
+# Supported Pluto2 Adapters
+#
+# CONFIG_DVB_PLUTO2 is not set
+
+#
+# Supported DVB Frontends
+#
+
+#
+# Customise DVB Frontends
+#
+# CONFIG_DVB_FE_CUSTOMISE is not set
+
+#
+# DVB-S (satellite) frontends
+#
+CONFIG_DVB_STV0299=m
+# CONFIG_DVB_CX24110 is not set
+# CONFIG_DVB_CX24123 is not set
+CONFIG_DVB_TDA8083=m
+# CONFIG_DVB_MT312 is not set
+# CONFIG_DVB_VES1X93 is not set
+# CONFIG_DVB_S5H1420 is not set
+CONFIG_DVB_TDA10086=m
+
+#
+# DVB-T (terrestrial) frontends
+#
+# CONFIG_DVB_SP8870 is not set
+# CONFIG_DVB_SP887X is not set
+CONFIG_DVB_CX22700=m
+CONFIG_DVB_CX22702=m
+# CONFIG_DVB_L64781 is not set
+CONFIG_DVB_TDA1004X=m
+CONFIG_DVB_NXT6000=m
+CONFIG_DVB_MT352=m
+CONFIG_DVB_ZL10353=m
+CONFIG_DVB_DIB3000MB=m
+CONFIG_DVB_DIB3000MC=m
+CONFIG_DVB_DIB7000M=m
+CONFIG_DVB_DIB7000P=m
+
+#
+# DVB-C (cable) frontends
+#
+CONFIG_DVB_VES1820=m
+# CONFIG_DVB_TDA10021 is not set
+CONFIG_DVB_STV0297=m
+
+#
+# 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=m
+
+#
+# Tuners/PLL support
+#
+CONFIG_DVB_PLL=m
+CONFIG_DVB_TDA826X=m
+CONFIG_DVB_TUNER_MT2060=m
+CONFIG_DVB_TUNER_LGH06XF=m
+
+#
+# Miscellaneous devices
+#
+CONFIG_DVB_LNBP21=m
+# CONFIG_DVB_ISL6421 is not set
+# CONFIG_DVB_TUA6100 is not set
+CONFIG_VIDEO_TUNER=m
+CONFIG_VIDEO_TVEEPROM=m
+CONFIG_USB_DABUSB=m
+
+#
+# Graphics support
+#
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+CONFIG_SOUND=m
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+CONFIG_SND_HWDEP=m
+CONFIG_SND_RAWMIDI=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=y
+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_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
+
+#
+# ALSA ARM devices
+#
+
+#
+# USB devices
+#
+CONFIG_SND_USB_AUDIO=m
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+
+#
+# HID Devices
+#
+CONFIG_HID=m
+
+#
+# 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_BANDWIDTH is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_SPLIT_ISO=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+# CONFIG_USB_ISP116X_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN 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=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=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_DPCM=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_STORAGE_ALAUDA=y
+CONFIG_USB_STORAGE_KARMA=y
+CONFIG_USB_LIBUSUAL=y
+
+#
+# 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
+# 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=m
+CONFIG_USB_XPAD=m
+CONFIG_USB_ATI_REMOTE=m
+CONFIG_USB_ATI_REMOTE2=m
+CONFIG_USB_KEYSPAN_REMOTE=m
+# CONFIG_USB_APPLETOUCH is not set
+
+#
+# USB Imaging devices
+#
+CONFIG_USB_MDC800=m
+CONFIG_USB_MICROTEK=m
+
+#
+# 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_CDCETHER=m
+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=m
+CONFIG_USB_NET_CDC_SUBSET=m
+CONFIG_USB_ALI_M5632=y
+CONFIG_USB_AN2720=y
+CONFIG_USB_BELKIN=y
+CONFIG_USB_ARMLINUX=y
+CONFIG_USB_EPSON2888=y
+CONFIG_USB_NET_ZAURUS=m
+# 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=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 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 is not set
+# 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=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=m
+CONFIG_USB_SERIAL_OMNINET=m
+# CONFIG_USB_SERIAL_DEBUG is not set
+CONFIG_USB_EZUSB=y
+
+#
+# USB Miscellaneous drivers
+#
+CONFIG_USB_EMI62=m
+CONFIG_USB_EMI26=m
+CONFIG_USB_ADUTUX=m
+CONFIG_USB_AUERSWALD=m
+CONFIG_USB_RIO500=m
+CONFIG_USB_LEGOTOWER=m
+CONFIG_USB_LCD=m
+CONFIG_USB_LED=m
+CONFIG_USB_CYPRESS_CY7C63=m
+CONFIG_USB_CYTHERM=m
+CONFIG_USB_PHIDGET=m
+CONFIG_USB_PHIDGETKIT=m
+CONFIG_USB_PHIDGETMOTORCONTROL=m
+CONFIG_USB_PHIDGETSERVO=m
+CONFIG_USB_IDMOUSE=m
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+CONFIG_USB_LD=m
+CONFIG_USB_TRANCEVIBRATOR=m
+# 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 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_X1205 is not set
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+CONFIG_RTC_DRV_RS5C372=y
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_TEST is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=m
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+# CONFIG_EXT2_FS_SECURITY is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=m
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+# 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=m
+CONFIG_REISERFS_FS=m
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_REISERFS_FS_XATTR is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=m
+CONFIG_XFS_QUOTA=y
+# CONFIG_XFS_SECURITY is not set
+CONFIG_XFS_POSIX_ACL=y
+# CONFIG_XFS_RT is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+CONFIG_MINIX_FS=m
+CONFIG_ROMFS_FS=m
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+CONFIG_QUOTACTL=y
+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 is not set
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+CONFIG_NTFS_FS=m
+# CONFIG_NTFS_DEBUG is not set
+CONFIG_NTFS_RW=y
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+CONFIG_CONFIGFS_FS=y
+
+#
+# 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=y
+CONFIG_JFFS2_FS_POSIX_ACL=y
+CONFIG_JFFS2_FS_SECURITY=y
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+CONFIG_CRAMFS=m
+# 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 is not set
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
+CONFIG_NFSD_V4=y
+CONFIG_NFSD_TCP=y
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
+CONFIG_SUNRPC_GSS=m
+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 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=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=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+# 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=y
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+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 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_LOG_BUF_SHIFT=14
+# 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
+
+#
+# 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_XCBC is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+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=y
+# CONFIG_CRYPTO_LRW is not set
+CONFIG_CRYPTO_DES=y
+# 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_TEST is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
+CONFIG_IOMAP_COPY=y
diff --git a/recipes/linux/linux/n2100/n2100-r8169-parity.patch b/recipes/linux/linux/n2100/n2100-r8169-parity.patch
new file mode 100644
index 0000000000..aeaeee9ff7
--- /dev/null
+++ b/recipes/linux/linux/n2100/n2100-r8169-parity.patch
@@ -0,0 +1,39 @@
+http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=4058/1
+
+From: Lennert Buytenhek
+
+On the n2100, both onboard r8169 ports exhibit PCI parity problems.
+Set the ->broken_parity_status flag for both ports so that the r8169
+drivers knows it should ignore error interrupts.
+
+
+--- linux-2.6.19.orig/arch/arm/mach-iop32x/n2100.c
++++ linux-2.6.19/arch/arm/mach-iop32x/n2100.c
+@@ -123,9 +123,26 @@ static struct hw_pci n2100_pci __initdat
+
+ static int __init n2100_pci_init(void)
+ {
+- if (machine_is_n2100())
++ if (machine_is_n2100()) {
++ int i;
++
+ pci_common_init(&n2100_pci);
+
++ /*
++ * Both r8169 chips on the n2100 exhibit PCI parity
++ * problems. Set the ->broken_parity_status flag for
++ * both ports so that the r8169 driver knows it should
++ * ignore error interrupts.
++ */
++ for (i = 1; i <= 2; i++) {
++ struct pci_dev *dev;
++
++ dev = pci_get_bus_and_slot(0, PCI_DEVFN(i, 0));
++ if (dev != NULL)
++ dev->broken_parity_status = 1;
++ }
++ }
++
+ return 0;
+ }
+
diff --git a/recipes/linux/linux/n2100/rtc-rs5c372-n2100.patch b/recipes/linux/linux/n2100/rtc-rs5c372-n2100.patch
new file mode 100644
index 0000000000..8849312a44
--- /dev/null
+++ b/recipes/linux/linux/n2100/rtc-rs5c372-n2100.patch
@@ -0,0 +1,13 @@
+Autodetect the RTC chip.
+
+--- a/drivers/rtc/rtc-rs5c372.c
++++ b/drivers/rtc/rtc-rs5c372.c
+@@ -16,7 +16,7 @@ #include <linux/bcd.h>
+ #define DRV_VERSION "0.3"
+
+ /* Addresses to scan */
+-static unsigned short normal_i2c[] = { /* 0x32,*/ I2C_CLIENT_END };
++static unsigned short normal_i2c[] = { 0x32, I2C_CLIENT_END };
+
+ /* Insmod parameters */
+ I2C_CLIENT_INSMOD;
diff --git a/recipes/linux/linux/patch-2.6.28-gc b/recipes/linux/linux/patch-2.6.28-gc
new file mode 100644
index 0000000000..e13666396b
--- /dev/null
+++ b/recipes/linux/linux/patch-2.6.28-gc
@@ -0,0 +1,32569 @@
+diff --git a/Documentation/exi.txt b/Documentation/exi.txt
+new file mode 100644
+index 0000000..a330c56
+--- /dev/null
++++ b/Documentation/exi.txt
+@@ -0,0 +1,81 @@
++The Expansion Interface (EXI)
++-----------------------------
++
++[Introductory information goes here...]
++
++
++Device drivers
++--------------
++
++Outlined below is the recommended practice when writing EXI device drivers.
++
++The bus driver already handles quite an amount of stuff, although some of
++it might have to be implemented by individual device drivers. If in doubt,
++see include/linux/exi.h.
++
++
++Registration
++------------
++
++Declare a struct exi_driver. Initialize at least the name, id_table,
++probe and remove fields:
++
++
++ static struct exi_device_id frob_id_tbl[] __devinitdata = {
++ { .dev_id = EXI_ID_FROB0, },
++ { .dev_id = EXI_ID_FROB1, },
++ { .dev_id = EXI_ID_FROB2, },
++ };
++
++ static struct exi_driver frob_driver = {
++ .name = "frob",
++ .id_table = frob_id_tbl,
++ .probe = frob_probe,
++ .remove = __devexit_p(frob_remove),
++ };
++
++
++`name' distinguishes the driver from others registered with the bus.
++It should be short, unique, yet remain informative.
++
++`id_table' is a pointer to a table of device IDs the driver claims to
++support. These should be taken directly from include/linux/exi_ids.h.
++This table should be marked __devinitdata.
++
++`probe' is a pointer to a function that's called once the driver is bound
++to a device it claims to support. This should be marked __devinit.
++
++`remove' is a pointer to a function that's called when either the driver
++unregisters with the bus, or a device bound to that specific driver is
++physically unplugged from the bus. This should be marked __devexit and
++created with __devexit_p().
++
++From within the driver's initialization function, register the driver with
++the bus by calling exi_driver_register() with the driver structure declared
++previously:
++
++ static int __init frob_init(void)
++ {
++ return exi_driver_register(&frob_driver);
++ }
++
++
++Deregistration
++--------------
++
++If the driver may be compiled as a loadable kernel module, then all you
++have to do is call exi_driver_unregister() in the driver's exit function:
++
++ static void __exit frob_exit(void)
++ {
++ exi_driver_unregister(&frob_driver);
++ }
++
++Device Private Data
++-------------------
++
++The functions exi_set_drvdata()/exi_get_drvdata() are available for the
++sole purpose of setting and getting driver private data for an EXI device.
++These are simply helpers around the driver-model functions that do the
++actual work. Use them. That way, you don't have to worry (or worry less)
++about changes to the driver-model API.
+diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
+index 525c13a..79074d6 100644
+--- a/arch/powerpc/Kconfig
++++ b/arch/powerpc/Kconfig
+@@ -584,7 +584,7 @@ config PPC_PCI_CHOICE
+ config PCI
+ bool "PCI support" if PPC_PCI_CHOICE
+ default y if !40x && !CPM2 && !8xx && !PPC_83xx \
+- && !PPC_85xx && !PPC_86xx
++ && !PPC_85xx && !PPC_86xx && !GAMECUBE_COMMON
+ default PCI_PERMEDIA if !4xx && !CPM2 && !8xx
+ default PCI_QSPAN if !4xx && !CPM2 && 8xx
+ select ARCH_SUPPORTS_MSI
+diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
+index 15eb278..fc6a8da 100644
+--- a/arch/powerpc/Kconfig.debug
++++ b/arch/powerpc/Kconfig.debug
+@@ -224,6 +224,14 @@ config PPC_EARLY_DEBUG_CPM
+ using a CPM-based serial port. This assumes that the bootwrapper
+ has run, and set up the CPM in a particular way.
+
++config PPC_EARLY_DEBUG_USBGECKO
++ bool "Early debugging through the USB Gecko adapter"
++ depends on GAMECUBE_COMMON
++ select USBGECKO_UDBG
++ help
++ Select this to enable early debugging for Nintendo GameCube/Wii
++ consoles via an external USB Gecko adapter.
++
+ endchoice
+
+ config PPC_EARLY_DEBUG_44x_PHYSLOW
+diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
+index 3d3daa6..d685ea2 100644
+--- a/arch/powerpc/boot/Makefile
++++ b/arch/powerpc/boot/Makefile
+@@ -60,17 +60,16 @@ src-wlib := string.S crt0.S crtsavres.S stdio.c main.c \
+ gunzip_util.c elf_util.c $(zlib) devtree.c oflib.c ofconsole.c \
+ 4xx.c ebony.c mv64x60.c mpsc.c mv64x60_i2c.c cuboot.c bamboo.c \
+ cpm-serial.c stdlib.c mpc52xx-psc.c planetcore.c uartlite.c \
+- fsl-soc.c mpc8xx.c pq2.c
++ fsl-soc.c mpc8xx.c pq2.c ugecon.c
+ src-plat := of.c cuboot-52xx.c cuboot-824x.c cuboot-83xx.c cuboot-85xx.c holly.c \
+ cuboot-ebony.c treeboot-ebony.c prpmc2800.c \
+- ps3-head.S ps3-hvcall.S ps3.c treeboot-bamboo.c cuboot-8xx.c \
+ cuboot-pq2.c cuboot-sequoia.c treeboot-walnut.c \
+ cuboot-bamboo.c cuboot-mpc7448hpc2.c cuboot-taishan.c \
+ fixed-head.S ep88xc.c ep405.c cuboot-c2k.c \
+ cuboot-katmai.c cuboot-rainier.c redboot-8xx.c ep8248e.c \
+ cuboot-warp.c cuboot-85xx-cpm2.c cuboot-yosemite.c simpleboot.c \
+ virtex405-head.S virtex.c redboot-83xx.c cuboot-sam440ep.c \
+- cuboot-acadia.c
++ cuboot-acadia.c gamecube.c wii.c
+ src-boot := $(src-wlib) $(src-plat) empty.c
+
+ src-boot := $(addprefix $(obj)/, $(src-boot))
+@@ -272,6 +271,8 @@ image-$(CONFIG_KSI8560) += cuImage.ksi8560
+ image-$(CONFIG_STORCENTER) += cuImage.storcenter
+ image-$(CONFIG_MPC7448HPC2) += cuImage.mpc7448hpc2
+ image-$(CONFIG_PPC_C2K) += cuImage.c2k
++image-$(CONFIG_GAMECUBE) += dtbImage.gamecube
++image-$(CONFIG_WII) += dtbImage.wii
+
+ # For 32-bit powermacs, build the COFF and miboot images
+ # as well as the ELF images.
+diff --git a/arch/powerpc/boot/dts/gamecube.dts b/arch/powerpc/boot/dts/gamecube.dts
+new file mode 100644
+index 0000000..c45c97e
+--- /dev/null
++++ b/arch/powerpc/boot/dts/gamecube.dts
+@@ -0,0 +1,129 @@
++/*
++ * arch/powerpc/boot/dts/gamecube.dts
++ *
++ * Nintendo GameCube platform device tree source
++ * Copyright (C) 2007-2009 The GameCube Linux Team
++ * Copyright (C) 2007,2008,2009 Albert Herranz
++ *
++ * 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.
++ *
++ */
++
++/ {
++ model = "NintendoGameCube";
++ compatible = "nintendo,gamecube";
++ #address-cells = <1>;
++ #size-cells = <1>;
++
++ chosen {
++ bootargs = "root=/dev/nfs nfsroot=192.168.001.253:/nfsroot/cube,nfsvers=3,udp ip=on video=gcn-vifb:tv=auto force_keyboard_port=4";
++ linux,stdout-path = "/exi@0c006800/usbgecko@0c006814";
++ };
++
++ memory {
++ device_type = "memory";
++ /* 24M minus framebuffer memory area (640*576*2*2) */
++ reg = <00000000 01698000>;
++ };
++
++ cpus {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ PowerPC,gekko@0 {
++ device_type = "cpu";
++ reg = <0>;
++ clock-frequency = <1cf7c580>; /* 486MHz */
++ bus-frequency = <9a7ec80>; /* 162MHz core-to-bus 3x */
++ timebase-frequency = <269fb20>; /* 162MHz / 4 */
++ /* Following required by dtc but not used */
++ i-cache-line-size = <20>;
++ d-cache-line-size = <20>;
++ i-cache-size = <8000>;
++ d-cache-size = <8000>;
++ };
++ };
++
++ pic: pic@0c003000 {
++ #interrupt-cells = <1>;
++ compatible = "nintendo,flipper-pic";
++ reg = <0c003000 8>;
++ interrupt-controller;
++ };
++
++ /* External Interface bus */
++ exi@0c006800 {
++ #address-cells = <1>;
++ #size-cells = <1>;
++ compatible = "nintendo,flipper-exi";
++ reg = <0c006800 40>;
++ interrupts = <04>;
++ interrupt-parent = <&pic>;
++
++ udbg_console: usbgecko@0c006814 {
++ compatible = "usbgecko,usbgecko";
++ reg = <0c006814 14>;
++ virtual-reg = <cc006814>;
++ };
++ };
++
++ /* devices contained int the flipper chipset */
++ soc {
++ #address-cells = <1>;
++ #size-cells = <1>;
++ #interrupt-cells = <1>;
++ model = "flipper";
++ compatible = "nintendo,flipper";
++ clock-frequency = <9a7ec80>; /* 162MHz */
++ ranges = <0c000000 0c000000 00010000>;
++
++ video@0c002000 {
++ compatible = "nintendo,flipper-video";
++ reg = <0c002000 100>;
++ interrupts = <08>;
++ interrupt-parent = <&pic>;
++ xfb-start = <01698000>; /* end-of-ram - xfb-size */
++ xfb-size = <168000>;
++ };
++
++ resetswitch@0c003000 {
++ compatible = "nintendo,flipper-resetswitch";
++ reg = <0c003000 4>;
++ interrupts = <01>;
++ interrupt-parent = <&pic>;
++ };
++
++ auxram@0c005000 {
++ compatible = "nintendo,flipper-auxram";
++ reg = <0c005000 200>; /* DSP */
++ interrupts = <06>;
++ interrupt-parent = <&pic>;
++ };
++
++ audio@0c005000 {
++ compatible = "nintendo,flipper-audio";
++ reg = <0c005000 200 /* DSP */
++ 0c006c00 20>; /* AI */
++ interrupts = <06>;
++ interrupt-parent = <&pic>;
++ };
++
++ disk@0c006000 {
++ compatible = "nintendo,flipper-disk";
++ reg = <0c006000 40>;
++ interrupts = <02>;
++ interrupt-parent = <&pic>;
++ };
++
++ serial@0c006400 {
++ compatible = "nintendo,flipper-serial";
++ reg = <0c006400 100>;
++ interrupts = <03>;
++ interrupt-parent = <&pic>;
++ };
++ };
++};
++
+diff --git a/arch/powerpc/boot/dts/wii.dts b/arch/powerpc/boot/dts/wii.dts
+new file mode 100644
+index 0000000..fdfbc2c
+--- /dev/null
++++ b/arch/powerpc/boot/dts/wii.dts
+@@ -0,0 +1,162 @@
++/*
++ * arch/powerpc/boot/dts/wii.dts
++ *
++ * Nintendo Wii platform device tree source
++ * Copyright (C) 2008-2009 The GameCube Linux Team
++ * Copyright (C) 2008,2009 Albert Herranz
++ *
++ * 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.
++ *
++ */
++
++
++/memreserve/ 01698000-017fffff; /* framebuffer, see video@0c002000 */
++/memreserve/ 01800000-0fffffff; /* memory hole */
++/memreserve/ 10000000-10003fff; /* DSP */
++
++/ {
++ model = "NintendoWii";
++ compatible = "nintendo,wii";
++ #address-cells = <1>;
++ #size-cells = <1>;
++
++ chosen {
++ /* ramdisk */
++ /* bootargs = "nobats root=/dev/ram0 video=gcnfb:tv=NTSC ip=on force_keyboard_port=4"; */
++
++ /* nfsroot */
++ /* bootargs = "nobats root=/dev/nfs nfsroot=192.168.001.253:/nfsroot/cube ip=on video=gcnfb:tv=NTSC force_keyboard_port=4"; */
++
++ /* root filesystem on 2nd partition of SD card, whiite style */
++ bootargs = "nobats root=/dev/rvlsda2 video=gcnfb:tv=NTSC force_keyboard_port=4 placeholder_for_additional_kernel_options_targetted_at_hexedit_lovers";
++ linux,stdout-path = "/exi@0d006800/usbgecko@0d006814";
++ };
++
++ memory {
++ device_type = "memory";
++ /* mem1 + hole + mem2 - ioh */
++ reg = <00000000 133e0000>;
++ };
++
++ cpus {
++ #cpus = <1>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ PowerPC,broadway@0 {
++ device_type = "cpu";
++ reg = <0>;
++ clock-frequency = <2b73a840>; /* 729MHz */
++ bus-frequency = <e7be2c0>; /* 243MHz core-to-bus 3x */
++ timebase-frequency = <39ef8b0>; /* 243MHz / 4 */
++ /* Following required by dtc but not used */
++ i-cache-line-size = <20>;
++ d-cache-line-size = <20>;
++ i-cache-size = <8000>;
++ d-cache-size = <8000>;
++ };
++ };
++
++ pic: pic@0c003000 {
++ #interrupt-cells = <1>;
++ compatible = "nintendo,flipper-pic";
++ reg = <0c003000 8>;
++ interrupt-controller;
++ };
++
++ /* External Interface bus */
++ exi@0d006800 {
++ #address-cells = <1>;
++ #size-cells = <1>;
++ compatible = "nintendo,hollywood-exi";
++ reg = <0d006800 40>;
++ interrupts = <04>;
++ interrupt-parent = <&pic>;
++
++ udbg_console: usbgecko@0d006814 {
++ compatible = "usbgecko,usbgecko";
++ reg = <0d006814 14>;
++ virtual-reg = <cd006814>;
++ };
++ };
++
++ /* devices contained in the hollywood chipset */
++ soc {
++ #address-cells = <1>;
++ #size-cells = <1>;
++ #interrupt-cells = <1>;
++ model = "hollywood";
++ compatible = "nintendo,hollywood";
++ clock-frequency = <e7be2c0>; /* 243MHz */
++ ranges = <0c000000 0c000000 00010000
++ 0d000000 0d000000 00010000
++ 0d800000 0d800000 00001000
++ 133e0000 133e0000 00020000>;
++
++ video@0c002000 {
++ compatible = "nintendo,hollywood-video";
++ reg = <0c002000 100>;
++ interrupts = <08>;
++ interrupt-parent = <&pic>;
++ xfb-start = <01698000>; /* end-of-mem1 - xfb-size */
++ xfb-size = <168000>; /* 640x576x2 x 2 bytes */
++ };
++
++ resetswitch@0c003000 {
++ compatible = "nintendo,hollywood-resetswitch";
++ reg = <0c003000 4>;
++ interrupts = <01>;
++ interrupt-parent = <&pic>;
++ };
++
++ audio@0c005000 {
++ compatible = "nintendo,hollywood-audio";
++ reg = <0c005000 200 /* DSP */
++ 0d006c00 20>; /* AI */
++ interrupts = <06>;
++ interrupt-parent = <&pic>;
++ };
++
++ serial@0d006400 {
++ compatible = "nintendo,hollywood-serial";
++ reg = <0d006400 100>;
++ interrupts = <03>;
++ interrupt-parent = <&pic>;
++ };
++
++ gpio0: starlet-gpio@0d8000c0 {
++ compatible = "nintendo,starlet-gpio";
++ reg = <0d8000c0 4>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ };
++
++ starlet-ipc@0d000000 {
++ compatible = "nintendo,starlet-ipc";
++ reg = <0d000000 40 /* IPC */
++ 133e0000 20000>; /* MEM2 ioh 128K */
++ interrupts = <0e>;
++ interrupt-parent = <&pic>;
++
++ };
++
++ starlet-es {
++ compatible = "nintendo,starlet-es";
++ };
++
++ starlet-sd {
++ compatible = "nintendo,starlet-sd";
++ };
++
++ starlet-keyboard {
++ compatible = "nintendo,starlet-keyboard";
++ };
++
++ starlet-hcd {
++ compatible = "nintendo,starlet-hcd";
++ };
++ };
++};
+diff --git a/arch/powerpc/boot/gamecube.c b/arch/powerpc/boot/gamecube.c
+new file mode 100644
+index 0000000..f3e3c0d
+--- /dev/null
++++ b/arch/powerpc/boot/gamecube.c
+@@ -0,0 +1,77 @@
++/*
++ * arch/powerpc/boot/gamecube.c
++ *
++ * Nintendo GameCube/Wii platforms
++ * Copyright (C) 2004-2009 The GameCube Linux Team
++ * Copyright (C) 2008,2009 Albert Herranz
++ *
++ * 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 <stddef.h>
++#include "stdio.h"
++#include "types.h"
++#include "io.h"
++#include "ops.h"
++
++#include "ugecon.h"
++
++BSS_STACK(8192);
++
++/*
++ * We enter with the MMU enabled and some legacy memory mappings active.
++ *
++ * We leave the MMU enabled, but we switch to an identity mapped memory
++ * scheme as expected by the start code.
++ *
++ */
++asm ("\n\
++.text\n\
++.globl _zimage_start\n\
++_zimage_start:\n\
++\n\
++ isync\n\
++ /* IBAT3,DBAT3 for first 16Mbytes */\n\
++ li 8, 0x01ff /* 16MB */\n\
++ li 9, 0x0002 /* rw */\n\
++ mtspr 0x216, 8 /* IBAT3U */\n\
++ mtspr 0x217, 9 /* IBAT3L */\n\
++ mtspr 0x21e, 8 /* DBAT3U */\n\
++ mtspr 0x21f, 9 /* DBAT3L */\n\
++\n\
++ sync\n\
++ isync\n\
++\n\
++ li 3, 0\n\
++ li 4, 0\n\
++ li 5, 0\n\
++\n\
++ bcl- 20,4*cr7+so,1f\n\
++1:\n\
++ mflr 8\n\
++ clrlwi 8, 8, 3\n\
++ addi 8, 8, 2f - 1b\n\
++ mtlr 8\n\
++ blr\n\
++2:\n\
++ b _zimage_start_lib\n\
++");
++
++/*
++ *
++ */
++void platform_init(unsigned long r3, unsigned long r4, unsigned long r5)
++{
++ u32 heapsize = 16*1024*1024 - (u32)_end;
++
++ simple_alloc_init(_end, heapsize, 32, 64);
++ fdt_init(_dtb_start);
++
++ if (!ug_grab_io_base() && ug_is_adapter_present())
++ console_ops.write = ug_console_write;
++}
++
+diff --git a/arch/powerpc/boot/ugecon.c b/arch/powerpc/boot/ugecon.c
+new file mode 100644
+index 0000000..b485eab
+--- /dev/null
++++ b/arch/powerpc/boot/ugecon.c
+@@ -0,0 +1,128 @@
++/*
++ * arch/powerpc/boot/ugecon.c
++ *
++ * USB Gecko bootwrapper console.
++ * Copyright (C) 2008-2009 The GameCube Linux Team
++ * Copyright (C) 2008,2009 Albert Herranz
++ *
++ * 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 <stddef.h>
++#include "stdio.h"
++#include "types.h"
++#include "io.h"
++#include "ops.h"
++
++
++#define EXI_CLK_32MHZ 5
++
++#define EXI_CSR 0x00
++#define EXI_CSR_CLKMASK (0x7<<4)
++#define EXI_CSR_CLK_32MHZ (EXI_CLK_32MHZ<<4)
++#define EXI_CSR_CSMASK (0x7<<7)
++#define EXI_CSR_CS_0 (0x1<<7) /* Chip Select 001 */
++
++#define EXI_CR 0x0c
++#define EXI_CR_TSTART (1<<0)
++#define EXI_CR_WRITE (1<<2)
++#define EXI_CR_READ_WRITE (2<<2)
++#define EXI_CR_TLEN(len) (((len)-1)<<4)
++
++#define EXI_DATA 0x10
++
++
++/* virtual address base for input/output, retrieved from device tree */
++static void *ug_io_base;
++
++
++static u32 ug_io_transaction(u32 in)
++{
++ u32 *csr_reg = ug_io_base + EXI_CSR;
++ u32 *data_reg = ug_io_base + EXI_DATA;
++ u32 *cr_reg = ug_io_base + EXI_CR;
++ u32 csr, data, cr;
++
++ /* select */
++ csr = EXI_CSR_CLK_32MHZ | EXI_CSR_CS_0;
++ out_be32(csr_reg, csr);
++
++ /* read/write */
++ data = in;
++ out_be32(data_reg, data);
++ cr = EXI_CR_TLEN(2) | EXI_CR_READ_WRITE | EXI_CR_TSTART;
++ out_be32(cr_reg, cr);
++
++ while (in_be32(cr_reg) & EXI_CR_TSTART)
++ barrier();
++
++ /* deselect */
++ out_be32(csr_reg, 0);
++
++ data = in_be32(data_reg);
++ return data;
++}
++
++static int ug_is_txfifo_ready(void)
++{
++ return ug_io_transaction(0xc0000000) & 0x04000000;
++}
++
++static void ug_raw_putc(char ch)
++{
++ ug_io_transaction(0xb0000000 | (ch << 20));
++}
++
++static void ug_putc(char ch)
++{
++ int count = 16;
++
++ if (!ug_io_base)
++ return;
++
++ while (!ug_is_txfifo_ready() && count--)
++ barrier();
++ if (count)
++ ug_raw_putc(ch);
++}
++
++void ug_console_write(const char *buf, int len)
++{
++ char *b = (char *)buf;
++
++ while (len--) {
++ if (*b == '\n')
++ ug_putc('\r');
++ ug_putc(*b++);
++ }
++}
++
++int ug_is_adapter_present(void)
++{
++ if (!ug_io_base)
++ return 0;
++
++ return ug_io_transaction(0x90000000) == 0x04700000;
++}
++
++int ug_grab_io_base(void)
++{
++ u32 v;
++ void *devp;
++
++ devp = finddevice("/exi/usbgecko");
++ if (devp == NULL)
++ goto err_out;
++ if (getprop(devp, "virtual-reg", &v, sizeof(v)) != sizeof(v))
++ goto err_out;
++
++ ug_io_base = (u8 *)v;
++ return 0;
++
++err_out:
++ return -1;
++}
+diff --git a/arch/powerpc/boot/ugecon.h b/arch/powerpc/boot/ugecon.h
+new file mode 100644
+index 0000000..1fdb590
+--- /dev/null
++++ b/arch/powerpc/boot/ugecon.h
+@@ -0,0 +1,25 @@
++/*
++ * arch/powerpc/boot/ugecon.h
++ *
++ * USB Gecko early bootwrapper console.
++ * Copyright (C) 2008-2009 The GameCube Linux Team
++ * Copyright (C) 2008,2009 Albert Herranz
++ *
++ * 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.
++ *
++ */
++
++#ifndef __UGECON_H
++#define __UGECON_H
++
++extern int ug_grab_io_base(void);
++extern int ug_is_adapter_present(void);
++
++extern void ug_putc(char ch);
++extern void ug_console_write(const char *buf, int len);
++
++#endif /* __UGECON_H */
++
+diff --git a/arch/powerpc/boot/wii.c b/arch/powerpc/boot/wii.c
+new file mode 100644
+index 0000000..b702514
+--- /dev/null
++++ b/arch/powerpc/boot/wii.c
+@@ -0,0 +1,78 @@
++/*
++ * arch/powerpc/boot/wii.c
++ *
++ * Nintendo Wii platform
++ * Copyright (C) 2004-2009 The GameCube Linux Team
++ * Copyright (C) 2008,2009 Albert Herranz
++ *
++ * 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 <stddef.h>
++#include "stdio.h"
++#include "types.h"
++#include "io.h"
++#include "ops.h"
++
++#include "ugecon.h"
++
++
++BSS_STACK(8192);
++
++/*
++ * We enter with the MMU enabled and some legacy memory mappings active.
++ *
++ * We leave the MMU enabled, but we switch to an identity mapped memory
++ * scheme as expected by the start code.
++ *
++ */
++asm ("\n\
++.text\n\
++.globl _zimage_start\n\
++_zimage_start:\n\
++\n\
++ isync\n\
++ /* IBAT3,DBAT3 for first 16Mbytes */\n\
++ li 8, 0x01ff /* 16MB */\n\
++ li 9, 0x0002 /* rw */\n\
++ mtspr 0x216, 8 /* IBAT3U */\n\
++ mtspr 0x217, 9 /* IBAT3L */\n\
++ mtspr 0x21e, 8 /* DBAT3U */\n\
++ mtspr 0x21f, 9 /* DBAT3L */\n\
++\n\
++ sync\n\
++ isync\n\
++\n\
++ li 3, 0\n\
++ li 4, 0\n\
++ li 5, 0\n\
++\n\
++ bcl- 20,4*cr7+so,1f\n\
++1:\n\
++ mflr 8\n\
++ clrlwi 8, 8, 3\n\
++ addi 8, 8, 2f - 1b\n\
++ mtlr 8\n\
++ blr\n\
++2:\n\
++ b _zimage_start_lib\n\
++");
++
++/*
++ *
++ */
++void platform_init(unsigned long r3, unsigned long r4, unsigned long r5)
++{
++ u32 heapsize = 16*1024*1024 - (u32)_end;
++
++ simple_alloc_init(_end, heapsize, 32, 64);
++ fdt_init(_dtb_start);
++
++ if (!ug_grab_io_base() && ug_is_adapter_present())
++ console_ops.write = ug_console_write;
++}
++
+diff --git a/arch/powerpc/configs/gamecube_defconfig b/arch/powerpc/configs/gamecube_defconfig
+new file mode 100644
+index 0000000..7e3e549
+--- /dev/null
++++ b/arch/powerpc/configs/gamecube_defconfig
+@@ -0,0 +1,989 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.28
++# Mon Jan 12 20:23:50 2009
++#
++# CONFIG_PPC64 is not set
++
++#
++# Processor support
++#
++CONFIG_6xx=y
++# CONFIG_PPC_85xx is not set
++# CONFIG_PPC_8xx is not set
++# CONFIG_40x is not set
++# CONFIG_44x is not set
++# CONFIG_E200 is not set
++CONFIG_PPC_FPU=y
++# CONFIG_ALTIVEC is not set
++CONFIG_PPC_STD_MMU=y
++CONFIG_PPC_STD_MMU_32=y
++# CONFIG_PPC_MM_SLICES is not set
++# CONFIG_SMP is not set
++CONFIG_NOT_COHERENT_CACHE=y
++CONFIG_PPC32=y
++CONFIG_WORD_SIZE=32
++# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
++CONFIG_MMU=y
++CONFIG_GENERIC_CMOS_UPDATE=y
++CONFIG_GENERIC_TIME=y
++CONFIG_GENERIC_TIME_VSYSCALL=y
++CONFIG_GENERIC_CLOCKEVENTS=y
++CONFIG_GENERIC_HARDIRQS=y
++# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
++CONFIG_IRQ_PER_CPU=y
++CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_HAVE_LATENCYTOP_SUPPORT=y
++CONFIG_LOCKDEP_SUPPORT=y
++CONFIG_RWSEM_XCHGADD_ALGORITHM=y
++CONFIG_ARCH_HAS_ILOG2_U32=y
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_GENERIC_FIND_NEXT_BIT=y
++# CONFIG_ARCH_NO_VIRT_TO_BUS is not set
++CONFIG_PPC=y
++CONFIG_EARLY_PRINTK=y
++CONFIG_GENERIC_NVRAM=y
++CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
++CONFIG_ARCH_MAY_HAVE_PC_FDC=y
++CONFIG_PPC_OF=y
++CONFIG_OF=y
++# CONFIG_PPC_UDBG_16550 is not set
++# CONFIG_GENERIC_TBSYNC is not set
++CONFIG_AUDIT_ARCH=y
++CONFIG_GENERIC_BUG=y
++# CONFIG_DEFAULT_UIMAGE is not set
++# CONFIG_PPC_DCR_NATIVE is not set
++# CONFIG_PPC_DCR_MMIO is not set
++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="-isobel-gcn"
++CONFIG_LOCALVERSION_AUTO=y
++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_AUDIT is not set
++CONFIG_IKCONFIG=y
++CONFIG_IKCONFIG_PROC=y
++CONFIG_LOG_BUF_SHIFT=14
++# CONFIG_CGROUPS is not set
++CONFIG_GROUP_SCHED=y
++CONFIG_FAIR_GROUP_SCHED=y
++# CONFIG_RT_GROUP_SCHED is not set
++CONFIG_USER_SCHED=y
++# CONFIG_CGROUP_SCHED is not set
++CONFIG_SYSFS_DEPRECATED=y
++CONFIG_SYSFS_DEPRECATED_V2=y
++# CONFIG_RELAY is not set
++# CONFIG_NAMESPACES is not set
++CONFIG_BLK_DEV_INITRD=y
++CONFIG_INITRAMFS_SOURCE=""
++# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
++CONFIG_SYSCTL=y
++CONFIG_EMBEDDED=y
++CONFIG_SYSCTL_SYSCALL=y
++CONFIG_KALLSYMS=y
++CONFIG_KALLSYMS_ALL=y
++# CONFIG_KALLSYMS_EXTRA_PASS is not set
++CONFIG_HOTPLUG=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++# CONFIG_ELF_CORE is not set
++CONFIG_COMPAT_BRK=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_ANON_INODES=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_TIMERFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_AIO=y
++# CONFIG_VM_EVENT_COUNTERS is not set
++CONFIG_SLAB=y
++# CONFIG_SLUB is not set
++# CONFIG_SLOB is not set
++# CONFIG_PROFILING is not set
++CONFIG_TRACEPOINTS=y
++CONFIG_MARKERS=y
++CONFIG_HAVE_OPROFILE=y
++# CONFIG_KPROBES is not set
++CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
++CONFIG_HAVE_IOREMAP_PROT=y
++CONFIG_HAVE_KPROBES=y
++CONFIG_HAVE_KRETPROBES=y
++CONFIG_HAVE_ARCH_TRACEHOOK=y
++# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
++CONFIG_SLABINFO=y
++CONFIG_RT_MUTEXES=y
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++# CONFIG_MODULE_FORCE_LOAD is not set
++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=y
++# CONFIG_BLK_DEV_IO_TRACE is not set
++# CONFIG_LSF is not set
++# CONFIG_BLK_DEV_BSG is not set
++# CONFIG_BLK_DEV_INTEGRITY is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++CONFIG_DEFAULT_AS=y
++# CONFIG_DEFAULT_DEADLINE is not set
++# CONFIG_DEFAULT_CFQ is not set
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="anticipatory"
++CONFIG_CLASSIC_RCU=y
++# CONFIG_FREEZER is not set
++
++#
++# Platform support
++#
++CONFIG_PPC_MULTIPLATFORM=y
++CONFIG_CLASSIC32=y
++# CONFIG_PPC_CHRP is not set
++# CONFIG_MPC5121_ADS is not set
++# CONFIG_MPC5121_GENERIC is not set
++# CONFIG_PPC_MPC52xx is not set
++# CONFIG_PPC_PMAC is not set
++# CONFIG_PPC_CELL is not set
++# CONFIG_PPC_CELL_NATIVE is not set
++# CONFIG_PPC_82xx is not set
++# CONFIG_PQ2ADS is not set
++# CONFIG_PPC_83xx is not set
++# CONFIG_PPC_86xx is not set
++CONFIG_EMBEDDED6xx=y
++# CONFIG_LINKSTATION is not set
++# CONFIG_STORCENTER is not set
++# CONFIG_MPC7448HPC2 is not set
++# CONFIG_PPC_HOLLY is not set
++# CONFIG_PPC_PRPMC2800 is not set
++# CONFIG_PPC_C2K is not set
++CONFIG_GAMECUBE=y
++# CONFIG_WII is not set
++CONFIG_FLIPPER_PIC=y
++CONFIG_GAMECUBE_COMMON=y
++CONFIG_GAMECUBE_RSW=y
++CONFIG_GAMECUBE_UDBG=y
++CONFIG_USBGECKO_UDBG=y
++# CONFIG_GAMECUBE_VIDEO_UDBG is not set
++# CONFIG_IPIC is not set
++# CONFIG_MPIC is not set
++# CONFIG_MPIC_WEIRD is not set
++# CONFIG_PPC_I8259 is not set
++# CONFIG_PPC_RTAS is not set
++# CONFIG_MMIO_NVRAM is not set
++# CONFIG_PPC_MPC106 is not set
++# CONFIG_PPC_970_NAP is not set
++# CONFIG_PPC_INDIRECT_IO is not set
++# CONFIG_GENERIC_IOMAP is not set
++# CONFIG_CPU_FREQ is not set
++# CONFIG_TAU is not set
++# CONFIG_FSL_ULI1575 is not set
++
++#
++# Kernel options
++#
++# CONFIG_HIGHMEM is not set
++# CONFIG_NO_HZ is not set
++# CONFIG_HIGH_RES_TIMERS is not set
++CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
++# CONFIG_HZ_100 is not set
++CONFIG_HZ_250=y
++# CONFIG_HZ_300 is not set
++# CONFIG_HZ_1000 is not set
++CONFIG_HZ=250
++# CONFIG_SCHED_HRTICK is not set
++# CONFIG_PREEMPT_NONE is not set
++# CONFIG_PREEMPT_VOLUNTARY is not set
++CONFIG_PREEMPT=y
++# CONFIG_PREEMPT_RCU is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
++# CONFIG_HAVE_AOUT is not set
++CONFIG_BINFMT_MISC=m
++# CONFIG_IOMMU_HELPER is not set
++CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
++CONFIG_ARCH_HAS_WALK_MEMORY=y
++CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
++CONFIG_KEXEC=y
++CONFIG_ARCH_FLATMEM_ENABLE=y
++CONFIG_ARCH_POPULATES_NODE_MAP=y
++CONFIG_SELECT_MEMORY_MODEL=y
++CONFIG_FLATMEM_MANUAL=y
++# CONFIG_DISCONTIGMEM_MANUAL is not set
++# CONFIG_SPARSEMEM_MANUAL is not set
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++CONFIG_PAGEFLAGS_EXTENDED=y
++CONFIG_SPLIT_PTLOCK_CPUS=4
++# CONFIG_MIGRATION is not set
++# CONFIG_RESOURCES_64BIT is not set
++# CONFIG_PHYS_ADDR_T_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=1
++CONFIG_BOUNCE=y
++CONFIG_VIRT_TO_BUS=y
++CONFIG_UNEVICTABLE_LRU=y
++CONFIG_FORCE_MAX_ZONEORDER=11
++CONFIG_PROC_DEVICETREE=y
++# CONFIG_CMDLINE_BOOL is not set
++CONFIG_EXTRA_TARGETS=""
++# CONFIG_PM is not set
++# CONFIG_SECCOMP is not set
++CONFIG_ISA_DMA_API=y
++
++#
++# Bus options
++#
++CONFIG_ZONE_DMA=y
++CONFIG_GENERIC_ISA_DMA=y
++# CONFIG_PCI is not set
++# CONFIG_PCI_DOMAINS is not set
++# CONFIG_PCI_SYSCALL is not set
++# CONFIG_ARCH_SUPPORTS_MSI is not set
++# CONFIG_PCCARD is not set
++# CONFIG_HAS_RAPIDIO is not set
++
++#
++# Advanced setup
++#
++CONFIG_ADVANCED_OPTIONS=y
++# CONFIG_LOWMEM_SIZE_BOOL is not set
++CONFIG_LOWMEM_SIZE=0x30000000
++# CONFIG_PAGE_OFFSET_BOOL is not set
++CONFIG_PAGE_OFFSET=0xc0000000
++# CONFIG_KERNEL_START_BOOL is not set
++CONFIG_KERNEL_START=0xc0000000
++CONFIG_PHYSICAL_START=0x00000000
++# CONFIG_TASK_SIZE_BOOL is not set
++CONFIG_TASK_SIZE=0xc0000000
++# CONFIG_CONSISTENT_START_BOOL is not set
++CONFIG_CONSISTENT_START=0xff100000
++# CONFIG_CONSISTENT_SIZE_BOOL is not set
++CONFIG_CONSISTENT_SIZE=0x00200000
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++CONFIG_UNIX=y
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_FIB_HASH=y
++CONFIG_IP_PNP=y
++CONFIG_IP_PNP_DHCP=y
++CONFIG_IP_PNP_BOOTP=y
++CONFIG_IP_PNP_RARP=y
++# 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 is not set
++# CONFIG_INET_XFRM_MODE_TUNNEL is not set
++# CONFIG_INET_XFRM_MODE_BEET is not set
++# CONFIG_INET_LRO is not set
++# CONFIG_INET_DIAG is not set
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++# CONFIG_IPV6 is not set
++# CONFIG_NETWORK_SECMARK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_NET_DSA is not set
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_DECNET is not set
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_ECONET is not set
++# CONFIG_WAN_ROUTER is not set
++# CONFIG_NET_SCHED is not set
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_CAN is not set
++# CONFIG_IRDA is not set
++# CONFIG_BT is not set
++# CONFIG_AF_RXRPC is not set
++# CONFIG_PHONET is not set
++# CONFIG_WIRELESS is not set
++# CONFIG_RFKILL is not set
++# CONFIG_NET_9P is not set
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++# CONFIG_STANDALONE is not set
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++# CONFIG_FW_LOADER is not set
++# 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 is not set
++CONFIG_OF_DEVICE=y
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_DEV_FD is not set
++CONFIG_GAMECUBE_DI=y
++CONFIG_GAMECUBE_ARAM=y
++CONFIG_GAMECUBE_SD=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=m
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_COUNT=2
++CONFIG_BLK_DEV_RAM_SIZE=4096
++# CONFIG_BLK_DEV_XIP is not set
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++# CONFIG_BLK_DEV_HD is not set
++CONFIG_MISC_DEVICES=y
++CONFIG_GAMECUBE_GQR=y
++# CONFIG_EEPROM_93CX6 is not set
++# CONFIG_ENCLOSURE_SERVICES is not set
++# CONFIG_C2PORT is not set
++CONFIG_HAVE_IDE=y
++# CONFIG_IDE is not set
++
++#
++# SCSI device support
++#
++# CONFIG_RAID_ATTRS is not set
++# CONFIG_SCSI is not set
++# CONFIG_SCSI_DMA is not set
++# CONFIG_SCSI_NETLINK is not set
++# CONFIG_ATA is not set
++# CONFIG_MD is not set
++# CONFIG_MACINTOSH_DRIVERS is not set
++CONFIG_NETDEVICES=y
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_MACVLAN is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_VETH is not set
++# CONFIG_PHYLIB is not set
++CONFIG_NET_ETHERNET=y
++# CONFIG_MII is not set
++CONFIG_GAMECUBE_BBA=y
++# CONFIG_IBM_NEW_EMAC_ZMII is not set
++# CONFIG_IBM_NEW_EMAC_RGMII is not set
++# CONFIG_IBM_NEW_EMAC_TAH is not set
++# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
++# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
++# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
++# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
++# CONFIG_B44 is not set
++# CONFIG_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
++# CONFIG_IWLWIFI_LEDS is not set
++# CONFIG_WAN is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP 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
++# CONFIG_PHONE 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 is not set
++CONFIG_INPUT_JOYDEV=y
++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_INPUT_MOUSE 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_ZHENHUA is not set
++# CONFIG_JOYSTICK_JOYDUMP is not set
++# CONFIG_INPUT_TABLET is not set
++# CONFIG_INPUT_TOUCHSCREEN is not set
++# CONFIG_INPUT_MISC is not set
++
++#
++# Hardware I/O ports
++#
++CONFIG_SERIO=y
++# CONFIG_SERIO_I8042 is not set
++# CONFIG_SERIO_SERPORT is not set
++# CONFIG_SERIO_LIBPS2 is not set
++# CONFIG_SERIO_RAW is not set
++# CONFIG_SERIO_XILINX_XPS_PS2 is not set
++# CONFIG_GAMEPORT is not set
++CONFIG_GAMECUBE_SI=y
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_CONSOLE_TRANSLATIONS=y
++CONFIG_VT_CONSOLE=y
++CONFIG_HW_CONSOLE=y
++# CONFIG_VT_HW_CONSOLE_BINDING is not set
++# CONFIG_DEVKMEM is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_8250 is not set
++
++#
++# Non-8250 serial port support
++#
++# CONFIG_SERIAL_UARTLITE is not set
++# CONFIG_SERIAL_USBGECKO is not set
++CONFIG_UNIX98_PTYS=y
++CONFIG_LEGACY_PTYS=y
++CONFIG_LEGACY_PTY_COUNT=64
++# CONFIG_IPMI_HANDLER is not set
++# CONFIG_HW_RANDOM is not set
++# CONFIG_NVRAM is not set
++# CONFIG_R3964 is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++# CONFIG_I2C is not set
++
++#
++# EXI support
++#
++CONFIG_GAMECUBE_EXI=y
++# CONFIG_SPI is not set
++CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
++# CONFIG_GPIOLIB is not set
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++# CONFIG_HWMON is not set
++# CONFIG_THERMAL is not set
++# CONFIG_THERMAL_HWMON is not set
++# CONFIG_WATCHDOG is not set
++CONFIG_SSB_POSSIBLE=y
++
++#
++# Sonics Silicon Backplane
++#
++# CONFIG_SSB is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_CORE is not set
++# CONFIG_MFD_SM501 is not set
++# CONFIG_HTC_PASIC3 is not set
++# CONFIG_MFD_TMIO is not set
++# CONFIG_REGULATOR is not set
++
++#
++# Multimedia devices
++#
++
++#
++# Multimedia core support
++#
++# CONFIG_VIDEO_DEV is not set
++# CONFIG_DVB_CORE is not set
++# CONFIG_VIDEO_MEDIA is not set
++
++#
++# Multimedia drivers
++#
++# CONFIG_DAB is not set
++
++#
++# Graphics support
++#
++# CONFIG_VGASTATE is not set
++# CONFIG_VIDEO_OUTPUT_CONTROL is not set
++CONFIG_FB=y
++# CONFIG_FIRMWARE_EDID is not set
++# CONFIG_FB_DDC is not set
++# CONFIG_FB_BOOT_VESA_SUPPORT is not set
++CONFIG_FB_CFB_FILLRECT=y
++CONFIG_FB_CFB_COPYAREA=y
++CONFIG_FB_CFB_IMAGEBLIT=y
++# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
++# CONFIG_FB_SYS_FILLRECT is not set
++# CONFIG_FB_SYS_COPYAREA is not set
++# CONFIG_FB_SYS_IMAGEBLIT is not set
++# CONFIG_FB_FOREIGN_ENDIAN is not set
++# CONFIG_FB_SYS_FOPS is not set
++# CONFIG_FB_SVGALIB is not set
++# CONFIG_FB_MACMODES is not set
++# CONFIG_FB_BACKLIGHT is not set
++# CONFIG_FB_MODE_HELPERS is not set
++# CONFIG_FB_TILEBLITTING is not set
++
++#
++# Frame buffer hardware drivers
++#
++# CONFIG_FB_OF is not set
++# CONFIG_FB_VGA16 is not set
++# CONFIG_FB_S1D13XXX is not set
++CONFIG_FB_GAMECUBE=y
++# CONFIG_FB_IBM_GXT4500 is not set
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_FB_METRONOME is not set
++# CONFIG_FB_MB862XX is not set
++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
++
++#
++# Display device support
++#
++# CONFIG_DISPLAY_SUPPORT is not set
++
++#
++# Console display driver support
++#
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_DUMMY_CONSOLE=y
++CONFIG_FRAMEBUFFER_CONSOLE=y
++# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY 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 is not set
++# CONFIG_LOGO_LINUX_VGA16 is not set
++# CONFIG_LOGO_LINUX_CLUT224 is not set
++CONFIG_LOGO_GAMECUBE_CLUT224=y
++CONFIG_SOUND=y
++CONFIG_SOUND_OSS_CORE=y
++CONFIG_SND=y
++CONFIG_SND_TIMER=y
++CONFIG_SND_PCM=y
++CONFIG_SND_SEQUENCER=y
++# CONFIG_SND_SEQ_DUMMY 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_SEQUENCER_OSS=y
++# CONFIG_SND_DYNAMIC_MINORS is not set
++CONFIG_SND_SUPPORT_OLD_API=y
++# CONFIG_SND_VERBOSE_PROCFS is not set
++# CONFIG_SND_VERBOSE_PRINTK is not set
++# CONFIG_SND_DEBUG is not set
++CONFIG_SND_DRIVERS=y
++# CONFIG_SND_DUMMY is not set
++# CONFIG_SND_VIRMIDI is not set
++# CONFIG_SND_MTPAV is not set
++# CONFIG_SND_SERIAL_U16550 is not set
++# CONFIG_SND_MPU401 is not set
++CONFIG_SND_PPC=y
++CONFIG_SND_GAMECUBE=y
++CONFIG_SND_GAMECUBE_MIC=m
++# CONFIG_SND_SOC is not set
++# CONFIG_SOUND_PRIME is not set
++CONFIG_HID_SUPPORT=y
++CONFIG_HID=y
++# CONFIG_HID_DEBUG is not set
++# CONFIG_HIDRAW is not set
++# CONFIG_HID_PID is not set
++
++#
++# Special HID drivers
++#
++CONFIG_HID_COMPAT=y
++# CONFIG_USB_SUPPORT is not set
++# CONFIG_MMC is not set
++# CONFIG_MEMSTICK is not set
++# CONFIG_NEW_LEDS is not set
++# CONFIG_ACCESSIBILITY is not set
++# CONFIG_EDAC is not set
++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
++
++#
++# SPI RTC drivers
++#
++
++#
++# Platform RTC drivers
++#
++# CONFIG_RTC_DRV_CMOS is not set
++# CONFIG_RTC_DRV_DS1286 is not set
++# CONFIG_RTC_DRV_DS1511 is not set
++# CONFIG_RTC_DRV_DS1553 is not set
++# CONFIG_RTC_DRV_DS1742 is not set
++# CONFIG_RTC_DRV_STK17TA8 is not set
++# CONFIG_RTC_DRV_M48T86 is not set
++# CONFIG_RTC_DRV_M48T35 is not set
++# CONFIG_RTC_DRV_M48T59 is not set
++# CONFIG_RTC_DRV_BQ4802 is not set
++# CONFIG_RTC_DRV_V3020 is not set
++CONFIG_RTC_DRV_GCN=y
++
++#
++# on-CPU RTC drivers
++#
++# CONFIG_RTC_DRV_PPC is not set
++# CONFIG_DMADEVICES is not set
++# CONFIG_UIO is not set
++# CONFIG_STAGING is not set
++
++#
++# File systems
++#
++CONFIG_EXT2_FS=y
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XIP is not set
++CONFIG_EXT3_FS=y
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT4_FS is not set
++CONFIG_JBD=y
++# CONFIG_JBD_DEBUG is not set
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_FS_POSIX_ACL is not set
++CONFIG_FILE_LOCKING=y
++# CONFIG_XFS_FS is not set
++# CONFIG_OCFS2_FS is not set
++CONFIG_DNOTIFY=y
++CONFIG_INOTIFY=y
++CONFIG_INOTIFY_USER=y
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_FUSE_FS is not set
++
++#
++# CD-ROM/DVD Filesystems
++#
++CONFIG_ISO9660_FS=y
++CONFIG_JOLIET=y
++# CONFIG_ZISOFS is not set
++# CONFIG_UDF_FS is not set
++# CONFIG_GCDVD_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_KCORE=y
++CONFIG_PROC_SYSCTL=y
++# CONFIG_PROC_PAGE_MONITOR is not set
++CONFIG_SYSFS=y
++CONFIG_TMPFS=y
++# CONFIG_TMPFS_POSIX_ACL is not set
++# CONFIG_HUGETLB_PAGE is not set
++# 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_CRAMFS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_OMFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_ROMFS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++CONFIG_NETWORK_FILESYSTEMS=y
++CONFIG_NFS_FS=y
++CONFIG_NFS_V3=y
++# CONFIG_NFS_V3_ACL is not set
++# CONFIG_NFS_V4 is not set
++CONFIG_ROOT_NFS=y
++# CONFIG_NFSD is not set
++CONFIG_LOCKD=y
++CONFIG_LOCKD_V4=y
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=y
++# CONFIG_SUNRPC_REGISTER_V4 is not set
++# CONFIG_RPCSEC_GSS_KRB5 is not set
++# CONFIG_RPCSEC_GSS_SPKM3 is not set
++# CONFIG_SMB_FS is not set
++CONFIG_CIFS=y
++# CONFIG_CIFS_STATS is not set
++# CONFIG_CIFS_WEAK_PW_HASH is not set
++# CONFIG_CIFS_XATTR 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
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++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
++# CONFIG_DLM is not set
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++CONFIG_CRC_CCITT=y
++# CONFIG_CRC16 is not set
++# CONFIG_CRC_T10DIF is not set
++# CONFIG_CRC_ITU_T is not set
++CONFIG_CRC32=y
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++CONFIG_PLIST=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
++CONFIG_HAVE_LMB=y
++
++#
++# Kernel hacking
++#
++# CONFIG_PRINTK_TIME is not set
++CONFIG_ENABLE_WARN_DEPRECATED=y
++CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_FRAME_WARN=1024
++# CONFIG_MAGIC_SYSRQ is not set
++# 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=y
++# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
++CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
++CONFIG_SCHED_DEBUG=y
++CONFIG_SCHEDSTATS=y
++# CONFIG_TIMER_STATS is not set
++# CONFIG_DEBUG_OBJECTS 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_SPINLOCK_SLEEP is not set
++# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
++CONFIG_STACKTRACE=y
++# CONFIG_DEBUG_KOBJECT is not set
++CONFIG_DEBUG_BUGVERBOSE=y
++# CONFIG_DEBUG_INFO is not set
++# CONFIG_DEBUG_VM is not set
++# CONFIG_DEBUG_WRITECOUNT is not set
++# CONFIG_DEBUG_MEMORY_INIT is not set
++# CONFIG_DEBUG_LIST is not set
++# CONFIG_DEBUG_SG is not set
++# CONFIG_BOOT_PRINTK_DELAY is not set
++# CONFIG_RCU_TORTURE_TEST is not set
++# CONFIG_RCU_CPU_STALL_DETECTOR is not set
++# CONFIG_BACKTRACE_SELF_TEST is not set
++# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
++# CONFIG_FAULT_INJECTION is not set
++CONFIG_LATENCYTOP=y
++CONFIG_SYSCTL_SYSCALL_CHECK=y
++CONFIG_NOP_TRACER=y
++CONFIG_HAVE_FUNCTION_TRACER=y
++CONFIG_RING_BUFFER=y
++CONFIG_TRACING=y
++
++#
++# Tracers
++#
++# CONFIG_FUNCTION_TRACER is not set
++# CONFIG_PREEMPT_TRACER is not set
++# CONFIG_SCHED_TRACER is not set
++CONFIG_CONTEXT_SWITCH_TRACER=y
++CONFIG_BOOT_TRACER=y
++# CONFIG_STACK_TRACER is not set
++# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
++# CONFIG_SAMPLES is not set
++CONFIG_HAVE_ARCH_KGDB=y
++# CONFIG_KGDB is not set
++# CONFIG_DEBUG_STACKOVERFLOW is not set
++# CONFIG_DEBUG_STACK_USAGE is not set
++# CONFIG_DEBUG_PAGEALLOC is not set
++# CONFIG_CODE_PATCHING_SELFTEST is not set
++# CONFIG_FTR_FIXUP_SELFTEST is not set
++# CONFIG_MSI_BITMAP_SELFTEST is not set
++# CONFIG_XMON is not set
++# CONFIG_IRQSTACKS is not set
++# CONFIG_VIRQ_DEBUG is not set
++# CONFIG_BDI_SWITCH is not set
++# CONFIG_BOOTX_TEXT is not set
++CONFIG_PPC_EARLY_DEBUG=y
++# CONFIG_PPC_EARLY_DEBUG_LPAR is not set
++# CONFIG_PPC_EARLY_DEBUG_G5 is not set
++# CONFIG_PPC_EARLY_DEBUG_RTAS_PANEL is not set
++# CONFIG_PPC_EARLY_DEBUG_RTAS_CONSOLE is not set
++# CONFIG_PPC_EARLY_DEBUG_MAPLE is not set
++# CONFIG_PPC_EARLY_DEBUG_ISERIES is not set
++# CONFIG_PPC_EARLY_DEBUG_PAS_REALMODE is not set
++# CONFIG_PPC_EARLY_DEBUG_BEAT is not set
++# CONFIG_PPC_EARLY_DEBUG_44x is not set
++# CONFIG_PPC_EARLY_DEBUG_40x is not set
++# CONFIG_PPC_EARLY_DEBUG_CPM is not set
++CONFIG_PPC_EARLY_DEBUG_USBGECKO=y
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY is not set
++# CONFIG_SECURITYFS is not set
++# CONFIG_SECURITY_FILE_CAPABILITIES is not set
++# CONFIG_CRYPTO is not set
++# CONFIG_PPC_CLOCK is not set
++# CONFIG_VIRTUALIZATION is not set
+diff --git a/arch/powerpc/configs/wii_defconfig b/arch/powerpc/configs/wii_defconfig
+new file mode 100644
+index 0000000..64d7f19
+--- /dev/null
++++ b/arch/powerpc/configs/wii_defconfig
+@@ -0,0 +1,1224 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.28
++# Mon Jan 12 20:19:45 2009
++#
++# CONFIG_PPC64 is not set
++
++#
++# Processor support
++#
++CONFIG_6xx=y
++# CONFIG_PPC_85xx is not set
++# CONFIG_PPC_8xx is not set
++# CONFIG_40x is not set
++# CONFIG_44x is not set
++# CONFIG_E200 is not set
++CONFIG_PPC_FPU=y
++# CONFIG_ALTIVEC is not set
++CONFIG_PPC_STD_MMU=y
++CONFIG_PPC_STD_MMU_32=y
++# CONFIG_PPC_MM_SLICES is not set
++# CONFIG_SMP is not set
++CONFIG_NOT_COHERENT_CACHE=y
++CONFIG_PPC32=y
++CONFIG_WORD_SIZE=32
++# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
++CONFIG_MMU=y
++CONFIG_GENERIC_CMOS_UPDATE=y
++CONFIG_GENERIC_TIME=y
++CONFIG_GENERIC_TIME_VSYSCALL=y
++CONFIG_GENERIC_CLOCKEVENTS=y
++CONFIG_GENERIC_HARDIRQS=y
++# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
++CONFIG_IRQ_PER_CPU=y
++CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_HAVE_LATENCYTOP_SUPPORT=y
++CONFIG_LOCKDEP_SUPPORT=y
++CONFIG_RWSEM_XCHGADD_ALGORITHM=y
++CONFIG_ARCH_HAS_ILOG2_U32=y
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_GENERIC_FIND_NEXT_BIT=y
++CONFIG_GENERIC_GPIO=y
++# CONFIG_ARCH_NO_VIRT_TO_BUS is not set
++CONFIG_PPC=y
++CONFIG_EARLY_PRINTK=y
++CONFIG_GENERIC_NVRAM=y
++CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
++CONFIG_ARCH_MAY_HAVE_PC_FDC=y
++CONFIG_PPC_OF=y
++CONFIG_OF=y
++# CONFIG_PPC_UDBG_16550 is not set
++# CONFIG_GENERIC_TBSYNC is not set
++CONFIG_AUDIT_ARCH=y
++CONFIG_GENERIC_BUG=y
++# CONFIG_DEFAULT_UIMAGE is not set
++# CONFIG_PPC_DCR_NATIVE is not set
++# CONFIG_PPC_DCR_MMIO is not set
++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="-isobel-wii"
++CONFIG_LOCALVERSION_AUTO=y
++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_AUDIT is not set
++CONFIG_IKCONFIG=y
++CONFIG_IKCONFIG_PROC=y
++CONFIG_LOG_BUF_SHIFT=14
++# CONFIG_CGROUPS is not set
++CONFIG_GROUP_SCHED=y
++CONFIG_FAIR_GROUP_SCHED=y
++# CONFIG_RT_GROUP_SCHED is not set
++CONFIG_USER_SCHED=y
++# CONFIG_CGROUP_SCHED is not set
++CONFIG_SYSFS_DEPRECATED=y
++CONFIG_SYSFS_DEPRECATED_V2=y
++# CONFIG_RELAY is not set
++# CONFIG_NAMESPACES is not set
++CONFIG_BLK_DEV_INITRD=y
++CONFIG_INITRAMFS_SOURCE=""
++# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
++CONFIG_SYSCTL=y
++CONFIG_EMBEDDED=y
++CONFIG_SYSCTL_SYSCALL=y
++CONFIG_KALLSYMS=y
++CONFIG_KALLSYMS_ALL=y
++# CONFIG_KALLSYMS_EXTRA_PASS is not set
++CONFIG_HOTPLUG=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++# CONFIG_ELF_CORE is not set
++CONFIG_COMPAT_BRK=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_ANON_INODES=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_TIMERFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_AIO=y
++# CONFIG_VM_EVENT_COUNTERS is not set
++CONFIG_SLAB=y
++# CONFIG_SLUB is not set
++# CONFIG_SLOB is not set
++# CONFIG_PROFILING is not set
++CONFIG_TRACEPOINTS=y
++CONFIG_MARKERS=y
++CONFIG_HAVE_OPROFILE=y
++# CONFIG_KPROBES is not set
++CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
++CONFIG_HAVE_IOREMAP_PROT=y
++CONFIG_HAVE_KPROBES=y
++CONFIG_HAVE_KRETPROBES=y
++CONFIG_HAVE_ARCH_TRACEHOOK=y
++# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
++CONFIG_SLABINFO=y
++CONFIG_RT_MUTEXES=y
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++# CONFIG_MODULE_FORCE_LOAD is not set
++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=y
++# CONFIG_BLK_DEV_IO_TRACE is not set
++# CONFIG_LSF is not set
++# CONFIG_BLK_DEV_BSG is not set
++# CONFIG_BLK_DEV_INTEGRITY is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++CONFIG_DEFAULT_AS=y
++# CONFIG_DEFAULT_DEADLINE is not set
++# CONFIG_DEFAULT_CFQ is not set
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="anticipatory"
++CONFIG_CLASSIC_RCU=y
++# CONFIG_FREEZER is not set
++
++#
++# Platform support
++#
++CONFIG_PPC_MULTIPLATFORM=y
++CONFIG_CLASSIC32=y
++# CONFIG_PPC_CHRP is not set
++# CONFIG_MPC5121_ADS is not set
++# CONFIG_MPC5121_GENERIC is not set
++# CONFIG_PPC_MPC52xx is not set
++# CONFIG_PPC_PMAC is not set
++# CONFIG_PPC_CELL is not set
++# CONFIG_PPC_CELL_NATIVE is not set
++# CONFIG_PPC_82xx is not set
++# CONFIG_PQ2ADS is not set
++# CONFIG_PPC_83xx is not set
++# CONFIG_PPC_86xx is not set
++CONFIG_EMBEDDED6xx=y
++# CONFIG_LINKSTATION is not set
++# CONFIG_STORCENTER is not set
++# CONFIG_MPC7448HPC2 is not set
++# CONFIG_PPC_HOLLY is not set
++# CONFIG_PPC_PRPMC2800 is not set
++# CONFIG_PPC_C2K is not set
++# CONFIG_GAMECUBE is not set
++CONFIG_WII=y
++CONFIG_FLIPPER_PIC=y
++CONFIG_GAMECUBE_COMMON=y
++CONFIG_GAMECUBE_RSW=y
++CONFIG_GAMECUBE_UDBG=y
++CONFIG_USBGECKO_UDBG=y
++# CONFIG_GAMECUBE_VIDEO_UDBG is not set
++CONFIG_WII_GPIO=y
++# CONFIG_IPIC is not set
++# CONFIG_MPIC is not set
++# CONFIG_MPIC_WEIRD is not set
++# CONFIG_PPC_I8259 is not set
++# CONFIG_PPC_RTAS is not set
++# CONFIG_MMIO_NVRAM is not set
++# CONFIG_PPC_MPC106 is not set
++# CONFIG_PPC_970_NAP is not set
++# CONFIG_PPC_INDIRECT_IO is not set
++# CONFIG_GENERIC_IOMAP is not set
++# CONFIG_CPU_FREQ is not set
++# CONFIG_TAU is not set
++# CONFIG_FSL_ULI1575 is not set
++
++#
++# Kernel options
++#
++# CONFIG_HIGHMEM is not set
++# CONFIG_NO_HZ is not set
++# CONFIG_HIGH_RES_TIMERS is not set
++CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
++# CONFIG_HZ_100 is not set
++CONFIG_HZ_250=y
++# CONFIG_HZ_300 is not set
++# CONFIG_HZ_1000 is not set
++CONFIG_HZ=250
++# CONFIG_SCHED_HRTICK is not set
++# CONFIG_PREEMPT_NONE is not set
++# CONFIG_PREEMPT_VOLUNTARY is not set
++CONFIG_PREEMPT=y
++# CONFIG_PREEMPT_RCU is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
++# CONFIG_HAVE_AOUT is not set
++CONFIG_BINFMT_MISC=m
++# CONFIG_IOMMU_HELPER is not set
++CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
++CONFIG_ARCH_HAS_WALK_MEMORY=y
++CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
++CONFIG_KEXEC=y
++CONFIG_ARCH_FLATMEM_ENABLE=y
++CONFIG_ARCH_POPULATES_NODE_MAP=y
++CONFIG_SELECT_MEMORY_MODEL=y
++CONFIG_FLATMEM_MANUAL=y
++# CONFIG_DISCONTIGMEM_MANUAL is not set
++# CONFIG_SPARSEMEM_MANUAL is not set
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++CONFIG_PAGEFLAGS_EXTENDED=y
++CONFIG_SPLIT_PTLOCK_CPUS=4
++# CONFIG_MIGRATION is not set
++# CONFIG_RESOURCES_64BIT is not set
++# CONFIG_PHYS_ADDR_T_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=1
++CONFIG_BOUNCE=y
++CONFIG_VIRT_TO_BUS=y
++CONFIG_UNEVICTABLE_LRU=y
++CONFIG_FORCE_MAX_ZONEORDER=11
++CONFIG_PROC_DEVICETREE=y
++# CONFIG_CMDLINE_BOOL is not set
++CONFIG_EXTRA_TARGETS=""
++# CONFIG_PM is not set
++# CONFIG_SECCOMP is not set
++CONFIG_ISA_DMA_API=y
++
++#
++# Bus options
++#
++CONFIG_ZONE_DMA=y
++CONFIG_GENERIC_ISA_DMA=y
++# CONFIG_PCI is not set
++# CONFIG_PCI_DOMAINS is not set
++# CONFIG_PCI_SYSCALL is not set
++# CONFIG_ARCH_SUPPORTS_MSI is not set
++# CONFIG_PCCARD is not set
++# CONFIG_HAS_RAPIDIO is not set
++
++#
++# Advanced setup
++#
++CONFIG_ADVANCED_OPTIONS=y
++# CONFIG_LOWMEM_SIZE_BOOL is not set
++CONFIG_LOWMEM_SIZE=0x30000000
++# CONFIG_PAGE_OFFSET_BOOL is not set
++CONFIG_PAGE_OFFSET=0xc0000000
++# CONFIG_KERNEL_START_BOOL is not set
++CONFIG_KERNEL_START=0xc0000000
++CONFIG_PHYSICAL_START=0x00000000
++# CONFIG_TASK_SIZE_BOOL is not set
++CONFIG_TASK_SIZE=0xc0000000
++# CONFIG_CONSISTENT_START_BOOL is not set
++CONFIG_CONSISTENT_START=0xff100000
++# CONFIG_CONSISTENT_SIZE_BOOL is not set
++CONFIG_CONSISTENT_SIZE=0x00200000
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++CONFIG_UNIX=y
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_FIB_HASH=y
++CONFIG_IP_PNP=y
++CONFIG_IP_PNP_DHCP=y
++# CONFIG_IP_PNP_BOOTP is not set
++CONFIG_IP_PNP_RARP=y
++# 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 is not set
++# CONFIG_INET_XFRM_MODE_TUNNEL is not set
++# CONFIG_INET_XFRM_MODE_BEET is not set
++# CONFIG_INET_LRO is not set
++# CONFIG_INET_DIAG is not set
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++# CONFIG_IPV6 is not set
++# CONFIG_NETWORK_SECMARK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_NET_DSA is not set
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_DECNET is not set
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_ECONET is not set
++# CONFIG_WAN_ROUTER is not set
++# CONFIG_NET_SCHED is not set
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_CAN is not set
++# CONFIG_IRDA is not set
++CONFIG_BT=y
++CONFIG_BT_L2CAP=y
++# CONFIG_BT_SCO is not set
++CONFIG_BT_RFCOMM=y
++# CONFIG_BT_RFCOMM_TTY is not set
++# CONFIG_BT_BNEP is not set
++CONFIG_BT_HIDP=y
++
++#
++# Bluetooth device drivers
++#
++CONFIG_BT_HCIBTUSB=y
++# CONFIG_BT_HCIUART is not set
++# 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
++# CONFIG_PHONET is not set
++CONFIG_WIRELESS=y
++# CONFIG_CFG80211 is not set
++CONFIG_WIRELESS_OLD_REGULATORY=y
++# 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_UEVENT_HELPER_PATH="/sbin/hotplug"
++# CONFIG_STANDALONE is not set
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++# CONFIG_FW_LOADER is not set
++# 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 is not set
++CONFIG_OF_DEVICE=y
++CONFIG_OF_GPIO=y
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_DEV_FD is not set
++CONFIG_GAMECUBE_SD=y
++CONFIG_WII_SD=y
++CONFIG_WII_MEM2=m
++# 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=2
++CONFIG_BLK_DEV_RAM_SIZE=4096
++# CONFIG_BLK_DEV_XIP is not set
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++# CONFIG_BLK_DEV_HD is not set
++CONFIG_MISC_DEVICES=y
++CONFIG_GAMECUBE_GQR=m
++# CONFIG_EEPROM_93CX6 is not set
++# CONFIG_ENCLOSURE_SERVICES is not set
++# CONFIG_C2PORT is not set
++CONFIG_HAVE_IDE=y
++# 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=y
++# 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_SRP_ATTRS is not set
++CONFIG_SCSI_LOWLEVEL=y
++# CONFIG_ISCSI_TCP is not set
++# CONFIG_SCSI_DEBUG is not set
++# CONFIG_SCSI_DH is not set
++# CONFIG_ATA is not set
++# CONFIG_MD is not set
++# CONFIG_MACINTOSH_DRIVERS is not set
++CONFIG_NETDEVICES=y
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_MACVLAN is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_VETH is not set
++# CONFIG_PHYLIB is not set
++CONFIG_NET_ETHERNET=y
++CONFIG_MII=y
++# CONFIG_IBM_NEW_EMAC_ZMII is not set
++# CONFIG_IBM_NEW_EMAC_RGMII is not set
++# CONFIG_IBM_NEW_EMAC_TAH is not set
++# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
++# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
++# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
++# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
++# CONFIG_B44 is not set
++# CONFIG_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
++# CONFIG_IWLWIFI_LEDS 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=y
++CONFIG_USB_NET_AX8817X=y
++# CONFIG_USB_NET_CDCETHER is not set
++# CONFIG_USB_NET_DM9601 is not set
++# CONFIG_USB_NET_SMSC95XX is not set
++# CONFIG_USB_NET_GL620A is not set
++# CONFIG_USB_NET_NET1080 is not set
++# CONFIG_USB_NET_PLUSB is not set
++# CONFIG_USB_NET_MCS7830 is not set
++# 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_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
++# CONFIG_ISDN is not set
++# 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=y
++# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=640
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480
++CONFIG_INPUT_JOYDEV=y
++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_GPIO is not set
++CONFIG_INPUT_MOUSE=y
++# CONFIG_MOUSE_PS2 is not set
++# CONFIG_MOUSE_SERIAL is not set
++# CONFIG_MOUSE_APPLETOUCH is not set
++# CONFIG_MOUSE_BCM5974 is not set
++# CONFIG_MOUSE_VSXXXAA is not set
++# CONFIG_MOUSE_GPIO 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_ZHENHUA is not set
++# CONFIG_JOYSTICK_JOYDUMP is not set
++# CONFIG_JOYSTICK_XPAD is not set
++# CONFIG_INPUT_TABLET is not set
++# CONFIG_INPUT_TOUCHSCREEN is not set
++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_CM109 is not set
++CONFIG_INPUT_UINPUT=y
++
++#
++# Hardware I/O ports
++#
++CONFIG_SERIO=y
++# CONFIG_SERIO_I8042 is not set
++# CONFIG_SERIO_SERPORT is not set
++# CONFIG_SERIO_LIBPS2 is not set
++# CONFIG_SERIO_RAW is not set
++# CONFIG_SERIO_XILINX_XPS_PS2 is not set
++# CONFIG_GAMEPORT is not set
++CONFIG_GAMECUBE_SI=y
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_CONSOLE_TRANSLATIONS=y
++CONFIG_VT_CONSOLE=y
++CONFIG_HW_CONSOLE=y
++# CONFIG_VT_HW_CONSOLE_BINDING is not set
++# CONFIG_DEVKMEM is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_8250 is not set
++
++#
++# Non-8250 serial port support
++#
++# CONFIG_SERIAL_UARTLITE is not set
++# CONFIG_SERIAL_USBGECKO is not set
++CONFIG_UNIX98_PTYS=y
++CONFIG_LEGACY_PTYS=y
++CONFIG_LEGACY_PTY_COUNT=64
++# CONFIG_IPMI_HANDLER is not set
++# CONFIG_HW_RANDOM is not set
++CONFIG_NVRAM=y
++# CONFIG_R3964 is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++# CONFIG_I2C is not set
++
++#
++# EXI support
++#
++CONFIG_GAMECUBE_EXI=y
++# CONFIG_SPI is not set
++CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
++CONFIG_GPIOLIB=y
++# CONFIG_DEBUG_GPIO is not set
++CONFIG_GPIO_SYSFS=y
++
++#
++# Memory mapped GPIO expanders:
++#
++# CONFIG_GPIO_XILINX is not set
++
++#
++# I2C GPIO expanders:
++#
++
++#
++# PCI GPIO expanders:
++#
++
++#
++# SPI GPIO expanders:
++#
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++# CONFIG_HWMON is not set
++# CONFIG_THERMAL is not set
++# CONFIG_THERMAL_HWMON is not set
++# CONFIG_WATCHDOG is not set
++CONFIG_SSB_POSSIBLE=y
++
++#
++# Sonics Silicon Backplane
++#
++# CONFIG_SSB is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_CORE is not set
++# CONFIG_MFD_SM501 is not set
++# CONFIG_HTC_PASIC3 is not set
++# CONFIG_MFD_TMIO is not set
++# CONFIG_REGULATOR is not set
++
++#
++# Multimedia devices
++#
++
++#
++# Multimedia core support
++#
++# CONFIG_VIDEO_DEV is not set
++# CONFIG_DVB_CORE is not set
++# CONFIG_VIDEO_MEDIA is not set
++
++#
++# Multimedia drivers
++#
++# CONFIG_DAB is not set
++
++#
++# Graphics support
++#
++# CONFIG_VGASTATE is not set
++# CONFIG_VIDEO_OUTPUT_CONTROL is not set
++CONFIG_FB=y
++# CONFIG_FIRMWARE_EDID is not set
++# CONFIG_FB_DDC is not set
++# CONFIG_FB_BOOT_VESA_SUPPORT is not set
++CONFIG_FB_CFB_FILLRECT=y
++CONFIG_FB_CFB_COPYAREA=y
++CONFIG_FB_CFB_IMAGEBLIT=y
++# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
++# CONFIG_FB_SYS_FILLRECT is not set
++# CONFIG_FB_SYS_COPYAREA is not set
++# CONFIG_FB_SYS_IMAGEBLIT is not set
++# CONFIG_FB_FOREIGN_ENDIAN is not set
++# CONFIG_FB_SYS_FOPS is not set
++# CONFIG_FB_SVGALIB is not set
++# CONFIG_FB_MACMODES is not set
++# CONFIG_FB_BACKLIGHT is not set
++# CONFIG_FB_MODE_HELPERS is not set
++# CONFIG_FB_TILEBLITTING is not set
++
++#
++# Frame buffer hardware drivers
++#
++# CONFIG_FB_OF is not set
++# CONFIG_FB_VGA16 is not set
++# CONFIG_FB_S1D13XXX is not set
++CONFIG_FB_GAMECUBE=y
++# CONFIG_FB_IBM_GXT4500 is not set
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_FB_METRONOME is not set
++# CONFIG_FB_MB862XX is not set
++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
++
++#
++# Display device support
++#
++# CONFIG_DISPLAY_SUPPORT is not set
++
++#
++# Console display driver support
++#
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_DUMMY_CONSOLE=y
++CONFIG_FRAMEBUFFER_CONSOLE=y
++# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY 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
++CONFIG_SOUND=y
++CONFIG_SOUND_OSS_CORE=y
++CONFIG_SND=y
++CONFIG_SND_TIMER=y
++CONFIG_SND_PCM=y
++CONFIG_SND_SEQUENCER=y
++# CONFIG_SND_SEQ_DUMMY 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_SEQUENCER_OSS=y
++# CONFIG_SND_DYNAMIC_MINORS is not set
++CONFIG_SND_SUPPORT_OLD_API=y
++# CONFIG_SND_VERBOSE_PROCFS is not set
++# CONFIG_SND_VERBOSE_PRINTK is not set
++# CONFIG_SND_DEBUG is not set
++CONFIG_SND_DRIVERS=y
++# CONFIG_SND_DUMMY is not set
++# CONFIG_SND_VIRMIDI is not set
++# CONFIG_SND_MTPAV is not set
++# CONFIG_SND_SERIAL_U16550 is not set
++# CONFIG_SND_MPU401 is not set
++CONFIG_SND_PPC=y
++CONFIG_SND_GAMECUBE=y
++CONFIG_SND_GAMECUBE_MIC=m
++# CONFIG_SND_USB is not set
++# CONFIG_SND_SOC is not set
++# CONFIG_SOUND_PRIME is not set
++CONFIG_HID_SUPPORT=y
++CONFIG_HID=y
++# CONFIG_HID_DEBUG is not set
++# CONFIG_HIDRAW is not set
++
++#
++# USB Input Devices
++#
++CONFIG_USB_HID=y
++# CONFIG_HID_PID is not set
++# CONFIG_USB_HIDDEV is not set
++
++#
++# Special HID drivers
++#
++CONFIG_HID_COMPAT=y
++CONFIG_HID_A4TECH=m
++CONFIG_HID_APPLE=m
++CONFIG_HID_BELKIN=m
++CONFIG_HID_BRIGHT=m
++CONFIG_HID_CHERRY=m
++CONFIG_HID_CHICONY=m
++CONFIG_HID_CYPRESS=m
++CONFIG_HID_DELL=m
++CONFIG_HID_EZKEY=m
++CONFIG_HID_GYRATION=m
++CONFIG_HID_LOGITECH=m
++# CONFIG_LOGITECH_FF is not set
++# CONFIG_LOGIRUMBLEPAD2_FF is not set
++CONFIG_HID_MICROSOFT=m
++CONFIG_HID_MONTEREY=m
++CONFIG_HID_PANTHERLORD=m
++# CONFIG_PANTHERLORD_FF is not set
++CONFIG_HID_PETALYNX=m
++CONFIG_HID_SAMSUNG=m
++CONFIG_HID_SONY=m
++CONFIG_HID_SUNPLUS=m
++CONFIG_THRUSTMASTER_FF=m
++CONFIG_ZEROPLUS_FF=m
++CONFIG_USB_SUPPORT=y
++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
++CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
++
++#
++# 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
++# CONFIG_USB_OTG_WHITELIST is not set
++# CONFIG_USB_OTG_BLACKLIST_HUB is not set
++# CONFIG_USB_MON is not set
++# CONFIG_USB_WUSB is not set
++# CONFIG_USB_WUSB_CBAF is not set
++
++#
++# USB Host Controller Drivers
++#
++# CONFIG_USB_C67X00_HCD is not set
++# CONFIG_USB_ISP116X_HCD is not set
++# CONFIG_USB_ISP1760_HCD is not set
++# CONFIG_USB_SL811_HCD is not set
++# CONFIG_USB_R8A66597_HCD is not set
++CONFIG_USB_WII_HCD=y
++# CONFIG_USB_HWA_HCD is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++# CONFIG_USB_WDM is not set
++# CONFIG_USB_TMC is not set
++
++#
++# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD 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_ISD200 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_STORAGE_CYPRESS_ATACB is not set
++CONFIG_USB_LIBUSUAL=y
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_MDC800 is not set
++# CONFIG_USB_MICROTEK is not set
++
++#
++# USB port drivers
++#
++# 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_SEVSEG 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
++# CONFIG_USB_ISIGHTFW is not set
++# CONFIG_USB_VST is not set
++# CONFIG_USB_GADGET is not set
++# CONFIG_MMC is not set
++# CONFIG_MEMSTICK is not set
++# CONFIG_NEW_LEDS is not set
++# CONFIG_ACCESSIBILITY is not set
++# CONFIG_EDAC is not set
++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
++
++#
++# SPI RTC drivers
++#
++
++#
++# Platform RTC drivers
++#
++# CONFIG_RTC_DRV_CMOS is not set
++# CONFIG_RTC_DRV_DS1286 is not set
++# CONFIG_RTC_DRV_DS1511 is not set
++# CONFIG_RTC_DRV_DS1553 is not set
++# CONFIG_RTC_DRV_DS1742 is not set
++# CONFIG_RTC_DRV_STK17TA8 is not set
++# CONFIG_RTC_DRV_M48T86 is not set
++# CONFIG_RTC_DRV_M48T35 is not set
++# CONFIG_RTC_DRV_M48T59 is not set
++# CONFIG_RTC_DRV_BQ4802 is not set
++# CONFIG_RTC_DRV_V3020 is not set
++CONFIG_RTC_DRV_GCN=y
++
++#
++# on-CPU RTC drivers
++#
++# CONFIG_RTC_DRV_PPC is not set
++# CONFIG_DMADEVICES is not set
++# CONFIG_UIO is not set
++# CONFIG_STAGING is not set
++
++#
++# File systems
++#
++CONFIG_EXT2_FS=y
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XIP is not set
++CONFIG_EXT3_FS=y
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT4_FS is not set
++CONFIG_JBD=y
++# CONFIG_JBD_DEBUG is not set
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_FS_POSIX_ACL is not set
++CONFIG_FILE_LOCKING=y
++# CONFIG_XFS_FS is not set
++# CONFIG_OCFS2_FS is not set
++CONFIG_DNOTIFY=y
++CONFIG_INOTIFY=y
++CONFIG_INOTIFY_USER=y
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_FUSE_FS is not set
++
++#
++# CD-ROM/DVD Filesystems
++#
++CONFIG_ISO9660_FS=y
++CONFIG_JOLIET=y
++# CONFIG_ZISOFS is not set
++# CONFIG_UDF_FS is not set
++# CONFIG_GCDVD_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_KCORE=y
++CONFIG_PROC_SYSCTL=y
++# CONFIG_PROC_PAGE_MONITOR is not set
++CONFIG_SYSFS=y
++CONFIG_TMPFS=y
++# CONFIG_TMPFS_POSIX_ACL is not set
++# CONFIG_HUGETLB_PAGE is not set
++# 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_CRAMFS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_OMFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_ROMFS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++CONFIG_NETWORK_FILESYSTEMS=y
++CONFIG_NFS_FS=y
++CONFIG_NFS_V3=y
++# CONFIG_NFS_V3_ACL is not set
++# CONFIG_NFS_V4 is not set
++CONFIG_ROOT_NFS=y
++# CONFIG_NFSD is not set
++CONFIG_LOCKD=y
++CONFIG_LOCKD_V4=y
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=y
++# CONFIG_SUNRPC_REGISTER_V4 is not set
++# 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
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++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
++# CONFIG_DLM is not set
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++CONFIG_CRC_CCITT=y
++# CONFIG_CRC16 is not set
++# CONFIG_CRC_T10DIF is not set
++# CONFIG_CRC_ITU_T is not set
++CONFIG_CRC32=y
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++CONFIG_PLIST=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
++CONFIG_HAVE_LMB=y
++
++#
++# Kernel hacking
++#
++# CONFIG_PRINTK_TIME is not set
++CONFIG_ENABLE_WARN_DEPRECATED=y
++CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_FRAME_WARN=1024
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_UNUSED_SYMBOLS is not set
++CONFIG_DEBUG_FS=y
++# CONFIG_HEADERS_CHECK is not set
++CONFIG_DEBUG_KERNEL=y
++# CONFIG_DEBUG_SHIRQ is not set
++CONFIG_DETECT_SOFTLOCKUP=y
++# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
++CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
++CONFIG_SCHED_DEBUG=y
++CONFIG_SCHEDSTATS=y
++# CONFIG_TIMER_STATS is not set
++# CONFIG_DEBUG_OBJECTS 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 is not set
++# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
++# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
++CONFIG_STACKTRACE=y
++# CONFIG_DEBUG_KOBJECT is not set
++# CONFIG_DEBUG_BUGVERBOSE is not set
++# CONFIG_DEBUG_INFO is not set
++# CONFIG_DEBUG_VM is not set
++# CONFIG_DEBUG_WRITECOUNT is not set
++# CONFIG_DEBUG_MEMORY_INIT is not set
++# CONFIG_DEBUG_LIST is not set
++# CONFIG_DEBUG_SG is not set
++# CONFIG_BOOT_PRINTK_DELAY is not set
++# CONFIG_RCU_TORTURE_TEST is not set
++# CONFIG_RCU_CPU_STALL_DETECTOR is not set
++# CONFIG_BACKTRACE_SELF_TEST is not set
++# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
++# CONFIG_FAULT_INJECTION is not set
++CONFIG_LATENCYTOP=y
++CONFIG_SYSCTL_SYSCALL_CHECK=y
++CONFIG_NOP_TRACER=y
++CONFIG_HAVE_FUNCTION_TRACER=y
++CONFIG_RING_BUFFER=y
++CONFIG_TRACING=y
++
++#
++# Tracers
++#
++# CONFIG_FUNCTION_TRACER is not set
++# CONFIG_PREEMPT_TRACER is not set
++# CONFIG_SCHED_TRACER is not set
++CONFIG_CONTEXT_SWITCH_TRACER=y
++CONFIG_BOOT_TRACER=y
++# CONFIG_STACK_TRACER is not set
++# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
++# CONFIG_SAMPLES is not set
++CONFIG_HAVE_ARCH_KGDB=y
++# CONFIG_KGDB is not set
++# CONFIG_DEBUG_STACKOVERFLOW is not set
++# CONFIG_DEBUG_STACK_USAGE is not set
++# CONFIG_DEBUG_PAGEALLOC is not set
++# CONFIG_CODE_PATCHING_SELFTEST is not set
++# CONFIG_FTR_FIXUP_SELFTEST is not set
++# CONFIG_MSI_BITMAP_SELFTEST is not set
++# CONFIG_XMON is not set
++# CONFIG_IRQSTACKS is not set
++# CONFIG_VIRQ_DEBUG is not set
++# CONFIG_BDI_SWITCH is not set
++# CONFIG_BOOTX_TEXT is not set
++CONFIG_PPC_EARLY_DEBUG=y
++# CONFIG_PPC_EARLY_DEBUG_LPAR is not set
++# CONFIG_PPC_EARLY_DEBUG_G5 is not set
++# CONFIG_PPC_EARLY_DEBUG_RTAS_PANEL is not set
++# CONFIG_PPC_EARLY_DEBUG_RTAS_CONSOLE is not set
++# CONFIG_PPC_EARLY_DEBUG_MAPLE is not set
++# CONFIG_PPC_EARLY_DEBUG_ISERIES is not set
++# CONFIG_PPC_EARLY_DEBUG_PAS_REALMODE is not set
++# CONFIG_PPC_EARLY_DEBUG_BEAT is not set
++# CONFIG_PPC_EARLY_DEBUG_44x is not set
++# CONFIG_PPC_EARLY_DEBUG_40x is not set
++# CONFIG_PPC_EARLY_DEBUG_CPM is not set
++CONFIG_PPC_EARLY_DEBUG_USBGECKO=y
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY is not set
++# CONFIG_SECURITYFS is not set
++# CONFIG_SECURITY_FILE_CAPABILITIES is not set
++# CONFIG_CRYPTO is not set
++# CONFIG_PPC_CLOCK is not set
++CONFIG_PPC_LIB_RHEAP=y
++# CONFIG_VIRTUALIZATION is not set
+diff --git a/arch/powerpc/include/asm/starlet.h b/arch/powerpc/include/asm/starlet.h
+new file mode 100644
+index 0000000..b8f77c7
+--- /dev/null
++++ b/arch/powerpc/include/asm/starlet.h
+@@ -0,0 +1,234 @@
++/*
++ * arch/powerpc/include/asm/starlet.h
++ *
++ * Nintendo Wii starlet processor definitions
++ * Copyright (C) 2008-2009 The GameCube Linux Team
++ * Copyright (C) 2008,2009 Albert Herranz
++ *
++ * 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.
++ *
++ */
++
++#ifndef __ASM_POWERPC_STARLET_H
++#define __ASM_POWERPC_STARLET_H
++
++#include <linux/types.h>
++#include <linux/spinlock_types.h>
++#include <linux/platform_device.h>
++#include <linux/dmapool.h>
++#include <linux/dma-mapping.h>
++#include <linux/list.h>
++#include <linux/scatterlist.h>
++#include <linux/timer.h>
++#include <asm/rheap.h>
++
++#define STARLET_EINVAL -4
++
++
++#define STARLET_IPC_DMA_ALIGN 0x1f /* 32 bytes */
++
++struct starlet_ipc_request;
++
++/* input/output heap */
++struct starlet_ioh {
++ spinlock_t lock;
++ rh_info_t *rheap;
++ unsigned long base_phys;
++ void *base;
++ size_t size;
++};
++
++/* pseudo-scatterlist support for the input/output heap */
++struct starlet_ioh_sg {
++ void *buf;
++ size_t len;
++ dma_addr_t dma_addr;
++};
++
++/* inter-process communication device abstraction */
++struct starlet_ipc_device {
++ unsigned long flags;
++
++ void __iomem *io_base;
++ int irq;
++
++ struct dma_pool *dma_pool; /* to allocate requests */
++ struct starlet_ioh *ioh; /* to allocate special io buffers */
++
++ unsigned int random_id;
++
++ spinlock_t list_lock;
++ struct list_head outstanding_list;
++ unsigned long nr_outstanding;
++ struct list_head pending_list;
++ unsigned long nr_pending;
++
++ struct timer_list timer;
++
++ struct starlet_ipc_request *req; /* for requests causing a ios reboot */
++
++ struct device *dev;
++};
++
++/* iovec entry suitable for ioctlv */
++struct starlet_iovec {
++ dma_addr_t dma_addr;
++ u32 dma_len;
++};
++
++typedef int (*starlet_ipc_callback_t)(struct starlet_ipc_request *req);
++
++struct starlet_ipc_request {
++ /* begin starlet firmware request format */
++ u32 cmd; /* 0x00 */
++ s32 result; /* 0x04 */
++ union { /* 0x08 */
++ s32 fd;
++ u32 req_cmd;
++ };
++ union {
++ struct {
++ dma_addr_t pathname; /* 0x0c */
++ u32 mode; /* 0x10 */
++ } open;
++ struct {
++ u32 request; /* 0x0c */
++ dma_addr_t ibuf; /* 0x10 */
++ u32 ilen; /* 0x14 */
++ dma_addr_t obuf; /* 0x18 */
++ u32 olen; /* 0x1c */
++ } ioctl;
++ struct {
++ u32 request; /* 0x0c */
++ u32 argc_in; /* 0x10 */
++ u32 argc_io; /* 0x14 */
++ dma_addr_t iovec_da; /* 0x18 */
++ } ioctlv;
++ u32 argv[5]; /* 0x0c,0x10,0x14,0x18,0x1c */
++ };
++ /* end starlet firmware request format */
++
++ /*
++ * A signature is used to discard bogus requests from earlier
++ * IPC instances.
++ */
++ unsigned int sig;
++
++ dma_addr_t dma_addr; /* request dma address */
++
++ /* ioctlv related data */
++ struct starlet_iovec *iovec;
++ size_t iovec_size;
++
++ unsigned sgl_nents_in;
++ unsigned sgl_nents_io;
++ union {
++ struct scatterlist *sgl_in;
++ struct starlet_ioh_sg *ioh_sgl_in;
++ };
++ union {
++ struct scatterlist *sgl_io;
++ struct starlet_ioh_sg *ioh_sgl_io;
++ };
++
++ void *done_data;
++ starlet_ipc_callback_t done;
++
++ starlet_ipc_callback_t complete;
++
++ unsigned long jiffies;
++
++ struct list_head node; /* for queueing */
++
++ struct starlet_ipc_device *ipc_dev;
++};
++
++
++
++/* from starlet-malloc.c */
++
++extern int starlet_malloc_lib_bootstrap(struct resource *mem);
++
++extern void *starlet_kzalloc(size_t size, gfp_t flags);
++extern void starlet_kfree(void *ptr);
++
++extern void *starlet_ioh_kzalloc(size_t size);
++extern void starlet_ioh_kfree(void *ptr);
++
++extern unsigned long starlet_ioh_virt_to_phys(void *ptr);
++
++extern void starlet_ioh_sg_init_table(struct starlet_ioh_sg *sgl,
++ unsigned int nents);
++extern void starlet_ioh_sg_set_buf(struct starlet_ioh_sg *sg,
++ void *buf, size_t len);
++
++#define starlet_ioh_for_each_sg(sgl, sg, nr, __i) \
++ for (__i = 0, sg = (sgl); __i < nr; __i++, sg++)
++
++extern int starlet_ioh_dma_map_sg(struct device *dev,
++ struct starlet_ioh_sg *sgl, int nents,
++ enum dma_data_direction direction);
++extern void starlet_ioh_dma_unmap_sg(struct device *dev,
++ struct starlet_ioh_sg *sgl, int nents,
++ enum dma_data_direction direction);
++/* from starlet-ipc.c */
++
++extern struct starlet_ipc_device *starlet_ipc_get_device(void);
++
++extern struct starlet_ipc_request *
++starlet_ipc_alloc_request(struct starlet_ipc_device *ipc_dev, gfp_t flags);
++extern void starlet_ipc_free_request(struct starlet_ipc_request *req);
++
++
++extern int starlet_open(const char *pathname, int flags);
++extern int starlet_close(int fd);
++
++extern int starlet_ioctl(int fd, int request,
++ void *ibuf, size_t ilen,
++ void *obuf, size_t olen);
++extern int starlet_ioctl_nowait(int fd, int request,
++ void *ibuf, size_t ilen,
++ void *obuf, size_t olen,
++ starlet_ipc_callback_t callback,
++ void *arg);
++
++extern int starlet_ioctlv(int fd, int request,
++ unsigned int nents_in,
++ struct scatterlist *sgl_in,
++ unsigned int nents_out,
++ struct scatterlist *sgl_out);
++extern int starlet_ioctlv_nowait(int fd, int request,
++ unsigned int nents_in,
++ struct scatterlist *sgl_in,
++ unsigned int nents_out,
++ struct scatterlist *sgl_out,
++ starlet_ipc_callback_t callback,
++ void *arg);
++extern int starlet_ioctlv_and_reboot(int fd, int request,
++ unsigned int nents_in,
++ struct scatterlist *sgl_in,
++ unsigned int nents_out,
++ struct scatterlist *sgl_out);
++
++extern int starlet_ioh_ioctlv(int fd, int request,
++ unsigned int nents_in,
++ struct starlet_ioh_sg *ioh_sgl_in,
++ unsigned int nents_io,
++ struct starlet_ioh_sg *ioh_sgl_io);
++extern int starlet_ioh_ioctlv_nowait(int fd, int request,
++ unsigned int nents_in,
++ struct starlet_ioh_sg *ioh_sgl_in,
++ unsigned int nents_io,
++ struct starlet_ioh_sg *ioh_sgl_io,
++ starlet_ipc_callback_t callback,
++ void *arg);
++
++/* from starlet-stm.c */
++
++extern void starlet_stm_restart(void);
++extern void starlet_stm_power_off(void);
++
++#endif /* __ASM_POWERPC_STARLET_H */
+diff --git a/arch/powerpc/include/asm/udbg.h b/arch/powerpc/include/asm/udbg.h
+index 6418cee..11ecd37 100644
+--- a/arch/powerpc/include/asm/udbg.h
++++ b/arch/powerpc/include/asm/udbg.h
+@@ -50,6 +50,7 @@ extern void __init udbg_init_btext(void);
+ extern void __init udbg_init_44x_as1(void);
+ extern void __init udbg_init_40x_realmode(void);
+ extern void __init udbg_init_cpm(void);
++extern void __init udbg_init_usbgecko(void);
+
+ #endif /* __KERNEL__ */
+ #endif /* _ASM_POWERPC_UDBG_H */
+diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
+index 7e87195..daf94a5 100644
+--- a/arch/powerpc/kernel/cputable.c
++++ b/arch/powerpc/kernel/cputable.c
+@@ -644,11 +644,11 @@ static struct cpu_spec __initdata cpu_specs[] = {
+ .machine_check = machine_check_generic,
+ .platform = "ppc750",
+ },
+- { /* 750CL */
+- .pvr_mask = 0xfffff0f0,
+- .pvr_value = 0x00087010,
+- .cpu_name = "750CL",
+- .cpu_features = CPU_FTRS_750CL,
++ { /* 745/755 */
++ .pvr_mask = 0xfffff000,
++ .pvr_value = 0x00083000,
++ .cpu_name = "745/755",
++ .cpu_features = CPU_FTRS_750,
+ .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE,
+ .icache_bsize = 32,
+ .dcache_bsize = 32,
+@@ -658,11 +658,11 @@ static struct cpu_spec __initdata cpu_specs[] = {
+ .machine_check = machine_check_generic,
+ .platform = "ppc750",
+ },
+- { /* 745/755 */
+- .pvr_mask = 0xfffff000,
+- .pvr_value = 0x00083000,
+- .cpu_name = "745/755",
+- .cpu_features = CPU_FTRS_750,
++ { /* 750CL (and "Broadway") */
++ .pvr_mask = 0xfffff0e0,
++ .pvr_value = 0x00087000,
++ .cpu_name = "750CL",
++ .cpu_features = CPU_FTRS_750CL,
+ .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE,
+ .icache_bsize = 32,
+ .dcache_bsize = 32,
+diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/head_32.S
+index 0c32682..ae6825a 100644
+--- a/arch/powerpc/kernel/head_32.S
++++ b/arch/powerpc/kernel/head_32.S
+@@ -159,6 +159,9 @@ __after_mmu_off:
+ #ifdef CONFIG_PPC_EARLY_DEBUG_CPM
+ bl setup_cpm_bat
+ #endif
++#ifdef CONFIG_PPC_EARLY_DEBUG_USBGECKO
++ bl setup_usbgecko_bat
++#endif
+
+ /*
+ * Call setup_cpu for CPU 0 and initialize 6xx Idle
+@@ -1253,6 +1256,24 @@ setup_cpm_bat:
+ blr
+ #endif
+
++#ifdef CONFIG_PPC_EARLY_DEBUG_USBGECKO
++setup_usbgecko_bat:
++ /* prepare a BAT for early io */
++ lis r8, 0x0c00
++ ori r8, r8, 0x002a /* uncached, guarded ,rw */
++ lis r11, 0xcc00
++ ori r11, r11, 0x3 /* 128K */
++#ifdef CONFIG_WII
++ oris r8, r8, 0x0100
++ oris r11, r11, 0x0100
++#endif
++ mtspr SPRN_DBAT1L, r8
++ mtspr SPRN_DBAT1U, r11
++ sync
++ isync
++ blr
++#endif
++
+ #ifdef CONFIG_8260
+ /* Jump into the system reset for the rom.
+ * We first disable the MMU, and then jump to the ROM reset address.
+diff --git a/arch/powerpc/kernel/prom_init_check.sh b/arch/powerpc/kernel/prom_init_check.sh
+index ea3a2ec..980cd4e 100644
+--- a/arch/powerpc/kernel/prom_init_check.sh
++++ b/arch/powerpc/kernel/prom_init_check.sh
+@@ -17,7 +17,7 @@
+ # it to the list below:
+
+ WHITELIST="add_reloc_offset __bss_start __bss_stop copy_and_flush
+-_end enter_prom memcpy memset reloc_offset __secondary_hold
++_end enter_prom memcmp memcpy memset reloc_offset __secondary_hold
+ __secondary_hold_acknowledge __secondary_hold_spinloop __start
+ strcmp strcpy strlcpy strlen strncmp strstr logo_linux_clut224
+ reloc_got2 kernstart_addr memstart_addr"
+diff --git a/arch/powerpc/kernel/udbg.c b/arch/powerpc/kernel/udbg.c
+index 7d6c9bb..a85bfb0 100644
+--- a/arch/powerpc/kernel/udbg.c
++++ b/arch/powerpc/kernel/udbg.c
+@@ -59,6 +59,8 @@ void __init udbg_early_init(void)
+ udbg_init_40x_realmode();
+ #elif defined(CONFIG_PPC_EARLY_DEBUG_CPM)
+ udbg_init_cpm();
++#elif defined(CONFIG_PPC_EARLY_DEBUG_USBGECKO)
++ udbg_init_usbgecko();
+ #endif
+
+ #ifdef CONFIG_PPC_EARLY_DEBUG
+diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
+index c31d6d2..62f8954 100644
+--- a/arch/powerpc/mm/pgtable_32.c
++++ b/arch/powerpc/mm/pgtable_32.c
+@@ -199,9 +199,19 @@ __ioremap(phys_addr_t addr, unsigned long size, unsigned long flags)
+ * mem_init() sets high_memory so only do the check after that.
+ */
+ if (mem_init_done && (p < virt_to_phys(high_memory))) {
+- printk("__ioremap(): phys addr 0x%llx is RAM lr %p\n",
+- (unsigned long long)p, __builtin_return_address(0));
+- return NULL;
++ /*
++ * On some systems, though, we may want to remap normal RAM
++ * that we have memreserve'd at the device tree.
++ * But we can't do that safely if we are using BATs.
++ *
++ */
++ if (!__map_without_bats) {
++ printk(KERN_WARNING
++ "__ioremap(): phys addr 0x%llx is RAM lr %p\n",
++ (unsigned long long)p,
++ __builtin_return_address(0));
++ return NULL;
++ }
+ }
+
+ if (size == 0)
+diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
+index 548efa5..36e041c 100644
+--- a/arch/powerpc/platforms/Kconfig.cputype
++++ b/arch/powerpc/platforms/Kconfig.cputype
+@@ -250,7 +250,7 @@ config NR_CPUS
+
+ config NOT_COHERENT_CACHE
+ bool
+- depends on 4xx || 8xx || E200 || PPC_MPC512x
++ depends on 4xx || 8xx || E200 || PPC_MPC512x || GAMECUBE_COMMON
+ default y
+
+ config CHECK_CACHE_COHERENCY
+diff --git a/arch/powerpc/platforms/embedded6xx/Kconfig b/arch/powerpc/platforms/embedded6xx/Kconfig
+index 4f9f818..d5a76c3 100644
+--- a/arch/powerpc/platforms/embedded6xx/Kconfig
++++ b/arch/powerpc/platforms/embedded6xx/Kconfig
+@@ -90,3 +90,90 @@ config MPC10X_OPENPIC
+ config MPC10X_STORE_GATHERING
+ bool "Enable MPC10x store gathering"
+ depends on MPC10X_BRIDGE
++
++config GAMECUBE
++ bool "Nintendo-GameCube"
++ depends on EMBEDDED6xx
++ select GAMECUBE_COMMON
++ help
++ Select GAMECUBE if configuring for the Nintendo GameCube.
++ More information at: <http://gc-linux.sourceforge.net/>
++
++config WII
++ bool "Nintendo-Wii"
++ depends on EMBEDDED6xx
++ select GAMECUBE_COMMON
++ select PPC_LIB_RHEAP
++ help
++ Select WII if configuring for the Nintendo Wii.
++ More information at: <http://gc-linux.sourceforge.net/>
++
++config FLIPPER_PIC
++ bool
++ default n
++
++config GAMECUBE_COMMON
++ bool
++ select NOT_COHERENT_CACHE
++ select FLIPPER_PIC
++ default n
++
++config GAMECUBE_UDBG
++ bool "Nintendo GameCube/Wii udbg support"
++ depends on GAMECUBE_COMMON
++ default n
++ help
++ If you say yes to this option, you will be able to choose between
++ several udbg drivers available for the Nintendo GameCube/Wii.
++
++ If in doubt, say N here.
++
++choice
++ prompt "Nintendo GameCube/Wii udbg drivers"
++ depends on GAMECUBE_UDBG
++
++config USBGECKO_UDBG
++ bool "USB Gecko udbg console for the Nintendo GameCube/Wii"
++ help
++ If you say yes to this option, support will be included for the
++ USB Gecko adapter as an udbg console.
++ The USB Gecko is a EXI to USB Serial converter that can be plugged
++ into a memcard slot in the Nintendo GameCube/Wii.
++
++ This driver bypasses the EXI layer completely.
++
++ If in doubt, say N here.
++
++config GAMECUBE_VIDEO_UDBG
++ bool "Nintendo GameCube/Wii framebuffer udbg console"
++ select FONTS
++ select FONT_8x16
++ help
++ If you say yes to this option, support will be included for a
++ framebuffer based udbg console for the Nintendo GameCube/Wii.
++
++ If in doubt, say N here.
++
++endchoice
++
++config GAMECUBE_RSW
++ bool "Nintendo GameCube/Wii reset switch/button"
++ depends on GAMECUBE_COMMON
++ default y
++ help
++ If you say yes to this option, support will be included for the
++ reset switch/button of the Nintendo GameCube/Wii.
++
++ If in doubt, say Y here.
++
++config WII_GPIO
++ bool "Nintendo Wii GPIO support"
++ depends on GPIOLIB
++ default y
++ help
++ If you say yes to this option, support will be included for the
++ Nintendo Wii GPIO lines that control, for example, the sensor
++ bar IR leds, the front led, or the eject switch of the disk unit.
++
++ If in doubt, say Y here.
++
+diff --git a/arch/powerpc/platforms/embedded6xx/Makefile b/arch/powerpc/platforms/embedded6xx/Makefile
+index 0773c08..8a080ba 100644
+--- a/arch/powerpc/platforms/embedded6xx/Makefile
++++ b/arch/powerpc/platforms/embedded6xx/Makefile
+@@ -7,3 +7,12 @@ obj-$(CONFIG_STORCENTER) += storcenter.o
+ obj-$(CONFIG_PPC_HOLLY) += holly.o
+ obj-$(CONFIG_PPC_PRPMC2800) += prpmc2800.o
+ obj-$(CONFIG_PPC_C2K) += c2k.o
++obj-$(CONFIG_GAMECUBE) += gamecube.o gamecube_dev.o
++obj-$(CONFIG_WII) += wii.o wii_dev.o \
++ starlet-ipc.o starlet-malloc.o \
++ starlet-stm.o starlet-es.o
++obj-$(CONFIG_FLIPPER_PIC) += flipper-pic.o
++obj-$(CONFIG_USBGECKO_UDBG) += usbgecko_udbg.o
++obj-$(CONFIG_GAMECUBE_VIDEO_UDBG) += gcnvi_udbg.o
++obj-$(CONFIG_GAMECUBE_RSW) += gcn-rsw.o
++obj-$(CONFIG_WII_GPIO) += starlet-gpio.o
+diff --git a/arch/powerpc/platforms/embedded6xx/flipper-pic.c b/arch/powerpc/platforms/embedded6xx/flipper-pic.c
+new file mode 100644
+index 0000000..d836103
+--- /dev/null
++++ b/arch/powerpc/platforms/embedded6xx/flipper-pic.c
+@@ -0,0 +1,217 @@
++/*
++ * arch/powerpc/platforms/embedded6xx/flipper-pic.c
++ *
++ * Nintendo GameCube/Wii interrupt controller support.
++ * Copyright (C) 2004-2009 The GameCube Linux Team
++ * Copyright (C) 2007,2008,2009 Albert Herranz
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version 2
++ * of the License, or (at your option) any later version.
++ *
++ */
++
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/irq.h>
++#include <linux/of.h>
++#include <asm/io.h>
++
++#include "flipper-pic.h"
++
++
++#define DRV_MODULE_NAME "flipper-pic"
++
++#define drv_printk(level, format, arg...) \
++ printk(level DRV_MODULE_NAME ": " format , ## arg)
++
++
++/*
++ * IRQ chip hooks.
++ *
++ */
++
++static void flipper_pic_mask_and_ack(unsigned int virq)
++{
++ int irq = virq_to_hw(virq);
++ void __iomem *io_base = get_irq_chip_data(virq);
++
++ clear_bit(irq, io_base + FLIPPER_IMR);
++ set_bit(irq, io_base + FLIPPER_ICR);
++}
++
++static void flipper_pic_ack(unsigned int virq)
++{
++ int irq = virq_to_hw(virq);
++ void __iomem *io_base = get_irq_chip_data(virq);
++
++ set_bit(irq, io_base + FLIPPER_ICR);
++}
++
++static void flipper_pic_mask(unsigned int virq)
++{
++ int irq = virq_to_hw(virq);
++ void __iomem *io_base = get_irq_chip_data(virq);
++
++ clear_bit(irq, io_base + FLIPPER_IMR);
++}
++
++static void flipper_pic_unmask(unsigned int virq)
++{
++ int irq = virq_to_hw(virq);
++ void __iomem *io_base = get_irq_chip_data(virq);
++
++ set_bit(irq, io_base + FLIPPER_IMR);
++}
++
++
++static struct irq_chip flipper_pic = {
++ .typename = "flipper-pic",
++ .ack = flipper_pic_ack,
++ .mask_ack = flipper_pic_mask_and_ack,
++ .mask = flipper_pic_mask,
++ .unmask = flipper_pic_unmask,
++};
++
++/*
++ * IRQ host hooks.
++ *
++ */
++
++static struct irq_host *flipper_irq_host;
++
++static int flipper_pic_map(struct irq_host *h, unsigned int virq,
++ irq_hw_number_t hwirq)
++{
++ set_irq_chip_data(virq, h->host_data);
++ set_irq_chip_and_handler(virq, &flipper_pic, handle_level_irq);
++ return 0;
++}
++
++static void flipper_pic_unmap(struct irq_host *h, unsigned int irq)
++{
++ set_irq_chip_data(irq, NULL);
++ set_irq_chip(irq, NULL);
++}
++
++static int flipper_pic_match(struct irq_host *h, struct device_node *np)
++{
++ return 1;
++}
++
++
++static struct irq_host_ops flipper_irq_host_ops = {
++ .map = flipper_pic_map,
++ .unmap = flipper_pic_unmap,
++ .match = flipper_pic_match,
++};
++
++/*
++ * Platform hooks.
++ *
++ */
++
++struct irq_host * __init flipper_pic_init(struct device_node *np)
++{
++ struct irq_host *irq_host;
++ struct resource res;
++ void __iomem *io_base;
++ int retval;
++
++ retval = of_address_to_resource(np, 0, &res);
++ if (retval) {
++ drv_printk(KERN_ERR, "no io memory range found\n");
++ return NULL;
++ }
++ io_base = ioremap(res.start, res.end - res.start + 1);
++
++ drv_printk(KERN_INFO, "controller at 0x%08x mapped to 0x%p\n",
++ res.start, io_base);
++
++ /* mask and ack all IRQs */
++ out_be32(io_base + FLIPPER_IMR, 0x00000000);
++ out_be32(io_base + FLIPPER_ICR, 0xffffffff);
++
++ irq_host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, FLIPPER_NR_IRQS,
++ &flipper_irq_host_ops, -1);
++ if (!irq_host) {
++ drv_printk(KERN_ERR, "failed to allocate irq_host\n");
++ return NULL;
++ }
++
++ irq_host->host_data = io_base;
++
++ return irq_host;
++}
++
++unsigned int flipper_pic_get_irq(void)
++{
++ void __iomem *io_base = flipper_irq_host->host_data;
++ int irq;
++ u32 irq_status;
++
++ irq_status = in_be32(io_base + FLIPPER_ICR) &
++ in_be32(io_base + FLIPPER_IMR);
++ if (irq_status == 0)
++ return -1; /* no more IRQs pending */
++
++ __asm__ __volatile__("cntlzw %0,%1" : "=r"(irq) : "r"(irq_status));
++ return irq_linear_revmap(flipper_irq_host, 31 - irq);
++}
++
++/*
++ * Probe function.
++ *
++ */
++
++void __init flipper_pic_probe(void)
++{
++ struct device_node *np;
++
++ np = of_find_compatible_node(NULL, NULL, "nintendo,flipper-pic");
++ BUG_ON(!np);
++
++ flipper_irq_host = flipper_pic_init(np);
++ BUG_ON(!flipper_irq_host);
++
++ irq_set_default_host(flipper_irq_host);
++
++ of_node_put(np);
++}
++
++/*
++ * Misc functions related to the flipper chipset.
++ *
++ */
++
++/*
++ * Resets the platform.
++ */
++void flipper_platform_reset(void)
++{
++ void __iomem *io_base;
++
++ if (flipper_irq_host && flipper_irq_host->host_data) {
++ io_base = flipper_irq_host->host_data;
++ out_8(io_base + FLIPPER_RESET, 0x00);
++ }
++}
++
++/*
++ * Returns non-zero if the reset button is pressed.
++ */
++int flipper_is_reset_button_pressed(void)
++{
++ void __iomem *io_base;
++ u32 icr;
++
++ if (flipper_irq_host && flipper_irq_host->host_data) {
++ io_base = flipper_irq_host->host_data;
++ icr = in_be32(io_base + FLIPPER_ICR);
++ drv_printk(KERN_INFO, "%x\n", icr);
++ return !(icr & FLIPPER_ICR_RSS);
++ }
++ return 0;
++}
++
+diff --git a/arch/powerpc/platforms/embedded6xx/flipper-pic.h b/arch/powerpc/platforms/embedded6xx/flipper-pic.h
+new file mode 100644
+index 0000000..483bee7
+--- /dev/null
++++ b/arch/powerpc/platforms/embedded6xx/flipper-pic.h
+@@ -0,0 +1,41 @@
++/*
++ * arch/powerpc/platforms/embedded6xx/flipper-pic.h
++ *
++ * Nintendo GameCube/Wii interrupt controller support.
++ * Copyright (C) 2004-2009 The GameCube Linux Team
++ * Copyright (C) 2007,2008,2009 Albert Herranz
++ *
++ * 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.
++ *
++ */
++
++#ifndef __FLIPPER_PIC_H
++#define __FLIPPER_PIC_H
++
++#define FLIPPER_NR_IRQS 32
++
++/*
++ * Each interrupt has a corresponding bit in both
++ * the Interrupt Cause (ICR) and Interrupt Mask (IMR) registers.
++ *
++ * Enabling/disabling an interrupt line involves asserting/clearing
++ * the corresponding bit in IMR. ACK'ing a request simply involves
++ * asserting the corresponding bit in ICR.
++ */
++#define FLIPPER_ICR 0x00
++#define FLIPPER_ICR_RSS (1<<16) /* reset switch state */
++
++#define FLIPPER_IMR 0x04
++
++#define FLIPPER_RESET 0x24
++
++unsigned int flipper_pic_get_irq(void);
++void __init flipper_pic_probe(void);
++
++void flipper_platform_reset(void);
++int flipper_is_reset_button_pressed(void);
++
++#endif
+diff --git a/arch/powerpc/platforms/embedded6xx/gamecube.c b/arch/powerpc/platforms/embedded6xx/gamecube.c
+new file mode 100644
+index 0000000..b3b4db9
+--- /dev/null
++++ b/arch/powerpc/platforms/embedded6xx/gamecube.c
+@@ -0,0 +1,111 @@
++/*
++ * arch/powerpc/platforms/embedded6xx/gamecube.c
++ *
++ * Nintendo GameCube board-specific support
++ * Copyright (C) 2004-2009 The GameCube Linux Team
++ * Copyright (C) 2007,2008,2009 Albert Herranz
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version 2
++ * of the License, or (at your option) any later version.
++ *
++ */
++
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/irq.h>
++#include <linux/kexec.h>
++#include <linux/seq_file.h>
++
++#include <asm/io.h>
++#include <asm/machdep.h>
++#include <asm/prom.h>
++#include <asm/time.h>
++#include <asm/udbg.h>
++
++#include "flipper-pic.h"
++#include "usbgecko_udbg.h"
++
++
++static void gamecube_restart(char *cmd)
++{
++ local_irq_disable();
++ flipper_platform_reset();
++ /* spin until power button pressed */
++ for (;;)
++ cpu_relax();
++}
++
++static void gamecube_power_off(void)
++{
++ local_irq_disable();
++ /* spin until power button pressed */
++ for (;;)
++ cpu_relax();
++}
++
++static void gamecube_halt(void)
++{
++ gamecube_restart(NULL);
++}
++
++static void gamecube_show_cpuinfo(struct seq_file *m)
++{
++ seq_printf(m, "vendor\t\t: IBM\n");
++ seq_printf(m, "machine\t\t: Nintendo GameCube\n");
++}
++
++static void gamecube_setup_arch(void)
++{
++}
++
++static void __init gamecube_init_early(void)
++{
++ ug_udbg_init();
++}
++
++static int __init gamecube_probe(void)
++{
++ unsigned long dt_root;
++
++ dt_root = of_get_flat_dt_root();
++ if (!of_flat_dt_is_compatible(dt_root, "nintendo,gamecube"))
++ return 0;
++
++ return 1;
++}
++
++static void gamecube_shutdown(void)
++{
++ /* currently not used */
++}
++
++#ifdef CONFIG_KEXEC
++static int gamecube_kexec_prepare(struct kimage *image)
++{
++ return 0;
++}
++#endif /* CONFIG_KEXEC */
++
++
++define_machine(gamecube) {
++ .name = "gamecube",
++ .probe = gamecube_probe,
++ .setup_arch = gamecube_setup_arch,
++ .init_early = gamecube_init_early,
++ .show_cpuinfo = gamecube_show_cpuinfo,
++ .restart = gamecube_restart,
++ .power_off = gamecube_power_off,
++ .halt = gamecube_halt,
++ .init_IRQ = flipper_pic_probe,
++ .get_irq = flipper_pic_get_irq,
++ .calibrate_decr = generic_calibrate_decr,
++ .progress = udbg_progress,
++ .machine_shutdown = gamecube_shutdown,
++#ifdef CONFIG_KEXEC
++ .machine_kexec_prepare = gamecube_kexec_prepare,
++ .machine_kexec = default_machine_kexec,
++#endif
++};
++
+diff --git a/arch/powerpc/platforms/embedded6xx/gamecube_dev.c b/arch/powerpc/platforms/embedded6xx/gamecube_dev.c
+new file mode 100644
+index 0000000..13e1f73
+--- /dev/null
++++ b/arch/powerpc/platforms/embedded6xx/gamecube_dev.c
+@@ -0,0 +1,34 @@
++/*
++ * arch/powerpc/platforms/embedded6xx/gamecube_dev.c
++ *
++ * Nintendo GameCube platform device setup.
++ * Copyright (C) 2008-2009 The GameCube Linux Team
++ * Copyright (C) 2008,2009 Albert Herranz
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version 2
++ * of the License, or (at your option) any later version.
++ *
++ */
++
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/of_platform.h>
++
++#include <asm/machdep.h>
++
++static struct of_device_id gamecube_of_bus[] = {
++ { .compatible = "nintendo,flipper", },
++ { },
++};
++
++static int __init gamecube_device_probe(void)
++{
++ if (!machine_is(gamecube))
++ return 0;
++
++ of_platform_bus_probe(NULL, gamecube_of_bus, NULL);
++ return 0;
++}
++device_initcall(gamecube_device_probe);
+diff --git a/arch/powerpc/platforms/embedded6xx/gcn-rsw.c b/arch/powerpc/platforms/embedded6xx/gcn-rsw.c
+new file mode 100644
+index 0000000..0bb20f0
+--- /dev/null
++++ b/arch/powerpc/platforms/embedded6xx/gcn-rsw.c
+@@ -0,0 +1,308 @@
++/*
++ * arch/powerpc/platforms/embedded6xx/gcn-rsw.c
++ *
++ * Nintendo GameCube/Wii reset switch (RSW) driver.
++ * Copyright (C) 2004-2009 The GameCube Linux Team
++ * Copyright (C) 2004 Stefan Esser
++ * Copyright (C) 2004,2005,2008,2009 Albert Herranz
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version 2
++ * of the License, or (at your option) any later version.
++ *
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/of_platform.h>
++#include <linux/interrupt.h>
++#include <linux/io.h>
++#include <linux/spinlock.h>
++#include <linux/delay.h>
++#include <linux/reboot.h>
++#include <linux/kexec.h>
++
++/* for flipper hardware registers */
++#include "flipper-pic.h"
++
++#define DRV_MODULE_NAME "gcn-rsw"
++#define DRV_DESCRIPTION "Nintendo GameCube/Wii Reset SWitch (RSW) driver"
++#define DRV_AUTHOR "Stefan Esser <se@nopiracy.de>, " \
++ "Albert Herranz"
++
++static char rsw_driver_version[] = "1.0i";
++
++#define drv_printk(level, format, arg...) \
++ printk(level DRV_MODULE_NAME ": " format , ## arg)
++
++
++#define RSW_NORMAL_TIMEOUT 3 /* seconds */
++#define RSW_EMERGENCY_PUSHES 10
++
++enum rsw_state {
++ IDLE = 0, /* nothing to do */
++ NORMAL_RESET, /* reboot requested */
++ EMERGENCY_RESET, /* try emergency reboot */
++};
++
++struct rsw_drvdata {
++ enum rsw_state state;
++ struct timer_list timer;
++ unsigned long jiffies;
++ int pushes;
++ int timeout;
++ spinlock_t lock;
++
++ void __iomem *io_base;
++ unsigned int irq;
++
++ struct device *dev;
++};
++
++
++/*
++ * Tells if the reset button is pressed.
++ */
++static int rsw_is_button_pressed(void __iomem *io_base)
++{
++ u32 icr = in_be32(io_base + FLIPPER_ICR);
++
++ drv_printk(KERN_INFO, "%x\n", icr);
++ return !(icr & FLIPPER_ICR_RSS);
++}
++
++/*
++ * Invokes a normal system restart.
++ */
++static void rsw_normal_restart(unsigned long dummy)
++{
++ ctrl_alt_del();
++}
++
++/*
++ * Performs a low level system restart.
++ */
++static void rsw_emergency_restart(void)
++{
++#ifdef CONFIG_KEXEC
++ struct kimage *image;
++ image = xchg(&kexec_image, 0);
++ if (image)
++ machine_kexec(image);
++#endif
++ machine_restart(NULL);
++}
++
++/*
++ * Handles the interrupt associated to the reset button.
++ */
++static irqreturn_t rsw_handler(int irq, void *data)
++{
++ struct rsw_drvdata *drvdata = (struct rsw_drvdata *)data;
++ unsigned long flags;
++
++ if (!rsw_is_button_pressed(drvdata->io_base)) {
++ /* nothing to do */
++ return IRQ_HANDLED;
++ }
++
++ spin_lock_irqsave(&drvdata->lock, flags);
++
++ /* someone pushed the reset button */
++ switch (drvdata->state) {
++ case IDLE:
++ drvdata->state = NORMAL_RESET;
++ printk(KERN_EMERG "Rebooting in %d seconds...\n",
++ drvdata->timeout);
++ printk(KERN_WARNING
++ "Push the Reset button again to cancel reboot!\n");
++
++ /* schedule a reboot in a few seconds */
++ init_timer(&drvdata->timer);
++ drvdata->timer.expires = jiffies + drvdata->timeout * HZ;
++ drvdata->timer.function =
++ (void (*)(unsigned long))rsw_normal_restart;
++ add_timer(&drvdata->timer);
++ drvdata->jiffies = jiffies;
++ break;
++ case NORMAL_RESET:
++ if (time_before(jiffies,
++ drvdata->jiffies + drvdata->timeout * HZ)) {
++ /* the reset button was hit again before deadline */
++ del_timer(&drvdata->timer);
++ drvdata->state = IDLE;
++ printk(KERN_EMERG "Reboot cancelled!\n");
++ } else {
++ /*
++ * Time expired. System should be now restarting.
++ * Go to emergency mode in case something goes bad.
++ */
++ drvdata->state = EMERGENCY_RESET;
++ drvdata->pushes = 0;
++ printk(KERN_WARNING
++ "SWITCHED TO EMERGENCY RESET MODE!\n"
++ "Push %d times the Reset button to force"
++ " a hard reset!\n"
++ "NOTE THAT THIS COULD CAUSE DATA LOSS!\n",
++ RSW_EMERGENCY_PUSHES);
++ }
++ break;
++ case EMERGENCY_RESET:
++ /* force a hard reset if the user insists ... */
++ if (++drvdata->pushes >= RSW_EMERGENCY_PUSHES) {
++ spin_unlock_irqrestore(&drvdata->lock, flags);
++ rsw_emergency_restart();
++ return IRQ_HANDLED;
++ } else {
++ printk(KERN_INFO "%d/%d\n", drvdata->pushes,
++ RSW_EMERGENCY_PUSHES);
++ }
++ break;
++ }
++
++ spin_unlock_irqrestore(&drvdata->lock, flags);
++
++ return IRQ_HANDLED;
++}
++
++/*
++ * Setup routines.
++ *
++ */
++
++static int rsw_init(struct rsw_drvdata *drvdata, struct resource *mem, int irq)
++{
++ int retval;
++
++ drvdata->io_base = ioremap(mem->start, mem->end - mem->start + 1);
++ drvdata->irq = irq;
++
++ spin_lock_init(&drvdata->lock);
++ drvdata->state = IDLE;
++ drvdata->timeout = RSW_NORMAL_TIMEOUT;
++
++ retval = request_irq(drvdata->irq, rsw_handler, 0,
++ DRV_MODULE_NAME, drvdata);
++ if (retval) {
++ drv_printk(KERN_ERR, "request of IRQ %d failed\n",
++ drvdata->irq);
++ }
++ return retval;
++}
++
++static void rsw_exit(struct rsw_drvdata *drvdata)
++{
++ free_irq(drvdata->irq, drvdata);
++ if (drvdata->io_base) {
++ iounmap(drvdata->io_base);
++ drvdata->io_base = NULL;
++ }
++}
++
++/*
++ * Driver model helper routines.
++ *
++ */
++
++static int rsw_do_probe(struct device *dev, struct resource *mem, int irq)
++{
++ struct rsw_drvdata *drvdata;
++ int retval;
++
++ drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL);
++ if (!drvdata) {
++ drv_printk(KERN_ERR, "failed to allocate rsw_drvdata\n");
++ return -ENOMEM;
++ }
++ dev_set_drvdata(dev, drvdata);
++ drvdata->dev = dev;
++
++ retval = rsw_init(drvdata, mem, irq);
++ if (retval) {
++ dev_set_drvdata(dev, NULL);
++ kfree(drvdata);
++ }
++ return retval;
++}
++
++static int rsw_do_remove(struct device *dev)
++{
++ struct rsw_drvdata *drvdata = dev_get_drvdata(dev);
++
++ if (drvdata) {
++ rsw_exit(drvdata);
++ dev_set_drvdata(dev, NULL);
++ kfree(drvdata);
++ return 0;
++ }
++ return -ENODEV;
++}
++
++/*
++ * OF platform driver hooks.
++ *
++ */
++
++static int __init rsw_of_probe(struct of_device *odev,
++ const struct of_device_id *match)
++{
++ struct resource mem;
++ int retval;
++
++ retval = of_address_to_resource(odev->node, 0, &mem);
++ if (retval) {
++ drv_printk(KERN_ERR, "no io memory range found\n");
++ return -ENODEV;
++ }
++
++ return rsw_do_probe(&odev->dev,
++ &mem, irq_of_parse_and_map(odev->node, 0));
++}
++
++static int __exit rsw_of_remove(struct of_device *odev)
++{
++ return rsw_do_remove(&odev->dev);
++}
++
++static struct of_device_id rsw_of_match[] = {
++ {.compatible = "nintendo,flipper-resetswitch"},
++ {.compatible = "nintendo,hollywood-resetswitch"},
++ {},
++};
++
++MODULE_DEVICE_TABLE(of, rsw_of_match);
++
++static struct of_platform_driver rsw_of_driver = {
++ .owner = THIS_MODULE,
++ .name = DRV_MODULE_NAME,
++ .match_table = rsw_of_match,
++ .probe = rsw_of_probe,
++ .remove = rsw_of_remove,
++};
++
++/*
++ * Kernel module hooks.
++ *
++ */
++
++static int __init rsw_init_module(void)
++{
++ drv_printk(KERN_INFO, "%s - version %s\n", DRV_DESCRIPTION,
++ rsw_driver_version);
++
++ return of_register_platform_driver(&rsw_of_driver);
++}
++
++static void __exit rsw_exit_module(void)
++{
++ of_unregister_platform_driver(&rsw_of_driver);
++}
++
++module_init(rsw_init_module);
++module_exit(rsw_exit_module);
++
++MODULE_DESCRIPTION(DRV_DESCRIPTION);
++MODULE_AUTHOR(DRV_AUTHOR);
++MODULE_LICENSE("GPL");
+diff --git a/arch/powerpc/platforms/embedded6xx/gcnvi_udbg.c b/arch/powerpc/platforms/embedded6xx/gcnvi_udbg.c
+new file mode 100644
+index 0000000..6b63e48
+--- /dev/null
++++ b/arch/powerpc/platforms/embedded6xx/gcnvi_udbg.c
+@@ -0,0 +1,315 @@
++/*
++ * arch/powerpc/platforms/embedded6xx/gcnvi_udbg.c
++ *
++ * Nintendo GameCube/Wii framebuffer udbg output support.
++ * Copyright (C) 2008-2009 The GameCube Linux Team
++ * Copyright (C) 2008,2009 Albert Herranz
++ *
++ * Based on arch/ppc/platforms/gcn-con.c
++ *
++ * Nintendo GameCube early debug console
++ * Copyright (C) 2004-2005 The GameCube Linux Team
++ *
++ * Based on console.c by tmbinc.
++ *
++ * 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/io.h>
++#include <linux/string.h>
++#include <linux/console.h>
++#include <linux/font.h>
++#include <asm/prom.h>
++#include <asm/udbg.h>
++#include <mm/mmu_decl.h>
++
++#include "gcnvi_udbg.h"
++
++/*
++ * Console settings.
++ *
++ */
++#define SCREEN_WIDTH 640
++#define SCREEN_HEIGHT 480
++
++#define FONT_XSIZE 8
++#define FONT_YSIZE 16
++#define FONT_XFACTOR 1
++#define FONT_YFACTOR 1
++#define FONT_XGAP 2
++#define FONT_YGAP 0
++
++#define COLOR_WHITE 0xFF80FF80
++#define COLOR_BLACK 0x00800080
++
++struct console_data {
++ unsigned char *framebuffer;
++ int xres, yres, stride;
++
++ const unsigned char *font;
++
++ int cursor_x, cursor_y;
++ int foreground, background;
++
++ int border_left, border_right, border_top, border_bottom;
++
++ int scrolled_lines;
++};
++
++static struct console_data *default_console;
++
++#if 0
++static int console_set_color(int background, int foreground)
++{
++ default_console->foreground = foreground;
++ default_console->background = background;
++ return 0;
++}
++#endif
++
++static void console_drawc(struct console_data *con, int x, int y,
++ unsigned char c)
++{
++ int ax, ay;
++ unsigned long *ptr;
++ unsigned long color, color2x[2];
++ int bits;
++
++ x >>= 1;
++ ptr = (unsigned long *)(con->framebuffer + con->stride * y + x * 4);
++
++ for (ay = 0; ay < FONT_YSIZE; ay++) {
++#if FONT_XFACTOR == 2
++ for (ax = 0; ax < 8; ax++) {
++ if ((con->font[c * FONT_YSIZE + ay] << ax) & 0x80)
++ color = con->foreground;
++ else
++ color = con->background;
++#if FONT_YFACTOR == 2
++ /* pixel doubling: we write u32 */
++ ptr[ay * 2 * con->stride / 4 + ax] = color;
++ /* line doubling */
++ ptr[(ay * 2 + 1) * con->stride / 4 + ax] = color;
++#else
++ ptr[ay * con->stride / 4 + ax] = color;
++#endif
++ }
++#else
++ for (ax = 0; ax < 4; ax++) {
++ bits = (con->font[c * FONT_YSIZE + ay] << (ax * 2));
++ if (bits & 0x80)
++ color2x[0] = con->foreground;
++ else
++ color2x[0] = con->background;
++ if (bits & 0x40)
++ color2x[1] = con->foreground;
++ else
++ color2x[1] = con->background;
++ ptr[ay * con->stride / 4 + ax] =
++ (color2x[0] & 0xFFFF00FF) |
++ (color2x[1] & 0x0000FF00);
++ }
++#endif
++ }
++}
++
++static void console_putc(struct console_data *con, char c)
++{
++ int cnt;
++ unsigned long *ptr;
++
++ switch (c) {
++ case '\n':
++ con->cursor_y += FONT_YSIZE * FONT_YFACTOR + FONT_YGAP;
++ con->cursor_x = con->border_left;
++ break;
++ default:
++ console_drawc(con, con->cursor_x, con->cursor_y, c);
++ con->cursor_x += FONT_XSIZE * FONT_XFACTOR + FONT_XGAP;
++ if ((con->cursor_x + (FONT_XSIZE * FONT_XFACTOR)) >
++ con->border_right) {
++ con->cursor_y += FONT_YSIZE * FONT_YFACTOR + FONT_YGAP;
++ con->cursor_x = con->border_left;
++ }
++ }
++ if ((con->cursor_y + FONT_YSIZE * FONT_YFACTOR) >= con->border_bottom) {
++ memcpy(con->framebuffer,
++ con->framebuffer +
++ con->stride * (FONT_YSIZE * FONT_YFACTOR + FONT_YGAP),
++ con->stride * con->yres - FONT_YSIZE);
++ cnt = (con->stride * (FONT_YSIZE*FONT_YFACTOR + FONT_YGAP)) / 4;
++ ptr = (unsigned long *)(con->framebuffer +
++ con->stride * (con->yres - FONT_YSIZE));
++ while (cnt--)
++ *ptr++ = con->background;
++ con->cursor_y -= FONT_YSIZE * FONT_YFACTOR + FONT_YGAP;
++ }
++}
++
++static void console_init(struct console_data *con, void *framebuffer,
++ int xres, int yres, int stride)
++{
++ int c;
++ unsigned long *p;
++
++ con->framebuffer = framebuffer;
++ con->xres = xres;
++ con->yres = yres;
++ con->border_left = 0;
++ con->border_top = 0;
++ con->border_right = con->xres;
++ con->border_bottom = con->yres;
++ con->stride = stride;
++ con->cursor_x = con->cursor_y = 0;
++
++ con->font = font_vga_8x16.data;
++
++ con->foreground = COLOR_WHITE;
++ con->background = COLOR_BLACK;
++
++ con->scrolled_lines = 0;
++
++ /* clear screen */
++ c = con->xres * con->yres / 2;
++ p = (unsigned long *)con->framebuffer;
++ while (c--)
++ *p++ = con->background;
++
++ default_console = con;
++}
++
++/*
++ * Video hardware setup.
++ *
++ */
++
++/* Hardware registers */
++#define VI_TFBL 0x1c
++#define VI_TFBR 0x20
++#define VI_BFBL 0x24
++#define VI_BFBR 0x28
++#define VI_DPV 0x2c
++
++/* NTSC settings (640x480) */
++static const u32 vi_Mode640X480NtscYUV16[32] = {
++ 0x0F060001, 0x476901AD, 0x02EA5140, 0x00030018,
++ 0x00020019, 0x410C410C, 0x40ED40ED, 0x00435A4E,
++ 0x00000000, 0x00435A4E, 0x00000000, 0x00000000,
++ 0x110701AE, 0x10010001, 0x00010001, 0x00010001,
++ 0x00000000, 0x00000000, 0x28500100, 0x1AE771F0,
++ 0x0DB4A574, 0x00C1188E, 0xC4C0CBE2, 0xFCECDECF,
++ 0x13130F08, 0x00080C0F, 0x00FF0000, 0x00000000,
++ 0x02800000, 0x000000FF, 0x00FF00FF, 0x00FF00FF
++};
++
++static void vi_setup_video(void __iomem *io_base, unsigned long xfb_start)
++{
++ const u32 *regs = vi_Mode640X480NtscYUV16;
++ int i;
++
++ /* initialize video registers */
++ for (i = 0; i < 7; i++)
++ out_be32(io_base + i * sizeof(__u32), regs[i]);
++
++ out_be32(io_base + VI_TFBR, regs[VI_TFBR / sizeof(__u32)]);
++ out_be32(io_base + VI_BFBR, regs[VI_BFBR / sizeof(__u32)]);
++ out_be32(io_base + VI_DPV, regs[VI_DPV / sizeof(__u32)]);
++ for (i = 16; i < 32; i++)
++ out_be32(io_base + i * sizeof(__u32), regs[i]);
++
++ /* set framebuffer address, interlaced mode */
++ out_be32(io_base + VI_TFBL, 0x10000000 | (xfb_start >> 5));
++ xfb_start += 2 * SCREEN_WIDTH; /* line length */
++ out_be32(io_base + VI_BFBL, 0x10000000 | (xfb_start >> 5));
++}
++
++/*
++ * Retrieves and prepares the virtual address needed to access the hardware.
++ */
++static void __iomem *vi_setup_io_base(struct device_node *np)
++{
++ phys_addr_t paddr;
++ const unsigned int *reg;
++ void *io_base = NULL;
++
++ reg = of_get_property(np, "reg", NULL);
++ if (reg) {
++ paddr = of_translate_address(np, reg);
++ if (paddr)
++ io_base = ioremap(paddr, reg[1]);
++ }
++ return io_base;
++}
++
++/*
++ * udbg functions.
++ *
++ */
++
++/* OF bindings */
++static struct of_device_id gcnvi_udbg_ids[] __initdata = {
++ { .compatible = "nintendo,hollywood-video", },
++ { .compatible = "nintendo,gamecube-video", },
++};
++
++static struct console_data gcnvi_udbg_console;
++
++/*
++ * Transmits a character.
++ */
++void gcnvi_udbg_putc(char ch)
++{
++ if (default_console)
++ console_putc(default_console, ch);
++}
++
++/*
++ * Initializes udbg support.
++ */
++void __init gcnvi_udbg_init(void)
++{
++ unsigned long xfb_start = 0, xfb_size = 0;
++ struct device_node *np = NULL;
++ const unsigned long *prop;
++ void *screen_base;
++ void *io_base;
++
++ for_each_matching_node(np, gcnvi_udbg_ids) {
++ if (np)
++ break;
++ }
++ if (!np)
++ return;
++
++ prop = of_get_property(np, "xfb-start", NULL);
++ if (prop) {
++ xfb_start = *prop;
++ prop = of_get_property(np, "xfb-size", NULL);
++ if (prop)
++ xfb_size = *prop;
++ }
++ io_base = vi_setup_io_base(np);
++
++ of_node_put(np);
++
++ if (!prop || !io_base)
++ return;
++
++ if (xfb_size < 2 * SCREEN_WIDTH * SCREEN_HEIGHT)
++ return;
++
++ screen_base = ioremap_nocache(xfb_start, xfb_size);
++ if (!screen_base)
++ return;
++
++ vi_setup_video(io_base, xfb_start);
++ console_init(&gcnvi_udbg_console, screen_base,
++ SCREEN_WIDTH, SCREEN_HEIGHT, 2 * SCREEN_WIDTH);
++
++ udbg_putc = gcnvi_udbg_putc;
++ printk(KERN_INFO "gcnvi_udbg: ready\n");
++}
+diff --git a/arch/powerpc/platforms/embedded6xx/gcnvi_udbg.h b/arch/powerpc/platforms/embedded6xx/gcnvi_udbg.h
+new file mode 100644
+index 0000000..daba549
+--- /dev/null
++++ b/arch/powerpc/platforms/embedded6xx/gcnvi_udbg.h
+@@ -0,0 +1,30 @@
++/*
++ * arch/powerpc/platforms/embedded6xx/gcnvi_udbg.h
++ *
++ * Nintendo GameCube/Wii framebuffer udbg output support.
++ * Copyright (C) 2008-2009 The GameCube Linux Team
++ * Copyright (C) 2008,2009 Albert Herranz
++ *
++ * 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.
++ *
++ */
++
++#ifndef __GCNVI_UDBG_H
++#define __GCNVI_UDBG_H
++
++#ifdef CONFIG_GAMECUBE_VIDEO_UDBG
++
++extern void __init gcnvi_udbg_init(void);
++
++#else
++
++static inline void __init gcnvi_udbg_init(void)
++{
++}
++
++#endif /* CONFIG_GAMECUBE_VIDEO_UDBG */
++
++#endif /* __GCNVI_UDBG_H */
+diff --git a/arch/powerpc/platforms/embedded6xx/starlet-es.c b/arch/powerpc/platforms/embedded6xx/starlet-es.c
+new file mode 100644
+index 0000000..a975f64
+--- /dev/null
++++ b/arch/powerpc/platforms/embedded6xx/starlet-es.c
+@@ -0,0 +1,592 @@
++/*
++ * arch/powerpc/platforms/embedded6xx/starlet-es.c
++ *
++ * Nintendo Wii starlet ES routines
++ * Copyright (C) 2008-2009 The GameCube Linux Team
++ * Copyright (C) 2008,2009 Albert Herranz
++ *
++ * 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.
++ *
++ */
++
++#define DEBUG
++
++#include <linux/kernel.h>
++#include <linux/of_platform.h>
++#include <linux/scatterlist.h>
++#include <asm/starlet.h>
++
++#define DRV_MODULE_NAME "starlet-es"
++#define DRV_DESCRIPTION "Nintendo Wii starlet ES driver"
++#define DRV_AUTHOR "Albert Herranz"
++
++static const char starlet_es_driver_version[] = "0.2i";
++
++#define DBG(fmt, arg...) pr_debug(fmt, ##arg)
++
++#define drv_printk(level, format, arg...) \
++ printk(level DRV_MODULE_NAME ": " format , ## arg)
++
++struct starlet_es_device {
++ int fd;
++
++ struct device *dev;
++};
++
++struct starlet_es_ticket_limit {
++ u32 tag;
++ u32 value;
++} __attribute__((packed));
++
++struct starlet_es_ticket_view {
++ u32 view;
++ u64 ticketid;
++ u32 devicetype;
++ u64 title;
++ u16 access_mask;
++ u8 reserved[0x3c];
++ u8 cidx_mask[0x40];
++ u16 padding;
++ struct starlet_es_ticket_limit limits[8];
++} __attribute__((packed));
++
++#if 0
++struct starlet_es_ticket {
++ char issuer[0x40];
++ u8 fill[63]; /* TODO: not really fill */
++ u8 title_key[16];
++ u8 fill2;
++ u64 ticketid;
++ u32 devicetype;
++ u64 title;
++ u16 access_mask;
++ u8 reserved[0x3c];
++ u8 cidx_mask[0x40];
++ u16 padding;
++ struct starlet_es_ticket_limit limits[8];
++} __attribute__((packed));
++#endif
++
++/*
++ * /dev/es
++ *
++ */
++
++#define ES_IOCTLV_LAUNCHTITLE 0x08
++#define ES_IOCTLV_GETTITLECOUNT 0x0e
++#define ES_IOCTLV_GETTITLES 0x0f
++#define ES_IOCTLV_GETTICKETVIEWCOUNT 0x12
++#define ES_IOCTLV_GETTICKETVIEWS 0x13
++
++static const char dev_es[] = "/dev/es";
++
++/*
++ * Handy small buffer routines.
++ * We use a small static aligned buffer to avoid allocations for short-lived
++ * operations involving 1 to 4 byte data transfers to/from IOS.
++ *
++ */
++
++static u32 es_small_buf[L1_CACHE_BYTES / sizeof(u32)]
++ __attribute__ ((aligned(STARLET_IPC_DMA_ALIGN + 1)));
++static const size_t es_small_buf_size = sizeof(es_small_buf_size);
++static DEFINE_MUTEX(es_small_buf_lock);
++
++static u32 *es_small_buf_get(void)
++{
++ u32 *buf;
++
++ if (!mutex_trylock(&es_small_buf_lock))
++ buf = starlet_kzalloc(es_small_buf_size, GFP_KERNEL);
++ else {
++ memset(es_small_buf, 0, es_small_buf_size);
++ buf = es_small_buf;
++ }
++
++ return buf;
++}
++
++static void es_small_buf_put(u32 *buf)
++{
++ if (buf == es_small_buf)
++ mutex_unlock(&es_small_buf_lock);
++ else
++ starlet_kfree(buf);
++}
++
++#if 0
++static void es_small_buf_dump(void)
++{
++ int i;
++ size_t nelems = sizeof(es_small_buf) / sizeof(u32);
++
++ drv_printk(KERN_INFO, "es_small_buf[%d]= {\n", nelems);
++ for (i = 0; i < nelems; i++)
++ drv_printk(KERN_INFO, "%08x, ", es_small_buf[i]);
++ drv_printk(KERN_INFO, "\n}\n");
++
++}
++#endif
++
++/*
++ *
++ *
++ */
++
++static struct starlet_es_device *starlet_es_device_instance;
++
++/**
++ *
++ */
++struct starlet_es_device *starlet_es_get_device(void)
++{
++ if (!starlet_es_device_instance)
++ drv_printk(KERN_ERR, "uninitialized device instance!\n");
++ return starlet_es_device_instance;
++}
++EXPORT_SYMBOL_GPL(starlet_es_get_device);
++
++/**
++ *
++ */
++int starlet_es_get_title_count(unsigned long *count)
++{
++ struct starlet_es_device *es_dev = starlet_es_get_device();
++ struct scatterlist io[1];
++ u32 *count_buf;
++ int error;
++
++ if (!es_dev)
++ return -ENODEV;
++
++ count_buf = es_small_buf_get();
++ if (!count_buf)
++ return -ENOMEM;
++
++ *count_buf = 0;
++ sg_init_one(io, count_buf, sizeof(*count_buf));
++
++ error = starlet_ioctlv(es_dev->fd, ES_IOCTLV_GETTITLECOUNT,
++ 0, NULL, 1, io);
++ if (error)
++ DBG("%s: error=%d (%08x)\n", __func__, error, error);
++ else
++ *count = *count_buf;
++
++ es_small_buf_put(count_buf);
++
++ return error;
++}
++
++/**
++ *
++ */
++int starlet_es_get_titles(u64 *titles, unsigned long count)
++{
++ struct starlet_es_device *es_dev = starlet_es_get_device();
++ struct scatterlist in[1], io[1];
++ u32 *count_buf;
++ int error;
++
++ if (!es_dev)
++ return -ENODEV;
++
++ count_buf = es_small_buf_get();
++ if (!count_buf)
++ return -ENOMEM;
++
++ *count_buf = count;
++ sg_init_one(in, count_buf, sizeof(*count_buf));
++ sg_init_one(io, titles, sizeof(*titles)*count);
++
++ error = starlet_ioctlv(es_dev->fd, ES_IOCTLV_GETTITLES,
++ 1, in, 1, io);
++ if (error)
++ DBG("%s: error=%d (%08x)\n", __func__, error, error);
++
++ es_small_buf_put(count_buf);
++
++ return error;
++}
++
++/**
++ *
++ */
++int starlet_es_get_ticket_view_count(u64 title, unsigned long *count)
++{
++ struct starlet_es_device *es_dev = starlet_es_get_device();
++ struct scatterlist in[1], io[1];
++ u64 *title_buf;
++ u32 *count_buf;
++ int error;
++
++ if (!es_dev)
++ return -ENODEV;
++
++ title_buf = starlet_kzalloc(sizeof(*title_buf), GFP_KERNEL);
++ if (!title_buf)
++ return -ENOMEM;
++
++ count_buf = es_small_buf_get();
++ if (!count_buf) {
++ starlet_kfree(title_buf);
++ return -ENOMEM;
++ }
++
++ *title_buf = title;
++ sg_init_one(in, title_buf, sizeof(*title_buf));
++ sg_init_one(io, count_buf, sizeof(*count_buf));
++
++ error = starlet_ioctlv(es_dev->fd, ES_IOCTLV_GETTICKETVIEWCOUNT,
++ 1, in, 1, io);
++ if (error)
++ DBG("%s: error=%d (%08x)\n", __func__, error, error);
++ else
++ *count = *count_buf;
++
++ starlet_kfree(title_buf);
++ es_small_buf_put(count_buf);
++
++ return error;
++}
++
++/**
++ *
++ */
++int starlet_es_get_ticket_views(u64 title,
++ struct starlet_es_ticket_view *views,
++ unsigned long count)
++{
++ struct starlet_es_device *es_dev = starlet_es_get_device();
++ struct scatterlist in[2], io[1];
++ u32 *count_buf;
++ u64 *title_buf;
++ int error;
++
++ if (!es_dev)
++ return -ENODEV;
++
++ title_buf = starlet_kzalloc(sizeof(*title_buf), GFP_KERNEL);
++ if (!title_buf)
++ return -ENOMEM;
++
++ count_buf = es_small_buf_get();
++ if (!count_buf) {
++ starlet_kfree(title_buf);
++ return -ENOMEM;
++ }
++
++ *title_buf = title;
++ *count_buf = count;
++ sg_init_table(in, 2);
++ sg_set_buf(&in[0], title_buf, sizeof(*title_buf));
++ sg_set_buf(&in[1], count_buf, sizeof(*count_buf));
++
++ sg_init_one(io, views, sizeof(*views)*count);
++
++ error = starlet_ioctlv(es_dev->fd, ES_IOCTLV_GETTICKETVIEWS,
++ 2, in, 1, io);
++ if (error)
++ DBG("%s: error=%d (%08x)\n", __func__, error, error);
++
++ es_small_buf_put(count_buf);
++ starlet_kfree(title_buf);
++
++ return error;
++}
++
++/**
++ *
++ */
++int starlet_es_launch_title_view(u64 title, struct starlet_es_ticket_view *view)
++{
++ struct starlet_es_device *es_dev = starlet_es_get_device();
++ struct scatterlist in[2];
++ u64 *title_buf;
++ int error;
++
++ if (!es_dev)
++ return -ENODEV;
++
++ title_buf = starlet_kzalloc(sizeof(*title_buf), GFP_KERNEL);
++ if (!title_buf)
++ return -ENOMEM;
++
++ *title_buf = title;
++ sg_init_table(in, 2);
++ sg_set_buf(&in[0], title_buf, sizeof(*title_buf));
++ sg_set_buf(&in[1], view, sizeof(*view));
++
++ error = starlet_ioctlv_and_reboot(es_dev->fd,
++ ES_IOCTLV_LAUNCHTITLE,
++ 2, in, 0, NULL);
++ if (error)
++ DBG("%s: error=%d (%08x)\n", __func__, error, error);
++
++ starlet_kfree(title_buf);
++
++ return error;
++}
++
++
++
++/*
++ * Setup routines.
++ *
++ */
++
++#define STARLET_ES_IOS_MIN 30
++#define STARLET_ES_IOS_MAX 36
++
++static int starlet_es_find_newest_title(struct starlet_es_device *es_dev,
++ u64 *title,
++ u64 title_min, u64 title_max)
++{
++ u64 *titles;
++ u64 candidate;
++ unsigned long count;
++ int found, i;
++ int error;
++
++ error = starlet_es_get_title_count(&count);
++ if (error)
++ return error;
++
++ titles = starlet_kzalloc(sizeof(*titles)*count, GFP_KERNEL);
++ if (!titles) {
++ DBG("%s: out of memory\n", __func__);
++ return -ENOMEM;
++ }
++
++ error = starlet_es_get_titles(titles, count);
++ if (error) {
++ starlet_kfree(titles);
++ return error;
++ }
++
++ found = 0;
++ candidate = title_min;
++ for (i = 0; i < count; i++) {
++ if (titles[i] > candidate && titles[i] <= title_max) {
++ candidate = titles[i];
++ found = 1;
++ }
++ }
++
++ starlet_kfree(titles);
++
++ if (!found)
++ return 0;
++
++ *title = candidate;
++
++ return 1;
++}
++
++static int starlet_es_launch_title(struct starlet_es_device *es_dev, u64 title)
++{
++ struct starlet_es_ticket_view *views;
++ unsigned long count;
++ int error;
++
++ error = starlet_es_get_ticket_view_count(title, &count);
++ if (error)
++ return error;
++
++ views = starlet_kzalloc(sizeof(*views)*count, GFP_KERNEL);
++ if (!views) {
++ DBG("%s: out of memory\n", __func__);
++ return -ENOMEM;
++ }
++
++ error = starlet_es_get_ticket_views(title, views, count);
++ if (error) {
++ starlet_kfree(views);
++ return error;
++ }
++
++ drv_printk(KERN_INFO, "launching IOS%u\n", (u32)(title & 0xffffffff));
++ error = starlet_es_launch_title_view(title, views); /* first view */
++
++ starlet_kfree(views);
++
++ return error;
++}
++
++static int starlet_es_load_preferred(struct starlet_es_device *es_dev,
++ u64 ios_min, u64 ios_max)
++{
++ u64 title;
++ int error;
++
++ error = starlet_es_find_newest_title(es_dev, &title, ios_min, ios_max);
++ if (!error)
++ return -EINVAL;
++ if (error > 0)
++ error = starlet_es_launch_title(es_dev, title);
++
++ return error;
++}
++
++static int starlet_nwc24_stop_scheduler(void)
++{
++ void *obuf;
++ const size_t osize = 0x20;
++ int fd;
++ int error = 0;
++
++ obuf = es_small_buf_get();
++ if (!obuf)
++ return -ENOMEM;
++
++ fd = starlet_open("/dev/net/kd/request", 0);
++ if (fd >= 0) {
++ error = starlet_ioctl(fd, 1, NULL, 0, obuf, osize);
++ starlet_close(fd);
++ }
++
++ es_small_buf_put(obuf);
++
++ if (error)
++ DBG("%s: error=%d (%08x)\n", __func__, error, error);
++ return error;
++}
++
++static int starlet_es_init(struct starlet_es_device *es_dev)
++{
++ u64 ios_min, ios_max;
++ int error;
++
++ error = starlet_open(dev_es, 0);
++ if (error >= 0) {
++ starlet_es_device_instance = es_dev;
++ es_dev->fd = error;
++
++ ios_min = 0x100000000ULL | STARLET_ES_IOS_MIN;
++ ios_max = 0x100000000ULL | STARLET_ES_IOS_MAX;
++
++ error = starlet_es_load_preferred(es_dev, ios_min, ios_max);
++ if (error) {
++ drv_printk(KERN_WARNING, "unable to load preferred"
++ " IOS version (min %llx, max %llx)\n",
++ ios_min, ios_max);
++ }
++ }
++
++ /*
++ * Try to disable the Nintendo Wifi Connect 24 scheduler.
++ * And do this even if we failed to load our preferred IOS.
++ *
++ * When the scheduler kicks in, starlet IPC calls from Broadway fail.
++ */
++ starlet_nwc24_stop_scheduler();
++
++ return error;
++}
++
++static void starlet_es_exit(struct starlet_es_device *es_dev)
++{
++ starlet_es_device_instance = NULL;
++ starlet_close(es_dev->fd);
++ es_dev->fd = -1;
++}
++
++
++/*
++ * Driver model helper routines.
++ *
++ */
++
++static int starlet_es_do_probe(struct device *dev)
++{
++ struct starlet_es_device *es_dev;
++ int retval;
++
++ es_dev = kzalloc(sizeof(*es_dev), GFP_KERNEL);
++ if (!es_dev) {
++ drv_printk(KERN_ERR, "failed to allocate es_dev\n");
++ return -ENOMEM;
++ }
++ dev_set_drvdata(dev, es_dev);
++ es_dev->dev = dev;
++
++ retval = starlet_es_init(es_dev);
++ if (retval) {
++ dev_set_drvdata(dev, NULL);
++ kfree(es_dev);
++ }
++ return retval;
++}
++
++static int starlet_es_do_remove(struct device *dev)
++{
++ struct starlet_es_device *es_dev = dev_get_drvdata(dev);
++
++ if (es_dev) {
++ starlet_es_exit(es_dev);
++ dev_set_drvdata(dev, NULL);
++ kfree(es_dev);
++ return 0;
++ }
++ return -ENODEV;
++}
++
++/*
++ * OF platform driver hooks.
++ *
++ */
++
++static int starlet_es_of_probe(struct of_device *odev,
++ const struct of_device_id *dev_id)
++{
++ return starlet_es_do_probe(&odev->dev);
++}
++
++static int starlet_es_of_remove(struct of_device *odev)
++{
++ return starlet_es_do_remove(&odev->dev);
++}
++
++static struct of_device_id starlet_es_of_match[] = {
++ { .compatible = "nintendo,starlet-es" },
++ { },
++};
++
++MODULE_DEVICE_TABLE(of, starlet_es_of_match);
++
++static struct of_platform_driver starlet_es_of_driver = {
++ .owner = THIS_MODULE,
++ .name = DRV_MODULE_NAME,
++ .match_table = starlet_es_of_match,
++ .probe = starlet_es_of_probe,
++ .remove = starlet_es_of_remove,
++};
++
++/*
++ * Kernel module interface hooks.
++ *
++ */
++
++static int __init starlet_es_init_module(void)
++{
++ drv_printk(KERN_INFO, "%s - version %s\n", DRV_DESCRIPTION,
++ starlet_es_driver_version);
++
++ return of_register_platform_driver(&starlet_es_of_driver);
++}
++
++static void __exit starlet_es_exit_module(void)
++{
++ of_unregister_platform_driver(&starlet_es_of_driver);
++}
++
++module_init(starlet_es_init_module);
++module_exit(starlet_es_exit_module);
++
++MODULE_DESCRIPTION(DRV_DESCRIPTION);
++MODULE_AUTHOR(DRV_AUTHOR);
++MODULE_LICENSE("GPL");
++
+diff --git a/arch/powerpc/platforms/embedded6xx/starlet-gpio.c b/arch/powerpc/platforms/embedded6xx/starlet-gpio.c
+new file mode 100644
+index 0000000..abdae88
+--- /dev/null
++++ b/arch/powerpc/platforms/embedded6xx/starlet-gpio.c
+@@ -0,0 +1,134 @@
++/*
++ * arch/powerpc/platforms/embedded6xx/starlet-gpio.c
++ *
++ * Nintendo Wii starlet GPIO driver
++ * Copyright (C) 2008-2009 The GameCube Linux Team
++ * Copyright (C) 2008,2009 Albert Herranz
++ *
++ * 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/io.h>
++#include <linux/kernel.h>
++#include <linux/of.h>
++#include <linux/of_gpio.h>
++#include <linux/of_platform.h>
++
++struct stgpio_chip {
++ struct of_mm_gpio_chip mmchip;
++ spinlock_t lock;
++};
++
++struct stgpio_regs {
++ __be32 out, dir, in;
++};
++
++
++static inline struct stgpio_chip *
++to_stgpio_chip(struct of_mm_gpio_chip *mm_gc)
++{
++ return container_of(mm_gc, struct stgpio_chip, mmchip);
++}
++
++static int stgpio_get(struct gpio_chip *gc, unsigned int gpio)
++{
++ struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
++ struct stgpio_regs __iomem *regs = mm_gc->regs;
++ u32 pin_mask = 1 << (31 - gpio);
++ unsigned int val;
++
++ val = !!(in_be32(&regs->in) & pin_mask);
++
++ pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
++
++ return val;
++}
++
++static void stgpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
++{
++ struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
++ struct stgpio_chip *st_gc = to_stgpio_chip(mm_gc);
++ struct stgpio_regs __iomem *regs = mm_gc->regs;
++ u32 pin_mask = 1 << (31 - gpio);
++ u32 data;
++ unsigned long flags;
++
++ spin_lock_irqsave(&st_gc->lock, flags);
++ data = in_be32(&regs->in) & ~pin_mask;
++ if (val)
++ data |= pin_mask;
++ out_be32(&regs->out, data);
++ spin_unlock_irqrestore(&st_gc->lock, flags);
++
++ pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
++}
++
++static int stgpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
++{
++ struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
++ struct stgpio_regs __iomem *regs = mm_gc->regs;
++ u32 pin_mask = 1 << (31 - gpio);
++
++ clrbits32(&regs->dir, pin_mask);
++
++ return 0;
++}
++
++static int stgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
++{
++ struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
++ struct stgpio_regs __iomem *regs = mm_gc->regs;
++ u32 pin_mask = 1 << (31 - gpio);
++
++ setbits32(&regs->dir, pin_mask);
++ stgpio_set(gc, gpio, val);
++
++ return 0;
++}
++
++int stgpio_add32(struct device_node *np)
++{
++ struct of_mm_gpio_chip *mm_gc;
++ struct of_gpio_chip *of_gc;
++ struct gpio_chip *gc;
++ struct stgpio_chip *st_gc;
++
++ st_gc = kzalloc(sizeof(*st_gc), GFP_KERNEL);
++ if (!st_gc)
++ return -ENOMEM;
++
++ spin_lock_init(&st_gc->lock);
++ mm_gc = &st_gc->mmchip;
++ of_gc = &mm_gc->of_gc;
++ gc = &of_gc->gc;
++
++ of_gc->gpio_cells = 1;
++
++ gc->ngpio = 32;
++ gc->direction_input = stgpio_dir_in;
++ gc->direction_output = stgpio_dir_out;
++ gc->get = stgpio_get;
++ gc->set = stgpio_set;
++
++ return of_mm_gpiochip_add(np, mm_gc);
++}
++
++static int stgpio_init(void)
++{
++ struct device_node *np;
++ int error;
++
++ for_each_compatible_node(np, NULL, "nintendo,starlet-gpio") {
++ error = stgpio_add32(np);
++ if (error < 0)
++ printk(KERN_ERR "starlet-gpio: error %d adding gpios"
++ " for %s\n", error, np->full_name);
++ }
++ return 0; /* whatever */
++}
++arch_initcall(stgpio_init);
++
+diff --git a/arch/powerpc/platforms/embedded6xx/starlet-ipc.c b/arch/powerpc/platforms/embedded6xx/starlet-ipc.c
+new file mode 100644
+index 0000000..fa91b7a
+--- /dev/null
++++ b/arch/powerpc/platforms/embedded6xx/starlet-ipc.c
+@@ -0,0 +1,1488 @@
++/*
++ * arch/powerpc/platforms/embedded6xx/starlet-ipc.c
++ *
++ * Nintendo Wii starlet IPC driver
++ * Copyright (C) 2008-2009 The GameCube Linux Team
++ * Copyright (C) 2008,2009 Albert Herranz
++ *
++ * 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.
++ *
++ */
++
++#define DEBUG
++
++/*#define DBG(fmt, arg...) pr_debug(fmt, ##arg)*/
++#define DBG(fmt, arg...) drv_printk(KERN_INFO, fmt, ##arg)
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/of_platform.h>
++#include <linux/ioport.h>
++#include <linux/interrupt.h>
++#include <linux/jiffies.h>
++#include <linux/dmapool.h>
++#include <linux/dma-mapping.h>
++#include <linux/random.h>
++#include <linux/scatterlist.h>
++#include <linux/string.h>
++#include <asm/io.h>
++#include <asm/bitops.h>
++
++#include <asm/starlet.h>
++
++
++#define DRV_MODULE_NAME "starlet-ipc"
++#define DRV_DESCRIPTION "Nintendo Wii starlet IPC driver"
++#define DRV_AUTHOR "Albert Herranz"
++
++static char starlet_ipc_driver_version[] = "0.2i";
++
++#define drv_printk(level, format, arg...) \
++ printk(level DRV_MODULE_NAME ": " format , ## arg)
++
++/*
++ * Hardware registers
++ */
++#define STARLET_IPC_TXBUF 0x00 /* data from cpu to starlet */
++
++#define STARLET_IPC_CSR 0x04
++#define STARLET_IPC_CSR_TSTART (1<<0) /* start transmit */
++#define STARLET_IPC_CSR_TBEI (1<<1) /* tx buf empty int */
++#define STARLET_IPC_CSR_RBFI (1<<2) /* rx buf full int */
++#define STARLET_IPC_CSR_INT (1<<3) /* interrupt ack */
++#define STARLET_IPC_CSR_RBFIMASK (1<<4) /* rx buf full int mask */
++#define STARLET_IPC_CSR_TBEIMASK (1<<5) /* tx buf empty int mask */
++
++#define STARLET_IPC_RXBUF 0x08 /* data from starlet to cpu */
++
++#define STARLET_IPC_ISR 0x30
++
++/* IOS calls */
++#define STARLET_IOS_OPEN 0x01
++#define STARLET_IOS_CLOSE 0x02
++#define STARLET_IOS_IOCTL 0x06
++#define STARLET_IOS_IOCTLV 0x07
++
++
++/* starlet_ipc_device flags */
++enum {
++ __TX_INUSE = 0, /* tx buffer in use flag */
++ __REBOOT, /* request causes IOS reboot */
++};
++
++/*
++ *
++ * Hardware.
++ */
++
++/*
++ * Update control and status register.
++ */
++static inline void starlet_ipc_update_csr(void __iomem *io_base, u32 val)
++{
++ u32 csr;
++
++ csr = in_be32(io_base + STARLET_IPC_CSR);
++ /* preserve interrupt masks */
++ csr &= STARLET_IPC_CSR_RBFIMASK | STARLET_IPC_CSR_TBEIMASK;
++ csr |= val;
++ out_be32(io_base + STARLET_IPC_CSR, csr);
++}
++
++/*
++ * Put data for starlet in the transmit fifo.
++ */
++static inline void starlet_ipc_sendto(void __iomem *io_base, u32 data)
++{
++ out_be32(io_base + STARLET_IPC_TXBUF, data);
++}
++
++/*
++ * Get data from starlet out the receive fifo.
++ */
++static inline u32 starlet_ipc_recvfrom(void __iomem *io_base)
++{
++ return in_be32(io_base + STARLET_IPC_RXBUF);
++}
++
++/*
++ * Issue an end-of-interrupt sequence.
++ */
++static void starlet_ipc_eoi(void __iomem *io_base)
++{
++ starlet_ipc_update_csr(io_base, STARLET_IPC_CSR_INT);
++}
++
++/*
++ * Calm the hardware down.
++ */
++static void starlet_ipc_quiesce(struct starlet_ipc_device *ipc_dev)
++{
++ u32 csr;
++
++ /* ack and disable MBOX? and REPLY interrupts */
++ csr = in_be32(ipc_dev->io_base + STARLET_IPC_CSR);
++ csr &= ~(STARLET_IPC_CSR_TBEIMASK | STARLET_IPC_CSR_RBFIMASK);
++ csr |= STARLET_IPC_CSR_TBEI | STARLET_IPC_CSR_RBFI;
++ out_be32(ipc_dev->io_base + STARLET_IPC_CSR, csr);
++}
++
++/*
++ * Request routines.
++ *
++ */
++
++#if 0
++
++#define __case_string(_s) \
++case _s: \
++ str = #_s; \
++ break;
++
++static char *stipc_cmd_string(u32 cmd)
++{
++ char *str = "unknown";
++
++ switch (cmd) {
++__case_string(STARLET_IOS_OPEN)
++__case_string(STARLET_IOS_CLOSE)
++__case_string(STARLET_IOS_IOCTL)
++__case_string(STARLET_IOS_IOCTLV)
++ }
++ return str;
++}
++
++static void starlet_ipc_pretty_print_request(struct starlet_ipc_request *req)
++{
++ drv_printk(KERN_INFO, "\n"
++ " struct starlet_ipc_request = {\n"
++ " cmd = %s (0x%08x)\n"
++ " result = %d (0x%08x)%s\n"
++ " seconds_elapsed = %u\n"
++ " dma_addr = %p\n"
++ " };\n"
++ ,
++ stipc_cmd_string(req->cmd), req->cmd,
++ req->result, req->result,
++ (req->result == 0xdeadbeef) ? " /* pending */" : "",
++ jiffies_to_msecs(jiffies - req->jiffies) / 1000,
++ (void *)req->dma_addr
++ );
++}
++
++#endif
++
++static void starlet_ipc_debug_print_request(struct starlet_ipc_request *req)
++{
++#if 0
++ DBG("cmd=%x, result=%x, fd=%x, dma_addr=%p\n",
++ req->cmd, req->result, req->fd, (void *)req->dma_addr);
++#endif
++}
++
++struct starlet_ipc_request *
++starlet_ipc_alloc_request(struct starlet_ipc_device *ipc_dev, gfp_t flags)
++{
++ struct starlet_ipc_request *req;
++ dma_addr_t dma_addr;
++
++ req = dma_pool_alloc(ipc_dev->dma_pool, flags, &dma_addr);
++ if (req) {
++ memset(req, 0, sizeof(*req));
++ req->ipc_dev = ipc_dev;
++ req->result = 0xdeadbeef;
++ req->sig = ipc_dev->random_id;
++ req->dma_addr = dma_addr;
++ INIT_LIST_HEAD(&req->node);
++ }
++ return req;
++}
++
++void starlet_ipc_free_request(struct starlet_ipc_request *req)
++{
++ dma_pool_free(req->ipc_dev->dma_pool, req, req->dma_addr);
++}
++
++static void starlet_ipc_start_request(struct starlet_ipc_request *req)
++{
++ struct starlet_ipc_device *ipc_dev = req->ipc_dev;
++ void __iomem *io_base = ipc_dev->io_base;
++ unsigned long flags;
++
++ starlet_ipc_debug_print_request(req);
++
++ spin_lock_irqsave(&ipc_dev->list_lock, flags);
++ list_add_tail(&req->node, &ipc_dev->outstanding_list);
++ ipc_dev->nr_outstanding++;
++ req->jiffies = jiffies;
++ spin_unlock_irqrestore(&ipc_dev->list_lock, flags);
++
++ starlet_ipc_sendto(io_base, (u32) req->dma_addr);
++ starlet_ipc_update_csr(io_base, STARLET_IPC_CSR_TSTART);
++}
++
++static void starlet_ipc_complete_request(struct starlet_ipc_request *req)
++{
++ struct starlet_ipc_device *ipc_dev = req->ipc_dev;
++ unsigned long flags;
++
++ spin_lock_irqsave(&ipc_dev->list_lock, flags);
++ list_del_init(&req->node);
++ ipc_dev->nr_outstanding--;
++ spin_unlock_irqrestore(&ipc_dev->list_lock, flags);
++
++ starlet_ipc_debug_print_request(req);
++
++ /* per request completion callback */
++ if (req->complete)
++ req->complete(req);
++
++ /* async callback */
++ if (req->done)
++ req->done(req);
++}
++
++static void starlet_ipc_submit_request(struct starlet_ipc_request *req)
++{
++ struct starlet_ipc_device *ipc_dev = req->ipc_dev;
++ unsigned long flags;
++
++ if (test_and_set_bit(__TX_INUSE, &ipc_dev->flags)) {
++ spin_lock_irqsave(&ipc_dev->list_lock, flags);
++ list_add_tail(&req->node, &ipc_dev->pending_list);
++ ipc_dev->nr_pending++;
++ spin_unlock_irqrestore(&ipc_dev->list_lock, flags);
++ } else {
++ starlet_ipc_start_request(req);
++ }
++}
++
++static struct starlet_ipc_request *
++starlet_ipc_find_request_by_bus_addr(struct starlet_ipc_device *ipc_dev,
++ dma_addr_t req_bus_addr)
++{
++ struct starlet_ipc_request *req;
++ unsigned long flags;
++
++ spin_lock_irqsave(&ipc_dev->list_lock, flags);
++ list_for_each_entry(req, &ipc_dev->outstanding_list, node) {
++ if (req && req->sig != ipc_dev->random_id) {
++ drv_printk(KERN_ERR, "IPC trash detected\n");
++ ipc_dev->nr_outstanding = 0;
++ INIT_LIST_HEAD(&ipc_dev->outstanding_list);
++ INIT_LIST_HEAD(&req->node);
++ spin_unlock_irqrestore(&ipc_dev->list_lock, flags);
++ return NULL;
++ }
++ if (req && req_bus_addr == req->dma_addr) {
++ spin_unlock_irqrestore(&ipc_dev->list_lock, flags);
++ return req;
++ }
++ }
++ spin_unlock_irqrestore(&ipc_dev->list_lock, flags);
++ return NULL;
++}
++
++/*
++ * Interrupt handlers.
++ *
++ */
++
++/*
++ * Transmit Buffer Empty Interrupt dispatcher.
++ */
++static int starlet_ipc_dispatch_tbei(struct starlet_ipc_device *ipc_dev)
++{
++ void __iomem *io_base = ipc_dev->io_base;
++ struct starlet_ipc_request *req = NULL;
++ struct list_head *pending = &ipc_dev->pending_list;
++ unsigned long flags;
++
++ spin_lock_irqsave(&ipc_dev->list_lock, flags);
++ if (!list_empty(pending)) {
++ req = list_entry(pending->next, struct starlet_ipc_request,
++ node);
++ list_del_init(&req->node);
++ ipc_dev->nr_pending--;
++ }
++ spin_unlock_irqrestore(&ipc_dev->list_lock, flags);
++ if (req) {
++ starlet_ipc_start_request(req);
++ } else {
++ if (!test_and_clear_bit(__TX_INUSE, &ipc_dev->flags)) {
++ /* we get two consecutive TBEIs on reboot */
++ if (test_and_clear_bit(__REBOOT, &ipc_dev->flags)) {
++ req = ipc_dev->req;
++ ipc_dev->req = NULL;
++ if (req) {
++ starlet_ipc_complete_request(req);
++ req->result = 0;
++ }
++ starlet_ipc_eoi(io_base);
++ }
++ }
++ }
++
++ return IRQ_HANDLED;
++}
++
++/*
++ * Receive Buffer Full Interrupt dispatcher.
++ */
++static int starlet_ipc_dispatch_rbfi(struct starlet_ipc_device *ipc_dev)
++{
++ void __iomem *io_base = ipc_dev->io_base;
++ struct starlet_ipc_request *req;
++ unsigned long req_bus_addr;
++
++ req_bus_addr = starlet_ipc_recvfrom(io_base);
++ if (!req_bus_addr)
++ return IRQ_NONE;
++
++ req = starlet_ipc_find_request_by_bus_addr(ipc_dev, req_bus_addr);
++ if (req) {
++ starlet_ipc_complete_request(req);
++ } else {
++ drv_printk(KERN_WARNING, "unknown request, bus=%p\n",
++ (void *)req_bus_addr);
++ }
++ starlet_ipc_eoi(io_base);
++ return IRQ_HANDLED;
++}
++
++typedef int (*ipc_handler_t) (struct starlet_ipc_device *);
++
++static int
++starlet_ipc_cond_dispatch_irq(struct starlet_ipc_device *ipc_dev,
++ u32 irqmask, u32 irq, ipc_handler_t handler)
++{
++ void __iomem *io_base = ipc_dev->io_base;
++ u32 csr;
++ int retval = IRQ_NONE;
++
++ csr = in_be32(io_base + STARLET_IPC_CSR);
++ if ((csr & (irqmask | irq)) == (irqmask | irq)) {
++ /* early ack */
++ starlet_ipc_update_csr(io_base, irq);
++ out_be32(io_base + STARLET_IPC_ISR, 0x40000000); /* huh? */
++ retval = handler(ipc_dev);
++ }
++ return retval;
++}
++
++static irqreturn_t starlet_ipc_handler(int irq, void *data)
++{
++ struct starlet_ipc_device *ipc_dev = (struct starlet_ipc_device *)data;
++ int handled = 0;
++ int retval;
++
++ /* starlet acked a request */
++ retval = starlet_ipc_cond_dispatch_irq(ipc_dev,
++ STARLET_IPC_CSR_TBEIMASK,
++ STARLET_IPC_CSR_TBEI,
++ starlet_ipc_dispatch_tbei);
++ if (retval == IRQ_HANDLED)
++ handled++;
++
++ /* starlet delivered a reply */
++ retval = starlet_ipc_cond_dispatch_irq(ipc_dev,
++ STARLET_IPC_CSR_RBFIMASK,
++ STARLET_IPC_CSR_RBFI,
++ starlet_ipc_dispatch_rbfi);
++ if (retval == IRQ_HANDLED)
++ handled++;
++
++ if (!handled)
++ return IRQ_NONE;
++
++ return IRQ_HANDLED;
++}
++
++/*
++ * IPC Calls.
++ *
++ */
++
++static int starlet_ipc_call_done(struct starlet_ipc_request *req)
++{
++ complete(req->done_data);
++ return 0;
++}
++
++static int starlet_ipc_call(struct starlet_ipc_request *req)
++{
++ DECLARE_COMPLETION(complete);
++
++ req->done_data = &complete;
++ req->done = starlet_ipc_call_done;
++ starlet_ipc_submit_request(req);
++ wait_for_completion(&complete);
++ return req->result;
++}
++
++static void starlet_ipc_call_nowait(struct starlet_ipc_request *req,
++ starlet_ipc_callback_t callback, void *arg)
++{
++ req->done_data = arg;
++ req->done = callback;
++ starlet_ipc_submit_request(req);
++}
++
++/*
++ *
++ * IOS High level interfaces.
++ */
++
++static struct starlet_ipc_device *starlet_ipc_device_instance;
++
++/**
++ *
++ */
++struct starlet_ipc_device *starlet_ipc_get_device(void)
++{
++ if (!starlet_ipc_device_instance)
++ drv_printk(KERN_ERR, "uninitialized device instance!\n");
++ return starlet_ipc_device_instance;
++}
++EXPORT_SYMBOL_GPL(starlet_ipc_get_device);
++
++/**
++ *
++ */
++int starlet_open(const char *pathname, int flags)
++{
++#define STSD_OPEN_BUF_SIZE 64
++ static char open_buf[STSD_OPEN_BUF_SIZE]
++ __attribute__ ((aligned(STARLET_IPC_DMA_ALIGN + 1)));
++ static DEFINE_MUTEX(open_buf_lock);
++
++ struct starlet_ipc_device *ipc_dev = starlet_ipc_get_device();
++ struct starlet_ipc_request *req;
++ dma_addr_t dma_addr;
++ char *local_pathname = NULL;
++ size_t len;
++ int error = -ENOMEM;
++
++ if (!ipc_dev)
++ return -ENODEV;
++
++ req = starlet_ipc_alloc_request(ipc_dev, GFP_KERNEL);
++ if (req) {
++ len = strlen(pathname) + 1;
++ if (len < sizeof(open_buf)) {
++ if (mutex_trylock(&open_buf_lock))
++ local_pathname = open_buf;
++ }
++ if (!local_pathname) {
++ local_pathname = starlet_kzalloc(len, GFP_KERNEL);
++ if (!local_pathname) {
++ starlet_ipc_free_request(req);
++ return -ENOMEM;
++ }
++ }
++
++ strncpy(local_pathname, pathname, len-1);
++ local_pathname[len-1] = 0;
++ dma_addr = dma_map_single(ipc_dev->dev, local_pathname, len,
++ DMA_TO_DEVICE);
++
++ req->cmd = STARLET_IOS_OPEN;
++ req->open.pathname = dma_addr; /* bus address */
++ req->open.mode = flags;
++ error = starlet_ipc_call(req);
++
++ dma_unmap_single(ipc_dev->dev, dma_addr, len, DMA_TO_DEVICE);
++
++ if (local_pathname == open_buf)
++ mutex_unlock(&open_buf_lock);
++ else
++ starlet_kfree(local_pathname);
++
++ starlet_ipc_free_request(req);
++ }
++ if (error < 0)
++ DBG("%s: error=%d (%x)\n", __func__, error, error);
++ return error;
++}
++EXPORT_SYMBOL_GPL(starlet_open);
++
++/*
++ *
++ */
++int starlet_close(int fd)
++{
++ struct starlet_ipc_device *ipc_dev = starlet_ipc_get_device();
++ struct starlet_ipc_request *req;
++ int error = -ENOMEM;
++
++ if (!ipc_dev)
++ return -ENODEV;
++
++ req = starlet_ipc_alloc_request(ipc_dev, GFP_KERNEL);
++ if (req) {
++ req->cmd = STARLET_IOS_CLOSE;
++ req->fd = fd;
++ error = starlet_ipc_call(req);
++ starlet_ipc_free_request(req);
++ }
++ return error;
++}
++EXPORT_SYMBOL_GPL(starlet_close);
++
++
++/*
++ * starlet_ioctl*
++ *
++ */
++
++static int starlet_ioctl_dma_complete(struct starlet_ipc_request *req)
++{
++ return 0;
++}
++
++/*
++ *
++ */
++int starlet_ioctl_dma_prepare(struct starlet_ipc_request *req,
++ int fd, int request,
++ dma_addr_t ibuf, size_t ilen,
++ dma_addr_t obuf, size_t olen)
++{
++ struct starlet_ipc_device *ipc_dev = starlet_ipc_get_device();
++
++ if (!ipc_dev)
++ return -ENODEV;
++
++ req->cmd = STARLET_IOS_IOCTL;
++ req->fd = fd;
++ req->ioctl.request = (u32) request;
++ req->ioctl.ibuf = ibuf;
++ req->ioctl.ilen = ilen;
++ req->ioctl.obuf = obuf;
++ req->ioctl.olen = olen;
++ req->complete = starlet_ioctl_dma_complete;
++
++ return 0;
++}
++
++/*
++ *
++ */
++int starlet_ioctl_dma(int fd, int request,
++ dma_addr_t ibuf, size_t ilen,
++ dma_addr_t obuf, size_t olen)
++{
++ struct starlet_ipc_device *ipc_dev = starlet_ipc_get_device();
++ struct starlet_ipc_request *req;
++ int error;
++
++ req = starlet_ipc_alloc_request(ipc_dev, GFP_ATOMIC);
++ if (!req)
++ return -ENOMEM;
++
++ error = starlet_ioctl_dma_prepare(req, fd, request,
++ ibuf, ilen,
++ obuf, olen);
++ if (!error)
++ error = starlet_ipc_call(req);
++ starlet_ipc_free_request(req);
++
++ if (error)
++ DBG("%s: error=%d (%x)\n", __func__, error, error);
++ return error;
++}
++EXPORT_SYMBOL_GPL(starlet_ioctl_dma);
++
++/**
++ *
++ */
++int starlet_ioctl_dma_nowait(int fd, int request,
++ dma_addr_t ibuf, size_t ilen,
++ dma_addr_t obuf, size_t olen,
++ starlet_ipc_callback_t callback, void *arg)
++{
++ struct starlet_ipc_device *ipc_dev = starlet_ipc_get_device();
++ struct starlet_ipc_request *req;
++ int error;
++
++ req = starlet_ipc_alloc_request(ipc_dev, GFP_ATOMIC);
++ if (!req)
++ return -ENOMEM;
++
++ error = starlet_ioctl_dma_prepare(req,
++ fd, request,
++ ibuf, ilen,
++ obuf, olen);
++ if (!error)
++ starlet_ipc_call_nowait(req, callback, arg);
++ else
++ starlet_ipc_free_request(req);
++
++ if (error)
++ DBG("%s: error=%d (%x)\n", __func__, error, error);
++ return error;
++}
++EXPORT_SYMBOL_GPL(starlet_ioctl_dma_nowait);
++
++static int starlet_ioctl_complete(struct starlet_ipc_request *req)
++{
++ struct starlet_ipc_device *ipc_dev = starlet_ipc_get_device();
++ dma_addr_t ibuf_ba, obuf_ba;
++ size_t ilen, olen;
++
++ ibuf_ba = req->ioctl.ibuf;
++ ilen = req->ioctl.ilen;
++ obuf_ba = req->ioctl.obuf;
++ olen = req->ioctl.olen;
++
++ if (ibuf_ba)
++ dma_unmap_single(ipc_dev->dev, ibuf_ba, ilen, DMA_TO_DEVICE);
++ if (obuf_ba)
++ dma_unmap_single(ipc_dev->dev, obuf_ba, olen, DMA_FROM_DEVICE);
++
++ return 0;
++}
++
++/*
++ *
++ */
++int starlet_ioctl_prepare(struct starlet_ipc_request *req,
++ int fd, int request,
++ void *ibuf, size_t ilen,
++ void *obuf, size_t olen)
++{
++ struct starlet_ipc_device *ipc_dev = starlet_ipc_get_device();
++ dma_addr_t ibuf_ba, obuf_ba;
++ int error;
++
++ if (!ipc_dev)
++ return -ENODEV;
++
++ BUG_ON(!IS_ALIGNED((unsigned long)ibuf, STARLET_IPC_DMA_ALIGN+1));
++ BUG_ON(!IS_ALIGNED((unsigned long)obuf, STARLET_IPC_DMA_ALIGN+1));
++
++ ibuf_ba = (ibuf) ? dma_map_single(ipc_dev->dev, ibuf, ilen,
++ DMA_TO_DEVICE) : 0;
++ obuf_ba = (obuf) ? dma_map_single(ipc_dev->dev, obuf, olen,
++ DMA_FROM_DEVICE) : 0;
++
++ error = starlet_ioctl_dma_prepare(req, fd, request,
++ ibuf_ba, ilen, obuf_ba, olen);
++ if (!error) {
++ req->complete = starlet_ioctl_complete;
++ if (ibuf)
++ dma_unmap_single(ipc_dev->dev, ibuf_ba, ilen,
++ DMA_TO_DEVICE);
++ if (obuf)
++ dma_unmap_single(ipc_dev->dev, obuf_ba, olen,
++ DMA_FROM_DEVICE);
++ }
++ return error;
++}
++
++/**
++ *
++ */
++int starlet_ioctl(int fd, int request,
++ void *ibuf, size_t ilen,
++ void *obuf, size_t olen)
++{
++ struct starlet_ipc_device *ipc_dev = starlet_ipc_get_device();
++ struct starlet_ipc_request *req;
++ int error;
++
++ req = starlet_ipc_alloc_request(ipc_dev, GFP_ATOMIC);
++ if (!req)
++ return -ENOMEM;
++
++ error = starlet_ioctl_prepare(req, fd, request,
++ ibuf, ilen, obuf, olen);
++ if (!error)
++ error = starlet_ipc_call(req);
++ starlet_ipc_free_request(req);
++
++ if (error < 0)
++ DBG("%s: error=%d (%x)\n", __func__, error, error);
++ return error;
++}
++EXPORT_SYMBOL_GPL(starlet_ioctl);
++
++/**
++ *
++ */
++int starlet_ioctl_nowait(int fd, int request,
++ void *ibuf, size_t ilen,
++ void *obuf, size_t olen,
++ starlet_ipc_callback_t callback, void *arg)
++{
++ struct starlet_ipc_device *ipc_dev = starlet_ipc_get_device();
++ struct starlet_ipc_request *req;
++ int error;
++
++ req = starlet_ipc_alloc_request(ipc_dev, GFP_ATOMIC);
++ if (!req)
++ return -ENOMEM;
++
++ error = starlet_ioctl_prepare(req, fd, request,
++ ibuf, ilen, obuf, olen);
++ if (!error)
++ starlet_ipc_call_nowait(req, callback, arg);
++ else
++ starlet_ipc_free_request(req);
++
++ if (error)
++ DBG("%s: error=%d (%x)\n", __func__, error, error);
++ return error;
++}
++EXPORT_SYMBOL_GPL(starlet_ioctl_nowait);
++
++
++static int starlet_ioctlv_complete(struct starlet_ipc_request *req)
++{
++ struct starlet_ipc_device *ipc_dev = starlet_ipc_get_device();
++ struct starlet_iovec *iovec = req->iovec;
++ dma_addr_t iovec_da = req->ioctlv.iovec_da;
++ size_t iovec_size = req->iovec_size;
++
++#if 0
++ unsigned int nents;
++ DBG("%s: nents_in=%u, nents_io=%u\n", __func__,
++ req->sgl_nents_in, req->sgl_nents_io);
++#endif
++
++ if (req->sgl_nents_in > 0)
++ dma_unmap_sg(ipc_dev->dev, req->sgl_in, req->sgl_nents_in,
++ DMA_TO_DEVICE);
++ if (req->sgl_nents_io > 0)
++ dma_unmap_sg(ipc_dev->dev, req->sgl_io, req->sgl_nents_io,
++ DMA_BIDIRECTIONAL);
++ if (iovec) {
++ dma_unmap_single(ipc_dev->dev,
++ iovec_da, iovec_size, DMA_TO_DEVICE);
++
++#if 0
++ struct starlet_iovec *p;
++ p = iovec;
++ nents = req->sgl_nents_in;
++ while (nents--) {
++ DBG("%s: in: dma_addr=%p, dma_len=%u\n", __func__,
++ (void *)p->dma_addr, p->dma_len);
++ p++;
++ }
++ nents = req->sgl_nents_io;
++ while (nents--) {
++ DBG("%s: io: dma_addr=%p, dma_len=%u\n", __func__,
++ (void *)p->dma_addr, p->dma_len);
++ p++;
++ }
++#endif
++
++ starlet_kfree(iovec);
++ }
++ return 0;
++}
++
++/*
++ *
++ */
++int starlet_ioctlv_prepare(struct starlet_ipc_request *req,
++ int fd, int request,
++ unsigned int nents_in,
++ struct scatterlist *sgl_in,
++ unsigned int nents_io,
++ struct scatterlist *sgl_io)
++{
++ struct starlet_ipc_device *ipc_dev = starlet_ipc_get_device();
++ struct starlet_iovec *iovec, *p;
++ dma_addr_t iovec_da = 0;
++ size_t iovec_size = 0;
++ struct scatterlist *sg;
++ unsigned int nents, i;
++
++ if (!ipc_dev)
++ return -ENODEV;
++
++ BUG_ON(nents_in > 0 && !sgl_in);
++ BUG_ON(nents_io > 0 && !sgl_io);
++
++ nents = nents_in + nents_io;
++ if (nents > 0) {
++ iovec_size = nents * sizeof(*iovec);
++ iovec = starlet_kzalloc(iovec_size, GFP_ATOMIC);
++ if (!iovec)
++ return -ENOMEM;
++ } else {
++ iovec = NULL;
++ }
++
++ p = iovec;
++ if (nents_in > 0) {
++ nents_in = dma_map_sg(ipc_dev->dev, sgl_in, nents_in,
++ DMA_TO_DEVICE);
++ for_each_sg(sgl_in, sg, nents_in, i) {
++#if 0
++ DBG("%s: in: dma_addr=%p, dma_len=%u\n", __func__,
++ (void *)sg_dma_address(sg), sg_dma_len(sg));
++#endif
++ p->dma_addr = sg_dma_address(sg);
++ p->dma_len = sg_dma_len(sg);
++ p++;
++ }
++ }
++ if (nents_io > 0) {
++ nents_io = dma_map_sg(ipc_dev->dev, sgl_io, nents_io,
++ DMA_BIDIRECTIONAL);
++ for_each_sg(sgl_io, sg, nents_io, i) {
++#if 0
++ DBG("%s: io: dma_addr=%p, dma_len=%u\n", __func__,
++ (void *)sg_dma_address(sg), sg_dma_len(sg));
++#endif
++ p->dma_addr = sg_dma_address(sg);
++ p->dma_len = sg_dma_len(sg);
++ p++;
++ }
++ }
++
++ if (iovec)
++ iovec_da = dma_map_single(ipc_dev->dev,
++ iovec, iovec_size,
++ DMA_TO_DEVICE);
++
++ req->iovec = iovec;
++ req->iovec_size = iovec_size;
++ req->sgl_nents_in = nents_in;
++ req->sgl_in = sgl_in;
++ req->sgl_nents_io = nents_io;
++ req->sgl_io = sgl_io;
++
++ req->cmd = STARLET_IOS_IOCTLV;
++ req->fd = fd;
++ req->ioctlv.request = request;
++ req->ioctlv.argc_in = nents_in;
++ req->ioctlv.argc_io = nents_io;
++ req->ioctlv.iovec_da = iovec_da;
++ req->complete = starlet_ioctlv_complete;
++
++#if 0
++ DBG("%s: fd=%d, request=%d,"
++ " argc_in=%u, argc_io=%u, iovec_da=%08x\n" , __func__,
++ req->fd, req->ioctlv.request,
++ req->ioctlv.argc_in, req->ioctlv.argc_io,
++ req->ioctlv.iovec_da);
++#endif
++ return 0;
++}
++
++/**
++ *
++ */
++int starlet_ioctlv(int fd, int request,
++ unsigned int nents_in,
++ struct scatterlist *sgl_in,
++ unsigned int nents_io,
++ struct scatterlist *sgl_io)
++{
++ struct starlet_ipc_device *ipc_dev = starlet_ipc_get_device();
++ struct starlet_ipc_request *req;
++ int error;
++
++ req = starlet_ipc_alloc_request(ipc_dev, GFP_ATOMIC);
++ if (!req)
++ return -ENOMEM;
++
++ error = starlet_ioctlv_prepare(req, fd, request,
++ nents_in, sgl_in,
++ nents_io, sgl_io);
++ if (!error)
++ error = starlet_ipc_call(req);
++ starlet_ipc_free_request(req);
++
++ if (error < 0)
++ DBG("%s: error=%d (%x)\n", __func__, error, error);
++ return error;
++}
++EXPORT_SYMBOL_GPL(starlet_ioctlv);
++
++/**
++ *
++ */
++int starlet_ioctlv_nowait(int fd, int request,
++ unsigned int nents_in,
++ struct scatterlist *sgl_in,
++ unsigned int nents_io,
++ struct scatterlist *sgl_io,
++ starlet_ipc_callback_t callback, void *arg)
++{
++ struct starlet_ipc_device *ipc_dev = starlet_ipc_get_device();
++ struct starlet_ipc_request *req;
++ int error;
++
++ req = starlet_ipc_alloc_request(ipc_dev, GFP_ATOMIC);
++ if (!req)
++ return -ENOMEM;
++
++ error = starlet_ioctlv_prepare(req, fd, request,
++ nents_in, sgl_in,
++ nents_io, sgl_io);
++ if (!error)
++ starlet_ipc_call_nowait(req, callback, arg);
++ else
++ starlet_ipc_free_request(req);
++
++ if (error < 0)
++ DBG("%s: error=%d (%x)\n", __func__, error, error);
++ return error;
++}
++EXPORT_SYMBOL_GPL(starlet_ioctlv_nowait);
++
++/**
++ *
++ */
++int starlet_ioctlv_and_reboot(int fd, int request,
++ unsigned int nents_in,
++ struct scatterlist *sgl_in,
++ unsigned int nents_io,
++ struct scatterlist *sgl_io)
++{
++ struct starlet_ipc_device *ipc_dev = starlet_ipc_get_device();
++ struct starlet_ipc_request *req;
++ int error;
++
++ req = starlet_ipc_alloc_request(ipc_dev, GFP_ATOMIC);
++ if (!req)
++ return -ENOMEM;
++
++ error = starlet_ioctlv_prepare(req, fd, request,
++ nents_in, sgl_in,
++ nents_io, sgl_io);
++ if (!error) {
++ ipc_dev->req = req;
++ set_bit(__REBOOT, &ipc_dev->flags);
++ error = starlet_ipc_call(req);
++ }
++ starlet_ipc_free_request(req);
++
++ if (error < 0)
++ DBG("%s: error=%d (%x)\n", __func__, error, error);
++ return error;
++}
++EXPORT_SYMBOL_GPL(starlet_ioctlv_and_reboot);
++
++/*
++ * starlet_ioh_ioctlv*
++ *
++ */
++
++static int starlet_ioh_ioctlv_complete(struct starlet_ipc_request *req)
++{
++ struct starlet_ipc_device *ipc_dev = starlet_ipc_get_device();
++ struct starlet_iovec *iovec = req->iovec;
++ dma_addr_t iovec_da = req->ioctlv.iovec_da;
++ size_t iovec_size = req->iovec_size;
++
++#if 0
++ unsigned int nents;
++ DBG("%s: nents_in=%u, nents_io=%u\n", __func__,
++ req->sgl_nents_in, req->sgl_nents_io);
++#endif
++
++ if (req->sgl_nents_in > 0)
++ starlet_ioh_dma_unmap_sg(ipc_dev->dev,
++ req->ioh_sgl_in, req->sgl_nents_in,
++ DMA_TO_DEVICE);
++ if (req->sgl_nents_io > 0)
++ starlet_ioh_dma_unmap_sg(ipc_dev->dev,
++ req->ioh_sgl_io, req->sgl_nents_io,
++ DMA_BIDIRECTIONAL);
++ if (iovec) {
++ dma_unmap_single(ipc_dev->dev,
++ iovec_da, iovec_size, DMA_TO_DEVICE);
++
++ { /* begin debug */
++#if 0
++ struct starlet_iovec *p;
++ p = iovec;
++ nents = req->sgl_nents_in;
++ while (nents--) {
++ DBG("%s: in: dma_addr=%p, dma_len=%u\n", __func__,
++ (void *)p->dma_addr, p->dma_len);
++ p++;
++ }
++ nents = req->sgl_nents_io;
++ while (nents--) {
++ DBG("%s: io: dma_addr=%p, dma_len=%u\n", __func__,
++ (void *)p->dma_addr, p->dma_len);
++ p++;
++ }
++#endif
++ } /* end debug */
++
++ starlet_kfree(iovec);
++ }
++ return 0;
++}
++
++/*
++ *
++ */
++int starlet_ioh_ioctlv_prepare(struct starlet_ipc_request *req,
++ int fd, int request,
++ unsigned int nents_in,
++ struct starlet_ioh_sg *ioh_sgl_in,
++ unsigned int nents_io,
++ struct starlet_ioh_sg *ioh_sgl_io)
++{
++ struct starlet_ipc_device *ipc_dev = starlet_ipc_get_device();
++ struct starlet_iovec *iovec, *p;
++ dma_addr_t iovec_da = 0;
++ size_t iovec_size = 0;
++ struct starlet_ioh_sg *ioh_sg;
++ unsigned int nents, i;
++
++ if (!ipc_dev)
++ return -ENODEV;
++
++ BUG_ON(nents_in > 0 && !ioh_sgl_in);
++ BUG_ON(nents_io > 0 && !ioh_sgl_io);
++
++ nents = nents_in + nents_io;
++ if (nents > 0) {
++ iovec_size = nents * sizeof(*iovec);
++ iovec = starlet_kzalloc(iovec_size, GFP_ATOMIC);
++ if (!iovec)
++ return -ENOMEM;
++ } else {
++ iovec = NULL;
++ }
++
++ p = iovec;
++ if (nents_in > 0) {
++ nents_in = starlet_ioh_dma_map_sg(ipc_dev->dev,
++ ioh_sgl_in, nents_in,
++ DMA_TO_DEVICE);
++ starlet_ioh_for_each_sg(ioh_sgl_in, ioh_sg, nents_in, i) {
++#if 0
++ DBG("%s: in: dma_addr=%p, dma_len=%u\n", __func__,
++ (void *)ioh_sg->dma_addr, ioh_sg->len);
++#endif
++ p->dma_addr = ioh_sg->dma_addr;
++ p->dma_len = ioh_sg->len;
++ p++;
++ }
++ }
++ if (nents_io > 0) {
++ nents_io = starlet_ioh_dma_map_sg(ipc_dev->dev,
++ ioh_sgl_io, nents_io,
++ DMA_BIDIRECTIONAL);
++ starlet_ioh_for_each_sg(ioh_sgl_io, ioh_sg, nents_io, i) {
++#if 0
++ DBG("%s: io: dma_addr=%p, dma_len=%u\n", __func__,
++ (void *)ioh_sg->dma_addr, ioh_sg->len);
++#endif
++ p->dma_addr = ioh_sg->dma_addr;
++ p->dma_len = ioh_sg->len;
++ p++;
++ }
++ }
++
++ if (iovec)
++ iovec_da = dma_map_single(ipc_dev->dev,
++ iovec, iovec_size,
++ DMA_TO_DEVICE);
++
++ req->iovec = iovec;
++ req->iovec_size = iovec_size;
++ req->sgl_nents_in = nents_in;
++ req->ioh_sgl_in = ioh_sgl_in;
++ req->sgl_nents_io = nents_io;
++ req->ioh_sgl_io = ioh_sgl_io;
++
++ req->cmd = STARLET_IOS_IOCTLV;
++ req->fd = fd;
++ req->ioctlv.request = request;
++ req->ioctlv.argc_in = nents_in;
++ req->ioctlv.argc_io = nents_io;
++ req->ioctlv.iovec_da = iovec_da;
++ req->complete = starlet_ioh_ioctlv_complete;
++
++ return 0;
++}
++
++/**
++ *
++ */
++int starlet_ioh_ioctlv(int fd, int request,
++ unsigned int nents_in,
++ struct starlet_ioh_sg *ioh_sgl_in,
++ unsigned int nents_io,
++ struct starlet_ioh_sg *ioh_sgl_io)
++{
++ struct starlet_ipc_device *ipc_dev = starlet_ipc_get_device();
++ struct starlet_ipc_request *req;
++ int error;
++
++ req = starlet_ipc_alloc_request(ipc_dev, GFP_ATOMIC);
++ if (!req)
++ return -ENOMEM;
++
++ error = starlet_ioh_ioctlv_prepare(req, fd, request,
++ nents_in, ioh_sgl_in,
++ nents_io, ioh_sgl_io);
++ if (!error)
++ error = starlet_ipc_call(req);
++ starlet_ipc_free_request(req);
++
++ if (error < 0)
++ DBG("%s: error=%d (%x)\n", __func__, error, error);
++ return error;
++}
++EXPORT_SYMBOL_GPL(starlet_ioh_ioctlv);
++
++/**
++ *
++ */
++int starlet_ioh_ioctlv_nowait(int fd, int request,
++ unsigned int nents_in,
++ struct starlet_ioh_sg *ioh_sgl_in,
++ unsigned int nents_io,
++ struct starlet_ioh_sg *ioh_sgl_io,
++ starlet_ipc_callback_t callback, void *arg)
++{
++ struct starlet_ipc_device *ipc_dev = starlet_ipc_get_device();
++ struct starlet_ipc_request *req;
++ int error;
++
++ req = starlet_ipc_alloc_request(ipc_dev, GFP_ATOMIC);
++ if (!req)
++ return -ENOMEM;
++
++ error = starlet_ioh_ioctlv_prepare(req, fd, request,
++ nents_in, ioh_sgl_in,
++ nents_io, ioh_sgl_io);
++ if (!error)
++ starlet_ipc_call_nowait(req, callback, arg);
++ else
++ starlet_ipc_free_request(req);
++
++ if (error < 0)
++ DBG("%s: error=%d (%x)\n", __func__, error, error);
++ return error;
++}
++EXPORT_SYMBOL_GPL(starlet_ioh_ioctlv_nowait);
++
++
++/*
++ * This "watchdog" code may be used to detect misbehaving requests.
++ *
++ * Note that some requests can take a lot of time to complete.
++ * For example, a keyboard event, which is delivered every time a key is
++ * pressed or released (or a keyboard is connected/disconnected), may take an
++ * arbitrary amount of time to arrive.
++ *
++ */
++
++#define STARLET_IPC_WATCHDOG_TIME (60 * HZ)
++
++static void starlet_ipc_watchdog(unsigned long arg)
++{
++#if 0
++ struct starlet_ipc_device *ipc_dev = (struct starlet_ipc_device *)arg;
++ struct starlet_ipc_request *req;
++ unsigned long flags;
++
++ spin_lock_irqsave(&ipc_dev->list_lock, flags);
++ list_for_each_entry(req, &ipc_dev->outstanding_list, node) {
++ if (req &&
++ time_after(jiffies,
++ req->jiffies + STARLET_IPC_WATCHDOG_TIME)) {
++ drv_printk(KERN_INFO, "request on the outstanding"
++ " list for too long\n");
++ starlet_ipc_pretty_print_request(req);
++ }
++ }
++ spin_unlock_irqrestore(&ipc_dev->list_lock, flags);
++
++ mod_timer(&ipc_dev->timer, jiffies + STARLET_IPC_WATCHDOG_TIME);
++#endif
++}
++
++/*
++ * Setup routines.
++ *
++ */
++
++/*
++ * Place here any desired hardware cleanups while drivers get written.
++ */
++static void starlet_fixups(void)
++{
++ static u32 buf[8]
++ __attribute__ ((aligned(STARLET_IPC_DMA_ALIGN + 1)));
++ struct scatterlist in[6], io[1];
++ int fd;
++ void *gpio;
++
++ /* close any open file descriptors, just in case */
++ for (fd = 0; fd < 24; fd++)
++ starlet_close(fd);
++
++ /*
++ * Hey! We are super-green. And you?
++ */
++
++ /* try to stop the dvd unit motor */
++ fd = starlet_open("/dev/di", 0);
++ if (fd >= 0) {
++ buf[0] = 0xe3000000; /* stop motor command */
++ buf[1] = 0;
++ buf[2] = 0;
++ starlet_ioctl(fd, buf[0],
++ buf, sizeof(buf),
++ buf, sizeof(buf));
++ starlet_close(fd);
++ }
++
++ /* try to disconnect the wiimote */
++ fd = starlet_open("/dev/usb/oh1/57e/305", 2);
++ if (fd >= 0) {
++ /*
++ * This assumes big endianness and 4 byte dma alignment.
++ */
++ buf[0] = 0x20000000; /* bmRequestType 0x20 */
++ buf[1] = 0x00000000; /* bRequest 0x00 */
++ buf[2] = 0x00000000; /* wValue 0x00, 0x00 */
++ buf[3] = 0x00000000; /* wIndex 0x00, 0x00 */
++ buf[4] = 0x03000000; /* wLength 0x03, 0x00 */
++ buf[5] = 0x00000000; /* timeout? 0x00 */
++ buf[6] = 0x030c0000; /* payload 0x03, 0x0c, 0x00 */
++ sg_init_table(in, 6);
++ sg_set_buf(&in[0], &buf[0], 1);
++ sg_set_buf(&in[1], &buf[1], 1);
++ sg_set_buf(&in[2], &buf[2], 2);
++ sg_set_buf(&in[3], &buf[3], 2);
++ sg_set_buf(&in[4], &buf[4], 2);
++ sg_set_buf(&in[5], &buf[5], 1);
++ sg_init_table(io, 1);
++ sg_set_buf(&io[0], &buf[6], 3);
++ starlet_ioctlv(fd, 0, 6, in, 1, io);
++ starlet_close(fd);
++ }
++
++ /*
++ * Try to turn off the front led and sensor bar.
++ * (not strictly starlet-only stuff but anyway...)
++ */
++ gpio = ioremap(0x0d8000c0, 4);
++ if (gpio) {
++ out_be32(gpio, in_be32(gpio) & ~0x120);
++ iounmap(gpio);
++ }
++}
++
++static int starlet_ipc_init(struct starlet_ipc_device *ipc_dev,
++ struct resource *mem, int irq)
++{
++ size_t size, io_size;
++ int error;
++
++ ipc_dev->random_id = get_random_int();
++
++ error = starlet_malloc_lib_bootstrap(&mem[1]);
++ if (error)
++ return error;
++
++ io_size = mem[0].end - mem[0].start + 1;
++ ipc_dev->io_base = ioremap(mem[0].start, io_size);
++ ipc_dev->irq = irq;
++
++ size = max((size_t)64, sizeof(struct starlet_ipc_request));
++ ipc_dev->dma_pool = dma_pool_create(DRV_MODULE_NAME,
++ ipc_dev->dev,
++ size, STARLET_IPC_DMA_ALIGN + 1, 0);
++ if (!ipc_dev->dma_pool) {
++ drv_printk(KERN_ERR, "dma_pool_create failed\n");
++ iounmap(ipc_dev->io_base);
++ return -ENOMEM;
++ }
++ spin_lock_init(&ipc_dev->list_lock);
++ INIT_LIST_HEAD(&ipc_dev->pending_list);
++ INIT_LIST_HEAD(&ipc_dev->outstanding_list);
++
++ starlet_ipc_device_instance = ipc_dev;
++
++ init_timer(&ipc_dev->timer);
++ ipc_dev->timer.function = starlet_ipc_watchdog;
++ ipc_dev->timer.data = (unsigned long)ipc_dev;
++ ipc_dev->timer.expires = jiffies + STARLET_IPC_WATCHDOG_TIME;
++ add_timer(&ipc_dev->timer);
++
++ error = request_irq(ipc_dev->irq, starlet_ipc_handler, 0,
++ DRV_MODULE_NAME, ipc_dev);
++ if (error) {
++ drv_printk(KERN_ERR, "request of IRQ %d failed\n", irq);
++ starlet_ipc_device_instance = NULL;
++ dma_pool_destroy(ipc_dev->dma_pool);
++ iounmap(ipc_dev->io_base);
++ return error;
++ }
++
++ /* ack and enable RBFI and TBEI interrupts */
++ out_be32(ipc_dev->io_base + STARLET_IPC_CSR,
++ STARLET_IPC_CSR_TBEIMASK | STARLET_IPC_CSR_RBFIMASK |
++ STARLET_IPC_CSR_TBEI | STARLET_IPC_CSR_RBFI);
++
++ starlet_fixups();
++
++ return error;
++}
++
++static void starlet_ipc_exit(struct starlet_ipc_device *ipc_dev)
++{
++ starlet_ipc_device_instance = NULL;
++ starlet_ipc_quiesce(ipc_dev);
++
++ del_timer(&ipc_dev->timer);
++
++ free_irq(ipc_dev->irq, ipc_dev);
++ dma_pool_destroy(ipc_dev->dma_pool);
++ iounmap(ipc_dev->io_base);
++ ipc_dev->io_base = NULL;
++}
++
++
++/*
++ * Driver model helper routines.
++ *
++ */
++
++static int starlet_ipc_do_probe(struct device *dev, struct resource *mem,
++ int irq)
++{
++ struct starlet_ipc_device *ipc_dev;
++ int retval;
++
++ ipc_dev = kzalloc(sizeof(*ipc_dev), GFP_KERNEL);
++ if (!ipc_dev) {
++ drv_printk(KERN_ERR, "failed to allocate ipc_dev\n");
++ return -ENOMEM;
++ }
++ dev_set_drvdata(dev, ipc_dev);
++ ipc_dev->dev = dev;
++
++ retval = starlet_ipc_init(ipc_dev, mem, irq);
++ if (retval) {
++ dev_set_drvdata(dev, NULL);
++ kfree(ipc_dev);
++ }
++ return retval;
++}
++
++static int starlet_ipc_do_remove(struct device *dev)
++{
++ struct starlet_ipc_device *ipc_dev = dev_get_drvdata(dev);
++
++ if (ipc_dev) {
++ starlet_ipc_exit(ipc_dev);
++ dev_set_drvdata(dev, NULL);
++ kfree(ipc_dev);
++ return 0;
++ }
++ return -ENODEV;
++}
++
++static int starlet_ipc_do_shutdown(struct device *dev)
++{
++ struct starlet_ipc_device *ipc_dev = dev_get_drvdata(dev);
++
++ if (ipc_dev) {
++ /*
++ * We can't shutdown IPC as we need it to reboot the
++ * machine.
++ * Thus, no starlet_ipc_quiesce(ipc_dev); here, sorry.
++ */
++ return 0;
++ }
++ return -ENODEV;
++}
++
++/*
++ * OF platform driver hooks.
++ *
++ */
++
++static int starlet_ipc_of_probe(struct of_device *odev,
++ const struct of_device_id *dev_id)
++{
++ struct resource mem[2];
++ int error;
++
++ error = of_address_to_resource(odev->node, 0, &mem[0]);
++ if (error) {
++ drv_printk(KERN_ERR, "no io memory range found\n");
++ return -ENODEV;
++ }
++ error = of_address_to_resource(odev->node, 1, &mem[1]);
++ if (error) {
++ drv_printk(KERN_ERR, "missing ioh memory area (%d)\n", error);
++ return -ENODEV;
++ }
++
++ return starlet_ipc_do_probe(&odev->dev, mem,
++ irq_of_parse_and_map(odev->node, 0));
++}
++
++static int starlet_ipc_of_remove(struct of_device *odev)
++{
++ return starlet_ipc_do_remove(&odev->dev);
++}
++
++static int starlet_ipc_of_shutdown(struct of_device *odev)
++{
++ return starlet_ipc_do_shutdown(&odev->dev);
++}
++
++static struct of_device_id starlet_ipc_of_match[] = {
++ { .compatible = "nintendo,starlet-ipc" },
++ { },
++};
++
++MODULE_DEVICE_TABLE(of, starlet_ipc_of_match);
++
++static struct of_platform_driver starlet_ipc_of_driver = {
++ .owner = THIS_MODULE,
++ .name = DRV_MODULE_NAME,
++ .match_table = starlet_ipc_of_match,
++ .probe = starlet_ipc_of_probe,
++ .remove = starlet_ipc_of_remove,
++ .shutdown = starlet_ipc_of_shutdown,
++};
++
++/*
++ * Kernel module interface hooks.
++ *
++ */
++
++static int __init starlet_ipc_init_module(void)
++{
++ drv_printk(KERN_INFO, "%s - version %s\n", DRV_DESCRIPTION,
++ starlet_ipc_driver_version);
++
++ return of_register_platform_driver(&starlet_ipc_of_driver);
++}
++
++static void __exit starlet_ipc_exit_module(void)
++{
++ of_unregister_platform_driver(&starlet_ipc_of_driver);
++}
++
++module_init(starlet_ipc_init_module);
++module_exit(starlet_ipc_exit_module);
++
++MODULE_DESCRIPTION(DRV_DESCRIPTION);
++MODULE_AUTHOR(DRV_AUTHOR);
++MODULE_LICENSE("GPL");
++
+diff --git a/arch/powerpc/platforms/embedded6xx/starlet-malloc.c b/arch/powerpc/platforms/embedded6xx/starlet-malloc.c
+new file mode 100644
+index 0000000..d9c9dcd
+--- /dev/null
++++ b/arch/powerpc/platforms/embedded6xx/starlet-malloc.c
+@@ -0,0 +1,365 @@
++/*
++ * arch/powerpc/platforms/embedded6xx/starlet-malloc.c
++ *
++ * Nintendo Wii starlet memory allocation library
++ * Copyright (C) 2008-2009 The GameCube Linux Team
++ * Copyright (C) 2008,2009 Albert Herranz
++ *
++ * 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 from the trenches:
++ *
++ * writes from broadway to mem2
++ * - 8 or 16 bit writes to mem2 modify 64 bits
++ * - writing 0xaa results in 0xaaffffffaaffffff being written
++ * - writing 0xaabb results in 0xaabbffffaabbffff being written
++ * - 32 bit writes work fine
++ * writes from starlet to mem1
++ * - data must be 4 byte aligned, length must be 4 byte aligned
++ *
++ * write protected area (reads after writes do not return written info)
++ * 0x13620000 - 0x14000000
++ *
++ */
++
++#define DEBUG
++
++#define DBG(fmt, arg...) pr_debug(fmt, ##arg)
++
++#include <linux/kernel.h>
++#include <linux/resource.h>
++#include <asm/starlet.h>
++
++
++#define LIB_MODULE_NAME "starlet-malloc"
++#define LIB_DESCRIPTION "Nintendo Wii starlet malloc library"
++#define LIB_AUTHOR "Albert Herranz"
++
++static char starlet_malloc_lib_version[] = "0.1i";
++
++#define drv_printk(level, format, arg...) \
++ printk(level LIB_MODULE_NAME ": " format , ## arg)
++
++
++#define STARLET_IOH_ALIGN 31
++
++/*
++ * Simple aligned kzalloc and free.
++ *
++ * Based on the idea proposed by Satya Kiran Popuri
++ * http://www.cs.uic.edu/~spopuri/amalloc.html
++ */
++
++/**
++ *
++ */
++static void *kzalloc_aligned(size_t size, gfp_t flags, size_t align)
++{
++ void *ptr, *aligned_ptr;
++ size_t aligned_size;
++
++ /* not a power of two */
++ if (align & (align - 1))
++ return NULL;
++
++ /* worst case allocation size */
++ aligned_size = size + align - 1;
++
++ /* add extra space to store allocation delta */
++ aligned_size += sizeof(size_t);
++
++ /* allocate all space */
++ ptr = kzalloc(aligned_size, flags);
++ if (!ptr)
++ return NULL;
++
++ /* calculate the aligned address, making room for the delta value */
++ aligned_ptr = PTR_ALIGN(ptr + sizeof(size_t), align);
++
++ /* save the delta before the address returned to caller */
++ *((size_t *)aligned_ptr - 1) = aligned_ptr - ptr;
++
++ return aligned_ptr;
++}
++
++static void kfree_aligned(void *aligned_ptr)
++{
++ void *ptr;
++ size_t delta;
++
++ if (!aligned_ptr)
++ return;
++
++ /* retrieve extra allocation delta */
++ delta = *((size_t *)aligned_ptr - 1);
++
++ /* calculate original allocation area start */
++ ptr = aligned_ptr - delta;
++
++ kfree(ptr);
++}
++
++
++/**
++ *
++ */
++void *starlet_kzalloc(size_t size, gfp_t flags)
++{
++ return kzalloc_aligned(size, flags, STARLET_IPC_DMA_ALIGN+1);
++}
++
++/**
++ *
++ */
++void starlet_kfree(void *ptr)
++{
++ kfree_aligned(ptr);
++}
++
++
++
++/*
++ * Functions for special input/output buffer allocations.
++ *
++ * Starlet seems to have a limitation when doing non-32 bit writes to MEM1.
++ * This can cause up to a 3 byte data loss when starlet delivers
++ * data of an unaligned size.
++ * Writes to MEM2 don't have such a limitation.
++ *
++ * We use special buffers when we need to retrieve data of an unaligned size
++ * from starlet.
++ *
++ */
++
++static int starlet_ioh_init(struct starlet_ioh *ioh, struct resource *mem)
++{
++ size_t size = mem->end - mem->start + 1;
++ rh_info_t *rheap;
++ int error = -ENOMEM;
++
++ ioh->base = ioremap_flags(mem->start, size, _PAGE_GUARDED);
++ if (!ioh->base) {
++ drv_printk(KERN_ERR, "unable to ioremap ioh area\n");
++ goto err;
++ }
++ ioh->base_phys = mem->start;
++ ioh->size = size;
++
++ {
++ void *first = NULL, *last = NULL;
++ u32 *p;
++
++ p = ioh->base + size;
++ do {
++ p--;
++ *p = 0xdeadbabe;
++ } while (p != ioh->base);
++ __dma_sync(ioh->base, size, DMA_TO_DEVICE);
++
++ p = ioh->base + size;
++ do {
++ p--;
++ if (*p != 0xdeadbabe) {
++ if (!last)
++ last = p;
++ first = p;
++ }
++ } while (p != ioh->base);
++
++ if (first)
++ drv_printk(KERN_INFO, "unreliable writes from"
++ " %p to %p\n", first, last);
++ }
++
++ rheap = rh_create(STARLET_IOH_ALIGN+1);
++ if (IS_ERR(rheap)) {
++ error = PTR_ERR(rheap);
++ goto err_rh_create;
++ }
++ ioh->rheap = rheap;
++
++ error = rh_attach_region(rheap, 0, size);
++ if (error)
++ goto err_rh_attach_region;
++
++ spin_lock_init(&ioh->lock);
++
++ drv_printk(KERN_INFO, "ioh at 0x%08lx, mapped to 0x%p, size %uk\n",
++ ioh->base_phys, ioh->base, ioh->size / 1024);
++
++ return 0;
++
++err_rh_create:
++ iounmap(ioh->base);
++err_rh_attach_region:
++ rh_destroy(ioh->rheap);
++err:
++ return error;
++}
++
++static struct starlet_ioh *starlet_ioh;
++
++/**
++ *
++ */
++static struct starlet_ioh *starlet_ioh_get(void)
++{
++ if (unlikely(!starlet_ioh))
++ drv_printk(KERN_ERR, "uninitialized ioh instance!\n");
++ return starlet_ioh;
++}
++
++unsigned long starlet_ioh_virt_to_phys(void *ptr)
++{
++ struct starlet_ioh *ioh = starlet_ioh_get();
++ unsigned long offset;
++
++ if (!ioh || !ptr)
++ return 0;
++
++ offset = ptr - ioh->base;
++ return ioh->base_phys + offset;
++}
++
++/**
++ *
++ */
++void *starlet_ioh_kzalloc_aligned(size_t size, size_t align)
++{
++ struct starlet_ioh *ioh = starlet_ioh_get();
++ unsigned long offset;
++ void *ptr;
++ unsigned long flags;
++
++ if (!ioh)
++ return NULL;
++
++ spin_lock_irqsave(&ioh->lock, flags);
++ offset = rh_alloc_align(ioh->rheap, size, align, NULL);
++ spin_unlock_irqrestore(&ioh->lock, flags);
++
++ if (IS_ERR_VALUE(offset))
++ return NULL;
++
++ ptr = ioh->base + offset;
++ memset(ptr, 0, size);
++
++ return ptr;
++}
++
++/**
++ *
++ */
++void *starlet_ioh_kzalloc(size_t size)
++{
++ return starlet_ioh_kzalloc_aligned(size, STARLET_IOH_ALIGN+1);
++}
++
++/**
++ *
++ */
++void starlet_ioh_kfree(void *ptr)
++{
++ struct starlet_ioh *ioh = starlet_ioh_get();
++ unsigned long offset;
++ unsigned long flags;
++
++ if (!ioh || !ptr)
++ return;
++
++ offset = ptr - ioh->base;
++
++ spin_lock_irqsave(&ioh->lock, flags);
++ rh_free(ioh->rheap, offset);
++ spin_unlock_irqrestore(&ioh->lock, flags);
++}
++
++int starlet_ioh_dma_map_sg(struct device *dev, struct starlet_ioh_sg *sgl,
++ int nents, enum dma_data_direction direction)
++{
++ struct starlet_ioh_sg *sg;
++ int i;
++
++ BUG_ON(direction == DMA_NONE);
++
++ starlet_ioh_for_each_sg(sgl, sg, nents, i) {
++ if (!sg->buf || sg->len == 0)
++ continue;
++ __dma_sync(sg->buf, sg->len, direction);
++ }
++ return nents;
++}
++
++void starlet_ioh_dma_unmap_sg(struct device *dev, struct starlet_ioh_sg *sgl,
++ int nents, enum dma_data_direction direction)
++{
++ /* nothing to do */
++}
++
++void starlet_ioh_sg_init_table(struct starlet_ioh_sg *sgl, unsigned int nents)
++{
++ memset(sgl, 0, nents * sizeof(*sgl));
++}
++
++/**
++ *
++ * @buf: must have been allocated using one of the starlet_ioh_* alloc
++ * functions.
++ */
++void starlet_ioh_sg_set_buf(struct starlet_ioh_sg *sg, void *buf, size_t len)
++{
++ struct starlet_ioh *ioh = starlet_ioh_get();
++ unsigned long offset;
++
++ if (buf && len) {
++ offset = buf - ioh->base;
++
++ sg->buf = buf;
++ sg->len = len;
++ sg->dma_addr = ioh->base_phys + offset;
++ } else {
++ sg->buf = NULL;
++ sg->len = 0;
++ sg->dma_addr = 0;
++ }
++}
++
++
++/**
++ *
++ */
++int starlet_malloc_lib_bootstrap(struct resource *mem)
++{
++ struct starlet_ioh *ioh;
++ int error;
++
++ if (starlet_ioh) {
++ drv_printk(KERN_WARNING, "already bootstrapped\n");
++ return 0;
++ }
++
++ drv_printk(KERN_INFO, "%s - version %s\n", LIB_DESCRIPTION,
++ starlet_malloc_lib_version);
++
++ ioh = kzalloc(sizeof(*ioh), GFP_KERNEL);
++ if (!ioh) {
++ drv_printk(KERN_ERR, "failed to allocate ioh\n");
++ return -ENOMEM;
++ }
++
++ error = starlet_ioh_init(ioh, mem);
++ if (error)
++ kfree(ioh);
++ else
++ starlet_ioh = ioh;
++
++ return error;
++}
++
++
+diff --git a/arch/powerpc/platforms/embedded6xx/starlet-stm.c b/arch/powerpc/platforms/embedded6xx/starlet-stm.c
+new file mode 100644
+index 0000000..a765964
+--- /dev/null
++++ b/arch/powerpc/platforms/embedded6xx/starlet-stm.c
+@@ -0,0 +1,93 @@
++/*
++ * arch/powerpc/platforms/embedded6xx/starlet-stm.c
++ *
++ * Nintendo Wii starlet STM routines
++ * Copyright (C) 2008-2009 The GameCube Linux Team
++ * Copyright (C) 2008,2009 Albert Herranz
++ *
++ * 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.
++ *
++ */
++
++#define DBG(fmt, arg...) drv_printk(KERN_INFO, fmt, ##arg)
++
++#include <linux/kernel.h>
++#include <linux/dma-mapping.h>
++#include <asm/starlet.h>
++
++
++/*
++ * /dev/stm/immediate
++ *
++ */
++
++#define STARLET_STM_HOTRESET 0x2001
++#define STARLET_STM_SHUTDOWN 0x2003
++
++#define STARLET_DEV_STM_IMMEDIATE "/dev/stm/immediate"
++
++#define drv_printk(level, format, arg...) \
++ printk(level "starlet-stm: " format , ## arg)
++
++
++static const char dev_stm_immediate[] = STARLET_DEV_STM_IMMEDIATE;
++
++/* private aligned buffer for restart/power_off operations */
++static u32 starlet_stm_buf[(STARLET_IPC_DMA_ALIGN+1)/sizeof(u32)]
++ __attribute__ ((aligned(STARLET_IPC_DMA_ALIGN+1)));
++
++/*
++ *
++ */
++static void starlet_stm_common_restart(int request, u32 value)
++{
++ u32 *buf = starlet_stm_buf;
++ size_t len = sizeof(starlet_stm_buf);
++ int fd;
++ int error;
++
++ /* REVISIT, use polled ipc calls here */
++
++
++ drv_printk(KERN_INFO, "trying IPC restart...\n");
++
++ fd = starlet_open(dev_stm_immediate, 0);
++ if (fd < 0) {
++ drv_printk(KERN_ERR, "failed to open %s\n", dev_stm_immediate);
++ error = fd;
++ goto done;
++ }
++
++ *buf = value;
++ error = starlet_ioctl(fd, request, buf, len, buf, len);
++ if (error < 0)
++ drv_printk(KERN_ERR, "ioctl %d failed\n", request);
++ starlet_close(fd);
++
++done:
++ if (error < 0)
++ DBG("%s: error=%d (%x)\n", __func__, error, error);
++}
++
++/*
++ *
++ */
++void starlet_stm_restart(void)
++{
++ starlet_stm_common_restart(STARLET_STM_HOTRESET, 0);
++}
++/*EXPORT_SYMBOL_GPL(starlet_stm_restart);*/
++
++/*
++ *
++ */
++void starlet_stm_power_off(void)
++{
++ starlet_stm_common_restart(STARLET_STM_SHUTDOWN, 0);
++}
++/*EXPORT_SYMBOL_GPL(starlet_stm_power_off);*/
++
++
+diff --git a/arch/powerpc/platforms/embedded6xx/usbgecko_udbg.c b/arch/powerpc/platforms/embedded6xx/usbgecko_udbg.c
+new file mode 100644
+index 0000000..0b17477
+--- /dev/null
++++ b/arch/powerpc/platforms/embedded6xx/usbgecko_udbg.c
+@@ -0,0 +1,318 @@
++/*
++ * arch/powerpc/platforms/embedded6xx/usbgecko_udbg.c
++ *
++ * udbg serial input/output routines for the USB Gecko adapter.
++ * Copyright (C) 2008-2009 The GameCube Linux Team
++ * Copyright (C) 2008,2009 Albert Herranz
++ *
++ * 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 <asm/io.h>
++#include <asm/prom.h>
++#include <asm/udbg.h>
++
++#include <mm/mmu_decl.h>
++
++#include "usbgecko_udbg.h"
++
++
++#define EXI_CLK_32MHZ 5
++
++#define EXI_CSR 0x00
++#define EXI_CSR_CLKMASK (0x7<<4)
++#define EXI_CSR_CLK_32MHZ (EXI_CLK_32MHZ<<4)
++#define EXI_CSR_CSMASK (0x7<<7)
++#define EXI_CSR_CS_0 (0x1<<7) /* Chip Select 001 */
++
++#define EXI_CR 0x0c
++#define EXI_CR_TSTART (1<<0)
++#define EXI_CR_WRITE (1<<2)
++#define EXI_CR_READ_WRITE (2<<2)
++#define EXI_CR_TLEN(len) (((len)-1)<<4)
++
++#define EXI_DATA 0x10
++
++#define UG_READ_ATTEMPTS 100
++#define UG_WRITE_ATTEMPTS 100
++
++
++static void __iomem *ug_io_base;
++
++/*
++ * Performs one input/output transaction between the spi host and the usbgecko.
++ */
++static u32 ug_io_transaction(u32 in)
++{
++ u32 __iomem *csr_reg = ug_io_base + EXI_CSR;
++ u32 __iomem *data_reg = ug_io_base + EXI_DATA;
++ u32 __iomem *cr_reg = ug_io_base + EXI_CR;
++ u32 csr, data, cr;
++
++ /* select */
++ csr = EXI_CSR_CLK_32MHZ | EXI_CSR_CS_0;
++ out_be32(csr_reg, csr);
++
++ /* read/write */
++ data = in;
++ out_be32(data_reg, data);
++ cr = EXI_CR_TLEN(2) | EXI_CR_READ_WRITE | EXI_CR_TSTART;
++ out_be32(cr_reg, cr);
++
++ while (in_be32(cr_reg) & EXI_CR_TSTART)
++ barrier();
++
++ /* deselect */
++ out_be32(csr_reg, 0);
++
++ /* result */
++ data = in_be32(data_reg);
++
++ return data;
++}
++
++/*
++ * Returns true if an usbgecko adapter is found.
++ */
++static int ug_is_adapter_present(void)
++{
++ if (!ug_io_base)
++ return 0;
++
++ return ug_io_transaction(0x90000000) == 0x04700000;
++}
++
++/*
++ * Returns true if the TX fifo is ready for transmission.
++ */
++static int ug_is_txfifo_ready(void)
++{
++ return ug_io_transaction(0xc0000000) & 0x04000000;
++}
++
++/*
++ * Tries to transmit a character.
++ * If the TX fifo is not ready the result is undefined.
++ */
++static void ug_raw_putc(char ch)
++{
++ ug_io_transaction(0xb0000000 | (ch << 20));
++}
++
++/*
++ * Transmits a character.
++ * It silently fails if the TX fifo is not ready after a number of retries.
++ */
++static void ug_putc(char ch)
++{
++ int count = UG_WRITE_ATTEMPTS;
++
++ if (!ug_io_base)
++ return;
++
++ if (ch == '\n')
++ ug_putc('\r');
++
++ while (!ug_is_txfifo_ready() && count--)
++ barrier();
++ if (count)
++ ug_raw_putc(ch);
++}
++
++#if 0
++/*
++ * Trasmits a null terminated character string.
++ */
++static void ug_puts(char *s)
++{
++ while (*s)
++ ug_putc(*s++);
++}
++#endif
++
++/*
++ * Returns true if the RX fifo is ready for transmission.
++ */
++static int ug_is_rxfifo_ready(void)
++{
++ return ug_io_transaction(0xd0000000) & 0x04000000;
++}
++
++/*
++ * Tries to receive a character.
++ * If a character is unavailable the function returns -1.
++ */
++static int ug_raw_getc(void)
++{
++ u32 data = ug_io_transaction(0xa0000000);
++ if (data & 0x08000000)
++ return (data >> 16) & 0xff;
++ else
++ return -1;
++}
++
++/*
++ * Receives a character.
++ * It fails if the RX fifo is not ready after a number of retries.
++ */
++static int ug_getc(void)
++{
++ int count = UG_READ_ATTEMPTS;
++
++ if (!ug_io_base)
++ return -1;
++
++ while (!ug_is_rxfifo_ready() && count--)
++ barrier();
++ return ug_raw_getc();
++}
++
++/*
++ * udbg functions.
++ *
++ */
++
++/*
++ * Transmits a character.
++ */
++void ug_udbg_putc(char ch)
++{
++ ug_putc(ch);
++}
++
++/*
++ * Receives a character. Waits until a character is available.
++ */
++static int ug_udbg_getc(void)
++{
++ int ch;
++
++ while ((ch = ug_getc()) == -1)
++ barrier();
++ return ch;
++}
++
++/*
++ * Receives a character. If a character is not available, returns -1.
++ */
++static int ug_udbg_getc_poll(void)
++{
++ if (!ug_is_rxfifo_ready())
++ return -1;
++ return ug_getc();
++}
++
++/*
++ * Retrieves and prepares the virtual address needed to access the hardware.
++ */
++static void __iomem *ug_udbg_setup_io_base(struct device_node *np)
++{
++ phys_addr_t paddr;
++ const unsigned int *reg;
++
++ reg = of_get_property(np, "reg", NULL);
++ if (reg) {
++ paddr = of_translate_address(np, reg);
++ if (paddr) {
++ ug_io_base = ioremap(paddr, reg[1]);
++ return ug_io_base;
++ }
++ }
++ return NULL;
++}
++
++/*
++ * USB Gecko udbg support initialization.
++ */
++void __init ug_udbg_init(void)
++{
++ struct device_node *np = NULL;
++ struct device_node *stdout;
++ const char *path;
++
++ if (ug_io_base)
++ udbg_printf("%s: early -> final\n", __func__);
++
++ if (!of_chosen) {
++ udbg_printf("%s: missing of_chosen\n", __func__);
++ goto done;
++ }
++
++ path = of_get_property(of_chosen, "linux,stdout-path", NULL);
++ if (!path) {
++ udbg_printf("%s: missing %s property", __func__,
++ "linux,stdout-path");
++ goto done;
++ }
++
++ stdout = of_find_node_by_path(path);
++ if (!stdout) {
++ udbg_printf("%s: missing path %s", __func__, path);
++ goto done;
++ }
++
++ for (np = NULL;
++ (np = of_find_compatible_node(np, NULL, "usbgecko,usbgecko"));)
++ if (np == stdout)
++ break;
++
++ of_node_put(stdout);
++ if (!np) {
++ udbg_printf("%s: stdout is not an usbgecko", __func__);
++ goto done;
++ }
++
++ if (!ug_udbg_setup_io_base(np)) {
++ udbg_printf("%s: failed to setup io base", __func__);
++ goto done;
++ }
++
++ if (!ug_is_adapter_present()) {
++ udbg_printf("usbgecko_udbg: not found\n");
++ ug_io_base = NULL;
++ } else {
++ udbg_putc = ug_udbg_putc;
++ udbg_getc = ug_udbg_getc;
++ udbg_getc_poll = ug_udbg_getc_poll;
++ udbg_printf("usbgecko_udbg: ready\n");
++ }
++
++done:
++ if (np)
++ of_node_put(np);
++ return;
++}
++
++#ifdef CONFIG_PPC_EARLY_DEBUG_USBGECKO
++
++/*
++ * USB Gecko early debug support initialization for udbg.
++ *
++ */
++void __init udbg_init_usbgecko(void)
++{
++ unsigned long vaddr, paddr;
++
++#if defined(CONFIG_GAMECUBE)
++ paddr = 0x0c000000;
++#elif defined(CONFIG_WII)
++ paddr = 0x0d000000;
++#else
++#error Invalid platform for USB Gecko based early debugging.
++#endif
++
++ vaddr = 0xc0000000 | paddr;
++ setbat(1, vaddr, paddr, 128*1024, _PAGE_IO);
++
++ ug_io_base = (void __iomem *)(vaddr | 0x6814);
++
++ udbg_putc = ug_udbg_putc;
++ udbg_getc = ug_udbg_getc;
++ udbg_getc_poll = ug_udbg_getc_poll;
++}
++
++#endif /* CONFIG_PPC_EARLY_DEBUG_USBGECKO */
+diff --git a/arch/powerpc/platforms/embedded6xx/usbgecko_udbg.h b/arch/powerpc/platforms/embedded6xx/usbgecko_udbg.h
+new file mode 100644
+index 0000000..98034ee
+--- /dev/null
++++ b/arch/powerpc/platforms/embedded6xx/usbgecko_udbg.h
+@@ -0,0 +1,36 @@
++/*
++ * arch/powerpc/platforms/embedded6xx/usbgecko_udbg.h
++ *
++ * udbg serial input/output routines for the USB Gecko adapter.
++ * Copyright (C) 2008-2009 The GameCube Linux Team
++ * Copyright (C) 2008,2009 Albert Herranz
++ *
++ * 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.
++ *
++ */
++
++#ifndef __USBGECKO_UDBG_H
++#define __USBGECKO_UDBG_H
++
++#ifdef CONFIG_USBGECKO_UDBG
++
++extern void __init ug_udbg_init(void);
++
++#else
++
++static inline void __init ug_udbg_init(void)
++{
++}
++
++#endif /* CONFIG_USBGECKO_UDBG */
++
++#ifdef CONFIG_PPC_EARLY_DEBUG_USBGECKO
++
++void __init udbg_init_usbgecko(void);
++
++#endif /* CONFIG_PPC_EARLY_DEBUG_USBGECKO */
++
++#endif /* __USBGECKO_UDBG_H */
+diff --git a/arch/powerpc/platforms/embedded6xx/wii.c b/arch/powerpc/platforms/embedded6xx/wii.c
+new file mode 100644
+index 0000000..7a7176d
+--- /dev/null
++++ b/arch/powerpc/platforms/embedded6xx/wii.c
+@@ -0,0 +1,115 @@
++/*
++ * arch/powerpc/platforms/embedded6xx/wii.c
++ *
++ * Nintendo Wii board-specific support
++ * Copyright (C) 2008-2009 The GameCube Linux Team
++ * Copyright (C) 2008,2009 Albert Herranz
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version 2
++ * of the License, or (at your option) any later version.
++ *
++ */
++
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/irq.h>
++#include <linux/seq_file.h>
++#include <linux/kexec.h>
++
++#include <asm/io.h>
++#include <asm/machdep.h>
++#include <asm/prom.h>
++#include <asm/time.h>
++#include <asm/starlet.h>
++#include <asm/udbg.h>
++
++#include "flipper-pic.h"
++#include "gcnvi_udbg.h"
++#include "usbgecko_udbg.h"
++
++
++static void wii_restart(char *cmd)
++{
++ starlet_stm_restart();
++ local_irq_disable();
++ /* spin until power button pressed */
++ for (;;)
++ cpu_relax();
++}
++
++static void wii_power_off(void)
++{
++ starlet_stm_power_off();
++ local_irq_disable();
++ /* spin until power button pressed */
++ for (;;)
++ cpu_relax();
++}
++
++static void wii_halt(void)
++{
++ wii_restart(NULL);
++}
++
++static void wii_show_cpuinfo(struct seq_file *m)
++{
++ seq_printf(m, "vendor\t\t: IBM\n");
++ seq_printf(m, "machine\t\t: Nintendo Wii\n");
++}
++
++static void __init wii_setup_arch(void)
++{
++ ug_udbg_init();
++ gcnvi_udbg_init();
++}
++
++static void __init wii_init_early(void)
++{
++}
++
++static int __init wii_probe(void)
++{
++ unsigned long dt_root;
++
++ dt_root = of_get_flat_dt_root();
++ if (!of_flat_dt_is_compatible(dt_root, "nintendo,wii"))
++ return 0;
++
++ return 1;
++}
++
++#ifdef CONFIG_KEXEC
++static void wii_shutdown(void)
++{
++ /* currently not used */
++}
++
++static int wii_kexec_prepare(struct kimage *image)
++{
++ return 0;
++}
++#endif /* CONFIG_KEXEC */
++
++
++define_machine(wii) {
++ .name = "wii",
++ .probe = wii_probe,
++ .setup_arch = wii_setup_arch,
++ .init_early = wii_init_early,
++ .show_cpuinfo = wii_show_cpuinfo,
++ .restart = wii_restart,
++ .power_off = wii_power_off,
++ .halt = wii_halt,
++ .init_IRQ = flipper_pic_probe,
++ .get_irq = flipper_pic_get_irq,
++ .calibrate_decr = generic_calibrate_decr,
++ .progress = udbg_progress,
++#ifdef CONFIG_KEXEC
++ .machine_shutdown = wii_shutdown,
++ .machine_kexec_prepare = wii_kexec_prepare,
++ .machine_kexec = default_machine_kexec,
++#endif
++};
++
+diff --git a/arch/powerpc/platforms/embedded6xx/wii_dev.c b/arch/powerpc/platforms/embedded6xx/wii_dev.c
+new file mode 100644
+index 0000000..c5ed8b5
+--- /dev/null
++++ b/arch/powerpc/platforms/embedded6xx/wii_dev.c
+@@ -0,0 +1,44 @@
++/*
++ * arch/powerpc/platforms/embedded6xx/wii_dev.c
++ *
++ * Nintendo Wii platform device setup.
++ * Copyright (C) 2008-2009 The GameCube Linux Team
++ * Copyright (C) 2008,2009 Albert Herranz
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version 2
++ * of the License, or (at your option) any later version.
++ *
++ */
++
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/of_platform.h>
++
++#include <asm/machdep.h>
++
++static struct of_device_id wii_of_bus[] = {
++ { .compatible = "nintendo,hollywood", },
++ { },
++};
++
++static int __init wii_device_probe(void)
++{
++ struct device_node *np;
++
++ if (!machine_is(wii))
++ return 0;
++
++ of_platform_bus_probe(NULL, wii_of_bus, NULL);
++
++ np = of_find_compatible_node(NULL, NULL, "nintendo,hollywood-mem2");
++ if (np) {
++ of_platform_device_create(np, NULL, NULL);
++ of_node_put(np);
++ }
++
++ return 0;
++}
++device_initcall(wii_device_probe);
++
+diff --git a/drivers/Kconfig b/drivers/Kconfig
+index 2f557f5..08d2933 100644
+--- a/drivers/Kconfig
++++ b/drivers/Kconfig
+@@ -50,6 +50,8 @@ source "drivers/char/Kconfig"
+
+ source "drivers/i2c/Kconfig"
+
++source "drivers/exi/Kconfig"
++
+ source "drivers/spi/Kconfig"
+
+ source "drivers/gpio/Kconfig"
+diff --git a/drivers/Makefile b/drivers/Makefile
+index fceb71a..d53f062 100644
+--- a/drivers/Makefile
++++ b/drivers/Makefile
+@@ -97,6 +97,8 @@ obj-$(CONFIG_DMA_ENGINE) += dma/
+ obj-$(CONFIG_DCA) += dca/
+ obj-$(CONFIG_HID) += hid/
+ obj-$(CONFIG_PPC_PS3) += ps3/
++obj-$(CONFIG_GAMECUBE_EXI) += exi/
++obj-$(CONFIG_GAMECUBE_SI) += input/si/
+ obj-$(CONFIG_OF) += of/
+ obj-$(CONFIG_SSB) += ssb/
+ obj-$(CONFIG_VIRTIO) += virtio/
+diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig
+index 0344a8a..7dd9143 100644
+--- a/drivers/block/Kconfig
++++ b/drivers/block/Kconfig
+@@ -56,6 +56,93 @@ config AMIGA_Z2RAM
+ To compile this driver as a module, choose M here: the
+ module will be called z2ram.
+
++config GAMECUBE_SD
++ tristate "Nintendo GameCube/Wii MMC/SD card"
++ depends on GAMECUBE_EXI
++ help
++ This enables support for using SD and MMC cards through
++ the Nintendo SD Card Adapter (DOL-019) or compatible hardware.
++
++ You probably want to compile FAT support, and the required
++ codepages, or mount will complain. See Filesystems -> DOS/FAT/NT
++ filesystems and Filesystems -> Native Language Support
++
++ Say Y if you want to include this driver in the kernel.
++
++ To compile this driver as a module, choose M here: the
++ module will be called gcn-sd.
++
++config GAMECUBE_ARAM
++ tristate "Nintendo GameCube Auxiliary RAM (ARAM)"
++ depends on GAMECUBE
++ help
++ This enables support for using the 16MB of ARAM found in the
++ Nintendo GameCube as a block device.
++ Say Y if you want to include this driver in the kernel.
++
++ To compile this driver as a module, choose M here: the
++ module will be called gcn-aram.
++
++config GAMECUBE_DI
++ tristate "Nintendo GameCube Disk Interface (DI)"
++ depends on GAMECUBE
++ help
++ This enables support for using the DVD drive unit found
++ in the Nintendo GameCube.
++ Say Y if you want to include this driver in the kernel.
++
++ To compile this driver as a module, choose M here: the
++ module will be called gcn-di.
++
++config GAMECUBE_DVD
++ tristate "Nintendo Gamecube DVD"
++ depends on GAMECUBE && !GAMECUBE_DI && BROKEN
++ help
++ This enables support for using the mini-DVD drive on the
++ Nintendo Gamecube.
++ Say Y if you want to include this driver in the kernel.
++
++ To compile this driver as a module, choose M here: the
++ module will be called gcn-dvd
++
++config GAMECUBE_MEMCARD
++ tristate "Nintendo GameCube/Wii memory card (EXPERIMENTAL)"
++ depends on GAMECUBE_EXI && EXPERIMENTAL && BROKEN
++ help
++ This enables support for using memory cards compatible with the
++ Nintendo GameCube.
++ Say Y if you want to include this driver in the kernel.
++
++ To compile this driver as a module, choose M here: the
++ module will be called gcn-memcard.
++
++config WII_MEM2
++ tristate "Nintendo Wii MEM2"
++ depends on WII
++ help
++ This enables support for using the MEM2 found in the
++ Nintendo Wii as a block device.
++ Say Y if you want to include this driver in the kernel.
++
++ To compile this driver as a module, choose M here: the
++ module will be called rvl-mem2.
++
++ config WII_SD
++ tristate "Nintendo Wii front slot MMC/SD"
++ depends on WII
++ help
++ This enables support for MMC/SD cards using the front SD card
++ slot of the Nintendo Wii.
++
++ You probably want to compile FAT support, and the required
++ codepages, or mount will complain. See Filesystems -> DOS/FAT/NT
++ filesystems and Filesystems -> Native Language Support
++
++ Say Y if you want to include this driver in the kernel.
++
++ To compile this driver as a module, choose M here: the
++ module will be called rvl-stsd.
++
+ config BLK_DEV_XD
+ tristate "XT hard disk support"
+ depends on ISA && ISA_DMA_API
+diff --git a/drivers/block/Makefile b/drivers/block/Makefile
+index 204332b..1af7546 100644
+--- a/drivers/block/Makefile
++++ b/drivers/block/Makefile
+@@ -11,6 +11,13 @@ obj-$(CONFIG_AMIGA_FLOPPY) += amiflop.o
+ obj-$(CONFIG_PS3_DISK) += ps3disk.o
+ obj-$(CONFIG_ATARI_FLOPPY) += ataflop.o
+ obj-$(CONFIG_AMIGA_Z2RAM) += z2ram.o
++obj-$(CONFIG_GAMECUBE_SD) += gcn-sd.o
++obj-$(CONFIG_GAMECUBE_ARAM) += gcn-aram.o
++obj-$(CONFIG_GAMECUBE_DI) += gcn-di/
++obj-$(CONFIG_GAMECUBE_DVD) += gcn-dvd/
++obj-$(CONFIG_GAMECUBE_MEMCARD) += gcn-memcard.o
++obj-$(CONFIG_WII_MEM2) += rvl-mem2.o
++obj-$(CONFIG_WII_SD) += rvl-stsd.o
+ obj-$(CONFIG_BLK_DEV_RAM) += brd.o
+ obj-$(CONFIG_BLK_DEV_LOOP) += loop.o
+ obj-$(CONFIG_BLK_DEV_XD) += xd.o
+diff --git a/drivers/block/gcn-aram.c b/drivers/block/gcn-aram.c
+new file mode 100644
+index 0000000..bc2774d
+--- /dev/null
++++ b/drivers/block/gcn-aram.c
+@@ -0,0 +1,597 @@
++/*
++ * drivers/block/gcn-aram.c
++ *
++ * Nintendo GameCube Auxiliary RAM (ARAM) block driver
++ * Copyright (C) 2004-2009 The GameCube Linux Team
++ * Copyright (C) 2005 Todd Jeffreys <todd@voidpointer.org>
++ * Copyright (C) 2005,2007,2008,2009 Albert Herranz
++ *
++ * Based on previous work by Franz Lehner.
++ *
++ * 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/blkdev.h>
++#include <linux/dma-mapping.h>
++#include <linux/fcntl.h> /* O_ACCMODE */
++#include <linux/hdreg.h> /* HDIO_GETGEO */
++#include <linux/interrupt.h>
++#include <linux/major.h>
++#include <linux/module.h>
++#include <linux/of_platform.h>
++#include <linux/io.h>
++
++
++#define DRV_MODULE_NAME "gcn-aram"
++#define DRV_DESCRIPTION "Nintendo GameCube Auxiliary RAM (ARAM) block driver"
++#define DRV_AUTHOR "Todd Jeffreys <todd@voidpointer.org>, " \
++ "Albert Herranz"
++
++static char aram_driver_version[] = "4.0i";
++
++#define drv_printk(level, format, arg...) \
++ printk(level DRV_MODULE_NAME ": " format , ## arg)
++
++
++/*
++ * Hardware.
++ */
++#define ARAM_DMA_ALIGN 0x1f /* 32 bytes */
++
++#define DSP_CSR 0x00a
++#define DSP_CSR_RES (1<<0)
++#define DSP_CSR_PIINT (1<<1)
++#define DSP_CSR_HALT (1<<2)
++#define DSP_CSR_AIDINT (1<<3)
++#define DSP_CSR_AIDINTMASK (1<<4)
++#define DSP_CSR_ARINT (1<<5)
++#define DSP_CSR_ARINTMASK (1<<6)
++#define DSP_CSR_DSPINT (1<<7)
++#define DSP_CSR_DSPINTMASK (1<<8)
++#define DSP_CSR_DSPDMA (1<<9)
++#define DSP_CSR_RESETXXX (1<<11)
++
++#define AR_SIZE 0x012
++
++#define AR_MODE 0x016
++#define AR_MODE_ACCELERATOR (1 << 0)
++
++#define AR_REFRESH 0x01a
++
++#define AR_DMA_MMADDR 0x020
++
++#define AR_DMA_ARADDR 0x024
++
++#define AR_DMA_CNT_H 0x028
++#define AR_READ (1 << 31)
++#define AR_WRITE 0
++
++#define AR_DMA_CNT_L 0x02a
++
++#define AR_DMA_CNT AR_DMA_CNT_H
++
++/*
++ * Driver settings
++ */
++#define ARAM_NAME DRV_MODULE_NAME
++#define ARAM_MAJOR Z2RAM_MAJOR /* we share the major */
++
++#define ARAM_SECTOR_SIZE PAGE_SIZE
++
++#define ARAM_BUFFERSIZE (16*1024*1024)
++
++/*
++ * Driver data.
++ */
++struct aram_drvdata {
++ spinlock_t lock;
++
++ spinlock_t io_lock;
++ void __iomem *io_base;
++ int irq;
++
++ struct block_device_operations fops;
++ struct gendisk *disk;
++ struct request_queue *queue;
++
++ struct request *req;
++ dma_addr_t dma_addr;
++ size_t dma_len;
++
++ int ref_count;
++
++ struct device *dev;
++};
++
++
++static inline enum dma_data_direction rq_dir_to_dma_dir(struct request *req)
++{
++ if (rq_data_dir(req) == READ)
++ return DMA_FROM_DEVICE;
++ else
++ return DMA_TO_DEVICE;
++}
++
++static inline int rq_dir_to_aram_dir(struct request *req)
++{
++ if (rq_data_dir(req) == READ)
++ return AR_READ;
++ else
++ return AR_WRITE;
++}
++
++static void aram_start_dma_transfer(struct aram_drvdata *drvdata,
++ unsigned long aram_addr)
++{
++ void __iomem *io_base = drvdata->io_base;
++ dma_addr_t dma_addr = drvdata->dma_addr;
++ size_t dma_len = drvdata->dma_len;
++
++ /* DMA transfers require proper alignment */
++ BUG_ON((dma_addr & ARAM_DMA_ALIGN) != 0 ||
++ (dma_len & ARAM_DMA_ALIGN) != 0);
++
++ out_be32(io_base + AR_DMA_MMADDR, dma_addr);
++ out_be32(io_base + AR_DMA_ARADDR, aram_addr);
++
++ /* writing the low-word kicks off the DMA */
++ out_be32(io_base + AR_DMA_CNT,
++ rq_dir_to_aram_dir(drvdata->req) | dma_len);
++}
++
++static irqreturn_t aram_irq_handler(int irq, void *dev0)
++{
++ struct aram_drvdata *drvdata = dev0;
++ struct request *req;
++ u16 __iomem *csr_reg = drvdata->io_base + DSP_CSR;
++ u16 csr;
++ unsigned long flags;
++
++ spin_lock_irqsave(&drvdata->io_lock, flags);
++
++ csr = in_be16(csr_reg);
++
++ /*
++ * Do nothing if the interrupt is not targetted for us.
++ * We share this interrupt with the sound driver.
++ */
++ if (!(csr & DSP_CSR_ARINT)) {
++ spin_unlock_irqrestore(&drvdata->io_lock, flags);
++ return IRQ_NONE;
++ }
++
++ /* strictly ack the ARAM interrupt, and nothing more */
++ csr &= ~(DSP_CSR_AIDINT | DSP_CSR_DSPINT);
++ out_be16(csr_reg, csr);
++
++ /* pick up current request being serviced */
++ req = drvdata->req;
++ drvdata->req = NULL;
++
++ spin_unlock_irqrestore(&drvdata->io_lock, flags);
++
++ if (req) {
++ __blk_end_request(req, 0, req->current_nr_sectors << 9);
++ dma_unmap_single(drvdata->dev,
++ drvdata->dma_addr, drvdata->dma_len,
++ rq_dir_to_dma_dir(req));
++ spin_lock(&drvdata->lock);
++ blk_start_queue(drvdata->queue);
++ spin_unlock(&drvdata->lock);
++ } else {
++ drv_printk(KERN_ERR, "ignoring interrupt, no request\n");
++ }
++
++ return IRQ_HANDLED;
++}
++
++static void aram_do_request(struct request_queue *q)
++{
++ struct aram_drvdata *drvdata = q->queuedata;
++ struct request *req;
++ unsigned long aram_addr;
++ size_t len;
++ unsigned long flags;
++
++ req = elv_next_request(q);
++ while (req) {
++ spin_lock_irqsave(&drvdata->io_lock, flags);
++
++ /* we schedule a single request each time */
++ if (drvdata->req) {
++ spin_unlock_irqrestore(&drvdata->io_lock, flags);
++ blk_stop_queue(q);
++ break;
++ }
++
++ blkdev_dequeue_request(req);
++
++ /* ignore requests that we can't handle */
++ if (!blk_fs_request(req)) {
++ spin_unlock_irqrestore(&drvdata->io_lock, flags);
++ continue;
++ }
++
++ /* store the request being handled */
++ drvdata->req = req;
++ blk_stop_queue(q);
++
++ spin_unlock_irqrestore(&drvdata->io_lock, flags);
++
++ /* calculate the ARAM address and length */
++ aram_addr = req->sector << 9;
++ len = req->current_nr_sectors << 9;
++
++ /* give up if the request goes out of bounds */
++ if (aram_addr + len > ARAM_BUFFERSIZE) {
++ drv_printk(KERN_ERR, "bad access: block=%lu,"
++ " size=%u\n", (unsigned long)req->sector,
++ len);
++ /* XXX correct? the request is already dequeued */
++ end_request(req, 0);
++ continue;
++ }
++
++ BUG_ON(req->nr_phys_segments != 1);
++
++ /* perform DMA mappings */
++ drvdata->dma_len = len;
++ drvdata->dma_addr = dma_map_single(drvdata->dev,
++ req->buffer, len,
++ rq_dir_to_dma_dir(req));
++
++ /* start the DMA transfer */
++ aram_start_dma_transfer(drvdata, aram_addr);
++ break;
++ }
++}
++
++/*
++ * Block device hooks.
++ *
++ */
++
++static int aram_open(struct block_device *bdev, fmode_t mode)
++{
++ struct aram_drvdata *drvdata = bdev->bd_disk->private_data;
++ unsigned long flags;
++ int retval = 0;
++
++ spin_lock_irqsave(&drvdata->lock, flags);
++
++ /* only allow a minor of 0 to be opened */
++ if (MINOR(bdev->bd_dev)) {
++ retval = -ENODEV;
++ goto out;
++ }
++
++ /* honor exclusive open mode */
++ if (drvdata->ref_count == -1 ||
++ (drvdata->ref_count && (mode & FMODE_EXCL))) {
++ retval = -EBUSY;
++ goto out;
++ }
++
++ if ((mode & FMODE_EXCL))
++ drvdata->ref_count = -1;
++ else
++ drvdata->ref_count++;
++
++out:
++ spin_unlock_irqrestore(&drvdata->lock, flags);
++ return retval;
++}
++
++static int aram_release(struct gendisk *disk, fmode_t mode)
++{
++ struct aram_drvdata *drvdata = disk->private_data;
++ unsigned long flags;
++
++ spin_lock_irqsave(&drvdata->lock, flags);
++ if (drvdata->ref_count > 0)
++ drvdata->ref_count--;
++ else
++ drvdata->ref_count = 0;
++ spin_unlock_irqrestore(&drvdata->lock, flags);
++
++ return 0;
++}
++
++static int aram_getgeo(struct block_device *bdev, struct hd_geometry *geo)
++{
++ geo->cylinders = get_capacity(bdev->bd_disk) / (4 * 16);
++ geo->heads = 4;
++ geo->sectors = 16;
++ return 0;
++}
++
++static struct block_device_operations aram_fops = {
++ .owner = THIS_MODULE,
++ .open = aram_open,
++ .release = aram_release,
++ .getgeo = aram_getgeo,
++};
++
++
++/*
++ * Setup routines.
++ *
++ */
++
++static int aram_init_blk_dev(struct aram_drvdata *drvdata)
++{
++ struct gendisk *disk;
++ struct request_queue *queue;
++ int retval;
++
++ drvdata->ref_count = 0;
++
++ retval = register_blkdev(ARAM_MAJOR, ARAM_NAME);
++ if (retval)
++ goto err_register_blkdev;
++
++ retval = -ENOMEM;
++ spin_lock_init(&drvdata->lock);
++ spin_lock_init(&drvdata->io_lock);
++ queue = blk_init_queue(aram_do_request, &drvdata->lock);
++ if (!queue)
++ goto err_blk_init_queue;
++
++ blk_queue_hardsect_size(queue, ARAM_SECTOR_SIZE);
++ blk_queue_dma_alignment(queue, ARAM_DMA_ALIGN);
++ blk_queue_max_phys_segments(queue, 1);
++ blk_queue_max_hw_segments(queue, 1);
++ queue->queuedata = drvdata;
++ drvdata->queue = queue;
++
++ disk = alloc_disk(1);
++ if (!disk)
++ goto err_alloc_disk;
++
++ disk->major = ARAM_MAJOR;
++ disk->first_minor = 0;
++ disk->fops = &aram_fops;
++ strcpy(disk->disk_name, ARAM_NAME);
++ disk->queue = drvdata->queue;
++ set_capacity(disk, ARAM_BUFFERSIZE >> 9);
++ disk->private_data = drvdata;
++ drvdata->disk = disk;
++
++ add_disk(drvdata->disk);
++
++ retval = 0;
++ goto out;
++
++err_alloc_disk:
++ blk_cleanup_queue(drvdata->queue);
++err_blk_init_queue:
++ unregister_blkdev(ARAM_MAJOR, ARAM_NAME);
++err_register_blkdev:
++out:
++ return retval;
++}
++
++static void aram_exit_blk_dev(struct aram_drvdata *drvdata)
++{
++ if (drvdata->disk) {
++ del_gendisk(drvdata->disk);
++ put_disk(drvdata->disk);
++ }
++ if (drvdata->queue)
++ blk_cleanup_queue(drvdata->queue);
++ unregister_blkdev(ARAM_MAJOR, ARAM_NAME);
++}
++
++static void aram_quiesce(struct aram_drvdata *drvdata)
++{
++ u16 __iomem *csr_reg = drvdata->io_base + DSP_CSR;
++ u16 csr;
++ unsigned long flags;
++
++ /*
++ * Disable ARAM interrupts, but do not accidentally ack non-ARAM ones.
++ */
++ spin_lock_irqsave(&drvdata->io_lock, flags);
++ csr = in_be16(csr_reg);
++ csr &= ~(DSP_CSR_AIDINT | DSP_CSR_DSPINT | DSP_CSR_ARINTMASK);
++ out_be16(csr_reg, csr);
++ spin_unlock_irqrestore(&drvdata->io_lock, flags);
++
++ /* wait until pending transfers are finished */
++ while (in_be16(csr_reg) & DSP_CSR_DSPDMA)
++ cpu_relax();
++}
++
++static int aram_init_irq(struct aram_drvdata *drvdata)
++{
++ u16 __iomem *csr_reg = drvdata->io_base + DSP_CSR;
++ u16 csr;
++ unsigned long flags;
++ int retval;
++
++ retval = request_irq(drvdata->irq, aram_irq_handler,
++ IRQF_DISABLED | IRQF_SHARED,
++ DRV_MODULE_NAME, drvdata);
++ if (retval) {
++ drv_printk(KERN_ERR, "request of IRQ %d failed\n",
++ drvdata->irq);
++ goto out;
++ }
++
++ /*
++ * Enable ARAM interrupts, and route them to the processor.
++ * Make sure to preserve the AI and DSP interrupts.
++ */
++ spin_lock_irqsave(&drvdata->io_lock, flags);
++ csr = in_be16(csr_reg);
++ csr |= (DSP_CSR_ARINT | DSP_CSR_ARINTMASK | DSP_CSR_PIINT);
++ csr &= ~(DSP_CSR_AIDINT | DSP_CSR_DSPINT);
++ out_be16(csr_reg, csr);
++ spin_unlock_irqrestore(&drvdata->io_lock, flags);
++
++out:
++ return retval;
++}
++
++static void aram_exit_irq(struct aram_drvdata *drvdata)
++{
++ aram_quiesce(drvdata);
++
++ free_irq(drvdata->irq, drvdata);
++}
++
++static int aram_init(struct aram_drvdata *drvdata,
++ struct resource *mem, int irq)
++{
++ int retval;
++
++ drvdata->io_base = ioremap(mem->start, mem->end - mem->start + 1);
++ drvdata->irq = irq;
++
++ retval = aram_init_blk_dev(drvdata);
++ if (!retval) {
++ retval = aram_init_irq(drvdata);
++ if (retval)
++ aram_exit_blk_dev(drvdata);
++ }
++ return retval;
++}
++
++static void aram_exit(struct aram_drvdata *drvdata)
++{
++ aram_exit_blk_dev(drvdata);
++ aram_exit_irq(drvdata);
++ if (drvdata->io_base) {
++ iounmap(drvdata->io_base);
++ drvdata->io_base = NULL;
++ }
++}
++
++/*
++ * Driver model helper routines.
++ *
++ */
++
++static int aram_do_probe(struct device *dev, struct resource *mem,
++ int irq)
++{
++ struct aram_drvdata *drvdata;
++ int retval;
++
++ drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL);
++ if (!drvdata) {
++ drv_printk(KERN_ERR, "failed to allocate aram_drvdata\n");
++ return -ENOMEM;
++ }
++ dev_set_drvdata(dev, drvdata);
++ drvdata->dev = dev;
++
++ retval = aram_init(drvdata, mem, irq);
++ if (retval) {
++ dev_set_drvdata(dev, NULL);
++ kfree(drvdata);
++ }
++ return retval;
++}
++
++static int aram_do_remove(struct device *dev)
++{
++ struct aram_drvdata *drvdata = dev_get_drvdata(dev);
++
++ if (drvdata) {
++ aram_exit(drvdata);
++ dev_set_drvdata(dev, NULL);
++ kfree(drvdata);
++ return 0;
++ }
++ return -ENODEV;
++}
++
++static int aram_do_shutdown(struct device *dev)
++{
++ struct aram_drvdata *drvdata = dev_get_drvdata(dev);
++
++ if (drvdata)
++ aram_quiesce(drvdata);
++ return 0;
++}
++
++
++/*
++ * OF platform device routines.
++ *
++ */
++
++static int __init aram_of_probe(struct of_device *odev,
++ const struct of_device_id *match)
++{
++ struct resource res;
++ int retval;
++
++ retval = of_address_to_resource(odev->node, 0, &res);
++ if (retval) {
++ drv_printk(KERN_ERR, "no io memory range found\n");
++ return -ENODEV;
++ }
++
++ return aram_do_probe(&odev->dev,
++ &res, irq_of_parse_and_map(odev->node, 0));
++}
++
++static int __exit aram_of_remove(struct of_device *odev)
++{
++ return aram_do_remove(&odev->dev);
++}
++
++static int aram_of_shutdown(struct of_device *odev)
++{
++ return aram_do_shutdown(&odev->dev);
++}
++
++
++static struct of_device_id aram_of_match[] = {
++ { .compatible = "nintendo,flipper-auxram" },
++ { },
++};
++
++
++MODULE_DEVICE_TABLE(of, aram_of_match);
++
++static struct of_platform_driver aram_of_driver = {
++ .owner = THIS_MODULE,
++ .name = DRV_MODULE_NAME,
++ .match_table = aram_of_match,
++ .probe = aram_of_probe,
++ .remove = aram_of_remove,
++ .shutdown = aram_of_shutdown,
++};
++
++/*
++ * Module interfaces.
++ *
++ */
++
++static int __init aram_init_module(void)
++{
++ drv_printk(KERN_INFO, "%s - version %s\n", DRV_DESCRIPTION,
++ aram_driver_version);
++
++ return of_register_platform_driver(&aram_of_driver);
++}
++
++static void __exit aram_exit_module(void)
++{
++ of_unregister_platform_driver(&aram_of_driver);
++}
++
++module_init(aram_init_module);
++module_exit(aram_exit_module);
++
++MODULE_DESCRIPTION(DRV_DESCRIPTION);
++MODULE_AUTHOR(DRV_AUTHOR);
++MODULE_LICENSE("GPL");
++
+diff --git a/drivers/block/gcn-di/Makefile b/drivers/block/gcn-di/Makefile
+new file mode 100644
+index 0000000..09a410d
+--- /dev/null
++++ b/drivers/block/gcn-di/Makefile
+@@ -0,0 +1,50 @@
++obj-$(CONFIG_GAMECUBE_DI) += gcn-di.o
++
++$(obj)/gcn-di.o: $(obj)/drive_20010608.h \
++ $(obj)/drive_20010831.h \
++ $(obj)/drive_20020402.h \
++ $(obj)/drive_20020823.h
++
++#CONFIG_GAMECUBE_DI_BUILD_FIRMWARE=y
++
++ifeq ($(CONFIG_GAMECUBE_DI_BUILD_FIRMWARE),y)
++
++ASMN102 = mn10200-linux-as
++LDMN102 = mn10200-linux-ld
++OCMN102 = mn10200-linux-objcopy
++
++quiet_cmd_build_difw = BLD FW $@
++cmd_build_difw = \
++ $(CPP) -DDRIVE_MODEL=$(DRIVE_MODEL) $< > $(obj)/$(@F).s; \
++ $(ASMN102) -o $(obj)/$(@F).o $(obj)/$(@F).s; \
++ $(LDMN102) --section-start absolute=0 -Ttext=0x40d000 \
++ -o $(obj)/$(@F).elf -e 0x40d000 $(obj)/$(@F).o; \
++ $(OCMN102) -I elf32-mn10200 -O binary $(obj)/$(@F).elf \
++ $(obj)/$(@F).bin; \
++ (echo -n "static "; cat $(obj)/$(@F).bin | scripts/bin2c "$(subst .h,,$(@F))_firmware") > $@; \
++ rm -f $(obj)/$(@F).o $(obj)/$(@F).elf $(obj)/$(@F).bin $(obj)/$(@F).s
++
++
++targets += drive_20010608.h
++$(obj)/drive_20010608.h: DRIVE_MODEL := 0x20010608
++$(obj)/drive_20010608.h: $(src)/drive_all.S FORCE
++ $(call if_changed,build_difw)
++
++targets += drive_20010831.h
++$(obj)/drive_20010831.h: DRIVE_MODEL := 0x20010831
++$(obj)/drive_20010831.h: $(src)/drive_all.S FORCE
++ $(call if_changed,build_difw)
++
++targets += drive_20020402.h
++$(obj)/drive_20020402.h: DRIVE_MODEL := 0x20020402
++$(obj)/drive_20020402.h: $(src)/drive_all.S FORCE
++ $(call if_changed,build_difw)
++
++targets += drive_20020823.h
++$(obj)/drive_20020823.h: DRIVE_MODEL := 0x20020823
++$(obj)/drive_20020823.h: $(src)/drive_all.S FORCE
++ $(call if_changed,build_difw)
++
++endif
++
++
+diff --git a/drivers/block/gcn-di/drive_20010608.h b/drivers/block/gcn-di/drive_20010608.h
+new file mode 100644
+index 0000000..7c3e9d8
+--- /dev/null
++++ b/drivers/block/gcn-di/drive_20010608.h
+@@ -0,0 +1,25 @@
++static const char drive_20010608_firmware[] =
++ "\xf7\x10\xff\xf7\xf4\x74\x25\xd0\x40\xf7\x20\x4c\x80\xf4\x74\x42"
++ "\x9d\x08\xf7\x20\xd6\xfc\xf4\x74\x45\xb1\x08\xf7\x20\xd2\xfc\x80"
++ "\x0c\xc4\xda\xfc\xfe\xc8\xda\xfc\xf5\x00\x01\xe9\x70\xc8\xda\xfc"
++ "\xf5\x00\x02\xe9\x75\xf4\x74\x02\xed\x40\x80\x02\xf0\x20\xc8\x78"
++ "\x80\xc0\x90\x81\xdc\xa8\x80\xf5\x30\x00\xf4\x44\x41\xd1\x40\xf8"
++ "\xaa\x00\x10\xf4\xd0\x3c\xd1\x40\xf0\x01\xdc\xa8\x80\xf5\x30\x00"
++ "\xf7\x48\xaa\x00\xe9\x07\xf4\xc4\x41\xd1\x40\x10\xfe\xf7\x48\xee"
++ "\x00\xe8\x0c\xd8\x55\xe9\x25\xcc\xa9\x80\xfd\x79\x00\xea\x0c\xcc"
++ "\xa9\x80\xc4\xa4\x81\xcc\xaa\x80\xc4\x88\x81\xdc\xa8\x80\xf8\xe0"
++ "\x00\x10\xa0\xf5\x10\x01\xf5\x10\x02\xf5\x10\x03\xfe\xc8\xda\xfc"
++ "\xf7\x00\xfe\xff\xf7\x31\xd2\xfc\xea\x0b\xc8\xda\xfc\xf7\x00\xfd"
++ "\xff\xf7\x31\xd6\xfc\xc4\xda\xfc\xcc\x44\xfc\xf7\x00\xfe\xff\xc4"
++ "\x44\xfc\xf4\x7d\x45\xb1\x08\xe9\x07\xf4\x75\x0c\xd1\x40\xea\x0c"
++ "\xf4\x7d\x42\x9d\x08\xe9\x05\xf4\x75\x35\xd1\x40\xf2\x7c\xd0\x04"
++ "\xcc\x5b\x80\xd8\x01\xe9\x02\x7c\x04\x51\x20\x71\x34\xf4\x7d\xb9"
++ "\x85\x08\xe9\x13\x80\x00\x85\x00\xd8\x00\xe8\x02\x85\x0c\xc5\xda"
++ "\xfc\xf4\x75\x40\xd1\x40\x14\xfe\x80\x01\xea\xea\xf7\x10\xff\xf7"
++ "\xf4\xc9\x40\xd1\x40\xd9\x00\xe8\x17\x21\xf4\x79\x00\xf0\x00\xe9"
++ "\x05\x80\x00\xf5\x10\x09\xd9\x06\xe9\x06\x61\x06\xd5\x06\x41\x06"
++ "\xf4\xe0\x1b\xe0\xc7\xf4\xe0\x96\xcc\xc7\x00\x00\x74\x0a\x08\x00"
++ "\x01\x00\x00\x00"
++ ;
++
++const int drive_20010608_firmware_size = 324;
+diff --git a/drivers/block/gcn-di/drive_20010831.h b/drivers/block/gcn-di/drive_20010831.h
+new file mode 100644
+index 0000000..16df341
+--- /dev/null
++++ b/drivers/block/gcn-di/drive_20010831.h
+@@ -0,0 +1,25 @@
++static const char drive_20010831_firmware[] =
++ "\xf7\x10\xff\xf7\xf4\x74\x25\xd0\x40\xf7\x20\x4c\x80\xf4\x74\x39"
++ "\x9e\x08\xf7\x20\xd6\xfc\xf4\x74\x02\xb3\x08\xf7\x20\xd2\xfc\x80"
++ "\x0c\xc4\xda\xfc\xfe\xc8\xda\xfc\xf5\x00\x01\xe9\x70\xc8\xda\xfc"
++ "\xf5\x00\x02\xe9\x75\xf4\x74\x02\xed\x40\x80\x02\xf0\x20\xc8\x78"
++ "\x80\xc0\x92\x81\xdc\xaa\x80\xf5\x30\x00\xf4\x44\x41\xd1\x40\xf8"
++ "\xaa\x00\x10\xf4\xd0\x3c\xd1\x40\xf0\x01\xdc\xaa\x80\xf5\x30\x00"
++ "\xf7\x48\xaa\x00\xe9\x07\xf4\xc4\x41\xd1\x40\x10\xfe\xf7\x48\xee"
++ "\x00\xe8\x0c\xd8\x55\xe9\x25\xcc\xab\x80\xfd\x79\x00\xea\x0c\xcc"
++ "\xab\x80\xc4\xa6\x81\xcc\xac\x80\xc4\x8a\x81\xdc\xaa\x80\xf8\xe0"
++ "\x00\x10\xa0\xf5\x10\x01\xf5\x10\x02\xf5\x10\x03\xfe\xc8\xda\xfc"
++ "\xf7\x00\xfe\xff\xf7\x31\xd2\xfc\xea\x0b\xc8\xda\xfc\xf7\x00\xfd"
++ "\xff\xf7\x31\xd6\xfc\xc4\xda\xfc\xcc\x44\xfc\xf7\x00\xfe\xff\xc4"
++ "\x44\xfc\xf4\x7d\x02\xb3\x08\xe9\x07\xf4\x75\x0c\xd1\x40\xea\x0c"
++ "\xf4\x7d\x39\x9e\x08\xe9\x05\xf4\x75\x35\xd1\x40\xf2\x7c\xd0\x04"
++ "\xcc\x5b\x80\xd8\x01\xe9\x02\x7c\x04\x51\x20\x71\x34\xf4\x7d\x7f"
++ "\x86\x08\xe9\x13\x80\x00\x85\x00\xd8\x00\xe8\x02\x85\x0c\xc5\xda"
++ "\xfc\xf4\x75\x40\xd1\x40\x14\xfe\x80\x01\xea\xea\xf7\x10\xff\xf7"
++ "\xf4\xc9\x40\xd1\x40\xd9\x00\xe8\x17\x21\xf4\x79\x00\xf0\x00\xe9"
++ "\x05\x80\x00\xf5\x10\x09\xd9\x06\xe9\x06\x61\x06\xd5\x06\x41\x06"
++ "\xf4\xe0\xd8\xe1\xc7\xf4\xe0\x4a\xce\xc7\x00\x00\xa4\x0a\x08\x00"
++ "\x01\x00\x00\x00"
++ ;
++
++const int drive_20010831_firmware_size = 324;
+diff --git a/drivers/block/gcn-di/drive_20020402.h b/drivers/block/gcn-di/drive_20020402.h
+new file mode 100644
+index 0000000..dc80971
+--- /dev/null
++++ b/drivers/block/gcn-di/drive_20020402.h
+@@ -0,0 +1,25 @@
++static const char drive_20020402_firmware[] =
++ "\xf7\x10\xff\xf7\xf4\x74\x25\xd0\x40\xf7\x20\x4c\x80\xf4\x74\xd6"
++ "\x9c\x08\xf7\x20\xd6\xfc\xf4\x74\x28\xae\x08\xf7\x20\xd2\xfc\x80"
++ "\x0c\xc4\xda\xfc\xfe\xc8\xda\xfc\xf5\x00\x01\xe9\x70\xc8\xda\xfc"
++ "\xf5\x00\x02\xe9\x75\xf4\x74\xf9\xec\x40\x80\x02\xf0\x20\xc8\x84"
++ "\x80\xc0\x9c\x81\xdc\xb4\x80\xf5\x30\x00\xf4\x44\x41\xd1\x40\xf8"
++ "\xaa\x00\x10\xf4\xd0\x3c\xd1\x40\xf0\x01\xdc\xb4\x80\xf5\x30\x00"
++ "\xf7\x48\xaa\x00\xe9\x07\xf4\xc4\x41\xd1\x40\x10\xfe\xf7\x48\xee"
++ "\x00\xe8\x0c\xd8\x55\xe9\x25\xcc\xb5\x80\xfd\x79\x00\xea\x0c\xcc"
++ "\xb5\x80\xc4\xb0\x81\xcc\xb6\x80\xc4\x94\x81\xdc\xb4\x80\xf8\xe0"
++ "\x00\x10\xa0\xf5\x10\x01\xf5\x10\x02\xf5\x10\x03\xfe\xc8\xda\xfc"
++ "\xf7\x00\xfe\xff\xf7\x31\xd2\xfc\xea\x0b\xc8\xda\xfc\xf7\x00\xfd"
++ "\xff\xf7\x31\xd6\xfc\xc4\xda\xfc\xcc\x44\xfc\xf7\x00\xfe\xff\xc4"
++ "\x44\xfc\xf4\x7d\x28\xae\x08\xe9\x07\xf4\x75\x0c\xd1\x40\xea\x0c"
++ "\xf4\x7d\xd6\x9c\x08\xe9\x05\xf4\x75\x35\xd1\x40\xf2\x7c\xd0\x04"
++ "\xcc\x5b\x80\xd8\x01\xe9\x02\x7c\x04\x51\x20\x71\x34\xf4\x7d\xc1"
++ "\x85\x08\xe9\x13\x80\x00\x85\x00\xd8\x00\xe8\x02\x85\x0c\xc5\xda"
++ "\xfc\xf4\x75\x40\xd1\x40\x14\xfe\x80\x01\xea\xea\xf7\x10\xff\xf7"
++ "\xf4\xc9\x40\xd1\x40\xd9\x00\xe8\x17\x21\xf4\x79\x00\xf0\x00\xe9"
++ "\x05\x80\x00\xf5\x10\x09\xd9\x06\xe9\x06\x61\x06\xd5\x06\x41\x06"
++ "\xf4\xe0\xfe\xdc\xc7\xf4\xe0\x14\xcc\xc7\x00\x00\x74\x0a\x08\x00"
++ "\x01\x00\x00\x00"
++ ;
++
++const int drive_20020402_firmware_size = 324;
+diff --git a/drivers/block/gcn-di/drive_20020823.h b/drivers/block/gcn-di/drive_20020823.h
+new file mode 100644
+index 0000000..f20b5cc
+--- /dev/null
++++ b/drivers/block/gcn-di/drive_20020823.h
+@@ -0,0 +1,25 @@
++static const char drive_20020823_firmware[] =
++ "\xf7\x10\xff\xf7\xf4\x74\x25\xd0\x40\xf7\x20\x4c\x80\xf4\x74\x32"
++ "\x9d\x08\xf7\x20\xd6\xfc\xf4\x74\x75\xae\x08\xf7\x20\xd2\xfc\x80"
++ "\x0c\xc4\xda\xfc\xfe\xc8\xda\xfc\xf5\x00\x01\xe9\x70\xc8\xda\xfc"
++ "\xf5\x00\x02\xe9\x75\xf4\x74\xf5\xec\x40\x80\x02\xf0\x20\xc8\x80"
++ "\x80\xc0\x98\x81\xdc\xb0\x80\xf5\x30\x00\xf4\x44\x41\xd1\x40\xf8"
++ "\xaa\x00\x10\xf4\xd0\x3c\xd1\x40\xf0\x01\xdc\xb0\x80\xf5\x30\x00"
++ "\xf7\x48\xaa\x00\xe9\x07\xf4\xc4\x41\xd1\x40\x10\xfe\xf7\x48\xee"
++ "\x00\xe8\x0c\xd8\x55\xe9\x25\xcc\xb1\x80\xfd\x79\x00\xea\x0c\xcc"
++ "\xb1\x80\xc4\xac\x81\xcc\xb2\x80\xc4\x90\x81\xdc\xb0\x80\xf8\xe0"
++ "\x00\x10\xa0\xf5\x10\x01\xf5\x10\x02\xf5\x10\x03\xfe\xc8\xda\xfc"
++ "\xf7\x00\xfe\xff\xf7\x31\xd2\xfc\xea\x0b\xc8\xda\xfc\xf7\x00\xfd"
++ "\xff\xf7\x31\xd6\xfc\xc4\xda\xfc\xcc\x44\xfc\xf7\x00\xfe\xff\xc4"
++ "\x44\xfc\xf4\x7d\x75\xae\x08\xe9\x07\xf4\x75\x0c\xd1\x40\xea\x0c"
++ "\xf4\x7d\x32\x9d\x08\xe9\x05\xf4\x75\x35\xd1\x40\xf2\x7c\xd0\x04"
++ "\xcc\x5b\x80\xd8\x01\xe9\x02\x7c\x04\x51\x20\x71\x34\xf4\x7d\xc1"
++ "\x85\x08\xe9\x13\x80\x00\x85\x00\xd8\x00\xe8\x02\x85\x0c\xc5\xda"
++ "\xfc\xf4\x75\x40\xd1\x40\x14\xfe\x80\x01\xea\xea\xf7\x10\xff\xf7"
++ "\xf4\xc9\x40\xd1\x40\xd9\x00\xe8\x17\x21\xf4\x79\x00\xf0\x00\xe9"
++ "\x05\x80\x00\xf5\x10\x09\xd9\x06\xe9\x06\x61\x06\xd5\x06\x41\x06"
++ "\xf4\xe0\x4b\xdd\xc7\xf4\xe0\x6d\xcc\xc7\x00\x00\x74\x0a\x08\x00"
++ "\x01\x00\x00\x00"
++ ;
++
++const int drive_20020823_firmware_size = 324;
+diff --git a/drivers/block/gcn-di/drive_all.S b/drivers/block/gcn-di/drive_all.S
+new file mode 100644
+index 0000000..e9d91a0
+--- /dev/null
++++ b/drivers/block/gcn-di/drive_all.S
+@@ -0,0 +1,415 @@
++/*
++ * DVD+/-R compatible "cactus" firmware extensions
++ * Copyright (C) 2005-2009 The GameCube Linux Team
++ * Copyright (C) 2005,2006,2009 Albert Herranz
++ *
++ * Originally based on analysis of Cobra 1.0 drive code released by tmbinc
++ * on dextrose.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.
++ *
++ */
++
++/*
++ * This code is compatible with binutils 2.15 limited mn10200 support.
++ * And it intentionally lacks the audio fix and DRE recovery features.
++ *
++ */
++
++
++.equ UNICR, 0xfc44
++.equ UNID, (1<<0)
++.equ ADB0, 0xfcd2
++.equ ADB1, 0xfcd6
++.equ ADBCTL, 0xfcda
++.equ ADB0CK, (1<<0)
++.equ ADB1CK, (1<<1)
++.equ ADB0ON, (1<<2)
++.equ ADB1ON, (1<<3)
++
++
++.equ irq_handler_vector, 0x804c /* 04, 06, 08, Panasonic Q */
++.equ irq_depth, 0x805b /* 04, 06, 08, Panasonic Q */
++
++.equ fake_command, 0xaa
++.equ set_drive_status_command, 0xee /* same as in gcn-di.c */
++.equ enable_extensions_command, 0x55 /* same as in gcn-di.c */
++
++.equ get_drive_status_command, 0xe0
++
++
++#if DRIVE_MODEL == 0x20020402 /* 04 */
++
++ .equ cmdbuf0, 0x80b4
++ .equ drive_status, 0x81b0
++ .equ drive_status2, 0x8194
++
++ .equ bert, 0x8084
++ .equ ernie, 0x819c
++ .equ cactus, 0x40ecf9
++
++ .section absolute
++
++ .equ adb1_break_address, 0x089cd6
++ .org 0x089d4e
++ adb1_fixup_exit:
++
++ .equ adb0_break_address, 0x08ae28
++ .org 0x08ae33
++ adb0_fixup_exit:
++
++ .equ disable_extensions_when_called_from, 0x0885c1 /* 04, 08 */
++
++#elif DRIVE_MODEL == 0x20010608 /* 06 */
++
++ .equ cmdbuf0, 0x80a8
++ .equ drive_status, 0x81a4
++ .equ drive_status2, 0x8188
++
++ .equ bert, 0x8078
++ .equ ernie, 0x8190
++ .equ cactus, 0x40ed02
++
++ .section absolute
++
++ .equ adb1_break_address, 0x089d42
++ .org 0x089dd0
++ adb1_fixup_exit:
++
++ .equ adb0_break_address, 0x08b145
++ .org 0x08b150
++ adb0_fixup_exit:
++
++ .equ disable_extensions_when_called_from, 0x0885b9
++
++#elif DRIVE_MODEL == 0x20020823 /* 08 */
++
++ .equ cmdbuf0, 0x80b0
++ .equ drive_status, 0x81ac
++ .equ drive_status2, 0x8190
++
++ .equ bert, 0x8080
++ .equ ernie, 0x8198
++ .equ cactus, 0x40ecf5
++
++ .section absolute
++
++ .equ adb1_break_address, 0x089d32
++ .org 0x089da7
++ adb1_fixup_exit:
++
++ .equ adb0_break_address, 0x08ae75
++ .org 0x08ae80
++ adb0_fixup_exit:
++
++ .equ disable_extensions_when_called_from, 0x0885c1 /* 04, 08 */
++
++#elif DRIVE_MODEL == 0x20010831 /* Panasonic Q */
++
++ .equ cmdbuf0, 0x80aa
++ .equ drive_status, 0x81a6
++ .equ drive_status2, 0x818a
++
++ .equ bert, 0x8078
++ .equ ernie, 0x8192
++ .equ cactus, 0x40ed02
++
++ .section absolute
++
++ .equ adb1_break_address, 0x089e39
++ .org 0x089f84
++ adb1_fixup_exit:
++
++ .equ adb0_break_address, 0x08b302
++ .org 0x08b30d
++ adb0_fixup_exit:
++
++ .equ disable_extensions_when_called_from, 0x08867f
++
++#else
++ #error Sorry, unsupported drive.
++#endif
++
++
++ .section .text
++ .global _start
++ .global _exit
++
++/*
++ * We are launched now through the 'func' debug command.
++ */
++_start:
++_main:
++ /* disable interrupts, do not disturb */
++ and 0xf7ff, psw
++
++ /* replace the current irq handler with ours */
++ mov our_irq_handler, a0
++ mov a0, (irq_handler_vector)
++
++ /* setup our extending functions ... */
++ mov adb1_break_address, a0
++ mov a0, (ADB1)
++ mov adb0_break_address, a0
++ mov a0, (ADB0)
++
++ /* ... and enable them */
++ mov ADB1ON|ADB0ON, d0
++ movb d0, (ADBCTL)
++
++ rts
++
++
++our_irq_handler:
++ /* check for Address Break 0 */
++ mov (ADBCTL), d0
++ and ADB0CK, d0
++ bne adb0_break_handler
++
++ /* check for Address Break 1 */
++ mov (ADBCTL), d0
++ and ADB1CK, d0
++ bne adb1_break_handler
++
++ /* XXX not sure about this one... */
++// mov 0x0c, d0
++// movb d0, (0x819a)
++
++ /* tell the drive to please accept the disk */
++ mov cactus, a0
++ mov 2, d0
++ bset d0, (a0)
++
++ /* this seems to avoid errors if the drive idles for too long */
++ mov (bert), d0
++ mov d0, (ernie)
++
++ /* save current command ... */
++ mov cmdbuf0, a0
++ movbu (0, a0), d0
++ movb d0, (saved_cmdbuf0)
++
++ /* ... and place a temporary fake command, to detect new commands */
++ mov fake_command, d0
++ movb d0, (a0)
++
++ /* call the original handler */
++ mov (saved_irq_handler), a0
++ jsr (a0)
++
++ /* if our fake command changed, we assume a new command has arrived */
++ mov cmdbuf0, a0
++ movbu (0, a0), d0
++ cmp fake_command, d0
++ bne extra_command_parser
++
++ /* if there is no new command, restore the previously saved command */
++ movb (saved_cmdbuf0), d0
++ movb d0, (a0)
++
++ rts
++
++
++extra_command_parser:
++ /* "set drive status" command */
++ cmp set_drive_status_command, d0
++ beq set_drive_status
++
++ /* "enable extensions" command */
++ cmp enable_extensions_command, d0
++ bne done
++
++enable_or_disable_extensions:
++ /* 0x55, 0xZZ, 0x00, 0x00 */
++ /* ZZ=0 disable, otherwise enable */
++ movbu (cmdbuf0+1), d0
++ jsr di_enable_or_disable_extensions
++ jmp get_drive_status
++
++set_drive_status:
++ /* 0xee, 0xZZ, 0xYY, 0x00 */
++ /* ZZ=drive_status, YY=drive_status2 */
++ movbu (cmdbuf0+1), d0
++ movb d0, (drive_status)
++ movbu (cmdbuf0+2), d0
++ movb d0, (drive_status2)
++
++
++get_drive_status:
++ /*
++ * This saves us an invalid command error and updates the status
++ * accordingly. In fact, our extended command becomes a "get status"
++ * command.
++ */
++ mov cmdbuf0, a0
++ mov get_drive_status_command, d0
++ movb d0, (a0)
++ sub d0, d0
++ movb d0, (1,a0)
++ movb d0, (2,a0)
++ movb d0, (3,a0)
++
++done:
++ rts
++
++
++/*
++ * This is how the stacks look like when our interrupt handler is called.
++ *
++ * Our interrupt handler is in fact not the real interrupt handler, but
++ * just a subroutine called by the real interrupt handler.
++ * That's why we just RTS and not RTI from our interrupt handler.
++ *
++ * | | | |
++ * 00| d0 0| <- old a3 | |
++ * 02| 8| | |
++ * 04| d1 6| | |
++ * 06| 4| | |
++ * 08| d2 2| | |
++ * 0a| 0| | |
++ * 0c| d3 8| | |
++ * 0e| 6| | |
++ * 10| a0 4| | |
++ * 12| 2| | |
++ * 14| a1 0| | |
++ * 16| 8| | |
++ * 18| a2 6| | |
++ * 1a| 4| | |
++ * 1c| MDR 2| | |
++ * 1e| PSW | | |
++ * 20| PC lo | | PC lo | <- a3
++ * 22| PC hi | | PC hi |
++ * : : | old a3 |
++ * | ... | | |
++ * +--------+ +--------+ <- (0x8ea1c) for drive 04
++ * normal context stack interrupt context stack
++ *
++ */
++
++adb0_break_handler:
++ mov (ADBCTL), d0
++ and ~ADB0CK, d0
++ mov (ADB0), a1
++ jmp address_break_handler
++
++adb1_break_handler:
++ mov (ADBCTL), d0
++ and ~ADB1CK, d0
++ mov (ADB1), a1
++
++address_break_handler:
++ /* ack the interrupt */
++ movb d0, (ADBCTL)
++ movbu (UNICR), d0
++ and ~UNID, d0
++ movb d0, (UNICR)
++
++ cmp adb0_break_address, a1
++ bne 1f
++ mov adb0_fixup, a1
++ jmp 2f
++
++1:
++ cmp adb1_break_address, a1
++ bne 2f
++ mov adb1_fixup, a1
++
++2:
++ /* point to the previous stack pointer */
++ mov a3, a0
++ add 4, a0
++
++ /*
++ * Special case. When entering interrupt context the first time,
++ * the old stack is pushed in the interrupt stack before calling us.
++ */
++ movbu (irq_depth), d0
++ cmp 1, d0
++ bne 1f
++ mov (4, a3), a0 /* get the old stack pointer */
++1:
++ /* overwrite the original return address (look at the stack layout) */
++ mov a1, (0x20, a0)
++
++ /*
++ * We disable the extensions when an original disc is found.
++ *
++ * We do that by checking if we were called from a piece of
++ * code reached only when original discs are inserted. Tricky.
++ */
++
++ /* 0x20 + 0x10 + 0x04 = 0x34 */
++ mov (0x34, a0), a1
++ cmp disable_extensions_when_called_from, a1
++ bne 9f /* else, do nothing */
++
++di_disable_extensions:
++ mov 0, d0
++
++di_enable_or_disable_extensions:
++ /* enable additional media if extensions are enabled */
++ mov 0, d1
++ cmp 0, d0
++ beq 1f
++ mov ADB0ON|ADB1ON, d1
++1:
++ movb d1, (ADBCTL)
++
++ mov enable_extensions, a1
++ movb d0, (a1)
++
++9:
++ rts
++
++di_enable_extensions:
++ mov 1, d0
++ jmp di_enable_or_disable_extensions
++
++
++adb0_fixup:
++ /* disable interrupts, XXX really needed here...? */
++ and 0xf7ff, psw
++
++ /* check if we need to tweak things or not */
++ movbu (enable_extensions), d1
++ cmp 0, d1
++ beq 1f
++
++ /* deal with the dvd seed */
++ mov (a0), d1
++ cmp 0x00f000, d1 /* controller setup */
++ bne 2f
++ mov 0x00, d0 /* seed 0x00 for normal DVD */
++ movb d0, (0x09, a0)
++2:
++ /* skip the extra field */
++ cmp 0x06, d1 /* transfer sector buffer */
++ bne 1f
++ mov (0x06, a0), d1
++ add 6, d1 /* skip it */
++ mov d1, (0x06, a0)
++1:
++ jmp adb0_fixup_exit
++
++
++adb1_fixup:
++ jmp adb1_fixup_exit
++
++
++.align 2
++saved_irq_handler:
++#if DRIVE_MODEL != 0x20010831
++ .long 0x00080A74 /* 04, 06, 08 */
++#else
++ .long 0x00080AA4 /* Panasonic Q */
++#endif
++enable_extensions:
++ .byte 0x01
++saved_cmdbuf0:
++ .byte 0x00
++
++_exit:
++
+diff --git a/drivers/block/gcn-di/gcn-di.c b/drivers/block/gcn-di/gcn-di.c
+new file mode 100644
+index 0000000..9f6564f
+--- /dev/null
++++ b/drivers/block/gcn-di/gcn-di.c
+@@ -0,0 +1,2363 @@
++/*
++ * drivers/block/gcn-di/gcn-di.c
++ *
++ * Nintendo GameCube Disk Interface (DI) driver
++ * Copyright (C) 2005-2009 The GameCube Linux Team
++ * Copyright (C) 2005,2006,2007,2009 Albert Herranz
++ *
++ * Portions based on previous work by Scream|CT.
++ *
++ * 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/blkdev.h>
++#include <linux/cdrom.h>
++#include <linux/delay.h>
++#include <linux/dma-mapping.h>
++#include <linux/fcntl.h>
++#include <linux/hdreg.h>
++#include <linux/init.h>
++#include <linux/interrupt.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/of_platform.h>
++#include <linux/proc_fs.h>
++#include <linux/seq_file.h>
++#include <linux/timer.h>
++#include <linux/io.h>
++
++#define DI_DEBUG
++
++#define DRV_MODULE_NAME "gcn-di"
++#define DRV_DESCRIPTION "Nintendo GameCube Disk Interface (DI) driver"
++#define DRV_AUTHOR "Albert Herranz"
++
++static char di_driver_version[] = "1.0i";
++
++#define drv_printk(level, format, arg...) \
++ printk(level DRV_MODULE_NAME ": " format , ## arg)
++
++#ifdef DI_DEBUG
++# define DBG(fmt, args...) \
++ printk(KERN_ERR "%s: " fmt, __func__ , ## args)
++#else
++# define DBG(fmt, args...)
++#endif
++
++
++/*
++ * Hardware.
++ */
++#define DI_DMA_ALIGN 0x1f /* 32 bytes */
++
++/* DI Status Register */
++#define DI_SR 0x00
++#define DI_SR_BRK (1<<0)
++#define DI_SR_DEINTMASK (1<<1)
++#define DI_SR_DEINT (1<<2)
++#define DI_SR_TCINTMASK (1<<3)
++#define DI_SR_TCINT (1<<4)
++#define DI_SR_BRKINTMASK (1<<5)
++#define DI_SR_BRKINT (1<<6)
++
++/* DI Cover Register */
++#define DI_CVR 0x04
++#define DI_CVR_CVR (1<<0)
++#define DI_CVR_CVRINTMASK (1<<1)
++#define DI_CVR_CVRINT (1<<2)
++
++/* DI Command Buffers */
++#define DI_CMDBUF0 0x08
++#define DI_CMDBUF1 0x0c
++#define DI_CMDBUF2 0x10
++
++/* DI DMA Memory Address Register */
++#define DI_MAR 0x14
++
++/* DI DMA Transfer Length Register */
++#define DI_LENGTH 0x18
++
++/* DI Control Register */
++#define DI_CR 0x1c
++#define DI_CR_TSTART (1<<0)
++#define DI_CR_DMA (1<<1)
++#define DI_CR_RW (1<<2)
++
++/* DI Immediate Data Buffer */
++#define DI_DATA 0x20
++
++/* DI Configuration Register */
++#define DI_CFG 0x24
++
++
++/* drive status, status */
++#define DI_STATUS(s) ((u8)((s)>>24))
++
++#define DI_STATUS_READY 0x00
++#define DI_STATUS_COVER_OPENED 0x01
++#define DI_STATUS_DISK_CHANGE 0x02
++#define DI_STATUS_NO_DISK 0x03
++#define DI_STATUS_MOTOR_STOP 0x04
++#define DI_STATUS_DISK_ID_NOT_READ 0x05
++
++/* drive status, error */
++#define DI_ERROR(s) ((u32)((s)&0x00ffffff))
++
++#define DI_ERROR_NO_ERROR 0x000000
++#define DI_ERROR_MOTOR_STOPPED 0x020400
++#define DI_ERROR_DISK_ID_NOT_READ 0x020401
++#define DI_ERROR_MEDIUM_NOT_PRESENT 0x023a00
++#define DI_ERROR_SEEK_INCOMPLETE 0x030200
++#define DI_ERROR_UNRECOVERABLE_READ 0x031100
++#define DI_ERROR_INVALID_COMMAND 0x052000
++#define DI_ERROR_BLOCK_OUT_OF_RANGE 0x052100
++#define DI_ERROR_INVALID_FIELD 0x052400
++#define DI_ERROR_MEDIUM_CHANGED 0x062800
++
++#define di_may_retry(s) ((DI_STATUS(s) == DI_STATUS_READY || \
++ DI_STATUS(s) == DI_STATUS_DISK_ID_NOT_READ) \
++ && \
++ (DI_ERROR(s) != DI_ERROR_SEEK_INCOMPLETE))
++
++/* DI Sector Size */
++#define DI_SECTOR_SHIFT 11
++#define DI_SECTOR_SIZE (1 << DI_SECTOR_SHIFT) /*2048*/
++#define DI_MAX_SECTORS 712880
++
++
++/* Driver Settings */
++#define DI_NAME DRV_MODULE_NAME
++#define DI_MAJOR 60
++
++#define DI_COMMAND_TIMEOUT 20 /* seconds */
++#define DI_COMMAND_RETRIES 10 /* times */
++
++#define DI_MOTOR_OFF_TIMEOUT 10
++
++#define KERNEL_SECTOR_SHIFT 9
++#define KERNEL_SECTOR_SIZE (1 << KERNEL_SECTOR_SHIFT) /*512*/
++
++
++/*
++ * Drive Information.
++ */
++struct di_drive_info {
++ u16 rev;
++ u16 code;
++ u32 date;
++ u8 pad[0x18];
++};
++
++/*
++ * Disk ID.
++ */
++struct di_disk_id {
++ u8 id[32];
++};
++
++/*
++ * An operation code.
++ */
++struct di_opcode {
++ u16 op;
++#define DI_OP(id, flags) (((u8)(id)<<8)|((u8)(flags)))
++#define DI_OP_ID(op) ((u8)((op)>>8))
++#define DI_OP_FLAGS(op) ((u8)(op))
++
++#define DI_DIR_READ 0x00
++#define DI_DIR_WRITE DI_CR_RW
++#define DI_MODE_IMMED 0x00
++#define DI_MODE_DMA DI_CR_DMA
++#define DI_IGNORE_ERRORS (1<<7)
++
++ char *name;
++
++ u32 cmdbuf0;
++};
++
++/*
++ * Drive code container.
++ */
++struct di_drive_code {
++ u32 address;
++ size_t len;
++ void *code;
++};
++
++struct di_device;
++
++/*
++ * A Disk Interface command.
++ */
++struct di_command {
++ u16 opidx;
++
++ u32 cmdbuf0;
++ u32 cmdbuf1;
++ u32 cmdbuf2;
++
++ void *data;
++ size_t len;
++
++ dma_addr_t dma_addr;
++ size_t dma_len;
++
++ void *done_data;
++ void (*done)(struct di_command *cmd);
++
++ u16 retries;
++ u16 max_retries;
++
++ u32 result;
++
++ struct di_device *ddev;
++};
++
++#define di_result_ok(result) ((result) == DI_SR_TCINT)
++#define di_command_ok(cmd) (di_result_ok((cmd)->result))
++
++enum {
++ __DI_INTEROPERABLE = 0,
++ __DI_MEDIA_CHANGED,
++ __DI_START_QUEUE,
++ __DI_RESETTING,
++ __DI_AVOID_DEBUG,
++};
++
++/*
++ * The Disk Interface device.
++ */
++struct di_device {
++ spinlock_t lock;
++
++ int irq;
++
++ spinlock_t io_lock;
++ void __iomem *io_base;
++
++ struct di_command *cmd;
++ struct di_command *failed_cmd;
++
++ struct di_command status;
++ u32 drive_status;
++
++ struct gendisk *disk;
++ struct request_queue *queue;
++ spinlock_t queue_lock;
++
++ struct request *req;
++ struct di_command req_cmd;
++
++ struct di_drive_code *drive_code;
++
++ u32 model;
++ unsigned long flags;
++#define DI_INTEROPERABLE (1<<__DI_INTEROPERABLE)
++#define DI_MEDIA_CHANGED (1<<__DI_MEDIA_CHANGED)
++#define DI_START_QUEUE (1<<__DI_START_QUEUE)
++#define DI_RESETTING (1<<__DI_RESETTING)
++#define DI_AVOID_DEBUG (1<<__DI_AVOID_DEBUG)
++
++ unsigned long nr_sectors;
++
++ struct timer_list motor_off_timer;
++
++#ifdef CONFIG_PROC_FS
++ struct proc_dir_entry *proc;
++#endif /* CONFIG_PROC_FS */
++
++ int ref_count;
++
++ struct device *dev;
++};
++
++
++static struct di_drive_info di_drive_info
++ __attribute__ ((aligned(DI_DMA_ALIGN+1)));
++
++/*
++ * We do not accept original media with this driver, as there is currently no
++ * general need for that.
++ * If you ever develop an application (a media player for example) which works
++ * with original media, just change di_accept_gods and recompile.
++ */
++static const int di_accept_gods;
++
++/*
++ * Drive firmware extensions.
++ *
++ */
++
++#define DI_DRIVE_CODE_BASE 0x40d000
++#define DI_DRIVE_IRQ_VECTOR 0x00804c
++
++/*
++ * Drive 04 (20020402) firmware extensions.
++ */
++
++#include "drive_20020402.h"
++
++static struct di_drive_code drive_20020402 = {
++ .address = DI_DRIVE_CODE_BASE,
++ .len = sizeof(drive_20020402_firmware),
++ .code = (u8 *)drive_20020402_firmware,
++};
++
++/*
++ * Drive 06 (20010608) firmware extensions.
++ */
++
++#include "drive_20010608.h"
++
++static struct di_drive_code drive_20010608 = {
++ .address = DI_DRIVE_CODE_BASE,
++ .len = sizeof(drive_20010608_firmware),
++ .code = (u8 *)drive_20010608_firmware,
++};
++
++/*
++ * Drive 08 (20020823) firmware extensions.
++ */
++
++#include "drive_20020823.h"
++
++static struct di_drive_code drive_20020823 = {
++ .address = DI_DRIVE_CODE_BASE,
++ .len = sizeof(drive_20020823_firmware),
++ .code = (u8 *)drive_20020823_firmware,
++};
++
++/*
++ * Panasonic Q (20010831) firmware extensions.
++ */
++
++#include "drive_20010831.h"
++
++static struct di_drive_code drive_20010831 = {
++ .address = DI_DRIVE_CODE_BASE,
++ .len = sizeof(drive_20010831_firmware),
++ .code = (u8 *)drive_20010831_firmware,
++};
++
++
++/*
++ * Drive operations table, incomplete.
++ * We just include here some of the available functions, in no particular
++ * order.
++ */
++#define CMDBUF(a, b, c, d) (((a)<<24)|((b)<<16)|((c)<<8)|(d))
++
++static struct di_opcode di_opcodes[] = {
++
++#define DI_OP_NOP 0
++ [DI_OP_NOP] = {
++ .op = DI_OP(DI_OP_NOP, 0),
++ .name = "NOP",
++ .cmdbuf0 = 0,
++ },
++
++#define DI_OP_INQ (DI_OP_NOP+1)
++ [DI_OP_INQ] = {
++ .op = DI_OP(DI_OP_INQ, DI_DIR_READ | DI_MODE_DMA),
++ .name = "INQ",
++ .cmdbuf0 = 0x12000000,
++ },
++
++#define DI_OP_STOPMOTOR (DI_OP_INQ+1)
++ [DI_OP_STOPMOTOR] = {
++ .op = DI_OP(DI_OP_STOPMOTOR, DI_DIR_READ | DI_MODE_IMMED),
++ .name = "STOPMOTOR",
++ .cmdbuf0 = 0xe3000000,
++ },
++
++#define DI_OP_READDISKID (DI_OP_STOPMOTOR+1)
++ [DI_OP_READDISKID] = {
++ .op = DI_OP(DI_OP_READDISKID, DI_DIR_READ | DI_MODE_DMA),
++ .name = "READDISKID",
++ .cmdbuf0 = 0xa8000040,
++ },
++
++#define DI_OP_READSECTOR (DI_OP_READDISKID+1)
++ [DI_OP_READSECTOR] = {
++ .op = DI_OP(DI_OP_READSECTOR, DI_DIR_READ | DI_MODE_DMA),
++ .name = "READSECTOR",
++ .cmdbuf0 = 0xa8000000,
++ },
++
++#define DI_OP_ENABLE1 (DI_OP_READSECTOR+1)
++ [DI_OP_ENABLE1] = {
++ .op = DI_OP(DI_OP_ENABLE1, DI_DIR_READ | DI_MODE_IMMED),
++ .name = "MATSHITA",
++ .cmdbuf0 = 0,
++ },
++
++#define DI_OP_ENABLE2 (DI_OP_ENABLE1+1)
++ [DI_OP_ENABLE2] = {
++ .op = DI_OP(DI_OP_ENABLE2, DI_DIR_READ | DI_MODE_IMMED),
++ .name = "DVD-GAME",
++ .cmdbuf0 = 0,
++ },
++
++/*
++ * The following commands are available in debug mode only.
++ */
++
++#define DI_OP_READMEM (DI_OP_ENABLE2+1)
++ [DI_OP_READMEM] = {
++ .op = DI_OP(DI_OP_READMEM, DI_DIR_READ | DI_MODE_IMMED),
++ .name = "READMEM",
++ .cmdbuf0 = 0xfe010000,
++ },
++
++#define DI_OP_WRITEMEM (DI_OP_READMEM+1)
++ [DI_OP_WRITEMEM] = {
++ .op = DI_OP(DI_OP_WRITEMEM, DI_DIR_READ | DI_MODE_DMA),
++ .name = "WRITEMEM",
++ .cmdbuf0 = 0xfe010100,
++ },
++
++#define DI_OP_FUNC (DI_OP_WRITEMEM+1)
++ [DI_OP_FUNC] = {
++ .op = DI_OP(DI_OP_FUNC, DI_DIR_READ | DI_MODE_IMMED),
++ .name = "FUNC",
++ .cmdbuf0 = 0xfe120000,
++ },
++
++#define DI_OP_GETSTATUS (DI_OP_FUNC+1)
++ [DI_OP_GETSTATUS] = {
++ .op = DI_OP(DI_OP_GETSTATUS, DI_DIR_READ | DI_MODE_IMMED),
++ .name = "GETSTATUS",
++ .cmdbuf0 = 0xe0000000,
++ },
++
++/* thanks to blackcheck for pointing this one */
++#define DI_OP_SPINMOTOR (DI_OP_GETSTATUS+1)
++ [DI_OP_SPINMOTOR] = {
++ .op = DI_OP(DI_OP_SPINMOTOR, DI_DIR_READ | DI_MODE_IMMED),
++ .name = "SPINMOTOR",
++ .cmdbuf0 = 0xfe110001,
++#define DI_SPINMOTOR_MASK 0x0000ff00
++#define DI_SPINMOTOR_DOWN 0x00000000
++#define DI_SPINMOTOR_UP 0x00000100
++#define DI_SPINMOTOR_CHECKDISK 0x00008000
++ },
++
++/*
++ * The following commands are part of the firmware extensions.
++ */
++
++#define DI_OP_SETSTATUS (DI_OP_SPINMOTOR+1)
++ [DI_OP_SETSTATUS] = {
++ .op = DI_OP(DI_OP_SETSTATUS, DI_DIR_READ | DI_MODE_IMMED),
++ .name = "SETSTATUS",
++ .cmdbuf0 = 0xee000000,
++#define DI_SETSTATUS_MASK 0x00ff0000
++#define DI_SETSTATUS_SHIFT 16
++ },
++
++#define DI_OP_ENABLEEXTENSIONS (DI_OP_SETSTATUS+1)
++ [DI_OP_ENABLEEXTENSIONS] = {
++ .op = DI_OP(DI_OP_ENABLEEXTENSIONS, DI_DIR_READ|DI_MODE_IMMED|
++ DI_IGNORE_ERRORS),
++ .name = "ENABLEEXTENSIONS",
++ .cmdbuf0 = 0x55000000,
++#define DI_ENABLEEXTENSIONS_MASK 0x00ff0000
++#define DI_ENABLEEXTENSIONS_SHIFT 16
++ },
++
++#define DI_OP_MAXOP DI_OP_ENABLEEXTENSIONS
++};
++
++#define DI_OP_CUSTOM ((u16)~0)
++
++
++static void di_reset(struct di_device *ddev);
++static int di_run_command(struct di_command *cmd);
++
++/*
++ * Returns the operation code related data for a command.
++ */
++static inline struct di_opcode *di_get_opcode(struct di_command *cmd)
++{
++ BUG_ON(cmd->opidx > DI_OP_MAXOP && cmd->opidx != DI_OP_CUSTOM);
++
++ if (cmd->opidx == DI_OP_CUSTOM)
++ return cmd->data;
++ else
++ return &di_opcodes[cmd->opidx];
++}
++
++/*
++ * Returns the operation code for a command.
++ */
++static inline u16 di_op(struct di_command *cmd)
++{
++ return di_get_opcode(cmd)->op;
++}
++
++
++/*
++ * Basic initialization for all commands.
++ */
++static void di_op_basic(struct di_command *cmd,
++ struct di_device *ddev, u16 opidx)
++{
++ struct di_opcode *opcode;
++
++ memset(cmd, 0, sizeof(*cmd));
++ cmd->ddev = ddev;
++ cmd->opidx = opidx;
++ cmd->max_retries = cmd->retries = 0;
++ opcode = di_get_opcode(cmd);
++ if (opcode)
++ cmd->cmdbuf0 = opcode->cmdbuf0;
++}
++
++/*
++ * Builds an "Inquiry" command.
++ */
++static void di_op_inq(struct di_command *cmd,
++ struct di_device *ddev,
++ struct di_drive_info *drive_info)
++{
++ di_op_basic(cmd, ddev, DI_OP_INQ);
++ cmd->cmdbuf2 = sizeof(*drive_info);
++ cmd->data = drive_info;
++ cmd->len = sizeof(*drive_info);
++}
++
++/*
++ * Builds a "Stop Motor" command.
++ */
++static inline void di_op_stopmotor(struct di_command *cmd,
++ struct di_device *ddev)
++{
++ di_op_basic(cmd, ddev, DI_OP_STOPMOTOR);
++}
++
++/*
++ * Builds a "Read Disc ID" command.
++ */
++static void di_op_readdiskid(struct di_command *cmd,
++ struct di_device *ddev,
++ struct di_disk_id *disk_id)
++{
++ di_op_basic(cmd, ddev, DI_OP_READDISKID);
++ cmd->cmdbuf2 = sizeof(*disk_id);
++ cmd->data = disk_id;
++ cmd->len = sizeof(*disk_id);
++ cmd->max_retries = cmd->retries = DI_COMMAND_RETRIES;
++}
++
++/*
++ * Builds a "Read Sector" command.
++ */
++static void di_op_readsector(struct di_command *cmd,
++ struct di_device *ddev,
++ u32 sector, void *data, size_t len)
++{
++ di_op_basic(cmd, ddev, DI_OP_READSECTOR);
++ cmd->cmdbuf1 = sector;
++ cmd->cmdbuf2 = len;
++ cmd->data = data;
++ cmd->len = len;
++ cmd->max_retries = cmd->retries = DI_COMMAND_RETRIES;
++}
++
++/*
++ * Builds the first enable command.
++ */
++static void di_op_enable1(struct di_command *cmd, struct di_device *ddev)
++{
++ di_op_basic(cmd, ddev, DI_OP_ENABLE1);
++ cmd->cmdbuf0 = CMDBUF(0xff, 0x01, 'M', 'A');
++ cmd->cmdbuf1 = CMDBUF('T', 'S', 'H', 'I');
++ cmd->cmdbuf2 = CMDBUF('T', 'A', 0x02, 0x00);
++}
++
++/*
++ * Builds the second enable command.
++ */
++static void di_op_enable2(struct di_command *cmd, struct di_device *ddev)
++{
++ di_op_basic(cmd, ddev, DI_OP_ENABLE2);
++ cmd->cmdbuf0 = CMDBUF(0xff, 0x00, 'D', 'V');
++ cmd->cmdbuf1 = CMDBUF('D', '-', 'G', 'A');
++ cmd->cmdbuf2 = CMDBUF('M', 'E', 0x03, 0x00);
++}
++
++/*
++ * Builds a "Read Memory" command.
++ * Requires debug mode enabled.
++ */
++static inline void di_op_readmem(struct di_command *cmd,
++ struct di_device *ddev)
++{
++ di_op_basic(cmd, ddev, DI_OP_READMEM);
++ cmd->cmdbuf2 = 0x00010000;
++}
++
++/*
++ * Builds a "Invoke func" command.
++ * Requires debug mode enabled.
++ */
++static inline void di_op_func(struct di_command *cmd,
++ struct di_device *ddev, u32 address)
++{
++ di_op_basic(cmd, ddev, DI_OP_FUNC);
++ cmd->cmdbuf1 = address;
++ cmd->cmdbuf2 = CMDBUF('f', 'u', 'n', 'c');
++}
++
++/*
++ * Builds a "Write Memory" command.
++ * Requires debug mode enabled.
++ */
++static inline void di_op_writemem(struct di_command *cmd,
++ struct di_device *ddev)
++{
++ di_op_basic(cmd, ddev, DI_OP_WRITEMEM);
++}
++
++/*
++ * Builds a "get drive status" command.
++ */
++static inline void di_op_getstatus(struct di_command *cmd,
++ struct di_device *ddev)
++{
++ di_op_basic(cmd, ddev, DI_OP_GETSTATUS);
++}
++
++/*
++ * Builds a "spin motor" command.
++ * Requires debug mode enabled.
++ */
++static void di_op_spinmotor(struct di_command *cmd,
++ struct di_device *ddev, u32 flags)
++{
++ di_op_basic(cmd, ddev, DI_OP_SPINMOTOR);
++ cmd->cmdbuf0 |= (flags & DI_SPINMOTOR_MASK);
++}
++
++/*
++ * Builds a "set drive status" command.
++ * Requires debug mode enabled.
++ */
++static void di_op_setstatus(struct di_command *cmd,
++ struct di_device *ddev, u8 status)
++{
++ di_op_basic(cmd, ddev, DI_OP_SETSTATUS);
++ cmd->cmdbuf0 |= ((status << DI_SETSTATUS_SHIFT) & DI_SETSTATUS_MASK);
++}
++
++/*
++ * Builds a "enable extensions" command.
++ * The extended firmware will transparently disable the extensions when
++ * original media is found.
++ * Requires debug mode enabled.
++ */
++static void di_op_enableextensions(struct di_command *cmd,
++ struct di_device *ddev, u8 enable)
++{
++ di_op_basic(cmd, ddev, DI_OP_ENABLEEXTENSIONS);
++ cmd->cmdbuf0 |= ((enable << DI_ENABLEEXTENSIONS_SHIFT) &
++ DI_ENABLEEXTENSIONS_MASK);
++}
++
++/*
++ * Builds a customized command.
++ */
++static inline void di_op_custom(struct di_command *cmd,
++ struct di_device *ddev,
++ struct di_opcode *opcode)
++{
++ di_op_basic(cmd, ddev, DI_OP_NOP);
++ cmd->opidx = DI_OP_CUSTOM;
++ cmd->data = opcode;
++}
++
++
++/*
++ * Returns the printable form of the status part of a drive status.
++ */
++static char *di_printable_status(u32 drive_status)
++{
++ char *s = "unknown";
++
++ switch (DI_STATUS(drive_status)) {
++ case DI_STATUS_READY:
++ s = "ready";
++ break;
++ case DI_STATUS_COVER_OPENED:
++ s = "cover opened";
++ break;
++ case DI_STATUS_DISK_CHANGE:
++ s = "disk change";
++ break;
++ case DI_STATUS_NO_DISK:
++ s = "no disk";
++ break;
++ case DI_STATUS_MOTOR_STOP:
++ s = "motor stop";
++ break;
++ case DI_STATUS_DISK_ID_NOT_READ:
++ s = "disk id not read";
++ break;
++ }
++ return s;
++}
++
++/*
++ * Returns the printable form of the error part of a drive status.
++ */
++static char *di_printable_error(u32 drive_status)
++{
++ char *s = "unknown";
++
++ switch (DI_ERROR(drive_status)) {
++ case DI_ERROR_NO_ERROR:
++ s = "no error";
++ break;
++ case DI_ERROR_MOTOR_STOPPED:
++ s = "motor stopped";
++ break;
++ case DI_ERROR_DISK_ID_NOT_READ:
++ s = "disk id not read";
++ break;
++ case DI_ERROR_MEDIUM_NOT_PRESENT:
++ s = "medium not present";
++ break;
++ case DI_ERROR_SEEK_INCOMPLETE:
++ s = "seek incomplete";
++ break;
++ case DI_ERROR_UNRECOVERABLE_READ:
++ s = "unrecoverable read";
++ break;
++ case DI_ERROR_INVALID_COMMAND:
++ s = "invalid command";
++ break;
++ case DI_ERROR_BLOCK_OUT_OF_RANGE:
++ s = "block out of range";
++ break;
++ case DI_ERROR_INVALID_FIELD:
++ s = "invalid field";
++ break;
++ case DI_ERROR_MEDIUM_CHANGED:
++ s = "medium changed";
++ break;
++ }
++
++ return s;
++}
++
++/*
++ * Prints the given drive status, only if debug enabled.
++ */
++static inline void di_debug_print_drive_status(u32 drive_status)
++{
++ DBG("%08x, [%s, %s]\n", drive_status,
++ di_printable_status(drive_status),
++ di_printable_error(drive_status));
++}
++
++/*
++ * Prints the given drive status.
++ */
++static void di_print_drive_status(u32 drive_status)
++{
++ drv_printk(KERN_INFO, "drive_status=%08x, [%s, %s]\n", drive_status,
++ di_printable_status(drive_status),
++ di_printable_error(drive_status));
++}
++
++/*
++ * Prints the given disk identifier.
++ */
++static void di_print_disk_id(struct di_disk_id *disk_id)
++{
++ drv_printk(KERN_INFO, "disk_id = [%s]\n", disk_id->id);
++}
++
++/*
++ *
++ * I/O.
++ */
++
++/*
++ * Converts a request direction into a DMA data direction.
++ */
++static inline
++enum dma_data_direction di_opidx_to_dma_dir(struct di_command *cmd)
++{
++ u16 op = di_op(cmd);
++
++ if ((op & DI_DIR_WRITE))
++ return DMA_TO_DEVICE;
++ else
++ return DMA_FROM_DEVICE;
++}
++
++/*
++ * Starts a DMA transfer.
++ */
++static void di_start_dma_transfer_raw(struct di_device *ddev,
++ dma_addr_t data, size_t len, int mode)
++{
++ void __iomem *io_base = ddev->io_base;
++ u32 __iomem *sr_reg = io_base + DI_SR;
++ unsigned long flags;
++
++ BUG_ON((data & DI_DMA_ALIGN) != 0 ||
++ (len & DI_DMA_ALIGN) != 0);
++
++ /* setup address and length of transfer */
++ out_be32(io_base + DI_LENGTH, len);
++ out_be32(io_base + DI_MAR, data);
++
++ /* enable the Transfer Complete interrupt */
++ spin_lock_irqsave(&ddev->io_lock, flags);
++ out_be32(sr_reg, in_be32(sr_reg) | DI_SR_TCINTMASK);
++ spin_unlock_irqrestore(&ddev->io_lock, flags);
++
++ /* start the transfer */
++ out_be32(io_base + DI_CR, DI_CR_TSTART | DI_CR_DMA | (mode&0x4));
++}
++
++/*
++ * Internal. Busy-waits until a DMA transfer finishes or timeouts.
++ */
++static int __wait_for_dma_transfer_or_timeout(u32 __iomem *cr_reg,
++ int secs)
++{
++ unsigned long timeout = jiffies + secs*HZ;
++
++ /* busy-wait for transfer complete */
++ while ((in_be32(cr_reg) & DI_CR_TSTART) &&
++ time_before(jiffies, timeout))
++ cpu_relax();
++
++ return (in_be32(cr_reg) & DI_CR_TSTART) ? -EBUSY : 0;
++}
++
++/*
++ * Busy-waits until DMA transfers are finished.
++ */
++static void di_wait_for_dma_transfer_raw(struct di_device *ddev)
++{
++ u32 __iomem *cr_reg = ddev->io_base + DI_CR;
++ u32 __iomem *sr_reg = ddev->io_base + DI_SR;
++ unsigned long flags;
++
++ /* we don't want TCINTs to disturb us while waiting */
++ spin_lock_irqsave(&ddev->io_lock, flags);
++ out_be32(sr_reg, in_be32(sr_reg) & ~DI_SR_TCINTMASK);
++ spin_unlock_irqrestore(&ddev->io_lock, flags);
++
++ /* if the drive got stuck, reset it */
++ if (__wait_for_dma_transfer_or_timeout(cr_reg, DI_COMMAND_TIMEOUT)) {
++ DBG("dvd stuck!\n");
++ di_reset(ddev);
++ }
++
++ /* ack and enable the Transfer Complete interrupt */
++ spin_lock_irqsave(&ddev->io_lock, flags);
++ out_be32(sr_reg, in_be32(sr_reg) | (DI_SR_TCINT|DI_SR_TCINTMASK));
++ spin_unlock_irqrestore(&ddev->io_lock, flags);
++
++ return;
++}
++
++/*
++ * Quiesces the hardware to a calm and known state.
++ */
++static void di_quiesce(struct di_device *ddev)
++{
++ void __iomem *io_base = ddev->io_base;
++ u32 __iomem *cr_reg = io_base + DI_CR;
++ u32 __iomem *sr_reg = io_base + DI_SR;
++ u32 __iomem *cvr_reg = io_base + DI_CVR;
++ u32 sr, cvr;
++ unsigned long flags;
++
++ spin_lock_irqsave(&ddev->io_lock, flags);
++
++ /* ack and mask dvd io interrupts */
++ sr = in_be32(sr_reg);
++ sr |= DI_SR_BRKINT | DI_SR_TCINT | DI_SR_DEINT;
++ sr &= ~(DI_SR_BRKINTMASK | DI_SR_TCINTMASK | DI_SR_DEINTMASK);
++ out_be32(sr_reg, sr);
++
++ /* ack and mask dvd cover interrupts */
++ cvr = in_be32(cvr_reg);
++ out_be32(cvr_reg, (cvr | DI_CVR_CVRINT) & ~DI_CVR_CVRINTMASK);
++
++ spin_unlock_irqrestore(&ddev->io_lock, flags);
++
++ /* busy-wait for transfer complete */
++ __wait_for_dma_transfer_or_timeout(cr_reg, DI_COMMAND_TIMEOUT);
++}
++
++/*
++ * Command engine.
++ *
++ */
++
++/*
++ * Outputs the command buffers, and optionally starts a transfer.
++ */
++static void di_prepare_command(struct di_command *cmd, int tstart)
++{
++ struct di_opcode *opcode = di_get_opcode(cmd);
++ void __iomem *io_base = cmd->ddev->io_base;
++
++ /*DBG("buf0 = 0x%08x, buf1 = 0x%08x, buf2 = 0x%08x\n",
++ cmd->cmdbuf0, cmd->cmdbuf1, cmd->cmdbuf2);*/
++
++ out_be32(io_base + DI_CMDBUF0, cmd->cmdbuf0);
++ out_be32(io_base + DI_CMDBUF1, cmd->cmdbuf1);
++ out_be32(io_base + DI_CMDBUF2, cmd->cmdbuf2);
++
++ cmd->ddev->drive_status = 0;
++
++ if (tstart)
++ out_be32(io_base + DI_CR, DI_CR_TSTART | (opcode->op & 0x6));
++}
++
++static void di_command_done(struct di_command *cmd);
++
++/*
++ * Starts a command by using the immediate mode.
++ */
++static int di_start_command(struct di_command *cmd)
++{
++ struct di_device *ddev = cmd->ddev;
++ unsigned long flags;
++ int retval = 1;
++
++ spin_lock_irqsave(&ddev->lock, flags);
++
++ BUG_ON(ddev->cmd);
++
++ ddev->cmd = cmd;
++ cmd->dma_len = 0; /* no dma here */
++ di_prepare_command(cmd, 1);
++
++ spin_unlock_irqrestore(&ddev->lock, flags);
++
++ return retval;
++}
++
++/*
++ * Starts a command by using the DMA mode.
++ */
++static int di_start_dma_command(struct di_command *cmd)
++{
++ struct di_device *ddev = cmd->ddev;
++ unsigned long flags;
++ int retval = 1;
++
++ spin_lock_irqsave(&ddev->lock, flags);
++
++ BUG_ON(ddev->cmd);
++
++ ddev->cmd = cmd;
++ cmd->dma_len = cmd->len;
++ cmd->dma_addr = dma_map_single(ddev->dev,
++ cmd->data, cmd->len,
++ di_opidx_to_dma_dir(cmd));
++
++ di_prepare_command(cmd, 0);
++ di_start_dma_transfer_raw(ddev, cmd->dma_addr, cmd->dma_len,
++ di_op(cmd) & DI_DIR_WRITE);
++
++ spin_unlock_irqrestore(&ddev->lock, flags);
++
++ return retval;
++}
++
++/*
++ * Completes a "get drive status" command, after a failed command.
++ */
++static void di_complete_getstatus(struct di_command *cmd)
++{
++ struct di_device *ddev = cmd->ddev;
++ void __iomem *io_base = ddev->io_base;
++ u32 __iomem *data_reg = io_base + DI_DATA;
++
++ ddev->drive_status = in_be32(data_reg);
++}
++
++/*
++ * Called after a transfer is completed.
++ */
++static void di_complete_transfer(struct di_device *ddev, u32 result)
++{
++ struct di_command *cmd;
++ struct di_opcode *opcode;
++ u32 drive_status;
++ unsigned long flags;
++
++ spin_lock_irqsave(&ddev->lock, flags);
++
++ /* do nothing if we have nothing to complete */
++ cmd = ddev->cmd;
++ if (!cmd) {
++ spin_unlock_irqrestore(&ddev->lock, flags);
++ goto out;
++ }
++
++ /* free the command slot */
++ ddev->cmd = NULL;
++ spin_unlock_irqrestore(&ddev->lock, flags);
++
++ /* deal with caches after a dma transfer */
++ if (cmd->dma_len) {
++ dma_unmap_single(ddev->dev,
++ cmd->dma_addr, cmd->dma_len,
++ di_opidx_to_dma_dir(cmd));
++ }
++
++ opcode = di_get_opcode(cmd);
++
++ /*
++ * If a command fails we check the drive status. Depending on that
++ * we may or not retry later the command.
++ */
++ cmd->result = result;
++ if (!di_command_ok(cmd)) {
++ /* the MATSHITA command always reports failure, ignore it */
++ if (DI_OP_ID(opcode->op) != DI_OP_ENABLE1) {
++ BUG_ON(ddev->failed_cmd != NULL);
++
++ ddev->failed_cmd = cmd;
++
++ /*
++ * Issue immediately a "get drive status"
++ * after a failed command.
++ */
++ cmd = &ddev->status;
++ di_op_getstatus(cmd, ddev);
++ cmd->done = di_complete_getstatus;
++ di_run_command(cmd);
++ goto out;
++ }
++ } else {
++ if (cmd->retries != cmd->max_retries) {
++ DBG("command %s succeeded after %d retries :-)\n",
++ opcode->name, cmd->max_retries - cmd->retries);
++ }
++ }
++
++ /* complete a successful command, or the MATSHITA one */
++ di_command_done(cmd);
++
++ spin_lock_irqsave(&ddev->lock, flags);
++ if (ddev->failed_cmd) {
++ cmd = ddev->failed_cmd;
++ ddev->failed_cmd = NULL;
++ spin_unlock_irqrestore(&ddev->lock, flags);
++
++ drive_status = ddev->drive_status;
++ opcode = di_get_opcode(cmd);
++
++ /* retry a previously failed command if appropiate */
++ if (cmd->retries > 0) {
++ if (di_may_retry(drive_status)) {
++ DBG("command %s failed, %d retries left\n",
++ opcode->name, cmd->retries);
++ di_debug_print_drive_status(drive_status);
++
++ cmd->retries--;
++ di_run_command(cmd);
++ goto out;
++ } else {
++ DBG("command %s failed,"
++ " aborting due to drive status\n",
++ opcode->name);
++ }
++ } else {
++ if (!(opcode->op & DI_IGNORE_ERRORS))
++ DBG("command %s failed\n", opcode->name);
++ }
++
++ if (!(opcode->op & DI_IGNORE_ERRORS))
++ di_print_drive_status(drive_status);
++
++ /* complete the failed command */
++ di_command_done(cmd);
++
++ /* update the driver status */
++ switch (DI_ERROR(drive_status)) {
++ case DI_ERROR_MOTOR_STOPPED:
++ case DI_ERROR_MEDIUM_NOT_PRESENT:
++ case DI_ERROR_MEDIUM_CHANGED:
++ set_bit(__DI_MEDIA_CHANGED, &ddev->flags);
++ break;
++ default:
++ break;
++ }
++
++ } else {
++ spin_unlock_irqrestore(&ddev->lock, flags);
++ }
++
++ /* start the block layer queue if someone requested it */
++ if (test_and_clear_bit(__DI_START_QUEUE, &ddev->flags)) {
++ spin_lock_irqsave(&ddev->queue_lock, flags);
++ blk_start_queue(ddev->queue);
++ spin_unlock_irqrestore(&ddev->queue_lock, flags);
++ }
++
++out:
++ return;
++}
++
++/*
++ * Calls any done hooks.
++ */
++static void di_command_done(struct di_command *cmd)
++{
++ /* if specified, call the completion routine */
++ if (cmd->done)
++ cmd->done(cmd);
++}
++
++/*
++ * Completion routine.
++ */
++static void di_wait_done(struct di_command *cmd)
++{
++ complete(cmd->done_data);
++}
++
++/*
++ * Runs a command.
++ */
++static int di_run_command(struct di_command *cmd)
++{
++ struct di_opcode *opcode = di_get_opcode(cmd);
++ int retval;
++
++ if (cmd->retries > cmd->max_retries)
++ cmd->retries = cmd->max_retries;
++
++ if (!(opcode->op & DI_MODE_DMA))
++ retval = di_start_command(cmd);
++ else
++ retval = di_start_dma_command(cmd);
++ return retval;
++}
++
++/*
++ * Runs a command and waits.
++ * Might sleep if called from user context.
++ */
++static int di_run_command_and_wait(struct di_command *cmd)
++{
++ DECLARE_COMPLETION(complete);
++
++ cmd->done_data = &complete;
++ cmd->done = di_wait_done;
++ if (di_run_command(cmd) > 0)
++ wait_for_completion(&complete);
++ return cmd->result;
++}
++
++/*
++ * Interrupt handler for DI interrupts.
++ */
++static irqreturn_t di_irq_handler(int irq, void *dev0)
++{
++ struct di_device *ddev = dev0;
++ void __iomem *io_base = ddev->io_base;
++ u32 __iomem *sr_reg = io_base + DI_SR;
++ u32 __iomem *cvr_reg = io_base + DI_CVR;
++ u32 sr, cvr, reason, mask;
++ unsigned long flags;
++
++ spin_lock_irqsave(&ddev->io_lock, flags);
++
++ sr = in_be32(sr_reg);
++ mask = sr & (DI_SR_BRKINTMASK | DI_SR_TCINTMASK | DI_SR_DEINTMASK);
++ reason = sr; /* & (mask << 1); */
++ if (reason) {
++ out_be32(sr_reg, sr | reason);
++ spin_unlock_irqrestore(&ddev->io_lock, flags);
++
++ if (reason & DI_SR_TCINT)
++ di_complete_transfer(ddev, DI_SR_TCINT);
++ if (reason & DI_SR_BRKINT) {
++ DBG("BRKINT\n");
++ di_complete_transfer(ddev, DI_SR_BRKINT);
++ }
++ if (reason & DI_SR_DEINT)
++ di_complete_transfer(ddev, DI_SR_DEINT);
++
++ spin_lock_irqsave(&ddev->io_lock, flags);
++ }
++
++ cvr = in_be32(cvr_reg);
++ mask = cvr & DI_CVR_CVRINTMASK;
++ reason = cvr; /* & (mask << 1); */
++ if ((reason & DI_CVR_CVRINT)) {
++ out_be32(cvr_reg, cvr | DI_CVR_CVRINT);
++ set_bit(__DI_MEDIA_CHANGED, &ddev->flags);
++ if (test_and_clear_bit(__DI_RESETTING, &ddev->flags)) {
++ if (!test_bit(__DI_AVOID_DEBUG, &ddev->flags)) {
++ if (ddev->flags & DI_INTEROPERABLE) {
++ DBG("extensions loaded"
++ " and hopefully working\n");
++ }
++ }
++ } else {
++ DBG("dvd cover interrupt\n");
++ }
++ }
++
++ spin_unlock_irqrestore(&ddev->io_lock, flags);
++
++ return IRQ_HANDLED;
++}
++
++/*
++ * Hard-resets the drive.
++ */
++static void di_reset(struct di_device *ddev)
++{
++ u32 __iomem *reset_reg = (u32 __iomem *)0xcc003024;
++ u32 reset;
++
++#define FLIPPER_RESET_DVD 0x00000004
++
++ /* set flags, but preserve the alien firmware flag */
++ ddev->flags = (ddev->flags & DI_AVOID_DEBUG) |
++ DI_RESETTING | DI_MEDIA_CHANGED;
++
++ reset = in_be32(reset_reg);
++ out_be32(reset_reg, (reset & ~FLIPPER_RESET_DVD) | 1);
++ mdelay(500);
++ out_be32(reset_reg, (reset | FLIPPER_RESET_DVD) | 1);
++ mdelay(500);
++
++ DBG("drive reset\n");
++}
++
++
++/*
++ * Misc routines.
++ *
++ */
++
++/*
++ * Retrieves (and prints out) the laser unit model.
++ */
++static u32 di_retrieve_drive_model(struct di_device *ddev)
++{
++ struct di_command cmd;
++
++ memset(&di_drive_info, 0, sizeof(di_drive_info));
++ di_op_inq(&cmd, ddev, &di_drive_info);
++ di_run_command_and_wait(&cmd);
++
++ drv_printk(KERN_INFO, "laser unit: rev=%x, code=%x, date=%x\n",
++ di_drive_info.rev, di_drive_info.code,
++ di_drive_info.date);
++
++ ddev->model = di_drive_info.date;
++ return ddev->model;
++}
++
++/*
++ * Gets the current drive status.
++ */
++static u32 di_get_drive_status(struct di_device *ddev)
++{
++ void __iomem *io_base = ddev->io_base;
++ u32 __iomem *data_reg = io_base + DI_DATA;
++ struct di_command cmd;
++ u32 drive_status;
++
++ di_op_getstatus(&cmd, ddev);
++ di_run_command_and_wait(&cmd);
++ drive_status = in_be32(data_reg);
++
++ return drive_status;
++}
++
++/*
++ * Checks if the drive is in a ready state.
++ */
++static int di_is_drive_ready(struct di_device *ddev)
++{
++ u32 drive_status;
++ int result = 0;
++
++ drive_status = di_get_drive_status(ddev);
++ if (DI_STATUS(drive_status) == DI_STATUS_DISK_ID_NOT_READ ||
++ DI_STATUS(drive_status) == DI_STATUS_READY) {
++ result = 1;
++ }
++
++ return result;
++}
++
++/*
++ *
++ * Firmware handling.
++ */
++
++/*
++ * Reads a long word from drive addressable memory.
++ * Requires debug mode enabled.
++ */
++static int di_fw_read_meml(struct di_device *ddev,
++ unsigned long *data, unsigned long address)
++{
++ void __iomem *io_base = ddev->io_base;
++ struct di_command cmd;
++ int result = -1;
++
++ di_op_readmem(&cmd, ddev);
++ cmd.cmdbuf1 = address;
++ di_run_command_and_wait(&cmd);
++ if (di_command_ok(&cmd)) {
++ *data = in_be32(io_base + DI_DATA);
++ result = 0;
++ }
++ return result;
++}
++
++/*
++ * Retrieves the current active interrupt handler for the drive.
++ * Requires debug mode enabled.
++ */
++static unsigned long di_fw_get_irq_handler(struct di_device *ddev)
++{
++ unsigned long data = 0;
++
++ di_fw_read_meml(ddev, &data, DI_DRIVE_IRQ_VECTOR);
++ return data;
++}
++
++/*
++ * Patches drive addressable memory.
++ * Requires debug mode enabled.
++ */
++static void di_fw_patch_mem(struct di_device *ddev, u32 address,
++ void *data, size_t len)
++{
++ struct di_command cmd;
++ struct di_opcode opcode;
++ int chunk_size;
++ const int max_chunk_size = 3 * sizeof(cmd.cmdbuf0);
++
++ while (len > 0) {
++ /* we can write in groups of 12 bytes at max */
++ if (len > max_chunk_size)
++ chunk_size = max_chunk_size;
++ else
++ chunk_size = len;
++
++ /* prepare for writing to drive's memory ... */
++ di_op_writemem(&cmd, ddev);
++ cmd.cmdbuf1 = address;
++ cmd.cmdbuf2 = chunk_size << 16;
++ di_run_command_and_wait(&cmd);
++ if (!di_command_ok(&cmd))
++ break;
++
++ /* ... and actually write to it */
++ opcode.op = DI_OP(DI_OP_CUSTOM, DI_DIR_READ | DI_MODE_IMMED);
++ opcode.name = "custom write";
++ di_op_custom(&cmd, ddev, &opcode);
++ memcpy(&cmd.cmdbuf0, data, chunk_size);
++ di_run_command(&cmd);
++
++ /*
++ * We can't rely on drive operating as expected here, so we
++ * explicitly poll for end of transfer and timeout eventually.
++ * Anyway, we assume everything was ok.
++ */
++ di_wait_for_dma_transfer_raw(ddev);
++ di_complete_transfer(ddev, DI_SR_TCINT);
++
++ /* ok, next chunk */
++ address += chunk_size;
++ data += chunk_size;
++ len -= chunk_size;
++ }
++}
++
++/*
++ * Runs a series of patches.
++ * Requires debug mode enabled.
++ */
++static void di_fw_patch(struct di_device *ddev,
++ struct di_drive_code *section, int nr_sections)
++{
++ while (nr_sections > 0) {
++ di_fw_patch_mem(ddev, section->address,
++ section->code, section->len);
++ section++;
++ nr_sections--;
++ }
++}
++
++/*
++ * Selects the appropiate drive code for each drive.
++ */
++static int di_select_drive_code(struct di_device *ddev)
++{
++ ddev->drive_code = NULL;
++
++ switch (ddev->model) {
++ case 0x20020402:
++ ddev->drive_code = &drive_20020402;
++ break;
++ case 0x20010608:
++ ddev->drive_code = &drive_20010608;
++ break;
++ case 0x20020823:
++ ddev->drive_code = &drive_20020823;
++ break;
++ case 0x20010831:
++ ddev->drive_code = &drive_20010831;
++ break;
++ default:
++ drv_printk(KERN_ERR, "sorry, drive %x is not yet"
++ " supported\n",
++ di_drive_info.date);
++ break;
++ }
++
++ return (ddev->drive_code) ? 0 : -EINVAL;
++}
++
++/*
++ *
++ */
++static u8 parking_code[] = {
++ 0xa0, /* sub d0, d0 */
++ 0xc4, 0xda, 0xfc, /* movb d0, (ADBCTL) */
++ 0xf4, 0x74, 0x74, 0x0a, 0x08, /* mov 0x080a74, a0 */ /* fixup */
++ 0xf7, 0x20, 0x4c, 0x80, /* mov a0, (0x804c) */
++ 0xfe, /* rts */
++};
++
++/*
++ * Parks (disables) any existing alien drive code.
++ * Requires debug mode enabled.
++ */
++static u32 di_park_firmware(struct di_device *ddev)
++{
++ struct di_command cmd;
++ u32 irq_handler, original_irq_handler;
++ u32 load_address;
++
++ /* calculate an appropiate load address for the parking code */
++ irq_handler = le32_to_cpu(di_fw_get_irq_handler(ddev));
++ load_address = (irq_handler >= 0x400000) ? 0x008502 : 0x40c600;
++
++ /* get the original interrupt handler */
++ irq_handler = (ddev->model != 0x20010831) ? 0x00080A74 : 0x00080AA4;
++ original_irq_handler = irq_handler;
++
++ /* fix the parking code to match our drive model */
++ cpu_to_le32s(&irq_handler);
++ memcpy(parking_code + 6, &irq_handler, 3);
++
++ /* load and call it */
++ di_fw_patch_mem(ddev, load_address, parking_code, sizeof(parking_code));
++ di_op_func(&cmd, ddev, load_address);
++ di_run_command_and_wait(&cmd);
++
++ /*
++ * Check if the parking code did its job.
++ * The drive should be running now under the original irq handler.
++ */
++ irq_handler = le32_to_cpu(di_fw_get_irq_handler(ddev));
++ if (irq_handler != original_irq_handler) {
++ drv_printk(KERN_ERR, "parking failed!\n");
++ di_reset(ddev);
++ } else {
++ DBG("parking done, irq handler = %08x\n", irq_handler);
++ }
++
++ /* drive is not patched anymore here */
++ clear_bit(__DI_INTEROPERABLE, &ddev->flags);
++
++ return di_get_drive_status(ddev);
++}
++
++/*
++ * Spins down the drive, immediatelly.
++ */
++static void di_spin_down_drive(struct di_device *ddev)
++{
++ struct di_command cmd;
++
++ di_op_stopmotor(&cmd, ddev);
++ di_run_command_and_wait(&cmd);
++}
++
++/*
++ * Enables the "debug" command set.
++ */
++static int di_enable_debug_commands(struct di_device *ddev)
++{
++ struct di_command cmd;
++
++ /* send these two consecutive enable commands */
++ di_op_enable1(&cmd, ddev);
++ di_run_command_and_wait(&cmd);
++ di_op_enable2(&cmd, ddev);
++ return di_run_command_and_wait(&cmd);
++}
++
++/*
++ * Tries to determine if firmware extensions are currently installed.
++ * Requires debug mode enabled.
++ */
++static int di_has_alien_drive_code(struct di_device *ddev)
++{
++ unsigned long address;
++ int result = 1;
++
++ /*
++ * We assume that alien drive code is in place if the interrupt handler
++ * is not pointing to ROM address space.
++ */
++ address = di_fw_get_irq_handler(ddev);
++ address = le32_to_cpu(address);
++ if (address) {
++ if ((address & 0xffff0000) == 0x00080000)
++ result = 0;
++ }
++ return result;
++}
++
++/*
++ * Enables some workarounds and/or special behaviours depending on
++ * the drive firmware found.
++ * Requires debug mode enabled.
++ */
++static void di_init_alien_drive_code_quirks(struct di_device *ddev)
++{
++ unsigned long fingerprint;
++
++ /*
++ * Test if a xenogc/duoq is installed.
++ */
++ if (!di_fw_read_meml(ddev, &fingerprint, 0x40c60a)) {
++ if (fingerprint == 0xf710fff7) {
++ drv_printk(KERN_INFO, "drivechip: xenogc/duoq\n");
++ set_bit(__DI_AVOID_DEBUG, &ddev->flags);
++ }
++ }
++}
++
++/*
++ * Configures the drive to accept DVD-R and DVD+R media.
++ */
++static void di_make_interoperable(struct di_device *ddev)
++{
++ struct di_command cmd;
++
++ if (!ddev->drive_code || test_bit(__DI_AVOID_DEBUG, &ddev->flags))
++ return;
++
++ /* calm things down */
++ di_spin_down_drive(ddev);
++
++ /* disable any alien drive code */
++ di_enable_debug_commands(ddev);
++ di_park_firmware(ddev);
++
++ /* re-enable debug commands */
++ di_enable_debug_commands(ddev);
++
++ /* load our own drive code extensions */
++ di_fw_patch(ddev, ddev->drive_code, 1);
++
++ /*
++ * The drive will become interoperable now.
++ * Here we go...!
++ */
++ set_bit(__DI_INTEROPERABLE, &ddev->flags);
++ di_op_func(&cmd, ddev, DI_DRIVE_CODE_BASE);
++ di_run_command_and_wait(&cmd);
++
++ /* this checks if drive is still working... */
++ di_get_drive_status(ddev);
++}
++
++/*
++ * Ensures that the debug features of the drive firmware are working.
++ */
++static int di_probe_debug_features(struct di_device *ddev)
++{
++ int result;
++
++ /* do nothing on unknown drive models */
++ if (!ddev->drive_code)
++ return -EINVAL;
++
++ result = di_enable_debug_commands(ddev);
++ if (!di_result_ok(result)) {
++ DBG("uhmm, debug commands seem banned...\n");
++ DBG("... let's hard reset the drive!\n");
++
++ di_reset(ddev);
++ result = di_enable_debug_commands(ddev);
++ }
++
++ return di_result_ok(result) ? 0 : -EINVAL;
++}
++
++/*
++ * Probes the existing firmware features and determines the best operation
++ * mode.
++ */
++static void di_probe_firmware(struct di_device *ddev)
++{
++ if (di_probe_debug_features(ddev)) {
++ /* we can't use debug features, thus try to avoid them */
++ drv_printk(KERN_INFO, "firmware: debug features do not work,"
++ " using standard command set\n");
++ set_bit(__DI_AVOID_DEBUG, &ddev->flags);
++ } else {
++ if (di_has_alien_drive_code(ddev)) {
++ drv_printk(KERN_INFO, "firmware: patched drive\n");
++ /* enable some workarounds if required */
++ di_init_alien_drive_code_quirks(ddev);
++ } else {
++ drv_printk(KERN_INFO, "firmware: unpatched drive\n");
++ }
++ }
++}
++
++/*
++ * Stops the drive's motor, according to a previous schedule.
++ */
++static void di_motor_off(unsigned long ddev0)
++{
++ struct di_device *ddev = (struct di_device *)ddev0;
++ struct di_command *cmd;
++ unsigned long flags;
++
++ /* postpone a bit the motor off if there are pending commands */
++ spin_lock_irqsave(&ddev->lock, flags);
++ if (!ddev->cmd) {
++ ddev->cmd = cmd = &ddev->status;
++ spin_unlock_irqrestore(&ddev->lock, flags);
++ di_op_stopmotor(cmd, ddev);
++ di_prepare_command(cmd, 1);
++ } else {
++ spin_unlock_irqrestore(&ddev->lock, flags);
++ mod_timer(&ddev->motor_off_timer, jiffies + 1*HZ);
++ }
++}
++
++/*
++ * Cancels a previously scheduled motor off.
++ */
++static inline void di_cancel_motor_off(struct di_device *ddev)
++{
++ del_timer(&ddev->motor_off_timer);
++}
++
++/*
++ * Stops the drive's motor after the specified amount of seconds has elapsed.
++ */
++static void di_schedule_motor_off(struct di_device *ddev, unsigned int secs)
++{
++ del_timer(&ddev->motor_off_timer);
++ ddev->motor_off_timer.expires = jiffies + secs*HZ;
++ ddev->motor_off_timer.data = (unsigned long)ddev;
++ add_timer(&ddev->motor_off_timer);
++}
++
++/*
++ * Spins up the drive.
++ */
++static void di_spin_up_drive(struct di_device *ddev, u8 enable_extensions)
++{
++ struct di_command cmd;
++ u32 drive_status;
++ unsigned int attempts = 2;
++
++ /* do nothing if the drive is already spinning */
++ if (di_is_drive_ready(ddev))
++ goto out;
++
++ if (test_bit(__DI_AVOID_DEBUG, &ddev->flags)) {
++ /* don't use debug commands, let's hope a drivechip is there */
++ di_reset(ddev);
++ } else {
++ while (attempts-- > 0) {
++ if (!test_bit(__DI_INTEROPERABLE, &ddev->flags))
++ di_make_interoperable(ddev);
++
++ /*
++ * We only re-enable the extensions if the drive is not
++ * in a pending read disk id state. Otherwise, we assume
++ * that the drive has already accepted the disk.
++ */
++ drive_status = di_get_drive_status(ddev);
++ if (DI_STATUS(drive_status) !=
++ DI_STATUS_DISK_ID_NOT_READ) {
++ di_op_enableextensions(&cmd, ddev,
++ enable_extensions);
++ di_run_command_and_wait(&cmd);
++ }
++
++ /* the spin motor command requires the debug mode */
++ di_enable_debug_commands(ddev);
++ di_op_spinmotor(&cmd, ddev, DI_SPINMOTOR_UP);
++ di_run_command_and_wait(&cmd);
++
++ if (!ddev->drive_status) {
++ di_op_setstatus(&cmd, ddev,
++ DI_STATUS_DISK_ID_NOT_READ+1);
++ cmd.cmdbuf0 |= 0x00000300; /* XXX cheqmate */
++ di_run_command_and_wait(&cmd);
++ } else {
++ if (DI_ERROR(ddev->drive_status) !=
++ DI_ERROR_MEDIUM_NOT_PRESENT)
++ di_reset(ddev);
++ continue;
++ }
++ break;
++ }
++ }
++out:
++ return;
++}
++
++
++/*
++ * Block layer hooks.
++ *
++ */
++
++static int di_read_toc(struct di_device *ddev)
++{
++ static struct di_disk_id disk_id
++ __attribute__ ((aligned(DI_DMA_ALIGN+1)));
++ struct di_command cmd;
++ int accepted_media = 0;
++ int retval = 0;
++ const u8 enable_extensions = 1;
++
++ di_cancel_motor_off(ddev);
++
++ /* spin up the drive if needed */
++ if ((ddev->flags & DI_MEDIA_CHANGED))
++ di_spin_up_drive(ddev, enable_extensions);
++
++ /* check that disk id can be read and that the media is appropiate */
++ memset(&disk_id, 0, sizeof(disk_id));
++ di_op_readdiskid(&cmd, ddev, &disk_id);
++ di_run_command_and_wait(&cmd);
++ if (di_command_ok(&cmd)) {
++ if (disk_id.id[0] && memcmp(disk_id.id, "GBL", 3) &&
++ !di_accept_gods) {
++ di_print_disk_id(&disk_id);
++ drv_printk(KERN_ERR, "sorry, gamecube media"
++ " support is disabled\n");
++ } else {
++ accepted_media = 1;
++ }
++ } else {
++ set_bit(__DI_MEDIA_CHANGED, &ddev->flags);
++ }
++
++ if (accepted_media) {
++ /*
++ * This is currently hardcoded. Scream|CT got this number
++ * by reading up to where the lens physically allowed.
++ *
++ * This is currently causing us problems.
++ * For example, recent 'mount' versions will read 4k from
++ * the end of the device when guessing filesystem types.
++ * The end of device we are reporting is not the real one,
++ * so the drive will fail to read that part if it was not
++ * burned.
++ *
++ * As a temporary solution, specify always a filesystem
++ * type when using mount, or fill the whole disk when
++ * burning.
++ */
++ ddev->nr_sectors = DI_MAX_SECTORS; /* in DVD sectors */
++ clear_bit(__DI_MEDIA_CHANGED, &ddev->flags);
++
++ DBG("media ready for operation\n");
++ } else {
++ ddev->nr_sectors = 0;
++ retval = -ENOMEDIUM;
++
++ di_spin_down_drive(ddev);
++
++ DBG("media NOT ready\n");
++ }
++
++ /* transform to kernel sectors */
++ ddev->nr_sectors <<= (DI_SECTOR_SHIFT - KERNEL_SECTOR_SHIFT);
++ set_capacity(ddev->disk, ddev->nr_sectors);
++
++ return retval;
++}
++
++
++static void di_request_done(struct di_command *cmd)
++{
++ struct di_device *ddev = cmd->ddev;
++ struct request *req;
++ unsigned long flags;
++ int error = (cmd->result & DI_SR_TCINT) ? 0 : -EIO;
++
++ spin_lock_irqsave(&ddev->lock, flags);
++
++ req = ddev->req;
++ ddev->req = NULL;
++
++ spin_unlock_irqrestore(&ddev->lock, flags);
++
++ if (req) {
++ __blk_end_request(req, error, req->current_nr_sectors << 9);
++ spin_lock_irqsave(&ddev->queue_lock, flags);
++ blk_start_queue(ddev->queue);
++ spin_unlock_irqrestore(&ddev->queue_lock, flags);
++ }
++}
++
++static void di_do_request(struct request_queue *q)
++{
++ struct di_device *ddev = q->queuedata;
++ struct di_command *cmd = &ddev->req_cmd;
++ struct request *req;
++ unsigned long start;
++ unsigned long flags;
++ size_t len;
++
++ while ((req = elv_next_request(q))) {
++ /* keep our reads within limits */
++ if (req->sector + req->current_nr_sectors > ddev->nr_sectors) {
++ drv_printk(KERN_ERR, "reading past end\n");
++ end_request(req, 0);
++ continue;
++ }
++
++ /* it doesn't make sense to write to this device */
++ if (rq_data_dir(req) == WRITE) {
++ drv_printk(KERN_ERR, "write attempted\n");
++ end_request(req, 0);
++ continue;
++ }
++
++ /* it is not a good idea to open the lid ... */
++ if ((ddev->flags & DI_MEDIA_CHANGED)) {
++ drv_printk(KERN_ERR, "media changed, aborting\n");
++ end_request(req, 0);
++ continue;
++ }
++
++ spin_lock_irqsave(&ddev->lock, flags);
++
++ /* we can schedule just a single request each time */
++ if (ddev->req || ddev->cmd) {
++ blk_stop_queue(q);
++ if (ddev->cmd)
++ set_bit(__DI_START_QUEUE, &ddev->flags);
++ spin_unlock_irqrestore(&ddev->lock, flags);
++ break;
++ }
++
++ blkdev_dequeue_request(req);
++
++ /* ignore requests that we can't handle */
++ if (!blk_fs_request(req)) {
++ spin_unlock_irqrestore(&ddev->lock, flags);
++ continue;
++ }
++
++ /* store the request being handled ... */
++ ddev->req = req;
++ blk_stop_queue(q);
++
++ spin_unlock_irqrestore(&ddev->lock, flags);
++
++ /* ... and launch the corresponding read sector command */
++ start = req->sector << KERNEL_SECTOR_SHIFT;
++ len = req->current_nr_sectors << KERNEL_SECTOR_SHIFT;
++
++ di_op_readsector(cmd, ddev, start >> 2,
++ req->buffer, len);
++ cmd->done_data = cmd;
++ cmd->done = di_request_done;
++ di_run_command(cmd);
++ }
++}
++
++/*
++ * Block device hooks.
++ *
++ */
++
++static int di_open(struct block_device *bdev, fmode_t mode)
++{
++ struct di_device *ddev = bdev->bd_disk->private_data;
++ struct di_command *cmd;
++ DECLARE_COMPLETION(complete);
++ unsigned long flags;
++ int retval = 0;
++
++ /* this is a read only device */
++ if (mode & FMODE_WRITE) {
++ retval = -EROFS;
++ goto out;
++ }
++
++ /*
++ * If we have a pending command, that's a previously scheduled
++ * motor off. Wait for it to terminate before going on.
++ */
++ spin_lock_irqsave(&ddev->lock, flags);
++ if (ddev->cmd && ddev->ref_count == 0) {
++ cmd = ddev->cmd;
++ cmd->done_data = &complete;
++ cmd->done = di_wait_done;
++ spin_unlock_irqrestore(&ddev->lock, flags);
++ wait_for_completion(&complete);
++ } else {
++ spin_unlock_irqrestore(&ddev->lock, flags);
++ }
++
++ /* this will take care of validating the media */
++ check_disk_change(bdev);
++ if (!ddev->nr_sectors) {
++ retval = -ENOMEDIUM;
++ goto out;
++ }
++
++ spin_lock_irqsave(&ddev->queue_lock, flags);
++
++ /* honor exclusive open mode */
++ if (ddev->ref_count == -1 ||
++ (ddev->ref_count && (mode & FMODE_EXCL))) {
++ retval = -EBUSY;
++ goto out_unlock;
++ }
++
++ if ((mode & FMODE_EXCL))
++ ddev->ref_count = -1;
++ else
++ ddev->ref_count++;
++
++out_unlock:
++ spin_unlock_irqrestore(&ddev->queue_lock, flags);
++out:
++ return retval;
++
++}
++
++static int di_release(struct gendisk *disk, fmode_t mode)
++{
++ struct di_device *ddev = disk->private_data;
++ unsigned long flags;
++
++ spin_lock_irqsave(&ddev->queue_lock, flags);
++
++ if (ddev->ref_count > 0)
++ ddev->ref_count--;
++ else
++ ddev->ref_count = 0;
++
++ spin_unlock_irqrestore(&ddev->queue_lock, flags);
++
++ if (ddev->ref_count == 0) {
++ /*
++ * We do not immediately stop the motor, which saves us
++ * a spin down/spin up in applications that re-open quickly
++ * the device, like mount when -t is not specified.
++ */
++ di_schedule_motor_off(ddev, 1);
++
++ set_bit(__DI_MEDIA_CHANGED, &ddev->flags);
++ }
++
++ return 0;
++}
++
++static int di_revalidate_disk(struct gendisk *disk)
++{
++ struct di_device *ddev = disk->private_data;
++ di_read_toc(ddev);
++ return 0;
++}
++
++static int di_media_changed(struct gendisk *disk)
++{
++ struct di_device *ddev = disk->private_data;
++ return (ddev->flags & DI_MEDIA_CHANGED) ? 1 : 0;
++}
++
++static int di_ioctl(struct block_device *bdev, fmode_t mode,
++ unsigned int cmd, unsigned long arg)
++{
++ switch (cmd) {
++ case CDROMMULTISESSION:
++ /* struct cdrom_multisession */
++ break;
++ case CDROMSTART:
++ break;
++ case CDROMSTOP:
++ break;
++ case CDROMREADTOCHDR:
++ /* struct cdrom_tochdr */
++ break;
++ case CDROMREADTOCENTRY:
++ /* struct cdrom_tocentry */
++ break;
++ case CDROMREADMODE2:
++ case CDROMREADMODE1:
++ case CDROMREADRAW:
++ /* struct cdrom_read (1-2048, 2-2336,RAW-2352) */
++ break;
++ case CDROM_GET_MCN:
++ /* retrieve the universal product code */
++ /* struct cdrom_mcn */
++ break;
++ case CDROMRESET:
++ /* reset the drive */
++ break;
++ case BLKRAGET:
++ case BLKFRAGET:
++ case BLKROGET:
++ case BLKBSZGET:
++ case BLKSSZGET:
++ case BLKSECTGET:
++ case BLKGETSIZE:
++ case BLKGETSIZE64:
++ case BLKFLSBUF:
++ return ioctl_by_bdev(bdev, cmd, arg);
++ default:
++ return -EINVAL;
++ }
++ return -EINVAL;
++}
++
++static struct block_device_operations di_fops = {
++ .owner = THIS_MODULE,
++ .open = di_open,
++ .release = di_release,
++ .revalidate_disk = di_revalidate_disk,
++ .media_changed = di_media_changed,
++ .ioctl = di_ioctl,
++};
++
++/*
++ * Setup routines.
++ *
++ */
++
++static int di_init_irq(struct di_device *ddev)
++{
++ void __iomem *io_base = ddev->io_base;
++ u32 __iomem *sr_reg = io_base + DI_SR;
++ u32 __iomem *cvr_reg = io_base + DI_CVR;
++ u32 sr, cvr;
++ unsigned long flags;
++ int retval;
++
++ init_timer(&ddev->motor_off_timer);
++ ddev->motor_off_timer.function =
++ (void (*)(unsigned long))di_motor_off;
++
++ ddev->flags = 0;
++ set_bit(__DI_MEDIA_CHANGED, &ddev->flags);
++
++ /* calm down things a bit first */
++ di_quiesce(ddev);
++
++ /* request interrupt */
++ retval = request_irq(ddev->irq, di_irq_handler, 0,
++ DRV_MODULE_NAME, ddev);
++ if (retval) {
++ drv_printk(KERN_ERR, "request of irq%d failed\n", ddev->irq);
++ goto out;
++ }
++
++ spin_lock_irqsave(&ddev->io_lock, flags);
++
++ sr = in_be32(sr_reg);
++ sr |= DI_SR_BRKINT | DI_SR_TCINT | DI_SR_DEINT;
++ sr |= DI_SR_BRKINTMASK | DI_SR_TCINTMASK | DI_SR_DEINTMASK;
++ out_be32(sr_reg, sr);
++
++ cvr = in_be32(cvr_reg);
++ out_be32(cvr_reg, cvr | DI_CVR_CVRINT | DI_CVR_CVRINTMASK);
++
++ spin_unlock_irqrestore(&ddev->io_lock, flags);
++
++ di_retrieve_drive_model(ddev);
++ di_select_drive_code(ddev);
++
++ di_probe_firmware(ddev);
++
++ di_schedule_motor_off(ddev, DI_MOTOR_OFF_TIMEOUT);
++
++out:
++ return retval;
++}
++
++static void di_exit_irq(struct di_device *ddev)
++{
++ /* stop DVD motor */
++ di_cancel_motor_off(ddev);
++ di_spin_down_drive(ddev);
++
++ di_quiesce(ddev);
++
++ free_irq(ddev->irq, ddev);
++}
++
++static int di_init_blk_dev(struct di_device *ddev)
++{
++ struct gendisk *disk;
++ struct request_queue *queue;
++ int retval;
++
++ spin_lock_init(&ddev->lock);
++ spin_lock_init(&ddev->io_lock);
++
++ ddev->ref_count = 0;
++
++ retval = register_blkdev(DI_MAJOR, DI_NAME);
++ if (retval) {
++ drv_printk(KERN_ERR, "error registering major %d\n", DI_MAJOR);
++ goto err_register_blkdev;
++ }
++
++ retval = -ENOMEM;
++ spin_lock_init(&ddev->queue_lock);
++ queue = blk_init_queue(di_do_request, &ddev->queue_lock);
++ if (!queue) {
++ drv_printk(KERN_ERR, "error initializing queue\n");
++ goto err_blk_init_queue;
++ }
++
++ blk_queue_hardsect_size(queue, DI_SECTOR_SIZE);
++ blk_queue_dma_alignment(queue, DI_DMA_ALIGN);
++ blk_queue_max_phys_segments(queue, 1);
++ blk_queue_max_hw_segments(queue, 1);
++ queue->queuedata = ddev;
++ ddev->queue = queue;
++
++ disk = alloc_disk(1);
++ if (!disk) {
++ drv_printk(KERN_ERR, "error allocating disk\n");
++ goto err_alloc_disk;
++ }
++
++ disk->major = DI_MAJOR;
++ disk->first_minor = 0;
++ disk->fops = &di_fops;
++ strcpy(disk->disk_name, DI_NAME);
++ disk->queue = ddev->queue;
++ disk->private_data = ddev;
++ ddev->disk = disk;
++
++ set_disk_ro(ddev->disk, 1);
++ add_disk(ddev->disk);
++
++ retval = 0;
++ goto out;
++
++err_alloc_disk:
++ blk_cleanup_queue(ddev->queue);
++err_blk_init_queue:
++ unregister_blkdev(DI_MAJOR, DI_NAME);
++err_register_blkdev:
++out:
++ return retval;
++}
++
++static void di_exit_blk_dev(struct di_device *ddev)
++{
++ if (ddev->disk) {
++ del_gendisk(ddev->disk);
++ put_disk(ddev->disk);
++ }
++ if (ddev->queue)
++ blk_cleanup_queue(ddev->queue);
++ unregister_blkdev(DI_MAJOR, DI_NAME);
++}
++
++static int di_init_proc(struct di_device *ddev)
++{
++#ifdef CONFIG_PROC_FS
++#endif /* CONFIG_PROC_FS */
++ return 0;
++}
++
++static void di_exit_proc(struct di_device *ddev)
++{
++#ifdef CONFIG_PROC_FS
++#endif /* CONFIG_PROC_FS */
++}
++
++static int di_init(struct di_device *ddev, struct resource *mem, int irq)
++{
++ int retval;
++
++ ddev->io_base = ioremap(mem->start, mem->end - mem->start + 1);
++ ddev->irq = irq;
++
++ retval = di_init_blk_dev(ddev);
++ if (!retval) {
++ retval = di_init_irq(ddev);
++ if (retval)
++ di_exit_blk_dev(ddev);
++ else
++ di_init_proc(ddev);
++ }
++ return retval;
++}
++
++static void di_exit(struct di_device *ddev)
++{
++ di_exit_blk_dev(ddev);
++ di_exit_irq(ddev);
++ di_exit_proc(ddev);
++ if (ddev->io_base) {
++ iounmap(ddev->io_base);
++ ddev->io_base = NULL;
++ }
++}
++
++/*
++ * Driver model helper routines.
++ *
++ */
++
++static int di_do_probe(struct device *dev,
++ struct resource *mem, int irq)
++{
++ struct di_device *ddev;
++ int retval;
++
++ ddev = kzalloc(sizeof(*ddev), GFP_KERNEL);
++ if (!ddev) {
++ drv_printk(KERN_ERR, "failed to allocate di_device\n");
++ return -ENOMEM;
++ }
++ dev_set_drvdata(dev, ddev);
++ ddev->dev = dev;
++
++ retval = di_init(ddev, mem, irq);
++ if (retval) {
++ dev_set_drvdata(dev, NULL);
++ kfree(ddev);
++ }
++ return retval;
++}
++
++static int di_do_remove(struct device *dev)
++{
++ struct di_device *ddev = dev_get_drvdata(dev);
++
++ if (ddev) {
++ di_exit(ddev);
++ dev_set_drvdata(dev, NULL);
++ kfree(ddev);
++ return 0;
++ }
++ return -ENODEV;
++}
++
++static int di_do_shutdown(struct device *dev)
++{
++ struct di_device *ddev = dev_get_drvdata(dev);
++
++ if (ddev)
++ di_quiesce(ddev);
++ return 0;
++}
++
++/*
++ * OF platform driver hooks.
++ *
++ */
++
++static int __init di_of_probe(struct of_device *odev,
++ const struct of_device_id *match)
++{
++ struct resource res;
++ int retval;
++
++ retval = of_address_to_resource(odev->node, 0, &res);
++ if (retval) {
++ drv_printk(KERN_ERR, "no io memory range found\n");
++ return -ENODEV;
++ }
++
++ return di_do_probe(&odev->dev,
++ &res, irq_of_parse_and_map(odev->node, 0));
++}
++
++static int __exit di_of_remove(struct of_device *odev)
++{
++ return di_do_remove(&odev->dev);
++}
++
++static int di_of_shutdown(struct of_device *odev)
++{
++ return di_do_shutdown(&odev->dev);
++}
++
++
++static struct of_device_id di_of_match[] = {
++ { .compatible = "nintendo,flipper-disk" },
++ { },
++};
++
++MODULE_DEVICE_TABLE(of, di_of_match);
++
++static struct of_platform_driver di_of_driver = {
++ .owner = THIS_MODULE,
++ .name = DRV_MODULE_NAME,
++ .match_table = di_of_match,
++ .probe = di_of_probe,
++ .remove = di_of_remove,
++ .shutdown = di_of_shutdown,
++};
++
++/*
++ * Module interface hooks.
++ *
++ */
++
++static int __init di_init_module(void)
++{
++ drv_printk(KERN_INFO, "%s - version %s\n", DRV_DESCRIPTION,
++ di_driver_version);
++
++ return of_register_platform_driver(&di_of_driver);
++}
++
++static void __exit di_exit_module(void)
++{
++ of_unregister_platform_driver(&di_of_driver);
++}
++
++module_init(di_init_module);
++module_exit(di_exit_module);
++
++MODULE_AUTHOR(DRV_AUTHOR);
++MODULE_DESCRIPTION(DRV_DESCRIPTION);
++MODULE_LICENSE("GPL");
+diff --git a/drivers/block/gcn-dvd/Makefile b/drivers/block/gcn-dvd/Makefile
+new file mode 100644
+index 0000000..1f3ebca
+--- /dev/null
++++ b/drivers/block/gcn-dvd/Makefile
+@@ -0,0 +1,3 @@
++obj-$(CONFIG_GAMECUBE_DVD) := gcn-dvd.o
++
++gcn-dvd-objs := main.o request.o
+diff --git a/drivers/block/gcn-dvd/main.c b/drivers/block/gcn-dvd/main.c
+new file mode 100644
+index 0000000..d07333e
+--- /dev/null
++++ b/drivers/block/gcn-dvd/main.c
+@@ -0,0 +1,810 @@
++/*
++ * drivers/block/gcn-dvd/main.c
++ *
++ * Nintendo GameCube DVD driver
++ * Copyright (C) 2005 The GameCube Linux Team
++ *
++ * 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/major.h>
++#include <linux/vmalloc.h>
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/blkdev.h>
++#include <linux/delay.h>
++#include <linux/cdrom.h>
++#include <linux/wait.h>
++#include <asm/setup.h>
++#include <asm/bitops.h>
++#include <asm/pgtable.h>
++#include <asm/cacheflush.h>
++#include <asm/cache.h>
++#include <linux/interrupt.h>
++#include <linux/dma-mapping.h>
++
++#include <linux/fcntl.h> /* O_ACCMODE */
++#include <linux/hdreg.h> /* HDIO_GETGEO */
++
++#include <asm/io.h>
++
++#include "request.h"
++
++#define DEVICE_NAME "DVD"
++#define DVD_MAJOR 60
++
++#define LINUX_SECTOR_SIZE 512
++#define LINUX_SECTOR_SHIFT 9
++#define DVD_SECTOR_SIZE 2048
++#define DVD_SECTOR_SHIFT 11
++#define DVD_MAX_SECTORS 712880
++
++#define DMA_ALIGNMENT_MASK 0x1F
++
++#define DVD_REGISTER_INIT ((void* __iomem)0xCC003024)
++
++#define DVD_REGISTER_BLOCK_BASE 0xCC006000
++#define DVD_REGISTER_BLOCK_LENGTH 0x40
++
++#define DVD_GAMECODE_U32 0x80000000 /* Gamecode */
++#define DVD_COMPANY_U16 0x80000004 /* Game company id */
++#define DVD_DISK_ID_U8 0x80000006 /* Disk id */
++#define DVD_DISK_VERSION_U8 0x80000007 /* Disk version */
++
++#define DVD_IRQ 2
++
++/* DI Status Register */
++#define DI_DISR ((void * __iomem)0xCC006000)
++#define DI_DISR_BRKINT (1<<6)
++#define DI_DISR_BRKINTMASK (1<<5)
++#define DI_DISR_TCINT (1<<4)
++#define DI_DISR_TCINTMASK (1<<3)
++#define DI_DISR_DEINT (1<<2)
++#define DI_DISR_DEINTMASK (1<<1)
++#define DI_DISR_BRK (1<<0)
++
++/* DI Cover Register */
++#define DI_DICVR ((void * __iomem)0xCC006004)
++#define DI_DICVR_CVRINT (1<<2)
++#define DI_DICVR_CVRINTMASK (1<<1)
++#define DI_DICVR_CVR (1<<0)
++
++/* DI Command Buffer 0 */
++#define DI_DICMDBUF0 ((void * __iomem)0xCC006008)
++#define DI_DICMDBUF0_CMD 24
++#define DI_DICMDBUF0_SUBCMD1 16
++#define DI_DICMDBUF0_SUBCMD2 0
++
++/* DI Command Buffer 1 */
++#define DI_DICMDBUF1 ((void * __iomem)0xCC00600C)
++
++/* DI Command Buffer 2 */
++#define DI_DICMDBUF2 ((void * __iomem)0xCC006010)
++
++/* DMA Memory Address Register */
++#define DI_DIMAR ((void * __iomem)0xCC006014)
++
++/* DI DMA Transfer Length Register */
++#define DI_DILENGTH ((void * __iomem)0xCC006018)
++
++/* DI Control Register */
++#define DI_DICR ((void * __iomem)0xCC00601C)
++#define DI_DICR_RW (1<<2)
++#define DI_DICR_DMA (1<<1)
++#define DI_DICR_TSTART (1<<0)
++
++/* DI Immediate Data Buffer */
++#define DI_DIIMMBUF ((void * __iomem)0xCC006020)
++
++#define DI_CMD_REZERO 0x01
++#define DI_CMD_INQUIRY 0x12
++#define DI_CMD_READ 0xA8
++#define DI_CMD_SEEK 0xAB
++#define DI_CMD_READTOC 0x43
++#define DI_CMD_STOP 0xE3
++/* This is a fake command, don't send to the hardware */
++#define DI_CMD_INITIALIZE 0xFF
++
++#define IS_CMD_TYPE(cmd,type) (((cmd) >> DI_DICMDBUF0_CMD) == (type))
++
++static struct gendisk *dvd_gendisk;
++static struct request_queue *dvd_queue;
++static spinlock_t dvd_queue_lock = SPIN_LOCK_UNLOCKED;
++static struct _taginterrupt_queue
++{
++ spinlock_t lock;
++ int drive_initialized;
++ struct list_head queue;
++} interrupt_queue;
++
++static struct _tagdvdinfo {
++ spinlock_t lock;
++ unsigned long refCount;
++ unsigned int media_changed;
++ unsigned long numDVDSectors;
++ unsigned long numLinuxSectors;
++
++ /* disc info */
++ struct _tagdvdid
++ {
++ u32 gamecode;
++ u16 company;
++ u8 id;
++ u8 version;
++ } disc;
++} dvd_info;
++
++#define LOCK(flags) spin_lock_irqsave(&dvd_info.lock,flags)
++#define UNLOCK(flags) spin_unlock_irqrestore(&dvd_info.lock,flags)
++
++/* Must be 0x20 in size = 32 bytes */
++#pragma pack(1)
++
++struct gc_dvd_drive_info
++{
++ u32 head;
++ u32 middle;
++ u32 last;
++ u8 padding[20];
++};
++
++struct gc_dvd_disc_info
++{
++ u16 revision;
++ u16 device_code;
++ u32 release_date;
++ u8 padding[24];
++};
++
++#pragma pack()
++
++struct dma_buffer
++{
++ size_t size;
++ void *ptr;
++ void *alignedPtr;
++ dma_addr_t handle;
++};
++
++#ifdef DEBUG
++#define DPRINTK(fmt,args...) printk(KERN_INFO "%s (%u): " fmt,__FUNCTION__,__LINE__,## args)
++#else
++#define DPRINTK(fmt,args...)
++#endif
++
++static int alloc_dma_buffer(size_t size,struct dma_buffer *pRet)
++{
++ /* allocate space for the aligned memory */
++ pRet->size = DMA_ALIGNMENT_MASK + size;
++ if (!(pRet->ptr = kmalloc(pRet->size,GFP_KERNEL | GFP_DMA))) {
++ DPRINTK("Cannot allocate DMA memory of size %i\n",pRet->size);
++ return -ENOMEM;
++ }
++
++ /* align the pointer */
++ if ((unsigned long)pRet->ptr & DMA_ALIGNMENT_MASK) {
++ pRet->alignedPtr = (void*)(((unsigned long)pRet->ptr + DMA_ALIGNMENT_MASK) & ~DMA_ALIGNMENT_MASK);
++ /* adjust the size if not aligned */
++ pRet->size -= (pRet->alignedPtr - pRet->ptr);
++ }
++ else {
++ pRet->alignedPtr = pRet->ptr;
++ }
++ /* get the dma mapping */
++ pRet->handle = virt_to_phys(pRet->alignedPtr);
++ return 0;
++}
++
++inline static void sync_dma_buffer(struct dma_buffer *pRet)
++{
++ __dma_sync(pRet->alignedPtr, pRet->size, DMA_FROM_DEVICE);
++}
++
++inline static void free_dma_buffer(struct dma_buffer *pRet)
++{
++ kfree(pRet->ptr);
++}
++
++/* hardware talk */
++static void gc_dvd_enable_interrupts(int enable)
++{
++ unsigned long outval;
++ /* enable main interrupts */
++ if (enable) {
++ outval = DI_DISR_BRKINT | DI_DISR_TCINT | DI_DISR_DEINT |
++ DI_DISR_BRKINTMASK | DI_DISR_TCINTMASK | DI_DISR_DEINTMASK;
++ }
++ else {
++ outval = DI_DISR_BRKINT | DI_DISR_TCINT | DI_DISR_DEINT;
++ }
++
++ writel(outval,DI_DISR);
++
++ /* This enables cover interrupts */
++ if (enable) {
++ outval = DI_DICVR_CVRINT | DI_DICVR_CVRINTMASK;
++ }
++ else {
++ outval = DI_DICVR_CVRINT;
++ }
++
++ writel(outval,DI_DICVR);
++}
++
++static void gc_dvd_execute_queue_command(struct gc_dvd_command *cmd)
++{
++ u32 val;
++ /* if they're doing a read and the drive is not initialized */
++ if (!interrupt_queue.drive_initialized &&
++ IS_CMD_TYPE(cmd->r_DI_DICMDBUF0,DI_CMD_READ)) {
++ /* insert an initialize queue item BEFORE this one */
++ static struct gc_dvd_command init_cmd = {
++ .r_DI_DICMDBUF0 = DI_CMD_INITIALIZE << DI_DICMDBUF0_CMD,
++ .completion_routine = NULL,
++ .param = NULL,
++ };
++
++ /* insert before this item */
++ list_add_tail(&init_cmd.list,&cmd->list);
++ /* now execute the initialize routine */
++ val = (readl(DVD_REGISTER_INIT) & ~4) | 1;
++ writel(val,DVD_REGISTER_INIT);
++ udelay(100);
++ val |= (4 | 1);
++ writel(val,DVD_REGISTER_INIT);
++ udelay(100);
++ /* it will return an interrupt when we're done, our
++ queue item will pick it up */
++ }
++ else if (cmd) {
++ writel(cmd->r_DI_DICMDBUF0,DI_DICMDBUF0);
++ writel(cmd->r_DI_DICMDBUF1,DI_DICMDBUF1);
++ writel(cmd->r_DI_DICMDBUF2,DI_DICMDBUF2);
++ writel((unsigned long)cmd->r_DI_DIMAR,DI_DIMAR);
++ writel(cmd->r_DI_DILENGTH,DI_DILENGTH);
++ writel(cmd->r_DI_DICR,DI_DICR);
++ }
++}
++
++static int gc_dvd_queue_command(struct gc_dvd_command *cmd)
++{
++ unsigned long flags;
++ int execute_immediately;
++
++ spin_lock_irqsave(&interrupt_queue.lock,flags);
++
++ cmd->int_status = is_still_running;
++ /* add to the tail of the list */
++ execute_immediately = list_empty(&interrupt_queue.queue);
++
++ list_add_tail(&cmd->list,&interrupt_queue.queue);
++
++ if (execute_immediately) {
++ gc_dvd_execute_queue_command(cmd);
++ }
++ /* release lock so interrupt handler can get it */
++ spin_unlock_irqrestore(&interrupt_queue.lock,flags);
++ return 0;
++}
++
++/* This function is called from an IRQ context, we just wake up the queue */
++static void gc_dvd_queue_completion_wake_up(struct gc_dvd_command *cmd)
++{
++ wake_up_interruptible(((wait_queue_head_t*)cmd->param));
++}
++
++static int gc_dvd_execute_blocking_command(unsigned int di_cmd,unsigned int sz,struct dma_buffer *buf)
++{
++ struct gc_dvd_command cmd;
++ wait_queue_head_t wait_queue;
++
++ if ((sz > 0) && alloc_dma_buffer(sz,buf)) {
++ return -ENOMEM;
++ }
++
++ init_waitqueue_head(&wait_queue);
++
++ cmd.flags = 0;
++ cmd.r_DI_DICMDBUF0 = di_cmd;
++ cmd.r_DI_DICMDBUF1 = 0;
++ cmd.r_DI_DICMDBUF2 = sz;
++ cmd.r_DI_DIMAR = (sz > 0) ? (void*)buf->handle : NULL;
++ cmd.r_DI_DILENGTH = sz;
++ cmd.r_DI_DICR = DI_DICR_TSTART | ((sz > 0) ? DI_DICR_DMA : 0);
++ cmd.completion_routine = gc_dvd_queue_completion_wake_up;
++ cmd.param = &wait_queue;
++
++ gc_dvd_queue_command(&cmd);
++ /* wait for it to finish */
++ while (wait_event_interruptible(wait_queue,cmd.int_status !=
++ is_still_running)) ;
++
++ return cmd.int_status;
++}
++
++static inline void gc_dvd_stop_motor(void)
++{
++ gc_dvd_execute_blocking_command(DI_CMD_STOP << DI_DICMDBUF0_CMD,0,NULL);
++}
++
++static int gc_dvd_inquiry(void)
++{
++
++ /* get status on disk */
++ struct dma_buffer buf;
++ struct gc_dvd_drive_info *pdi;
++ int is;
++
++ is = gc_dvd_execute_blocking_command(DI_CMD_INQUIRY << DI_DICMDBUF0_CMD,
++ sizeof(struct gc_dvd_drive_info),
++ &buf);
++ if (is == -ENOMEM) {
++ return is;
++ }
++ else if (is != is_transfer_complete) {
++ printk(KERN_ERR "Gamecube DVD: error in inquiry cmd\n");
++ is = -ENODEV;
++ }
++ else {
++ sync_dma_buffer(&buf);
++
++ pdi = (struct gc_dvd_drive_info*)buf.alignedPtr;
++ printk(KERN_INFO "Gamecube DVD: 0x%x, 0x%x,0x%x\n",pdi->head,pdi->middle,pdi->last);
++
++ is = 0;
++ }
++
++ free_dma_buffer(&buf);
++ return is;
++}
++
++static int gc_dvd_read_toc(void)
++{
++ struct dma_buffer buf;
++ struct gc_dvd_disc_info *pdi;
++ int i;
++
++ i = gc_dvd_execute_blocking_command(DI_CMD_READ << DI_DICMDBUF0_CMD | 0x40,
++ sizeof(struct gc_dvd_disc_info),
++ &buf);
++ if (i != is_transfer_complete) {
++ dvd_info.numDVDSectors = 0;
++
++ if (i != -ENOMEM) {
++ free_dma_buffer(&buf);
++ }
++ else {
++ i = -ENOMEDIUM;
++ }
++
++ printk(KERN_ERR "Gamecube DVD: error reading TOC - missing medium?\n");
++ }
++ else {
++ sync_dma_buffer(&buf);
++
++ pdi = (struct gc_dvd_disc_info*)buf.alignedPtr;
++ printk(KERN_INFO "Gamecube DVD: revision: %u, device_code %u, release_date: %u\n",pdi->revision,pdi->device_code,pdi->release_date);
++
++ dvd_info.numDVDSectors = DVD_MAX_SECTORS;
++ /* reset media_changed flag */
++ dvd_info.media_changed = 0;
++
++ free_dma_buffer(&buf);
++
++ i = 0;
++ }
++ /* inform the kernel of the size */
++ dvd_info.numLinuxSectors = dvd_info.numDVDSectors << (DVD_SECTOR_SHIFT - LINUX_SECTOR_SHIFT);
++ set_capacity(dvd_gendisk,dvd_info.numLinuxSectors);
++ return i;
++}
++
++/* Handlers */
++static int gc_dvd_revalidate(struct gendisk *disk)
++{
++ gc_dvd_read_toc();
++ return 0;
++}
++
++static int gc_dvd_open(struct inode *inode,struct file *filp)
++{
++ unsigned long flags;
++ /* we are read only */
++ if (filp->f_mode & FMODE_WRITE) {
++ return -EROFS;
++ }
++
++ /* check the disc, only allow minor of 0 to be opened */
++ if (iminor(inode)) {
++ return -ENODEV;
++ }
++
++ /* update information about the disc */
++ LOCK(flags);
++ if (dvd_info.refCount > 0) {
++ /* we only let one at a time */
++ UNLOCK(flags);
++ return -EBUSY;
++ }
++ else {
++ check_disk_change(inode->i_bdev);
++ /* revalidate should be called if necessary, check results here */
++ if (dvd_info.numDVDSectors == 0) {
++ UNLOCK(flags);
++ return -ENOMEDIUM;
++ }
++ }
++ dvd_info.refCount++;
++ UNLOCK(flags);
++ return 0;
++}
++static int gc_dvd_release(struct inode *inode,struct file *filp)
++{
++ unsigned long flags;
++
++ gc_dvd_stop_motor();
++
++ LOCK(flags);
++ dvd_info.refCount--;
++ /* force a media change so we re-read the toc and initialize the disc */
++ dvd_info.media_changed = 1;
++ UNLOCK(flags);
++ return 0;
++}
++
++static int gc_dvd_ioctl(struct inode *inode,struct file *filp,
++ unsigned int cmd,unsigned long arg)
++{
++ switch (cmd)
++ {
++ case CDROMMULTISESSION:
++ /* struct cdrom_multisession */
++ break;
++
++ case CDROMSTART:
++ break;
++
++ case CDROMSTOP:
++ break;
++
++ case CDROMREADTOCHDR:
++ /* struct cdrom_tochdr */
++ break;
++
++ case CDROMREADTOCENTRY:
++ /* struct cdrom_tocentry */
++ break;
++
++ case CDROMREADMODE2:
++ case CDROMREADMODE1:
++ case CDROMREADRAW:
++ /* struct cdrom_read (1-2048, 2-2336,RAW-2352) */
++ break;
++
++ case CDROM_GET_MCN:
++ /* retrieve the universal product code */
++ /* struct cdrom_mcn */
++ break;
++
++ case CDROMRESET:
++ /* reset the drive */
++ break;
++
++ case BLKRAGET:
++ case BLKFRAGET:
++ case BLKROGET:
++ case BLKBSZGET:
++ case BLKSSZGET:
++ case BLKSECTGET:
++ case BLKGETSIZE:
++ case BLKGETSIZE64:
++ case BLKFLSBUF:
++ return ioctl_by_bdev(inode->i_bdev,cmd,arg);
++ default:
++ return -ENOTTY;
++ }
++ return -ENOTTY;
++}
++
++static int gc_dvd_media_changed(struct gendisk *disk)
++{
++ /* return 1 if the disc has changed */
++ return (dvd_info.media_changed ? 1 : 0);
++}
++
++static void gc_dvd_read_request_callback(struct gc_dvd_command *cmd)
++{
++ unsigned long flags;
++ struct request *req = (struct request*)cmd->param;
++ struct request_queue *rqueue = req->q;
++ int status;
++
++ /* since this was performed via DMA, invalidate the cache */
++ if (cmd->int_status == is_transfer_complete) {
++ __dma_sync(req->buffer, cmd->r_DI_DILENGTH, DMA_FROM_DEVICE);
++ }
++ /* free this item so another request can get it */
++ gc_dvd_request_release_data(cmd);
++ /* now end the request and send back to block layer */
++ spin_lock_irqsave(rqueue->queue_lock,flags);
++ status = is_transfer_complete;
++ if (!end_that_request_first(req,
++ status, req->current_nr_sectors)) {
++ add_disk_randomness(req->rq_disk);
++ end_that_request_last(req, status);
++ }
++ /* start queue back up */
++ blk_start_queue(rqueue);
++ spin_unlock_irqrestore(rqueue->queue_lock,flags);
++}
++
++static void gc_dvd_do_request(request_queue_t *q)
++{
++ struct request *req;
++ unsigned long start;
++ unsigned long len;
++ struct gc_dvd_command *cmd;
++
++ while ((req = elv_next_request(q))) {
++ /* check if they are reading beyond the limits */
++ if ((req->sector + req->current_nr_sectors) > dvd_info.numLinuxSectors) {
++ printk(KERN_ERR "Gamecube DVD: reading past end\n");
++ end_request(req,0);
++ }
++ else if (rq_data_dir(req) == WRITE) {
++ printk(KERN_ERR "Gamecube DVD: write attempted\n");
++ end_request(req,0);
++ }
++ else if (dvd_info.media_changed) {
++ DPRINTK("media changed in read routine, aborting\n");
++ end_request(req,0);
++ }
++ else if (req->current_nr_sectors >= (1 << (DVD_SECTOR_SHIFT - LINUX_SECTOR_SHIFT))) {
++ /* now schedule the read */
++ if (gc_dvd_request_get_data(&cmd) || !cmd) {
++ /* we're full, stop the queue */
++ blk_stop_queue(q);
++ return;
++ }
++ else {
++ /* remove item from the queue */
++ blkdev_dequeue_request(req);
++
++ /* setup my structure */
++ start = req->sector << LINUX_SECTOR_SHIFT;
++ len = req->current_nr_sectors << LINUX_SECTOR_SHIFT;
++
++ cmd->flags = 0;
++ cmd->r_DI_DICMDBUF0 = DI_CMD_READ << DI_DICMDBUF0_CMD;
++ cmd->r_DI_DICMDBUF1 = start >> (DVD_SECTOR_SHIFT - LINUX_SECTOR_SHIFT);
++ cmd->r_DI_DICMDBUF2 = len;
++ cmd->r_DI_DIMAR = (void*)virt_to_phys(req->buffer);
++ cmd->r_DI_DILENGTH = len;
++ cmd->r_DI_DICR = DI_DICR_TSTART | DI_DICR_DMA;
++ cmd->completion_routine = gc_dvd_read_request_callback;
++ cmd->param = req;
++ gc_dvd_queue_command(cmd);
++ }
++ }
++ }
++}
++
++static struct block_device_operations dvd_fops =
++{
++ .owner = THIS_MODULE,
++ .open = gc_dvd_open,
++ .release = gc_dvd_release,
++ .revalidate_disk = gc_dvd_revalidate,
++ .media_changed = gc_dvd_media_changed,
++ .ioctl = gc_dvd_ioctl,
++};
++
++static irqreturn_t gc_dvd_irq_handler(int irq,void *dev_id,struct pt_regs *regs)
++{
++ unsigned int reason;
++ unsigned long flags;
++ struct gc_dvd_command *cur_item;
++#define REASON_FLAG_COVER 0x80000000
++ /* try the main status */
++ if ((reason=readl(DI_DISR)) & (DI_DISR_BRKINT | DI_DISR_TCINT | DI_DISR_DEINT)) {
++ /* acknowledge the interrupt */
++ writel(reason | DI_DISR_BRKINT | DI_DISR_TCINT | DI_DISR_DEINT,DI_DISR);
++ }
++ else if ((reason=readl(DI_DICVR)) & (DI_DICVR_CVRINT)) {
++ /* acknowlegde the interrupt */
++ writel(reason | DI_DICVR_CVRINT,DI_DICVR);
++ /* set media changed flag */
++ if (!(reason & DI_DICVR_CVR)) {
++ dvd_info.media_changed = 1;
++ }
++ /* set flag to be used later on */
++ reason |= REASON_FLAG_COVER;
++ }
++ else {
++ /* not for us, get out of here */
++ return IRQ_NONE;
++ }
++ /* ok we have an interrupt, now process our queue */
++ /* lock our structure */
++ spin_lock_irqsave(&interrupt_queue.lock,flags);
++ /* now look at our structure and call appropriate callback if necessary */
++ if (!list_empty(&interrupt_queue.queue)) {
++ /* first unlink the queue item */
++ cur_item = (struct gc_dvd_command*)interrupt_queue.queue.next;
++ list_del(&cur_item->list);
++ /* do special checks on the command type to keep track of drive state */
++ if (IS_CMD_TYPE(cur_item->r_DI_DICMDBUF0,DI_CMD_STOP)) {
++ interrupt_queue.drive_initialized = 0;
++ }
++ else if (IS_CMD_TYPE(cur_item->r_DI_DICMDBUF0,DI_CMD_INITIALIZE)) {
++ interrupt_queue.drive_initialized = 1;
++ }
++ /* now execute the next request if we have one */
++ if (!list_empty(&interrupt_queue.queue)) {
++ gc_dvd_execute_queue_command((struct gc_dvd_command*)
++ interrupt_queue.queue.next);
++ }
++ /* unlock the lock */
++ spin_unlock_irqrestore(&interrupt_queue.lock,flags);
++ /* determine the correct interrupt status */
++ if (reason & REASON_FLAG_COVER) {
++ if (reason & DI_DICVR_CVR) {
++ cur_item->int_status = is_cover_opened;
++ }
++ else {
++ cur_item->int_status = is_cover_closed;
++ }
++ }
++ else if (reason & DI_DISR_TCINT) {
++ cur_item->int_status = is_transfer_complete;
++ }
++ else if (reason & DI_DISR_DEINT) {
++ cur_item->int_status = is_error;
++ }
++ else if (reason & DI_DISR_BRKINT) {
++ cur_item->int_status = is_break;
++ }
++ /* call the callback */
++ if (cur_item->completion_routine) {
++ cur_item->completion_routine(cur_item);
++ }
++ }
++ else {
++ spin_unlock_irqrestore(&interrupt_queue.lock,flags);
++ DPRINTK("Received interrupt but nothing was waiting for it\n");
++ }
++
++ return IRQ_HANDLED;
++}
++
++static int __init gc_dvd_init(void)
++{
++ int ret;
++
++ printk(KERN_INFO "Gamecube DVD driver: init\n");
++
++ /* initialize the refcount */
++ memset(&dvd_info,0,sizeof(dvd_info));
++ dvd_info.media_changed = 1;
++
++ /* initialize the interrupt_queue */
++ spin_lock_init(&interrupt_queue.lock);
++ interrupt_queue.drive_initialized = 0;
++ INIT_LIST_HEAD(&interrupt_queue.queue);
++
++ spin_lock_init(&dvd_info.lock);
++
++ /* initial the request queue */
++ gc_dvd_request_init();
++ /* first reserve our memory region to we can query hardware */
++ if (check_mem_region(DVD_REGISTER_BLOCK_BASE,DVD_REGISTER_BLOCK_LENGTH) ||
++ !request_mem_region(DVD_REGISTER_BLOCK_BASE,DVD_REGISTER_BLOCK_LENGTH,"Gamecube DVD")) {
++ printk(KERN_ERR "Couldn't reserve memory area for DVD\n");
++ return -ENOMEM;
++ }
++
++ if ((ret=request_irq(DVD_IRQ,gc_dvd_irq_handler,SA_INTERRUPT,"Gamecube DVD",0))) {
++ printk(KERN_ERR "Unable to reserve DVD IRQ\n");
++ goto delete_mem_region;
++ }
++
++ /* enable interrupts */
++ gc_dvd_enable_interrupts(1);
++ /* query the drive first */
++ if ((ret=gc_dvd_inquiry())) {
++ goto delete_irq;
++ }
++ /* now stop the dvd motor */
++ gc_dvd_stop_motor();
++
++ if ((ret=register_blkdev(DVD_MAJOR,DEVICE_NAME))) {
++ goto delete_irq;
++ }
++
++ if (!(dvd_gendisk = alloc_disk(1))) {
++ ret = -ENOMEM;
++ goto unreg_blkdev;
++ }
++
++ if (!(dvd_queue = blk_init_queue(gc_dvd_do_request,&dvd_queue_lock))) {
++ ret = -ENOMEM;
++ goto delete_gendisk;
++ }
++
++ dvd_gendisk->major = DVD_MAJOR;
++ dvd_gendisk->first_minor = 0;
++ dvd_gendisk->fops = &dvd_fops;
++ strcpy(dvd_gendisk->disk_name,"dvd");
++
++ dvd_gendisk->queue = dvd_queue;
++
++ /* ok now setup the desired parameters, like block size, hardsect size,
++ max hardware sectors to read at once, read ahead, etc */
++ /* Hardware sector size */
++ blk_queue_hardsect_size(dvd_queue,DVD_SECTOR_SIZE);
++ /* Maximum sectors that can be read per request, hardware limit */
++ blk_queue_max_phys_segments(dvd_queue,1);
++ blk_queue_max_hw_segments(dvd_queue,1);
++ /* Max size of coalesced segment */
++ /* blk_queue_max_segment_size(dvd_queue,size); */
++ /* Set the dma alignment */
++ blk_queue_dma_alignment(dvd_queue,DMA_ALIGNMENT_MASK);
++
++ set_disk_ro(dvd_gendisk,1);
++ add_disk(dvd_gendisk);
++
++ return 0;
++
++ delete_gendisk:
++ del_gendisk(dvd_gendisk);
++ put_disk(dvd_gendisk);
++ dvd_gendisk = NULL;
++ unreg_blkdev:
++ unregister_blkdev(DVD_MAJOR,DEVICE_NAME);
++ delete_irq:
++ free_irq(DVD_IRQ,0);
++ delete_mem_region:
++ release_mem_region(DVD_REGISTER_BLOCK_BASE,DVD_REGISTER_BLOCK_LENGTH);
++ return ret;
++}
++
++static void __exit gc_dvd_exit(void)
++{
++ printk(KERN_INFO "Gamecube DVD driver: exit\n");
++
++ /* TODO send a break/interrupt to the device */
++ gc_dvd_stop_motor();
++ gc_dvd_enable_interrupts(0);
++
++ free_irq(DVD_IRQ, 0);
++
++ release_mem_region(DVD_REGISTER_BLOCK_BASE,DVD_REGISTER_BLOCK_LENGTH);
++
++ blk_unregister_region(MKDEV(DVD_MAJOR,0),256);
++ unregister_blkdev(DVD_MAJOR,DEVICE_NAME);
++
++ if (dvd_gendisk) {
++ del_gendisk(dvd_gendisk);
++ put_disk(dvd_gendisk);
++
++ dvd_gendisk = NULL;
++ }
++
++ if (dvd_queue) {
++ blk_cleanup_queue(dvd_queue);
++
++ dvd_queue = NULL;
++ }
++}
++
++MODULE_AUTHOR("Scream|CT");
++MODULE_DESCRIPTION("Gamecube DVD driver");
++MODULE_LICENSE("GPL");
++
++module_init(gc_dvd_init);
++module_exit(gc_dvd_exit);
+diff --git a/drivers/block/gcn-dvd/request.c b/drivers/block/gcn-dvd/request.c
+new file mode 100644
+index 0000000..19203e3
+--- /dev/null
++++ b/drivers/block/gcn-dvd/request.c
+@@ -0,0 +1,70 @@
++/*
++ * drivers/block/gcn-dvd/request.c
++ *
++ * Nintendo GameCube DVD driver
++ * Copyright (C) 2005 The GameCube Linux Team
++ *
++ * 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/types.h>
++#include <linux/errno.h>
++#include <linux/list.h>
++#include <linux/spinlock.h>
++#include "request.h"
++
++struct data_item
++{
++ struct list_head list;
++ struct gc_dvd_command data;
++};
++
++// define array of data items
++static struct data_item data[MAX_ITEMS];
++static spinlock_t lock;
++static struct list_head lfree;
++
++void gc_dvd_request_init(void)
++{
++ int i;
++
++ INIT_LIST_HEAD(&lfree);
++ spin_lock_init(&lock);
++
++ for (i=0;i<MAX_ITEMS;++i) {
++ list_add_tail(&data[i].list,&lfree);
++ }
++}
++
++int gc_dvd_request_get_data(struct gc_dvd_command **ppcmd)
++{
++ unsigned long flags;
++ struct data_item *pdi;
++ // get the first object and remove from the free list
++ spin_lock_irqsave(&lock,flags);
++ if (list_empty(&lfree)) {
++ spin_unlock_irqrestore(&lock,flags);
++ return -ENOMEM;
++ }
++ pdi = (struct data_item*)lfree.next;
++ list_del(&pdi->list);
++ spin_unlock_irqrestore(&lock,flags);
++ // return it
++ *ppcmd = &pdi->data;
++ return 0;
++}
++
++void gc_dvd_request_release_data(struct gc_dvd_command *pcmd)
++{
++ unsigned long flags;
++ struct data_item *pdi;
++ /* return the item */
++ spin_lock_irqsave(&lock,flags);
++ pdi = (struct data_item*)((u8*)pcmd - sizeof(struct list_head));
++ list_add_tail(&pdi->list,&lfree);
++ spin_unlock_irqrestore(&lock,flags);
++}
+diff --git a/drivers/block/gcn-dvd/request.h b/drivers/block/gcn-dvd/request.h
+new file mode 100644
+index 0000000..f0fdd0b
+--- /dev/null
++++ b/drivers/block/gcn-dvd/request.h
+@@ -0,0 +1,45 @@
++/*
++ * drivers/block/gcn-dvd/request.h
++ *
++ * Nintendo GameCube DVD driver
++ * Copyright (C) 2005 The GameCube Linux Team
++ *
++ * 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.
++ *
++ */
++
++#ifndef __request___
++#define __request___
++
++#define MAX_ITEMS 8
++
++enum gc_dvd_interrupt_status { is_still_running,
++ is_transfer_complete,
++ is_error,
++ is_break,
++ is_cover_closed,
++ is_cover_opened};
++
++struct gc_dvd_command
++{
++ struct list_head list;
++ u32 flags;
++ enum gc_dvd_interrupt_status int_status;
++ u32 r_DI_DICMDBUF0;
++ u32 r_DI_DICMDBUF1;
++ u32 r_DI_DICMDBUF2;
++ void *r_DI_DIMAR;
++ u32 r_DI_DILENGTH;
++ u32 r_DI_DICR;
++ void *param;
++ void (*completion_routine)(struct gc_dvd_command *cmd);
++};
++
++void gc_dvd_request_init(void);
++int gc_dvd_request_get_data(struct gc_dvd_command **ppcmd);
++void gc_dvd_request_release_data(struct gc_dvd_command *pcmd);
++
++#endif
+diff --git a/drivers/block/gcn-memcard.c b/drivers/block/gcn-memcard.c
+new file mode 100644
+index 0000000..e14e614
+--- /dev/null
++++ b/drivers/block/gcn-memcard.c
+@@ -0,0 +1,569 @@
++/*
++ * drivers/block/gcn-memcard.c
++ *
++ * Nintendo GameCube Memory Card block driver
++ * Copyright (C) 2004 The GameCube Linux Team
++ *
++ * Based on work from Torben Nielsen.
++ *
++ * 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.
++ *
++ */
++#define DEVICE_NAME "memcard"
++
++#include <linux/major.h>
++#include <linux/vmalloc.h>
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/blkdev.h>
++#include <linux/delay.h>
++#include <linux/interrupt.h>
++#include <linux/fcntl.h> /* O_ACCMODE */
++#include <linux/hdreg.h> /* HDIO_GETGEO */
++
++#include <linux/exi.h>
++
++#include <asm/setup.h>
++#include <asm/bitops.h>
++#include <asm/pgtable.h>
++#include <asm/cacheflush.h>
++
++#define MEMCARD_MAX_UNITS 2
++
++static int major_num = 0;
++module_param(major_num, int, 0);
++
++#define TRUE (1)
++#define FALSE (0)
++
++static int curr_card_sector[MEMCARD_MAX_UNITS] = { -1, -1 };
++static int card_sector_mask[MEMCARD_MAX_UNITS] = { 0, 0 };
++static int current_device = -1;
++static spinlock_t memcard_lock = SPIN_LOCK_UNLOCKED;
++
++
++
++static struct block_device_operations memcard_fops;
++static struct gendisk *memcard_gendisk[MEMCARD_MAX_UNITS];
++
++static unsigned char *card_sector_buffer[MEMCARD_MAX_UNITS];
++
++#define MEMCARD_READ 1
++#define MEMCARD_WRITE 0
++#define ALLOW_WRITE
++#define CARD_SECTOR_SIZE 0x2000
++
++/*#define CARD_DBG printk*/
++#define CARD_DBG(format, arg...); { }
++
++/* MemCard commands originally by Costis */
++
++
++#define CARD_FILENAME 32
++#define CARD_MAXFILES 127
++#define CARD_MAXICONS 8
++#define CARD_READSIZE 512
++#define CARD_SECTORSIZE 8192
++#define CARD_SLOTA 0
++#define CARD_SLOTB 1
++#define CARD_SYSAREA 5
++#define CARD_WRITESIZE 128
++
++
++#define EXI_CONTROL_TYPE_READ 0
++#define EXI_CONTROL_TYPE_WRITE 1
++#define EXI_STATUS0 *(unsigned long*)0xCC006800
++
++#define EXI_DMABUF0 *(unsigned long*)0xCC006804
++#define EXI_DMALEN0 *(unsigned long*)0xCC006808
++#define EXI_DMACNT0 *(unsigned long*)0xCC00680C
++
++#define EXI_CONTROL_DMA 2
++#define EXI_CONTROL_ENABLE 1
++
++static int exi_probe(unsigned long channel)
++{
++ if (*(unsigned long *) (&EXI_STATUS0 + (channel * 5)) & 0x1000)
++ return 1;
++ else
++ return 0;
++}
++
++static unsigned long exi_retrieve_id(unsigned long channel,
++ unsigned long device)
++{
++ unsigned long tID;
++
++ if (exi_probe(channel)) {
++
++ /* Select the specified EXI channel and device. */
++ exi_select(channel, device, 0);
++
++ /* Send the EXI ID command (0x0000) */
++ tID = 0;
++ exi_write(channel, (unsigned char *) &tID, 2);
++ /* Read the actual ID data (4 bytes) */
++ exi_read(channel, (unsigned char *) &tID, 4);
++ /* Deselect the selected EXI device. */
++ exi_deselect(channel);
++
++ return tID;
++ } else {
++ return 0;
++ }
++}
++
++
++/*
++ Determines if a memcard is present in the given slot.
++*/
++
++static int card_is_present(unsigned long channel)
++{
++
++ unsigned long id;
++
++ id = exi_retrieve_id(channel, 0);
++
++ if (id & 0xffff0000 || id & 3)
++ return 0;
++
++ return id;
++}
++
++
++/**
++ Channel must be from 0 to 2.
++ Buffer must be aligned to a 32-bit offset.
++ Size must be a multiple of 32 bytes.
++ Type must be either EXI_CONTROL_TYPE_READ or EXI_CONTROL_TYPE_WRITE.
++*/
++static void exi_dma(unsigned long channel, unsigned char *abuffer,
++ unsigned long size, unsigned long type)
++{
++ /* EXI DMA Operation */
++ *(unsigned long *) (&EXI_DMABUF0 + (channel * 5)) =
++ (unsigned long) abuffer & 0x3FFFFE0;
++ *(unsigned long *) (&EXI_DMALEN0 + (channel * 5)) =
++ size & 0x3FFFFE0;
++ *(unsigned long *) (&EXI_DMACNT0 + (channel * 5)) =
++ EXI_CONTROL_ENABLE | EXI_CONTROL_DMA | (type << 2);
++
++ /* Wait until the EXI DMA operation has been completed. */
++ while (*(volatile unsigned long *) (&EXI_DMACNT0 + channel * 5) &
++ EXI_CONTROL_ENABLE);
++
++ return;
++}
++
++
++static unsigned char card_read_status(unsigned long channel)
++{
++ unsigned char cbuf[4];
++
++ /* Select the specified EXI channel and device. */
++ exi_select(channel, 0, 4);
++
++ /* Send the EXI ID command (0x83xx) */
++ cbuf[0] = 0x83; /* Command Byte */
++ cbuf[1] = 0x00;
++ exi_write(channel, cbuf, 2);
++ /* Read the actual ID data (2 bytes) */
++ exi_read(channel, cbuf, 1);
++
++ /* Deselect the selected EXI device. */
++ exi_deselect(channel);
++
++ return cbuf[0];
++}
++
++static void card_read_array(unsigned long channel, unsigned char *abuf,
++ unsigned long address, unsigned long size)
++{
++ int i;
++ unsigned char cbuf[4];
++ unsigned char *bbuf = abuf;
++
++ for (i = 0; i < size / CARD_READSIZE; i++) {
++
++ /* Check if the card is ready */
++ while (!(card_read_status(channel) & 1));
++
++ /* Select the specified EXI channel and device. */
++ exi_select(channel, 0, 4);
++
++ /* Send the EXI Sector Read command (0x52xxxxxx) */
++ cbuf[0] = 0x52; /* Command Byte */
++ cbuf[1] = (address >> 17) & 0x3F;
++ cbuf[2] = (address >> 9) & 0xFF;
++ cbuf[3] = (address >> 7) & 3;
++ exi_write(channel, cbuf, 4);
++
++ cbuf[0] = address & 0x7F;
++ exi_write(channel, cbuf, 1);
++
++ cbuf[0] = 0;
++ cbuf[1] = 0;
++ cbuf[2] = 0;
++ cbuf[3] = 0;
++ exi_write(channel, cbuf, 4);
++
++ exi_dma(channel, bbuf, CARD_READSIZE,
++ EXI_CONTROL_TYPE_READ);
++
++ /* Deselect the selected EXI device. */
++ exi_deselect(channel);
++
++ address += CARD_READSIZE;
++ bbuf += CARD_READSIZE;
++ }
++}
++
++static void card_sector_erase(unsigned long channel, unsigned long sector)
++{
++ unsigned char cbuf[3];
++
++ /* Check if the card is ready */
++ while (!(card_read_status(channel) & 1));
++
++ /* Select the specified EXI channel and device. */
++ exi_select(channel, 0, 4);
++
++ /* Send the EXI Sector Erase command (0xF1xxxx) */
++ cbuf[0] = 0xF1; // Command Byte
++ cbuf[1] = (sector >> 17) & 0x7F;
++ cbuf[2] = (sector >> 9) & 0xFF;
++ exi_write(channel, cbuf, 3);
++
++ /* Deselect the selected EXI device. */
++ exi_deselect(channel);
++
++ /* Wait till the erase is finished */
++ while (card_read_status(channel) & 0x8000);
++}
++
++static void card_sector_program(unsigned long channel, unsigned char *abuf,
++ unsigned long address, unsigned long size)
++{
++ int i;
++ unsigned char cbuf[4];
++ unsigned char *bbuf = abuf;
++
++ for (i = 0; i < size / CARD_WRITESIZE; i++) {
++
++ /* Check if the card is ready */
++ while (!(card_read_status(channel) & 1));
++
++ /* Select the specified EXI channel and device. */
++ exi_select(channel, 0, 4);
++
++ /* Send the EXI Sector Program command (0xF2xxxxxx) */
++ cbuf[0] = 0xF2; /* Command Byte */
++ cbuf[1] = (address >> 17) & 0x3F;
++ cbuf[2] = (address >> 9) & 0xFF;
++ cbuf[3] = (address >> 7) & 3;
++ exi_write(channel, cbuf, 4);
++
++ cbuf[0] = address & 0x7F;
++ exi_write(channel, cbuf, 1);
++
++ exi_dma(channel, bbuf, CARD_WRITESIZE,
++ EXI_CONTROL_TYPE_WRITE);
++
++ /* Deselect the selected EXI device. */
++ exi_deselect(channel);
++
++ /* Wait till the write is finished */
++ while (card_read_status(channel) & 0x8000);
++
++ address += CARD_WRITESIZE;
++ bbuf += CARD_WRITESIZE;
++ }
++}
++
++/**
++ Block device handling
++ */
++
++static int memcard_buffersize(int channel)
++{
++ return card_is_present(channel) << 17;
++}
++
++static void card_flush(int channel)
++{
++ int i, mask;
++ unsigned long start = curr_card_sector[channel] * CARD_SECTOR_SIZE;
++ CARD_DBG("card_flush(%d)\n", channel);
++ if (curr_card_sector[channel] == -1)
++ return;
++ CARD_DBG("Flush channel = %d mask = %x\n", channel,
++ card_sector_mask[channel]);
++ for (i = 0, mask = ~card_sector_mask[channel]; i < 16; i++) {
++ if (mask & 1) {
++ CARD_DBG("card_flush: read block %d\n", i);
++ }
++ }
++ CARD_DBG("card_flush: writing out ch = %d, start = %08lx\n",
++ channel, start);
++ flush_dcache_range((unsigned long) card_sector_buffer[channel],
++ (unsigned long) card_sector_buffer[channel] +
++ CARD_SECTOR_SIZE);
++
++ card_sector_erase(channel, start);
++ card_sector_program(channel, card_sector_buffer[channel], start,
++ CARD_SECTOR_SIZE);
++ card_sector_mask[channel] = 0;
++ curr_card_sector[channel] = -1;
++}
++
++static void do_memcard_request(request_queue_t * q)
++{
++ struct request *req;
++ blk_stop_queue(q);
++ spin_lock(&memcard_lock);
++
++ while ((req = elv_next_request(q)) != NULL) {
++ unsigned long start = req->sector << 9;
++ unsigned long len = req->current_nr_sectors << 9;
++ int channel = req->rq_disk->first_minor;
++
++ if (start + len > memcard_buffersize(channel)) {
++ printk(KERN_ERR DEVICE_NAME
++ ": bad access: block=%lu, count=%u\n",
++ (unsigned long) req->sector,
++ req->current_nr_sectors);
++ end_request(req, 0);
++ continue;
++ }
++
++ if (rq_data_dir(req) == READ) {
++ CARD_DBG
++ ("do_memcard_request: READ(%s,%lu,%lu), channel = %d\n",
++ req->rq_disk->disk_name,
++ (unsigned long) req->sector,
++ (unsigned long) req->current_nr_sectors,
++ channel);
++
++ card_flush(channel);
++ flush_dcache_range((unsigned long) req->buffer,
++ (unsigned long) req->buffer +
++ len);
++ card_read_array(channel, req->buffer, start, len);
++ invalidate_dcache_range((unsigned long) req->
++ buffer,
++ (unsigned long) req->
++ buffer + len);
++
++ } else {
++ int i;
++ CARD_DBG
++ ("do_memcard_request: WRITE channel = %d\n",
++ channel);
++ for (i = 0; i < req->current_nr_sectors; i++) {
++ int new_card_sector =
++ (req->sector + i) >> 4;
++ int card_sector_idx =
++ (req->sector + i) & 0xf;
++ if (new_card_sector !=
++ curr_card_sector[channel]) {
++ card_flush(channel);
++ curr_card_sector[channel] =
++ new_card_sector;
++ }
++ card_sector_mask[channel] |=
++ 1 << card_sector_idx;
++ CARD_DBG("update block %d, sector %d\n",
++ card_sector_idx, new_card_sector);
++ memcpy(card_sector_buffer[channel] +
++ (card_sector_idx << 9),
++ req->buffer + (i << 9), 1 << 9);
++ if (card_sector_idx == 0xF)
++ card_flush(channel);
++ }
++ }
++
++
++ end_request(req, 1);
++ }
++
++ spin_unlock(&memcard_lock);
++ blk_start_queue(q);
++
++}
++
++
++static int memcard_open(struct inode *inode, struct file *filp)
++{
++ CARD_DBG("MEMCARD Open device\n");
++
++ int device;
++ int rc = -ENOMEM;
++
++ device = iminor(inode);
++
++ if (current_device != -1 && current_device != device) {
++ rc = -EBUSY;
++ goto err_out;
++ }
++
++ if (memcard_buffersize(device) == 0) {
++ rc = -ENODEV;
++ goto err_out;
++ }
++
++ return 0;
++
++ err_out:
++ CARD_DBG("MEMCARD Open device Error %d\n", rc);
++
++ return rc;
++
++}
++
++static int memcard_ioctl(struct inode *inode, struct file *file,
++ unsigned int cmd, unsigned long arg)
++{
++ CARD_DBG("MEMCARD IOCTL\n");
++
++ if (cmd == HDIO_GETGEO) {
++ long size;
++ struct hd_geometry geo;
++ /*
++ * get geometry: we have to fake one... trim the size to a
++ * multiple of 1024 (0.5M): tell we have 32 sectors, 32 heads,
++ * whatever cylinders.
++ */
++ size = memcard_buffersize(iminor(inode));
++ geo.heads = 32;
++ geo.sectors = 32;
++ geo.start = 0;
++ geo.cylinders = size / (geo.heads * geo.sectors);
++
++ if (copy_to_user((void *) arg, &geo, sizeof(geo)))
++ return -EFAULT;
++ return 0;
++ }
++
++ return -EINVAL;
++}
++
++static int memcard_release(struct inode *inode, struct file *filp)
++{
++ CARD_DBG("MEMCARD Close device\n");
++ card_flush(iminor(inode));
++ if (current_device == -1)
++ return 0;
++
++ return 0;
++}
++
++
++static int memcard_revalidate(struct gendisk *disk)
++{
++ CARD_DBG("MEMCARD Revalidate\n");
++ set_capacity(disk, memcard_buffersize(disk->first_minor) >> 9);
++ return 0;
++}
++
++static struct block_device_operations memcard_fops = {
++ .owner = THIS_MODULE,
++ .open = memcard_open,
++ .release = memcard_release,
++ .revalidate_disk = memcard_revalidate,
++ .ioctl = memcard_ioctl,
++};
++
++
++static struct request_queue *memcard_queue[MEMCARD_MAX_UNITS];
++
++int __init memcard_init(void)
++{
++ int ret;
++ int i;
++
++ CARD_DBG("MemCard Block Device Driver Init\n");
++
++ ret = -EBUSY;
++ major_num = register_blkdev(major_num, DEVICE_NAME);
++ if (major_num <= 0)
++ goto err;
++
++ ret = -ENOMEM;
++ for (i = 0; i < MEMCARD_MAX_UNITS; i++) {
++ memcard_gendisk[i] = alloc_disk(1);
++ if (!memcard_gendisk[i])
++ goto out_disk;
++ }
++
++ for (i = 0; i < MEMCARD_MAX_UNITS; i++) {
++ memcard_queue[i] =
++ blk_init_queue(do_memcard_request, &memcard_lock);
++ if (!memcard_queue[i])
++ goto out_queue;
++ }
++
++ for (i = 0; i < MEMCARD_MAX_UNITS; i++) {
++ memcard_gendisk[i]->major = major_num;
++ memcard_gendisk[i]->first_minor = i;
++ memcard_gendisk[i]->fops = &memcard_fops;
++ sprintf(memcard_gendisk[i]->disk_name, "memcard%d", i);
++ strcpy(memcard_gendisk[i]->devfs_name,
++ memcard_gendisk[i]->disk_name);
++
++ memcard_gendisk[i]->queue = memcard_queue[i];
++ set_capacity(memcard_gendisk[i],
++ memcard_buffersize(i) >> 9);
++
++ add_disk(memcard_gendisk[i]);
++ }
++
++ spin_lock_init(&memcard_lock);
++
++ for (i = 0; i < MEMCARD_MAX_UNITS; i++) {
++ card_sector_buffer[i] = kmalloc(CARD_SECTOR_SIZE, GFP_KERNEL);
++ }
++
++ return 0;
++
++ out_queue:
++ for (i = 0; i < MEMCARD_MAX_UNITS; i++)
++ put_disk(memcard_gendisk[i]);
++ out_disk:
++ unregister_blkdev(major_num, DEVICE_NAME);
++ err:
++ return ret;
++}
++
++
++void __exit memcard_cleanup(void)
++{
++ int i;
++ blk_unregister_region(MKDEV(major_num, 0), 256);
++ for (i = 0; i < MEMCARD_MAX_UNITS; i++) {
++ del_gendisk(memcard_gendisk[i]);
++ put_disk(memcard_gendisk[i]);
++ }
++
++ if (unregister_blkdev(major_num, DEVICE_NAME) != 0)
++ printk(KERN_ERR DEVICE_NAME
++ ": unregister of device failed\n");
++
++ for (i = 0; i < MEMCARD_MAX_UNITS; i++) {
++ blk_cleanup_queue(memcard_queue[i]);
++ kfree(card_sector_buffer[i]);
++ }
++
++
++ CARD_DBG("Removed gc_memcard\n");
++ return;
++}
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Torben Nielsen");
++module_init(memcard_init);
++module_exit(memcard_cleanup);
+diff --git a/drivers/block/gcn-sd.c b/drivers/block/gcn-sd.c
+new file mode 100644
+index 0000000..be489bc
+--- /dev/null
++++ b/drivers/block/gcn-sd.c
+@@ -0,0 +1,1709 @@
++/*
++ * drivers/block/gcn-sd.c
++ *
++ * MMC/SD card block driver for the Nintendo GameCube/Wii
++ * Copyright (C) 2004-2009 The GameCube Linux Team
++ * Copyright (C) 2004,2005 Rob Reylink
++ * Copyright (C) 2005 Todd Jeffreys
++ * Copyright (C) 2005,2006,2007,2008,2009 Albert Herranz
++ *
++ * 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 is a block device driver for the Nintendo SD Card Adapter (DOL-019)
++ * and compatible hardware.
++ * The driver has been tested with SPI-enabled MMC cards and SD cards.
++ *
++ * The following table shows the device major and minors needed to access
++ * MMC/SD cards:
++ *
++ * +------+-------------+-------+-------+
++ * | Slot | Target | Major | Minor |
++ * +======+=============+=======+=======+
++ * | A | disk | 61 | 0 |
++ * | A | partition 1 | 61 | 1 |
++ * | A | partition 2 | 61 | 2 |
++ * | A | partition 3 | 61 | 3 |
++ * | A | partition 4 | 61 | 4 |
++ * | A | partition 5 | 61 | 5 |
++ * | A | partition 6 | 61 | 6 |
++ * | A | partition 7 | 61 | 7 |
++ * +------+-------------+-------+-------+
++ * | B | disk | 61 | 8 |
++ * | B | partition 1 | 61 | 9 |
++ * | B | partition 2 | 61 | 10 |
++ * | B | partition 3 | 61 | 11 |
++ * | B | partition 4 | 61 | 12 |
++ * | B | partition 5 | 61 | 13 |
++ * | B | partition 6 | 61 | 14 |
++ * | B | partition 7 | 61 | 15 |
++ * +------+-------------+-------+-------+
++ *
++ * For example, run "mknod /dev/gcnsdb1 b 61 9" to create a device file
++ * to access the 1st partition on the card inserted in memcard slot B.
++ *
++ */
++
++#define SD_DEBUG
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/delay.h>
++#include <linux/kthread.h>
++#include <linux/major.h>
++#include <linux/blkdev.h>
++#include <linux/hdreg.h>
++#include <linux/crc-ccitt.h>
++
++/*
++ * The existing Linux MMC layer does not support SPI operation yet.
++ * Anyway, we try to recycle here some common code.
++ */
++#include <linux/mmc/host.h>
++#include <linux/mmc/card.h>
++#include <linux/mmc/mmc.h>
++#include <linux/mmc/sd.h>
++
++#include <linux/exi.h>
++
++#define DRV_MODULE_NAME "gcn-sd"
++#define DRV_DESCRIPTION "MMC/SD card block driver for the Nintendo GameCube/Wii"
++#define DRV_AUTHOR "Rob Reylink, " \
++ "Todd Jeffreys, " \
++ "Albert Herranz"
++
++static char sd_driver_version[] = "4.1i";
++
++#define sd_printk(level, format, arg...) \
++ printk(level DRV_MODULE_NAME ": " format , ## arg)
++
++#ifdef SD_DEBUG
++# define DBG(fmt, args...) \
++ printk(KERN_ERR "%s: " fmt, __func__ , ## args)
++#else
++# define DBG(fmt, args...)
++#endif
++
++
++/*
++ *
++ * EXI related definitions.
++ */
++#define SD_SLOTA_CHANNEL 0 /* EXI0xxx */
++#define SD_SLOTA_DEVICE 0 /* chip select, EXI0CSB0 */
++
++#define SD_SLOTB_CHANNEL 1 /* EXI1xxx */
++#define SD_SLOTB_DEVICE 0 /* chip select, EXI1CSB0 */
++
++#define SD_SPI_CLK 16000000
++#define SD_SPI_CLK_IDX EXI_CLK_16MHZ
++
++
++/*
++ *
++ * MMC/SD related definitions.
++ */
++
++/* cycles in 8 clock units */
++#define SD_IDLE_CYCLES 80
++#define SD_FINISH_CYCLES 8
++
++/* several times in 8 clock units */
++#define MMC_SPI_N_CR 8 /* card response time */
++
++/* data start and stop tokens */
++#define MMC_SPI_TOKEN_START_SINGLE_BLOCK_READ 0xfe
++#define MMC_SPI_TOKEN_START_MULTIPLE_BLOCK_READ 0xfe
++#define MMC_SPI_TOKEN_START_SINGLE_BLOCK_WRITE 0xfe
++#define MMC_SPI_TOKEN_START_MULTIPLE_BLOCK_WRITE 0xfc
++#define MMC_SPI_TOKEN_STOP_MULTIPLE_BLOCK_WRITE 0xfd
++
++/* data response */
++#define DR_SPI_MASK 0x1f
++#define DR_SPI_DATA_ACCEPTED 0x05
++#define DR_SPI_DATA_REJECTED_CRC_ERROR 0x0b
++#define DR_SPI_DATA_REJECTED_WRITE_ERROR 0x0d
++
++/* this is still a missing command in the current MMC framework ... */
++#define MMC_READ_OCR 58
++
++/*
++ * OCR Bit positions to 10s of Vdd mV.
++ */
++static const unsigned short mmc_ocr_bit_to_vdd[] = {
++ 150, 155, 160, 165, 170, 180, 190, 200,
++ 210, 220, 230, 240, 250, 260, 270, 280,
++ 290, 300, 310, 320, 330, 340, 350, 360
++};
++
++static const unsigned int tran_exp[] = {
++ 10000, 100000, 1000000, 10000000,
++ 0, 0, 0, 0
++};
++
++static const unsigned char tran_mant[] = {
++ 0, 10, 12, 13, 15, 20, 25, 30,
++ 35, 40, 45, 50, 55, 60, 70, 80,
++};
++
++static const unsigned int tacc_exp[] = {
++ 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000,
++};
++
++static const unsigned int tacc_mant[] = {
++ 0, 10, 12, 13, 15, 20, 25, 30,
++ 35, 40, 45, 50, 55, 60, 70, 80,
++};
++
++/*
++ *
++ * Driver settings.
++ */
++#define MMC_SHIFT 3 /* 8 partitions */
++
++#define SD_MAJOR 61
++#define SD_NAME "gcnsd"
++
++#define KERNEL_SECTOR_SHIFT 9
++#define KERNEL_SECTOR_SIZE (1 << KERNEL_SECTOR_SHIFT) /*512 */
++
++enum {
++ __SD_MEDIA_CHANGED = 0,
++ __SD_BAD_CARD,
++};
++
++
++/*
++ * Raw MMC/SD command.
++ */
++struct sd_command {
++ u8 cmd;
++ u32 arg;
++ u8 crc;
++} __attribute__ ((__packed__)); /* do not add padding, please */
++
++/*
++ * MMC/SD host.
++ *
++ * We have one host for each memory card slot. And a host can only drive a
++ * single card each time.
++ */
++struct sd_host {
++ spinlock_t lock;
++
++ int refcnt;
++ unsigned long flags;
++#define SD_MEDIA_CHANGED (1<<__SD_MEDIA_CHANGED)
++#define SD_BAD_CARD (1<<__SD_BAD_CARD)
++
++ /* card related info */
++ struct mmc_card card;
++
++ /* timeouts in 8 clock cycles */
++ unsigned long read_timeout;
++ unsigned long write_timeout;
++
++ /* operations condition register */
++ u32 ocr_avail; /* just 3.3V for the GameCube */
++ u32 ocr;
++
++ /* last card response */
++ u8 resp;
++
++ /* frequency */
++ unsigned int clock;
++ u8 exi_clock;
++
++ /* command buffer */
++ struct sd_command cmd;
++
++ spinlock_t queue_lock;
++ struct request_queue *queue;
++
++ struct gendisk *disk;
++
++ struct task_struct *io_thread;
++ struct mutex io_mutex;
++
++ struct exi_device *exi_device;
++};
++
++static void sd_kill(struct sd_host *host);
++
++
++static void sd_card_set_bad(struct sd_host *host)
++{
++ set_bit(__SD_BAD_CARD, &host->flags);
++}
++
++static int sd_card_is_bad(struct sd_host *host)
++{
++ return test_bit(__SD_BAD_CARD, &host->flags);
++}
++
++/*
++ *
++ * MMC/SD data structures manipulation.
++ */
++
++/*
++ * FIXME: use a faster method (table)
++ * (the in-kernel crc 16 (ccitt crc) tables seem not compatible with us)
++ */
++static u16 crc_xmodem_update(u16 crc, u8 data)
++{
++ int i;
++
++ crc = crc ^ ((u16) data << 8);
++
++ for (i = 0; i < 8; i++) {
++ if (crc & 0x8000)
++ crc = (crc << 1) ^ 0x1021;
++ else
++ crc <<= 1;
++ }
++
++ return crc;
++}
++
++#define UNSTUFF_BITS(resp, start, size) \
++ ({ \
++ const int __size = size; \
++ const u32 __mask = (__size < 32 ? 1 << __size : 0) - 1; \
++ const int __off = 3 - ((start) / 32); \
++ const int __shft = (start) & 31; \
++ u32 __res; \
++ \
++ __res = resp[__off] >> __shft; \
++ if (__size + __shft > 32) \
++ __res |= resp[__off-1] << ((32 - __shft) % 32); \
++ __res & __mask; \
++ })
++
++/*
++ * Given the decoded CSD structure, decode the raw CID to our CID structure.
++ */
++static void mmc_decode_cid(struct mmc_card *card)
++{
++ u32 *resp = card->raw_cid;
++
++ memset(&card->cid, 0, sizeof(struct mmc_cid));
++
++ if (mmc_card_sd(card)) {
++ card->cid.manfid = UNSTUFF_BITS(resp, 120, 8);
++ card->cid.oemid = UNSTUFF_BITS(resp, 104, 16);
++ card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8);
++ card->cid.prod_name[1] = UNSTUFF_BITS(resp, 88, 8);
++ card->cid.prod_name[2] = UNSTUFF_BITS(resp, 80, 8);
++ card->cid.prod_name[3] = UNSTUFF_BITS(resp, 72, 8);
++ card->cid.prod_name[4] = UNSTUFF_BITS(resp, 64, 8);
++ card->cid.hwrev = UNSTUFF_BITS(resp, 60, 4);
++ card->cid.fwrev = UNSTUFF_BITS(resp, 56, 4);
++ card->cid.serial = UNSTUFF_BITS(resp, 24, 32);
++ card->cid.year = UNSTUFF_BITS(resp, 12, 8);
++ card->cid.month = UNSTUFF_BITS(resp, 8, 4);
++ card->cid.year += 2000;
++ } else {
++ /*
++ * The selection of the format here is guesswork based upon
++ * information people have sent to date.
++ */
++ switch (card->csd.mmca_vsn) {
++ case 0: /* MMC v1.0 - v1.2 */
++ case 1: /* MMC v1.4 */
++ card->cid.manfid = UNSTUFF_BITS(resp, 104, 24);
++ card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8);
++ card->cid.prod_name[1] = UNSTUFF_BITS(resp, 88, 8);
++ card->cid.prod_name[2] = UNSTUFF_BITS(resp, 80, 8);
++ card->cid.prod_name[3] = UNSTUFF_BITS(resp, 72, 8);
++ card->cid.prod_name[4] = UNSTUFF_BITS(resp, 64, 8);
++ card->cid.prod_name[5] = UNSTUFF_BITS(resp, 56, 8);
++ card->cid.prod_name[6] = UNSTUFF_BITS(resp, 48, 8);
++ card->cid.hwrev = UNSTUFF_BITS(resp, 44, 4);
++ card->cid.fwrev = UNSTUFF_BITS(resp, 40, 4);
++ card->cid.serial = UNSTUFF_BITS(resp, 16, 24);
++ card->cid.month = UNSTUFF_BITS(resp, 12, 4);
++ card->cid.year = UNSTUFF_BITS(resp, 8, 4);
++ card->cid.year += 1997;
++ break;
++ case 2: /* MMC v2.0 - v2.2 */
++ case 3: /* MMC v3.1 - v3.3 */
++ card->cid.manfid = UNSTUFF_BITS(resp, 120, 8);
++ card->cid.oemid = UNSTUFF_BITS(resp, 104, 16);
++ card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8);
++ card->cid.prod_name[1] = UNSTUFF_BITS(resp, 88, 8);
++ card->cid.prod_name[2] = UNSTUFF_BITS(resp, 80, 8);
++ card->cid.prod_name[3] = UNSTUFF_BITS(resp, 72, 8);
++ card->cid.prod_name[4] = UNSTUFF_BITS(resp, 64, 8);
++ card->cid.prod_name[5] = UNSTUFF_BITS(resp, 56, 8);
++ card->cid.serial = UNSTUFF_BITS(resp, 16, 32);
++ card->cid.month = UNSTUFF_BITS(resp, 12, 4);
++ card->cid.year = UNSTUFF_BITS(resp, 8, 4);
++ card->cid.year += 1997;
++ break;
++ default:
++ sd_printk(KERN_ERR, "card has unknown MMCA"
++ " version %d\n", card->csd.mmca_vsn);
++ break;
++ }
++ }
++}
++
++/*
++ * Given a 128-bit response, decode to our card CSD structure.
++ */
++static void mmc_decode_csd(struct mmc_card *card)
++{
++ struct mmc_csd *csd = &card->csd;
++ unsigned int e, m, csd_struct;
++ u32 *resp = card->raw_csd;
++
++ /*
++ * We only understand CSD structure v1.0, v1.1 and v2.
++ * v2 has extra information in bits 15, 11 and 10.
++ */
++ csd_struct = UNSTUFF_BITS(resp, 126, 2);
++ if (csd_struct != 0 && csd_struct != 1 && csd_struct != 2) {
++ sd_printk(KERN_ERR, "unrecognised CSD structure"
++ " version %d\n", csd_struct);
++ return;
++ }
++
++ csd->mmca_vsn = UNSTUFF_BITS(resp, 122, 4);
++
++ /* TAAC */
++ m = UNSTUFF_BITS(resp, 115, 4);
++ e = UNSTUFF_BITS(resp, 112, 3);
++ csd->tacc_ns = (tacc_exp[e] * tacc_mant[m] + 9) / 10;
++
++ /* NSAC */
++ csd->tacc_clks = UNSTUFF_BITS(resp, 104, 8) * 100;
++
++ /* TRAN_SPEED */
++ m = UNSTUFF_BITS(resp, 99, 4);
++ e = UNSTUFF_BITS(resp, 96, 3);
++ csd->max_dtr = tran_exp[e] * tran_mant[m];
++
++ /* CCC */
++ csd->cmdclass = UNSTUFF_BITS(resp, 84, 12);
++
++ /* READ_BL_LEN */
++ csd->read_blkbits = UNSTUFF_BITS(resp, 80, 4);
++
++ /* C_SIZE */
++ m = UNSTUFF_BITS(resp, 62, 12);
++
++ /* C_SIZE_MULT */
++ e = UNSTUFF_BITS(resp, 47, 3);
++
++ csd->capacity = (1 + m) << (e + 2); /* in card blocks */
++}
++
++#if 0
++static void sd_print_cid(struct mmc_cid *cid)
++{
++ sd_printk(KERN_INFO,
++ "manfid = %d\n"
++ "oemid = %d\n"
++ "prod_name = %s\n"
++ "hwrev = %d\n"
++ "fwrev = %d\n"
++ "serial = %08x\n"
++ "year = %d\n"
++ "month = %d\n",
++ cid->manfid,
++ cid->oemid,
++ cid->prod_name,
++ cid->hwrev, cid->fwrev, cid->serial, cid->year, cid->month);
++}
++#endif
++
++/* */
++static inline unsigned int ms_to_cycles(unsigned int ms, unsigned int clock)
++{
++ return ms * (clock / 1000);
++}
++
++/* */
++static unsigned int sd_set_clock(struct sd_host *host, unsigned int clock)
++{
++ if (clock >= 32000000) {
++ host->clock = 32000000;
++ host->exi_clock = EXI_CLK_32MHZ;
++ } else if (clock >= 16000000) {
++ host->clock = 16000000;
++ host->exi_clock = EXI_CLK_16MHZ;
++ } else if (clock >= 8000000) {
++ host->clock = 8000000;
++ host->exi_clock = EXI_CLK_8MHZ;
++ } else if (clock >= 4000000) {
++ host->clock = 4000000;
++ host->exi_clock = EXI_CLK_4MHZ;
++ } else if (clock >= 2000000) {
++ host->clock = 2000000;
++ host->exi_clock = EXI_CLK_2MHZ;
++ } else {
++ host->clock = 1000000;
++ host->exi_clock = EXI_CLK_1MHZ;
++ }
++ return host->clock;
++}
++
++/* */
++static void sd_calc_timeouts(struct sd_host *host)
++{
++ /*
++ * FIXME: calculate timeouts from card information
++ * (use safe defaults for now)
++ */
++ host->read_timeout = ms_to_cycles(100, host->clock);
++ host->write_timeout = ms_to_cycles(250, host->clock);
++}
++
++/*
++ *
++ * SPI I/O support routines, including some handy SPI to EXI language
++ * translations.
++ */
++
++/* */
++static inline void spi_cs_low(struct sd_host *host)
++{
++ exi_dev_take(host->exi_device);
++ exi_dev_select(host->exi_device);
++}
++
++/* */
++static inline void spi_cs_high(struct sd_host *host)
++{
++ exi_dev_deselect(host->exi_device);
++ exi_dev_give(host->exi_device);
++}
++
++/* */
++static inline void spi_write(struct sd_host *host, void *data, size_t len)
++{
++ exi_dev_write(host->exi_device, data, len);
++}
++
++/* */
++static inline void spi_read(struct sd_host *host, void *data, size_t len)
++{
++ /*
++ * Houston, we have a problem.
++ *
++ * The EXI hardware implementation seems to use a shift register which
++ * outputs data from the MSB to the MOSI line and inputs data from
++ * the MISO line into the LSB.
++ * When a read operation is performed, data from the MISO line
++ * is entered into the shift register LSB as expected. But also the
++ * data already present in the shift register is sent out through the
++ * MOSI line from the MSB.
++ * This is in fact the "feature" that enabled tmbinc to dump the IPL.
++ *
++ * When interfacing with SD cards, this causes us a serious problem.
++ *
++ * We are required to send all ones (1s) while reading data from
++ * the SD card. Otherwise, the card can interpret the data sent as
++ * commands (if they start with the bit pattern 01 for example).
++ *
++ * If we use the EXI immediate mode transfer, we can workaround the
++ * situation by writing all 1s to the DATA register before reading
++ * (this is indeed automatically done by the EXI layer).
++ * But we simply can't do that when using EXI DMA transfers (these
++ * kind of transfers do not allow bidirectional operation).
++ *
++ * Given that no EXI DMA read transfers seem reliable, we fallback
++ * to the "interrupt-driven" immediate mode of the EXI layer.
++ * This will help reducing CPU monopolization on large reads.
++ *
++ */
++ exi_dev_transfer(host->exi_device, data, len, EXI_OP_READ, EXI_CMD_IDI);
++}
++
++/* cycles are expressed in 8 clock cycles */
++static void spi_burn_cycles(struct sd_host *host, int cycles)
++{
++ u8 d;
++
++ while (cycles-- > 0) {
++ d = 0xff;
++ spi_write(host, &d, sizeof(d));
++ }
++}
++
++/* cycles are expressed in 8 clock cycles */
++static int spi_wait_for_resp(struct sd_host *host,
++ u8 resp, u8 resp_mask, unsigned long cycles)
++{
++ u8 data;
++
++ while (cycles-- > 0) {
++ spi_read(host, &data, sizeof(data));
++ if ((data & resp_mask) == resp) {
++ host->resp = data;
++ return data;
++ }
++ }
++ return -ENODATA;
++}
++
++/*
++ *
++ */
++static int sd_read_data(struct sd_host *host, void *data, size_t len, int token)
++{
++ int retval = 0;
++
++ if (token) {
++ retval = spi_wait_for_resp(host, token, 0xff,
++ host->read_timeout);
++ if (retval < 0)
++ goto out;
++ }
++ spi_read(host, data, len);
++ retval = 0;
++
++out:
++ return retval;
++}
++
++/*
++ *
++ */
++static int sd_write_data(struct sd_host *host, void *data, size_t len,
++ int token)
++{
++ u16 crc;
++ u8 t, *d;
++ size_t l;
++ int retval = 0;
++
++ /* FIXME, rewrite this a bit */
++ {
++ crc = 0;
++ d = data;
++ l = len;
++
++ while (l-- > 0)
++ crc = crc_xmodem_update(crc, *d++);
++ }
++
++ /* send the write block token */
++ t = token;
++ spi_write(host, &t, sizeof(t));
++
++ /* send the data */
++ spi_write(host, data, len);
++
++ /* send the crc */
++ spi_write(host, &crc, sizeof(crc));
++
++ /* get the card data response */
++ retval = spi_wait_for_resp(host, 0x01, 0x11, host->write_timeout);
++ if (retval < 0)
++ goto out;
++ if ((retval & DR_SPI_MASK) != DR_SPI_DATA_ACCEPTED) {
++ DBG("data response=%02x\n", retval);
++ retval = -EIO;
++ goto out;
++ }
++
++ /* wait for the busy signal to clear */
++ retval = spi_wait_for_resp(host, 0xff, 0xff, host->write_timeout);
++ if (retval < 0)
++ goto out;
++
++ retval = 0;
++
++out:
++ return retval;
++}
++
++/*
++ *
++ * MMC/SD command transactions related routines.
++ */
++
++/* */
++static inline void sd_cmd(struct sd_command *cmd, u8 opcode, u32 arg)
++{
++ cmd->cmd = 0x40 | opcode;
++ cmd->arg = arg;
++ cmd->crc = 0x01; /* FIXME, crc is not currently used */
++}
++
++/* */
++static inline void sd_cmd_go_idle_state(struct sd_command *cmd)
++{
++ cmd->cmd = 0x40;
++ cmd->arg = 0;
++ cmd->crc = 0x95;
++}
++
++/* */
++static inline void sd_debug_print_cmd(struct sd_command *cmd)
++{
++ DBG("cmd = %d, arg = %08x, crc = %02x\n",
++ cmd->cmd & ~0x40, cmd->arg, cmd->crc);
++}
++
++/*
++ *
++ */
++static int sd_start_command(struct sd_host *host, struct sd_command *cmd)
++{
++ int retval = 0;
++
++ /* select the card by driving CS low */
++ spi_cs_low(host);
++
++ /* send the command through the MOSI line */
++ spi_write(host, cmd, sizeof(*cmd));
++
++ /*
++ * Wait for the card response.
++ * Card responses come in the MISO line and have the most significant
++ * bit cleared.
++ */
++ retval = spi_wait_for_resp(host, 0x00, 0x80, MMC_SPI_N_CR);
++
++ if (retval > 0 && !(retval & 0x01) && cmd->cmd != 0x40)
++ DBG("command = %d, response = 0x%02x\n", cmd->cmd & ~0x40,
++ retval);
++
++ return retval;
++}
++
++/*
++ *
++ */
++static void sd_end_command(struct sd_host *host)
++{
++ /* wait 8 clock cycles as dictated by the specification */
++ spi_burn_cycles(host, SD_FINISH_CYCLES);
++
++ /* deselect the card by driving CS high */
++ spi_cs_high(host);
++}
++
++/*
++ *
++ */
++static int sd_run_no_data_command(struct sd_host *host, struct sd_command *cmd)
++{
++ int retval;
++
++ /* send command, wait for response, and burn extra cycles */
++ retval = sd_start_command(host, cmd);
++ sd_end_command(host);
++
++ return retval;
++}
++
++/*
++ *
++ */
++static int sd_generic_read(struct sd_host *host,
++ u8 opcode, u32 arg,
++ void *data, size_t len, int token)
++{
++ struct sd_command *cmd = &host->cmd;
++ u16 crc, calc_crc = 0xffff;
++ u8 *d;
++ size_t l;
++ int retval;
++
++ /* build raw command */
++ sd_cmd(cmd, opcode, arg);
++
++ /* select card, send command and wait for response */
++ retval = sd_start_command(host, cmd);
++ if (retval < 0)
++ goto out;
++ if (retval != 0x00) {
++ retval = -EIO;
++ goto out;
++ }
++
++ /* wait for read token, then read data */
++ retval = sd_read_data(host, data, len, token);
++ if (retval < 0)
++ goto out;
++
++ /* read trailing crc */
++ spi_read(host, &crc, sizeof(crc));
++
++ retval = 0;
++
++ /* FIXME, rewrite this a bit */
++ {
++ calc_crc = 0;
++ d = data;
++ l = len;
++
++ while (l-- > 0)
++ calc_crc = crc_xmodem_update(calc_crc, *d++);
++
++ if (calc_crc != crc)
++ retval = -EIO;
++ }
++
++out:
++ /* burn extra cycles and deselect card */
++ sd_end_command(host);
++
++ if (retval < 0) {
++ DBG("read, offset=%d, len=%d\n", arg, len);
++ DBG("crc=%04x, calc_crc=%04x, %s\n", crc, calc_crc,
++ (retval < 0) ? "failed" : "ok");
++ }
++
++ return retval;
++}
++
++/*
++ *
++ */
++static int sd_generic_write(struct sd_host *host,
++ u8 opcode, u32 arg,
++ void *data, size_t len, int token)
++{
++ struct sd_command *cmd = &host->cmd;
++ int retval;
++
++ /* build raw command */
++ sd_cmd(cmd, opcode, arg);
++
++ /* select card, send command and wait for response */
++ retval = sd_start_command(host, cmd);
++ if (retval < 0)
++ goto out;
++ if (retval != 0x00) {
++ retval = -EIO;
++ goto out;
++ }
++
++ /* send data token, data and crc, get data response */
++ retval = sd_write_data(host, data, len, token);
++ if (retval < 0)
++ goto out;
++
++ retval = 0;
++
++out:
++ /* burn extra cycles and deselect card */
++ sd_end_command(host);
++
++ if (retval < 0)
++ DBG("write, offset=%d, len=%d\n", arg, len);
++
++ return retval;
++}
++
++/*
++ *
++ */
++static int sd_read_ocr(struct sd_host *host)
++{
++ struct sd_command *cmd = &host->cmd;
++ int retval;
++
++ memset(&host->ocr, 0, sizeof(host->ocr));
++
++ sd_cmd(cmd, MMC_READ_OCR, 0);
++
++ /* select card, send command and wait for response */
++ retval = sd_start_command(host, cmd);
++ if (retval < 0)
++ goto out;
++
++ /* the OCR contents come immediately after the card response */
++ spi_read(host, &host->ocr, sizeof(host->ocr));
++ retval = 0;
++
++out:
++ /* burn extra cycles and deselect card */
++ sd_end_command(host);
++ return retval;
++}
++
++/*
++ *
++ */
++static inline int sd_read_csd(struct sd_host *host)
++{
++ memset(&host->card.raw_csd, 0, sizeof(host->card.raw_csd));
++ return sd_generic_read(host, MMC_SEND_CSD, 0,
++ &host->card.raw_csd,
++ sizeof(host->card.raw_csd),
++ MMC_SPI_TOKEN_START_SINGLE_BLOCK_READ);
++}
++
++/*
++ *
++ */
++static inline int sd_read_cid(struct sd_host *host)
++{
++ memset(&host->card.raw_cid, 0, sizeof(host->card.raw_cid));
++ return sd_generic_read(host, MMC_SEND_CID, 0,
++ &host->card.raw_cid,
++ sizeof(host->card.raw_cid),
++ MMC_SPI_TOKEN_START_SINGLE_BLOCK_READ);
++}
++
++/*
++ *
++ */
++static inline int sd_read_single_block(struct sd_host *host,
++ unsigned long start,
++ void *data, size_t len)
++{
++ int retval;
++ int attempts = 3;
++
++ if (test_bit(__SD_MEDIA_CHANGED, &host->flags))
++ attempts = 1;
++
++ while (attempts > 0) {
++ retval = sd_generic_read(host, MMC_READ_SINGLE_BLOCK, start,
++ data, len,
++ MMC_SPI_TOKEN_START_SINGLE_BLOCK_READ);
++ if (retval >= 0)
++ break;
++ attempts--;
++ DBG("start=%lu, data=%p, len=%d, retval = %d\n", start, data,
++ len, retval);
++ }
++ return retval;
++}
++
++/*
++ *
++ */
++static inline int sd_write_single_block(struct sd_host *host,
++ unsigned long start,
++ void *data, size_t len)
++{
++ int retval;
++
++ retval = sd_generic_write(host, MMC_WRITE_BLOCK, start,
++ data, len,
++ MMC_SPI_TOKEN_START_SINGLE_BLOCK_WRITE);
++ if (retval < 0)
++ DBG("start=%lu, data=%p, len=%d, retval = %d\n", start, data,
++ len, retval);
++
++ return retval;
++}
++
++/*
++ *
++ */
++static int sd_reset_sequence(struct sd_host *host)
++{
++ struct sd_command *cmd = &host->cmd;
++ u8 d;
++ int i;
++ int retval = 0;
++
++ host->card.state = 0;
++
++ /*
++ * Wait at least 80 dummy clock cycles with the card deselected
++ * and with the MOSI line continuously high.
++ */
++ exi_dev_take(host->exi_device);
++ exi_dev_deselect(host->exi_device);
++ for (i = 0; i < SD_IDLE_CYCLES; i++) {
++ d = 0xff;
++ exi_dev_write(host->exi_device, &d, sizeof(d));
++ }
++ exi_dev_give(host->exi_device);
++
++ /*
++ * Send a CMD0, card must ack with "idle state" (0x01).
++ * This puts the card into SPI mode and soft resets it.
++ * CRC checking is disabled by default.
++ */
++ for (i = 0; i < 255; i++) {
++ /* CMD0 */
++ sd_cmd_go_idle_state(cmd);
++ retval = sd_run_no_data_command(host, cmd);
++ if (retval < 0) {
++ retval = -ENODEV;
++ goto out;
++ }
++ if (retval == R1_SPI_IDLE)
++ break;
++ }
++ if (retval != R1_SPI_IDLE) {
++ retval = -ENODEV;
++ goto out;
++ }
++
++ /*
++ * Send a ACMD41 to activate card initialization process.
++ * SD card must ack with "ok" (0x00).
++ * MMC card will report "invalid command" (0x04).
++ */
++ for (i = 0; i < 0xffff; i++) {
++ /* ACMD41 = CMD55 + CMD41 */
++ sd_cmd(cmd, MMC_APP_CMD, 0);
++ retval = sd_run_no_data_command(host, cmd);
++ if (retval < 0) {
++ retval = -ENODEV;
++ goto out;
++ }
++
++ sd_cmd(cmd, SD_APP_OP_COND, 0);
++ retval = sd_run_no_data_command(host, cmd);
++ if (retval < 0) {
++ retval = -ENODEV;
++ goto out;
++ }
++ if (retval == 0x00) {
++ /* we found a SD card */
++ mmc_card_set_present(&host->card);
++ host->card.type = MMC_TYPE_SD;
++ break;
++ }
++ if ((retval & R1_SPI_ILLEGAL_COMMAND)) {
++ /* this looks like a MMC card */
++ break;
++ }
++ }
++
++ /*
++ * MMC cards require CMD1 to activate card initialization process.
++ * MMC card must ack with "ok" (0x00)
++ */
++ if (!mmc_card_sd(&host->card)) {
++ for (i = 0; i < 0xffff; i++) {
++ sd_cmd(cmd, MMC_SEND_OP_COND, 0);
++ retval = sd_run_no_data_command(host, cmd);
++ if (retval < 0) {
++ retval = -ENODEV;
++ goto out;
++ }
++ if (retval == 0x00) {
++ /* we found a MMC card */
++ mmc_card_set_present(&host->card);
++ break;
++ }
++ }
++ if (retval != 0x00) {
++ DBG("MMC card, bad, retval=%02x\n", retval);
++ sd_card_set_bad(host);
++ }
++ }
++
++out:
++ return retval;
++}
++
++/*
++ *
++ */
++static int sd_welcome_card(struct sd_host *host)
++{
++ int retval;
++
++ /* soft reset the card */
++ retval = sd_reset_sequence(host);
++ if (retval < 0 || sd_card_is_bad(host))
++ goto out;
++
++ /* read Operating Conditions Register */
++ retval = sd_read_ocr(host);
++ if (retval < 0)
++ goto err_bad_card;
++
++ /* refuse to drive cards reporting voltage ranges out of scope */
++ if (!(host->ocr & host->ocr_avail)) {
++ sd_printk(KERN_WARNING, "reported OCR (%08x)"
++ " indicates that it is not safe to use this"
++ " card with a GameCube\n", host->ocr);
++ retval = -ENODEV;
++ goto err_bad_card;
++ }
++
++ /* read and decode the Card Specific Data */
++ retval = sd_read_csd(host);
++ if (retval < 0)
++ goto err_bad_card;
++ mmc_decode_csd(&host->card);
++
++ /* calculate some card access related timeouts */
++ sd_calc_timeouts(host);
++
++ /* read and decode the Card Identification Data */
++ retval = sd_read_cid(host);
++ if (retval < 0)
++ goto err_bad_card;
++ mmc_decode_cid(&host->card);
++
++ sd_printk(KERN_INFO, "slot%d: descr \"%s\", size %luk, block %ub,"
++ " serial %08x\n",
++ to_channel(exi_get_exi_channel(host->exi_device)),
++ host->card.cid.prod_name,
++ (unsigned long)((host->card.csd.capacity *
++ (1 << host->card.csd.read_blkbits)) / 1024),
++ 1 << host->card.csd.read_blkbits,
++ host->card.cid.serial);
++
++ retval = 0;
++ goto out;
++
++err_bad_card:
++ sd_card_set_bad(host);
++out:
++ return retval;
++}
++
++/*
++ *
++ * Block layer.
++ */
++
++/*
++ * Performs a read request.
++ */
++static int sd_read_request(struct sd_host *host, struct request *req)
++{
++ int i;
++ unsigned long nr_blocks; /* in card blocks */
++ size_t block_len; /* in bytes */
++ unsigned long start;
++ void *buf = req->buffer;
++ int retval;
++
++ /*
++ * It seems that some cards do not accept single block reads for the
++ * read block length reported by the card.
++ * For now, we perform only 512 byte single block reads.
++ */
++
++ start = req->sector << KERNEL_SECTOR_SHIFT;
++#if 0
++ nr_blocks = req->current_nr_sectors >>
++ (host->card.csd.read_blkbits - KERNEL_SECTOR_SHIFT);
++ block_len = 1 << host->card.csd.read_blkbits;
++#else
++ nr_blocks = req->current_nr_sectors;
++ block_len = 1 << KERNEL_SECTOR_SHIFT;
++#endif
++
++ for (i = 0; i < nr_blocks; i++) {
++ retval = sd_read_single_block(host, start, buf, block_len);
++ if (retval < 0)
++ break;
++
++ start += block_len;
++ buf += block_len;
++ }
++
++ /* number of kernel sectors transferred */
++#if 0
++ retval = i << (host->card.csd.read_blkbits - KERNEL_SECTOR_SHIFT);
++#else
++ retval = i;
++#endif
++
++ return retval;
++}
++
++/*
++ * Performs a write request.
++ */
++static int sd_write_request(struct sd_host *host, struct request *req)
++{
++ int i;
++ unsigned long nr_blocks; /* in card blocks */
++ size_t block_len; /* in bytes */
++ unsigned long start;
++ void *buf = req->buffer;
++ int retval;
++
++ /* FIXME?, maybe should use 2^WRITE_BL_LEN blocks */
++
++ /* kernel sectors and card write blocks are both 512 bytes long */
++ start = req->sector << KERNEL_SECTOR_SHIFT;
++ nr_blocks = req->current_nr_sectors;
++ block_len = 1 << KERNEL_SECTOR_SHIFT;
++
++ for (i = 0; i < nr_blocks; i++) {
++ retval = sd_write_single_block(host, start, buf, block_len);
++ if (retval < 0)
++ break;
++
++ start += block_len;
++ buf += block_len;
++ }
++
++ /* number of kernel sectors transferred */
++ retval = i;
++
++ return retval;
++}
++
++/*
++ * Verifies if a request should be dispatched or not.
++ *
++ * Returns:
++ * <0 in case of error.
++ * 0 if request passes the checks
++ * >0 if request can be ignored
++ */
++static int sd_check_request(struct sd_host *host, struct request *req)
++{
++ unsigned long nr_sectors;
++
++ if (test_bit(__SD_MEDIA_CHANGED, &host->flags)) {
++ sd_printk(KERN_ERR, "media changed, aborting\n");
++ return -ENOMEDIUM;
++ }
++
++ /* unit is kernel sectors */
++ nr_sectors =
++ host->card.csd.capacity << (host->card.csd.read_blkbits -
++ KERNEL_SECTOR_SHIFT);
++
++ /* keep our reads within limits */
++ if (req->sector + req->current_nr_sectors > nr_sectors) {
++ sd_printk(KERN_ERR, "reading past end, aborting\n");
++ return -EINVAL;
++ }
++
++ if (!blk_fs_request(req))
++ return 1;
++
++ return 0;
++}
++
++/*
++ * Request dispatcher.
++ */
++static int sd_do_request(struct sd_host *host, struct request *req)
++{
++ int retval;
++
++ retval = sd_check_request(host, req);
++ if (retval)
++ return 0;
++
++ switch (rq_data_dir(req)) {
++ case WRITE:
++ retval = sd_write_request(host, req);
++ break;
++ case READ:
++ retval = sd_read_request(host, req);
++ break;
++ }
++
++ return retval;
++}
++
++/*
++ * Input/Output thread.
++ */
++static int sd_io_thread(void *param)
++{
++ struct sd_host *host = param;
++ struct request *req;
++ unsigned long flags;
++ int nr_sectors;
++ int error;
++
++#if 0
++ /*
++ * We are going to perfom badly due to the read problem explained
++ * above. At least, be nice with other processes trying to use the
++ * cpu.
++ */
++ set_user_nice(current, 0);
++#endif
++
++ current->flags |= PF_NOFREEZE|PF_MEMALLOC;
++
++ mutex_lock(&host->io_mutex);
++ for (;;) {
++ req = NULL;
++ set_current_state(TASK_INTERRUPTIBLE);
++
++ spin_lock_irqsave(&host->queue_lock, flags);
++ if (!blk_queue_plugged(host->queue))
++ req = elv_next_request(host->queue);
++ spin_unlock_irqrestore(&host->queue_lock, flags);
++
++ if (!req) {
++ if (kthread_should_stop()) {
++ set_current_state(TASK_RUNNING);
++ break;
++ }
++ mutex_unlock(&host->io_mutex);
++ schedule();
++ mutex_lock(&host->io_mutex);
++ continue;
++ }
++ set_current_state(TASK_INTERRUPTIBLE);
++ nr_sectors = sd_do_request(host, req);
++ error = (nr_sectors < 0) ? nr_sectors : 0;
++
++ spin_lock_irqsave(&host->queue_lock, flags);
++ __blk_end_request(req, error, nr_sectors << 9);
++ spin_unlock_irqrestore(&host->queue_lock, flags);
++ }
++ mutex_unlock(&host->io_mutex);
++
++ return 0;
++}
++
++/*
++ * Block layer request function.
++ * Wakes up the IO thread.
++ */
++static void sd_request_func(struct request_queue *q)
++{
++ struct sd_host *host = q->queuedata;
++ wake_up_process(host->io_thread);
++}
++
++/*
++ *
++ * Driver interface.
++ */
++
++static DECLARE_MUTEX(open_lock);
++
++/*
++ * Opens the drive device.
++ */
++static int sd_open(struct block_device *bdev, fmode_t mode)
++{
++ struct sd_host *host = bdev->bd_disk->private_data;
++ int retval = 0;
++
++ if (!host || !host->exi_device)
++ return -ENXIO;
++
++ /* honor exclusive open mode */
++ if (host->refcnt == -1 ||
++ (host->refcnt && (mode & FMODE_EXCL))) {
++ retval = -EBUSY;
++ goto out;
++ }
++
++ /* this takes care of revalidating the media if needed */
++ check_disk_change(bdev);
++ if (!host->card.csd.capacity) {
++ retval = -ENOMEDIUM;
++ goto out;
++ }
++
++ down(&open_lock);
++
++ if ((mode & FMODE_EXCL))
++ host->refcnt = -1;
++ else
++ host->refcnt++;
++
++ up(&open_lock);
++
++out:
++ return retval;
++
++}
++
++/*
++ * Releases the drive device.
++ */
++static int sd_release(struct gendisk *disk, fmode_t mode)
++{
++ struct sd_host *host = disk->private_data;
++
++ if (!host)
++ return -ENXIO;
++
++ down(&open_lock);
++
++ if (host->refcnt > 0)
++ host->refcnt--;
++ else
++ host->refcnt = 0;
++
++ up(&open_lock);
++
++ /* lazy removal of unreferenced zombies */
++ if (!host->refcnt && !host->exi_device)
++ kfree(host);
++
++ return 0;
++}
++
++/*
++ * Checks if media changed.
++ */
++static int sd_media_changed(struct gendisk *disk)
++{
++ struct sd_host *host = disk->private_data;
++ unsigned int last_serial;
++ int retval;
++
++ /* report a media change for zombies */
++ if (!host)
++ return 1;
++
++ /* report a media change if someone forced it */
++ if (test_bit(__SD_MEDIA_CHANGED, &host->flags))
++ return 1;
++
++ /* check if the serial number of the card changed */
++ last_serial = host->card.cid.serial;
++ retval = sd_read_cid(host);
++ if (!retval && last_serial == host->card.cid.serial && last_serial)
++ clear_bit(__SD_MEDIA_CHANGED, &host->flags);
++ else
++ set_bit(__SD_MEDIA_CHANGED, &host->flags);
++
++ return (host->flags & SD_MEDIA_CHANGED) ? 1 : 0;
++}
++
++/*
++ * Checks if media is still valid.
++ */
++static int sd_revalidate_disk(struct gendisk *disk)
++{
++ struct sd_host *host = disk->private_data;
++ int retval = 0;
++
++ /* report missing medium for zombies */
++ if (!host) {
++ retval = -ENOMEDIUM;
++ goto out;
++ }
++
++ /* the block layer likes to call us multiple times... */
++ if (!sd_media_changed(host->disk))
++ goto out;
++
++ /* get the card into a known status */
++ retval = sd_welcome_card(host);
++ if (retval < 0 || sd_card_is_bad(host)) {
++ retval = -ENOMEDIUM;
++ goto out;
++ }
++
++ /* inform the block layer about various sizes */
++ blk_queue_hardsect_size(host->queue, 1 << KERNEL_SECTOR_SHIFT);
++ set_capacity(host->disk, host->card.csd.capacity <<
++ (host->card.csd.read_blkbits - KERNEL_SECTOR_SHIFT));
++
++ clear_bit(__SD_MEDIA_CHANGED, &host->flags);
++
++out:
++ return retval;
++}
++
++static int sd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
++{
++ geo->cylinders = get_capacity(bdev->bd_disk) / (4 * 16);
++ geo->heads = 4;
++ geo->sectors = 16;
++ return 0;
++}
++
++
++static struct block_device_operations sd_fops = {
++ .owner = THIS_MODULE,
++ .open = sd_open,
++ .release = sd_release,
++ .revalidate_disk = sd_revalidate_disk,
++ .media_changed = sd_media_changed,
++ .getgeo = sd_getgeo,
++};
++
++/*
++ * Initializes the block layer interfaces.
++ */
++static int sd_init_blk_dev(struct sd_host *host)
++{
++ struct gendisk *disk;
++ struct request_queue *queue;
++ int channel;
++ int retval;
++
++ channel = to_channel(exi_get_exi_channel(host->exi_device));
++
++ /* queue */
++ retval = -ENOMEM;
++ spin_lock_init(&host->queue_lock);
++ queue = blk_init_queue(sd_request_func, &host->queue_lock);
++ if (!queue) {
++ sd_printk(KERN_ERR, "error initializing queue\n");
++ goto err_blk_init_queue;
++ }
++ blk_queue_dma_alignment(queue, EXI_DMA_ALIGN);
++ blk_queue_max_phys_segments(queue, 1);
++ blk_queue_max_hw_segments(queue, 1);
++ blk_queue_max_sectors(queue, 8);
++ queue->queuedata = host;
++ host->queue = queue;
++
++ /* disk */
++ disk = alloc_disk(1 << MMC_SHIFT);
++ if (!disk) {
++ sd_printk(KERN_ERR, "error allocating disk\n");
++ goto err_alloc_disk;
++ }
++ disk->major = SD_MAJOR;
++ disk->first_minor = channel << MMC_SHIFT;
++ disk->fops = &sd_fops;
++ sprintf(disk->disk_name, "%s%c", SD_NAME, 'a' + channel);
++ disk->private_data = host;
++ disk->queue = host->queue;
++ host->disk = disk;
++
++ retval = 0;
++ goto out;
++
++err_alloc_disk:
++ blk_cleanup_queue(host->queue);
++ host->queue = NULL;
++err_blk_init_queue:
++out:
++ return retval;
++}
++
++/*
++ * Exits the block layer interfaces.
++ */
++static void sd_exit_blk_dev(struct sd_host *host)
++{
++ blk_cleanup_queue(host->queue);
++ put_disk(host->disk);
++}
++
++
++/*
++ * Initializes and launches the IO thread.
++ */
++static int sd_init_io_thread(struct sd_host *host)
++{
++ int channel;
++ int result = 0;
++
++ channel = to_channel(exi_get_exi_channel(host->exi_device));
++
++ mutex_init(&host->io_mutex);
++ host->io_thread = kthread_run(sd_io_thread, host,
++ "ksdiod/%c", 'a' + channel);
++ if (IS_ERR(host->io_thread)) {
++ sd_printk(KERN_ERR, "error creating io thread\n");
++ result = PTR_ERR(host->io_thread);
++ }
++ return result;
++}
++
++/*
++ * Terminates and waits for the IO thread to complete.
++ */
++static void sd_exit_io_thread(struct sd_host *host)
++{
++ if (!IS_ERR(host->io_thread)) {
++ wake_up_process(host->io_thread);
++ kthread_stop(host->io_thread);
++ host->io_thread = ERR_PTR(-EINVAL);
++ }
++}
++
++/*
++ * Initializes a host.
++ */
++static int sd_init(struct sd_host *host)
++{
++ int retval;
++
++ spin_lock_init(&host->lock);
++
++ host->refcnt = 0;
++ set_bit(__SD_MEDIA_CHANGED, &host->flags);
++
++ host->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
++ sd_set_clock(host, SD_SPI_CLK);
++ sd_calc_timeouts(host);
++
++ retval = sd_init_blk_dev(host);
++ if (!retval) {
++ retval = sd_revalidate_disk(host->disk);
++ if (retval < 0 || !mmc_card_present(&host->card)) {
++ retval = -ENODEV;
++ goto err_blk_dev;
++ }
++
++ retval = sd_init_io_thread(host);
++ if (retval)
++ goto err_blk_dev;
++
++ add_disk(host->disk);
++ }
++
++ return retval;
++
++err_blk_dev:
++ sd_exit_blk_dev(host);
++ return retval;
++}
++
++/*
++ * Deinitializes (exits) a host.
++ */
++static void sd_exit(struct sd_host *host)
++{
++ del_gendisk(host->disk);
++ sd_exit_io_thread(host);
++ sd_exit_blk_dev(host);
++}
++
++/*
++ * Terminates a host.
++ */
++static void sd_kill(struct sd_host *host)
++{
++ if (host->refcnt > 0) {
++ sd_printk(KERN_ERR, "hey! card removed while in use!\n");
++ set_bit(__SD_MEDIA_CHANGED, &host->flags);
++ }
++
++ sd_exit(host);
++ host->exi_device = NULL;
++
++ /* release the host immediately when not in use */
++ if (!host->refcnt)
++ kfree(host);
++}
++
++
++/*
++ * EXI layer interface.
++ *
++ */
++
++/*
++ * Checks if the given EXI device is a MMC/SD card and makes it available
++ * if true.
++ */
++static int sd_probe(struct exi_device *exi_device)
++{
++ struct sd_host *host;
++ int retval;
++
++ /* don't try to drive a device which already has a real identifier */
++ if (exi_device->eid.id != EXI_ID_NONE)
++ return -ENODEV;
++
++ host = kzalloc(sizeof(*host), GFP_KERNEL);
++ if (!host)
++ return -ENOMEM;
++
++ host->exi_device = exi_device_get(exi_device);
++ WARN_ON(exi_get_drvdata(exi_device));
++ exi_set_drvdata(exi_device, host);
++ retval = sd_init(host);
++ if (retval) {
++ exi_set_drvdata(exi_device, NULL);
++ host->exi_device = NULL;
++ kfree(host);
++ exi_device_put(exi_device);
++ }
++ return retval;
++}
++
++/*
++ * Makes unavailable the MMC/SD card identified by the EXI device `exi_device'.
++ */
++static void sd_remove(struct exi_device *exi_device)
++{
++ struct sd_host *host = exi_get_drvdata(exi_device);
++
++ WARN_ON(!host);
++ WARN_ON(!host->exi_device);
++
++ exi_set_drvdata(exi_device, NULL);
++ if (host)
++ sd_kill(host);
++ exi_device_put(exi_device);
++}
++
++static struct exi_device_id sd_eid_table[] = {
++ [0] = {
++ .channel = SD_SLOTA_CHANNEL,
++ .device = SD_SLOTA_DEVICE,
++ .id = EXI_ID_NONE,
++ },
++ [1] = {
++ .channel = SD_SLOTB_CHANNEL,
++ .device = SD_SLOTB_DEVICE,
++ .id = EXI_ID_NONE,
++ },
++ {.id = 0}
++};
++
++static struct exi_driver sd_driver = {
++ .name = DRV_MODULE_NAME,
++ .eid_table = sd_eid_table,
++ .frequency = SD_SPI_CLK_IDX,
++ .probe = sd_probe,
++ .remove = sd_remove,
++};
++
++
++/*
++ * Kernel module interface.
++ *
++ */
++
++/*
++ *
++ */
++static int __init sd_init_module(void)
++{
++ int retval = 0;
++
++ sd_printk(KERN_INFO, "%s - version %s\n", DRV_DESCRIPTION,
++ sd_driver_version);
++
++ if (register_blkdev(SD_MAJOR, DRV_MODULE_NAME)) {
++ sd_printk(KERN_ERR, "unable to register major %d\n", SD_MAJOR);
++ retval = -EIO;
++ goto out;
++ }
++
++ retval = exi_driver_register(&sd_driver);
++
++out:
++ return retval;
++}
++
++/*
++ *
++ */
++static void __exit sd_exit_module(void)
++{
++ unregister_blkdev(SD_MAJOR, DRV_MODULE_NAME);
++ exi_driver_unregister(&sd_driver);
++}
++
++module_init(sd_init_module);
++module_exit(sd_exit_module);
++
++MODULE_AUTHOR(DRV_AUTHOR);
++MODULE_DESCRIPTION(DRV_DESCRIPTION);
++MODULE_LICENSE("GPL");
++
+diff --git a/drivers/block/rvl-mem2.c b/drivers/block/rvl-mem2.c
+new file mode 100644
+index 0000000..01339f5
+--- /dev/null
++++ b/drivers/block/rvl-mem2.c
+@@ -0,0 +1,384 @@
++/*
++ * drivers/block/rvl-mem2.c
++ *
++ * Nintendo Wii MEM2 block driver
++ * Copyright (C) 2008-2009 The GameCube Linux Team
++ * Copyright (C) 2008,2009 Albert Herranz
++ *
++ * Based on gcn-aram.c.
++ *
++ * 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/major.h>
++#include <linux/of_platform.h>
++#include <linux/blkdev.h>
++#include <linux/fcntl.h> /* O_ACCMODE */
++#include <linux/hdreg.h> /* HDIO_GETGEO */
++#include <linux/io.h>
++
++
++#define DRV_MODULE_NAME "rvl-mem2"
++#define DRV_DESCRIPTION "Nintendo Wii MEM2 block driver"
++#define DRV_AUTHOR "Albert Herranz"
++
++static char mem2_driver_version[] = "0.1-isobel";
++
++#define drv_printk(level, format, arg...) \
++ printk(level DRV_MODULE_NAME ": " format , ## arg)
++
++
++/*
++ * Driver settings
++ */
++#define MEM2_NAME DRV_MODULE_NAME
++#define MEM2_MAJOR Z2RAM_MAJOR
++
++#define MEM2_SECTOR_SIZE PAGE_SIZE
++
++
++struct mem2_drvdata {
++ spinlock_t lock;
++
++ void __iomem *io_base;
++ size_t size;
++
++ struct block_device_operations fops;
++ struct gendisk *disk;
++ struct request_queue *queue;
++
++ int ref_count;
++
++ struct device *dev;
++};
++
++/*
++ *
++ */
++
++/*
++ * Performs block layer requests.
++ */
++static void mem2_do_request(struct request_queue *q)
++{
++ struct mem2_drvdata *drvdata = q->queuedata;
++ struct request *req;
++ unsigned long mem2_addr;
++ size_t len;
++ int error;
++
++ req = elv_next_request(q);
++ while (req) {
++ if (blk_fs_request(req)) {
++ /* calculate the MEM2 address and length */
++ mem2_addr = req->sector << 9;
++ len = req->current_nr_sectors << 9;
++
++ /* give up if the request goes out of bounds */
++ if (mem2_addr + len > drvdata->size) {
++ drv_printk(KERN_ERR, "bad access: block=%lu,"
++ " size=%u\n",
++ (unsigned long)req->sector, len);
++ error = -EIO;
++ } else {
++ switch (rq_data_dir(req)) {
++ case READ:
++ memcpy(req->buffer,
++ drvdata->io_base + mem2_addr,
++ len);
++ break;
++ case WRITE:
++ memcpy(drvdata->io_base + mem2_addr,
++ req->buffer, len);
++ break;
++ }
++ error = 0;
++ }
++ blk_end_request(req, error, len);
++ } else {
++ end_request(req, 0);
++ }
++ req = elv_next_request(q);
++ }
++}
++
++/*
++ * Opens the MEM2 device.
++ */
++static int mem2_open(struct block_device *bdev, fmode_t mode)
++{
++ struct mem2_drvdata *drvdata = bdev->bd_disk->private_data;
++ unsigned long flags;
++ int retval = 0;
++
++ spin_lock_irqsave(&drvdata->lock, flags);
++
++ /* only allow a minor of 0 to be opened */
++ if (MINOR(bdev->bd_dev)) {
++ retval = -ENODEV;
++ goto out;
++ }
++
++ /* honor exclusive open mode */
++ if (drvdata->ref_count == -1 ||
++ (drvdata->ref_count && (mode & FMODE_EXCL))) {
++ retval = -EBUSY;
++ goto out;
++ }
++
++ if ((mode & FMODE_EXCL))
++ drvdata->ref_count = -1;
++ else
++ drvdata->ref_count++;
++
++out:
++ spin_unlock_irqrestore(&drvdata->lock, flags);
++ return retval;
++}
++
++/*
++ * Closes the MEM2 device.
++ */
++static int mem2_release(struct gendisk *disk, fmode_t mode)
++{
++ struct mem2_drvdata *drvdata = disk->private_data;
++ unsigned long flags;
++
++ spin_lock_irqsave(&drvdata->lock, flags);
++ if (drvdata->ref_count > 0)
++ drvdata->ref_count--;
++ else
++ drvdata->ref_count = 0;
++ spin_unlock_irqrestore(&drvdata->lock, flags);
++
++ return 0;
++}
++
++static int mem2_getgeo(struct block_device *bdev, struct hd_geometry *geo)
++{
++ geo->cylinders = get_capacity(bdev->bd_disk) / (4 * 16);
++ geo->heads = 4;
++ geo->sectors = 16;
++ return 0;
++}
++
++
++static struct block_device_operations mem2_fops = {
++ .owner = THIS_MODULE,
++ .open = mem2_open,
++ .release = mem2_release,
++ .getgeo = mem2_getgeo,
++};
++
++
++/*
++ *
++ */
++static int mem2_init_blk_dev(struct mem2_drvdata *drvdata)
++{
++ struct gendisk *disk;
++ struct request_queue *queue;
++ int retval;
++
++ drvdata->ref_count = 0;
++
++ retval = register_blkdev(MEM2_MAJOR, MEM2_NAME);
++ if (retval)
++ goto err_register_blkdev;
++
++ retval = -ENOMEM;
++ spin_lock_init(&drvdata->lock);
++ queue = blk_init_queue(mem2_do_request, &drvdata->lock);
++ if (!queue)
++ goto err_blk_init_queue;
++
++ blk_queue_hardsect_size(queue, MEM2_SECTOR_SIZE);
++ blk_queue_max_phys_segments(queue, 1);
++ blk_queue_max_hw_segments(queue, 1);
++ queue->queuedata = drvdata;
++ drvdata->queue = queue;
++
++ disk = alloc_disk(1);
++ if (!disk)
++ goto err_alloc_disk;
++
++ disk->major = MEM2_MAJOR;
++ disk->first_minor = 0;
++ disk->fops = &mem2_fops;
++ strcpy(disk->disk_name, MEM2_NAME);
++ disk->queue = drvdata->queue;
++ set_capacity(disk, drvdata->size >> 9);
++ disk->private_data = drvdata;
++ drvdata->disk = disk;
++
++ add_disk(drvdata->disk);
++
++ retval = 0;
++ goto out;
++
++err_alloc_disk:
++ blk_cleanup_queue(drvdata->queue);
++err_blk_init_queue:
++ unregister_blkdev(MEM2_MAJOR, MEM2_NAME);
++err_register_blkdev:
++out:
++ return retval;
++}
++
++/*
++ *
++ */
++static void mem2_exit_blk_dev(struct mem2_drvdata *drvdata)
++{
++ if (drvdata->disk) {
++ del_gendisk(drvdata->disk);
++ put_disk(drvdata->disk);
++ }
++ if (drvdata->queue)
++ blk_cleanup_queue(drvdata->queue);
++ unregister_blkdev(MEM2_MAJOR, MEM2_NAME);
++}
++
++/*
++ *
++ */
++static int mem2_init(struct mem2_drvdata *drvdata, struct resource *mem)
++{
++ int retval;
++ size_t size;
++
++ size = mem->end - mem->start + 1;
++ drvdata->size = size;
++ drvdata->io_base = ioremap(mem->start, size);
++ if (!drvdata->io_base) {
++ drv_printk(KERN_ERR, "failed to ioremap MEM2\n");
++ return -EIO;
++ }
++
++ retval = mem2_init_blk_dev(drvdata);
++ if (retval)
++ iounmap(drvdata->io_base);
++ return retval;
++}
++
++/*
++ *
++ */
++static void mem2_exit(struct mem2_drvdata *drvdata)
++{
++ if (drvdata->io_base)
++ iounmap(drvdata->io_base);
++ mem2_exit_blk_dev(drvdata);
++}
++
++/*
++ *
++ */
++static int mem2_do_probe(struct device *dev, struct resource *mem)
++{
++ struct mem2_drvdata *drvdata;
++ int retval;
++
++ drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL);
++ if (!drvdata) {
++ drv_printk(KERN_ERR, "failed to allocate mem2_drvdata\n");
++ return -ENOMEM;
++ }
++ dev_set_drvdata(dev, drvdata);
++ drvdata->dev = dev;
++
++ retval = mem2_init(drvdata, mem);
++ if (retval) {
++ dev_set_drvdata(dev, NULL);
++ kfree(drvdata);
++ }
++ return retval;
++}
++
++/*
++ *
++ */
++static int mem2_do_remove(struct device *dev)
++{
++ struct mem2_drvdata *drvdata = dev_get_drvdata(dev);
++
++ if (drvdata) {
++ mem2_exit(drvdata);
++ dev_set_drvdata(dev, NULL);
++ return 0;
++ }
++ return -ENODEV;
++}
++
++/*
++ * Driver model probe function.
++ */
++static int __init mem2_of_probe(struct of_device *odev,
++ const struct of_device_id *match)
++{
++ struct resource res;
++ int retval;
++
++ retval = of_address_to_resource(odev->node, 0, &res);
++ if (retval) {
++ drv_printk(KERN_ERR, "no memory range found\n");
++ return -ENODEV;
++ }
++
++ return mem2_do_probe(&odev->dev, &res);
++}
++
++/*
++ * Driver model remove function.
++ */
++static int __exit mem2_of_remove(struct of_device *odev)
++{
++ return mem2_do_remove(&odev->dev);
++}
++
++static struct of_device_id mem2_of_match[] = {
++ { .compatible = "nintendo,hollywood-mem2" },
++ { },
++};
++
++MODULE_DEVICE_TABLE(of, mem2_of_match);
++
++static struct of_platform_driver mem2_of_driver = {
++ .owner = THIS_MODULE,
++ .name = DRV_MODULE_NAME,
++ .match_table = mem2_of_match,
++ .probe = mem2_of_probe,
++ .remove = mem2_of_remove,
++};
++
++/*
++ * Module initialization function.
++ */
++static int __init mem2_init_module(void)
++{
++ drv_printk(KERN_INFO, "%s - version %s\n", DRV_DESCRIPTION,
++ mem2_driver_version);
++
++ return of_register_platform_driver(&mem2_of_driver);
++}
++
++/*
++ * Module deinitialization funtion.
++ */
++static void __exit mem2_exit_module(void)
++{
++ of_unregister_platform_driver(&mem2_of_driver);
++}
++
++module_init(mem2_init_module);
++module_exit(mem2_exit_module);
++
++MODULE_DESCRIPTION(DRV_DESCRIPTION);
++MODULE_AUTHOR(DRV_AUTHOR);
++MODULE_LICENSE("GPL");
++
+diff --git a/drivers/block/rvl-stsd.c b/drivers/block/rvl-stsd.c
+new file mode 100644
+index 0000000..d3b7044
+--- /dev/null
++++ b/drivers/block/rvl-stsd.c
+@@ -0,0 +1,2294 @@
++/*
++ * drivers/block/rvl-stsd.c
++ *
++ * Block driver for the Nintendo Wii SD front slot.
++ * Copyright (C) 2008-2009 The GameCube Linux Team
++ * Copyright (C) 2008,2009 Albert Herranz
++ *
++ * Based on drivers/block/gcn-sd.c
++ *
++ * Copyright (C) 2004-2008 The GameCube Linux Team
++ * Copyright (C) 2004,2005 Rob Reylink
++ * Copyright (C) 2005 Todd Jeffreys
++ * Copyright (C) 2005,2006,2007,2008 Albert Herranz
++ *
++ * 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.
++ *
++ */
++
++#define DEBUG
++
++/*#define DBG(fmt, arg...) pr_debug(fmt, ##arg)*/
++#define DBG(fmt, arg...) drv_printk(KERN_ERR, fmt, ##arg)
++
++#include <linux/blkdev.h>
++#include <linux/delay.h>
++#include <linux/dma-mapping.h>
++#include <linux/hdreg.h>
++#include <linux/init.h>
++#include <linux/kernel.h>
++#include <linux/kthread.h>
++#include <linux/major.h>
++#include <linux/module.h>
++#include <linux/of_platform.h>
++#include <asm/starlet.h>
++
++/*
++ * We are not a native MMC driver...
++ * But anyway, we try to recycle here some of the available code.
++ */
++#include <linux/mmc/host.h>
++#include <linux/mmc/card.h>
++#include <linux/mmc/mmc.h>
++#include <linux/mmc/sd.h>
++#include <linux/mmc/sdio.h>
++#include "../mmc/host/sdhci.h"
++
++#define DRV_MODULE_NAME "rvl-stsd"
++#define DRV_DESCRIPTION "Block driver for the Nintendo Wii SD front slot"
++#define DRV_AUTHOR "Albert Herranz"
++
++static char stsd_driver_version[] = "0.3i";
++
++#define drv_printk(level, format, arg...) \
++ printk(level DRV_MODULE_NAME ": " format , ## arg)
++
++/*
++ * Driver settings.
++ */
++#define MMC_SHIFT 3 /* 8 partitions */
++
++#define STSD_MAJOR 62
++#define STSD_NAME "rvlsd"
++
++#define KERNEL_SECTOR_SHIFT 9
++#define KERNEL_SECTOR_SIZE (1 << KERNEL_SECTOR_SHIFT) /*512 */
++
++#define STSD_MAX_SECTORS 16
++
++
++/*
++ * IOS-related constants.
++ */
++
++/* ioctls */
++#define STSD_IOCTL_SETHSR 1
++#define STSD_IOCTL_GETHSR 2
++#define STSD_IOCTL_RESET 4
++#define STSD_IOCTL_SETCLOCK 6
++#define STSD_IOCTL_SENDCMD 7
++#define STSD_IOCTL_GETSTATUS 11
++#define STSD_IOCTL_GETOCR 12
++
++#define STSD_IOCTLV_SENDCMD 7
++
++/* SD command types */
++#define STSD_CMDTYPE_BC 1
++#define STSD_CMDTYPE_BCR 2
++#define STSD_CMDTYPE_AC 3
++#define STSD_CMDTYPE_ADTC 4
++
++/* SD response types */
++#define STSD_RSPTYPE_NONE 0
++#define STSD_RSPTYPE_R1 1
++#define STSD_RSPTYPE_R1B 2
++#define STSD_RSPTYPE_R2 3
++#define STSD_RSPTYPE_R3 4
++#define STSD_RSPTYPE_R4 5
++#define STSD_RSPTYPE_R5 6
++#define STSD_RSPTYPE_R6 7
++#define STSD_RSPTYPE_R7 8
++
++/* card status bits */
++#define STSD_STATUS_CARD_INSERTED (1<<0)
++#define STSD_STATUS_CARD_INITIALIZED (1<<16)
++
++/* IOS errors */
++#define STSD_ERR_INVALID_CARD 0xc1000020
++
++/*
++ * Hardware registers.
++ */
++
++/*
++ * Simplified SD Host Controller Specification
++ * Version 2.00
++ * February 8, 2007
++ */
++
++/*
++ * SD Host Standard Registers
++ *
++ */
++
++/* we are recycling the stuff already in "../mmc/host/sdhci.h" */
++
++/* TMCLK*2^a a=[13..27] */
++#define STSD_TIMEOUT_CONTROL_DIV(a) (((a)-13)&0xf)
++
++static char stsd_dev_sdio_slot0[] = "/dev/sdio/slot0";
++
++/*
++ * Used to get/set the host controller hardware register values through IOS.
++ */
++struct stsd_reg_query {
++ u32 addr;
++ u32 _unk1;
++ u32 _unk2;
++ u32 size;
++ u32 data;
++ u32 _unk3;
++};
++
++/*
++ * Used to send commands to an SD card through IOS.
++ */
++struct stsd_command {
++ u32 opcode;
++ u32 cmdtype;
++ u32 rsptype;
++ u32 arg;
++ u32 blk_count;
++ u32 blk_size;
++ dma_addr_t dma_addr;
++ u32 is_dma;
++ u32 _unk2;
++};
++
++struct stsd_xfer {
++ size_t size;
++ enum dma_data_direction direction;
++
++ struct starlet_ioh_sg in[2], io[1];
++ struct stsd_command *cmd;
++
++ /* one-time initialized members */
++ void *reply;
++ size_t reply_len;
++ dma_addr_t dma_addr;
++ void *bounce_buf;
++ size_t bounce_buf_size;
++ size_t blk_size;
++};
++
++enum {
++ __STSD_MEDIA_CHANGED = 0,
++ __STSD_BAD_CARD,
++ __STSD_MANUAL_SETUP,
++ __STSD_SDHC,
++};
++
++struct stsd_host {
++ spinlock_t lock;
++ unsigned long flags;
++#define STSD_MEDIA_CHANGED (1<<__STSD_MEDIA_CHANGED)
++#define STSD_BAD_CARD (1<<__STSD_BAD_CARD)
++#define STSD_MANUAL_SETUP (1<<__STSD_MANUAL_SETUP)
++#define STSD_SDHC (1<<__STSD_SDHC)
++
++ /* u32 ocr; */
++ unsigned int f_max;
++ unsigned int clock;
++ u32 bus_width;
++
++ u16 status;
++
++ /* card related info */
++ struct mmc_card card;
++
++ int refcnt;
++
++ spinlock_t queue_lock;
++ struct request_queue *queue;
++ struct gendisk *disk;
++ unsigned int max_phys_segments;
++
++ struct stsd_xfer *xfer;
++
++ struct task_struct *io_thread;
++ struct mutex io_mutex;
++
++ int fd;
++ struct device *dev;
++};
++
++
++static const unsigned int tran_exp[] = {
++ 10000, 100000, 1000000, 10000000,
++ 0, 0, 0, 0
++};
++
++static const unsigned char tran_mant[] = {
++ 0, 10, 12, 13, 15, 20, 25, 30,
++ 35, 40, 45, 50, 55, 60, 70, 80,
++};
++
++static const unsigned int tacc_exp[] = {
++ 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000,
++};
++
++static const unsigned int tacc_mant[] = {
++ 0, 10, 12, 13, 15, 20, 25, 30,
++ 35, 40, 45, 50, 55, 60, 70, 80,
++};
++
++
++/*
++ * debug section
++ *
++ */
++
++#if defined(DEBUG) && 0
++
++#define __case_string(_s) \
++case _s: \
++ str = #_s; \
++ break;
++
++static char *stsd_opcode_string(u32 opcode)
++{
++ char *str = "unknown";
++
++ switch (opcode) {
++__case_string(MMC_GO_IDLE_STATE)
++__case_string(MMC_SEND_OP_COND)
++__case_string(MMC_ALL_SEND_CID)
++__case_string(MMC_SET_RELATIVE_ADDR)
++__case_string(MMC_SET_DSR)
++__case_string(MMC_SWITCH)
++__case_string(MMC_SELECT_CARD)
++__case_string(MMC_SEND_EXT_CSD)
++__case_string(MMC_SEND_CSD)
++__case_string(MMC_SEND_CID)
++__case_string(MMC_READ_DAT_UNTIL_STOP)
++__case_string(MMC_STOP_TRANSMISSION)
++__case_string(MMC_SEND_STATUS)
++__case_string(MMC_GO_INACTIVE_STATE)
++__case_string(MMC_SPI_READ_OCR)
++__case_string(MMC_SPI_CRC_ON_OFF)
++__case_string(MMC_SET_BLOCKLEN)
++__case_string(MMC_READ_SINGLE_BLOCK)
++__case_string(MMC_READ_MULTIPLE_BLOCK)
++__case_string(MMC_WRITE_DAT_UNTIL_STOP)
++__case_string(MMC_SET_BLOCK_COUNT)
++__case_string(MMC_WRITE_BLOCK)
++__case_string(MMC_WRITE_MULTIPLE_BLOCK)
++__case_string(MMC_PROGRAM_CID)
++__case_string(MMC_PROGRAM_CSD)
++__case_string(MMC_SET_WRITE_PROT)
++__case_string(MMC_CLR_WRITE_PROT)
++__case_string(MMC_SEND_WRITE_PROT)
++__case_string(MMC_ERASE_GROUP_START)
++__case_string(MMC_ERASE_GROUP_END)
++__case_string(MMC_ERASE)
++__case_string(MMC_FAST_IO)
++__case_string(MMC_GO_IRQ_STATE)
++__case_string(MMC_LOCK_UNLOCK)
++/*__case_string(SD_SEND_RELATIVE_ADDR)*/
++/*__case_string(SD_SEND_IF_COND)*/
++/*__case_string(SD_SWITCH)*/
++__case_string(SD_IO_SEND_OP_COND)
++__case_string(SD_IO_RW_DIRECT)
++__case_string(SD_IO_RW_EXTENDED)
++ }
++
++ return str;
++}
++
++static char *stsd_rsptype_string(u32 rsptype)
++{
++ char *str = "unknown";
++
++ switch (rsptype) {
++__case_string(STSD_RSPTYPE_NONE)
++__case_string(STSD_RSPTYPE_R1)
++__case_string(STSD_RSPTYPE_R1B)
++__case_string(STSD_RSPTYPE_R2)
++__case_string(STSD_RSPTYPE_R3)
++__case_string(STSD_RSPTYPE_R4)
++__case_string(STSD_RSPTYPE_R5)
++__case_string(STSD_RSPTYPE_R6)
++__case_string(STSD_RSPTYPE_R7)
++ }
++
++ return str;
++}
++
++static char *stsd_cmdtype_string(u32 cmdtype)
++{
++ char *str = "unknown";
++
++ switch (cmdtype) {
++__case_string(STSD_CMDTYPE_BC)
++__case_string(STSD_CMDTYPE_BCR)
++__case_string(STSD_CMDTYPE_AC)
++__case_string(STSD_CMDTYPE_ADTC)
++ }
++
++ return str;
++}
++
++static char *stsd_statusbit_string(u32 statusbit)
++{
++ char *str = "unknown";
++
++ switch (statusbit) {
++__case_string(R1_OUT_OF_RANGE)
++__case_string(R1_ADDRESS_ERROR)
++__case_string(R1_BLOCK_LEN_ERROR)
++__case_string(R1_ERASE_SEQ_ERROR)
++__case_string(R1_ERASE_PARAM)
++__case_string(R1_WP_VIOLATION)
++__case_string(R1_CARD_IS_LOCKED)
++__case_string(R1_LOCK_UNLOCK_FAILED)
++__case_string(R1_COM_CRC_ERROR)
++__case_string(R1_ILLEGAL_COMMAND)
++__case_string(R1_CARD_ECC_FAILED)
++__case_string(R1_CC_ERROR)
++__case_string(R1_ERROR)
++__case_string(R1_UNDERRUN)
++__case_string(R1_OVERRUN)
++__case_string(R1_CID_CSD_OVERWRITE)
++__case_string(R1_WP_ERASE_SKIP)
++__case_string(R1_CARD_ECC_DISABLED)
++__case_string(R1_ERASE_RESET)
++__case_string(R1_READY_FOR_DATA)
++__case_string(R1_APP_CMD)
++ }
++
++ return str;
++}
++
++static char *stsd_card_state_string(u32 status)
++{
++ char *str = "unknown";
++
++ switch (R1_CURRENT_STATE(status)) {
++ case 0:
++ str = "IDLE";
++ break;
++ case 1:
++ str = "READY";
++ break;
++ case 2:
++ str = "IDENT";
++ break;
++ case 3:
++ str = "STANDBY";
++ break;
++ case 4:
++ str = "TRANSFER";
++ break;
++ case 5:
++ str = "SEND";
++ break;
++ case 6:
++ str = "RECEIVE";
++ break;
++ case 7:
++ str = "PROGRAM";
++ break;
++ case 8:
++ str = "DISCONNECT";
++ break;
++ }
++
++ return str;
++}
++static void stsd_print_status(u32 status)
++{
++ u32 i, bit;
++
++ drv_printk(KERN_INFO, "card state %s\n",
++ stsd_card_state_string(status));
++
++ i = 13;
++ for (i = 13; i <= 31; i++) {
++ bit = 1 << i;
++ if ((status & bit))
++ drv_printk(KERN_INFO, "%02d %s\n", i,
++ stsd_statusbit_string(bit));
++ }
++ bit = 1 << 8;
++ if ((status & bit))
++ drv_printk(KERN_INFO, "%02d %s\n", 8,
++ stsd_statusbit_string(bit));
++ bit = 1 << 5;
++ if ((status & bit))
++ drv_printk(KERN_INFO, "%02d %s\n", 5,
++ stsd_statusbit_string(bit));
++}
++
++static void stsd_print_cid(struct mmc_cid *cid)
++{
++ drv_printk(KERN_INFO,
++ "manfid = %d\n"
++ "oemid = %d\n"
++ "prod_name = %s\n"
++ "hwrev = %d\n"
++ "fwrev = %d\n"
++ "serial = %08x\n"
++ "year = %d\n"
++ "month = %d\n",
++ cid->manfid,
++ cid->oemid,
++ cid->prod_name,
++ cid->hwrev, cid->fwrev, cid->serial, cid->year, cid->month);
++}
++
++static void stsd_print_csd(struct mmc_csd *csd)
++{
++ drv_printk(KERN_INFO,
++ "mmca_vsn = %d\n"
++ "cmdclass = %d\n"
++ "tacc_clks = %d\n"
++ "tacc_ns = %d\n"
++ "r2w_factor = %d\n"
++ "max_dtr = %d\n"
++ "read_blkbits = %d\n"
++ "write_blkbits = %d\n"
++ "capacity = %d\n"
++ "read_partial = %d\n"
++ "read_misalign = %d\n"
++ "write_partial = %d\n"
++ "write_misalign = %d\n",
++ csd->mmca_vsn,
++ csd->cmdclass,
++ csd->tacc_clks,
++ csd->tacc_ns,
++ csd->r2w_factor,
++ csd->max_dtr,
++ csd->read_blkbits,
++ csd->write_blkbits,
++ csd->capacity,
++ csd->read_partial,
++ csd->read_misalign,
++ csd->write_partial,
++ csd->write_misalign);
++}
++
++static void stsd_dump_hs_regs(struct stsd_host *host)
++{
++ drv_printk(KERN_DEBUG, "============== REGISTER DUMP ==============\n");
++
++ drv_printk(KERN_DEBUG, "Sys addr: 0x%08x | Version: 0x%08x\n",
++ stsd_hsr_in_u32(host, SDHCI_DMA_ADDRESS),
++ stsd_hsr_in_u16(host, SDHCI_HOST_VERSION));
++ drv_printk(KERN_DEBUG, "Blk size: 0x%08x | Blk cnt: 0x%08x\n",
++ stsd_hsr_in_u16(host, SDHCI_BLOCK_SIZE),
++ stsd_hsr_in_u16(host, SDHCI_BLOCK_COUNT));
++ drv_printk(KERN_DEBUG, "Argument: 0x%08x | Trn mode: 0x%08x\n",
++ stsd_hsr_in_u32(host, SDHCI_ARGUMENT),
++ stsd_hsr_in_u16(host, SDHCI_TRANSFER_MODE));
++ drv_printk(KERN_DEBUG, "Present: 0x%08x | Host ctl: 0x%08x\n",
++ stsd_hsr_in_u32(host, SDHCI_PRESENT_STATE),
++ stsd_hsr_in_u8(host, SDHCI_HOST_CONTROL));
++ drv_printk(KERN_DEBUG, "Power: 0x%08x | Blk gap: 0x%08x\n",
++ stsd_hsr_in_u8(host, SDHCI_POWER_CONTROL),
++ stsd_hsr_in_u8(host, SDHCI_BLOCK_GAP_CONTROL));
++ drv_printk(KERN_DEBUG, "Wake-up: 0x%08x | Clock: 0x%08x\n",
++ stsd_hsr_in_u8(host, SDHCI_WAKE_UP_CONTROL),
++ stsd_hsr_in_u16(host, SDHCI_CLOCK_CONTROL));
++ drv_printk(KERN_DEBUG, "Timeout: 0x%08x | Int stat: 0x%08x\n",
++ stsd_hsr_in_u8(host, SDHCI_TIMEOUT_CONTROL),
++ stsd_hsr_in_u32(host, SDHCI_INT_STATUS));
++ drv_printk(KERN_DEBUG, "Int enab: 0x%08x | Sig enab: 0x%08x\n",
++ stsd_hsr_in_u32(host, SDHCI_INT_ENABLE),
++ stsd_hsr_in_u32(host, SDHCI_SIGNAL_ENABLE));
++ drv_printk(KERN_DEBUG, "AC12 err: 0x%08x | Slot int: 0x%08x\n",
++ stsd_hsr_in_u16(host, SDHCI_ACMD12_ERR),
++ stsd_hsr_in_u16(host, SDHCI_SLOT_INT_STATUS));
++ drv_printk(KERN_DEBUG, "Caps: 0x%08x | Max curr: 0x%08x\n",
++ stsd_hsr_in_u32(host, SDHCI_CAPABILITIES),
++ stsd_hsr_in_u32(host, SDHCI_MAX_CURRENT));
++
++ drv_printk(KERN_DEBUG, "===========================================\n");
++}
++
++#endif /* DEBUG */
++
++/*
++ *
++ * MMC/SD data structures manipulation.
++ * Borrowed from MMC layer.
++ */
++
++#define UNSTUFF_BITS(resp, start, size) \
++ ({ \
++ const int __size = size; \
++ const u32 __mask = (__size < 32 ? 1 << __size : 0) - 1; \
++ const int __off = 3 - ((start) / 32); \
++ const int __shft = (start) & 31; \
++ u32 __res; \
++ \
++ __res = resp[__off] >> __shft; \
++ if (__size + __shft > 32) \
++ __res |= resp[__off-1] << ((32 - __shft) % 32); \
++ __res & __mask; \
++ })
++
++/*
++ * Given the decoded CSD structure, decode the raw CID to our CID structure.
++ */
++static void mmc_decode_cid(struct mmc_card *card)
++{
++ u32 *resp = card->raw_cid;
++
++ memset(&card->cid, 0, sizeof(struct mmc_cid));
++
++ /*
++ * SD doesn't currently have a version field so we will
++ * have to assume we can parse this.
++ */
++ card->cid.manfid = UNSTUFF_BITS(resp, 120, 8);
++ card->cid.oemid = UNSTUFF_BITS(resp, 104, 16);
++ card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8);
++ card->cid.prod_name[1] = UNSTUFF_BITS(resp, 88, 8);
++ card->cid.prod_name[2] = UNSTUFF_BITS(resp, 80, 8);
++ card->cid.prod_name[3] = UNSTUFF_BITS(resp, 72, 8);
++ card->cid.prod_name[4] = UNSTUFF_BITS(resp, 64, 8);
++ card->cid.hwrev = UNSTUFF_BITS(resp, 60, 4);
++ card->cid.fwrev = UNSTUFF_BITS(resp, 56, 4);
++ card->cid.serial = UNSTUFF_BITS(resp, 24, 32);
++ card->cid.year = UNSTUFF_BITS(resp, 12, 8);
++ card->cid.month = UNSTUFF_BITS(resp, 8, 4);
++
++ card->cid.year += 2000; /* SD cards year offset */
++}
++
++/*
++ * Given a 128-bit response, decode to our card CSD structure.
++ */
++static int mmc_decode_csd(struct mmc_card *card)
++{
++ struct mmc_csd *csd = &card->csd;
++ unsigned int e, m, csd_struct;
++ u32 *resp = card->raw_csd;
++
++ csd_struct = UNSTUFF_BITS(resp, 126, 2);
++
++ switch (csd_struct) {
++ case 0:
++ m = UNSTUFF_BITS(resp, 115, 4);
++ e = UNSTUFF_BITS(resp, 112, 3);
++ csd->tacc_ns = (tacc_exp[e] * tacc_mant[m] + 9) / 10;
++ csd->tacc_clks = UNSTUFF_BITS(resp, 104, 8) * 100;
++
++ m = UNSTUFF_BITS(resp, 99, 4);
++ e = UNSTUFF_BITS(resp, 96, 3);
++ csd->max_dtr = tran_exp[e] * tran_mant[m];
++ csd->cmdclass = UNSTUFF_BITS(resp, 84, 12);
++
++ e = UNSTUFF_BITS(resp, 47, 3);
++ m = UNSTUFF_BITS(resp, 62, 12);
++ csd->capacity = (1 + m) << (e + 2);
++
++ csd->read_blkbits = UNSTUFF_BITS(resp, 80, 4);
++ csd->read_partial = UNSTUFF_BITS(resp, 79, 1);
++ csd->write_misalign = UNSTUFF_BITS(resp, 78, 1);
++ csd->read_misalign = UNSTUFF_BITS(resp, 77, 1);
++ csd->r2w_factor = UNSTUFF_BITS(resp, 26, 3);
++ csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4);
++ csd->write_partial = UNSTUFF_BITS(resp, 21, 1);
++ break;
++ case 1:
++ /*
++ * This is a block-addressed SDHC card. Most
++ * interesting fields are unused and have fixed
++ * values. To avoid getting tripped by buggy cards,
++ * we assume those fixed values ourselves.
++ */
++ mmc_card_set_blockaddr(card);
++
++ csd->tacc_ns = 0; /* Unused */
++ csd->tacc_clks = 0; /* Unused */
++
++ m = UNSTUFF_BITS(resp, 99, 4);
++ e = UNSTUFF_BITS(resp, 96, 3);
++ csd->max_dtr = tran_exp[e] * tran_mant[m];
++ csd->cmdclass = UNSTUFF_BITS(resp, 84, 12);
++
++ m = UNSTUFF_BITS(resp, 48, 22);
++ csd->capacity = (1 + m) << 10;
++
++ csd->read_blkbits = 9;
++ csd->read_partial = 0;
++ csd->write_misalign = 0;
++ csd->read_misalign = 0;
++ csd->r2w_factor = 4; /* Unused */
++ csd->write_blkbits = 9;
++ csd->write_partial = 0;
++ break;
++ default:
++ printk(KERN_ERR "unrecognised CSD structure version %d\n",
++ csd_struct);
++ return -EINVAL;
++ }
++
++ /*stsd_print_csd(csd);*/
++
++ return 0;
++}
++
++/*
++ * REVISIT maybe get rid of this and specify the rsptype directly
++ */
++static u32 stsd_opcode_to_rsptype(u32 opcode)
++{
++ u32 rsptype = STSD_RSPTYPE_R1;
++
++ switch (opcode) {
++ case MMC_GO_IDLE_STATE:
++ case MMC_SET_DSR:
++ case MMC_GO_INACTIVE_STATE:
++ rsptype = STSD_RSPTYPE_NONE;
++ break;
++ case MMC_SWITCH:
++ case MMC_STOP_TRANSMISSION:
++ case MMC_SET_WRITE_PROT:
++ case MMC_CLR_WRITE_PROT:
++ case MMC_ERASE:
++ case MMC_LOCK_UNLOCK:
++ rsptype = STSD_RSPTYPE_R1B;
++ break;
++ case MMC_ALL_SEND_CID:
++ case MMC_SEND_CSD:
++ case MMC_SEND_CID:
++ rsptype = STSD_RSPTYPE_R2;
++ break;
++ case MMC_SEND_OP_COND:
++ case SD_APP_OP_COND:
++ rsptype = STSD_RSPTYPE_R3;
++ break;
++ case MMC_FAST_IO:
++ case SD_IO_SEND_OP_COND:
++ rsptype = STSD_RSPTYPE_R4;
++ break;
++ case MMC_GO_IRQ_STATE:
++ case SD_IO_RW_DIRECT:
++ case SD_IO_RW_EXTENDED:
++ rsptype = STSD_RSPTYPE_R5;
++ break;
++ case SD_SEND_RELATIVE_ADDR:
++ rsptype = STSD_RSPTYPE_R6;
++ break;
++ case SD_SEND_IF_COND:
++ /* WEIRD */
++ /*rsptype = STSD_RSPTYPE_R7;*/
++ rsptype = STSD_RSPTYPE_R6;
++ break;
++ default:
++ break;
++ }
++
++ return rsptype;
++}
++
++static inline void stsd_card_set_bad(struct stsd_host *host)
++{
++ set_bit(__STSD_BAD_CARD, &host->flags);
++}
++
++static inline void stsd_card_unset_bad(struct stsd_host *host)
++{
++ clear_bit(__STSD_BAD_CARD, &host->flags);
++}
++
++static inline int stsd_card_is_bad(struct stsd_host *host)
++{
++ return test_bit(__STSD_BAD_CARD, &host->flags);
++}
++
++static inline void stsd_card_set_sdhc(struct stsd_host *host)
++{
++ set_bit(__STSD_SDHC, &host->flags);
++}
++
++static inline void stsd_card_unset_sdhc(struct stsd_host *host)
++{
++ clear_bit(__STSD_SDHC, &host->flags);
++}
++
++static inline int stsd_card_is_sdhc(struct stsd_host *host)
++{
++ return test_bit(__STSD_SDHC, &host->flags);
++}
++
++static inline void stsd_card_set_manual_setup(struct stsd_host *host)
++{
++ set_bit(__STSD_MANUAL_SETUP, &host->flags);
++}
++
++static inline void stsd_card_unset_manual_setup(struct stsd_host *host)
++{
++ clear_bit(__STSD_MANUAL_SETUP, &host->flags);
++}
++
++static inline int stsd_card_needs_manual_setup(struct stsd_host *host)
++{
++ return test_bit(__STSD_MANUAL_SETUP, &host->flags);
++}
++
++static inline int stsd_card_status_is_inserted(u32 status)
++{
++ return (status & STSD_STATUS_CARD_INSERTED)
++ == STSD_STATUS_CARD_INSERTED;
++}
++
++static inline int stsd_card_status_is_initialized(u32 status)
++{
++ return (status & STSD_STATUS_CARD_INITIALIZED)
++ == STSD_STATUS_CARD_INITIALIZED;
++}
++
++/*
++ * Hardware.
++ *
++ */
++
++/*
++ * Handy small buffer routines.
++ * We use a small static aligned buffer to avoid allocations for short-lived
++ * operations involving 1 to 4 byte data transfers to/from IOS.
++ *
++ */
++
++static u32 stsd_small_buf[L1_CACHE_BYTES / sizeof(u32)]
++ __attribute__ ((aligned(STARLET_IPC_DMA_ALIGN + 1)));
++static const size_t stsd_small_buf_size = sizeof(stsd_small_buf_size);
++static DEFINE_MUTEX(stsd_small_buf_lock);
++
++static u32 *stsd_small_buf_get(void)
++{
++ u32 *buf;
++
++ if (!mutex_trylock(&stsd_small_buf_lock))
++ buf = starlet_kzalloc(stsd_small_buf_size, GFP_NOIO);
++ else {
++ memset(stsd_small_buf, 0, stsd_small_buf_size);
++ buf = stsd_small_buf;
++ }
++
++ return buf;
++}
++
++void stsd_small_buf_put(u32 *buf)
++{
++ if (buf == stsd_small_buf)
++ mutex_unlock(&stsd_small_buf_lock);
++ else
++ starlet_kfree(buf);
++}
++
++
++/*
++ * SD Host Standard Registers accessors.
++ *
++ */
++
++/*
++ * @data must be aligned
++ * @size must be between 1 and 4
++ */
++static int __stsd_hsr_in(struct stsd_host *host,
++ u32 addr, u32 *data, size_t size)
++{
++ struct stsd_reg_query *query;
++ int error;
++
++ query = starlet_kzalloc(sizeof(*query), GFP_ATOMIC);
++ if (!query)
++ return -ENOMEM;
++
++ query->addr = addr;
++ query->size = size;
++
++ error = starlet_ioctl(host->fd, STSD_IOCTL_GETHSR,
++ query, sizeof(*query), data, sizeof(*data));
++
++ starlet_kfree(query);
++
++ if (error)
++ DBG("%s: error=%d (%08x)\n", __func__, error, error);
++
++ return error;
++}
++
++static int __stsd_hsr_out(struct stsd_host *host,
++ u32 addr, u32 *data, size_t size)
++{
++ struct stsd_reg_query *query;
++ int error;
++
++ query = starlet_kzalloc(sizeof(*query), GFP_ATOMIC);
++ if (!query)
++ return -ENOMEM;
++
++ query->addr = addr;
++ query->size = size;
++ query->data = *data;
++
++ error = starlet_ioctl(host->fd, STSD_IOCTL_SETHSR,
++ query, sizeof(*query), NULL, 0);
++
++ starlet_kfree(query);
++
++ if (error)
++ DBG("%s: error=%d (%08x)\n", __func__, error, error);
++
++ return error;
++}
++
++
++static int stsd_hsr_in(struct stsd_host *host,
++ u32 reg, void *buf, size_t size)
++{
++ u32 *local_buf;
++ int error;
++
++ /* we do 8, 16 and 32 bits reads */
++ if (size > 4)
++ return -EINVAL;
++
++ local_buf = stsd_small_buf_get();
++ if (!local_buf)
++ return -ENOMEM;
++
++ error = __stsd_hsr_in(host, reg, local_buf, size);
++ if (!error) {
++ switch (size) {
++ case 1:
++ *(u8 *)buf = *local_buf & 0xff;
++ break;
++ case 2:
++ *(u16 *)buf = *local_buf & 0xffff;
++ break;
++ case 4:
++ *(u32 *)buf = *local_buf;
++ break;
++ default:
++ BUG();
++ break;
++ }
++ }
++
++ stsd_small_buf_put(local_buf);
++
++ return error;
++}
++
++static int stsd_hsr_out(struct stsd_host *host,
++ u32 reg, void *buf, size_t size)
++{
++ u32 *local_buf;
++ int error;
++
++ /* we do 8, 16 and 32 bits reads */
++ if (size > 4)
++ return -EINVAL;
++
++ local_buf = stsd_small_buf_get();
++ if (!local_buf)
++ return -ENOMEM;
++
++ switch (size) {
++ case 1:
++ *local_buf = *(u8 *)buf;
++ break;
++ case 2:
++ *local_buf = *(u16 *)buf;
++ break;
++ case 4:
++ *local_buf = *(u32 *)buf;
++ break;
++ default:
++ BUG();
++ break;
++ }
++ error = __stsd_hsr_out(host, reg, local_buf, size);
++
++ stsd_small_buf_put(local_buf);
++
++ return error;
++}
++
++#define __declare_stsd_hsr_wait_for_resp(_type) \
++static int stsd_hsr_wait_for_resp_##_type(struct stsd_host *host, \
++ u32 reg, _type resp, _type resp_mask, \
++ unsigned long jiffies) \
++{ \
++ _type val; \
++ int error; \
++ \
++ unsigned long cycles = 10; \
++ while (cycles-- > 0) { \
++ error = stsd_hsr_in(host, reg, &val, sizeof(val)); \
++ if (error) \
++ return error; \
++ if ((val & resp_mask) == resp) \
++ return 0; \
++ mdelay(10); \
++ } \
++ return -ENODATA; \
++}
++
++__declare_stsd_hsr_wait_for_resp(u8);
++__declare_stsd_hsr_wait_for_resp(u16);
++
++#define __declare_stsd_hsr_in(_type) \
++static inline _type stsd_hsr_in_##_type(struct stsd_host *host, u32 reg) \
++{ \
++ _type val; \
++ \
++ stsd_hsr_in(host, reg, &val, sizeof(val)); \
++ return val; \
++}
++
++__declare_stsd_hsr_in(u8);
++__declare_stsd_hsr_in(u16);
++__declare_stsd_hsr_in(u32);
++
++#define __declare_stsd_hsr_out(_type) \
++static inline void stsd_hsr_out_##_type(struct stsd_host *host, u32 reg,\
++ _type val) \
++{ \
++ stsd_hsr_out(host, reg, &val, sizeof(val)); \
++}
++
++__declare_stsd_hsr_out(u8);
++__declare_stsd_hsr_out(u16);
++__declare_stsd_hsr_out(u32);
++
++
++
++/*
++ * Ioctl helpers.
++ *
++ */
++
++static int stsd_ioctl_small_read(struct stsd_host *host, int request,
++ void *buf, size_t size)
++{
++ void *local_buf;
++ int error;
++
++ /* we do 8, 16 and 32 bits reads */
++ if (size > stsd_small_buf_size) {
++ error = -EINVAL;
++ goto done;
++ }
++
++ local_buf = stsd_small_buf_get();
++ if (!local_buf) {
++ error = -ENOMEM;
++ goto done;
++ }
++
++ error = starlet_ioctl(host->fd, request,
++ NULL, 0, local_buf, size);
++ if (!error)
++ memcpy(buf, local_buf, size);
++
++ stsd_small_buf_put(local_buf);
++
++done:
++ if (error)
++ DBG("%s: error=%d (%08x)\n", __func__, error, error);
++ return error;
++}
++
++static int stsd_ioctl_small_write(struct stsd_host *host, int request,
++ void *buf, size_t size)
++{
++ void *local_buf;
++ int error;
++
++ /* we do 8, 16 and 32 bits writes */
++ if (size > stsd_small_buf_size) {
++ error = -EINVAL;
++ goto done;
++ }
++
++ local_buf = stsd_small_buf_get();
++ if (!local_buf) {
++ error = -ENOMEM;
++ goto done;
++ }
++
++ memcpy(local_buf, buf, size);
++ error = starlet_ioctl(host->fd, request,
++ local_buf, size, NULL, 0);
++
++ stsd_small_buf_put(local_buf);
++
++done:
++ if (error)
++ DBG("%s: error=%d (%08x)\n", __func__, error, error);
++ return error;
++}
++
++
++/*
++ * Hardware interfaces.
++ *
++ */
++
++static int stsd_get_status(struct stsd_host *host, u32 *status)
++{
++ int error;
++
++ error = stsd_ioctl_small_read(host, STSD_IOCTL_GETSTATUS,
++ status, sizeof(*status));
++ if (error)
++ DBG("%s: error=%d (%08x)\n", __func__, error, error);
++
++ return error;
++}
++
++static void stsd_set_bus_width(struct stsd_host *host, int width)
++{
++ u8 hcr;
++
++ hcr = stsd_hsr_in_u8(host, SDHCI_HOST_CONTROL);
++ if (width == 4) {
++ hcr |= SDHCI_CTRL_4BITBUS;
++ } else {
++ hcr &= ~SDHCI_CTRL_4BITBUS;
++ width = 1;
++ }
++ stsd_hsr_out_u8(host, SDHCI_HOST_CONTROL, hcr);
++ host->bus_width = width;
++}
++
++static int stsd_set_clock(struct stsd_host *host, unsigned int clock)
++{
++ int error;
++ u32 divisor;
++
++ for (divisor = 1; divisor <= 32; divisor <<= 1) {
++ if (host->f_max / divisor <= clock)
++ break;
++ }
++
++ error = stsd_ioctl_small_write(host, STSD_IOCTL_SETCLOCK,
++ &divisor, sizeof(divisor));
++ if (error)
++ DBG("%s: error=%d (%08x)\n", __func__, error, error);
++ else
++ host->clock = clock;
++
++ return error;
++}
++
++static int stsd_reset_card(struct stsd_host *host)
++{
++ struct mmc_card *card = &host->card;
++ int error;
++ u32 status;
++
++ stsd_card_unset_bad(host);
++ stsd_card_unset_sdhc(host);
++ stsd_card_unset_manual_setup(host);
++
++ memset(&card->cid, 0, sizeof(struct mmc_cid));
++ memset(&card->csd, 0, sizeof(struct mmc_csd));
++ host->card.rca = 0;
++
++ error = stsd_ioctl_small_read(host, STSD_IOCTL_RESET,
++ &status, sizeof(status));
++ if (error) {
++ if (error != STSD_ERR_INVALID_CARD)
++ DBG("%s: error=%d (%08x)\n", __func__, error, error);
++ } else {
++ host->card.rca = status >> 16;
++ host->status = status & 0xffff;
++ }
++
++ return error;
++}
++
++#if 0
++static int stsd_get_ocr(struct stsd_host *host)
++{
++ int error;
++ u32 ocr;
++
++ error = stsd_ioctl_small_read(host, STSD_IOCTL_GETOCR,
++ &ocr, sizeof(ocr));
++ if (error)
++ DBG("%s: error=%d (%08x)\n", __func__, error, error);
++ else
++ host->ocr = ocr;
++
++ return error;
++}
++#endif
++
++/*
++ * Command engine.
++ *
++ */
++
++static int stsd_send_command(struct stsd_host *host,
++ u32 opcode, u32 type, u32 arg,
++ void *buf, size_t buf_len)
++{
++ struct scatterlist in[2], io[1];
++ struct stsd_command *cmd;
++ u32 *reply;
++ size_t reply_len;
++ int error;
++
++ reply_len = 4 * sizeof(u32);
++ if (buf_len > reply_len)
++ return -EINVAL;
++
++ cmd = starlet_kzalloc(sizeof(*cmd), GFP_NOIO);
++ if (!cmd)
++ return -ENOMEM;
++
++ reply = starlet_kzalloc(reply_len, GFP_NOIO);
++ if (!reply) {
++ starlet_kfree(cmd);
++ return -ENOMEM;
++ }
++
++ cmd->opcode = opcode;
++ cmd->arg = arg;
++
++ cmd->cmdtype = type;
++ cmd->rsptype = stsd_opcode_to_rsptype(opcode);
++ if (opcode == MMC_SELECT_CARD && arg == 0)
++ cmd->rsptype = STSD_RSPTYPE_NONE;
++
++ if (stsd_card_needs_manual_setup(host)) {
++ /*
++ * We need to use ioctlvs, instead of ioctls, to drive
++ * manually initialized cards.
++ * This makes IOS "cooperative" :)
++ */
++ sg_init_table(in, 2);
++ sg_set_buf(&in[0], cmd, sizeof(*cmd));
++ sg_set_buf(&in[1], reply, 0);
++
++ sg_init_table(io, 1);
++ sg_set_buf(&io[0], reply, reply_len);
++
++ error = starlet_ioctlv(host->fd, STSD_IOCTL_SENDCMD,
++ 2, in, 1, io);
++ } else {
++ error = starlet_ioctl(host->fd, STSD_IOCTL_SENDCMD,
++ cmd, sizeof(*cmd), reply, reply_len);
++ }
++
++ if (error) {
++ DBG("%s: error=%d (%08x), opcode=%d\n", __func__,
++ error, error, opcode);
++ } else {
++ if (buf)
++ memcpy(buf, reply, buf_len);
++ }
++
++ starlet_kfree(reply);
++ starlet_kfree(cmd);
++
++ return error;
++}
++
++static int stsd_send_app_command(struct stsd_host *host,
++ u32 opcode, u32 type, u32 arg,
++ void *buf, size_t buf_len)
++{
++ int error;
++
++ error = stsd_send_command(host, MMC_APP_CMD, STSD_CMDTYPE_AC,
++ host->card.rca << 16, NULL, 0);
++ if (!error) {
++ error = stsd_send_command(host, opcode, type, arg,
++ buf, buf_len);
++ }
++ return error;
++}
++
++
++/*
++ * Command helpers.
++ *
++ */
++
++
++static int stsd_cmd_read_cxd(struct stsd_host *host, int request, void *buf)
++{
++ int error;
++ u32 *q, savedq;
++ u8 *p, crc;
++ const size_t size = 128/8*sizeof(u8);
++
++ error = stsd_send_command(host, request, STSD_CMDTYPE_AC,
++ host->card.rca << 16, buf, size);
++
++ if (!error) {
++ /*
++ * WEIRD,
++ * starlet sends CSD and CID contents in a very special way.
++ *
++ * If the 128 bit register value is:
++ * 0123456789abcdef
++ * starlet will send it as:
++ * bcde789a3456f012
++ * with byte f (the crc field) zeroed.
++ */
++
++ /* bcde789a3456f012 -> f0123456789abcde */
++ q = buf;
++ savedq = q[0];
++ q[0] = q[3];
++ q[3] = savedq;
++ savedq = q[1];
++ q[1] = q[2];
++ q[2] = savedq;
++
++ /* f0123456789abcde -> 0123456789abcdef */
++ p = buf;
++ crc = p[0];
++ memcpy(p, p+1, size-1);
++ p[size-1] = crc;
++ }
++ return error;
++}
++
++static int stsd_cmd_read_csd(struct stsd_host *host)
++{
++ return stsd_cmd_read_cxd(host, MMC_SEND_CSD, host->card.raw_csd);
++}
++
++static int stsd_cmd_read_cid(struct stsd_host *host)
++{
++ return stsd_cmd_read_cxd(host, MMC_SEND_CID, host->card.raw_cid);
++}
++
++static int stsd_cmd_all_send_cid(struct stsd_host *host)
++{
++ const size_t size = 128/8*sizeof(u8);
++
++ /* WEIRD, don't use CMDTYPE_BCR for MMC_ALL_SEND_CID */
++ return stsd_send_command(host, MMC_ALL_SEND_CID, 0,
++ host->card.rca << 16,
++ host->card.raw_cid, size);
++}
++
++static int stsd_cmd_set_relative_addr(struct stsd_host *host, unsigned int rca)
++{
++ int error;
++ u32 reply;
++
++ error = stsd_send_command(host, MMC_SET_RELATIVE_ADDR, STSD_CMDTYPE_AC,
++ rca, &reply, sizeof(reply));
++ if (!error) {
++ host->card.rca = reply >> 16;
++ /* DBG("rca=%d, new_rca=%x\n", rca, host->card.rca); */
++ }
++ return error;
++}
++
++
++static int stsd_cmd_select_card(struct stsd_host *host)
++{
++ return stsd_send_command(host, MMC_SELECT_CARD, STSD_CMDTYPE_AC,
++ host->card.rca << 16,
++ NULL, 0);
++}
++
++static int stsd_cmd_deselect_card(struct stsd_host *host)
++{
++ return stsd_send_command(host, MMC_SELECT_CARD, STSD_CMDTYPE_AC,
++ 0,
++ NULL, 0);
++}
++
++static int stsd_cmd_set_block_len(struct stsd_host *host, unsigned int len)
++{
++ return stsd_send_command(host, MMC_SET_BLOCKLEN, STSD_CMDTYPE_AC,
++ len,
++ NULL, 0);
++}
++
++static int stsd_app_cmd_set_bus_width(struct stsd_host *host, int width)
++{
++ int error;
++ u16 val;
++
++ if (width == 4)
++ val = SD_BUS_WIDTH_4;
++ else
++ val = SD_BUS_WIDTH_1;
++
++ error = stsd_send_app_command(host, SD_APP_SET_BUS_WIDTH,
++ STSD_CMDTYPE_AC,
++ val, NULL, 0);
++ if (error)
++ DBG("%s: error=%d (%08x)\n", __func__, error, error);
++
++ return error;
++}
++
++
++
++static int stsd_setup_host_controller(struct stsd_host *host)
++{
++ const u32 mask = SDHCI_INT_RESPONSE | SDHCI_INT_DATA_END |
++ SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE |
++ SDHCI_INT_TIMEOUT | SDHCI_INT_CRC |
++ SDHCI_INT_END_BIT | SDHCI_INT_INDEX |
++ SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_DATA_CRC |
++ SDHCI_INT_ACMD12ERR;
++ u8 rst, pwr, clk_idx;
++ int error;
++
++ /*
++ * Reset host controller.
++ */
++
++ /* write 1 to the Reset All bit in the Software Reset register ... */
++ rst = SDHCI_RESET_ALL;
++ stsd_hsr_out_u8(host, SDHCI_SOFTWARE_RESET, rst);
++
++ /* ... then wait for the Reset All bit to be cleared */
++ error = stsd_hsr_wait_for_resp_u8(host, SDHCI_SOFTWARE_RESET,
++ 0, rst,
++ 100*(HZ/1000));
++ if (error) {
++ drv_printk(KERN_ERR, "host controller didn't get out of"
++ " reset\n");
++ goto done;
++ }
++
++ /*
++ * Setup interrupt sources.
++ */
++
++ /* ack the interrupt sources that IOS uses ... */
++ stsd_hsr_out_u32(host, SDHCI_INT_ENABLE, mask);
++ stsd_hsr_in_u32(host, SDHCI_INT_ENABLE);
++ /* ... then unmask them */
++ stsd_hsr_out_u32(host, SDHCI_SIGNAL_ENABLE, mask);
++ stsd_hsr_in_u32(host, SDHCI_SIGNAL_ENABLE);
++
++ /*
++ * Setup bus power.
++ */
++
++ /* FIXME, we should use capabilities register here */
++ /* for now use 3.3V setting */
++ pwr = SDHCI_POWER_330;
++
++ /* turn on bus power and use selected voltage setting */
++ stsd_hsr_out_u8(host, SDHCI_POWER_CONTROL, pwr & ~SDHCI_POWER_ON);
++ stsd_hsr_out_u8(host, SDHCI_POWER_CONTROL, pwr | SDHCI_POWER_ON);
++
++ /*
++ * Initialize clocks.
++ */
++
++ /* FIXME, we should use capabilities register here */
++ /* for now use index 01h which is base clock divided by 2 */
++ clk_idx = 1;
++
++ /* disable clock signalling... */
++ stsd_hsr_out_u16(host, SDHCI_CLOCK_CONTROL, 0);
++ /* ... then enable internal clock ... */
++ stsd_hsr_out_u16(host, SDHCI_CLOCK_CONTROL,
++ SDHCI_CLOCK_INT_EN |
++ (clk_idx << SDHCI_DIVIDER_SHIFT));
++ /* ... and wait until it gets stable */
++ error = stsd_hsr_wait_for_resp_u16(host, SDHCI_CLOCK_CONTROL,
++ SDHCI_CLOCK_INT_STABLE,
++ SDHCI_CLOCK_INT_STABLE,
++ 1*HZ);
++ if (error) {
++ drv_printk(KERN_ERR, "internal clock didn't get stable\n");
++ goto done;
++ }
++
++ /* SD clock can be enabled now */
++ stsd_hsr_out_u16(host, SDHCI_CLOCK_CONTROL,
++ SDHCI_CLOCK_INT_EN |
++ SDHCI_CLOCK_CARD_EN |
++ (1 << SDHCI_DIVIDER_SHIFT));
++
++ /*
++ * Setup timeout.
++ */
++
++ /* setup timeout to TMCLK * 2^27 */
++ stsd_hsr_out_u8(host, SDHCI_TIMEOUT_CONTROL,
++ STSD_TIMEOUT_CONTROL_DIV(27));
++
++done:
++ if (error)
++ DBG("%s: error=%d (%08x)\n", __func__, error, error);
++
++ return error;
++}
++
++static int stsd_setup_card(struct stsd_host *host)
++{
++ const u8 check_pattern = 0xaa;
++ u32 arg;
++ u32 resp[4];
++ int i;
++ int error;
++
++ /* WEIRD, don't use CMDTYPE_BC for MMC_GO_IDLE_STATE */
++ error = stsd_send_command(host, MMC_GO_IDLE_STATE, 0,
++ 0, NULL, 0);
++ if (error)
++ goto done;
++
++#define STSD_VHS(a) ((((a)&0x0f)<<8))
++#define STSD_VHS_27_36 STSD_VHS(0x1)
++
++ /* WEIRD, don't use CMDTYPE_BC for SD_SEND_IF_COND */
++ arg = STSD_VHS_27_36 | check_pattern;
++ error = stsd_send_command(host, SD_SEND_IF_COND, 0,
++ arg, &resp, sizeof(resp));
++ if (error)
++ goto done;
++
++ if ((resp[0] & 0xff) != check_pattern) {
++ DBG("arg=0x%x, resp[0]=0x%x\n", arg, resp[0]);
++ error = -ENODEV;
++ goto done;
++ }
++
++ /*
++ * At this point we have identified a v2.00 SD Memory Card.
++ *
++ */
++
++ /*
++ * Get OCR
++ */
++
++#define STSD_OCR_HCS (1<<30) /* Host Capacity Support */
++#define STSD_OCR_CCS (1<<30) /* Card Capacity Support */
++
++ for (i = 0; i < 100; i++) {
++ /* WEIRD, don't use CMDTYPE_BCR for MMC_APP_CMD */
++ error = stsd_send_command(host, MMC_APP_CMD, STSD_CMDTYPE_AC,
++ 0, NULL, 0);
++ if (error)
++ goto done;
++
++ /* WEIRD, don't use CMDTYPE_BCR for SD_APP_OP_COND */
++ error = stsd_send_command(host, SD_APP_OP_COND, 0,
++ STSD_OCR_HCS|
++ MMC_VDD_32_33|MMC_VDD_33_34,
++ &resp, sizeof(resp));
++ if (error)
++ goto done;
++
++ if ((resp[0] & MMC_CARD_BUSY) != 0) {
++ /* card power up completed */
++ break;
++ }
++
++ error = -ETIMEDOUT;
++ mdelay(10);
++ }
++ if (error) {
++ drv_printk(KERN_ERR, "timed out while trying to get OCR\n");
++ goto done;
++ }
++
++ if ((resp[0] & STSD_OCR_CCS) != 0) {
++ /* high capacity card */
++ stsd_card_set_sdhc(host);
++ }
++
++ error = stsd_cmd_all_send_cid(host);
++ if (error)
++ goto done;
++
++ error = stsd_cmd_set_relative_addr(host, 0);
++ if (error)
++ goto done;
++
++done:
++ if (error)
++ DBG("%s: error=%d (%08x)\n", __func__, error, error);
++ return error;
++}
++
++static int stsd_reopen_sdio(struct stsd_host *host)
++{
++ int error = 0;
++
++ starlet_close(host->fd);
++ host->fd = starlet_open(stsd_dev_sdio_slot0, 1);
++ if (host->fd < 0) {
++ drv_printk(KERN_ERR, "unable to re-open %s\n",
++ stsd_dev_sdio_slot0);
++ error = -ENODEV;
++ }
++ return error;
++}
++
++
++static int stsd_welcome_card(struct stsd_host *host)
++{
++ size_t block_len; /* in bytes */
++ u32 status;
++ int error;
++
++ mutex_lock(&host->io_mutex);
++
++ /*
++ * Re-open the sdio device if things look wrong.
++ */
++ error = stsd_get_status(host, &status);
++ if (error == STARLET_EINVAL) {
++ error = stsd_reopen_sdio(host);
++ if (error)
++ goto err_bad_card;
++ }
++
++ /*
++ * Try a normal initialization sequence first, and revert to
++ * manual mode if that fails.
++ */
++
++ stsd_reset_card(host);
++
++ error = stsd_get_status(host, &status);
++ if (error)
++ goto err_bad_card;
++ if (!stsd_card_status_is_inserted(status)) {
++ drv_printk(KERN_ERR, "no card found\n");
++ goto err_bad_card;
++ }
++
++ if (!stsd_card_status_is_initialized(status)) {
++ /* manual initialization, needed for SDHC support */
++ stsd_card_set_manual_setup(host);
++
++ error = stsd_reopen_sdio(host);
++ if (error)
++ goto err_bad_card;
++
++ error = stsd_setup_host_controller(host);
++ if (error)
++ goto err_bad_card;
++
++ error = stsd_setup_card(host);
++ if (error)
++ goto err_bad_card;
++ }
++
++#if 0
++ /* read Operating Conditions Register */
++ error = stsd_get_ocr(host);
++ if (error < 0)
++ goto err_bad_card;
++#endif
++
++ error = stsd_cmd_deselect_card(host);
++ if (error)
++ goto err_bad_card;
++
++ /* read and decode the Card Specific Data */
++ error = stsd_cmd_read_csd(host);
++ if (error)
++ goto err_bad_card;
++ mmc_decode_csd(&host->card);
++
++ /* read and decode the Card Identification Data */
++ error = stsd_cmd_read_cid(host);
++ if (error)
++ goto err_bad_card;
++ mmc_decode_cid(&host->card);
++
++ error = stsd_cmd_select_card(host);
++ if (error)
++ goto err_bad_card;
++
++ stsd_set_clock(host, host->card.csd.max_dtr);
++
++ /* FIXME check if card supports 4 bit bus width */
++ stsd_set_bus_width(host, 4);
++ error = stsd_app_cmd_set_bus_width(host, 4);
++ if (error)
++ goto err_bad_card;
++
++ /* setup block length */
++ block_len = KERNEL_SECTOR_SIZE;
++ error = stsd_cmd_set_block_len(host, block_len);
++ if (error)
++ goto err_bad_card;
++
++#if 0
++ mmc_card_set_present(&host->card);
++#endif
++
++ mutex_unlock(&host->io_mutex);
++
++ drv_printk(KERN_INFO, "descr \"%s\", size %luk, block %ub,"
++ " serial %08x\n",
++ host->card.cid.prod_name,
++ (unsigned long)((host->card.csd.capacity / 1024) *
++ (1 << host->card.csd.read_blkbits)),
++ 1 << host->card.csd.read_blkbits,
++ host->card.cid.serial);
++
++ error = 0;
++ goto out;
++
++err_bad_card:
++ mutex_unlock(&host->io_mutex);
++ stsd_card_set_bad(host);
++out:
++ return error;
++}
++
++
++/*
++ * Block layer helper routines.
++ *
++ */
++
++static int stsd_do_block_transfer(struct stsd_host *host, int write,
++ unsigned long start,
++ void *buf, size_t nr_blocks)
++{
++ struct stsd_xfer *xfer = host->xfer;
++ struct stsd_command *cmd = xfer->cmd;
++ int error;
++
++ xfer->direction = (write) ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
++ xfer->size = nr_blocks * xfer->blk_size;
++
++ if (xfer->size > xfer->bounce_buf_size) {
++ drv_printk(KERN_ERR, "oops, request size %d > %d\n",
++ xfer->size, xfer->bounce_buf_size);
++ return -ENOMEM;
++ }
++
++ /*
++ * This is stupid.
++ * Starlet expects the buffer to be an input iovec (from starlet
++ * point of view) even for reads. Thus, map the buffer explicitly here.
++ */
++ if (write)
++ memcpy(xfer->bounce_buf, buf, xfer->size);
++ __dma_sync(xfer->bounce_buf, xfer->size, xfer->direction);
++/*
++ xfer->dma_addr = dma_map_single(host->dev, buf,
++ xfer->size, xfer->direction);
++*/
++
++ starlet_ioh_sg_init_table(xfer->in, 2);
++ starlet_ioh_sg_set_buf(&xfer->in[0], cmd, sizeof(*cmd));
++ starlet_ioh_sg_set_buf(&xfer->in[1], xfer->bounce_buf, xfer->size);
++
++ starlet_ioh_sg_init_table(xfer->io, 1);
++ starlet_ioh_sg_set_buf(&xfer->io[0], xfer->reply, xfer->reply_len);
++
++ cmd->opcode = (write) ? MMC_WRITE_MULTIPLE_BLOCK :
++ MMC_READ_MULTIPLE_BLOCK;
++ cmd->arg = start;
++ cmd->cmdtype = STSD_CMDTYPE_AC; /* STSD_CMDTYPE_ADTC */
++ cmd->rsptype = stsd_opcode_to_rsptype(cmd->opcode);
++ cmd->blk_count = nr_blocks;
++ cmd->blk_size = xfer->blk_size;
++ cmd->dma_addr = xfer->dma_addr; /* bounce buf */
++ cmd->is_dma = 1;
++
++ error = starlet_ioh_ioctlv(host->fd, STSD_IOCTLV_SENDCMD,
++ 2, xfer->in, 1, xfer->io);
++/*
++ dma_unmap_single(host->dev,
++ xfer->dma_addr, xfer->size, xfer->direction);
++*/
++
++ if (!write)
++ memcpy(buf, xfer->bounce_buf, xfer->size);
++
++ if (error)
++ DBG("%s: error=%d (%08x)\n", __func__, error, error);
++
++ return error;
++}
++
++/*
++ * Returns >0 if a request should be dispatched.
++ */
++static int stsd_check_request(struct stsd_host *host, struct request *req)
++{
++ unsigned long nr_sectors;
++
++ if (test_bit(__STSD_MEDIA_CHANGED, &host->flags)) {
++ drv_printk(KERN_ERR, "media changed, aborting\n");
++ return -ENOMEDIUM;
++ }
++
++ /* unit is kernel sectors */
++ nr_sectors =
++ host->card.csd.capacity << (host->card.csd.read_blkbits -
++ KERNEL_SECTOR_SHIFT);
++
++ /* keep our reads within limits */
++ if (req->sector + req->current_nr_sectors > nr_sectors) {
++ drv_printk(KERN_ERR, "reading past end, aborting\n");
++ return -EINVAL;
++ }
++
++ if (!blk_fs_request(req))
++ return 0;
++
++ return 1;
++}
++
++static int stsd_do_request(struct stsd_host *host, struct request *req)
++{
++ unsigned long nr_blocks; /* in card blocks */
++ unsigned long start;
++ int write;
++ int uptodate;
++ int error;
++
++ uptodate = stsd_check_request(host, req);
++ if (uptodate <= 0)
++ return uptodate;
++
++ write = (rq_data_dir(req) == READ) ? 0 : 1;
++
++ start = req->sector;
++ if (!stsd_card_is_sdhc(host))
++ start <<= KERNEL_SECTOR_SHIFT;
++ nr_blocks = req->current_nr_sectors;
++
++ error = stsd_do_block_transfer(host, write,
++ start, req->buffer, nr_blocks);
++ if (error)
++ DBG("%s: error=%d (%08x), start=%lu, \n", __func__,
++ error, error, start);
++
++ return error;
++}
++
++static int stsd_io_thread(void *param)
++{
++ struct stsd_host *host = param;
++ struct request *req;
++ unsigned long flags;
++ int error;
++
++ current->flags |= PF_NOFREEZE|PF_MEMALLOC;
++
++ mutex_lock(&host->io_mutex);
++ for (;;) {
++ req = NULL;
++ set_current_state(TASK_INTERRUPTIBLE);
++
++ spin_lock_irqsave(&host->queue_lock, flags);
++ if (!blk_queue_plugged(host->queue))
++ req = elv_next_request(host->queue);
++ spin_unlock_irqrestore(&host->queue_lock, flags);
++
++ if (!req) {
++ if (kthread_should_stop()) {
++ set_current_state(TASK_RUNNING);
++ break;
++ }
++ mutex_unlock(&host->io_mutex);
++ schedule();
++ mutex_lock(&host->io_mutex);
++ continue;
++ }
++ set_current_state(TASK_INTERRUPTIBLE);
++ error = stsd_do_request(host, req);
++
++ spin_lock_irqsave(&host->queue_lock, flags);
++ __blk_end_request(req, error, blk_rq_bytes(req));
++ spin_unlock_irqrestore(&host->queue_lock, flags);
++ }
++ mutex_unlock(&host->io_mutex);
++
++ return 0;
++}
++
++static void stsd_request_func(struct request_queue *q)
++{
++ struct stsd_host *host = q->queuedata;
++
++ wake_up_process(host->io_thread);
++}
++
++/*
++ * Block device hooks.
++ *
++ */
++
++static DECLARE_MUTEX(open_lock);
++
++static int stsd_open(struct block_device *bdev, fmode_t mode)
++{
++ struct stsd_host *host = bdev->bd_disk->private_data;
++ int error = 0;
++
++ if (!host || host->fd < 0)
++ return -ENXIO;
++
++ /* honor exclusive open mode */
++ if (host->refcnt == -1 ||
++ (host->refcnt && (mode & FMODE_EXCL))) {
++ error = -EBUSY;
++ goto out;
++ }
++
++ /* this takes care of revalidating the media if needed */
++ check_disk_change(bdev);
++ if (!host->card.csd.capacity) {
++ error = -ENOMEDIUM;
++ goto out;
++ }
++
++ down(&open_lock);
++
++ if ((mode & FMODE_EXCL))
++ host->refcnt = -1;
++ else
++ host->refcnt++;
++
++ up(&open_lock);
++
++out:
++ return error;
++
++}
++
++static int stsd_release(struct gendisk *disk, fmode_t mode)
++{
++ struct stsd_host *host = disk->private_data;
++
++ if (!host)
++ return -ENXIO;
++
++ down(&open_lock);
++
++ if (host->refcnt > 0)
++ host->refcnt--;
++ else
++ host->refcnt = 0;
++
++ up(&open_lock);
++
++ if (!host->refcnt && host->fd == -1)
++ kfree(host);
++
++ return 0;
++}
++
++static int stsd_media_changed(struct gendisk *disk)
++{
++ struct stsd_host *host = disk->private_data;
++ unsigned int last_serial;
++ int error;
++
++ /* report a media change for zombies */
++ if (!host)
++ return 1;
++
++ /* report a media change if someone forced it */
++ if (test_bit(__STSD_MEDIA_CHANGED, &host->flags))
++ return 1;
++
++ /* REVISIT use the starlet provided iotcl to check the status */
++
++ mutex_lock(&host->io_mutex);
++
++ /* check if the serial number of the card changed */
++ last_serial = host->card.cid.serial;
++ error = stsd_cmd_deselect_card(host);
++ if (!error) {
++ error = stsd_cmd_read_cid(host);
++ if (!error)
++ error = stsd_cmd_select_card(host);
++ }
++
++ mutex_unlock(&host->io_mutex);
++
++ if (!error && last_serial == host->card.cid.serial && last_serial)
++ clear_bit(__STSD_MEDIA_CHANGED, &host->flags);
++ else
++ set_bit(__STSD_MEDIA_CHANGED, &host->flags);
++
++ return (host->flags & STSD_MEDIA_CHANGED) ? 1 : 0;
++}
++
++static int stsd_revalidate_disk(struct gendisk *disk)
++{
++ struct stsd_host *host = disk->private_data;
++ int error = 0;
++
++ /* report missing medium for zombies */
++ if (!host) {
++ error = -ENOMEDIUM;
++ goto out;
++ }
++
++ /* the block layer likes to call us multiple times... */
++ if (!stsd_media_changed(host->disk))
++ goto out;
++
++ /* get the card into a known status */
++ error = stsd_welcome_card(host);
++ if (error < 0 || stsd_card_is_bad(host)) {
++ drv_printk(KERN_ERR, "card welcome failed\n");
++ if (stsd_card_is_bad(host))
++ drv_printk(KERN_ERR, "stsd_card_is_bad() true\n");
++ if (error < 0)
++ drv_printk(KERN_ERR, "error = %d\n", error);
++ error = -ENOMEDIUM;
++ /* FALL THROUGH */
++ }
++
++ /* inform the block layer about various sizes */
++ blk_queue_hardsect_size(host->queue, KERNEL_SECTOR_SIZE);
++ set_capacity(host->disk, host->card.csd.capacity <<
++ (host->card.csd.read_blkbits - KERNEL_SECTOR_SHIFT));
++
++ clear_bit(__STSD_MEDIA_CHANGED, &host->flags);
++
++out:
++ if (error)
++ DBG("%s: error=%d (%08x)\n", __func__, error, error);
++ return error;
++}
++
++static int stsd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
++{
++ geo->cylinders = get_capacity(bdev->bd_disk) / (4 * 16);
++ geo->heads = 4;
++ geo->sectors = 16;
++ return 0;
++}
++
++static struct block_device_operations stsd_fops = {
++ .owner = THIS_MODULE,
++ .open = stsd_open,
++ .release = stsd_release,
++ .revalidate_disk = stsd_revalidate_disk,
++ .media_changed = stsd_media_changed,
++ .getgeo = stsd_getgeo,
++};
++
++/*
++ * Setup routines.
++ *
++ */
++
++static int stsd_init_xfer(struct stsd_host *host)
++{
++ struct stsd_xfer *xfer;
++
++ xfer = starlet_kzalloc(sizeof(*xfer), GFP_KERNEL);
++ if (!xfer)
++ return -ENOMEM;
++
++ xfer->reply_len = 4 * sizeof(u32);
++ xfer->reply = starlet_ioh_kzalloc(xfer->reply_len);
++ if (!xfer->reply) {
++ starlet_kfree(xfer);
++ return -ENOMEM;
++ }
++ xfer->cmd = starlet_ioh_kzalloc(sizeof(*xfer->cmd));
++ if (!xfer->cmd) {
++ starlet_ioh_kfree(xfer->reply);
++ starlet_kfree(xfer);
++ return -ENOMEM;
++ }
++ xfer->bounce_buf_size = STSD_MAX_SECTORS * KERNEL_SECTOR_SIZE;
++ xfer->bounce_buf = starlet_ioh_kzalloc(xfer->bounce_buf_size);
++ if (!xfer->bounce_buf) {
++ starlet_ioh_kfree(xfer->cmd);
++ starlet_ioh_kfree(xfer->reply);
++ starlet_kfree(xfer);
++ return -ENOMEM;
++ }
++ xfer->dma_addr = starlet_ioh_virt_to_phys(xfer->bounce_buf);
++
++ xfer->blk_size = KERNEL_SECTOR_SIZE;
++
++ host->xfer = xfer;
++
++ return 0;
++}
++
++static void stsd_exit_xfer(struct stsd_host *host)
++{
++ struct stsd_xfer *xfer = host->xfer;
++
++ starlet_ioh_kfree(xfer->cmd);
++ starlet_ioh_kfree(xfer->reply);
++ starlet_kfree(host->xfer);
++}
++
++static int stsd_init_blk_dev(struct stsd_host *host)
++{
++ struct gendisk *disk;
++ struct request_queue *queue;
++ int error;
++
++ mutex_init(&host->io_mutex);
++
++ /* queue */
++ error = -ENOMEM;
++ spin_lock_init(&host->queue_lock);
++ queue = blk_init_queue(stsd_request_func, &host->queue_lock);
++ if (!queue) {
++ drv_printk(KERN_ERR, "error initializing queue\n");
++ goto err_blk_init_queue;
++ }
++ host->max_phys_segments = 1;
++ blk_queue_max_phys_segments(queue, host->max_phys_segments);
++ blk_queue_max_hw_segments(queue, host->max_phys_segments);
++ blk_queue_max_sectors(queue, STSD_MAX_SECTORS); /* 16 * 512 = 8K */
++ blk_queue_dma_alignment(queue, STARLET_IPC_DMA_ALIGN);
++ queue->queuedata = host;
++ host->queue = queue;
++
++ /* disk */
++ disk = alloc_disk(1 << MMC_SHIFT);
++ if (!disk) {
++ drv_printk(KERN_ERR, "error allocating disk\n");
++ goto err_alloc_disk;
++ }
++ disk->major = STSD_MAJOR;
++ disk->first_minor = 0 << MMC_SHIFT;
++ disk->fops = &stsd_fops;
++ sprintf(disk->disk_name, "%s%c", STSD_NAME, 'a');
++ disk->private_data = host;
++ disk->queue = host->queue;
++ host->disk = disk;
++
++ error = 0;
++ goto out;
++
++err_alloc_disk:
++ blk_cleanup_queue(host->queue);
++ host->queue = NULL;
++err_blk_init_queue:
++out:
++ return error;
++}
++
++static void stsd_exit_blk_dev(struct stsd_host *host)
++{
++ blk_cleanup_queue(host->queue);
++ put_disk(host->disk);
++}
++
++static int stsd_init_io_thread(struct stsd_host *host)
++{
++ int result = 0;
++
++ host->io_thread = kthread_run(stsd_io_thread, host, "ksdio");
++ if (IS_ERR(host->io_thread)) {
++ drv_printk(KERN_ERR, "error creating io thread\n");
++ result = PTR_ERR(host->io_thread);
++ }
++ return result;
++}
++
++static void stsd_exit_io_thread(struct stsd_host *host)
++{
++ if (!IS_ERR(host->io_thread)) {
++ wake_up_process(host->io_thread);
++ kthread_stop(host->io_thread);
++ host->io_thread = ERR_PTR(-EINVAL);
++ }
++}
++
++static int stsd_init(struct stsd_host *host)
++{
++ int error;
++
++ host->refcnt = 0;
++ spin_lock_init(&host->lock);
++ set_bit(__STSD_MEDIA_CHANGED, &host->flags);
++ host->f_max = 25000000; /* 25MHz */
++
++ host->fd = starlet_open(stsd_dev_sdio_slot0, 0);
++ if (host->fd < 0) {
++ drv_printk(KERN_ERR, "unable to open %s\n",
++ stsd_dev_sdio_slot0);
++ return -ENODEV;
++ }
++
++ error = stsd_init_blk_dev(host);
++ if (error)
++ goto out;
++
++ error = stsd_init_xfer(host);
++ if (error)
++ goto err_blk_dev;
++
++ error = stsd_revalidate_disk(host->disk);
++#if 0
++ if (error < 0 || !mmc_card_present(&host->card)) {
++ error = -ENODEV;
++ goto err_xfer;
++ }
++#endif
++
++ error = stsd_init_io_thread(host);
++ if (error)
++ goto err_xfer;
++
++ add_disk(host->disk);
++
++ return 0;
++
++err_xfer:
++ stsd_exit_xfer(host);
++err_blk_dev:
++ stsd_exit_blk_dev(host);
++out:
++ return error;
++}
++
++static void stsd_exit(struct stsd_host *host)
++{
++ del_gendisk(host->disk);
++ stsd_exit_io_thread(host);
++ stsd_exit_xfer(host);
++ stsd_exit_blk_dev(host);
++ if (host->fd >= 0)
++ starlet_close(host->fd);
++ host->fd = -1;
++
++}
++
++static void stsd_kill(struct stsd_host *host)
++{
++ if (host->refcnt > 0) {
++ drv_printk(KERN_ERR, "hey! card removed while in use!\n");
++ set_bit(__STSD_MEDIA_CHANGED, &host->flags);
++ }
++
++ stsd_exit(host);
++
++ /* release the host immediately when not in use */
++ if (!host->refcnt)
++ kfree(host);
++}
++
++/*
++ * Driver model helper routines.
++ *
++ */
++
++static int __devinit stsd_do_probe(struct device *dev)
++{
++ struct stsd_host *host;
++ int error;
++
++ host = kzalloc(sizeof(*host), GFP_KERNEL);
++ if (!host) {
++ drv_printk(KERN_ERR, "%s: failed to allocate stsd_host\n",
++ __func__);
++ return -ENOMEM;
++ }
++ dev_set_drvdata(dev, host);
++ host->dev = dev;
++
++ error = stsd_init(host);
++ if (error) {
++ kfree(host);
++ dev_set_drvdata(dev, NULL);
++ }
++
++ return error;
++}
++
++static int __devexit stsd_do_remove(struct device *dev)
++{
++ struct stsd_host *host = dev_get_drvdata(dev);
++
++ if (!host)
++ return -ENODEV;
++
++ stsd_kill(host);
++ dev_set_drvdata(dev, NULL);
++
++ return 0;
++}
++
++/*
++ * OF platform device routines.
++ *
++ */
++
++static int __init stsd_of_probe(struct of_device *odev,
++ const struct of_device_id *match)
++{
++ return stsd_do_probe(&odev->dev);
++}
++
++static int __exit stsd_of_remove(struct of_device *odev)
++{
++ return stsd_do_remove(&odev->dev);
++}
++
++static struct of_device_id stsd_of_match[] = {
++ { .compatible = "nintendo,starlet-sd" },
++ { },
++};
++
++MODULE_DEVICE_TABLE(of, stsd_of_match);
++
++static struct of_platform_driver stsd_of_driver = {
++ .owner = THIS_MODULE,
++ .name = DRV_MODULE_NAME,
++ .match_table = stsd_of_match,
++ .probe = stsd_of_probe,
++ .remove = stsd_of_remove,
++};
++
++
++/*
++ * Kernel module interface.
++ *
++ */
++
++static int __init stsd_init_module(void)
++{
++ drv_printk(KERN_INFO, "%s - version %s\n", DRV_DESCRIPTION,
++ stsd_driver_version);
++
++ if (register_blkdev(STSD_MAJOR, DRV_MODULE_NAME)) {
++ drv_printk(KERN_ERR, "unable to register major %d\n",
++ STSD_MAJOR);
++ return -EIO;
++ }
++
++ return of_register_platform_driver(&stsd_of_driver);
++}
++
++static void __exit stsd_exit_module(void)
++{
++ of_unregister_platform_driver(&stsd_of_driver);
++ unregister_blkdev(STSD_MAJOR, DRV_MODULE_NAME);
++}
++
++module_init(stsd_init_module);
++module_exit(stsd_exit_module);
++
++MODULE_AUTHOR(DRV_AUTHOR);
++MODULE_DESCRIPTION(DRV_DESCRIPTION);
++MODULE_LICENSE("GPL");
++
+diff --git a/drivers/exi/Kconfig b/drivers/exi/Kconfig
+new file mode 100644
+index 0000000..c810782
+--- /dev/null
++++ b/drivers/exi/Kconfig
+@@ -0,0 +1,20 @@
++#
++# Nintendo GameCube EXI (Expansion Interface) support.
++#
++
++if GAMECUBE_COMMON
++
++menu "EXI support"
++
++config GAMECUBE_EXI
++ bool "Nintendo GameCube/Wii External Interface (EXI)"
++ default y
++ help
++ On the External Interface sit the memory card slots,
++ serial ports I & II, the Mask ROM, RTC, SRAM and UART.
++
++ If in doubt, say Y here.
++
++endmenu
++
++endif
+diff --git a/drivers/exi/Makefile b/drivers/exi/Makefile
+new file mode 100644
+index 0000000..eb80bce
+--- /dev/null
++++ b/drivers/exi/Makefile
+@@ -0,0 +1,5 @@
++#
++# Makefile for the EXI bus core.
++#
++
++obj-$(CONFIG_GAMECUBE_EXI) += exi-driver.o exi-hw.o
+diff --git a/drivers/exi/exi-driver.c b/drivers/exi/exi-driver.c
+new file mode 100644
+index 0000000..ae173a5
+--- /dev/null
++++ b/drivers/exi/exi-driver.c
+@@ -0,0 +1,515 @@
++/*
++ * drivers/exi/exi-driver.c
++ *
++ * Nintendo GameCube EXternal Interface (EXI) driver model routines.
++ * Copyright (C) 2004-2009 The GameCube Linux Team
++ * Copyright (C) 2004 Arthur Othieno <a.othieno@bluewin.ch>
++ * Copyright (C) 2004,2005 Todd Jeffreys <todd@voidpointer.org>
++ * Copyright (C) 2005,2006,2007,2008,2009 Albert Herranz
++ *
++ * 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/delay.h>
++#include <linux/exi.h>
++#include <linux/init.h>
++#include <linux/kthread.h>
++#include <linux/module.h>
++#include <linux/of_platform.h>
++
++#define DRV_MODULE_NAME "exi"
++#define DRV_DESCRIPTION "Nintendo GameCube/Wii EXternal Interface (EXI) driver"
++#define DRV_AUTHOR "Arthur Othieno <a.othieno@bluewin.ch>, " \
++ "Todd Jeffreys <todd@voidpointer.org>, " \
++ "Albert Herranz"
++
++static char exi_driver_version[] = "4.0i";
++
++#define drv_printk(level, format, arg...) \
++ printk(level DRV_MODULE_NAME ": " format , ## arg)
++
++
++struct exi_map_id_to_name {
++ unsigned int id;
++ char *name;
++};
++
++
++static void exi_bus_device_release(struct device *dev);
++static int exi_bus_match(struct device *dev, struct device_driver *drv);
++
++
++static struct bus_type exi_bus_type = {
++ .name = "exi",
++ .match = exi_bus_match,
++};
++EXPORT_SYMBOL(exi_bus_type);
++
++static struct device exi_bus_devices[EXI_MAX_CHANNELS] = {
++ [0] = {
++ .bus_id = "exi0",
++ .release = exi_bus_device_release,
++ .parent = NULL
++ },
++ [1] = {
++ .bus_id = "exi1",
++ .release = exi_bus_device_release,
++ .parent = NULL
++ },
++ [2] = {
++ .bus_id = "exi2",
++ .release = exi_bus_device_release,
++ .parent = NULL
++ },
++};
++
++static struct exi_device exi_devices[EXI_MAX_CHANNELS][EXI_DEVICES_PER_CHANNEL];
++
++static struct exi_map_id_to_name exi_map_id_to_name[] = {
++ { .id = EXI_ID_NONE, .name = "(external card)" },
++ { .id = 0xffff1698, .name = "GameCube Mask ROM/RTC/SRAM/UART" },
++ { .id = 0xfffff308, .name = "Wii Mask ROM/RTC/SRAM/UART" },
++ { .id = 0x00000004, .name = "Memory Card 59" },
++ { .id = 0x00000008, .name = "Memory Card 123" },
++ { .id = 0x00000010, .name = "Memory Card 251" },
++ { .id = 0x00000020, .name = "Memory Card 507" },
++ { .id = 0x00000040, .name = "Memory Card 1019" },
++ { .id = 0x00000080, .name = "Memory Card 2043" },
++ { .id = 0x01010000, .name = "USB Adapter" },
++ { .id = 0x01020000, .name = "NPDP GDEV" },
++ { .id = 0x02020000, .name = "Modem" },
++ { .id = 0x03010000, .name = "Marlin?" },
++ { .id = 0x04020200, .name = "BroadBand Adapter (DOL-015)" },
++ { .id = 0x04120000, .name = "AD16" },
++ { .id = 0x05070000, .name = "IS Viewer" },
++ { .id = 0x0a000000, .name = "Microphone (DOL-022)" },
++ { .id = 0 }
++};
++
++/*
++ * Internal. Return the friendly name of an exi identifier.
++ */
++static const char *exi_name_id(unsigned int id)
++{
++ struct exi_map_id_to_name *map = exi_map_id_to_name;
++
++ while (map->id) {
++ if (map->id == id)
++ return map->name;
++ map++;
++ }
++ return "Unknown";
++}
++
++/*
++ * Internal. Check if an exi device matches a given exi device id.
++ */
++static int exi_device_match_one(const struct exi_device_id *eid,
++ const struct exi_device *exi_device)
++{
++ /*
++ * We allow drivers to claim devices that do not provide
++ * EXI identifiers by matching directly on channel/device.
++ * These drivers must use EXI_ID_NONE on their eids.
++ */
++ if (eid->id == exi_device->eid.id || eid->id == EXI_ID_NONE) {
++ /* match against channel and device */
++ if (exi_device->eid.channel == eid->channel &&
++ exi_device->eid.device == eid->device) {
++ return 1;
++ }
++ }
++ return 0;
++}
++
++/*
++ * Internal. Check if an exi device matches a given set of exi device ids.
++ * Return the exi device identifier or %NULL if there is no match.
++ */
++static const struct exi_device_id *
++exi_device_match(const struct exi_device_id *eids,
++ const struct exi_device *exi_device)
++{
++ while (eids && eids->id) {
++ if (exi_device_match_one(eids, exi_device))
++ return eids;
++ eids++;
++ }
++ return NULL;
++}
++
++/*
++ * Internal. Used to check if an exi device is supported by an exi driver.
++ */
++static int exi_bus_match(struct device *dev, struct device_driver *drv)
++{
++ struct exi_device *exi_device = to_exi_device(dev);
++ struct exi_driver *exi_driver = to_exi_driver(drv);
++ const struct exi_device_id *eids = exi_driver->eid_table;
++
++ if (eids && exi_device_match(eids, exi_device))
++ return 1;
++ return 0;
++}
++
++/*
++ * Internal. Bus device release.
++ */
++static void exi_bus_device_release(struct device *dev)
++{
++ drv_printk(KERN_WARNING, "exi_bus_device_release called!\n");
++}
++
++static void exi_device_release(struct device *dev);
++
++/*
++ * Internal. Initialize an exi_device structure.
++ */
++static void exi_device_init(struct exi_device *exi_device,
++ unsigned int channel, unsigned int device)
++{
++ memset(exi_device, 0, sizeof(*exi_device));
++
++ exi_device->eid.id = EXI_ID_INVALID;
++ exi_device->eid.channel = channel;
++ exi_device->eid.device = device;
++ exi_device->frequency = EXI_FREQ_SCAN;
++
++ exi_device->exi_channel = to_exi_channel(channel);
++
++ exi_device->dev.parent = &exi_bus_devices[channel];
++ exi_device->dev.bus = &exi_bus_type;
++ sprintf(exi_device->dev.bus_id, "exi%01x:%01x", channel, device);
++ exi_device->dev.platform_data = to_exi_channel(channel);
++ exi_device->dev.release = exi_device_release;
++}
++
++/*
++ * Internal. Device release.
++ */
++static void exi_device_release(struct device *dev)
++{
++ struct exi_device *exi_device = to_exi_device(dev);
++ unsigned int channel, device;
++
++ channel = exi_device->eid.channel;
++ device = exi_device->eid.device;
++
++ exi_device_init(exi_device, channel, device);
++}
++
++/**
++ * exi_device_get - Increments the reference count of the exi device
++ * @exi_device: device being referenced
++ *
++ * Each live reference to an exi device should be refcounted.
++ * A pointer to the device with the incremented reference counter
++ * is returned.
++ */
++struct exi_device *exi_device_get(struct exi_device *exi_device)
++{
++ if (exi_device)
++ get_device(&exi_device->dev);
++ return exi_device;
++}
++EXPORT_SYMBOL(exi_device_get);
++
++/**
++ * exi_device_put - Releases a use of the exi device
++ * @exi_device: device that's been disconnected
++ *
++ * Must be called when a user of a device is finished with it.
++ */
++void exi_device_put(struct exi_device *exi_device)
++{
++ if (exi_device)
++ put_device(&exi_device->dev);
++}
++EXPORT_SYMBOL(exi_device_put);
++
++/**
++ * exi_get_exi_device - Returns a reference to an exi device
++ * @exi_channel: exi channel where the device is located
++ * @device: device number within the channel
++ */
++struct exi_device *exi_get_exi_device(struct exi_channel *exi_channel,
++ int device)
++{
++ /* REVISIT, take a ref here? */
++ return &exi_devices[to_channel(exi_channel)][device];
++}
++EXPORT_SYMBOL(exi_get_exi_device);
++
++/*
++ * Internal. Call device driver probe function on match.
++ */
++static int exi_device_probe(struct device *dev)
++{
++ struct exi_device *exi_device = to_exi_device(dev);
++ struct exi_driver *exi_driver = to_exi_driver(dev->driver);
++ const struct exi_device_id *eid;
++ int retval = -ENODEV;
++
++ if (!exi_driver->eid_table)
++ goto out;
++
++ eid = exi_device_match(exi_driver->eid_table, exi_device);
++ if (eid) {
++ exi_device->frequency = exi_driver->frequency;
++ if (exi_driver->probe)
++ retval = exi_driver->probe(exi_device);
++ }
++ if (retval >= 0)
++ retval = 0;
++
++out:
++ return retval;
++}
++
++/*
++ * Internal. Call device driver remove function.
++ */
++static int exi_device_remove(struct device *dev)
++{
++ struct exi_device *exi_device = to_exi_device(dev);
++ struct exi_driver *exi_driver = to_exi_driver(dev->driver);
++
++ if (exi_driver->remove)
++ exi_driver->remove(exi_device);
++
++ return 0;
++}
++
++
++/**
++ * exi_driver_register - register an EXI device driver.
++ * @driver: driver structure to register.
++ *
++ * Registers an EXI device driver with the bus
++ * and consequently with the driver model core.
++ */
++int exi_driver_register(struct exi_driver *driver)
++{
++ driver->driver.name = driver->name;
++ driver->driver.bus = &exi_bus_type;
++ driver->driver.probe = exi_device_probe;
++ driver->driver.remove = exi_device_remove;
++
++ return driver_register(&driver->driver);
++}
++EXPORT_SYMBOL(exi_driver_register);
++
++/**
++ * exi_driver_unregister - unregister an EXI device driver.
++ * @driver: driver structure to unregister.
++ *
++ * Unregisters an EXI device driver with the bus
++ * and consequently with the driver model core.
++ */
++void exi_driver_unregister(struct exi_driver *driver)
++{
++ driver_unregister(&driver->driver);
++}
++EXPORT_SYMBOL(exi_driver_unregister);
++
++
++/*
++ * Internal. Re-scan a given device.
++ */
++static void exi_device_rescan(struct exi_device *exi_device)
++{
++ unsigned int id;
++ int error;
++
++ /* now ID the device */
++ id = exi_get_id(exi_device);
++
++ if (exi_device->eid.id != EXI_ID_INVALID) {
++ /* device removed or changed */
++ drv_printk(KERN_INFO, "about to remove [%s] id=0x%08x %s\n",
++ exi_device->dev.bus_id,
++ exi_device->eid.id,
++ exi_name_id(exi_device->eid.id));
++ device_unregister(&exi_device->dev);
++ drv_printk(KERN_INFO, "remove completed\n");
++ exi_device->eid.id = EXI_ID_INVALID;
++ }
++
++ if (id != EXI_ID_INVALID) {
++ /* a new device has been found */
++ drv_printk(KERN_INFO, "about to add [%s] id=0x%08x %s\n",
++ exi_device->dev.bus_id,
++ id, exi_name_id(id));
++ exi_device->eid.id = id;
++ error = device_register(&exi_device->dev);
++ if (error) {
++ drv_printk(KERN_INFO, "add failed (%d)\n", error);
++ exi_device->eid.id = EXI_ID_INVALID;
++ } else
++ drv_printk(KERN_INFO, "add completed\n");
++ }
++
++ exi_update_ext_status(exi_get_exi_channel(exi_device));
++}
++
++/*
++ * Internal. Re-scan a given exi channel, looking for added, changed and
++ * removed exi devices.
++ */
++static void exi_channel_rescan(struct exi_channel *exi_channel)
++{
++ struct exi_device *exi_device;
++ unsigned int channel, device;
++
++ /* add the exi devices underneath the parents */
++ for (device = 0; device < EXI_DEVICES_PER_CHANNEL; ++device) {
++ channel = to_channel(exi_channel);
++ exi_device = &exi_devices[channel][device];
++ exi_device_rescan(exi_device);
++ }
++}
++
++/*
++ * Internal. Scans all the exi channels looking for exi devices.
++ */
++static void exi_bus_rescan(void)
++{
++ struct exi_channel *exi_channel;
++ unsigned int channel;
++
++ for (channel = 0; channel < EXI_MAX_CHANNELS; ++channel) {
++ exi_channel = to_exi_channel(channel);
++ exi_channel_rescan(exi_channel);
++ }
++}
++
++
++static struct task_struct *exi_bus_task;
++wait_queue_head_t exi_bus_waitq;
++
++/*
++ * Internal. Looks for new, changed or removed devices.
++ */
++static int exi_bus_thread(void *__unused)
++{
++ struct exi_channel *exi_channel;
++ struct exi_device *exi_device;
++ unsigned int channel;
++ int is_loaded, was_loaded;
++
++ while (!kthread_should_stop()) {
++ /* scan the memcard slot channels for device changes */
++ for (channel = 0; channel <= 1; ++channel) {
++ exi_channel = to_exi_channel(channel);
++
++ is_loaded = exi_get_ext_line(exi_channel);
++ was_loaded = (exi_channel->flags & EXI_EXT) ? 1 : 0;
++
++ if (is_loaded ^ was_loaded) {
++ exi_device = &exi_devices[channel][0];
++ exi_device_rescan(exi_device);
++ }
++ }
++
++ sleep_on_timeout(&exi_bus_waitq, HZ);
++ }
++
++ return 0;
++}
++
++/*
++ *
++ */
++static int exi_init(struct resource *mem, unsigned int irq)
++{
++ struct exi_channel *exi_channel;
++ struct exi_device *exi_device;
++ unsigned int channel, device;
++ int retval;
++
++ retval = exi_hw_init(DRV_MODULE_NAME, mem, irq);
++ if (retval)
++ goto err_hw_init;
++
++ /* initialize devices */
++ for (channel = 0; channel < EXI_MAX_CHANNELS; ++channel) {
++ exi_channel = to_exi_channel(channel);
++ for (device = 0; device < EXI_DEVICES_PER_CHANNEL; ++device) {
++ exi_device = &exi_devices[channel][device];
++ exi_device_init(exi_device, channel, device);
++ }
++ }
++
++ /* register root devices */
++ for (channel = 0; channel < EXI_MAX_CHANNELS; ++channel) {
++ retval = device_register(&exi_bus_devices[channel]);
++ if (retval)
++ goto err_device_register;
++ }
++
++ /* register the bus */
++ retval = bus_register(&exi_bus_type);
++ if (retval)
++ goto err_bus_register;
++
++ /* now enumerate through the bus and add all detected devices */
++ exi_bus_rescan();
++
++ /* setup a thread to manage plugable devices */
++ init_waitqueue_head(&exi_bus_waitq);
++ exi_bus_task = kthread_run(exi_bus_thread, NULL, "kexid");
++ if (IS_ERR(exi_bus_task))
++ drv_printk(KERN_WARNING, "failed to start exi kernel thread\n");
++
++ return 0;
++
++err_bus_register:
++err_device_register:
++ while (--channel > 0)
++ device_unregister(&exi_bus_devices[channel]);
++ exi_hw_exit(mem, irq);
++err_hw_init:
++ return retval;
++}
++
++/*
++ *
++ */
++static int __init exi_layer_init(void)
++{
++ struct device_node *np;
++ struct resource res;
++ int retval;
++
++ drv_printk(KERN_INFO, "%s - version %s\n", DRV_DESCRIPTION,
++ exi_driver_version);
++
++ np = of_find_compatible_node(NULL, NULL, "nintendo,flipper-exi");
++ if (!np) {
++ np = of_find_compatible_node(NULL, NULL,
++ "nintendo,hollywood-exi");
++ if (!np)
++ return -ENODEV;
++ }
++
++ retval = of_address_to_resource(np, 0, &res);
++ if (retval) {
++ drv_printk(KERN_ERR, "no io memory range found\n");
++ return -ENOMEM;
++ }
++
++ retval = exi_init(&res, irq_of_parse_and_map(np, 0));
++ of_node_put(np);
++
++ return retval;
++}
++postcore_initcall(exi_layer_init);
++
++MODULE_AUTHOR(DRV_AUTHOR);
++MODULE_DESCRIPTION(DRV_DESCRIPTION);
++MODULE_LICENSE("GPL");
++
+diff --git a/drivers/exi/exi-hw.c b/drivers/exi/exi-hw.c
+new file mode 100644
+index 0000000..de3414b
+--- /dev/null
++++ b/drivers/exi/exi-hw.c
+@@ -0,0 +1,1408 @@
++/*
++ * drivers/exi/exi-hw.c
++ *
++ * Nintendo GameCube EXpansion Interface support. Hardware routines.
++ * Copyright (C) 2004-2009 The GameCube Linux Team
++ * Copyright (C) 2004,2005 Todd Jeffreys <todd@voidpointer.org>
++ * Copyright (C) 2005,2006,2007,2008,2009 Albert Herranz
++ *
++ * 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.
++ *
++ */
++
++/*
++ * IMPLEMENTATION NOTES
++ *
++ * The EXI Layer provides the following primitives:
++ *
++ * op atomic?
++ * ------------------ -------
++ * take yes
++ * give yes
++ * select yes
++ * deselect yes
++ * transfer yes/no (1)
++ *
++ * These primitives are encapsulated in several APIs.
++ * See include/linux/exi.h for additional information.
++ *
++ * 1. Kernel Contexts
++ *
++ * User, softirq and hardirq contexts are supported, with some limitations.
++ *
++ * Launching EXI operations in softirq or hardirq context requires kernel
++ * coordination to ensure channels are free before use.
++ *
++ * The EXI Layer Event System delivers events in softirq context, but it already
++ * makes provisions to ensure that channels are useable by the event handlers.
++ * Events are delivered only when the channels on the event handler
++ * channel mask are all deselected. This allows one to run EXI commands in
++ * softirq context from the EXI event handlers.
++ *
++ * "take" operations in user context will sleep if necessary until the
++ * channel is "given".
++ *
++ *
++ * 2. Transfers
++ *
++ * The EXI Layer provides a transfer API to perform read and write
++ * operations.
++ * By default, transfers partially or totally suitable for DMA will be
++ * partially or totally processed through DMA. The EXI Layer takes care of
++ * splitting a transfer in several pieces so the best transfer method is
++ * used each time.
++ *
++ * (1) A immediate mode transfer is atomic, but a DMA transfer is not.
++ */
++
++/*#define EXI_DEBUG 1*/
++
++#include <linux/types.h>
++#include <linux/dma-mapping.h>
++#include <linux/wait.h>
++#include <linux/delay.h>
++#include <linux/io.h>
++#include <linux/spinlock.h>
++
++#include <linux/exi.h>
++#include "exi-hw.h"
++
++
++#define drv_printk(level, format, arg...) \
++ printk(level "exi: " format , ## arg)
++
++#ifdef EXI_DEBUG
++# define DBG(fmt, args...) \
++ printk(KERN_ERR "%s: " fmt, __func__ , ## args)
++#else
++# define DBG(fmt, args...)
++#endif
++
++
++static void exi_tasklet(unsigned long param);
++
++
++/* io memory base for EXI */
++static void __iomem *exi_io_mem;
++
++
++/*
++ * These are the available exi channels.
++ */
++static struct exi_channel exi_channels[EXI_MAX_CHANNELS] = {
++ [0] = {
++ .channel = 0,
++ .lock = __SPIN_LOCK_UNLOCKED(exi_channels[0].lock),
++ .io_lock = __SPIN_LOCK_UNLOCKED(exi_channels[0].io_lock),
++ .wait_queue = __WAIT_QUEUE_HEAD_INITIALIZER(
++ exi_channels[0].wait_queue),
++ },
++ [1] = {
++ .channel = 1,
++ .lock = __SPIN_LOCK_UNLOCKED(exi_channels[1].lock),
++ .io_lock = __SPIN_LOCK_UNLOCKED(exi_channels[1].io_lock),
++ .wait_queue = __WAIT_QUEUE_HEAD_INITIALIZER(
++ exi_channels[1].wait_queue),
++ },
++ [2] = {
++ .channel = 2,
++ .lock = __SPIN_LOCK_UNLOCKED(exi_channels[2].lock),
++ .io_lock = __SPIN_LOCK_UNLOCKED(exi_channels[2].io_lock),
++ .wait_queue = __WAIT_QUEUE_HEAD_INITIALIZER(
++ exi_channels[2].wait_queue),
++ },
++};
++
++/* handy iterator for exi channels */
++#define exi_channel_for_each(pos) \
++ for (pos = &exi_channels[0]; pos < &exi_channels[EXI_MAX_CHANNELS]; \
++ pos++)
++
++/* conversions between channel numbers and exi channel structures */
++#define __to_exi_channel(channel) (&exi_channels[channel])
++#define __to_channel(exi_channel) (exi_channel->channel)
++
++/**
++ * to_exi_channel - returns an exi_channel given a channel number
++ * @channel: channel number
++ *
++ * Return the exi_channel structure associated to a given channel.
++ */
++struct exi_channel *to_exi_channel(unsigned int channel)
++{
++ if (channel > EXI_MAX_CHANNELS)
++ return NULL;
++
++ return __to_exi_channel(channel);
++}
++EXPORT_SYMBOL(to_exi_channel);
++
++/**
++ * to_channel - returns a channel number given an exi channel
++ * @exi_channel: channel
++ *
++ * Return the channel number for a given exi_channel structure.
++ */
++unsigned int to_channel(struct exi_channel *exi_channel)
++{
++ BUG_ON(exi_channel == NULL);
++
++ return __to_channel(exi_channel);
++}
++EXPORT_SYMBOL(to_channel);
++
++/**
++ * exi_channel_owner - returns the owner of the given channel
++ * @exi_channel: channel
++ *
++ * Return the device owning a given exi_channel structure.
++ */
++struct exi_device *exi_channel_owner(struct exi_channel *exi_channel)
++{
++ return exi_channel->owner;
++}
++
++
++/*
++ *
++ *
++ */
++
++/**
++ * exi_select_raw - selects a device on an exi channel
++ * @exi_channel: channel
++ * @device: device number on channel
++ * @freq: clock frequency index
++ *
++ * Select a given device on a specified EXI channel by setting its
++ * CS line, and use the specified clock frequency when doing transfers.
++ */
++void exi_select_raw(struct exi_channel *exi_channel, unsigned int device,
++ unsigned int freq)
++{
++ u32 __iomem *csr_reg = exi_channel->io_base + EXI_CSR;
++ u32 csr;
++ unsigned long flags;
++
++ BUG_ON(device > EXI_DEVICES_PER_CHANNEL ||
++ freq > EXI_MAX_FREQ);
++
++ /*
++ * Preserve interrupt masks while setting the CS line bits.
++ */
++ spin_lock_irqsave(&exi_channel->io_lock, flags);
++ csr = in_be32(csr_reg);
++ csr &= (EXI_CSR_EXTINMASK | EXI_CSR_TCINTMASK | EXI_CSR_EXIINTMASK);
++ csr |= ((1<<device) << 7) | (freq << 4);
++ out_be32(csr_reg, csr);
++ spin_unlock_irqrestore(&exi_channel->io_lock, flags);
++}
++EXPORT_SYMBOL(exi_select_raw);
++
++
++/**
++ * exi_deselect_raw - deselects all devices on an exi channel
++ * @exi_channel: channel
++ *
++ * Deselect any device previously selected on the specified EXI
++ * channel by unsetting all CS lines.
++ */
++void exi_deselect_raw(struct exi_channel *exi_channel)
++{
++ u32 __iomem *csr_reg = exi_channel->io_base + EXI_CSR;
++ u32 csr;
++ unsigned long flags;
++
++ /*
++ * Preserve interrupt masks while clearing the CS line bits.
++ */
++ spin_lock_irqsave(&exi_channel->io_lock, flags);
++ csr = in_be32(csr_reg);
++ csr &= (EXI_CSR_EXTINMASK | EXI_CSR_TCINTMASK | EXI_CSR_EXIINTMASK);
++ out_be32(csr_reg, csr);
++ spin_unlock_irqrestore(&exi_channel->io_lock, flags);
++}
++EXPORT_SYMBOL(exi_deselect_raw);
++
++/**
++ * exi_transfer_raw - performs an exi transfer using immediate mode
++ * @exi_channel: channel
++ * @data: pointer to data being read/writen
++ * @len: length of data
++ * @mode: direction of transfer (EXI_OP_{READ,READWRITE,WRITE})
++ *
++ * Read or write data on a given EXI channel.
++ *
++ */
++void exi_transfer_raw(struct exi_channel *exi_channel,
++ void *data, size_t len, int mode)
++{
++ while (len >= 4) {
++ __exi_transfer_raw_u32(exi_channel, data, mode);
++ exi_channel->stats_xfers++;
++ data += 4;
++ len -= 4;
++ }
++
++ switch (len) {
++ case 1:
++ __exi_transfer_raw_u8(exi_channel, data, mode);
++ exi_channel->stats_xfers++;
++ break;
++ case 2:
++ __exi_transfer_raw_u16(exi_channel, data, mode);
++ exi_channel->stats_xfers++;
++ break;
++ case 3:
++ /* XXX optimize this case */
++ __exi_transfer_raw_u16(exi_channel, data, mode);
++ exi_channel->stats_xfers++;
++ __exi_transfer_raw_u8(exi_channel, data+2, mode);
++ exi_channel->stats_xfers++;
++ break;
++ default:
++ break;
++ }
++}
++EXPORT_SYMBOL(exi_transfer_raw);
++
++/*
++ * Internal. Start a transfer using "interrupt-driven immediate" mode.
++ */
++static void exi_start_idi_transfer_raw(struct exi_channel *exi_channel,
++ void *data, size_t len, int mode)
++{
++ void __iomem *io_base = exi_channel->io_base;
++ u32 __iomem *csr_reg = io_base + EXI_CSR;
++ u32 val = ~0;
++ unsigned long flags;
++
++ BUG_ON(len < 1 || len > 4);
++
++ exi_channel->stats_idi_xfers++;
++ exi_channel->stats_xfers++;
++
++ if ((mode & EXI_OP_WRITE)) {
++ switch (len) {
++ case 1:
++ val = *((u8 *)data) << 24;
++ break;
++ case 2:
++ val = *((u16 *)data) << 16;
++ break;
++ case 3:
++ val = *((u16 *)data) << 16;
++ val |= *((u8 *)data+2) << 8;
++ break;
++ case 4:
++ val = *((u32 *)data);
++ break;
++ default:
++ break;
++ }
++ }
++
++ out_be32(io_base + EXI_DATA, val);
++
++ /* enable the Transfer Complete interrupt */
++ spin_lock_irqsave(&exi_channel->io_lock, flags);
++ out_be32(csr_reg, in_be32(csr_reg) | EXI_CSR_TCINTMASK);
++ spin_unlock_irqrestore(&exi_channel->io_lock, flags);
++
++ /* start the transfer */
++ out_be32(io_base + EXI_CR,
++ EXI_CR_TSTART | EXI_CR_TLEN(len) | (mode&0xf));
++}
++
++/*
++ * Internal. Finish a transfer using "interrupt-driven immediate" mode.
++ */
++static void exi_end_idi_transfer_raw(struct exi_channel *exi_channel,
++ void *data, size_t len, int mode)
++{
++ void __iomem *io_base = exi_channel->io_base;
++ u32 val = ~0;
++
++ BUG_ON(len < 1 || len > 4);
++
++ if ((mode&0xf) != EXI_OP_WRITE) {
++ val = in_be32(io_base + EXI_DATA);
++ switch (len) {
++ case 1:
++ *((u8 *)data) = (u8)(val >> 24);
++ break;
++ case 2:
++ *((u16 *)data) = (u16)(val >> 16);
++ break;
++ case 3:
++ *((u16 *)data) = (u16)(val >> 16);
++ *((u8 *)data+2) = (u8)(val >> 8);
++ break;
++ case 4:
++ *((u32 *)data) = (u32)(val);
++ break;
++ default:
++ break;
++ }
++ }
++}
++
++/*
++ * Internal. Start a transfer using DMA mode.
++ */
++static void exi_start_dma_transfer_raw(struct exi_channel *exi_channel,
++ dma_addr_t data, size_t len, int mode)
++{
++ void __iomem *io_base = exi_channel->io_base;
++ u32 __iomem *csr_reg = io_base + EXI_CSR;
++ unsigned long flags;
++
++ BUG_ON((data & EXI_DMA_ALIGN) != 0 ||
++ (len & EXI_DMA_ALIGN) != 0);
++
++ exi_channel->stats_dma_xfers++;
++ exi_channel->stats_xfers++;
++
++ /*
++ * We clear the DATA register here to avoid confusing some
++ * special hardware, like SD cards.
++ * Indeed, we need all 1s here.
++ */
++ out_be32(io_base + EXI_DATA, ~0);
++
++ /* setup address and length of transfer */
++ out_be32(io_base + EXI_MAR, data);
++ out_be32(io_base + EXI_LENGTH, len);
++
++ /* enable the Transfer Complete interrupt */
++ spin_lock_irqsave(&exi_channel->io_lock, flags);
++ out_be32(csr_reg, in_be32(csr_reg) | EXI_CSR_TCINTMASK);
++ spin_unlock_irqrestore(&exi_channel->io_lock, flags);
++
++ /* start the transfer */
++ out_be32(io_base + EXI_CR, EXI_CR_TSTART | EXI_CR_DMA | (mode&0xf));
++}
++
++
++/*
++ * Internal. Busy-wait until a DMA mode transfer operation completes.
++ */
++static void exi_wait_for_transfer_raw(struct exi_channel *exi_channel)
++{
++ u32 __iomem *cr_reg = exi_channel->io_base + EXI_CR;
++ u32 __iomem *csr_reg = exi_channel->io_base + EXI_CSR;
++ unsigned long flags;
++ unsigned long deadline = jiffies + 2*HZ;
++ int borked = 0;
++
++ /* we don't want TCINTs to disturb us while waiting */
++ spin_lock_irqsave(&exi_channel->io_lock, flags);
++ out_be32(csr_reg, in_be32(csr_reg) & ~EXI_CSR_TCINTMASK);
++ spin_unlock_irqrestore(&exi_channel->io_lock, flags);
++
++ /* busy-wait for transfer complete */
++ while ((in_be32(cr_reg)&EXI_CR_TSTART) && !borked) {
++ cpu_relax();
++ borked = time_after(jiffies, deadline);
++ }
++
++ if (borked) {
++ drv_printk(KERN_ERR, "exi transfer took too long, "
++ "is your hardware ok?");
++ }
++
++ /* ack the Transfer Complete interrupt */
++ spin_lock_irqsave(&exi_channel->io_lock, flags);
++ out_be32(csr_reg, in_be32(csr_reg) | EXI_CSR_TCINT);
++ spin_unlock_irqrestore(&exi_channel->io_lock, flags);
++}
++
++
++/*
++ *
++ *
++ */
++
++static void exi_command_done(struct exi_command *cmd);
++
++/*
++ * Internal. Initialize an exi_channel structure.
++ */
++void exi_channel_init(struct exi_channel *exi_channel, unsigned int channel)
++{
++ memset(exi_channel, 0, sizeof(*exi_channel));
++ exi_channel->events[EXI_EVENT_IRQ].id = EXI_EVENT_IRQ;
++ exi_channel->events[EXI_EVENT_INSERT].id = EXI_EVENT_INSERT;
++ exi_channel->events[EXI_EVENT_TC].id = EXI_EVENT_TC;
++
++ spin_lock_init(&exi_channel->lock);
++ spin_lock_init(&exi_channel->io_lock);
++ init_waitqueue_head(&exi_channel->wait_queue);
++
++ exi_channel->channel = channel;
++ exi_channel->io_base = exi_io_mem + channel * EXI_CHANNEL_SPACING;
++
++ tasklet_init(&exi_channel->tasklet,
++ exi_tasklet, (unsigned long)exi_channel);
++}
++
++/*
++ * Internal. Check if an exi channel has delayed work to do.
++ */
++static void exi_check_pending_work(void)
++{
++ struct exi_channel *exi_channel;
++
++ exi_channel_for_each(exi_channel) {
++ if (exi_channel->csr)
++ tasklet_schedule(&exi_channel->tasklet);
++ }
++}
++
++/*
++ * Internal. Finish a DMA transfer.
++ * Caller holds the channel lock.
++ */
++static void exi_end_dma_transfer(struct exi_channel *exi_channel)
++{
++ struct exi_command *cmd;
++
++ cmd = exi_channel->queued_cmd;
++ if (cmd) {
++ BUG_ON(!(exi_channel->flags & EXI_DMABUSY));
++
++ exi_channel->flags &= ~EXI_DMABUSY;
++ dma_unmap_single(&exi_channel->owner->dev,
++ cmd->dma_addr, cmd->dma_len,
++ (cmd->opcode == EXI_OP_READ) ?
++ DMA_FROM_DEVICE : DMA_TO_DEVICE);
++
++ exi_channel->queued_cmd = NULL;
++ }
++}
++
++/*
++ * Internal. Finish an "interrupt-driven immediate" transfer.
++ * Caller holds the channel lock.
++ *
++ * If more data is pending transfer, it schedules a new transfer.
++ * Returns zero if no more transfers are required, non-zero otherwise.
++ *
++ */
++static int exi_end_idi_transfer(struct exi_channel *exi_channel)
++{
++ struct exi_command *cmd;
++ int len, offset;
++ unsigned int balance = 16 /* / sizeof(u32) */;
++
++ cmd = exi_channel->queued_cmd;
++ if (cmd) {
++ BUG_ON((exi_channel->flags & EXI_DMABUSY));
++
++ len = (cmd->bytes_left > 4) ? 4 : cmd->bytes_left;
++ offset = cmd->len - cmd->bytes_left;
++ exi_end_idi_transfer_raw(exi_channel,
++ cmd->data + offset, len,
++ cmd->opcode);
++ cmd->bytes_left -= len;
++
++ if (balance && cmd->bytes_left > 0) {
++ offset += len;
++ len = (cmd->bytes_left > balance) ?
++ balance : cmd->bytes_left;
++ exi_transfer_raw(exi_channel,
++ cmd->data + offset, len, cmd->opcode);
++ cmd->bytes_left -= len;
++ }
++
++ if (cmd->bytes_left > 0) {
++ offset = cmd->len - cmd->bytes_left;
++ len = (cmd->bytes_left > 4) ? 4 : cmd->bytes_left;
++
++ exi_start_idi_transfer_raw(exi_channel,
++ cmd->data + offset, len,
++ cmd->opcode);
++ } else {
++ exi_channel->queued_cmd = NULL;
++ }
++ }
++
++ return (exi_channel->queued_cmd) ? 1 : 0;
++}
++
++/*
++ * Internal. Wait until a single transfer completes, and launch callbacks
++ * when the whole transfer is completed.
++ */
++static int exi_wait_for_transfer_one(struct exi_channel *exi_channel)
++{
++ struct exi_command *cmd;
++ unsigned long flags;
++ int pending = 0;
++
++ spin_lock_irqsave(&exi_channel->lock, flags);
++
++ exi_wait_for_transfer_raw(exi_channel);
++
++ cmd = exi_channel->queued_cmd;
++ if (cmd) {
++ if ((exi_channel->flags & EXI_DMABUSY)) {
++ /* dma transfers need just one transfer */
++ exi_end_dma_transfer(exi_channel);
++ } else {
++ pending = exi_end_idi_transfer(exi_channel);
++ }
++
++ spin_unlock_irqrestore(&exi_channel->lock, flags);
++
++ if (!pending)
++ exi_command_done(cmd);
++ goto out;
++ }
++
++ spin_unlock_irqrestore(&exi_channel->lock, flags);
++out:
++ return pending;
++}
++
++#if 0
++/*
++ * Internal. Wait until a full transfer completes and launch callbacks.
++ */
++static void exi_wait_for_transfer(struct exi_channel *exi_channel)
++{
++ while (exi_wait_for_transfer_one(exi_channel))
++ cpu_relax();
++}
++#endif
++
++/*
++ * Internal. Call any done hooks.
++ */
++static void exi_command_done(struct exi_command *cmd)
++{
++ /* if specified, call the completion routine */
++ if (cmd->done)
++ cmd->done(cmd);
++}
++
++/*
++ * Internal. Take a channel.
++ */
++static int exi_take_channel(struct exi_channel *exi_channel,
++ struct exi_device *exi_device, int wait)
++{
++ unsigned long flags;
++ int result = 0;
++
++ BUG_ON(!exi_device);
++
++ spin_lock_irqsave(&exi_channel->lock, flags);
++ while (exi_channel->owner) {
++ spin_unlock_irqrestore(&exi_channel->lock, flags);
++ if (!wait)
++ return -EBUSY;
++ wait_event(exi_channel->wait_queue,
++ !exi_channel->owner);
++ spin_lock_irqsave(&exi_channel->lock, flags);
++ }
++ exi_channel->owner = exi_device;
++ spin_unlock_irqrestore(&exi_channel->lock, flags);
++
++ return result;
++}
++
++/*
++ * Internal. Give a channel.
++ */
++static int exi_give_channel(struct exi_channel *exi_channel)
++{
++ WARN_ON(exi_channel->owner == NULL);
++ exi_channel->owner = NULL;
++ wake_up(&exi_channel->wait_queue);
++ return 0;
++}
++
++/*
++ * Internal. Perform the post non-DMA transfer associated to a DMA transfer.
++ */
++static void exi_cmd_post_transfer(struct exi_command *cmd)
++{
++ struct exi_channel *exi_channel = cmd->exi_channel;
++ struct exi_command *post_cmd = &exi_channel->post_cmd;
++
++ DBG("channel=%d\n", exi_channel->channel);
++
++ exi_transfer_raw(exi_channel, post_cmd->data, post_cmd->len,
++ post_cmd->opcode);
++
++ cmd->done_data = post_cmd->done_data;
++ cmd->done = post_cmd->done;
++ exi_op_nop(post_cmd, exi_channel);
++ exi_command_done(cmd);
++}
++
++
++#define exi_align_next(x) (void *) \
++ (((unsigned long)(x)+EXI_DMA_ALIGN)&~EXI_DMA_ALIGN)
++#define exi_align_prev(x) (void *) \
++ ((unsigned long)(x)&~EXI_DMA_ALIGN)
++#define exi_is_aligned(x) (void *) \
++ (!((unsigned long)(x)&EXI_DMA_ALIGN))
++
++/*
++ * Internal. Perform a transfer.
++ * Caller holds the channel lock.
++ */
++static int exi_cmd_transfer(struct exi_command *cmd)
++{
++ static u8 exi_aligned_transfer_buf[EXI_DMA_ALIGN+1]
++ __attribute__ ((aligned(EXI_DMA_ALIGN+1)));
++ struct exi_channel *exi_channel = cmd->exi_channel;
++ struct exi_command *post_cmd = &exi_channel->post_cmd;
++ void *pre_data, *data, *post_data;
++ unsigned int pre_len, len, post_len;
++ int opcode;
++ int result = 0;
++
++ BUG_ON(!exi_channel->owner);
++
++ len = cmd->len;
++ if (!len)
++ goto done;
++
++ DBG("channel=%d, opcode=%d\n", exi_channel->channel, cmd->opcode);
++
++ opcode = cmd->opcode;
++ data = cmd->data;
++
++ /* interrupt driven immediate transfer... */
++ if ((cmd->flags & EXI_CMD_IDI)) {
++ exi_channel->queued_cmd = cmd;
++ exi_channel->flags &= ~EXI_DMABUSY;
++
++ cmd->bytes_left = cmd->len;
++ len = (cmd->bytes_left > 4) ? 4 : cmd->bytes_left;
++ exi_start_idi_transfer_raw(exi_channel, data, len, opcode);
++
++ result = 1; /* wait */
++ goto done;
++ }
++
++ /*
++ * We can't do DMA transfers unless we have at least 32 bytes.
++ * And we won't do DMA transfers if user requests that.
++ */
++ if (len < EXI_DMA_ALIGN+1 || (cmd->flags & EXI_CMD_NODMA)) {
++ exi_transfer_raw(exi_channel, data, len, opcode);
++ goto done;
++ }
++
++ /*
++ * |_______________|______...______|_______________| DMA alignment
++ * <--pre_len--><---- len -----><-post_len->
++ * +-----------+------...------+-----------+
++ * | pre_data | data | post_data |
++ * | non-DMA | DMA | non-DMA |
++ * +-----------+------...------+-----------+
++ * < 32 bytes N*32 bytes < 32 bytes
++ * |<--------->|<-----...----->|<--------->|
++ * <-------------- cmd->len --------------->
++ */
++
++ pre_data = data;
++ post_data = exi_align_prev(pre_data+len);
++ data = exi_align_next(pre_data);
++
++ pre_len = data - pre_data;
++ post_len = (pre_data + len) - post_data;
++ len = post_data - data;
++
++ /*
++ * Coalesce pre and post data transfers if no DMA transfer is possible.
++ */
++ if (!len) {
++ /*
++ * Maximum transfer size here is 31+31=62 bytes.
++ */
++
++ /*
++ * On transfer sizes greater than or equal to 32 bytes
++ * we can optimize the transfer by performing a 32-byte
++ * DMA transfer using a specially aligned temporary buffer,
++ * followed by a non-DMA transfer for the remaining bytes.
++ */
++ if (pre_len + post_len > EXI_DMA_ALIGN) {
++ post_len = pre_len + post_len - (EXI_DMA_ALIGN+1);
++ post_data = pre_data + EXI_DMA_ALIGN+1;
++ len = EXI_DMA_ALIGN+1;
++ data = exi_aligned_transfer_buf;
++ memcpy(data, pre_data, EXI_DMA_ALIGN+1);
++ pre_len = 0;
++ } else {
++ exi_transfer_raw(exi_channel, pre_data,
++ pre_len + post_len, opcode);
++ goto done;
++ }
++ }
++
++ /*
++ * The first unaligned chunk can't use DMA.
++ */
++ if (pre_len > 0) {
++ /*
++ * Maximum transfer size here is 31 bytes.
++ */
++ exi_transfer_raw(exi_channel, pre_data, pre_len, opcode);
++ }
++
++ /*
++ * Perform a DMA transfer on the aligned data, followed by a non-DMA
++ * data transfer on the remaining data.
++ */
++ if (post_len > 0) {
++ /*
++ * Maximum transfer size here will be 31 bytes.
++ */
++ exi_op_transfer(post_cmd, exi_channel,
++ post_data, post_len, opcode);
++ post_cmd->done_data = cmd->done_data;
++ post_cmd->done = cmd->done;
++ cmd->done_data = NULL;
++ cmd->done = exi_cmd_post_transfer;
++ }
++
++ exi_channel->queued_cmd = cmd;
++ exi_channel->flags |= EXI_DMABUSY;
++
++ cmd->dma_len = len;
++ cmd->dma_addr = dma_map_single(&exi_channel->owner->dev,
++ data, len,
++ (cmd->opcode == EXI_OP_READ) ?
++ DMA_FROM_DEVICE : DMA_TO_DEVICE);
++
++ exi_start_dma_transfer_raw(exi_channel, cmd->dma_addr, len, opcode);
++
++ result = 1; /* wait */
++
++done:
++ return result;
++}
++
++/**
++ * exi_run_command - executes a single exi command
++ * @cmd: the command to execute
++ *
++ * Context: user
++ *
++ * Run just one command.
++ *
++ */
++static int exi_run_command(struct exi_command *cmd)
++{
++ struct exi_channel *exi_channel = cmd->exi_channel;
++ struct exi_device *exi_device = cmd->exi_device;
++ unsigned long flags;
++ int wait = !(cmd->flags & EXI_CMD_NOWAIT);
++ int result = 0;
++
++ if (cmd->opcode != EXI_OP_TAKE)
++ WARN_ON(exi_channel->owner != exi_device);
++
++ switch (cmd->opcode) {
++ case EXI_OP_NOP:
++ break;
++ case EXI_OP_TAKE:
++ result = exi_take_channel(exi_channel, exi_device, wait);
++ break;
++ case EXI_OP_GIVE:
++ result = exi_give_channel(exi_channel);
++ if (!exi_channel->owner)
++ exi_check_pending_work();
++ break;
++ case EXI_OP_SELECT:
++ exi_select_raw(exi_channel, exi_device->eid.device,
++ exi_device->frequency);
++ break;
++ case EXI_OP_DESELECT:
++ exi_deselect_raw(exi_channel);
++ break;
++ case EXI_OP_READ:
++ case EXI_OP_READWRITE:
++ case EXI_OP_WRITE:
++ spin_lock_irqsave(&exi_channel->lock, flags);
++ result = exi_cmd_transfer(cmd);
++ spin_unlock_irqrestore(&exi_channel->lock, flags);
++ break;
++ default:
++ result = -ENOSYS;
++ break;
++ }
++
++ /*
++ * We check for delayed work every time the channel becomes
++ * idle.
++ */
++ if (!result)
++ exi_command_done(cmd);
++
++ return result;
++}
++
++
++/*
++ * Internal. Completion routine.
++ */
++static void exi_wait_done(struct exi_command *cmd)
++{
++ complete(cmd->done_data);
++}
++
++/*
++ * Internal. Run a command and wait.
++ * Might sleep if called from user context. Otherwise will busy-wait.
++ */
++static int exi_run_command_and_wait(struct exi_command *cmd)
++{
++ DECLARE_COMPLETION(complete);
++ int result;
++
++ cmd->done_data = &complete;
++ cmd->done = exi_wait_done;
++ result = exi_run_command(cmd);
++ if (result > 0) {
++ wait_for_completion(&complete);
++ result = 0;
++ }
++ return result;
++}
++
++/**
++ * exi_take - reserves an exi channel for exclusive use by a device
++ * @exi_device: exi device making the reservation
++ * @wait: wait for the operation to complete
++ *
++ * Reserves the channel of a given EXI device.
++ */
++int exi_take(struct exi_device *exi_device, int wait)
++{
++ struct exi_command cmd;
++
++ exi_op_take(&cmd, exi_device);
++ if (!wait)
++ cmd.flags |= EXI_CMD_NOWAIT;
++ return exi_run_command(&cmd);
++}
++EXPORT_SYMBOL(exi_take);
++
++/**
++ * exi_give - releases an exi channel
++ * @exi_device: exi device making the release
++ *
++ * Releases the channel of a given EXI device.
++ */
++int exi_give(struct exi_device *exi_device)
++{
++ struct exi_command cmd;
++
++ exi_op_give(&cmd, exi_device->exi_channel);
++ return exi_run_command(&cmd);
++}
++EXPORT_SYMBOL(exi_give);
++
++/**
++ * exi_select - selects a exi device
++ * @exi_device: exi device being selected
++ *
++ * Selects a given EXI device.
++ */
++void exi_select(struct exi_device *exi_device)
++{
++ struct exi_command cmd;
++
++ exi_op_select(&cmd, exi_device);
++ exi_run_command(&cmd);
++}
++EXPORT_SYMBOL(exi_select);
++
++/**
++ * exi_deselect - deselects all devices on an exi channel
++ * @exi_channel: channel
++ *
++ * Deselects all EXI devices on the given channel.
++ *
++ */
++void exi_deselect(struct exi_channel *exi_channel)
++{
++ struct exi_command cmd;
++
++ exi_op_deselect(&cmd, exi_channel);
++ exi_run_command(&cmd);
++}
++EXPORT_SYMBOL(exi_deselect);
++
++/**
++ * exi_transfer - Performs a read or write EXI transfer.
++ * @exi_channel: channel
++ * @data: pointer to data being read/written
++ * @len: length of data
++ * @opcode: operation code (EXI_OP_{READ,READWRITE,WRITE})
++ *
++ * Read or write data on a given EXI channel.
++ */
++void exi_transfer(struct exi_channel *exi_channel, void *data, size_t len,
++ int opcode, unsigned long flags)
++{
++ struct exi_command cmd;
++
++ exi_op_transfer(&cmd, exi_channel, data, len, opcode);
++ cmd.flags |= flags;
++ exi_run_command_and_wait(&cmd);
++}
++EXPORT_SYMBOL(exi_transfer);
++
++/*
++ * Internal. Release several previously reserved channels, according to a
++ * channel mask.
++ */
++static void __give_some_channels(unsigned int channel_mask)
++{
++ struct exi_channel *exi_channel;
++ unsigned int channel;
++
++ for (channel = 0; channel_mask && channel < EXI_MAX_CHANNELS;
++ channel++) {
++ if ((channel_mask & (1<<channel))) {
++ channel_mask &= ~(1<<channel);
++ exi_channel = __to_exi_channel(channel);
++ exi_channel->owner = NULL;
++ }
++ }
++}
++
++/*
++ * Internal. Try to reserve atomically several channels, according to a
++ * channel mask.
++ */
++static inline int __try_take_some_channels(unsigned int channel_mask,
++ struct exi_device *exi_device)
++{
++ struct exi_channel *exi_channel;
++ unsigned int channel, taken_channel_mask = 0;
++ unsigned long flags;
++ int result = 0;
++
++ for (channel = 0; channel_mask && channel < EXI_MAX_CHANNELS;
++ channel++) {
++ if ((channel_mask & (1<<channel))) {
++ channel_mask &= ~(1<<channel);
++ exi_channel = __to_exi_channel(channel);
++ spin_lock_irqsave(&exi_channel->lock, flags);
++ if (exi_channel->owner) {
++ spin_unlock_irqrestore(&exi_channel->lock,
++ flags);
++ result = -EBUSY;
++ break;
++ }
++ exi_channel->owner = exi_device;
++ taken_channel_mask |= (1<<channel);
++ spin_unlock_irqrestore(&exi_channel->lock, flags);
++ }
++ }
++
++ if (result)
++ __give_some_channels(taken_channel_mask);
++
++ return result;
++}
++
++/*
++ * Internal. Determine if we can trigger an exi event.
++ */
++static inline int exi_can_trigger_event(struct exi_event *event)
++{
++ return !__try_take_some_channels(event->channel_mask, event->owner);
++}
++
++/*
++ * Internal. Finish an exi event invocation.
++ */
++static inline void exi_finish_event(struct exi_event *event)
++{
++ __give_some_channels(event->channel_mask);
++}
++
++/*
++ * Internal. Trigger an exi event.
++ */
++static inline int exi_trigger_event(struct exi_channel *exi_channel,
++ struct exi_event *event)
++{
++ exi_event_handler_t handler;
++ int result = 0;
++
++ handler = event->handler;
++ if (handler)
++ result = handler(exi_channel, event->id, event->data);
++ return result;
++}
++
++/*
++ * Internal. Conditionally trigger an exi event.
++ */
++static void exi_cond_trigger_event(struct exi_channel *exi_channel,
++ unsigned int event_id, int csr_mask)
++{
++ struct exi_event *event;
++ unsigned long flags;
++
++ if ((exi_channel->csr & csr_mask)) {
++ event = &exi_channel->events[event_id];
++ if (exi_can_trigger_event(event)) {
++ spin_lock_irqsave(&exi_channel->lock, flags);
++ exi_channel->csr &= ~csr_mask;
++ spin_unlock_irqrestore(&exi_channel->lock, flags);
++ exi_trigger_event(exi_channel, event);
++ exi_finish_event(event);
++ }
++ }
++
++ return;
++}
++
++/*
++ * Internal. Tasklet used to execute delayed work.
++ */
++static void exi_tasklet(unsigned long param)
++{
++ struct exi_channel *exi_channel = (struct exi_channel *)param;
++
++ DBG("channel=%d, csr=%08lx\n", exi_channel->channel, exi_channel->csr);
++
++ if (exi_channel->queued_cmd) {
++ DBG("tasklet while xfer in flight on channel %d, csr = %08lx\n",
++ exi_channel->channel, exi_channel->csr);
++ }
++
++ /*
++ * We won't lauch event handlers if any of the channels we
++ * provided on event registration is in use.
++ */
++
++ /*exi_cond_trigger_event(exi_channel, EXI_EVENT_TC, EXI_CSR_TCINT);*/
++ exi_cond_trigger_event(exi_channel, EXI_EVENT_IRQ, EXI_CSR_EXIINT);
++ exi_cond_trigger_event(exi_channel, EXI_EVENT_INSERT, EXI_CSR_EXTIN);
++}
++
++/*
++ * Internal. Interrupt handler for EXI interrupts.
++ */
++static irqreturn_t exi_irq_handler(int irq, void *dev_id)
++{
++ struct exi_channel *exi_channel;
++ u32 __iomem *csr_reg;
++ u32 csr, status, mask;
++ unsigned long flags;
++
++ exi_channel_for_each(exi_channel) {
++ csr_reg = exi_channel->io_base + EXI_CSR;
++
++ /*
++ * Determine if we have pending interrupts on this channel,
++ * and which ones.
++ */
++ spin_lock_irqsave(&exi_channel->io_lock, flags);
++
++ csr = in_be32(csr_reg);
++ mask = csr & (EXI_CSR_EXTINMASK |
++ EXI_CSR_TCINTMASK | EXI_CSR_EXIINTMASK);
++ status = csr & (mask << 1);
++ if (!status) {
++ spin_unlock_irqrestore(&exi_channel->io_lock, flags);
++ continue;
++ }
++
++ /* XXX do not signal TC events for now... */
++ exi_channel->csr |= (status & ~EXI_CSR_TCINT);
++
++ DBG("channel=%d, csr=%08lx\n", exi_channel->channel,
++ exi_channel->csr);
++
++ /* ack all for this channel */
++ out_be32(csr_reg, csr | status);
++
++ spin_unlock_irqrestore(&exi_channel->io_lock, flags);
++
++ if ((status & EXI_CSR_TCINT))
++ exi_wait_for_transfer_one(exi_channel);
++ if ((status & EXI_CSR_EXTIN))
++ wake_up(&exi_bus_waitq);
++
++ if (exi_channel->csr && !exi_is_taken(exi_channel))
++ tasklet_schedule(&exi_channel->tasklet);
++ }
++ return IRQ_HANDLED;
++}
++
++/*
++ * Internal. Enable an exi event.
++ */
++static int exi_enable_event(struct exi_channel *exi_channel,
++ unsigned int event_id)
++{
++ u32 __iomem *csr_reg = exi_channel->io_base + EXI_CSR;
++ u32 csr;
++ unsigned long flags;
++
++ spin_lock_irqsave(&exi_channel->io_lock, flags);
++ csr = in_be32(csr_reg);
++
++ /* ack and enable the associated interrupt */
++ switch (event_id) {
++ case EXI_EVENT_INSERT:
++ out_be32(csr_reg, csr | (EXI_CSR_EXTIN | EXI_CSR_EXTINMASK));
++ break;
++ case EXI_EVENT_TC:
++ /*out_be32(csr_reg,
++ csr | (EXI_CSR_TCINT | EXI_CSR_TCINTMASK));*/
++ break;
++ case EXI_EVENT_IRQ:
++ out_be32(csr_reg, csr | (EXI_CSR_EXIINT | EXI_CSR_EXIINTMASK));
++ break;
++ }
++ spin_unlock_irqrestore(&exi_channel->io_lock, flags);
++ return 0;
++}
++
++/*
++ * Internal. Disable an exi event.
++ */
++static int exi_disable_event(struct exi_channel *exi_channel,
++ unsigned int event_id)
++{
++ u32 __iomem *csr_reg = exi_channel->io_base + EXI_CSR;
++ u32 csr;
++ unsigned long flags;
++
++ spin_lock_irqsave(&exi_channel->io_lock, flags);
++ csr = in_be32(csr_reg);
++
++ /* ack and disable the associated interrupt */
++ switch (event_id) {
++ case EXI_EVENT_INSERT:
++ out_be32(csr_reg, (csr | EXI_CSR_EXTIN) & ~EXI_CSR_EXTINMASK);
++ break;
++ case EXI_EVENT_TC:
++ /*out_be32(csr_reg,
++ (csr | EXI_CSR_TCINT) & ~EXI_CSR_TCINTMASK);*/
++ break;
++ case EXI_EVENT_IRQ:
++ out_be32(csr_reg, (csr | EXI_CSR_EXIINT) & ~EXI_CSR_EXIINTMASK);
++ break;
++ }
++ spin_unlock_irqrestore(&exi_channel->io_lock, flags);
++ return 0;
++}
++
++/**
++ * exi_event_register - Registers an event on a given channel.
++ * @exi_channel: channel
++ * @event_id: event id
++ * @handler: event handler
++ * @data: data passed to event handler
++ *
++ * Register a handler to be called whenever a specified event happens
++ * on the given channel.
++ */
++int exi_event_register(struct exi_channel *exi_channel, unsigned int event_id,
++ struct exi_device *exi_device,
++ exi_event_handler_t handler, void *data,
++ unsigned int channel_mask)
++{
++ struct exi_event *event;
++ int result = 0;
++
++ BUG_ON(event_id > EXI_MAX_EVENTS);
++
++ event = &exi_channel->events[event_id];
++
++ spin_lock(&exi_channel->lock);
++ if (event->handler) {
++ result = -EBUSY;
++ goto out;
++ }
++ event->owner = exi_device;
++ event->handler = handler;
++ event->data = data;
++ event->channel_mask = channel_mask;
++ exi_enable_event(exi_channel, event_id);
++
++out:
++ spin_unlock(&exi_channel->lock);
++ return result;
++}
++EXPORT_SYMBOL(exi_event_register);
++
++/**
++ * exi_event_unregister - Unregisters an event on a given channel.
++ * @exi_channel: channel
++ * @event_id: event id
++ *
++ * Unregister a previously registered event handler.
++ */
++int exi_event_unregister(struct exi_channel *exi_channel, unsigned int event_id)
++{
++ struct exi_event *event;
++ int result = 0;
++
++ BUG_ON(event_id > EXI_MAX_EVENTS);
++
++ event = &exi_channel->events[event_id];
++
++ spin_lock(&exi_channel->lock);
++ exi_disable_event(exi_channel, event_id);
++ event->owner = NULL;
++ event->handler = NULL;
++ event->data = NULL;
++ event->channel_mask = 0;
++ spin_unlock(&exi_channel->lock);
++
++ return result;
++}
++EXPORT_SYMBOL(exi_event_unregister);
++
++/*
++ * Internal. Quiesce a channel.
++ */
++static void exi_quiesce_channel(struct exi_channel *exi_channel, u32 csr_mask)
++{
++ /* wait for dma transfers to complete */
++ exi_wait_for_transfer_raw(exi_channel);
++
++ /* ack and mask all interrupts */
++ out_be32(exi_channel->io_base + EXI_CSR,
++ EXI_CSR_TCINT | EXI_CSR_EXIINT | EXI_CSR_EXTIN | csr_mask);
++}
++
++/*
++ * Internal. Quiesce all channels.
++ */
++static void exi_quiesce_all_channels(u32 csr_mask)
++{
++ struct exi_channel *exi_channel;
++
++ exi_channel_for_each(exi_channel) {
++ exi_quiesce_channel(exi_channel, csr_mask);
++ }
++}
++
++/**
++ * exi_get_id - Returns the EXI ID of a device
++ * @exi_channel: channel
++ * @device: device number on channel
++ * @freq: clock frequency index
++ *
++ * Returns the EXI ID of an EXI device on a given channel.
++ * Might sleep.
++ */
++u32 exi_get_id(struct exi_device *exi_device)
++{
++ struct exi_channel *exi_channel = exi_device->exi_channel;
++ u32 __iomem *csr_reg = exi_channel->io_base + EXI_CSR;
++ u32 id = EXI_ID_INVALID;
++ u16 cmd = 0;
++
++ /* ask for the EXI id */
++ exi_dev_take(exi_device);
++ exi_dev_select(exi_device);
++ exi_dev_write(exi_device, &cmd, sizeof(cmd));
++ exi_dev_read(exi_device, &id, sizeof(id));
++ exi_dev_deselect(exi_device);
++ exi_dev_give(exi_device);
++
++ /* "canonicalize" the id */
++ if (!id)
++ id = EXI_ID_INVALID;
++ /*
++ * We return a EXI_ID_NONE if there is some unidentified device
++ * inserted in memcard slot A or memcard slot B.
++ * This, for example, allows the SD/MMC driver to see inserted cards.
++ */
++ if (id == EXI_ID_INVALID) {
++ if ((__to_channel(exi_channel) == 0 ||
++ __to_channel(exi_channel) == 1)
++ && exi_device->eid.device == 0) {
++ if (in_be32(csr_reg) & EXI_CSR_EXT)
++ id = EXI_ID_NONE;
++ }
++ }
++
++ return id;
++}
++EXPORT_SYMBOL(exi_get_id);
++
++/*
++ * Tells if there is a device inserted in one of the memory card slots.
++ */
++int exi_get_ext_line(struct exi_channel *exi_channel)
++{
++ u32 __iomem *csr_reg = exi_channel->io_base + EXI_CSR;
++ return (in_be32(csr_reg) & EXI_CSR_EXT) ? 1 : 0;
++}
++
++/*
++ * Saves the current insertion status of a given channel.
++ */
++void exi_update_ext_status(struct exi_channel *exi_channel)
++{
++ if (exi_get_ext_line(exi_channel))
++ exi_channel->flags |= EXI_EXT;
++ else
++ exi_channel->flags &= ~EXI_EXT;
++}
++
++/*
++ * Pseudo-Internal. Initialize basic channel structures and hardware.
++ */
++int exi_hw_init(char *module_name, struct resource *mem, unsigned int irq)
++{
++ struct exi_channel *exi_channel;
++ int channel;
++ int result;
++
++ exi_io_mem = ioremap(mem->start, mem->end - mem->start + 1);
++ if (!exi_io_mem) {
++ drv_printk(KERN_ERR, "ioremap failed\n");
++ return -ENOMEM;
++ }
++
++ for (channel = 0; channel < EXI_MAX_CHANNELS; channel++) {
++ exi_channel = __to_exi_channel(channel);
++
++ /* initialize a channel structure */
++ exi_channel_init(exi_channel, channel);
++ }
++
++ /* calm down the hardware and allow extractions */
++ exi_quiesce_all_channels(EXI_CSR_EXTINMASK);
++
++ /* register the exi interrupt handler */
++ result = request_irq(irq, exi_irq_handler, 0, module_name, NULL);
++ if (result)
++ drv_printk(KERN_ERR, "failed to register IRQ %d\n", irq);
++
++ return result;
++}
++
++/*
++ * Pseudo-Internal.
++ */
++void exi_hw_exit(struct resource *mem, unsigned int irq)
++{
++ exi_quiesce_all_channels(0);
++ iounmap(exi_io_mem);
++ free_irq(irq, NULL);
++}
+diff --git a/drivers/exi/exi-hw.h b/drivers/exi/exi-hw.h
+new file mode 100644
+index 0000000..a2382bf
+--- /dev/null
++++ b/drivers/exi/exi-hw.h
+@@ -0,0 +1,195 @@
++/*
++ * drivers/exi/exi-hw.h
++ *
++ * Nintendo GameCube EXpansion Interface support. Hardware routines.
++ * Copyright (C) 2004-2009 The GameCube Linux Team
++ * Copyright (C) 2004,2005 Todd Jeffreys <todd@voidpointer.org>
++ * Copyright (C) 2005,2006,2007,2008,2009 Albert Herranz
++ *
++ * 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.
++ *
++ */
++
++#ifndef __EXI_HW_H
++#define __EXI_HW_H
++
++#include <linux/exi.h>
++#include <linux/interrupt.h>
++#include <linux/resource.h>
++#include <asm/atomic.h>
++
++
++#define EXI_MAX_CHANNELS 3 /* channels on the EXI bus */
++#define EXI_DEVICES_PER_CHANNEL 3 /* number of devices per EXI channel */
++#define EXI_MAX_EVENTS 3 /* types of events on the EXI bus */
++
++#define EXI_CLK_1MHZ 0
++#define EXI_CLK_2MHZ 1
++#define EXI_CLK_4MHZ 2
++#define EXI_CLK_8MHZ 3
++#define EXI_CLK_16MHZ 4
++#define EXI_CLK_32MHZ 5
++
++#define EXI_MAX_FREQ 7
++#define EXI_FREQ_SCAN EXI_CLK_8MHZ
++
++#define EXI_READ 0
++#define EXI_WRITE 1
++
++#define EXI_IDI_MAX_SIZE 4
++
++
++#define EXI_DMA_ALIGN 0x1f /* 32 bytes */
++
++#define EXI_CHANNEL_SPACING 0x14
++
++#define EXI_CSR 0x00
++#define EXI_CSR_EXIINTMASK (1<<0)
++#define EXI_CSR_EXIINT (1<<1)
++#define EXI_CSR_TCINTMASK (1<<2)
++#define EXI_CSR_TCINT (1<<3)
++#define EXI_CSR_CLKMASK (0x7<<4)
++#define EXI_CSR_CLK_1MHZ (EXI_CLK_1MHZ<<4)
++#define EXI_CSR_CLK_2MHZ (EXI_CLK_2MHZ<<4)
++#define EXI_CSR_CLK_4MHZ (EXI_CLK_4MHZ<<4)
++#define EXI_CSR_CLK_8MHZ (EXI_CLK_8MHZ<<4)
++#define EXI_CSR_CLK_16MHZ (EXI_CLK_16MHZ<<4)
++#define EXI_CSR_CLK_32MHZ (EXI_CLK_32MHZ<<4)
++#define EXI_CSR_CSMASK (0x7<<7)
++#define EXI_CSR_CS_0 (0x1<<7) /* Chip Select 001 */
++#define EXI_CSR_CS_1 (0x2<<7) /* Chip Select 010 */
++#define EXI_CSR_CS_2 (0x4<<7) /* Chip Select 100 */
++#define EXI_CSR_EXTINMASK (1<<10)
++#define EXI_CSR_EXTIN (1<<11)
++#define EXI_CSR_EXT (1<<12)
++
++#define EXI_MAR 0x04
++
++#define EXI_LENGTH 0x08
++
++#define EXI_CR 0x0c
++#define EXI_CR_TSTART (1<<0)
++#define EXI_CR_DMA (1<<1)
++#define EXI_CR_READ (0<<2)
++#define EXI_CR_WRITE (1<<2)
++#define EXI_CR_READ_WRITE (2<<2)
++#define EXI_CR_TLEN(len) (((len)-1)<<4)
++
++#define EXI_DATA 0x10
++
++enum {
++ __EXI_DMABUSY = 0,
++ __EXI_EXT,
++};
++
++/*
++ * For registering event handlers with the exi layer.
++ */
++struct exi_event {
++ int id; /* event id */
++ struct exi_device *owner; /* device owning of the event */
++ exi_event_handler_t handler;
++ void *data;
++ unsigned int channel_mask; /* channels used by handler */
++};
++
++/*
++ * This structure represents an exi channel.
++ */
++struct exi_channel {
++ spinlock_t lock; /* misc channel lock */
++
++ int channel;
++ unsigned long flags;
++#define EXI_DMABUSY (1<<__EXI_DMABUSY)
++#define EXI_EXT (1<<__EXI_EXT)
++
++ spinlock_t io_lock; /* serializes access to CSR */
++ void __iomem *io_base;
++
++ struct exi_device *owner;
++ wait_queue_head_t wait_queue;
++
++ struct exi_command *queued_cmd;
++ struct exi_command post_cmd;
++
++ unsigned long csr;
++ struct tasklet_struct tasklet;
++
++ unsigned long stats_idi_xfers;
++ unsigned long stats_dma_xfers;
++ unsigned long stats_xfers;
++
++ struct exi_event events[EXI_MAX_EVENTS];
++};
++
++extern struct exi_device *exi_channel_owner(struct exi_channel *exi_channel);
++extern int exi_get_ext_line(struct exi_channel *exi_channel);
++extern void exi_update_ext_status(struct exi_channel *exi_channel);
++
++extern int exi_hw_init(char *name, struct resource *mem, unsigned int irq);
++extern void exi_hw_exit(struct resource *mem, unsigned int irq);
++
++#define exi_is_taken(x) ((x)->owner)
++
++/*
++ * Internal.
++ * Declare simple transfer functions for single bytes, words and dwords,
++ * and build a general transfer function based on that.
++ */
++#define __declare__exi_transfer_raw(_type, _val, _data, _on_write, _on_read) \
++static inline void __exi_transfer_raw_##_type(struct exi_channel *exi_channel,\
++ _type * _data, int mode) \
++{ \
++ u32 __iomem *csr_reg = exi_channel->io_base + EXI_CSR; \
++ u32 __iomem *data_reg = exi_channel->io_base + EXI_DATA; \
++ u32 __iomem *cr_reg = exi_channel->io_base + EXI_CR; \
++ u32 _val = ~0; \
++ unsigned long flags; \
++ \
++ /* \
++ * On reads we write too some known value to EXIxDATA because \
++ * information currently stored there is leaked to the \
++ * MOSI line, confusing some hardware. \
++ */ \
++ if (((mode&0xf) != EXI_OP_READ)) /* write or read-write */ \
++ _on_write; \
++ out_be32(data_reg, _val); \
++ \
++ /* start transfer */ \
++ _val = EXI_CR_TSTART | EXI_CR_TLEN(sizeof(_type)) | (mode&0xf); \
++ out_be32(cr_reg, _val); \
++ \
++ /* wait for transfer completion */ \
++ while (in_be32(cr_reg) & EXI_CR_TSTART) \
++ cpu_relax(); \
++ \
++ /* XXX check if we need that on immediate mode */ \
++ /* assert transfer complete interrupt */ \
++ spin_lock_irqsave(&exi_channel->io_lock, flags); \
++ out_be32(csr_reg, in_be32(csr_reg) | EXI_CSR_TCINT); \
++ spin_unlock_irqrestore(&exi_channel->io_lock, flags); \
++ \
++ if ((mode&0xf) != EXI_OP_WRITE) { /* read or read-write */ \
++ _val = in_be32(data_reg); \
++ _on_read; \
++ } \
++}
++
++#define __declare__exi_transfer_raw_simple(_type) \
++__declare__exi_transfer_raw( \
++ _type, _v, _d, \
++ _v = *(_d) << (32 - (8*sizeof(_type))), \
++ *(_d) = (_type)(_v >> (32 - (8*sizeof(_type)))) \
++ )
++
++__declare__exi_transfer_raw_simple(u8)
++__declare__exi_transfer_raw_simple(u16)
++__declare__exi_transfer_raw_simple(u32)
++
++extern wait_queue_head_t exi_bus_waitq;
++
++#endif /* __EXI_HW_H */
+diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig
+index 5f9d860..bcf4d1f 100644
+--- a/drivers/input/Kconfig
++++ b/drivers/input/Kconfig
+@@ -180,6 +180,8 @@ source "drivers/input/serio/Kconfig"
+
+ source "drivers/input/gameport/Kconfig"
+
++source "drivers/input/si/Kconfig"
++
+ endmenu
+
+ endmenu
+diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
+index efd70a9..ed0a67a 100644
+--- a/drivers/input/keyboard/Kconfig
++++ b/drivers/input/keyboard/Kconfig
+@@ -314,6 +314,17 @@ config KEYBOARD_BFIN
+ To compile this driver as a module, choose M here: the
+ module will be called bf54x-keys.
+
++config KEYBOARD_WII
++ tristate "Nintendo Wii USB keyboard IOS glue"
++ depends on (WII && !USB)
++ help
++ Say Y here if you have a Nintendo Wii console running Linux and have
++ a keyboard attached to one of its USB ports.
++ This driver uses the IOS interface glue to access the USB keyboard.
++
++ To compile this driver as a module, choose M here: the
++ module will be called rvl-stkbd.
++
+ config KEYBOARD_SH_KEYSC
+ tristate "SuperH KEYSC keypad support"
+ depends on SUPERH
+diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
+index 0edc8f2..2918d70 100644
+--- a/drivers/input/keyboard/Makefile
++++ b/drivers/input/keyboard/Makefile
+@@ -27,3 +27,4 @@ obj-$(CONFIG_KEYBOARD_HP7XX) += jornada720_kbd.o
+ obj-$(CONFIG_KEYBOARD_MAPLE) += maple_keyb.o
+ obj-$(CONFIG_KEYBOARD_BFIN) += bf54x-keys.o
+ obj-$(CONFIG_KEYBOARD_SH_KEYSC) += sh_keysc.o
++obj-$(CONFIG_KEYBOARD_WII) += rvl-stkbd.o
+diff --git a/drivers/input/keyboard/rvl-stkbd.c b/drivers/input/keyboard/rvl-stkbd.c
+new file mode 100644
+index 0000000..272f772
+--- /dev/null
++++ b/drivers/input/keyboard/rvl-stkbd.c
+@@ -0,0 +1,512 @@
++/*
++ * drivers/input/keyboard/rvl-stkbd.c
++ *
++ * Nintendo Wii starlet keyboard driver.
++ * Copyright (C) 2008-2009 The GameCube Linux Team
++ * Copyright (C) 2008,2009 Albert Herranz
++ *
++ * 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:
++ * The keyboard driver requires at least IOS30 installed.
++ * LED support is pending.
++ */
++
++#define DEBUG
++
++#define DBG(fmt, arg...) pr_debug(fmt, ##arg)
++
++#include <linux/init.h>
++#include <linux/input.h>
++#include <linux/kernel.h>
++#include <linux/kthread.h>
++#include <linux/module.h>
++#include <linux/of_platform.h>
++#include <asm/starlet.h>
++
++#define DRV_MODULE_NAME "rvl-stkbd"
++#define DRV_DESCRIPTION "Nintendo Wii starlet keyboard driver"
++#define DRV_AUTHOR "Albert Herranz"
++
++static char stkbd_driver_version[] = "0.1i";
++
++#define drv_printk(level, format, arg...) \
++ printk(level DRV_MODULE_NAME ": " format , ## arg)
++
++/*
++ * Keyboard events from IOS.
++ */
++#define STKBD_EV_CONNECT 0x00000000
++#define STKBD_EV_DISCONNECT 0x00000001
++#define STKBD_EV_REPORT 0x00000002
++
++struct stkbd_event {
++ u32 type;
++ u32 _unk1;
++ union {
++ struct {
++ u8 modifiers;
++ u8 reserved;
++ u8 keys[6];
++ } report;
++ u8 raw_report[8];
++ };
++} __attribute__((packed));
++
++/*
++ * Keyboard device.
++ */
++
++enum {
++ __STKBD_RUNNING = 1, /* device is opened and running */
++ __STKBD_WAITING_REPORT /* waiting for IOS report */
++};
++
++struct stkbd_keyboard {
++ int fd;
++
++ struct stkbd_event *event;
++ u8 old_raw_report[8];
++
++ unsigned long flags;
++#define STKBD_RUNNING (1 << __STKBD_RUNNING)
++#define STKBD_WAITING_REPORT (1 << __STKBD_WAITING_REPORT)
++
++ char name[32];
++ struct input_dev *idev;
++ unsigned int usage;
++
++ struct device *dev;
++};
++
++/* device path in IOS for the USB keyboard */
++static char stkbd_dev_path[] = "/dev/usb/kbd";
++
++/*
++ * Keycodes are standard USB keyboard HID keycodes.
++ * We use the same table as in drivers/hid/usbhid/usbkbd.c.
++ */
++
++#define NR_SCANCODES 256
++
++static unsigned char stkbd_keycode[NR_SCANCODES] = {
++/*000*/ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++/*004*/ KEY_A, KEY_B, KEY_C, KEY_D,
++/*008*/ KEY_E, KEY_F, KEY_G, KEY_H,
++/*012*/ KEY_I, KEY_J, KEY_K, KEY_L,
++/*016*/ KEY_M, KEY_N, KEY_O, KEY_P,
++/*020*/ KEY_Q, KEY_R, KEY_S, KEY_T,
++/*024*/ KEY_U, KEY_V, KEY_W, KEY_X,
++/*028*/ KEY_Y, KEY_Z, KEY_1, KEY_2,
++/*032*/ KEY_3, KEY_4, KEY_5, KEY_6,
++/*036*/ KEY_7, KEY_8, KEY_9, KEY_0,
++/*040*/ KEY_ENTER, KEY_ESC, KEY_BACKSPACE, KEY_TAB,
++/*044*/ KEY_SPACE, KEY_MINUS, KEY_EQUAL, KEY_LEFTBRACE,
++/*048*/ KEY_RIGHTBRACE, KEY_BACKSLASH, KEY_BACKSLASH, KEY_SEMICOLON,
++/*052*/ KEY_APOSTROPHE, KEY_GRAVE, KEY_COMMA, KEY_DOT,
++/*056*/ KEY_SLASH, KEY_CAPSLOCK, KEY_F1, KEY_F2,
++/*060*/ KEY_F3, KEY_F4, KEY_F5, KEY_F6,
++/*064*/ KEY_F7, KEY_F8, KEY_F9, KEY_F10,
++/*068*/ KEY_F11, KEY_F12, KEY_SYSRQ, KEY_SCROLLLOCK,
++/*072*/ KEY_PAUSE, KEY_INSERT, KEY_HOME, KEY_PAGEUP,
++/*076*/ KEY_DELETE, KEY_END, KEY_PAGEDOWN, KEY_RIGHT,
++/*080*/ KEY_LEFT, KEY_DOWN, KEY_UP, KEY_NUMLOCK,
++/*084*/ KEY_KPSLASH, KEY_KPASTERISK, KEY_KPMINUS, KEY_KPPLUS,
++/*088*/ KEY_KPENTER, KEY_KP1, KEY_KP2, KEY_KP3,
++/*092*/ KEY_KP4, KEY_KP5, KEY_KP6, KEY_KP7,
++/*096*/ KEY_KP8, KEY_KP9, KEY_KP0, KEY_KPDOT,
++/*100*/ KEY_102ND, KEY_COMPOSE, KEY_POWER, KEY_KPEQUAL,
++/*104*/ KEY_F13, KEY_F14, KEY_F15, KEY_F16,
++/*108*/ KEY_F17, KEY_F18, KEY_F19, KEY_F20,
++/*112*/ KEY_F21, KEY_F22, KEY_F23, KEY_F24,
++/*116*/ KEY_OPEN, KEY_HELP, KEY_PROPS, KEY_FRONT,
++/*120*/ KEY_STOP, KEY_AGAIN, KEY_UNDO, KEY_CUT,
++/*124*/ KEY_COPY, KEY_PASTE, KEY_FIND, KEY_MUTE,
++/*128*/ KEY_VOLUMEUP, KEY_VOLUMEDOWN, KEY_RESERVED, KEY_RESERVED,
++/*132*/ KEY_RESERVED, KEY_KPCOMMA, KEY_RESERVED, KEY_RO,
++/*136*/ KEY_KATAKANAHIRAGANA, KEY_YEN, KEY_HENKAN, KEY_MUHENKAN,
++/*140*/ KEY_KPJPCOMMA, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++/*144*/ KEY_HANGEUL, KEY_HANJA, KEY_KATAKANA, KEY_HIRAGANA,
++/*148*/ KEY_ZENKAKUHANKAKU, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++/*152*/ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++/*156*/ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++/*160*/ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++/*164*/ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++/*168*/ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++/*172*/ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++/*176*/ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++/*180*/ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++/*184*/ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++/*188*/ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++/*192*/ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++/*196*/ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++/*200*/ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++/*204*/ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++/*208*/ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++/*212*/ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++/*216*/ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++/*220*/ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++/*224*/ KEY_LEFTCTRL, KEY_LEFTSHIFT, KEY_LEFTALT, KEY_LEFTMETA,
++/*228*/ KEY_RIGHTCTRL, KEY_RIGHTSHIFT, KEY_RIGHTALT, KEY_RIGHTMETA,
++/*232*/ KEY_PLAYPAUSE, KEY_STOPCD, KEY_PREVIOUSSONG, KEY_NEXTSONG,
++/*236*/ KEY_EJECTCD, KEY_VOLUMEUP, KEY_VOLUMEDOWN, KEY_MUTE,
++/*240*/ KEY_WWW, KEY_BACK, KEY_FORWARD, KEY_STOP,
++/*244*/ KEY_FIND, KEY_SCROLLUP, KEY_SCROLLDOWN, KEY_EDIT,
++/*248*/ KEY_SLEEP, KEY_SCROLLLOCK, KEY_REFRESH, KEY_CALC,
++/*252*/ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++};
++
++
++static int stkbd_wait_for_events(struct stkbd_keyboard *kbd);
++
++static void stkbd_dispatch_report(struct stkbd_keyboard *kbd)
++{
++ struct stkbd_event *event = kbd->event;
++ u8 *new = event->raw_report;
++ u8 *old = kbd->old_raw_report;
++ int i;
++
++ /*
++ * The report is a standard USB HID report for a keyboard.
++ * Modifiers come in byte 0 as variable data and map to
++ * positions 224-231 of the USB HID keyboard/keypad page.
++ */
++ for (i = 0; i < 8; i++)
++ input_report_key(kbd->idev, stkbd_keycode[i + 224],
++ (new[0] >> i) & 1);
++
++ /*
++ * Byte 1 is reserved and ignored here.
++ * Bytes 2 to 7 contain the indexes of up to 6 keys pressed.
++ * A value of 01 for an index means "Keyboard ErrorRollOver" and is
++ * reported when the keyboard is in error (for example, when too
++ * many keys are simultaneously pressed).
++ * Index values less than or equal to 03 can be safely ignored.
++ */
++ for (i = 2; i < 8; i++) {
++ /* released keys are old indexes not found in new array */
++ if (old[i] > 3 && memscan(new + 2, old[i], 6) == new + 8) {
++ if (stkbd_keycode[old[i]])
++ input_report_key(kbd->idev,
++ stkbd_keycode[old[i]], 0);
++ else
++ drv_printk(KERN_WARNING, "unknown key"
++ " (scancode %#x) released.", old[i]);
++ }
++
++ /* pressed keys are new indexes not found in old array */
++ if (new[i] > 3 && memscan(old + 2, new[i], 6) == old + 8) {
++ if (stkbd_keycode[new[i]])
++ input_report_key(kbd->idev,
++ stkbd_keycode[new[i]], 1);
++ else
++ drv_printk(KERN_WARNING, "unknown key"
++ " (scancode %#x) pressed.", new[i]);
++ }
++ }
++
++ input_sync(kbd->idev);
++ memcpy(old, new, 8);
++}
++
++static int stkbd_dispatch_ipc_request(struct starlet_ipc_request *req)
++{
++ struct stkbd_keyboard *kbd;
++ struct stkbd_event *event;
++ int error;
++
++ /* retrieve the interesting data before freeing the request */
++ kbd = req->done_data;
++ error = req->result;
++ starlet_ipc_free_request(req);
++
++ clear_bit(__STKBD_WAITING_REPORT, &kbd->flags);
++
++ if (kbd->fd == -1)
++ return -ENODEV;
++
++ if (error) {
++ DBG("%s: error=%d (%x)\n", __func__, error, error);
++ } else {
++ event = kbd->event;
++
++ switch (event->type) {
++ case STKBD_EV_CONNECT:
++ drv_printk(KERN_INFO, "keyboard connected\n");
++ break;
++ case STKBD_EV_DISCONNECT:
++ drv_printk(KERN_INFO, "keyboard disconnected\n");
++ break;
++ case STKBD_EV_REPORT:
++ if (test_bit(__STKBD_RUNNING, &kbd->flags))
++ stkbd_dispatch_report(kbd);
++ break;
++ }
++
++ error = stkbd_wait_for_events(kbd);
++ }
++ return error;
++}
++
++static int stkbd_wait_for_events(struct stkbd_keyboard *kbd)
++{
++ struct stkbd_event *event = kbd->event;
++ int error = 0;
++
++ if (!test_and_set_bit(__STKBD_WAITING_REPORT, &kbd->flags)) {
++ error = starlet_ioctl_nowait(kbd->fd, 0,
++ NULL, 0,
++ event, sizeof(*event),
++ stkbd_dispatch_ipc_request,
++ kbd);
++ if (error)
++ drv_printk(KERN_ERR, "ioctl error %d (%04x)\n",
++ error, error);
++ }
++ return error;
++}
++
++/*
++ * Input driver hooks.
++ *
++ */
++
++static DEFINE_MUTEX(open_lock);
++
++static int stkbd_open(struct input_dev *idev)
++{
++ struct stkbd_keyboard *kbd = input_get_drvdata(idev);
++ int error = 0;
++
++ if (!kbd)
++ return -ENODEV;
++
++ mutex_lock(&open_lock);
++ kbd->usage++;
++ set_bit(__STKBD_RUNNING, &kbd->flags);
++ mutex_unlock(&open_lock);
++
++ return error;
++}
++
++static void stkbd_close(struct input_dev *idev)
++{
++ struct stkbd_keyboard *kbd = input_get_drvdata(idev);
++
++ if (!kbd)
++ return;
++
++ mutex_lock(&open_lock);
++ kbd->usage--;
++ if (kbd->usage == 0)
++ clear_bit(__STKBD_RUNNING, &kbd->flags);
++ mutex_unlock(&open_lock);
++}
++
++static void stkbd_setup_keyboard(struct input_dev *idev)
++{
++ int i;
++
++ set_bit(EV_KEY, idev->evbit);
++ set_bit(EV_REP, idev->evbit);
++
++ for (i = 0; i < 255; ++i)
++ set_bit(stkbd_keycode[i], idev->keybit);
++ clear_bit(0, idev->keybit);
++}
++
++static int stkbd_init_input_dev(struct stkbd_keyboard *kbd)
++{
++ struct input_dev *idev;
++ int error;
++
++ idev = input_allocate_device();
++ if (!idev) {
++ drv_printk(KERN_ERR, "failed to allocate input_dev\n");
++ return -ENOMEM;
++ }
++
++ idev->dev.parent = kbd->dev;
++
++ strcpy(kbd->name, "USB keyboard");
++ idev->name = kbd->name;
++
++ input_set_drvdata(idev, kbd);
++ kbd->idev = idev;
++
++ stkbd_setup_keyboard(idev);
++
++ idev->open = stkbd_open;
++ idev->close = stkbd_close;
++
++ error = input_register_device(kbd->idev);
++ if (error) {
++ input_free_device(kbd->idev);
++ return error;
++ }
++
++ return 0;
++}
++
++static void stkbd_exit_input_dev(struct stkbd_keyboard *kbd)
++{
++ input_free_device(kbd->idev);
++}
++
++/*
++ * Setup routines.
++ *
++ */
++
++static int stkbd_init(struct stkbd_keyboard *kbd)
++{
++ struct stkbd_event *event;
++ int error;
++
++ event = starlet_kzalloc(sizeof(*event), GFP_KERNEL);
++ if (!event) {
++ drv_printk(KERN_ERR, "failed to allocate stkbd_event\n");
++ error = -ENOMEM;
++ goto err;
++ }
++ kbd->event = event;
++
++ kbd->fd = starlet_open(stkbd_dev_path, 0);
++ if (kbd->fd < 0) {
++ drv_printk(KERN_ERR, "unable to open device %s\n",
++ stkbd_dev_path);
++ error = kbd->fd;
++ goto err_event;
++ }
++
++ error = stkbd_init_input_dev(kbd);
++ if (error)
++ goto err_fd;
++
++ /* start to grab events from the keyboard */
++ error = stkbd_wait_for_events(kbd);
++ if (error)
++ goto err_input_dev;
++
++ return 0;
++
++err_input_dev:
++ stkbd_exit_input_dev(kbd);
++err_fd:
++ starlet_close(kbd->fd);
++err_event:
++ starlet_kfree(event);
++err:
++ return error;
++}
++
++static void stkbd_exit(struct stkbd_keyboard *kbd)
++{
++ stkbd_exit_input_dev(kbd);
++ starlet_close(kbd->fd);
++ starlet_kfree(kbd->event);
++}
++
++/*
++ * Driver model helper routines.
++ *
++ */
++
++static int stkbd_do_probe(struct device *dev)
++{
++ struct stkbd_keyboard *kbd;
++ int error;
++
++ kbd = kzalloc(sizeof(*kbd), GFP_KERNEL);
++ if (!kbd) {
++ drv_printk(KERN_ERR, "failed to allocate stkbd_keyboard\n");
++ return -ENOMEM;
++ }
++ dev_set_drvdata(dev, kbd);
++ kbd->dev = dev;
++
++ error = stkbd_init(kbd);
++ if (error) {
++ dev_set_drvdata(dev, NULL);
++ kfree(kbd);
++ }
++ return error;
++}
++
++static int stkbd_do_remove(struct device *dev)
++{
++ struct stkbd_keyboard *kbd = dev_get_drvdata(dev);
++
++ if (kbd) {
++ stkbd_exit(kbd);
++ dev_set_drvdata(dev, NULL);
++ kfree(kbd);
++ return 0;
++ }
++ return -ENODEV;
++}
++
++
++/*
++ * OF platform driver hooks.
++ *
++ */
++
++static int __init stkbd_of_probe(struct of_device *odev,
++ const struct of_device_id *match)
++{
++ return stkbd_do_probe(&odev->dev);
++}
++
++static int __exit stkbd_of_remove(struct of_device *odev)
++{
++ return stkbd_do_remove(&odev->dev);
++}
++
++static struct of_device_id stkbd_of_match[] = {
++ { .compatible = "nintendo,starlet-keyboard" },
++ { },
++};
++
++
++MODULE_DEVICE_TABLE(of, stkbd_of_match);
++
++static struct of_platform_driver stkbd_of_driver = {
++ .owner = THIS_MODULE,
++ .name = DRV_MODULE_NAME,
++ .match_table = stkbd_of_match,
++ .probe = stkbd_of_probe,
++ .remove = stkbd_of_remove,
++};
++
++
++/*
++ * Module interface hooks.
++ *
++ */
++
++static int __init stkbd_init_module(void)
++{
++ drv_printk(KERN_INFO, "%s - version %s\n", DRV_DESCRIPTION,
++ stkbd_driver_version);
++
++ return of_register_platform_driver(&stkbd_of_driver);
++}
++
++static void __exit stkbd_exit_module(void)
++{
++ of_unregister_platform_driver(&stkbd_of_driver);
++}
++
++module_init(stkbd_init_module);
++module_exit(stkbd_exit_module);
++
++MODULE_DESCRIPTION(DRV_DESCRIPTION);
++MODULE_AUTHOR(DRV_AUTHOR);
++MODULE_LICENSE("GPL");
+diff --git a/drivers/input/si/Kconfig b/drivers/input/si/Kconfig
+new file mode 100644
+index 0000000..51de017
+--- /dev/null
++++ b/drivers/input/si/Kconfig
+@@ -0,0 +1,14 @@
++#
++# Nintendo GameCube/Wii Serial Interface (SI) configuration
++#
++
++config GAMECUBE_SI
++ tristate "Nintendo GameCube/Wii Serial Interface (SI) support"
++ depends on GAMECUBE_COMMON
++ ---help---
++ Say Y here if you want to use the standard pads as joysticks or
++ want to use a keyboard. Everything is autodetected.
++
++ NOTE: Keyboard detection doesn't work 100%. Building this as a
++ module is recommended, this way you can unload/load the driver
++ to re-detect.
+diff --git a/drivers/input/si/Makefile b/drivers/input/si/Makefile
+new file mode 100644
+index 0000000..5087995
+--- /dev/null
++++ b/drivers/input/si/Makefile
+@@ -0,0 +1,5 @@
++#
++# Makefile for the Nintendo GameCube/Wii Serial Interface (SI).
++#
++
++obj-$(CONFIG_GAMECUBE_SI) += gcn-si.o
+diff --git a/drivers/input/si/gcn-keymap.h b/drivers/input/si/gcn-keymap.h
+new file mode 100644
+index 0000000..7a3345a
+--- /dev/null
++++ b/drivers/input/si/gcn-keymap.h
+@@ -0,0 +1,79 @@
++/*
++ * keymap for a Datel adapater + US keyboard (not the normal keyboard)
++ * not mapped:
++ * printscreen / sysreq
++ * pause / break
++ * numlock
++ * windows key 1
++ * windows key 2
++ * windows menu key
++ *
++ * cursor keys send both 36 and their own code, so 36 must be RESERVED
++ */
++
++static unsigned char gamecube_keymap[] = {
++ /* 00 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++ KEY_RESERVED, KEY_RESERVED, KEY_HOME, KEY_END,
++ /* 08 */ KEY_PAGEUP, KEY_PAGEDOWN, KEY_SCROLLLOCK, KEY_RESERVED,
++ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++ /* 10 */ KEY_A, KEY_B, KEY_C, KEY_D,
++ KEY_E, KEY_F, KEY_G, KEY_H,
++ /* 18 */ KEY_I, KEY_J, KEY_K, KEY_L,
++ KEY_M, KEY_N, KEY_O, KEY_P,
++ /* 20 */ KEY_Q, KEY_R, KEY_S, KEY_T,
++ KEY_U, KEY_V, KEY_W, KEY_X,
++ /* 28 */ KEY_Y, KEY_Z, KEY_1, KEY_2,
++ KEY_3, KEY_4, KEY_5, KEY_6,
++ /* 30 */ KEY_7, KEY_8, KEY_9, KEY_0,
++ KEY_MINUS, KEY_EQUAL, KEY_RESERVED, KEY_KPASTERISK,
++ /* 38 */ KEY_LEFTBRACE, KEY_SEMICOLON, KEY_APOSTROPHE, KEY_RIGHTBRACE,
++ KEY_COMMA, KEY_DOT, KEY_SLASH, KEY_BACKSLASH,
++ /* 40 */ KEY_F1, KEY_F2, KEY_F3, KEY_F4,
++ KEY_F5, KEY_F6, KEY_F7, KEY_F8,
++ /* 48 */ KEY_F9, KEY_F10, KEY_F11, KEY_F12,
++ KEY_ESC, KEY_INSERT, KEY_DELETE, KEY_GRAVE,
++ /* 50 */ KEY_BACKSPACE, KEY_TAB, KEY_RESERVED, KEY_CAPSLOCK,
++ KEY_LEFTSHIFT, KEY_RIGHTSHIFT, KEY_LEFTCTRL, KEY_LEFTALT,
++ /* 58 */ KEY_RESERVED, KEY_SPACE, KEY_RESERVED, KEY_RESERVED,
++ KEY_LEFT, KEY_DOWN, KEY_UP, KEY_RIGHT,
++ /* 60 */ KEY_RESERVED, KEY_ENTER, KEY_RESERVED, KEY_RESERVED,
++ KEY_SEMICOLON, KEY_KPPLUS, KEY_RESERVED, KEY_RESERVED,
++ /* 68 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++ /* 70 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++ /* 78 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++ /* 80 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++ /* 88 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++ /* 90 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++ /* 98 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++ /* a0 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++ /* a8 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++ /* b0 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++ /* b8 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++ /* c0 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++ /* c8 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++ /* d0 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++ /* d8 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++ /* e0 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++ /* e8 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++ /* f0 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++ /* f8 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED
++};
+diff --git a/drivers/input/si/gcn-si.c b/drivers/input/si/gcn-si.c
+new file mode 100644
+index 0000000..731437f
+--- /dev/null
++++ b/drivers/input/si/gcn-si.c
+@@ -0,0 +1,730 @@
++/*
++ * drivers/input/gcn-si.c
++ *
++ * Nintendo GameCube/Wii Serial Interface (SI) driver.
++ * Copyright (C) 2004-2009 The GameCube Linux Team
++ * Copyright (C) 2004 Steven Looman
++ * Copyright (C) 2005,2008,2009 Albert Herranz
++ *
++ * 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.
++ *
++ */
++
++/* #define SI_DEBUG */
++
++#include <linux/delay.h>
++#include <linux/init.h>
++#include <linux/input.h>
++#include <linux/io.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/of_platform.h>
++#include <linux/timer.h>
++
++/*
++ * This keymap is for a datel adapter + normal US keyboard.
++ */
++#include "gcn-keymap.h"
++
++/*
++ * Defining HACK_FORCE_KEYBOARD_PORT allows one to specify a port that
++ * will be identified as a keyboard port in case the port gets incorrectly
++ * identified.
++ */
++#define HACK_FORCE_KEYBOARD_PORT
++
++
++#define DRV_MODULE_NAME "gcn-si"
++#define DRV_DESCRIPTION "Nintendo GameCube/Wii Serial Interface (SI) driver"
++#define DRV_AUTHOR "Steven Looman <steven@krx.nl>, " \
++ "Albert Herranz"
++
++static char si_driver_version[] = "1.0i";
++
++#define drv_printk(level, format, arg...) \
++ printk(level DRV_MODULE_NAME ": " format , ## arg)
++
++#define SI_MAX_PORTS 4 /* the four controller ports */
++#define SI_REFRESH_TIME (HZ/100) /* polling interval */
++
++/*
++ * Hardware registers
++ */
++#define SI_PORT_SPACING 12
++
++#define SICOUTBUF(i) (0x00 + (i)*SI_PORT_SPACING)
++#define SICINBUFH(i) (0x04 + (i)*SI_PORT_SPACING)
++#define SICINBUFL(i) (0x08 + (i)*SI_PORT_SPACING)
++#define SIPOLL 0x30
++#define SICOMCSR 0x34
++#define SISR 0x38
++#define SIEXILK 0x3c
++
++#define ID_PAD 0x0900
++#define ID_KEYBOARD 0x0820
++#define ID_WIRELESS_BIT (1 << 15)
++#define ID_WAVEBIRD_BIT (1 << 8)
++
++#define PAD_START (1 << 28)
++#define PAD_Y (1 << 27)
++#define PAD_X (1 << 26)
++#define PAD_B (1 << 25)
++#define PAD_A (1 << 24)
++#define PAD_LT (1 << 22)
++#define PAD_RT (1 << 21)
++#define PAD_Z (1 << 20)
++#define PAD_UP (1 << 19)
++#define PAD_DOWN (1 << 18)
++#define PAD_RIGHT (1 << 17)
++#define PAD_LEFT (1 << 16)
++
++
++struct si_keyboard_status {
++ unsigned char old[3];
++};
++
++enum si_control_type {
++ CTL_PAD,
++ CTL_KEYBOARD,
++ CTL_UNKNOWN
++};
++
++struct si_drvdata;
++
++struct si_port {
++ unsigned int index;
++ struct si_drvdata *drvdata;
++
++ u32 id; /* SI id */
++
++ enum si_control_type type;
++ unsigned int raw[2];
++
++ struct input_dev *idev;
++ struct timer_list timer;
++ char name[32];
++
++ union {
++ struct si_keyboard_status keyboard;
++ };
++
++};
++
++struct si_drvdata {
++ struct si_port ports[SI_MAX_PORTS];
++
++ void __iomem *io_base;
++
++ struct device *dev;
++};
++
++
++#ifdef HACK_FORCE_KEYBOARD_PORT
++
++static int si_force_keyboard_port = -1;
++
++#ifdef MODULE
++module_psi_named(force_keyboard_port, si_force_keyboard_port, int, 0644);
++MODULE_PARM_DESC(force_keyboard_port, "port n becomes a keyboard port if"
++ " automatic identification fails");
++#else
++static int __init si_force_keyboard_port_setup(char *line)
++{
++ if (sscanf(line, "%d", &si_force_keyboard_port) != 1)
++ si_force_keyboard_port = -1;
++ return 1;
++}
++__setup("force_keyboard_port=", si_force_keyboard_port_setup);
++#endif /* MODULE */
++
++#endif /* HACK_FORCE_KEYBOARD_PORT */
++
++
++/*
++ * Hardware.
++ *
++ */
++
++static void si_reset(void __iomem *io_base)
++{
++ int i;
++
++ /* clear all SI registers */
++
++ for (i = 0; i < SI_MAX_PORTS; ++i)
++ out_be32(io_base + SICOUTBUF(i), 0);
++ for (i = 0; i < SI_MAX_PORTS; ++i)
++ out_be32(io_base + SICINBUFH(i), 0);
++ for (i = 0; i < SI_MAX_PORTS; ++i)
++ out_be32(io_base + SICINBUFL(i), 0);
++ out_be32(io_base + SIPOLL, 0);
++ out_be32(io_base + SICOMCSR, 0);
++ out_be32(io_base + SISR, 0);
++
++ /* these too... */
++ out_be32(io_base + 0x80, 0);
++ out_be32(io_base + 0x84, 0);
++ out_be32(io_base + 0x88, 0);
++ out_be32(io_base + 0x8c, 0);
++ out_be32(io_base + 0x90, 0);
++ out_be32(io_base + 0x94, 0);
++ out_be32(io_base + 0x98, 0);
++ out_be32(io_base + 0x9c, 0);
++ out_be32(io_base + 0xa0, 0);
++ out_be32(io_base + 0xa4, 0);
++ out_be32(io_base + 0xa8, 0);
++ out_be32(io_base + 0xac, 0);
++}
++
++static void si_set_rumbling(void __iomem *io_base, unsigned int index,
++ int rumble)
++{
++ out_be32(io_base + SICOUTBUF(index), 0x00400000 | (rumble) ? 1 : 0);
++ out_be32(io_base + SISR, 0x80000000);
++}
++
++static void si_wait_transfer_done(void __iomem *io_base)
++{
++ unsigned long deadline = jiffies + 2*HZ;
++ int borked = 0;
++
++ while (!(in_be32(io_base + SICOMCSR) & (1 << 31)) && !borked) {
++ cpu_relax();
++ borked = time_after(jiffies, deadline);
++ }
++
++ if (borked) {
++ drv_printk(KERN_ERR, "serial transfer took too long, "
++ "is your hardware ok?");
++ }
++
++ out_be32(io_base + SICOMCSR,
++ in_be32(io_base + SICOMCSR) | (1 << 31)); /* ack IRQ */
++}
++
++static u32 si_get_controller_id(void __iomem *io_base,
++ unsigned int index)
++{
++ out_be32(io_base + SICOUTBUF(index), 0);
++ out_be32(io_base + SIPOLL, 0);
++
++ out_be32(io_base + SISR, 0x80000000);
++ out_be32(io_base + SICOMCSR, 0xd0010001 | index << 1);
++ si_wait_transfer_done(io_base);
++
++ return in_be32(io_base + 0x80) >> 16;
++}
++
++static void si_setup_polling(struct si_drvdata *drvdata)
++{
++ void __iomem *io_base = drvdata->io_base;
++ unsigned long pad_bits = 0;
++ int i;
++
++ for (i = 0; i < SI_MAX_PORTS; ++i) {
++ switch (drvdata->ports[i].type) {
++ case CTL_PAD:
++ out_be32(io_base + SICOUTBUF(i), 0x00400300);
++ break;
++ case CTL_KEYBOARD:
++ out_be32(io_base + SICOUTBUF(i), 0x00540000);
++ break;
++ default:
++ continue;
++ }
++ pad_bits |= 1 << (7 - i);
++ }
++ out_be32(io_base + SIPOLL, 0x00f70200 | pad_bits);
++
++ out_be32(io_base + SISR, 0x80000000);
++ out_be32(io_base + SICOMCSR, 0xc0010801);
++ si_wait_transfer_done(io_base);
++}
++
++static void si_timer(unsigned long data)
++{
++ struct si_port *port = (struct si_port *)data;
++ unsigned int index = port->index;
++ void __iomem *io_base = port->drvdata->io_base;
++ unsigned long raw[2];
++ unsigned char key[3];
++ unsigned char oldkey;
++ int i;
++
++ raw[0] = in_be32(io_base + SICINBUFH(index));
++ raw[1] = in_be32(io_base + SICINBUFL(index));
++
++ switch (port->type) {
++ case CTL_PAD:
++ /* buttons */
++ input_report_key(port->idev, BTN_A, raw[0] & PAD_A);
++ input_report_key(port->idev, BTN_B, raw[0] & PAD_B);
++ input_report_key(port->idev, BTN_X, raw[0] & PAD_X);
++ input_report_key(port->idev, BTN_Y, raw[0] & PAD_Y);
++ input_report_key(port->idev, BTN_Z, raw[0] & PAD_Z);
++ input_report_key(port->idev, BTN_TL,
++ raw[0] & PAD_LT);
++ input_report_key(port->idev, BTN_TR,
++ raw[0] & PAD_RT);
++ input_report_key(port->idev, BTN_START,
++ raw[0] & PAD_START);
++ input_report_key(port->idev, BTN_0, raw[0] & PAD_UP);
++ input_report_key(port->idev, BTN_1, raw[0] & PAD_RIGHT);
++ input_report_key(port->idev, BTN_2, raw[0] & PAD_DOWN);
++ input_report_key(port->idev, BTN_3, raw[0] & PAD_LEFT);
++
++ /* axis */
++ /* a stick */
++ input_report_abs(port->idev, ABS_X,
++ raw[0] >> 8 & 0xFF);
++ input_report_abs(port->idev, ABS_Y,
++ 0xFF - (raw[0] >> 0 & 0xFF));
++
++ /* b pad */
++ if (raw[0] & PAD_RIGHT)
++ input_report_abs(port->idev, ABS_HAT0X, 1);
++ else if (raw[0] & PAD_LEFT)
++ input_report_abs(port->idev, ABS_HAT0X, -1);
++ else
++ input_report_abs(port->idev, ABS_HAT0X, 0);
++
++ if (raw[0] & PAD_DOWN)
++ input_report_abs(port->idev, ABS_HAT0Y, 1);
++ else if (raw[0] & PAD_UP)
++ input_report_abs(port->idev, ABS_HAT0Y, -1);
++ else
++ input_report_abs(port->idev, ABS_HAT0Y, 0);
++
++ /* c stick */
++ input_report_abs(port->idev, ABS_RX,
++ raw[1] >> 24 & 0xFF);
++ input_report_abs(port->idev, ABS_RY,
++ raw[1] >> 16 & 0xFF);
++
++ /* triggers */
++ input_report_abs(port->idev, ABS_BRAKE,
++ raw[1] >> 8 & 0xFF);
++ input_report_abs(port->idev, ABS_GAS,
++ raw[1] >> 0 & 0xFF);
++
++ break;
++
++ case CTL_KEYBOARD:
++ /*
++ raw nibbles:
++ [4]<C>[0][0][0][0][0][0] <1H><1L><2H><2L><3H><3L><X><C>
++ where:
++ [n] = fixed to n
++ <nH> <nL> = high / low nibble of n-th key pressed
++ (0 if not pressed)
++ <X> = <1H> xor <2H> xor <3H>
++ <C> = counter: 0, 0, 1, 1, 2, 2, ..., F, F, 0, 0, ...
++ */
++ key[0] = (raw[1] >> 24) & 0xFF;
++ key[1] = (raw[1] >> 16) & 0xFF;
++ key[2] = (raw[1] >> 8) & 0xFF;
++
++ /* check if anything was released */
++ for (i = 0; i < 3; ++i) {
++ oldkey = port->keyboard.old[i];
++ if (oldkey != key[0] &&
++ oldkey != key[1] && oldkey != key[2])
++ input_report_key(port->idev,
++ gamecube_keymap[oldkey], 0);
++ }
++
++ /* report keys */
++ for (i = 0; i < 3; ++i) {
++ if (key[i])
++ input_report_key(port->idev,
++ gamecube_keymap[key[i]], 1);
++ port->keyboard.old[i] = key[i];
++ }
++ break;
++
++ default:
++ break;
++ }
++
++ input_sync(port->idev);
++
++ mod_timer(&port->timer, jiffies + SI_REFRESH_TIME);
++}
++
++/*
++ * Input driver hooks.
++ *
++ */
++
++static int si_open(struct input_dev *idev)
++{
++ struct si_port *port = input_get_drvdata(idev);
++
++ init_timer(&port->timer);
++ port->timer.function = si_timer;
++ port->timer.data = (unsigned long)port;
++ port->timer.expires = jiffies + SI_REFRESH_TIME;
++ add_timer(&port->timer);
++
++ return 0;
++}
++
++static void si_close(struct input_dev *idev)
++{
++ struct si_port *port = input_get_drvdata(idev);
++
++ del_timer(&port->timer);
++}
++
++static int si_event(struct input_dev *idev, unsigned int type,
++ unsigned int code, int value)
++{
++ struct si_port *port = input_get_drvdata(idev);
++ unsigned int index = port->index;
++ void __iomem *io_base = port->drvdata->io_base;
++
++ if (type == EV_FF) {
++ if (code == FF_RUMBLE)
++ si_set_rumbling(io_base, index, value);
++ }
++
++ return value;
++}
++
++static int si_setup_pad(struct input_dev *idev)
++{
++ struct ff_device *ff;
++ int retval;
++
++ set_bit(EV_KEY, idev->evbit);
++ set_bit(EV_ABS, idev->evbit);
++
++ set_bit(BTN_A, idev->keybit);
++ set_bit(BTN_B, idev->keybit);
++ set_bit(BTN_X, idev->keybit);
++ set_bit(BTN_Y, idev->keybit);
++ set_bit(BTN_Z, idev->keybit);
++ set_bit(BTN_TL, idev->keybit);
++ set_bit(BTN_TR, idev->keybit);
++ set_bit(BTN_START, idev->keybit);
++ set_bit(BTN_0, idev->keybit);
++ set_bit(BTN_1, idev->keybit);
++ set_bit(BTN_2, idev->keybit);
++ set_bit(BTN_3, idev->keybit);
++
++ /* a stick */
++ set_bit(ABS_X, idev->absbit);
++ idev->absmin[ABS_X] = 0;
++ idev->absmax[ABS_X] = 255;
++ idev->absfuzz[ABS_X] = 8;
++ idev->absflat[ABS_X] = 8;
++
++ set_bit(ABS_Y, idev->absbit);
++ idev->absmin[ABS_Y] = 0;
++ idev->absmax[ABS_Y] = 255;
++ idev->absfuzz[ABS_Y] = 8;
++ idev->absflat[ABS_Y] = 8;
++
++ /* b pad */
++ input_set_abs_params(idev, ABS_HAT0X, -1, 1, 0, 0);
++ input_set_abs_params(idev, ABS_HAT0Y, -1, 1, 0, 0);
++
++ /* c stick */
++ set_bit(ABS_RX, idev->absbit);
++ idev->absmin[ABS_RX] = 0;
++ idev->absmax[ABS_RX] = 255;
++ idev->absfuzz[ABS_RX] = 8;
++ idev->absflat[ABS_RX] = 8;
++
++ set_bit(ABS_RY, idev->absbit);
++ idev->absmin[ABS_RY] = 0;
++ idev->absmax[ABS_RY] = 255;
++ idev->absfuzz[ABS_RY] = 8;
++ idev->absflat[ABS_RY] = 8;
++
++ /* triggers */
++ set_bit(ABS_GAS, idev->absbit);
++ idev->absmin[ABS_GAS] = -255;
++ idev->absmax[ABS_GAS] = 255;
++ idev->absfuzz[ABS_GAS] = 16;
++ idev->absflat[ABS_GAS] = 16;
++
++ set_bit(ABS_BRAKE, idev->absbit);
++ idev->absmin[ABS_BRAKE] = -255;
++ idev->absmax[ABS_BRAKE] = 255;
++ idev->absfuzz[ABS_BRAKE] = 16;
++ idev->absflat[ABS_BRAKE] = 16;
++
++ /* rumbling */
++ set_bit(EV_FF, idev->evbit);
++ set_bit(FF_RUMBLE, idev->ffbit);
++ retval = input_ff_create(idev, 1);
++ if (retval)
++ return retval;
++ ff = idev->ff;
++ idev->event = si_event;
++ return 0;
++}
++
++static void si_setup_keyboard(struct input_dev *idev)
++{
++ int i;
++
++ set_bit(EV_KEY, idev->evbit);
++ set_bit(EV_REP, idev->evbit);
++
++ for (i = 0; i < 255; ++i)
++ set_bit(gamecube_keymap[i], idev->keybit);
++}
++
++static int si_port_probe(struct si_port *port)
++{
++ unsigned int index = port->index;
++ void __iomem *io_base = port->drvdata->io_base;
++ struct input_dev *idev;
++ int retval = 0;
++
++ si_reset(io_base);
++
++ /*
++ * Determine input device type from SI id.
++ */
++ port->id = si_get_controller_id(io_base, index);
++ if (port->id == ID_PAD) {
++ port->type = CTL_PAD;
++ strcpy(port->name, "standard pad");
++ } else if (port->id & ID_WIRELESS_BIT) {
++ /* wireless pad */
++ port->type = CTL_PAD;
++ strcpy(port->name, (port->id & ID_WAVEBIRD_BIT) ?
++ "Nintendo Wavebird" : "wireless pad");
++ } else if (port->id == ID_KEYBOARD) {
++ port->type = CTL_KEYBOARD;
++ strcpy(port->name, "keyboard");
++ } else {
++ port->type = CTL_UNKNOWN;
++ if (port->id) {
++ sprintf(port->name, "unknown (%x)",
++ port->id);
++#ifdef HACK_FORCE_KEYBOARD_PORT
++ if (index+1 == si_force_keyboard_port) {
++ drv_printk(KERN_WARNING,
++ "port %d forced to keyboard mode\n",
++ index+1);
++ port->id = ID_KEYBOARD;
++ port->type = CTL_KEYBOARD;
++ strcpy(port->name, "keyboard (forced)");
++ }
++#endif /* HACK_FORCE_KEYBOARD_PORT */
++ } else {
++ strcpy(port->name, "not present");
++ }
++ }
++
++ if (port->type == CTL_UNKNOWN) {
++ retval = -ENODEV;
++ goto done;
++ }
++
++ idev = input_allocate_device();
++ if (!idev) {
++ drv_printk(KERN_ERR, "failed to allocate input_dev\n");
++ retval = -ENOMEM;
++ goto done;
++ }
++
++ idev->open = si_open;
++ idev->close = si_close;
++ idev->name = port->name;
++
++ switch (port->type) {
++ case CTL_PAD:
++ retval = si_setup_pad(idev);
++ break;
++ case CTL_KEYBOARD:
++ si_setup_keyboard(idev);
++ break;
++ default:
++ break;
++ }
++
++ if (retval) {
++ input_free_device(idev);
++ goto done;
++ }
++
++ input_set_drvdata(idev, port);
++ port->idev = idev;
++
++done:
++ return retval;
++}
++
++/*
++ * Setup routines.
++ *
++ */
++
++static int si_init(struct si_drvdata *drvdata, struct resource *mem)
++{
++ struct si_port *port;
++ int index;
++ int retval;
++ int error;
++
++ drvdata->io_base = ioremap(mem->start, mem->end - mem->start + 1);
++
++ for (index = 0; index < SI_MAX_PORTS; ++index) {
++ port = &drvdata->ports[index];
++
++ memset(port, 0, sizeof(*port));
++ port->index = index;
++ port->drvdata = drvdata;
++
++ retval = si_port_probe(port);
++ if (!retval) {
++ error = input_register_device(port->idev);
++ if (error) {
++ drv_printk(KERN_ERR,
++ "input device registration failed"
++ " (%d) for port %d", error, index+1);
++ port->idev = NULL;
++ } else
++ drv_printk(KERN_INFO, "port %d: %s\n",
++ index+1, port->name);
++ }
++ }
++
++ si_setup_polling(drvdata);
++
++ return 0;
++}
++
++static void si_exit(struct si_drvdata *drvdata)
++{
++ struct si_port *port;
++ int index;
++
++ for (index = 0; index < SI_MAX_PORTS; ++index) {
++ port = &drvdata->ports[index];
++ if (port->idev)
++ input_unregister_device(port->idev);
++ }
++
++ if (drvdata->io_base) {
++ iounmap(drvdata->io_base);
++ drvdata->io_base = NULL;
++ }
++}
++
++/*
++ * Driver model helper routines.
++ *
++ */
++
++static int si_do_probe(struct device *dev, struct resource *mem)
++{
++ struct si_drvdata *drvdata;
++ int retval;
++
++ drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL);
++ if (!drvdata) {
++ drv_printk(KERN_ERR, "failed to allocate si_drvdata\n");
++ return -ENOMEM;
++ }
++ dev_set_drvdata(dev, drvdata);
++ drvdata->dev = dev;
++
++ retval = si_init(drvdata, mem);
++ if (retval) {
++ dev_set_drvdata(dev, NULL);
++ kfree(drvdata);
++ }
++ return retval;
++}
++
++static int si_do_remove(struct device *dev)
++{
++ struct si_drvdata *drvdata = dev_get_drvdata(dev);
++
++ if (drvdata) {
++ si_exit(drvdata);
++ dev_set_drvdata(dev, NULL);
++ kfree(drvdata);
++ return 0;
++ }
++ return -ENODEV;
++}
++
++
++/*
++ * OF platform driver hooks.
++ *
++ */
++
++static int __init si_of_probe(struct of_device *odev,
++ const struct of_device_id *match)
++{
++ struct resource mem;
++ int retval;
++
++ retval = of_address_to_resource(odev->node, 0, &mem);
++ if (retval) {
++ drv_printk(KERN_ERR, "no io memory range found\n");
++ return -ENODEV;
++ }
++
++ return si_do_probe(&odev->dev, &mem);
++}
++
++static int __exit si_of_remove(struct of_device *odev)
++{
++ return si_do_remove(&odev->dev);
++}
++
++static struct of_device_id si_of_match[] = {
++ { .compatible = "nintendo,flipper-serial" },
++ { .compatible = "nintendo,hollywood-serial" },
++ { },
++};
++
++
++MODULE_DEVICE_TABLE(of, si_of_match);
++
++static struct of_platform_driver si_of_driver = {
++ .owner = THIS_MODULE,
++ .name = DRV_MODULE_NAME,
++ .match_table = si_of_match,
++ .probe = si_of_probe,
++ .remove = si_of_remove,
++};
++
++
++/*
++ * Module interface hooks.
++ *
++ */
++
++static int __init si_init_module(void)
++{
++ drv_printk(KERN_INFO, "%s - version %s\n", DRV_DESCRIPTION,
++ si_driver_version);
++
++ return of_register_platform_driver(&si_of_driver);
++}
++
++static void __exit si_exit_module(void)
++{
++ of_unregister_platform_driver(&si_of_driver);
++}
++
++module_init(si_init_module);
++module_exit(si_exit_module);
++
++MODULE_DESCRIPTION(DRV_DESCRIPTION);
++MODULE_AUTHOR(DRV_AUTHOR);
++MODULE_LICENSE("GPL");
++
+diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
+index fee7304..1b07a82 100644
+--- a/drivers/misc/Kconfig
++++ b/drivers/misc/Kconfig
+@@ -55,6 +55,28 @@ config ATMEL_TCB_CLKSRC_BLOCK
+ TC can be used for other purposes, such as PWM generation and
+ interval timing.
+
++config GAMECUBE_GQR
++ tristate "Nintendo GameCube/Wii Graphic Quantization Registers (GQR)"
++ depends on GAMECUBE_COMMON
++ help
++ This option enables device driver support for the Gekko/Broadway
++ processors' Graphic Quantization Registers.
++ These registers are used with the psql and psqst instructions.
++ The registers will appear in /proc/sys/gqr.
++
++config GAMECUBE_MI
++ tristate "Nintendo GameCube Memory Interface (MI)"
++ depends on GAMECUBE
++ help
++ If you say yes to this option, support will be included for the
++ Memory Interface (MI) of the Nintendo GameCube.
++
++ The MI allows one to setup up to four protected memory regions,
++ catching invalid accesses to them. The MI catches out of bounds
++ memory accesses too.
++
++ If in doubt, say N here.
++
+ config IBM_ASM
+ tristate "Device driver for IBM RSA service processor"
+ depends on X86 && PCI && INPUT && EXPERIMENTAL
+diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
+index 817f7f5..79387aa 100644
+--- a/drivers/misc/Makefile
++++ b/drivers/misc/Makefile
+@@ -33,3 +33,5 @@ obj-$(CONFIG_SGI_XP) += sgi-xp/
+ obj-$(CONFIG_SGI_GRU) += sgi-gru/
+ obj-$(CONFIG_HP_ILO) += hpilo.o
+ obj-$(CONFIG_C2PORT) += c2port/
++obj-$(CONFIG_GAMECUBE_GQR) += gcn-gqr.o
++obj-$(CONFIG_GAMECUBE_MI) += gcn-mi.o
+diff --git a/drivers/misc/gcn-gqr.c b/drivers/misc/gcn-gqr.c
+new file mode 100644
+index 0000000..6648265
+--- /dev/null
++++ b/drivers/misc/gcn-gqr.c
+@@ -0,0 +1,129 @@
++/*
++ * drivers/misc/gcn-gqr.c
++ *
++ * Nintendo GameCube GQR driver
++ * Copyright (C) 2004-2009 The GameCube Linux Team
++ * Copyright (C) 2004 Todd Jeffreys <todd@voidpointer.org>
++ * Copyright (C) 2007,2008,2009 Albert Herranz
++ *
++ * 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/init.h>
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/errno.h>
++#include <linux/fs.h>
++#include <linux/ctype.h>
++#include <linux/sysctl.h>
++#include <linux/types.h>
++#include <linux/uaccess.h>
++
++static u32 gqr_values[8];
++static struct ctl_table_header *gqr_table_header;
++
++#define SPR_GQR0 912
++#define SPR_GQR1 913
++#define SPR_GQR2 914
++#define SPR_GQR3 915
++#define SPR_GQR4 916
++#define SPR_GQR5 917
++#define SPR_GQR6 918
++#define SPR_GQR7 919
++
++#define MFSPR_CASE(i) case (i): (*((u32 *)table->data) = mfspr(SPR_GQR##i))
++#define MTSPR_CASE(i) case (i): mtspr(SPR_GQR##i, *((u32 *)table->data))
++
++static int proc_dogqr(ctl_table *table, int write, struct file *file,
++ void __user *buffer, size_t *lenp, loff_t *ppos)
++{
++ int r;
++
++ if (!write) { /* if they are reading, update the variable */
++ switch (table->data - (void *)gqr_values) {
++ MFSPR_CASE(0); break;
++ MFSPR_CASE(1); break;
++ MFSPR_CASE(2); break;
++ MFSPR_CASE(3); break;
++ MFSPR_CASE(4); break;
++ MFSPR_CASE(5); break;
++ MFSPR_CASE(6); break;
++ MFSPR_CASE(7); break;
++ default:
++ return -EFAULT; /* shouldn't happen */
++ }
++ }
++
++ r = proc_dointvec(table, write, file, buffer, lenp, ppos);
++
++ if ((r == 0) && write) { /* if they are writing, update the reg */
++ switch (table->data - (void *)gqr_values) {
++ MTSPR_CASE(0); break;
++ MTSPR_CASE(1); break;
++ MTSPR_CASE(2); break;
++ MTSPR_CASE(3); break;
++ MTSPR_CASE(4); break;
++ MTSPR_CASE(5); break;
++ MTSPR_CASE(6); break;
++ MTSPR_CASE(7); break;
++ default:
++ return -EFAULT; /* shouldn't happen */
++ }
++ }
++
++ return r;
++}
++
++#define DECLARE_GQR(i) { \
++ .ctl_name = CTL_UNNUMBERED, \
++ .procname = "gqr" #i, \
++ .data = gqr_values + i, \
++ .maxlen = sizeof(int), \
++ .mode = 0644, \
++ .proc_handler = &proc_dogqr \
++ }
++
++static ctl_table gqr_members[] = {
++ DECLARE_GQR(0),
++ DECLARE_GQR(1),
++ DECLARE_GQR(2),
++ DECLARE_GQR(3),
++ DECLARE_GQR(4),
++ DECLARE_GQR(5),
++ DECLARE_GQR(6),
++ DECLARE_GQR(7),
++ { .ctl_name = 0 }
++};
++
++static ctl_table gqr_table[] = {
++ {
++ .ctl_name = CTL_UNNUMBERED,
++ .procname = "gqr",
++ .mode = 0555,
++ .child = gqr_members,
++ },
++ { .ctl_name = 0 }
++};
++
++int __init gcngqr_init(void)
++{
++ gqr_table_header = register_sysctl_table(gqr_table);
++ if (!gqr_table_header) {
++ printk(KERN_ERR "Unable to register GQR sysctl table\n");
++ return -ENOMEM;
++ }
++ return 0;
++}
++
++void __exit gcngqr_exit(void)
++{
++ unregister_sysctl_table(gqr_table_header);
++}
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Todd Jeffreys <todd@voidpointer.org>");
++module_init(gcngqr_init);
++module_exit(gcngqr_exit);
+diff --git a/drivers/misc/gcn-mi.c b/drivers/misc/gcn-mi.c
+new file mode 100644
+index 0000000..864017d
+--- /dev/null
++++ b/drivers/misc/gcn-mi.c
+@@ -0,0 +1,443 @@
++/*
++ * drivers/misc/gcn-mi.c
++ *
++ * Nintendo GameCube Memory Interface (MI) driver.
++ * Copyright (C) 2004-2009 The GameCube Linux Team
++ * Copyright (C) 2004,2005,2007,2008,2009 Albert Herranz
++ *
++ * 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/device.h>
++#include <linux/init.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/ioport.h>
++#include <linux/interrupt.h>
++#include <linux/spinlock.h>
++#include <linux/proc_fs.h>
++#include <linux/io.h>
++
++#include "gcn-mi.h"
++
++
++#define MI_IRQ 7
++
++#define MI_BASE 0xcc004000
++#define MI_SIZE 0x80
++
++#define MI_PROT_REGION0 ((u32 __iomem *)(MI_BASE+0x00))
++#define MI_PROT_REGION1 ((u32 __iomem *)(MI_BASE+0x04))
++#define MI_PROT_REGION2 ((u32 __iomem *)(MI_BASE+0x08))
++#define MI_PROT_REGION3 ((u32 __iomem *)(MI_BASE+0x0c))
++
++#define MI_PROT_TYPE ((u16 __iomem *)(MI_BASE+0x10))
++
++#define MI_IMR ((u16 __iomem *)(MI_BASE+0x1c))
++#define MI_ICR ((u16 __iomem *)(MI_BASE+0x1e))
++
++#define MI_0x4020 ((u16 __iomem *)(MI_BASE+0x20))
++
++#define MI_ADDRLO ((u16 __iomem *)(MI_BASE+0x22))
++#define MI_ADDRHI ((u16 __iomem *)(MI_BASE+0x24))
++
++#define MI_PAGE_SHIFT 10
++#define MI_PAGE_MASK (~((1 << MI_PAGE_SHIFT) - 1))
++#define MI_PAGE_SIZE (1UL << MI_PAGE_SHIFT)
++
++struct mi_private {
++ struct device *device;
++ int irq;
++ int nr_regions;
++ int regions_bitmap;
++ unsigned long faults[MI_MAX_REGIONS+1];
++ unsigned long last_address;
++ unsigned long last_address_faults;
++ spinlock_t lock;
++#ifdef CONFIG_PROC_FS
++ struct proc_dir_entry *proc_file;
++#endif
++};
++
++static struct mi_private *mi_private;
++
++#define DRV_MODULE_NAME "gcn-mi"
++#define DRV_DESCRIPTION "Nintendo GameCube Memory Interface driver"
++#define DRV_AUTHOR "Albert Herranz"
++
++#define PFX DRV_MODULE_NAME ": "
++#define mi_printk(level, format, arg...) \
++ printk(level PFX format , ## arg)
++
++/*
++ *
++ */
++static irqreturn_t mi_handler(int this_irq, void *data)
++{
++ struct mi_private *priv = (struct mi_private *)data;
++ unsigned long flags;
++ int region, cause, ack;
++ unsigned long address;
++
++ spin_lock_irqsave(&priv->lock, flags);
++
++ address = in_be16(MI_ADDRLO) | (in_be16(MI_ADDRHI)<<16);
++
++ ack = 0;
++ cause = in_be16(MI_ICR);
++
++ /* a fault was detected in some of the registered regions */
++ if ((cause & 0xf) != 0) {
++ for (region = 0; region < MI_MAX_REGIONS; region++) {
++ if ((cause & (1 << region)) != 0) {
++ priv->faults[region]++;
++ mi_printk(KERN_INFO, "bad access on region #%d"
++ " at 0x%lx\n", region, address);
++ }
++ }
++ }
++
++ /* a fault was detected out of any registered region */
++ if ((cause & (1 << 4)) != 0) {
++ priv->faults[MI_MAX_REGIONS]++;
++ if (address == priv->last_address) {
++ priv->last_address_faults++;
++ } else {
++ if (priv->last_address_faults > 0) {
++#if 0
++ mi_printk(KERN_INFO, "bad access"
++ " at 0x%lx (%lu times)\n",
++ priv->last_address,
++ priv->last_address_faults);
++#endif
++ }
++ priv->last_address = address;
++ priv->last_address_faults = 1;
++ }
++ }
++ ack |= cause;
++ out_be16(MI_ICR, ack); /* ack int */
++ out_be16(MI_0x4020, 0); /* kind of ack */
++
++ spin_unlock_irqrestore(&priv->lock, flags);
++
++ return IRQ_HANDLED;
++}
++
++#ifdef CONFIG_PROC_FS
++/*
++ *
++ */
++static int mi_proc_read(char *page, char **start,
++ off_t off, int count,
++ int *eof, void *data)
++{
++ struct mi_private *priv = (struct mi_private *)data;
++ int len;
++ int region;
++
++ len = sprintf(page, "# <region> <faults>\n");
++ for (region = 0; region < MI_MAX_REGIONS; region++) {
++ if ((priv->regions_bitmap & (1<<region)) != 0) {
++ len += sprintf(page+len, "%d\t%lu\n",
++ region, priv->faults[region]);
++ }
++ }
++ len += sprintf(page+len, "%s\t%lu\n",
++ "none", priv->faults[MI_MAX_REGIONS]);
++
++ return len;
++}
++
++#endif /* CONFIG_PROC_FS */
++
++/*
++ *
++ */
++static int mi_setup_irq(struct mi_private *priv)
++{
++ int retval;
++
++ retval = request_irq(priv->irq, mi_handler, 0, DRV_MODULE_NAME, priv);
++ if (retval)
++ mi_printk(KERN_ERR, "request of irq%d failed\n", priv->irq);
++ else
++ out_be16(MI_IMR, (1<<4)); /* do not mask all MI interrupts */
++
++ return retval;
++}
++
++/*
++ *
++ */
++static int mi_probe(struct device *device, struct resource *mem, int irq)
++{
++ struct mi_private *priv;
++ int retval;
++
++ priv = kmalloc(sizeof(struct mi_private), GFP_KERNEL);
++ if (!priv) {
++ retval = -ENOMEM;
++ goto err;
++ }
++
++ memset(priv, 0, sizeof(*priv));
++ /*
++ int region;
++ priv->nr_regions = 0;
++ priv->regions_bitmap = 0;
++ for( region = 0; region < MI_MAX_REGIONS; region++ ) {
++ priv->faults[region] = 0;
++ }
++ priv->last_address_faults = 0;
++ */
++ spin_lock_init(&priv->lock);
++
++ priv->device = device;
++ dev_set_drvdata(priv->device, priv);
++
++ priv->irq = irq;
++ retval = mi_setup_irq(priv);
++ if (retval)
++ goto err_setup_irq;
++
++#ifdef CONFIG_PROC_FS
++ struct platform_device *pdev = to_platform_device(device);
++ priv->proc_file = create_proc_read_entry(pdev->dev.bus_id, 0444, NULL,
++ mi_proc_read, priv);
++ priv->proc_file->owner = THIS_MODULE;
++#endif /* CONFIG_PROC_FS */
++
++ mi_private = priv;
++
++ return 0;
++
++err_setup_irq:
++ dev_set_drvdata(priv->device, NULL);
++ kfree(priv);
++err:
++ return retval;
++}
++
++/*
++ *
++ */
++static void mi_shutdown(struct mi_private *priv)
++{
++ gcn_mi_region_unprotect_all();
++}
++
++/*
++ *
++ */
++static void mi_remove(struct mi_private *priv)
++{
++#ifdef CONFIG_PROC_FS
++ struct platform_device *pdev = to_platform_device(priv->device);
++ remove_proc_entry(pdev->dev.bus_id, NULL);
++#endif /* CONFIG_PROC_FS */
++
++ mi_shutdown(priv);
++
++ /* free interrupt handler */
++ free_irq(priv->irq, priv);
++
++ kfree(priv);
++ mi_private = NULL;
++}
++
++/*
++ *
++ */
++static int __init mi_drv_probe(struct device *device)
++{
++ struct platform_device *pdev = to_platform_device(device);
++ struct resource *mem;
++ int irq;
++
++ irq = platform_get_irq(pdev, 0);
++ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ if (!mem)
++ return -ENODEV;
++
++ mi_printk(KERN_INFO, "%s\n", DRV_DESCRIPTION);
++
++ return mi_probe(device, mem, irq);
++}
++
++/*
++ *
++ */
++static int mi_drv_remove(struct device *device)
++{
++ struct mi_private *priv = dev_get_drvdata(device);
++
++ if (priv) {
++ mi_remove(priv);
++ dev_set_drvdata(device, NULL);
++ }
++
++ return 0;
++}
++
++/*
++ *
++ */
++static void mi_drv_shutdown(struct device *device)
++{
++ struct mi_private *priv = dev_get_drvdata(device);
++
++ if (priv)
++ mi_shutdown(priv);
++}
++
++static struct device_driver mi_device_driver = {
++ .name = "mi",
++ .bus = &platform_bus_type,
++ .probe = mi_drv_probe,
++ .remove = mi_drv_remove,
++ .shutdown = mi_drv_shutdown,
++};
++
++static struct resource mi_resources[] = {
++ [0] = {
++ .start = MI_BASE,
++ .end = MI_BASE + MI_SIZE - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = MI_IRQ,
++ .end = MI_IRQ,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static struct platform_device mi_device = {
++ .name = "mi",
++ .id = 0,
++ .num_resources = ARRAY_SIZE(mi_resources),
++ .resource = mi_resources,
++};
++
++/*
++ *
++ */
++static int __init mi_init(void)
++{
++ int retval = 0;
++
++ retval = driver_register(&mi_device_driver);
++ if (!retval)
++ retval = platform_device_register(&mi_device);
++
++ return retval;
++}
++
++/*
++ *
++ */
++static void __exit mi_exit(void)
++{
++ platform_device_unregister(&mi_device);
++ driver_unregister(&mi_device_driver);
++}
++
++module_init(mi_init);
++module_exit(mi_exit);
++
++
++/* public interface */
++
++/*
++ *
++ */
++int gcn_mi_region_protect(unsigned long physlo, unsigned long physhi, int type)
++{
++ struct mi_private *priv = mi_private;
++ int region, free_regions;
++ u16 pagelo, pagehi;
++
++ if (!priv)
++ return -ENODEV;
++
++ if (type < MI_PROT_NONE || type > MI_PROT_RW)
++ return -EINVAL;
++
++ if ((physlo & ~MI_PAGE_MASK) != 0 || (physhi & ~MI_PAGE_MASK) != 0)
++ return -EINVAL;
++
++ free_regions = MI_MAX_REGIONS - priv->nr_regions;
++ if (free_regions <= 0)
++ return -ENOMEM;
++ for (region = 0; region < MI_MAX_REGIONS; region++) {
++ if ((priv->regions_bitmap & (1<<region)) == 0)
++ break;
++ }
++ if (region >= MI_MAX_REGIONS)
++ return -ENOMEM;
++ priv->regions_bitmap |= (1 << region);
++ priv->nr_regions++;
++
++ out_be16(MI_PROT_TYPE,
++ (in_be16(MI_PROT_TYPE) & ~(3 << 2*region))|(type << 2*region));
++ pagelo = physlo >> MI_PAGE_SHIFT;
++ pagehi = (physhi >> MI_PAGE_SHIFT) - 1;
++ out_be32(MI_PROT_REGION0 + 4*region, (pagelo << 16) | pagehi);
++ out_be16(MI_IMR, in_be16(MI_IMR) | (1 << region));
++
++ mi_printk(KERN_INFO, "protected region #%d"
++ " from 0x%0lx to 0x%0lx with 0x%0x\n", region,
++ (unsigned long)(pagelo << MI_PAGE_SHIFT),
++ (unsigned long)(((pagehi+1) << MI_PAGE_SHIFT) - 1),
++ type);
++
++ return region;
++}
++
++/*
++ *
++ */
++int gcn_mi_region_unprotect(int region)
++{
++ struct mi_private *priv = mi_private;
++
++ if (!priv)
++ return -ENODEV;
++
++ if (region < 0 || region > MI_MAX_REGIONS)
++ return -EINVAL;
++
++ out_be16(MI_IMR, in_be16(MI_IMR) & ~(1 << region));
++ out_be32(MI_PROT_REGION0 + 4*region, 0);
++ out_be16(MI_PROT_TYPE,
++ in_be16(MI_PROT_TYPE) | (MI_PROT_RW << 2*region));
++
++ if ((priv->regions_bitmap & (1<<region)) != 0)
++ mi_printk(KERN_INFO, "region #%d unprotected\n", region);
++
++ priv->regions_bitmap &= ~(1 << region);
++ priv->nr_regions--;
++
++ return 0;
++}
++
++/*
++ *
++ */
++void gcn_mi_region_unprotect_all(void)
++{
++ int region;
++
++ out_be16(MI_IMR, 0);
++ for (region = 0; region < MI_MAX_REGIONS; region++)
++ gcn_mi_region_unprotect(region);
++}
++
++MODULE_DESCRIPTION(DRV_DESCRIPTION);
++MODULE_AUTHOR(DRV_AUTHOR);
++MODULE_LICENSE("GPL");
+diff --git a/drivers/misc/gcn-mi.h b/drivers/misc/gcn-mi.h
+new file mode 100644
+index 0000000..201387b
+--- /dev/null
++++ b/drivers/misc/gcn-mi.h
+@@ -0,0 +1,30 @@
++/*
++ * drivers/misc/gcn-mi.h
++ *
++ * Nintendo GameCube Memory Interface driver
++ * Copyright (C) 2004-2009 The GameCube Linux Team
++ * Copyright (C) 2004,2005,2008,2009 Albert Herranz
++ *
++ * 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.
++ *
++ */
++
++#ifndef __GCN_MI_H
++#define __GCN_MI_H
++
++#define MI_MAX_REGIONS 4
++
++#define MI_PROT_NONE 0x00
++#define MI_PROT_RO 0x01
++#define MI_PROT_WO 0x02
++#define MI_PROT_RW 0x03
++
++int gcn_mi_region_protect(unsigned long physlo, unsigned long physhi, int type);
++int gcn_mi_region_unprotect(int region);
++void gcn_mi_region_unprotect_all(void);
++
++#endif /* __GCN_MI_H */
++
+diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
+index 231eeaf..a56c769 100644
+--- a/drivers/net/Kconfig
++++ b/drivers/net/Kconfig
+@@ -270,6 +270,15 @@ config BMAC
+ To compile this driver as a module, choose M here: the module
+ will be called bmac.
+
++config GAMECUBE_BBA
++ tristate "Nintendo GameCube ethernet BroadBand Adapter (BBA)"
++ depends on GAMECUBE_EXI && GAMECUBE
++ help
++ Say Y here to add ethernet support for the Broadband Adapter (BBA).
++
++ To compile this driver as a module, choose M here: the module
++ will be called gcn-bba.
++
+ config ARIADNE
+ tristate "Ariadne support"
+ depends on ZORRO
+diff --git a/drivers/net/Makefile b/drivers/net/Makefile
+index 017383a..79854fa 100644
+--- a/drivers/net/Makefile
++++ b/drivers/net/Makefile
+@@ -226,6 +226,7 @@ obj-$(CONFIG_PASEMI_MAC) += pasemi_mac_driver.o
+ pasemi_mac_driver-objs := pasemi_mac.o pasemi_mac_ethtool.o
+ obj-$(CONFIG_MLX4_CORE) += mlx4/
+ obj-$(CONFIG_ENC28J60) += enc28j60.o
++obj-$(CONFIG_GAMECUBE_BBA) += gcn-bba.o
+
+ obj-$(CONFIG_XTENSA_XT2000_SONIC) += xtsonic.o
+
+diff --git a/drivers/net/gcn-bba.c b/drivers/net/gcn-bba.c
+new file mode 100644
+index 0000000..2f67968
+--- /dev/null
++++ b/drivers/net/gcn-bba.c
+@@ -0,0 +1,1252 @@
++/**
++ * drivers/net/gcn-bba.c
++ *
++ * Nintendo GameCube Broadband Adapter (BBA) driver
++ * Copyright (C) 2004-2009 The GameCube Linux Team
++ * Copyright (C) 2005 Todd Jeffreys
++ * Copyright (C) 2004,2005,2006,2007,2008,2009 Albert Herranz
++ *
++ * Based on previous work by Stefan Esser, Franz Lehner, Costis and tmbinc.
++ *
++ * 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.
++ *
++ */
++
++#define BBA_DEBUG
++
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/types.h>
++#include <linux/fcntl.h>
++#include <linux/string.h>
++#include <linux/interrupt.h>
++#include <linux/ioport.h>
++#include <linux/errno.h>
++#include <linux/init.h>
++#include <linux/delay.h>
++#include <linux/inet.h>
++#include <linux/netdevice.h>
++#include <linux/etherdevice.h>
++#include <linux/skbuff.h>
++#include <linux/spinlock.h>
++#include <linux/kthread.h>
++#include <linux/wait.h>
++#include <linux/io.h>
++#include <linux/exi.h>
++#include <asm/system.h>
++
++
++#define DRV_MODULE_NAME "gcn-bba"
++#define DRV_DESCRIPTION "Nintendo GameCube Broadband Adapter (BBA) driver"
++#define DRV_AUTHOR "Albert Herranz, " \
++ "Todd Jeffreys"
++
++static char bba_driver_version[] = "1.4i";
++
++
++#define bba_printk(level, format, arg...) \
++ printk(level DRV_MODULE_NAME ": " format , ## arg)
++
++#ifdef BBA_DEBUG
++# define DBG(fmt, args...) \
++ printk(KERN_ERR "%s: " fmt, __func__ , ## args)
++#else
++# define DBG(fmt, args...)
++#endif
++
++/*
++ * EXpansion Interface glue for the Broadband Adapter.
++ *
++ */
++#define BBA_EXI_ID 0x04020200
++
++#define BBA_EXI_IRQ_CHANNEL 2 /* INT line uses EXI2INTB */
++#define BBA_EXI_CHANNEL 0 /* rest of lines use EXI0xxx */
++#define BBA_EXI_DEVICE 2 /* chip select, EXI0CSB2 */
++#define BBA_EXI_FREQ 5 /* 32MHz */
++
++#define BBA_CMD_IR_MASKALL 0x00
++#define BBA_CMD_IR_MASKNONE 0xf8
++
++static inline void bba_select(void);
++static inline void bba_deselect(void);
++static inline void bba_write(void *data, size_t len);
++static inline void bba_read(void *data, size_t len);
++
++static void bba_ins(int reg, void *val, int len);
++static void bba_outs(int reg, void *val, int len);
++
++/*
++ * Command Registers I/O.
++ */
++
++static inline void bba_cmd_ins_nosel(int reg, void *val, int len)
++{
++ u16 req;
++ req = reg << 8;
++ bba_write(&req, sizeof(req));
++ bba_read(val, len);
++}
++
++static void bba_cmd_ins(int reg, void *val, int len)
++{
++ bba_select();
++ bba_cmd_ins_nosel(reg, val, len);
++ bba_deselect();
++}
++
++static inline void bba_cmd_outs_nosel(int reg, void *val, int len)
++{
++ u16 req;
++ req = (reg << 8) | 0x4000;
++ bba_write(&req, sizeof(req));
++ bba_write(val, len);
++}
++
++static void bba_cmd_outs(int reg, void *val, int len)
++{
++ bba_select();
++ bba_cmd_outs_nosel(reg, val, len);
++ bba_deselect();
++}
++
++static inline u8 bba_cmd_in8(int reg)
++{
++ u8 val;
++ bba_cmd_ins(reg, &val, sizeof(val));
++ return val;
++}
++
++static u8 bba_cmd_in8_slow(int reg)
++{
++ u8 val;
++ bba_select();
++ bba_cmd_ins_nosel(reg, &val, sizeof(val));
++ udelay(200);
++ bba_deselect();
++ return val;
++}
++
++static inline void bba_cmd_out8(int reg, u8 val)
++{
++ bba_cmd_outs(reg, &val, sizeof(val));
++}
++
++
++/*
++ * Registers I/O.
++ */
++
++static inline u8 bba_in8(int reg)
++{
++ u8 val;
++ bba_ins(reg, &val, sizeof(val));
++ return val;
++}
++
++static inline void bba_out8(int reg, u8 val)
++{
++ bba_outs(reg, &val, sizeof(val));
++}
++
++static inline u16 bba_in16(int reg)
++{
++ u16 val;
++ bba_ins(reg, &val, sizeof(val));
++ return le16_to_cpup(&val);
++}
++
++static inline void bba_out16(int reg, u16 val)
++{
++ cpu_to_le16s(&val);
++ bba_outs(reg, &val, sizeof(val));
++}
++
++#define bba_in12(reg) (bba_in16(reg) & 0x0fff)
++#define bba_out12(reg, val) do { bba_out16(reg, (val)&0x0fff); } while (0)
++
++static inline void bba_ins_nosel(int reg, void *val, int len)
++{
++ u32 req;
++ req = (reg << 8) | 0x80000000;
++ bba_write(&req, sizeof(req));
++ bba_read(val, len);
++}
++
++static void bba_ins(int reg, void *val, int len)
++{
++ bba_select();
++ bba_ins_nosel(reg, val, len);
++ bba_deselect();
++}
++
++static inline void bba_outs_nosel(int reg, void *val, int len)
++{
++ u32 req;
++ req = (reg << 8) | 0xC0000000;
++ bba_write(&req, sizeof(req));
++ bba_write(val, len);
++}
++
++static inline void bba_outs_nosel_continued(void *val, int len)
++{
++ bba_write(val, len);
++}
++
++static void bba_outs(int reg, void *val, int len)
++{
++ bba_select();
++ bba_outs_nosel(reg, val, len);
++ bba_deselect();
++}
++
++
++/*
++ * Macronix mx98728ec supporting bits.
++ *
++ */
++
++#define BBA_NCRA 0x00 /* Network Control Register A, RW */
++#define BBA_NCRA_RESET (1<<0) /* RESET */
++#define BBA_NCRA_ST0 (1<<1) /* ST0, Start transmit command/status */
++#define BBA_NCRA_ST1 (1<<2) /* ST1, " */
++#define BBA_NCRA_SR (1<<3) /* SR, Start Receive */
++
++#define BBA_NCRB 0x01 /* Network Control Register B, RW */
++#define BBA_NCRB_PR (1<<0) /* PR, Promiscuous Mode */
++#define BBA_NCRB_CA (1<<1) /* CA, Capture Effect Mode */
++#define BBA_NCRB_PM (1<<2) /* PM, Pass Multicast */
++#define BBA_NCRB_PB (1<<3) /* PB, Pass Bad Frame */
++#define BBA_NCRB_AB (1<<4) /* AB, Accept Broadcast */
++#define BBA_NCRB_HBD (1<<5) /* HBD, reserved */
++#define BBA_NCRB_RXINTC0 (1<<6) /* RXINTC, Receive Interrupt Counter */
++#define BBA_NCRB_RXINTC1 (1<<7) /* " */
++#define BBA_NCRB_1_PACKET_PER_INT (0<<6) /* 0 0 */
++#define BBA_NCRB_2_PACKETS_PER_INT (1<<6) /* 0 1 */
++#define BBA_NCRB_4_PACKETS_PER_INT (2<<6) /* 1 0 */
++#define BBA_NCRB_8_PACKETS_PER_INT (3<<6) /* 1 1 */
++
++#define BBA_LTPS 0x04 /* Last Transmitted Packet Status, RO */
++#define BBA_LRPS 0x05 /* Last Received Packet Status, RO */
++
++#define BBA_IMR 0x08 /* Interrupt Mask Register, RW, 00h */
++#define BBA_IMR_FRAGIM (1<<0) /* FRAGIM, Fragment Counter Int Mask */
++#define BBA_IMR_RIM (1<<1) /* RIM, Receive Interrupt Mask */
++#define BBA_IMR_TIM (1<<2) /* TIM, Transmit Interrupt Mask */
++#define BBA_IMR_REIM (1<<3) /* REIM, Receive Error Interrupt Mask */
++#define BBA_IMR_TEIM (1<<4) /* TEIM, Transmit Error Interrupt Mask */
++#define BBA_IMR_FIFOEIM (1<<5) /* FIFOEIM, FIFO Error Interrupt Mask */
++#define BBA_IMR_BUSEIM (1<<6) /* BUSEIM, BUS Error Interrupt Mask */
++#define BBA_IMR_RBFIM (1<<7) /* RBFIM, RX Buf Full Interrupt Mask */
++
++#define BBA_IR 0x09 /* Interrupt Register, RW, 00h */
++#define BBA_IR_FRAGI (1<<0) /* FRAGI, Fragment Counter Interrupt */
++#define BBA_IR_RI (1<<1) /* RI, Receive Interrupt */
++#define BBA_IR_TI (1<<2) /* TI, Transmit Interrupt */
++#define BBA_IR_REI (1<<3) /* REI, Receive Error Interrupt */
++#define BBA_IR_TEI (1<<4) /* TEI, Transmit Error Interrupt */
++#define BBA_IR_FIFOEI (1<<5) /* FIFOEI, FIFO Error Interrupt */
++#define BBA_IR_BUSEI (1<<6) /* BUSEI, BUS Error Interrupt */
++#define BBA_IR_RBFI (1<<7) /* RBFI, RX Buffer Full Interrupt */
++
++#define BBA_BP 0x0a/*+0x0b*/ /* Boundary Page Pointer Register */
++#define BBA_TLBP 0x0c/*+0x0d*/ /* TX Low Boundary Page Pointer Register */
++#define BBA_TWP 0x0e/*+0x0f*/ /* Transmit Buf Write Page Pointer Register */
++#define BBA_TRP 0x12/*+0x13*/ /* Transmit Buf Read Page Pointer Register */
++#define BBA_RWP 0x16/*+0x17*/ /* Receive Buffer Write Page Pointer Register */
++#define BBA_RRP 0x18/*+0x19*/ /* Receive Buffer Read Page Pointer Register */
++#define BBA_RHBP 0x1a/*+0x1b*/ /* Receive High Boundary Page Ptr Register */
++
++#define BBA_RXINTT 0x14/*+0x15*/ /* Receive Interrupt Timer Register */
++
++#define BBA_NAFR_PAR0 0x20 /* Physical Address Register Byte 0 */
++#define BBA_NAFR_PAR1 0x21 /* Physical Address Register Byte 1 */
++#define BBA_NAFR_PAR2 0x22 /* Physical Address Register Byte 2 */
++#define BBA_NAFR_PAR3 0x23 /* Physical Address Register Byte 3 */
++#define BBA_NAFR_PAR4 0x24 /* Physical Address Register Byte 4 */
++#define BBA_NAFR_PAR5 0x25 /* Physical Address Register Byte 5 */
++
++#define BBA_NWAYC 0x30 /* NWAY Configuration Register, RW, 84h */
++#define BBA_NWAYC_FD (1<<0) /* FD, Full Duplex Mode */
++#define BBA_NWAYC_PS100 (1<<1) /* PS100/10, Port Select 100/10 */
++#define BBA_NWAYC_ANE (1<<2) /* ANE, Autonegotiation Enable */
++#define BBA_NWAYC_ANS_RA (0x01<<3) /* ANS, Restart Autonegotiation */
++#define BBA_NWAYC_LTE (1<<7) /* LTE, Link Test Enable */
++
++#define BBA_GCA 0x32 /* GMAC Configuration A Register, RW, 00h */
++#define BBA_GCA_ARXERRB (1<<3) /* ARXERRB, Accept RX pkt with error */
++
++#define BBA_MISC 0x3d /* MISC Control Register 1, RW, 3ch */
++#define BBA_MISC_BURSTDMA (1<<0)
++#define BBA_MISC_DISLDMA (1<<1)
++
++#define BBA_TXFIFOCNT 0x3e/*0x3f*/ /* Transmit FIFO Counter Register */
++#define BBA_WRTXFIFOD 0x48/*-0x4b*/ /* Write TX FIFO Data Port Register */
++
++#define BBA_MISC2 0x50 /* MISC Control Register 2, RW, 00h */
++#define BBA_MISC2_HBRLEN0 (1<<0) /* HBRLEN, Host Burst Read Length */
++#define BBA_MISC2_HBRLEN1 (1<<1) /* " */
++#define BBA_MISC2_AUTORCVR (1<<7) /* Auto RX Full Recovery */
++
++#define BBA_RX_STATUS_BF (1<<0)
++#define BBA_RX_STATUS_CRC (1<<1)
++#define BBA_RX_STATUS_FAE (1<<2)
++#define BBA_RX_STATUS_FO (1<<3)
++#define BBA_RX_STATUS_RW (1<<4)
++#define BBA_RX_STATUS_MF (1<<5)
++#define BBA_RX_STATUS_RF (1<<6)
++#define BBA_RX_STATUS_RERR (1<<7)
++
++#define BBA_TX_STATUS_CC0 (1<<0)
++#define BBA_TX_STATUS_CC1 (1<<1)
++#define BBA_TX_STATUS_CC2 (1<<2)
++#define BBA_TX_STATUS_CC3 (1<<3)
++#define BBA_TX_STATUS_CCMASK (0x0f)
++#define BBA_TX_STATUS_CRSLOST (1<<4)
++#define BBA_TX_STATUS_UF (1<<5)
++#define BBA_TX_STATUS_OWC (1<<6)
++#define BBA_TX_STATUS_OWN (1<<7)
++#define BBA_TX_STATUS_TERR (1<<7)
++
++#define BBA_TX_MAX_PACKET_SIZE 1518 /* 14+1500+4 */
++#define BBA_RX_MAX_PACKET_SIZE 1536 /* 6 pages * 256 bytes */
++
++
++/**
++ *
++ * DRIVER NOTES
++ *
++ * 1. Packet Memory organization
++ *
++ * rx: 15 pages of 256 bytes, 2 full sized packets only (6 pages each)
++ * tx: through FIFO, not using packet memory
++ *
++ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
++ * |1|2|3|4|5|6|7|8|9|A|B|C|D|E|F|
++ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
++ * ^ ^
++ * | |
++ * TLBP RHBP
++ * BP
++ *
++ */
++
++#define BBA_INIT_TLBP 0x00
++#define BBA_INIT_BP 0x01
++#define BBA_INIT_RHBP 0x0f
++#define BBA_INIT_RWP BBA_INIT_BP
++#define BBA_INIT_RRP BBA_INIT_BP
++
++enum {
++ __BBA_RBFIM_OFF = 0,
++};
++
++struct bba_descr {
++#if defined(__BIG_ENDIAN_BITFIELD)
++ __u32 status:8,
++ packet_len : 12,
++ next_packet_ptr : 12;
++#else
++ __u32 next_packet_ptr:12,
++ packet_len : 12,
++ status : 8;
++#endif
++} __attribute((packed));
++
++
++struct bba_private {
++ spinlock_t lock;
++ unsigned long flags;
++#define BBA_RBFIM_OFF (1<<__BBA_RBFIM_OFF)
++
++ u32 msg_enable;
++ u8 revid;
++ u8 __0x04_init[2];
++ u8 __0x05_init;
++
++ struct sk_buff *tx_skb;
++ int rx_work;
++
++ struct task_struct *io_thread;
++ wait_queue_head_t io_waitq;
++
++ struct net_device *dev;
++ struct net_device_stats stats;
++
++ struct exi_device *exi_device;
++};
++
++static int bba_event_handler(struct exi_channel *exi_channel,
++ unsigned int event, void *dev0);
++static int bba_setup_hardware(struct net_device *dev);
++
++/*
++ * Opens the network device.
++ */
++static int bba_open(struct net_device *dev)
++{
++ struct bba_private *priv = (struct bba_private *)dev->priv;
++ int retval;
++
++ /* INTs are triggered on EXI channel 2 */
++ retval = exi_event_register(to_exi_channel(BBA_EXI_IRQ_CHANNEL),
++ EXI_EVENT_IRQ,
++ priv->exi_device,
++ bba_event_handler, dev,
++ (1 << BBA_EXI_CHANNEL));
++ if (retval < 0) {
++ bba_printk(KERN_ERR, "unable to register EXI event %d\n",
++ EXI_EVENT_IRQ);
++ goto out;
++ }
++
++ /* reset the hardware to a known state */
++ exi_dev_take(priv->exi_device);
++ retval = bba_setup_hardware(dev);
++ exi_dev_give(priv->exi_device);
++
++ /* inform the network layer that we are ready */
++ netif_start_queue(dev);
++out:
++ return retval;
++}
++
++/*
++ * Closes the network device.
++ */
++static int bba_close(struct net_device *dev)
++{
++ struct bba_private *priv = (struct bba_private *)dev->priv;
++
++ /* do not allow more packets to be queued */
++ netif_carrier_off(dev);
++ netif_stop_queue(dev);
++
++ exi_dev_take(priv->exi_device);
++
++ /* stop receiver */
++ bba_out8(BBA_NCRA, bba_in8(BBA_NCRA) & ~BBA_NCRA_SR);
++
++ /* mask all interrupts */
++ bba_out8(BBA_IMR, 0x00);
++
++ exi_dev_give(priv->exi_device);
++
++ /* unregister exi event */
++ exi_event_unregister(to_exi_channel(BBA_EXI_IRQ_CHANNEL),
++ EXI_EVENT_IRQ);
++
++ return 0;
++}
++
++/*
++ * Returns the network device statistics.
++ */
++static struct net_device_stats *bba_get_stats(struct net_device *dev)
++{
++ struct bba_private *priv = (struct bba_private *)dev->priv;
++
++ return &priv->stats;
++}
++
++/*
++ * Starts transmission for a packet.
++ * We can't do real hardware i/o here.
++ */
++static int bba_start_xmit(struct sk_buff *skb, struct net_device *dev)
++{
++ struct bba_private *priv = (struct bba_private *)dev->priv;
++ unsigned long flags;
++ int retval = NETDEV_TX_OK;
++
++ /* we are not able to send packets greater than this */
++ if (skb->len > BBA_TX_MAX_PACKET_SIZE) {
++ dev_kfree_skb(skb);
++ priv->stats.tx_dropped++;
++ /* silently drop the package */
++ goto out;
++ }
++
++ spin_lock_irqsave(&priv->lock, flags);
++
++ /*
++ * If there's no packet pending, store the packet for transmission
++ * and wake up the io thread. Otherwise, we are busy.
++ */
++ if (!priv->tx_skb) {
++ priv->tx_skb = skb;
++ dev->trans_start = jiffies;
++ wake_up(&priv->io_waitq);
++ } else {
++ retval = NETDEV_TX_BUSY;
++ }
++
++ /* we can only send one packet at a time through the FIFO */
++ netif_stop_queue(dev);
++
++ spin_unlock_irqrestore(&priv->lock, flags);
++
++out:
++ return retval;
++}
++
++/*
++ * Updates transmission error statistics.
++ * Caller holds the device lock.
++ */
++static int bba_tx_err(u8 status, struct net_device *dev)
++{
++ struct bba_private *priv = (struct bba_private *)dev->priv;
++ int last_tx_errors = priv->stats.tx_errors;
++
++ if (status & BBA_TX_STATUS_TERR) {
++ if (status & BBA_TX_STATUS_CCMASK) {
++ priv->stats.collisions +=
++ (status & BBA_TX_STATUS_CCMASK);
++ priv->stats.tx_errors++;
++ }
++ if (status & BBA_TX_STATUS_CRSLOST) {
++ priv->stats.tx_carrier_errors++;
++ priv->stats.tx_errors++;
++ }
++ if (status & BBA_TX_STATUS_UF) {
++ priv->stats.tx_fifo_errors++;
++ priv->stats.tx_errors++;
++ }
++ if (status & BBA_TX_STATUS_OWC) {
++ priv->stats.tx_window_errors++;
++ priv->stats.tx_errors++;
++ }
++ }
++
++ if (last_tx_errors != priv->stats.tx_errors) {
++ if (netif_msg_tx_err(priv)) {
++ bba_printk(KERN_DEBUG, "tx errors, status %8.8x.\n",
++ status);
++ }
++ }
++ return priv->stats.tx_errors;
++}
++
++/*
++ * Transmits a packet already stored in the driver's internal tx slot.
++ */
++static int bba_tx(struct net_device *dev)
++{
++ struct bba_private *priv = (struct bba_private *)dev->priv;
++ struct sk_buff *skb;
++ unsigned long flags;
++ int retval = NETDEV_TX_OK;
++
++ static u8 pad[ETH_ZLEN] __attribute__ ((aligned(EXI_DMA_ALIGN+1)));
++ int pad_len;
++
++ exi_dev_take(priv->exi_device);
++
++ /* if the TXFIFO is in use, we'll try it later when free */
++ if (bba_in8(BBA_NCRA) & (BBA_NCRA_ST0 | BBA_NCRA_ST1)) {
++ retval = NETDEV_TX_BUSY;
++ goto out;
++ }
++
++ spin_lock_irqsave(&priv->lock, flags);
++ skb = priv->tx_skb;
++ priv->tx_skb = NULL;
++ spin_unlock_irqrestore(&priv->lock, flags);
++
++ /* tell the card about the length of this packet */
++ bba_out12(BBA_TXFIFOCNT, skb->len);
++
++ /*
++ * Store the packet in the TXFIFO, including padding if needed.
++ * Packet transmission tries to make use of DMA transfers.
++ */
++
++ bba_select();
++ bba_outs_nosel(BBA_WRTXFIFOD, skb->data, skb->len);
++ if (skb->len < ETH_ZLEN) {
++ pad_len = ETH_ZLEN - skb->len;
++ memset(pad, 0, pad_len);
++ bba_outs_nosel_continued(pad, pad_len);
++ }
++ bba_deselect();
++
++ /* tell the card to send the packet right now */
++ bba_out8(BBA_NCRA, (bba_in8(BBA_NCRA) | BBA_NCRA_ST1) & ~BBA_NCRA_ST0);
++
++ /* update statistics */
++ priv->stats.tx_bytes += skb->len;
++ priv->stats.tx_packets++;
++
++ /* free this packet and remove it from our transmission "queue" */
++ dev_kfree_skb(skb);
++
++out:
++ exi_dev_give(priv->exi_device);
++
++ return retval;
++}
++
++/*
++ * Updates reception error statistics.
++ * Caller has already taken the exi channel.
++ */
++static int bba_rx_err(u8 status, struct net_device *dev)
++{
++ struct bba_private *priv = (struct bba_private *)dev->priv;
++ int last_rx_errors = priv->stats.rx_errors;
++
++ if (status == 0xff) {
++ priv->stats.rx_over_errors++;
++ priv->stats.rx_errors++;
++ } else {
++ if (status & BBA_RX_STATUS_RERR) {
++ if (status & BBA_RX_STATUS_CRC) {
++ priv->stats.rx_crc_errors++;
++ priv->stats.rx_errors++;
++ }
++ if (status & BBA_RX_STATUS_FO) {
++ priv->stats.rx_fifo_errors++;
++ priv->stats.rx_errors++;
++ }
++ if (status & BBA_RX_STATUS_RW) {
++ priv->stats.rx_length_errors++;
++ priv->stats.rx_errors++;
++ }
++ if (status & BBA_RX_STATUS_BF) {
++ priv->stats.rx_over_errors++;
++ priv->stats.rx_errors++;
++ }
++ if (status & BBA_RX_STATUS_RF) {
++ priv->stats.rx_length_errors++;
++ priv->stats.rx_errors++;
++ }
++ }
++ if (status & BBA_RX_STATUS_FAE) {
++ priv->stats.rx_frame_errors++;
++ priv->stats.rx_errors++;
++ }
++ }
++
++ if (last_rx_errors != priv->stats.rx_errors) {
++ if (netif_msg_rx_err(priv)) {
++ bba_printk(KERN_DEBUG, "rx errors, status %8.8x.\n",
++ status);
++ }
++ }
++ return priv->stats.rx_errors;
++}
++
++/*
++ * Reception function. Receives up to @budget packets.
++ */
++static int bba_rx(struct net_device *dev, int budget)
++{
++ struct bba_private *priv = (struct bba_private *)dev->priv;
++ struct sk_buff *skb;
++ struct bba_descr descr;
++ int lrps, size;
++ unsigned long pos, top;
++ unsigned short rrp, rwp;
++ int received = 0;
++
++ exi_dev_take(priv->exi_device);
++
++ /* get current receiver pointers */
++ rwp = bba_in12(BBA_RWP);
++ rrp = bba_in12(BBA_RRP);
++
++ while (netif_running(dev) && received < budget && rrp != rwp) {
++ bba_ins(rrp << 8, &descr, sizeof(descr));
++ le32_to_cpus((u32 *) &descr);
++
++ size = descr.packet_len - 4; /* ignore CRC */
++ lrps = descr.status;
++
++ /* abort processing in case of errors */
++ if (size > BBA_RX_MAX_PACKET_SIZE + 4) {
++ DBG("packet too big %d", size);
++ continue;
++ }
++
++ if ((lrps & (BBA_RX_STATUS_RERR | BBA_RX_STATUS_FAE))) {
++ DBG("error %x on received packet\n", lrps);
++ bba_rx_err(lrps, dev);
++ rwp = bba_in12(BBA_RWP);
++ rrp = bba_in12(BBA_RRP);
++ continue;
++ }
++
++ /* allocate a buffer, omitting the CRC (4 bytes) */
++ skb = dev_alloc_skb(size + NET_IP_ALIGN);
++ if (!skb) {
++ priv->stats.rx_dropped++;
++ continue;
++ }
++ skb->dev = dev;
++ skb_reserve(skb, NET_IP_ALIGN); /* align */
++ skb_put(skb, size);
++
++ pos = (rrp << 8) + 4; /* skip descriptor */
++ top = (BBA_INIT_RHBP + 1) << 8;
++
++ if ((pos + size) < top) {
++ /* full packet in one chunk */
++ bba_ins(pos, skb->data, size);
++ } else {
++ /* packet wrapped */
++ int chunk_size = top - pos;
++
++ bba_ins(pos, skb->data, chunk_size);
++ rrp = BBA_INIT_RRP;
++ bba_ins(rrp << 8, skb->data + chunk_size,
++ size - chunk_size);
++ }
++
++ skb->protocol = eth_type_trans(skb, dev);
++
++ dev->last_rx = jiffies;
++ priv->stats.rx_bytes += size;
++ priv->stats.rx_packets++;
++
++ netif_rx(skb);
++ received++;
++
++ /* move read pointer to next packet */
++ bba_out12(BBA_RRP, rrp = descr.next_packet_ptr);
++
++ /* get write pointer and continue */
++ rwp = bba_in12(BBA_RWP);
++ }
++
++ /* there are no more packets pending if we didn't exhaust our budget */
++ if (received < budget)
++ priv->rx_work = 0;
++
++ /* re-enable RBFI if it was disabled before */
++ if (test_and_clear_bit(__BBA_RBFIM_OFF, &priv->flags))
++ bba_out8(BBA_IMR, bba_in8(BBA_IMR) | BBA_IMR_RBFIM);
++
++ exi_dev_give(priv->exi_device);
++
++ return received;
++}
++
++/*
++ * Input/Output thread. Sends and receives packets.
++ */
++static int bba_io_thread(void *bba_priv)
++{
++ struct bba_private *priv = bba_priv;
++/* struct task_struct *me = current; */
++/* struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 }; */
++
++/* sched_setscheduler(me, SCHED_FIFO, &param); */
++
++ set_user_nice(current, -20);
++ current->flags |= PF_NOFREEZE;
++ set_current_state(TASK_RUNNING);
++
++ /*
++ * XXX We currently do not freeze this thread.
++ * The bba is often used to access the root filesystem.
++ */
++
++ while (!kthread_should_stop()) {
++ /*
++ * We want to get scheduled at least once every 2 minutes
++ * to avoid a softlockup spurious message...
++ * "INFO: task kbbaiod blocked for more than 120 seconds."
++ */
++ wait_event_timeout(priv->io_waitq,
++ priv->rx_work || priv->tx_skb, 90*HZ);
++ while (priv->rx_work || priv->tx_skb) {
++ if (priv->rx_work)
++ bba_rx(priv->dev, 0x0f);
++ if (priv->tx_skb)
++ bba_tx(priv->dev);
++ }
++ }
++ return 0;
++}
++
++/*
++ * Handles interrupt work from the network device.
++ * Caller has already taken the exi channel.
++ */
++static void bba_interrupt(struct net_device *dev)
++{
++ struct bba_private *priv = (struct bba_private *)dev->priv;
++ u8 ir, imr, status, lrps, ltps;
++ int loops = 0;
++
++ ir = bba_in8(BBA_IR);
++ imr = bba_in8(BBA_IMR);
++ status = ir & imr;
++
++ /* close possible races with dev_close */
++ if (unlikely(!netif_running(dev))) {
++ bba_out8(BBA_IR, status);
++ bba_out8(BBA_IMR, 0x00);
++ goto out;
++ }
++
++ while (status) {
++ bba_out8(BBA_IR, status);
++
++ /* avoid multiple receive buffer full interrupts */
++ if (status & BBA_IR_RBFI) {
++ bba_out8(BBA_IMR, bba_in8(BBA_IMR) & ~BBA_IMR_RBFIM);
++ set_bit(__BBA_RBFIM_OFF, &priv->flags);
++ }
++
++ if ((status & (BBA_IR_RI | BBA_IR_RBFI))) {
++ priv->rx_work = 1;
++ wake_up(&priv->io_waitq);
++ }
++ if ((status & (BBA_IR_TI|BBA_IR_FIFOEI))) {
++ /* allow more packets to be sent */
++ netif_wake_queue(dev);
++ }
++
++ if ((status & (BBA_IR_RBFI|BBA_IR_REI))) {
++ lrps = bba_in8(BBA_LRPS);
++ bba_rx_err(lrps, dev);
++ }
++ if (status & BBA_IR_TEI) {
++ ltps = bba_in8(BBA_LTPS);
++ bba_tx_err(ltps, dev);
++ }
++
++ if (status & BBA_IR_FIFOEI)
++ DBG("FIFOEI\n");
++ if (status & BBA_IR_BUSEI)
++ DBG("BUSEI\n");
++ if (status & BBA_IR_FRAGI)
++ DBG("FRAGI\n");
++
++ ir = bba_in8(BBA_IR);
++ imr = bba_in8(BBA_IMR);
++ status = ir & imr;
++
++ loops++;
++ }
++
++ if (loops > 3)
++ DBG("a lot of interrupt work (%d loops)\n", loops);
++
++ /* wake up xmit queue in case transmitter is idle */
++ if ((bba_in8(BBA_NCRA) & (BBA_NCRA_ST0 | BBA_NCRA_ST1)) == 0)
++ netif_wake_queue(dev);
++
++out:
++ return;
++}
++
++/*
++ * Retrieves the MAC address of the adapter.
++ * Caller has already taken the exi channel.
++ */
++static void bba_retrieve_ether_addr(struct net_device *dev)
++{
++ bba_ins(BBA_NAFR_PAR0, dev->dev_addr, ETH_ALEN);
++ if (!is_valid_ether_addr(dev->dev_addr))
++ random_ether_addr(dev->dev_addr);
++}
++
++/*
++ * Resets the hardware to a known state.
++ * Caller has already taken the exi channel.
++ */
++static void bba_reset_hardware(struct net_device *dev)
++{
++ struct bba_private *priv = (struct bba_private *)dev->priv;
++
++ /* unknown, mx register 0x60 */
++ bba_out8(0x60, 0);
++ udelay(1000);
++
++ /* unknown, command register 0x0f */
++ bba_cmd_in8_slow(0x0f);
++ udelay(1000);
++
++ /* software reset (write 1 then write 0) */
++ bba_out8(BBA_NCRA, BBA_NCRA_RESET);
++ udelay(100);
++ bba_out8(BBA_NCRA, 0);
++
++ /* unknown, command register 0x01 */
++ /* XXX obtain bits needed for challenge/response calculation later */
++ priv->revid = bba_cmd_in8(0x01);
++
++ /* unknown, command registers 0x04, 0x05 */
++ bba_cmd_outs(0x04, priv->__0x04_init, 2);
++ bba_cmd_out8(0x05, priv->__0x05_init);
++
++ /*
++ * These initializations seem to limit the final port speed to 10Mbps
++ * half duplex. Bypassing them, allows one to set other port speeds.
++ * But, remember that the bba spi-like bus clock operates at 32MHz.
++ * ---Albert Herranz
++ */
++
++ /* unknown, mx registers 0x5b, 0x5c, 0x5e */
++ bba_out8(0x5b, bba_in8(0x5b) & ~(1 << 7));
++ bba_out8(0x5e, 1); /* without this the BBA goes at half the speed */
++ bba_out8(0x5c, bba_in8(0x5c) | 4);
++ udelay(1000);
++
++ /* accept broadcast, assert int for every packet received */
++ bba_out8(BBA_NCRB, BBA_NCRB_AB | BBA_NCRB_1_PACKET_PER_INT);
++
++ /* setup receive interrupt time out, in 40ns units */
++ bba_out8(BBA_RXINTT, 0x00);
++ bba_out8(BBA_RXINTT+1, 0x06); /* 0x0600 = 61us */
++
++ /* auto RX full recovery */
++ bba_out8(BBA_MISC2, BBA_MISC2_AUTORCVR);
++
++ /* initialize packet memory layout */
++ bba_out12(BBA_TLBP, BBA_INIT_TLBP);
++ bba_out12(BBA_BP, BBA_INIT_BP);
++ bba_out12(BBA_RHBP, BBA_INIT_RHBP);
++
++ /* set receive page pointers */
++ bba_out12(BBA_RWP, BBA_INIT_RWP);
++ bba_out12(BBA_RRP, BBA_INIT_RRP);
++
++ /* packet memory won't contain packets with RW, FO, CRC errors */
++ bba_out8(BBA_GCA, BBA_GCA_ARXERRB);
++}
++
++/*
++ * Prepares the hardware for operation.
++ * Caller has already taken the exi channel.
++ */
++static int bba_setup_hardware(struct net_device *dev)
++{
++ /* reset hardware to a sane state */
++ bba_reset_hardware(dev);
++
++ /* start receiver */
++ bba_out8(BBA_NCRA, BBA_NCRA_SR);
++
++ /* clear all interrupts */
++ bba_out8(BBA_IR, 0xFF);
++
++ /* enable all interrupts */
++ bba_out8(BBA_IMR, 0xFF & ~(BBA_IMR_FIFOEIM /*| BBA_IMR_REIM*/));
++
++ /* unknown, short command registers 0x02 */
++ /* XXX enable interrupts on the EXI glue logic */
++ bba_cmd_out8(0x02, BBA_CMD_IR_MASKNONE);
++
++ /* DO NOT clear interrupts on the EXI glue logic !!! */
++ /* we need that initial interrupts for the challenge/response */
++
++ return 0; /* OK */
++}
++
++/*
++ * Calculates a response for a given challenge.
++ */
++static unsigned long bba_calc_response(unsigned long val,
++ struct bba_private *priv)
++{
++ u8 revid_0, revid_eth_0, revid_eth_1;
++ revid_0 = priv->revid;
++ revid_eth_0 = priv->__0x04_init[0];
++ revid_eth_1 = priv->__0x04_init[1];
++
++ u8 i0, i1, i2, i3;
++ i0 = val >> 24;
++ i1 = val >> 16;
++ i2 = val >> 8;
++ i3 = val;
++
++ u8 c0, c1, c2, c3;
++ c0 = (i0 + i1 * 0xc1 + 0x18 + revid_0) ^ (i3 * i2 + 0x90);
++ c1 = (i1 + i2 + 0x90) ^ (c0 + i0 - 0xc1);
++ c2 = (i2 + 0xc8) ^ (c0 + ((revid_eth_0 + revid_0 * 0x23) ^ 0x19));
++ c3 = (i0 + 0xc1) ^ (i3 + ((revid_eth_1 + 0xc8) ^ 0x90));
++
++ return (c0 << 24) | (c1 << 16) | (c2 << 8) | c3;
++}
++
++/*
++ * Handles IRQ events from the exi layer.
++ *
++ * We are called from softirq context, and with the exi channel kindly taken
++ * for us. We can also safely do exi transfers of less than 32 bytes, which
++ * are guaranteed to not sleep by the exi layer.
++ */
++static int bba_event_handler(struct exi_channel *exi_channel,
++ unsigned int event, void *dev0)
++{
++ struct net_device *dev = (struct net_device *)dev0;
++ struct bba_private *priv = (struct bba_private *)dev->priv;
++ register u8 status, mask;
++
++ /* XXX mask all EXI glue interrupts */
++ bba_cmd_out8(0x02, BBA_CMD_IR_MASKALL);
++
++ /* get interrupt status from EXI glue */
++ status = bba_cmd_in8(0x03);
++
++ /* start with the usual case */
++ mask = (1<<7);
++
++ /* normal interrupt from the macronix chip */
++ if (status & mask) {
++ /* call our interrupt handler */
++ bba_interrupt(dev);
++ goto out;
++ }
++
++ /* "killing" interrupt, try to not get one of these! */
++ mask >>= 1;
++ if (status & mask) {
++ DBG("bba: killing interrupt!\n");
++ /* reset the adapter so that we can continue working */
++ bba_setup_hardware(dev);
++ goto out;
++ }
++
++ /* command error interrupt, haven't seen one yet */
++ mask >>= 1;
++ if (status & mask)
++ goto out;
++
++ /* challenge/response interrupt */
++ mask >>= 1;
++ if (status & mask) {
++ unsigned long response;
++ unsigned long challenge;
++
++ /* kids, don't do it without an adult present */
++ bba_cmd_out8(0x05, priv->__0x05_init);
++ bba_cmd_ins(0x08, &challenge, sizeof(challenge));
++ response = bba_calc_response(challenge, priv);
++ bba_cmd_outs(0x09, &response, sizeof(response));
++
++ goto out;
++ }
++
++ /* challenge/response status interrupt */
++ mask >>= 1;
++ if (status & mask) {
++ /* better get a "1" here ... */
++ u8 result = bba_cmd_in8(0x0b);
++ if (result != 1) {
++ bba_printk(KERN_DEBUG,
++ "challenge failed! (result=%d)\n", result);
++ }
++ goto out;
++ }
++
++ /* should not happen, treat as normal interrupt in any case */
++ DBG("bba: unknown interrupt type = %d\n", status);
++
++out:
++ /* assert interrupt */
++ bba_cmd_out8(0x03, mask);
++
++ /* enable interrupts again */
++ bba_cmd_out8(0x02, BBA_CMD_IR_MASKNONE);
++
++ return 1;
++}
++
++static struct net_device *bba_dev;
++
++static inline void bba_select(void)
++{
++ struct bba_private *priv = (struct bba_private *)bba_dev->priv;
++ exi_dev_select(priv->exi_device);
++
++}
++
++static inline void bba_deselect(void)
++{
++ struct bba_private *priv = (struct bba_private *)bba_dev->priv;
++ exi_dev_deselect(priv->exi_device);
++}
++
++static inline void bba_read(void *data, size_t len)
++{
++ struct bba_private *priv = (struct bba_private *)bba_dev->priv;
++ return exi_dev_read(priv->exi_device, data, len);
++}
++
++static inline void bba_write(void *data, size_t len)
++{
++ struct bba_private *priv = (struct bba_private *)bba_dev->priv;
++ return exi_dev_write(priv->exi_device, data, len);
++}
++
++/*
++ * Initializes a BroadBand Adapter device.
++ */
++static int __devinit bba_init_device(struct exi_device *exi_device)
++{
++ struct net_device *dev;
++ struct bba_private *priv;
++ int err;
++
++ /* allocate a network device */
++ dev = alloc_etherdev(sizeof(*priv));
++ if (!dev) {
++ bba_printk(KERN_ERR, "unable to allocate net device\n");
++ err = -ENOMEM;
++ goto err_out;
++ }
++ SET_NETDEV_DEV(dev, &exi_device->dev);
++
++ /* we use the event system from the EXI driver, so no irq here */
++ dev->irq = 0;
++
++ /* network device hooks */
++ dev->open = bba_open;
++ dev->stop = bba_close;
++ dev->hard_start_xmit = bba_start_xmit;
++ dev->get_stats = bba_get_stats;
++
++ priv = netdev_priv(dev);
++ priv->dev = dev;
++ priv->exi_device = exi_device;
++
++ spin_lock_init(&priv->lock);
++
++ /* initialization values */
++ priv->revid = 0xf0;
++ priv->__0x04_init[0] = 0xd1;
++ priv->__0x04_init[1] = 0x07;
++ priv->__0x05_init = 0x4e;
++
++ /* i/o artifacts */
++ priv->tx_skb = NULL;
++ priv->rx_work = 0;
++ init_waitqueue_head(&priv->io_waitq);
++ priv->io_thread = kthread_run(bba_io_thread, priv, "kbbaiod");
++
++ /* the hardware can't do multicast */
++ dev->flags &= ~IFF_MULTICAST;
++
++ exi_set_drvdata(exi_device, dev);
++ if (bba_dev)
++ free_netdev(bba_dev);
++ bba_dev = dev;
++
++ /* we need to retrieve the MAC address before registration */
++ exi_dev_take(priv->exi_device);
++ bba_reset_hardware(dev);
++ bba_retrieve_ether_addr(dev);
++ exi_dev_give(priv->exi_device);
++
++ /* this makes our device available to the kernel */
++ err = register_netdev(dev);
++ if (err) {
++ bba_printk(KERN_ERR, "cannot register net device, aborting.\n");
++ goto err_out_free_dev;
++ }
++
++ return 0;
++
++err_out_free_dev:
++ exi_set_drvdata(exi_device, NULL);
++ free_netdev(dev);
++ bba_dev = NULL;
++
++err_out:
++ return err;
++}
++
++/*
++ * Removes a BroadBand Adapter device from the system.
++ */
++static void __devexit bba_remove(struct exi_device *exi_device)
++{
++ struct net_device *dev = (struct net_device *)
++ exi_get_drvdata(exi_device);
++ struct bba_private *priv;
++
++ if (dev) {
++ priv = (struct bba_private *)dev->priv;
++
++ kthread_stop(priv->io_thread);
++
++ unregister_netdev(dev);
++ free_netdev(dev);
++ exi_set_drvdata(exi_device, NULL);
++ bba_dev = NULL;
++ }
++ exi_device_put(exi_device);
++}
++
++/*
++ * Probes for a BroadBand Adapter device.
++ * Actually, the exi layer has already probed for us.
++ */
++static int __devinit bba_probe(struct exi_device *exi_device)
++{
++ int ret = -ENODEV;
++
++ if (exi_device_get(exi_device))
++ ret = bba_init_device(exi_device);
++
++ return ret;
++}
++
++
++static struct exi_device_id bba_eid_table[] = {
++ [0] = {
++ .channel = BBA_EXI_CHANNEL,
++ .device = BBA_EXI_DEVICE,
++ .id = BBA_EXI_ID
++ },
++ { .id = 0 }
++};
++
++static struct exi_driver bba_driver = {
++ .name = "bba",
++ .eid_table = bba_eid_table,
++ .frequency = BBA_EXI_FREQ,
++ .probe = bba_probe,
++ .remove = bba_remove,
++};
++
++/**
++ * bba_init_module - driver initialization routine
++ *
++ * Initializes the BroadBand Adapter driver module.
++ *
++ */
++static int __init bba_init_module(void)
++{
++ bba_printk(KERN_INFO, "%s - version %s\n", DRV_DESCRIPTION,
++ bba_driver_version);
++
++ return exi_driver_register(&bba_driver);
++}
++
++/**
++ * bba_exit_module - driver exit routine
++ *
++ * Removes the BroadBand Adapter driver module.
++ *
++ */
++static void __exit bba_exit_module(void)
++{
++ exi_driver_unregister(&bba_driver);
++}
++
++module_init(bba_init_module);
++module_exit(bba_exit_module);
++
++MODULE_AUTHOR(DRV_AUTHOR);
++MODULE_DESCRIPTION(DRV_DESCRIPTION);
++MODULE_LICENSE("GPL");
++
+diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
+index 02d25c7..1fcf0d3 100644
+--- a/drivers/net/usb/usbnet.c
++++ b/drivers/net/usb/usbnet.c
+@@ -522,7 +522,9 @@ static int unlink_urbs (struct usbnet *dev, struct sk_buff_head *q)
+
+ // during some PM-driven resume scenarios,
+ // these (async) unlinks complete immediately
++ spin_unlock(&q->lock);
+ retval = usb_unlink_urb (urb);
++ spin_lock(&q->lock);
+ if (retval != -EINPROGRESS && retval != 0)
+ devdbg (dev, "unlink urb err, %d", retval);
+ else
+diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
+index 123092d..fd42af5 100644
+--- a/drivers/rtc/Kconfig
++++ b/drivers/rtc/Kconfig
+@@ -497,6 +497,16 @@ config RTC_DRV_WM8350
+ This driver can also be built as a module. If so, the module
+ will be called "rtc-wm8350".
+
++config RTC_DRV_GCN
++ bool "Nintendo GameCube/Wii Real Time Clock and SRAM"
++ depends on GAMECUBE_EXI
++ default y
++ help
++ If you say yes to this option, support will be included for the
++ Real Time Clock and SRAM of the Nintendo GameCube/Wii.
++
++ If in doubt, say Y here.
++
+ comment "on-CPU RTC drivers"
+
+ config RTC_DRV_OMAP
+diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
+index 6e79c91..10a907f 100644
+--- a/drivers/rtc/Makefile
++++ b/drivers/rtc/Makefile
+@@ -36,6 +36,7 @@ obj-$(CONFIG_RTC_DRV_DS1742) += rtc-ds1742.o
+ obj-$(CONFIG_RTC_DRV_DS3234) += rtc-ds3234.o
+ obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o
+ obj-$(CONFIG_RTC_DRV_FM3130) += rtc-fm3130.o
++obj-$(CONFIG_RTC_DRV_GCN) += rtc-gcn.o
+ obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o
+ obj-$(CONFIG_RTC_DRV_M41T80) += rtc-m41t80.o
+ obj-$(CONFIG_RTC_DRV_M41T94) += rtc-m41t94.o
+diff --git a/drivers/rtc/rtc-gcn.c b/drivers/rtc/rtc-gcn.c
+new file mode 100644
+index 0000000..d5bae5c
+--- /dev/null
++++ b/drivers/rtc/rtc-gcn.c
+@@ -0,0 +1,339 @@
++/*
++ * drivers/rtc/rtc-gcn.c
++ *
++ * Nintendo GameCube/Wii RTC/SRAM driver
++ * Copyright (C) 2004-2009 The GameCube Linux Team
++ * Copyright (C) 2005,2008,2009 Albert Herranz
++ *
++ * Based on gamecube_time.c from Torben Nielsen.
++ *
++ * 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/init.h>
++#include <linux/time.h>
++#include <linux/rtc.h>
++#include <linux/exi.h>
++#include <asm/machdep.h>
++
++#define DRV_MODULE_NAME "rtc-gcn"
++#define DRV_DESCRIPTION "Nintendo GameCube/Wii RTC/SRAM driver"
++#define DRV_AUTHOR "Torben Nielsen, " \
++ "Albert Herranz"
++
++static char gcnrtc_driver_version[] = "1.0i";
++
++#define drv_printk(level, format, arg...) \
++ printk(level DRV_MODULE_NAME ": " format , ## arg)
++
++
++#define RTC_EXI_GCN_ID 0xffff1698
++#define RTC_EXI_RVL_ID 0xfffff308
++
++#define RTC_EXI_CHANNEL 0
++#define RTC_EXI_DEVICE 1
++#define RTC_EXI_FREQ 3 /* 8MHz */
++
++#define RTC_OFFSET 946684800L
++
++
++struct gcn_sram {
++ u16 csum1;
++ u16 csum2;
++ u32 ead0;
++ u32 ead1;
++ int bias;
++ s8 horz_display_offset;
++ u8 ntd;
++ u8 language;
++ u8 flags;
++ u8 reserved[44];
++};
++
++struct gcnrtc_drvdata {
++ spinlock_t lock;
++ struct exi_device *dev;
++
++ struct rtc_device *rtc_dev;
++
++ struct gcn_sram sram;
++};
++
++static struct gcnrtc_drvdata gcnrtc_drvdata;
++
++/*
++ * Hardware interfaces.
++ *
++ */
++
++/*
++ * Loads the SRAM contents.
++ * Context: user.
++ */
++static void sram_load(struct exi_device *dev)
++{
++ struct gcnrtc_drvdata *drvdata = exi_get_drvdata(dev);
++ struct gcn_sram *sram = &drvdata->sram;
++ u32 req;
++
++ exi_dev_take(dev);
++
++ /* select the SRAM device */
++ exi_dev_select(dev);
++
++ /* send the appropriate command */
++ req = 0x20000100;
++ exi_dev_write(dev, &req, sizeof(req));
++
++ /* read the SRAM data */
++ exi_dev_read(dev, sram, sizeof(*sram));
++
++ /* deselect the SRAM device */
++ exi_dev_deselect(dev);
++
++ exi_dev_give(dev);
++
++ return;
++}
++
++/*
++ * Gets the hardware clock date and time.
++ * Context: user.
++ */
++static unsigned long gcnrtc_read_time(struct exi_device *dev)
++{
++ unsigned long a = 0;
++
++ exi_dev_take(dev);
++
++ /* select the SRAM device */
++ exi_dev_select(dev);
++
++ /* send the appropriate command */
++ a = 0x20000000;
++ exi_dev_write(dev, &a, sizeof(a));
++
++ /* read the time and date value */
++ exi_dev_read(dev, &a, sizeof(a));
++
++ /* deselect the RTC device */
++ exi_dev_deselect(dev);
++
++ exi_dev_give(dev);
++
++ return a;
++}
++
++/*
++ * Sets the hardware clock date and time to @aval.
++ * Context: user, interrupt (adjtimex).
++ */
++static int gcnrtc_write_time(struct exi_device *dev, unsigned long aval)
++{
++ u32 req;
++ int retval;
++
++ /*
++ * We may get called from the timer interrupt. In that case,
++ * we could fail if the exi channel used to access the RTC
++ * is busy. If this happens, we just return an error. The timer
++ * interrupt code is prepared to deal with such case.
++ */
++
++ retval = exi_dev_try_take(dev);
++ if (!retval) {
++ /* select the RTC device */
++ exi_dev_select(dev);
++
++ /* send the appropriate command */
++ req = 0xa0000000;
++ exi_dev_write(dev, &req, sizeof(req));
++
++ /* set the new time and date value */
++ exi_dev_write(dev, &aval, sizeof(aval));
++
++ /* deselect the RTC device */
++ exi_dev_deselect(dev);
++
++ exi_dev_give(dev);
++ }
++ return retval;
++}
++
++/*
++ * Platform time functions.
++ *
++ */
++
++/*
++ * Platform specific function to return the current date and time.
++ */
++static void gcnrtc_plat_rtc_get_time(struct rtc_time *t)
++{
++ struct gcnrtc_drvdata *drvdata = &gcnrtc_drvdata;
++ unsigned long nowtime;
++
++ if (!drvdata->dev)
++ return;
++
++ nowtime = gcnrtc_read_time(drvdata->dev) +
++ drvdata->sram.bias + RTC_OFFSET;
++ rtc_time_to_tm(nowtime, t);
++}
++
++/*
++ * Platform specific function to set the current date and time.
++ *
++ */
++static int gcnrtc_plat_rtc_set_time(struct rtc_time *t)
++{
++ struct gcnrtc_drvdata *drvdata = &gcnrtc_drvdata;
++ unsigned long nowtime;
++
++ if (!drvdata->dev)
++ return -ENODEV;
++
++ rtc_tm_to_time(t, &nowtime);
++ return gcnrtc_write_time(drvdata->dev,
++ nowtime - RTC_OFFSET - drvdata->sram.bias);
++}
++
++/*
++ * RTC class driver.
++ *
++ */
++
++/*
++ *
++ */
++static int gcnrtc_rtc_read_time(struct device *dev, struct rtc_time *t)
++{
++ gcnrtc_plat_rtc_get_time(t);
++ return 0;
++}
++
++/*
++ *
++ */
++static int gcnrtc_rtc_set_time(struct device *dev, struct rtc_time *t)
++{
++ return gcnrtc_plat_rtc_set_time(t);
++}
++
++static const struct rtc_class_ops gcnrtc_ops = {
++ .read_time = gcnrtc_rtc_read_time,
++ .set_time = gcnrtc_rtc_set_time,
++};
++
++
++/*
++ * EXI driver.
++ *
++ */
++
++/*
++ *
++ */
++static int gcnrtc_probe(struct exi_device *dev)
++{
++ struct gcnrtc_drvdata *drvdata = &gcnrtc_drvdata;
++ unsigned long flags;
++ int retval = -ENODEV;
++
++ if (exi_device_get(dev)) {
++ spin_lock_init(&drvdata->lock);
++
++ exi_set_drvdata(dev, drvdata);
++ drvdata->dev = dev;
++
++ memset(&drvdata->sram, 0, sizeof(struct gcn_sram));
++ sram_load(dev);
++
++ spin_lock_irqsave(&drvdata->lock, flags);
++ ppc_md.set_rtc_time = gcnrtc_plat_rtc_set_time;
++ ppc_md.get_rtc_time = gcnrtc_plat_rtc_get_time;
++ spin_unlock_irqrestore(&drvdata->lock, flags);
++
++ drvdata->rtc_dev = rtc_device_register(DRV_MODULE_NAME,
++ &dev->dev,
++ &gcnrtc_ops,
++ THIS_MODULE);
++ retval = 0;
++ }
++
++ return retval;
++}
++
++/*
++ *
++ */
++static void gcnrtc_remove(struct exi_device *dev)
++{
++ struct gcnrtc_drvdata *drvdata = exi_get_drvdata(dev);
++ unsigned long flags;
++
++ if (drvdata) {
++ spin_lock_irqsave(&drvdata->lock, flags);
++ ppc_md.set_rtc_time = NULL;
++ ppc_md.get_rtc_time = NULL;
++ spin_unlock_irqrestore(&drvdata->lock, flags);
++
++ if (!IS_ERR(drvdata->rtc_dev))
++ rtc_device_unregister(drvdata->rtc_dev);
++ }
++ exi_device_put(dev);
++}
++
++
++static struct exi_device_id gcnrtc_eid_table[] = {
++ {
++ .channel = RTC_EXI_CHANNEL,
++ .device = RTC_EXI_DEVICE,
++ .id = RTC_EXI_GCN_ID
++ },
++ {
++ .channel = RTC_EXI_CHANNEL,
++ .device = RTC_EXI_DEVICE,
++ .id = RTC_EXI_RVL_ID
++ },
++ { },
++};
++
++static struct exi_driver gcnrtc_driver = {
++ .name = DRV_MODULE_NAME,
++ .eid_table = gcnrtc_eid_table,
++ .frequency = RTC_EXI_FREQ,
++ .probe = gcnrtc_probe,
++ .remove = gcnrtc_remove,
++};
++
++
++/*
++ *
++ */
++static int __init gcnrtc_init_module(void)
++{
++ drv_printk(KERN_INFO, "%s - version %s\n",
++ DRV_DESCRIPTION, gcnrtc_driver_version);
++
++ return exi_driver_register(&gcnrtc_driver);
++}
++
++/*
++ *
++ */
++static void __exit gcnrtc_exit_module(void)
++{
++ exi_driver_unregister(&gcnrtc_driver);
++}
++
++module_init(gcnrtc_init_module);
++module_exit(gcnrtc_exit_module);
++
++MODULE_AUTHOR(DRV_AUTHOR);
++MODULE_DESCRIPTION(DRV_DESCRIPTION);
++MODULE_LICENSE("GPL");
+diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
+index 579d63a..fc383ae 100644
+--- a/drivers/serial/Kconfig
++++ b/drivers/serial/Kconfig
+@@ -1372,4 +1372,17 @@ config SPORT_BAUD_RATE
+ default 19200 if (SERIAL_SPORT_BAUD_RATE_19200)
+ default 9600 if (SERIAL_SPORT_BAUD_RATE_9600)
+
++config SERIAL_USBGECKO
++ bool "USBGecko adapter on the Nintendo GameCube/Wii"
++ depends on GAMECUBE_EXI
++ select SERIAL_CORE
++ help
++ This is a driver for the USB Gecko adapter for the Nintendo GameCube
++ and Wii gaming consoles. It provides a console and a tty interface.
++
++ If you have an adapter like this, say Y here, otherwise say N.
++
++ To compile this driver as a module, choose M here: the
++ module will be called usbgecko.
++
+ endmenu
+diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
+index 0c17c8d..a00d73e 100644
+--- a/drivers/serial/Makefile
++++ b/drivers/serial/Makefile
+@@ -73,3 +73,4 @@ obj-$(CONFIG_SERIAL_OF_PLATFORM) += of_serial.o
+ obj-$(CONFIG_SERIAL_KS8695) += serial_ks8695.o
+ obj-$(CONFIG_KGDB_SERIAL_CONSOLE) += kgdboc.o
+ obj-$(CONFIG_SERIAL_QE) += ucc_uart.o
++obj-$(CONFIG_SERIAL_USBGECKO) += usbgecko.o
+diff --git a/drivers/serial/usbgecko.c b/drivers/serial/usbgecko.c
+new file mode 100644
+index 0000000..223890d
+--- /dev/null
++++ b/drivers/serial/usbgecko.c
+@@ -0,0 +1,597 @@
++/*
++ * drivers/serial/usbgecko.c
++ *
++ * Console and TTY driver for the USB Gecko adapter.
++ * Copyright (C) 2008-2009 The GameCube Linux Team
++ * Copyright (C) 2008,2009 Albert Herranz
++ *
++ * 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.
++ *
++ */
++
++#define UG_DEBUG
++
++#include <linux/kernel.h>
++#include <linux/device.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/console.h>
++#include <linux/tty.h>
++#include <linux/tty_driver.h>
++#include <linux/tty_flip.h>
++#include <linux/kthread.h>
++#include <linux/delay.h>
++
++#include <linux/exi.h>
++
++#define DRV_MODULE_NAME "usbgecko"
++#define DRV_DESCRIPTION "Console and TTY driver for the USB Gecko adapter"
++#define DRV_AUTHOR "Albert Herranz"
++
++static char ug_driver_version[] = "0.1i";
++
++#define drv_printk(level, format, arg...) \
++ printk(level DRV_MODULE_NAME ": " format , ## arg)
++
++/*
++ *
++ * EXI related definitions.
++ */
++#define UG_SLOTA_CHANNEL 0 /* EXI0xxx */
++#define UG_SLOTA_DEVICE 0 /* chip select, EXI0CSB0 */
++
++#define UG_SLOTB_CHANNEL 1 /* EXI1xxx */
++#define UG_SLOTB_DEVICE 0 /* chip select, EXI1CSB0 */
++
++#define UG_SPI_CLK_IDX EXI_CLK_32MHZ
++
++
++struct ug_adapter {
++ struct exi_device *exi_device;
++ struct task_struct *poller;
++ struct mutex mutex;
++ int refcnt;
++};
++
++static struct ug_adapter ug_adapters[2];
++
++
++/*
++ *
++ * Hardware interface.
++ */
++
++/*
++ *
++ */
++static void ug_exi_io_transaction(struct exi_device *exi_device, u16 i, u16 *o)
++{
++ u16 data;
++
++ exi_dev_select(exi_device);
++ data = i;
++ exi_dev_readwrite(exi_device, &data, 2);
++ exi_dev_deselect(exi_device);
++ *o = data;
++}
++
++#if 0
++/*
++ *
++ */
++static void ug_io_transaction(struct ug_adapter *adapter, u16 i, u16 *o)
++{
++ struct exi_device *exi_device = adapter->exi_device;
++
++ if (exi_device)
++ ug_exi_io_transaction(exi_device, i, o);
++}
++#endif
++
++/*
++ *
++ */
++static int ug_check_adapter(struct exi_device *exi_device)
++{
++ u16 data;
++
++ exi_dev_take(exi_device);
++ ug_exi_io_transaction(exi_device, 0x9000, &data);
++ exi_dev_give(exi_device);
++
++ return data == 0x0470;
++}
++
++#if 0
++/*
++ *
++ */
++static int ug_is_txfifo_empty(struct ug_adapter *adapter)
++{
++ struct exi_device *exi_device = adapter->exi_device;
++ u16 data;
++
++ if (!exi_device)
++ return 0;
++
++ if (!exi_dev_try_take(exi_device)) {
++ ug_exi_io_transaction(exi_device, 0xC000, &data);
++ exi_dev_give(exi_device);
++ return data & 0x0400;
++ }
++ return 0;
++}
++
++/*
++ *
++ */
++static int ug_is_rxfifo_empty(struct ug_adapter *adapter)
++{
++ struct exi_device *exi_device = adapter->exi_device;
++ u16 data;
++
++ if (!exi_device)
++ return 0;
++
++ if (!exi_dev_try_take(exi_device)) {
++ ug_exi_io_transaction(exi_device, 0xD000, &data);
++ exi_dev_give(exi_device);
++ return data & 0x0400;
++ }
++ return 0;
++}
++
++/*
++ *
++ */
++static int ug_putc(struct ug_adapter *adapter, char c)
++{
++ struct exi_device *exi_device = adapter->exi_device;
++ u16 data;
++
++ if (!exi_device)
++ return 0;
++
++ if (!exi_dev_try_take(exi_device)) {
++ ug_exi_io_transaction(exi_device, 0xB000|(c<<4), &data);
++ exi_dev_give(exi_device);
++ return data & 0x0400;
++ }
++ return 0;
++}
++
++/*
++ *
++ */
++static int ug_getc(struct ug_adapter *adapter, char *c)
++{
++ struct exi_device *exi_device = adapter->exi_device;
++ u16 data;
++
++ if (!exi_device)
++ return 0;
++
++ if (!exi_dev_try_take(exi_device)) {
++ ug_exi_io_transaction(exi_device, 0xA000, &data);
++ exi_dev_give(exi_device);
++ if ((data & 0x0800)) {
++ *c = data & 0xff;
++ return 1;
++ }
++ }
++ return 0;
++}
++#endif
++
++/*
++ *
++ */
++static int ug_safe_putc(struct ug_adapter *adapter, char c)
++{
++ struct exi_device *exi_device = adapter->exi_device;
++ u16 data;
++
++ if (!exi_device)
++ return 0;
++
++ if (!exi_dev_try_take(exi_device)) {
++ ug_exi_io_transaction(exi_device, 0xC000, &data);
++ if ((data & 0x0400))
++ ug_exi_io_transaction(exi_device, 0xB000|(c<<4), &data);
++ exi_dev_give(exi_device);
++ return data & 0x0400;
++ }
++ return 0;
++}
++
++/*
++ *
++ */
++static int ug_safe_getc(struct ug_adapter *adapter, char *c)
++{
++ struct exi_device *exi_device = adapter->exi_device;
++ u16 data;
++
++ if (!exi_device)
++ return 0;
++
++ if (!exi_dev_try_take(exi_device)) {
++ ug_exi_io_transaction(exi_device, 0xD000, &data);
++ if ((data & 0x0400)) {
++ ug_exi_io_transaction(exi_device, 0xA000, &data);
++ exi_dev_give(exi_device);
++ if ((data & 0x0800)) {
++ *c = data & 0xff;
++ return 1;
++ }
++ } else {
++ exi_dev_give(exi_device);
++ }
++ }
++ return 0;
++}
++
++
++/*
++ *
++ * Linux console interface.
++ */
++
++/*
++ *
++ */
++static void ug_console_write(struct console *co, const char *buf,
++ unsigned int count)
++{
++ struct ug_adapter *adapter = co->data;
++ char *b = (char *)buf;
++
++ while (count--) {
++ if (*b == '\n')
++ ug_safe_putc(adapter, '\r');
++ ug_safe_putc(adapter, *b++);
++ }
++}
++
++/*
++ *
++ */
++static int ug_console_read(struct console *co, char *buf,
++ unsigned int count)
++{
++ struct ug_adapter *adapter = co->data;
++ int i;
++ char c;
++
++ i = count;
++ while (i--) {
++ ug_safe_getc(adapter, &c);
++ *buf++ = c;
++ }
++ return count;
++}
++
++static struct tty_driver *ug_tty_driver;
++
++static struct tty_driver *ug_console_device(struct console *co, int *index)
++{
++ *index = co->index;
++ return ug_tty_driver;
++}
++
++
++static struct console ug_consoles[] = {
++ {
++ .name = DRV_MODULE_NAME "0",
++ .write = ug_console_write,
++ .read = ug_console_read,
++ .device = ug_console_device,
++ .flags = CON_PRINTBUFFER | CON_ENABLED,
++ .index = 0,
++ .data = &ug_adapters[0],
++ },
++ {
++ .name = DRV_MODULE_NAME "1",
++ .write = ug_console_write,
++ .read = ug_console_read,
++ .device = ug_console_device,
++ .flags = CON_PRINTBUFFER | CON_ENABLED,
++ .index = 1,
++ .data = &ug_adapters[1],
++ },
++};
++
++
++/*
++ *
++ * Linux tty driver.
++ */
++
++static int ug_tty_poller(void *tty_)
++{
++ struct sched_param param = { .sched_priority = 1 };
++ struct tty_struct *tty = tty_;
++ struct ug_adapter *adapter;
++ int count, chunk;
++ const int max_outstanding = 32;
++ char ch;
++
++ sched_setscheduler(current, SCHED_FIFO, &param);
++ set_task_state(current, TASK_RUNNING);
++
++ chunk = 0;
++ while (!kthread_should_stop()) {
++ count = 0;
++ adapter = tty->driver_data;
++ if (adapter)
++ count = ug_safe_getc(adapter, &ch);
++ set_task_state(current, TASK_INTERRUPTIBLE);
++ if (count) {
++ tty_insert_flip_char(tty, ch, TTY_NORMAL);
++ if (chunk++ > max_outstanding) {
++ tty_flip_buffer_push(tty);
++ chunk = 0;
++ }
++ } else {
++ if (chunk) {
++ tty_flip_buffer_push(tty);
++ chunk = 0;
++ }
++ schedule_timeout(1);
++ }
++ set_task_state(current, TASK_RUNNING);
++ }
++
++ return 0;
++}
++
++static int ug_tty_open(struct tty_struct *tty, struct file *filp)
++{
++ struct ug_adapter *adapter;
++ int index;
++ int retval = 0;
++
++ index = tty->index;
++ adapter = &ug_adapters[index];
++
++ mutex_lock(&adapter->mutex);
++
++ if (!adapter->exi_device) {
++ mutex_unlock(&adapter->mutex);
++ return -ENODEV;
++ }
++
++ if (!adapter->refcnt) {
++ adapter->poller = kthread_run(ug_tty_poller, tty, "kugtty");
++ if (IS_ERR(adapter->poller)) {
++ drv_printk(KERN_ERR, "error creating poller thread\n");
++ mutex_unlock(&adapter->mutex);
++ return -ENOMEM;
++ }
++ }
++
++ adapter->refcnt++;
++ tty->driver_data = adapter;
++
++ mutex_unlock(&adapter->mutex);
++
++ return retval;
++}
++
++static void ug_tty_close(struct tty_struct *tty, struct file *filp)
++{
++ struct ug_adapter *adapter;
++ int index;
++
++ index = tty->index;
++ adapter = &ug_adapters[index];
++
++ mutex_lock(&adapter->mutex);
++
++ adapter->refcnt--;
++ if (!adapter->refcnt) {
++ if (!IS_ERR(adapter->poller))
++ kthread_stop(adapter->poller);
++ adapter->poller = ERR_PTR(-EINVAL);
++ tty->driver_data = NULL;
++ }
++
++ mutex_unlock(&adapter->mutex);
++}
++
++static int ug_tty_write(struct tty_struct *tty,
++ const unsigned char *buf, int count)
++{
++ struct ug_adapter *adapter = tty->driver_data;
++ char *b = (char *)buf;
++ int index;
++ int i;
++
++ if (!adapter)
++ return -ENODEV;
++
++ index = tty->index;
++ adapter = &ug_adapters[index];
++ for (i = 0; i < count; i++)
++ ug_safe_putc(adapter, *b++);
++ return count;
++}
++
++static int ug_tty_write_room(struct tty_struct *tty)
++{
++ return 0x123; /* whatever */
++}
++
++static int ug_tty_chars_in_buffer(struct tty_struct *tty)
++{
++ return 0; /* unbuffered */
++}
++
++
++static const struct tty_operations ug_tty_ops = {
++ .open = ug_tty_open,
++ .close = ug_tty_close,
++ .write = ug_tty_write,
++ .write_room = ug_tty_write_room,
++ .chars_in_buffer = ug_tty_chars_in_buffer,
++};
++
++
++static int ug_tty_init(void)
++{
++ struct tty_driver *driver;
++ int retval;
++
++ driver = alloc_tty_driver(2);
++ if (!driver)
++ return -ENOMEM;
++ driver->name = DRV_MODULE_NAME "con";
++ driver->major = TTY_MAJOR;
++ driver->minor_start = 64;
++ driver->type = TTY_DRIVER_TYPE_SYSCONS;
++ driver->init_termios = tty_std_termios;
++ tty_set_operations(driver, &ug_tty_ops);
++ retval = tty_register_driver(driver);
++ if (retval) {
++ put_tty_driver(driver);
++ return retval;
++ }
++ ug_tty_driver = driver;
++ return 0;
++}
++
++static void ug_tty_exit(void)
++{
++ struct tty_driver *driver = ug_tty_driver;
++
++ ug_tty_driver = NULL;
++ if (driver) {
++ tty_unregister_driver(driver);
++ put_tty_driver(driver);
++ }
++}
++
++
++
++/*
++ *
++ * EXI layer interface.
++ */
++
++/*
++ *
++ */
++static int ug_probe(struct exi_device *exi_device)
++{
++ struct console *console;
++ struct ug_adapter *adapter;
++ unsigned int slot;
++
++ /* don't try to drive a device which already has a real identifier */
++ if (exi_device->eid.id != EXI_ID_NONE)
++ return -ENODEV;
++
++ if (!ug_check_adapter(exi_device))
++ return -ENODEV;
++
++ slot = to_channel(exi_get_exi_channel(exi_device));
++ console = &ug_consoles[slot];
++ adapter = console->data;
++
++ drv_printk(KERN_INFO, "USB Gecko detected in memcard slot-%c\n",
++ 'A'+slot);
++
++ adapter->poller = ERR_PTR(-EINVAL);
++ mutex_init(&adapter->mutex);
++ adapter->refcnt = 0;
++
++ adapter->exi_device = exi_device_get(exi_device);
++ exi_set_drvdata(exi_device, adapter);
++ register_console(console);
++
++ ug_tty_init();
++
++ return 0;
++}
++
++/*
++ * Makes unavailable the USB Gecko adapter identified by the EXI device
++ * `exi_device'.
++ */
++static void ug_remove(struct exi_device *exi_device)
++{
++ struct console *console;
++ struct ug_adapter *adapter;
++ unsigned int slot;
++
++ slot = to_channel(exi_get_exi_channel(exi_device));
++ console = &ug_consoles[slot];
++ adapter = console->data;
++
++ if (adapter->refcnt)
++ drv_printk(KERN_ERR, "adapter removed while in use!\n");
++
++ ug_tty_exit();
++
++ unregister_console(console);
++ exi_set_drvdata(exi_device, NULL);
++ adapter->exi_device = NULL;
++ exi_device_put(exi_device);
++
++ mutex_destroy(&adapter->mutex);
++
++ drv_printk(KERN_INFO, "USB Gecko removed from memcard slot-%c\n",
++ 'A'+slot);
++}
++
++static struct exi_device_id ug_eid_table[] = {
++ [0] = {
++ .channel = UG_SLOTA_CHANNEL,
++ .device = UG_SLOTA_DEVICE,
++ .id = EXI_ID_NONE,
++ },
++ [1] = {
++ .channel = UG_SLOTB_CHANNEL,
++ .device = UG_SLOTB_DEVICE,
++ .id = EXI_ID_NONE,
++ },
++ {.id = 0}
++};
++
++static struct exi_driver ug_exi_driver = {
++ .name = DRV_MODULE_NAME,
++ .eid_table = ug_eid_table,
++ .frequency = UG_SPI_CLK_IDX,
++ .probe = ug_probe,
++ .remove = ug_remove,
++};
++
++
++/*
++ *
++ * Module interface.
++ */
++
++static int __init ug_init_module(void)
++{
++ drv_printk(KERN_INFO, "%s - version %s\n", DRV_DESCRIPTION,
++ ug_driver_version);
++
++ return exi_driver_register(&ug_exi_driver);
++}
++
++static void __exit ug_exit_module(void)
++{
++ exi_driver_unregister(&ug_exi_driver);
++}
++
++module_init(ug_init_module);
++module_exit(ug_exit_module);
++
++MODULE_AUTHOR(DRV_AUTHOR);
++MODULE_DESCRIPTION(DRV_DESCRIPTION);
++MODULE_LICENSE("GPL");
++
+diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
+index 289d81a..cdadf99 100644
+--- a/drivers/usb/Kconfig
++++ b/drivers/usb/Kconfig
+@@ -22,6 +22,7 @@ config USB_ARCH_HAS_HCD
+ default y if PCMCIA && !M32R # sl811_cs
+ default y if ARM # SL-811
+ default y if SUPERH # r8a66597-hcd
++ default y if WII # rvl-sthcd
+ default PCI
+
+ # many non-PCI SOC chips embed OHCI
+diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile
+index 8b7c419..ba41ba1 100644
+--- a/drivers/usb/Makefile
++++ b/drivers/usb/Makefile
+@@ -16,6 +16,7 @@ obj-$(CONFIG_USB_UHCI_HCD) += host/
+ obj-$(CONFIG_USB_SL811_HCD) += host/
+ obj-$(CONFIG_USB_U132_HCD) += host/
+ obj-$(CONFIG_USB_R8A66597_HCD) += host/
++obj-$(CONFIG_USB_WII_HCD) += host/
+ obj-$(CONFIG_USB_HWA_HCD) += host/
+
+ obj-$(CONFIG_USB_C67X00_HCD) += c67x00/
+diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
+index f3a75a9..60c8f71 100644
+--- a/drivers/usb/host/Kconfig
++++ b/drivers/usb/host/Kconfig
+@@ -294,6 +294,25 @@ config SUPERH_ON_CHIP_R8A66597
+ This driver enables support for the on-chip R8A66597 in the
+ SH7366 and SH7723 processors.
+
++config USB_WII_HCD
++ tristate "Nintendo Wii HCD support"
++ depends on USB && WII && !HIGHMEM && EXPERIMENTAL
++ help
++ The Nintendo Wii includes a USB 1.1 host controller that can be
++ accessed through the API provided by the starlet subsystem.
++
++ Enable this option if you plan to use the internal Nintendo Wii
++ bluetooth dongle or any USB peripheral connected to the external
++ ports.
++
++ USB devices using isochronous transfers are not supported.
++ Use of USB hubs is partially supported.
++
++ Use completely at you own risk. If unsure, say N.
++
++ To compile this driver as a module, choose M here: the
++ module will be called rvl-sthcd.
++
+ config USB_WHCI_HCD
+ tristate "Wireless USB Host Controller Interface (WHCI) driver (EXPERIMENTAL)"
+ depends on EXPERIMENTAL
+diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
+index 23be222..98209ee 100644
+--- a/drivers/usb/host/Makefile
++++ b/drivers/usb/host/Makefile
+@@ -21,4 +21,5 @@ obj-$(CONFIG_USB_SL811_CS) += sl811_cs.o
+ obj-$(CONFIG_USB_U132_HCD) += u132-hcd.o
+ obj-$(CONFIG_USB_R8A66597_HCD) += r8a66597-hcd.o
+ obj-$(CONFIG_USB_ISP1760_HCD) += isp1760.o
++obj-$(CONFIG_USB_WII_HCD) += rvl-sthcd.o
+ obj-$(CONFIG_USB_HWA_HCD) += hwa-hc.o
+diff --git a/drivers/usb/host/rvl-sthcd.c b/drivers/usb/host/rvl-sthcd.c
+new file mode 100644
+index 0000000..8f68297
+--- /dev/null
++++ b/drivers/usb/host/rvl-sthcd.c
+@@ -0,0 +1,2373 @@
++/*
++ * drivers/usb/host/rvl-sthcd.c
++ *
++ * USB Host Controller driver for the Nintendo Wii
++ * Copyright (C) 2008-2009 The GameCube Linux Team
++ * Copyright (C) 2008 Maarten ter Huurne
++ * Copyright (C) 2008,2009 Albert Herranz
++ *
++ * 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.
++ *
++ */
++
++/*
++ *
++ * TODO
++ * - cleanup debuging mess
++ *
++ */
++
++#ifdef CONFIG_HIGHMEM
++#error Sorry, this driver cannot currently work if HIGHMEM is y
++#endif
++
++#define DBG(fmt, arg...) drv_printk(KERN_DEBUG, fmt, ##arg)
++
++#include <linux/device.h>
++#include <linux/errno.h>
++#include <linux/kernel.h>
++#include <linux/kthread.h>
++#include <linux/module.h>
++#include <linux/of_platform.h>
++#include <linux/scatterlist.h>
++#include <linux/usb.h>
++#include <asm/starlet.h>
++
++#include "../core/hcd.h"
++#include "../core/hub.h"
++
++#define DRV_MODULE_NAME "rvl-sthcd"
++#define DRV_DESCRIPTION "USB Host Controller driver for the Nintendo Wii"
++#define DRV_AUTHOR "Maarten ter Huurne, " \
++ "Albert Herranz"
++
++static char sthcd_driver_version[] = "0.4i";
++
++#define drv_printk(level, format, arg...) \
++ printk(level DRV_MODULE_NAME ": " format , ## arg)
++
++
++/* TODO: Use enum instead? */
++#define STHCD_IOCTLV_CONTROLREQ 0
++#define STHCD_IOCTLV_BULKREQ 1
++#define STHCD_IOCTLV_INTRREQ 2
++#define STHCD_IOCTL_SUSPENDDEVICE 5
++#define STHCD_IOCTL_RESUMEDEVICE 6
++#define STHCD_IOCTLV_GETDEVICELIST 12
++#define STHCD_IOCTL_DEVICEREMOVALNOTIFY 26
++#define STHCD_IOCTLV_DEVICEINSERTNOTIFY 27
++
++/*
++ * The Nintendo Wii has only 2 external USB ports (plus 1 internal USB port),
++ * but the starlet API provides access to USB devices in a port independent
++ * way. This is true also for USB devices attached to external hubs.
++ *
++ * Our HCD model currently maps one starlet USB device to one HCD port, thus
++ * we need additional ports here.
++ */
++#define STHCD_MAX_DEVIDS 15
++#define STHCD_MAX_PORTS STHCD_MAX_DEVIDS
++
++/*
++ * We get error -7008 after performing large transfers.
++ * Using this arbitrary limit makes things work.
++ */
++#define STHCD_MAX_CHUNK_SIZE (2048)
++
++#define STHCD_PORT_MAX_RESETS 2 /* maximum number of consecutive
++ * resets allowed for a port */
++#define STHCD_RESCAN_INTERVAL 5 /* seconds */
++
++#define starlet_ioh_sg_entry(sg, ptr) \
++ starlet_ioh_sg_set_buf((sg), (ptr), sizeof(*(ptr)))
++
++
++struct sthcd_hcd;
++struct sthcd_port;
++struct sthcd_oh;
++
++/*
++ * starlet USB device abstraction (udev).
++ *
++ */
++struct sthcd_udev {
++ u16 idVendor;
++ u16 idProduct;
++ int fd; /* starlet file descriptor */
++
++ u16 devnum; /* USB address set by kernel */
++
++ struct list_head node; /* in list of connected devices */
++ struct sthcd_oh *oh; /* parent Open Host controller */
++
++ struct list_head pep_list; /* list of private endpoints */
++};
++
++/*
++ * starlet USB device identifier.
++ *
++ */
++struct sthcd_devid {
++ u32 _unk1;
++ u16 idVendor;
++ u16 idProduct;
++};
++
++enum {
++ __STHCD_PORT_INUSE = 0,
++ __STHCD_PORT_DOOMED,
++};
++
++
++/*
++ * "Virtual" HCD USB port.
++ *
++ */
++struct sthcd_port {
++ unsigned long flags;
++#define STHCD_PORT_INUSE (1 << __STHCD_PORT_INUSE)
++#define STHCD_PORT_DOOMED (1 << __STHCD_PORT_DOOMED)
++
++ u32 status_change;
++ unsigned nr_resets;
++
++ struct sthcd_udev udev; /* one udev per port */
++};
++
++/*
++ * starlet Open Host controller abstraction (oh).
++ *
++ */
++struct sthcd_oh {
++ unsigned int index;
++ int fd; /* starlet file descriptor */
++
++ unsigned int max_devids;
++ struct sthcd_devid *new_devids;
++ struct sthcd_devid *devids;
++ unsigned int nr_devids; /* actual no of devices */
++
++ struct sthcd_hcd *hcd; /* parent Host Controller */
++};
++
++/*
++ * Host Controller (hcd).
++ *
++ */
++struct sthcd_hcd {
++ spinlock_t lock;
++
++ struct sthcd_oh oh[2];
++
++ struct sthcd_port *ports; /* array of ports */
++ unsigned int nr_ports;
++
++ struct list_head device_list; /* list of connected devices */
++
++ wait_queue_head_t rescan_waitq; /* wait queue for the rescan task */
++ struct task_struct *rescan_task;
++};
++
++
++/*
++ * Private endpoint (pep).
++ *
++ * A pep takes care of the transfers for an endpoint.
++ */
++
++struct sthcd_ctrl_params_in {
++ struct usb_ctrlrequest req;
++ u8 _unk1; /* timeout? */
++};
++struct sthcd_ctrl_xfer_ctx {
++ struct starlet_ioh_sg in[6];
++ struct sthcd_ctrl_params_in *params_in;
++};
++
++struct sthcd_bulk_intr_params_in {
++ u8 bEndpointAddress;
++ u16 wLength;
++};
++struct sthcd_bulk_intr_xfer_ctx {
++ struct starlet_ioh_sg in[2];
++ struct sthcd_bulk_intr_params_in *params_in;
++};
++
++enum {
++ __STHCD_PEP_DISABLED = 0,
++ __STHCD_PEP_XFERBUSY, /* pep is actively xferring data */
++};
++
++struct sthcd_pep {
++ unsigned long flags;
++#define STHCD_PEP_DISABLED (1 << __STHCD_PEP_DISABLED)
++#define STHCD_PEP_XFERBUSY (1 << __STHCD_PEP_XFERBUSY)
++
++ unsigned long outstanding;
++
++ struct usb_host_endpoint *ep; /* associated endpoint */
++ struct sthcd_hcd *sthcd; /* associated hcd */
++
++ /* local copy of endpoint descriptor bmAttributes */
++ __u8 bmAttributes;
++
++ /* xfer context data */
++
++ struct urb *urb; /* urb being transferred */
++
++ struct sthcd_udev *udev; /* udev for this urb */
++ struct list_head node; /* in list of peps for this udev */
++
++ size_t io_xfer_offset; /* number of bytes transferred */
++ void *io_buf; /* data buffer */
++ size_t io_buf_len; /* length of io_buf */
++
++ int request; /* ioctlv request */
++ union {
++ struct sthcd_bulk_intr_xfer_ctx *bulk_intr;
++ struct sthcd_ctrl_xfer_ctx *ctrl;
++ } ctx; /* transfer context */
++
++ unsigned int nents_in; /* number of input sg entries */
++ struct starlet_ioh_sg *in; /* input sg list */
++ struct starlet_ioh_sg io[1]; /* input/output sg list */
++};
++
++
++/*
++ * Debugging facilities.
++ *
++ */
++
++#if 0
++static inline void print_buffer(void *buf, u32 size)
++{
++ int i;
++ for (i = 0; i < (size + 3) / 4; i += 4) {
++ u32 *data = &((u32 *)buf)[i];
++ printk(KERN_INFO " %08X %08X %08X %08X\n",
++ data[0], data[1], data[2], data[3]
++ );
++ }
++}
++#endif
++
++/*
++ * Type conversion routines.
++ *
++ */
++
++static inline struct sthcd_hcd *hcd_to_sthcd(struct usb_hcd *hcd)
++{
++ return (struct sthcd_hcd *)(hcd->hcd_priv);
++}
++
++static inline struct usb_hcd *sthcd_to_hcd(struct sthcd_hcd *sthcd)
++{
++ return container_of((void *)sthcd, struct usb_hcd, hcd_priv);
++}
++
++static inline struct sthcd_port *udev_to_port(struct sthcd_udev *_udev)
++{
++ return container_of(_udev, struct sthcd_port, udev);
++}
++
++
++/*
++ * Private End Point abstraction.
++ *
++ */
++
++static inline struct sthcd_pep *ep_to_pep(struct usb_host_endpoint *ep)
++{
++ return ep->hcpriv;
++}
++
++static inline int pep_is_enabled(struct sthcd_pep *pep)
++{
++ return !test_bit(__STHCD_PEP_DISABLED, &pep->flags);
++}
++
++static int sthcd_pep_alloc_ctrl_xfer_ctx(struct sthcd_pep *pep)
++{
++ struct sthcd_ctrl_xfer_ctx *ctx;
++ struct sthcd_ctrl_params_in *params_in;
++ int error;
++
++ ctx = starlet_kzalloc(sizeof(*ctx), GFP_ATOMIC);
++ if (!ctx) {
++ error = -ENOMEM;
++ goto done;
++ }
++
++ params_in = starlet_ioh_kzalloc(sizeof(*params_in));
++ if (!params_in) {
++ starlet_kfree(ctx);
++ error = -ENOMEM;
++ goto done;
++ }
++
++ ctx->params_in = params_in;
++
++ starlet_ioh_sg_init_table(ctx->in, 6);
++ starlet_ioh_sg_entry(&ctx->in[0], &params_in->req.bRequestType);
++ starlet_ioh_sg_entry(&ctx->in[1], &params_in->req.bRequest);
++ starlet_ioh_sg_entry(&ctx->in[2], &params_in->req.wValue);
++ starlet_ioh_sg_entry(&ctx->in[3], &params_in->req.wIndex);
++ starlet_ioh_sg_entry(&ctx->in[4], &params_in->req.wLength);
++ starlet_ioh_sg_entry(&ctx->in[5], &params_in->_unk1);
++
++ pep->ctx.ctrl = ctx;
++
++ pep->nents_in = ARRAY_SIZE(ctx->in);
++ pep->in = ctx->in;
++
++ error = 0;
++
++done:
++ if (error < 0)
++ DBG("%s: error=%d (%x)\n", __func__, error, error);
++ return error;
++}
++
++static void sthcd_pep_free_ctrl_xfer_ctx(struct sthcd_pep *pep)
++{
++ struct sthcd_ctrl_xfer_ctx *ctx = pep->ctx.ctrl;
++
++ if (ctx) {
++ starlet_ioh_kfree(ctx->params_in);
++ starlet_kfree(ctx);
++ pep->ctx.ctrl = NULL;
++ }
++}
++
++static int sthcd_pep_alloc_bulk_intr_xfer_ctx(struct sthcd_pep *pep)
++{
++ struct sthcd_bulk_intr_xfer_ctx *ctx;
++ struct sthcd_bulk_intr_params_in *params_in;
++ int error;
++
++ ctx = starlet_kzalloc(sizeof(*ctx), GFP_ATOMIC);
++ if (!ctx) {
++ error = -ENOMEM;
++ goto done;
++ }
++
++ params_in = starlet_ioh_kzalloc(sizeof(*params_in));
++ if (!params_in) {
++ starlet_kfree(ctx);
++ error = -ENOMEM;
++ goto done;
++ }
++
++ ctx->params_in = params_in;
++
++ starlet_ioh_sg_init_table(ctx->in, 2);
++ starlet_ioh_sg_entry(&ctx->in[0], &params_in->bEndpointAddress);
++ starlet_ioh_sg_entry(&ctx->in[1], &params_in->wLength);
++
++ pep->ctx.bulk_intr = ctx;
++
++ pep->nents_in = ARRAY_SIZE(ctx->in);
++ pep->in = ctx->in;
++
++ error = 0;
++
++done:
++ if (error < 0)
++ DBG("%s: error=%d (%x)\n", __func__, error, error);
++ return error;
++}
++
++static void sthcd_pep_free_bulk_intr_xfer_ctx(struct sthcd_pep *pep)
++{
++ struct sthcd_bulk_intr_xfer_ctx *ctx = pep->ctx.bulk_intr;
++
++ if (ctx) {
++ starlet_ioh_kfree(ctx->params_in);
++ starlet_kfree(ctx);
++ pep->ctx.bulk_intr = NULL;
++ }
++}
++
++static int sthcd_pep_alloc_xfer_ctx(struct sthcd_pep *pep)
++{
++ unsigned int xfer_type = pep->bmAttributes &
++ USB_ENDPOINT_XFERTYPE_MASK;
++ int error;
++
++ switch (xfer_type) {
++ case USB_ENDPOINT_XFER_CONTROL:
++ error = sthcd_pep_alloc_ctrl_xfer_ctx(pep);
++ break;
++ case USB_ENDPOINT_XFER_BULK:
++ case USB_ENDPOINT_XFER_INT:
++ error = sthcd_pep_alloc_bulk_intr_xfer_ctx(pep);
++ break;
++ default:
++ error = -ENXIO;
++ break;
++ }
++
++ if (error < 0)
++ DBG("%s: error=%d (%x)\n", __func__, error, error);
++ return error;
++}
++
++static void sthcd_pep_free_xfer_ctx(struct sthcd_pep *pep)
++{
++ unsigned int xfer_type = pep->bmAttributes &
++ USB_ENDPOINT_XFERTYPE_MASK;
++
++ switch (xfer_type) {
++ case USB_ENDPOINT_XFER_CONTROL:
++ sthcd_pep_free_ctrl_xfer_ctx(pep);
++ break;
++ case USB_ENDPOINT_XFER_BULK:
++ case USB_ENDPOINT_XFER_INT:
++ sthcd_pep_free_bulk_intr_xfer_ctx(pep);
++ break;
++ default:
++ DBG("%s: invalid endpoint xfer type %u\n", __func__,
++ xfer_type);
++ break;
++ }
++}
++
++static int sthcd_pep_alloc_xfer_io_buf(struct sthcd_pep *pep, size_t size)
++{
++ /* REVISIT, size must be greater than 0 */
++ size_t io_buf_size = size + 32;
++ int error;
++
++ pep->io_buf = starlet_ioh_kzalloc(io_buf_size);
++ if (!pep->io_buf) {
++ error = -ENOMEM;
++ goto done;
++ }
++
++ starlet_ioh_sg_init_table(pep->io, 1);
++ starlet_ioh_sg_set_buf(&pep->io[0], pep->io_buf, size);
++
++ error = 0;
++
++done:
++ if (error < 0)
++ DBG("%s: error=%d (%x)\n", __func__, error, error);
++ return error;
++}
++
++static void sthcd_pep_free_xfer_io_buf(struct sthcd_pep *pep)
++{
++ if (pep->io_buf) {
++ starlet_ioh_sg_set_buf(&pep->io[0], NULL, 0);
++ starlet_ioh_kfree(pep->io_buf);
++ pep->io_buf = NULL;
++ }
++}
++
++/*
++ *
++ * Context: interrupts disabled, hcd lock held
++ */
++static int sthcd_pep_init(struct sthcd_pep *pep, struct sthcd_hcd *sthcd,
++ struct usb_host_endpoint *ep)
++{
++ int error;
++
++ BUG_ON(!ep);
++
++ pep->sthcd = sthcd;
++ pep->ep = ep;
++ pep->bmAttributes = ep->desc.bmAttributes;
++
++ error = sthcd_pep_alloc_xfer_ctx(pep);
++ if (error)
++ goto done;
++
++done:
++ if (error < 0)
++ DBG("%s: error=%d (%x)\n", __func__, error, error);
++ return error;
++}
++
++/*
++ *
++ * Context: interrupts disabled, hcd lock held
++ */
++static void sthcd_pep_exit(struct sthcd_pep *pep)
++{
++ BUG_ON(pep->urb);
++ BUG_ON(!pep->ep);
++
++ sthcd_pep_free_xfer_ctx(pep);
++
++ pep->ep = NULL;
++ pep->sthcd = NULL;
++}
++
++/*
++ *
++ * Context: interrupts disabled, hcd lock held
++ */
++static struct sthcd_pep *sthcd_pep_alloc(struct sthcd_hcd *sthcd,
++ struct usb_host_endpoint *ep)
++{
++ struct sthcd_pep *pep;
++ int error;
++
++ pep = kzalloc(sizeof(*pep), GFP_ATOMIC);
++ if (!pep)
++ return NULL;
++
++ error = sthcd_pep_init(pep, sthcd, ep);
++ if (error) {
++ kfree(pep);
++ return NULL;
++ }
++
++ return pep;
++}
++
++/*
++ *
++ * Context: interrupts disabled, hcd lock held
++ */
++static void sthcd_pep_free(struct sthcd_pep *pep)
++{
++ sthcd_pep_exit(pep);
++ kfree(pep);
++}
++
++/*
++ *
++ * Context: interrupts disabled, hcd lock held
++ */
++static struct sthcd_udev *sthcd_find_udev_by_num(struct sthcd_hcd *sthcd,
++ u16 devnum)
++{
++ struct sthcd_udev *udev;
++
++ list_for_each_entry(udev, &sthcd->device_list, node) {
++ if (udev->devnum == devnum)
++ return udev;
++ }
++ DBG("%s: udev %u not found\n", __func__, devnum);
++ return NULL;
++}
++
++/*
++ *
++ * Context: interrupts disabled, hcd lock held
++ */
++static int sthcd_pep_takein_urb(struct sthcd_pep *pep, struct urb *urb)
++{
++ struct sthcd_hcd *sthcd = pep->sthcd;
++ struct sthcd_udev *udev;
++ int error = 0;
++
++ if (!pep_is_enabled(pep)) {
++ error = -ESHUTDOWN;
++ goto done;
++ }
++
++ if (pep->urb) {
++ error = -EBUSY;
++ goto done;
++ }
++
++ if (unlikely(!pep->udev)) {
++ BUG_ON(!urb->dev);
++ udev = sthcd_find_udev_by_num(sthcd, urb->dev->devnum);
++ if (!udev) {
++ error = -ENODEV;
++ goto done;
++ }
++ pep->udev = udev;
++ list_add_tail(&pep->node, &udev->pep_list);
++ }
++
++ pep->urb = urb;
++done:
++ if (error < 0)
++ DBG("%s: error=%d (%x)\n", __func__, error, error);
++ return error;
++}
++
++/*
++ *
++ * Context: interrupts disabled, hcd lock held
++ */
++static void sthcd_pep_takeout_urb(struct sthcd_pep *pep)
++{
++ WARN_ON(!pep->urb);
++
++ pep->urb = NULL;
++ if (pep->udev)
++ list_del_init(&pep->node);
++ pep->udev = NULL;
++}
++
++/*
++ *
++ * Context: interrupts disabled, hcd lock held
++ */
++static void sthcd_pep_setup_ctrl_xfer(struct sthcd_pep *pep)
++{
++ struct urb *urb = pep->urb;
++ struct sthcd_ctrl_xfer_ctx *ctx = pep->ctx.ctrl;
++ struct sthcd_ctrl_params_in *params_in;
++
++ params_in = ctx->params_in;
++ memcpy(&params_in->req, urb->setup_packet, sizeof(params_in->req));
++ params_in->req.wLength = cpu_to_le16(pep->io_buf_len);
++}
++
++/*
++ *
++ * Context: interrupts disabled, hcd lock held
++ */
++static void sthcd_pep_setup_bulk_intr_xfer(struct sthcd_pep *pep)
++{
++ struct urb *urb = pep->urb;
++ struct sthcd_bulk_intr_xfer_ctx *ctx = pep->ctx.bulk_intr;
++ struct sthcd_bulk_intr_params_in *params_in;
++
++ params_in = ctx->params_in;
++ params_in->bEndpointAddress = urb->ep->desc.bEndpointAddress;
++ params_in->wLength = pep->io_buf_len;
++}
++
++/*
++ *
++ * Context: interrupts disabled, hcd lock held
++ */
++static int sthcd_pep_setup_xfer(struct sthcd_pep *pep)
++{
++ struct urb *urb = pep->urb;
++ int request;
++ int error = 0;
++
++ switch (usb_pipetype(urb->pipe)) {
++ case PIPE_CONTROL:
++ request = STHCD_IOCTLV_CONTROLREQ;
++ sthcd_pep_setup_ctrl_xfer(pep);
++ break;
++ case PIPE_INTERRUPT:
++ request = STHCD_IOCTLV_INTRREQ;
++ sthcd_pep_setup_bulk_intr_xfer(pep);
++ break;
++ case PIPE_BULK:
++ request = STHCD_IOCTLV_BULKREQ;
++ sthcd_pep_setup_bulk_intr_xfer(pep);
++ break;
++ default:
++ error = -EINVAL;
++ break;
++ }
++
++ if (!error) {
++ pep->request = request;
++ starlet_ioh_sg_set_buf(&pep->io[0],
++ pep->io_buf, pep->io_buf_len);
++ }
++
++ if (error < 0)
++ DBG("%s: error=%d (%x)\n", __func__, error, error);
++ return error;
++}
++
++/*
++ *
++ * Context: interrupts disabled, hcd lock held
++ */
++static int sthcd_pep_setup_next_xfer(struct sthcd_pep *pep)
++{
++ struct urb *urb = pep->urb;
++ int retval = 0;
++ int error;
++
++ if (pep->io_xfer_offset < urb->transfer_buffer_length) {
++ pep->io_buf_len = urb->transfer_buffer_length -
++ pep->io_xfer_offset;
++ if (pep->io_buf_len > STHCD_MAX_CHUNK_SIZE)
++ pep->io_buf_len = STHCD_MAX_CHUNK_SIZE;
++
++ retval = pep->io_buf_len;
++
++ error = sthcd_pep_setup_xfer(pep);
++ if (error)
++ retval = error;
++ }
++
++ if (retval < 0)
++ DBG("%s: retval=%d (%x)\n", __func__, retval, retval);
++ return retval;
++}
++
++/*
++ *
++ * Context: interrupts disabled, hcd lock held
++ */
++static int sthcd_pep_setup_first_xfer(struct sthcd_pep *pep)
++{
++ struct urb *urb = pep->urb;
++ int retval;
++ int error;
++
++ pep->io_xfer_offset = 0;
++ pep->io_buf_len = urb->transfer_buffer_length;
++ if (pep->io_buf_len > STHCD_MAX_CHUNK_SIZE)
++ pep->io_buf_len = STHCD_MAX_CHUNK_SIZE;
++
++ retval = pep->io_buf_len;
++
++ error = sthcd_pep_setup_xfer(pep);
++ if (error)
++ retval = error;
++
++ if (retval < 0)
++ DBG("%s: retval=%d (%x)\n", __func__, retval, retval);
++ return retval;
++}
++
++/*
++ *
++ * Context: interrupts disabled, hcd lock held
++ */
++static void sthcd_pep_finish_xfer(struct sthcd_pep *pep, int xfer_len)
++{
++ struct urb *urb = pep->urb;
++
++ if (xfer_len <= 0)
++ goto done;
++
++ BUG_ON(!urb);
++ BUG_ON(!pep->io_buf);
++
++ /*
++ * For IN transfers, copy the received chunk data into the urb
++ * xfer buffer.
++ */
++ if (usb_urb_dir_in(urb)) {
++ /* device -> host */
++ BUG_ON(!urb->transfer_buffer);
++ memcpy(urb->transfer_buffer + pep->io_xfer_offset,
++ pep->io_buf, xfer_len);
++ }
++
++ pep->io_xfer_offset += xfer_len;
++
++done:
++ return;
++}
++
++static int sthcd_pep_xfer_callback(struct starlet_ipc_request *req);
++
++/*
++ *
++ * Context: interrupts disabled, hcd lock held
++ */
++static int sthcd_pep_start_xfer(struct sthcd_pep *pep)
++{
++ struct urb *urb = pep->urb;
++ struct sthcd_udev *udev = pep->udev;
++ int error;
++
++ BUG_ON(!urb);
++
++ /* udev was disconnected */
++ if (unlikely(!udev)) {
++ error = -ENODEV;
++ goto done;
++ }
++
++ if (!pep_is_enabled(pep)) {
++ error = -ESHUTDOWN;
++ goto done;
++ }
++
++ /* for OUT transfers, copy the data to send into the pep xfer buffer */
++ if (pep->io_buf_len > 0) {
++ if (usb_urb_dir_out(urb)) {
++ /* host -> device */
++ BUG_ON(!urb->transfer_buffer);
++ memcpy(pep->io_buf,
++ urb->transfer_buffer + pep->io_xfer_offset,
++ pep->io_buf_len);
++ }
++ }
++
++ starlet_ioh_sg_set_buf(&pep->io[0],
++ pep->io_buf, pep->io_buf_len);
++
++ /* start an async transfer */
++ error = starlet_ioh_ioctlv_nowait(udev->fd, pep->request,
++ pep->nents_in, pep->in, 1, pep->io,
++ sthcd_pep_xfer_callback, pep);
++ if (!error)
++ pep->outstanding++;
++
++done:
++ if (error < 0)
++ DBG("%s: error=%d (%x)\n", __func__, error, error);
++ return error;
++}
++
++/*
++ *
++ * Context: interrupts disabled, hcd lock held
++ */
++static int sthcd_giveback_urb(struct sthcd_hcd *sthcd,
++ struct urb *urb, int status)
++__releases(sthcd->lock) __acquires(sthcd->lock)
++{
++ struct usb_hcd *hcd = sthcd_to_hcd(sthcd);
++
++ /*
++ * Release the hcd lock here as the callback may need to
++ * hold it again.
++ */
++ spin_unlock(&sthcd->lock);
++ usb_hcd_giveback_urb(hcd, urb, status);
++ spin_lock(&sthcd->lock);
++
++ return status;
++}
++
++/*
++ *
++ * Context: interrupts disabled, hcd lock held
++ */
++struct urb *sthcd_find_next_urb_in_ep(struct usb_host_endpoint *ep)
++{
++ if (list_empty(&ep->urb_list))
++ return NULL;
++ else
++ return list_first_entry(&ep->urb_list, struct urb, urb_list);
++}
++
++static int sthcd_pep_send_urb(struct sthcd_pep *pep, struct urb *urb);
++
++/*
++ *
++ * Context: interrupts disabled, hcd lock held
++ */
++static int sthcd_pep_cond_send_next_urb(struct sthcd_pep *pep)
++{
++ struct urb *urb;
++ int retval = 0;
++ int error;
++
++ /* schedule next urb if any */
++ urb = sthcd_find_next_urb_in_ep(pep->ep);
++ if (urb) {
++ error = sthcd_pep_send_urb(pep, urb);
++ if (!error) {
++ retval = 1;
++ goto done;
++ } else {
++ retval = error;
++ }
++ }
++done:
++ if (retval < 0)
++ DBG("%s: retval=%d (%x)\n", __func__, retval, retval);
++ return retval;
++}
++
++/*
++ *
++ * Context: interrupts disabled, hcd lock held
++ */
++static int sthcd_pep_send_urb(struct sthcd_pep *pep, struct urb *urb)
++{
++ struct sthcd_port *port = NULL;
++ struct sthcd_hcd *sthcd;
++ struct usb_ctrlrequest *req;
++ u16 typeReq, wValue;
++ int retval, fake;
++ int error;
++
++ /*
++ * Unconditionally fail urbs targetted at doomed ports.
++ */
++ if (pep->udev) {
++ port = udev_to_port(pep->udev);
++ if (test_bit(__STHCD_PORT_DOOMED, &port->flags)) {
++ error = -ENODEV;
++ goto done;
++ }
++ }
++
++ if (test_and_set_bit(__STHCD_PEP_XFERBUSY, &pep->flags)) {
++ /*
++ * There is a pep xfer in progress.
++ * Our urb is already queued on the usb device, so do nothing
++ * here and rely on the pep xfer callback to do the actual
++ * work when it's done with the current urb in flight.
++ */
++ error = 0;
++ goto done;
++ }
++
++ /* we can have one ongoing urb only */
++ error = sthcd_pep_takein_urb(pep, urb);
++ if (error)
++ goto done;
++
++ urb->hcpriv = urb; /* mark urb in use */
++
++ retval = sthcd_pep_setup_first_xfer(pep);
++ if (retval < 0) {
++ error = retval;
++ goto err_setup_xfer;
++ }
++
++ fake = 0;
++ if (pep->request == STHCD_IOCTLV_CONTROLREQ) {
++ req = (struct usb_ctrlrequest *)urb->setup_packet;
++ typeReq = (req->bRequestType << 8) | req->bRequest;
++ wValue = le16_to_cpu(req->wValue);
++
++ switch (typeReq) {
++ case DeviceOutRequest | USB_REQ_SET_ADDRESS: /* 0005 */
++ if (urb->dev->devnum != 0) {
++ /* REVISIT, never reached */
++ drv_printk(KERN_WARNING,
++ "address change %u->%u\n",
++ urb->dev->devnum, wValue);
++ }
++ /*
++ * We are guaranteed to have an udev because the takein
++ * was successful.
++ */
++ pep->udev->devnum = wValue;
++ urb->actual_length = 0;
++
++ /* clear the port reset count, we have an address */
++ if (wValue) {
++ /*
++ * We need to retrieve the port again
++ * as we might have entered the function
++ * without an udev assigned to the pep.
++ */
++ port = udev_to_port(pep->udev);
++ port->nr_resets = 0;
++ }
++ fake = 1;
++ break;
++ default:
++ break;
++ }
++ }
++
++ if (fake) {
++ sthcd = pep->sthcd;
++ /* finish this fake urb synchronously... */
++ usb_hcd_unlink_urb_from_ep(sthcd_to_hcd(sthcd), urb);
++ sthcd_giveback_urb(sthcd, urb, 0);
++ /* ... and proceed with the next urb, if applicable */
++ sthcd_pep_cond_send_next_urb(pep);
++ } else {
++ /* allocate an io buffer for this transfer */
++ error = sthcd_pep_alloc_xfer_io_buf(pep, pep->io_buf_len);
++ if (error)
++ goto err_alloc_io_buf;
++
++ /* ... and start the first transfer */
++ error = sthcd_pep_start_xfer(pep);
++ if (error)
++ goto err_start_xfer;
++ }
++
++ return 0;
++
++err_start_xfer:
++ sthcd_pep_free_xfer_io_buf(pep);
++err_alloc_io_buf:
++err_setup_xfer:
++ sthcd_pep_takeout_urb(pep);
++ urb->hcpriv = NULL;
++done:
++ if (error < 0)
++ DBG("%s: error=%d (%x)\n", __func__, error, error);
++ return error;
++}
++
++static void sthcd_pep_print(struct sthcd_pep *pep)
++{
++ struct usb_device *udev;
++ u16 idVendor, idProduct;
++
++ idVendor = idProduct = 0xffff;
++ if (pep->urb) {
++ udev = pep->urb->dev;
++ if (udev) {
++ idVendor = le16_to_cpu(udev->descriptor.idVendor);
++ idProduct = le16_to_cpu(udev->descriptor.idProduct);
++ }
++ }
++ DBG("(%04X:%04X) request=%d,"
++ " io_buf=%p, io_buf_len=%u, io_xfer_offset=%u\n",
++ idVendor, idProduct,
++ pep->request,
++ pep->io_buf,
++ pep->io_buf_len,
++ pep->io_xfer_offset);
++}
++
++/*
++ *
++ * Context: in interrupt
++ */
++static int sthcd_pep_xfer_callback(struct starlet_ipc_request *req)
++{
++ int xfer_len = req->result;
++ struct sthcd_pep *pep = req->done_data;
++ int status = 0;
++ struct sthcd_port *port;
++ struct sthcd_hcd *sthcd;
++ struct usb_hcd *hcd;
++ struct urb *urb;
++ int retval;
++ unsigned long flags;
++ int error;
++
++ starlet_ipc_free_request(req);
++
++ sthcd = pep->sthcd;
++ spin_lock_irqsave(&sthcd->lock, flags);
++
++ hcd = sthcd_to_hcd(sthcd);
++
++ pep->outstanding--;
++
++ urb = pep->urb;
++ if (!urb) {
++ /*
++ * starlet completed an URB that was already dequeued.
++ *
++ * We must free here the memory used by the pep, including
++ * I/O buffers, avoiding dereferencing any USB stack data
++ * pointed by the pep, as it may be invalid now.
++ */
++ sthcd_pep_free_xfer_io_buf(pep);
++ sthcd_pep_free(pep);
++ goto done;
++ }
++
++ /* sanity checks, determine transfer status and length */
++ if (xfer_len < 0) {
++ status = xfer_len;
++ xfer_len = 0;
++
++ if (status != -7004 && status != -7003 && status != -7005) {
++ drv_printk(KERN_ERR, "request completed"
++ " with error %d\n", status);
++ sthcd_pep_print(pep);
++ }
++
++ switch (status) {
++ case -7003:
++ case -7004:
++ /* endpoint stall */
++ status = -EPIPE;
++ break;
++ case -7005:
++ /* nak? */
++ status = -ECONNRESET;
++ break;
++ case -7008:
++ case -7022:
++ case -4:
++ /* FALL-THROUGH */
++ default:
++ /*
++ * We got an unknown, probably un-retryable, error.
++ * Flag the port as unuseable. The associated
++ * device will be disconnected ASAP.
++ */
++ port = udev_to_port(pep->udev);
++ set_bit(__STHCD_PORT_DOOMED, &port->flags);
++ DBG("%s: error %d on port %d, doomed!\n", __func__,
++ status, port - pep->sthcd->ports + 1);
++
++ /* also, do not use the pep for xfers anymore */
++ set_bit(__STHCD_PEP_DISABLED, &pep->flags);
++ status = -ENODEV;
++ break;
++ }
++ } else {
++ if (usb_pipecontrol(urb->pipe)) {
++ /*
++ * starlet includes the length of the request
++ * into the reply for control transfers.
++ * We need to substract the request size from
++ * the reply len to get the actual data size.
++ */
++ xfer_len -= sizeof(struct usb_ctrlrequest);
++ if (xfer_len < 0) {
++ drv_printk(KERN_ERR, "request incomplete,"
++ " %d bytes short\n",
++ -xfer_len);
++ status = -EPIPE;
++ xfer_len = 0;
++ }
++ }
++ if (xfer_len > pep->io_buf_len) {
++ DBG("%s: xfer len %u larger than xfer buf"
++ " len %u\n", __func__,
++ xfer_len, pep->io_buf_len);
++ xfer_len = pep->io_buf_len;
++ }
++
++ }
++
++ if (xfer_len > 0) {
++ sthcd_pep_finish_xfer(pep, xfer_len);
++
++ /*
++ * Only schedule the next chunk if we didn't get a short xfer
++ * and the pep is still active
++ */
++ if (xfer_len == pep->io_buf_len && pep_is_enabled(pep)) {
++ retval = sthcd_pep_setup_next_xfer(pep);
++ if (retval <= 0) {
++ /* an error happened or all chunks were done */
++ status = retval;
++ } else {
++ /* next xfer */
++ sthcd_pep_start_xfer(pep);
++ goto done;
++ }
++ }
++ }
++
++ sthcd_pep_free_xfer_io_buf(pep);
++ urb->actual_length = pep->io_xfer_offset;
++
++ /* at this point, we are done with this urb */
++ clear_bit(__STHCD_PEP_XFERBUSY, &pep->flags);
++
++ sthcd_pep_takeout_urb(pep);
++
++ BUG_ON(!sthcd);
++ BUG_ON(!urb);
++
++ error = usb_hcd_check_unlink_urb(hcd, urb, status);
++ if (!error) {
++ usb_hcd_unlink_urb_from_ep(hcd, urb);
++
++ /* give back this urb */
++ sthcd_giveback_urb(sthcd, urb, status);
++ } else {
++ /* REVISIT, paranoid */
++ DBG("%s: error checking unlink\n", __func__);
++ }
++
++ /* if applicable, launch the next urb in this endpoint queue */
++ sthcd_pep_cond_send_next_urb(pep);
++
++done:
++ spin_unlock_irqrestore(&sthcd->lock, flags);
++
++ return 0;
++}
++
++
++/*
++ * starlet USB device "udev" abstraction.
++ *
++ *
++ */
++
++
++static struct sthcd_udev *sthcd_get_free_udev(struct sthcd_hcd *sthcd)
++{
++ struct sthcd_port *port;
++ struct sthcd_udev *udev;
++ int i;
++
++ port = sthcd->ports;
++ for (i = 0; i < sthcd->nr_ports; i++, port++) {
++ udev = &port->udev;
++ if (!test_and_set_bit(__STHCD_PORT_INUSE, &port->flags))
++ return udev;
++ }
++ return NULL;
++}
++
++static struct sthcd_udev *sthcd_find_udev_by_ids(struct sthcd_hcd *sthcd,
++ u16 idVendor, u16 idProduct)
++{
++ struct sthcd_udev *udev;
++
++ list_for_each_entry(udev, &sthcd->device_list, node) {
++ if (udev->idVendor == idVendor && udev->idProduct == idProduct)
++ return udev;
++ }
++ return NULL;
++}
++
++#if 0
++static int sthcd_udev_suspend(struct sthcd_udev *udev)
++{
++ int error;
++
++ error = starlet_ioctl(udev->fd, STHCD_IOCTL_SUSPENDDEVICE,
++ NULL, 0, NULL, 0);
++ if (error < 0)
++ DBG("%s: error=%d (%x)\n", __func__, error, error);
++ return error;
++}
++
++static int sthcd_udev_resume(struct sthcd_udev *udev)
++{
++ int error;
++
++ error = starlet_ioctl(udev->fd, STHCD_IOCTL_RESUMEDEVICE,
++ NULL, 0, NULL, 0);
++ if (error < 0)
++ DBG("%s: error=%d (%x)\n", __func__, error, error);
++ return error;
++}
++#endif
++
++static int sthcd_udev_close(struct sthcd_udev *udev)
++{
++ int fd = udev->fd;
++
++ udev->fd = -1;
++ return starlet_close(fd);
++}
++
++static int sthcd_udev_open(struct sthcd_udev *udev)
++{
++ struct sthcd_oh *oh = udev->oh;
++ char pathname[32];
++ int error;
++
++ if (udev->fd != -1) {
++ drv_printk(KERN_WARNING, "udev %04X.%04X already opened,"
++ " closing it first\n",
++ udev->idVendor, udev->idProduct);
++ sthcd_udev_close(udev);
++ }
++
++ snprintf(pathname, sizeof(pathname), "/dev/usb/oh%u/%04x/%04x",
++ oh->index, udev->idVendor, udev->idProduct);
++ error = starlet_open(pathname, 0);
++ if (error < 0) {
++ drv_printk(KERN_ERR, "open %s failed\n", pathname);
++ return error;
++ }
++ udev->fd = error;
++
++ return 0;
++}
++
++static void sthcd_udev_exit(struct sthcd_udev *udev)
++{
++ struct sthcd_hcd *sthcd;
++ struct sthcd_pep *pep;
++ unsigned long flags;
++
++ sthcd = udev->oh->hcd;
++
++ spin_lock_irqsave(&sthcd->lock, flags);
++
++ /* remove from the list of connected devices */
++ list_del_init(&udev->node);
++
++ /* unlink all associated peps */
++ list_for_each_entry(pep, &udev->pep_list, node) {
++ if (pep->udev) {
++ pep->udev = NULL;
++ list_del_init(&pep->node);
++ }
++ }
++
++ spin_unlock_irqrestore(&sthcd->lock, flags);
++
++ sthcd_udev_close(udev);
++
++ udev->idVendor = 0;
++ udev->idProduct = 0;
++ udev->oh = NULL;
++ udev->devnum = 0;
++}
++
++static int sthcd_udev_init(struct sthcd_udev *udev,
++ struct sthcd_oh *oh,
++ u16 idVendor, u16 idProduct)
++{
++ struct sthcd_hcd *sthcd = oh->hcd;
++ int error;
++ unsigned long flags;
++
++ INIT_LIST_HEAD(&udev->pep_list);
++
++ udev->idVendor = idVendor;
++ udev->idProduct = idProduct;
++ udev->oh = oh;
++ udev->fd = -1;
++ udev->devnum = 0;
++
++ error = sthcd_udev_open(udev);
++ if (error)
++ return error;
++
++ spin_lock_irqsave(&sthcd->lock, flags);
++ list_add_tail(&udev->node, &sthcd->device_list);
++ spin_unlock_irqrestore(&sthcd->lock, flags);
++
++ return error;
++}
++
++
++/*
++ * Hub emulation routines.
++ *
++ */
++
++#define STHCD_USB_DT_HUB_TOTAL_SIZE \
++ (USB_DT_HUB_NONVAR_SIZE + 2*((STHCD_MAX_PORTS + 1 + 7) / 8))
++
++static struct usb_hub_descriptor sthcd_hub_hub_descr = {
++ .bDescLength = STHCD_USB_DT_HUB_TOTAL_SIZE,
++ .bDescriptorType = USB_DT_HUB,
++ .bNbrPorts = STHCD_MAX_PORTS,
++ .wHubCharacteristics = 0x0000,
++ .bPwrOn2PwrGood = 0,
++ .bHubContrCurrent = 0,
++};
++
++
++static int
++sthcd_hub_control_standard(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
++ u16 wIndex, char *buf, u16 wLength)
++{
++ int retval = -EINVAL;
++
++ switch (typeReq) {
++ case DeviceOutRequest | USB_REQ_SET_CONFIGURATION: /* 0009 */
++ if (wValue != 1) {
++ drv_printk(KERN_INFO, "invalid configuration %d\n",
++ wValue);
++ } else {
++ retval = 0;
++ }
++ break;
++ case DeviceRequest | USB_REQ_GET_STATUS: /* 8000 */
++ if (wLength < 2) {
++ retval = -ENOMEM;
++ } else {
++ buf[0] = (1 << USB_DEVICE_SELF_POWERED);
++ buf[1] = 0;
++ retval = 2;
++ }
++ break;
++ default:
++ drv_printk(KERN_WARNING, "%s: request %04X not supported\n",
++ __func__, typeReq);
++ break;
++ }
++ DBG("%s: retval=%d (%x)\n", __func__, retval, retval);
++ return retval;
++}
++
++static int
++sthcd_hub_control_hub(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
++ u16 wIndex, void *buf, u16 wLength)
++{
++ struct sthcd_hcd *sthcd = hcd_to_sthcd(hcd);
++ struct usb_hub_status *hub_status;
++ struct usb_hub_descriptor *hub_descr;
++ size_t size, port_array_size;
++ u8 *p;
++ int retval = -EINVAL;
++
++ switch (typeReq) {
++ case GetHubStatus: /* 0xA000 */
++ size = sizeof(*hub_status);
++ if (wLength < size) {
++ retval = -ENOMEM;
++ } else {
++ hub_status = buf;
++ hub_status->wHubStatus = 0x0000; /* no problems */
++ hub_status->wHubChange = 0x0000; /* no changes */
++ retval = size;
++ }
++ break;
++ case GetHubDescriptor: /* 0xA006 */
++ /*
++ * For the DeviceRemovable and PortPwrCtrlMask fields:
++ * bit 0 is reserved.
++ * bit 1 is the internal (oh1) port, which is non-removable.
++ * bit 2..nr_ports+1 are the external (oh0) ports.
++ */
++ port_array_size = (1 + sthcd->nr_ports + 7) / 8;
++ size = USB_DT_HUB_NONVAR_SIZE + 2*port_array_size;
++
++ if (wLength < size) {
++ retval = -ENOMEM;
++ } else {
++ p = buf;
++
++ memcpy(p, &sthcd_hub_hub_descr, USB_DT_HUB_NONVAR_SIZE);
++ p += USB_DT_HUB_NONVAR_SIZE;
++
++ /* fixup the descriptor with the real number of ports */
++ hub_descr = buf;
++ hub_descr->bDescLength = size;
++ hub_descr->bNbrPorts = sthcd->nr_ports;
++
++ /* DeviceRemovable field, table 11-13 Hub Descriptor */
++ memset(p, 0, port_array_size);
++ *p |= 0x02; /* port 1 is non-removable */
++ p += port_array_size;
++
++ /* PortPwrCtrlMask field, table 11-13 Hub Descriptor */
++ memset(p, 0xff, port_array_size);
++
++ retval = size;
++ }
++ break;
++ default:
++ drv_printk(KERN_WARNING, "%s: request %04X not supported\n",
++ __func__, typeReq);
++ break;
++ }
++
++ if (retval < 0)
++ DBG("%s: retval=%d (%x)\n", __func__, retval, retval);
++ return retval;
++}
++
++
++static int
++sthcd_hub_control_port(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
++ u16 wIndex, void *buf, u16 wLength)
++{
++ struct sthcd_hcd *sthcd = hcd_to_sthcd(hcd);
++ struct sthcd_port *port;
++ unsigned long flags;
++ int retval = 0;
++
++ if (wIndex == 0 || wIndex > sthcd->nr_ports) {
++ DBG("%s: invalid port %u\n", __func__, wIndex);
++ return -EINVAL;
++ }
++
++ spin_lock_irqsave(&sthcd->lock, flags);
++
++ wIndex--;
++ port = &sthcd->ports[wIndex];
++
++ switch (typeReq) {
++ case GetPortStatus: /* 0xA300 */
++ if (test_bit(__STHCD_PORT_DOOMED, &port->flags)) {
++ /* disconnect */
++ if (!!(port->status_change & USB_PORT_STAT_CONNECTION))
++ port->status_change |=
++ (USB_PORT_STAT_C_CONNECTION<<16);
++ port->status_change &= ~USB_PORT_STAT_CONNECTION;
++ }
++ /* REVISIT wait 50ms before clearing the RESET state */
++ if (port->status_change & USB_PORT_STAT_RESET) {
++ port->nr_resets++;
++ if (port->nr_resets > 2) {
++ DBG("%s: port %d was reset %u time(s),"
++ " doomed!\n", __func__,
++ wIndex+1, port->nr_resets);
++ set_bit(__STHCD_PORT_DOOMED, &port->flags);
++ }
++ if (!(port->status_change & USB_PORT_STAT_ENABLE))
++ port->status_change |=
++ (USB_PORT_STAT_C_ENABLE << 16);
++ port->status_change &= ~USB_PORT_STAT_RESET;
++ port->status_change |= (USB_PORT_STAT_ENABLE |
++ (USB_PORT_STAT_C_RESET << 16));
++ port->udev.devnum = 0;
++ }
++ retval = 4;
++ ((__le32 *) buf)[0] = cpu_to_le32(port->status_change);
++ break;
++ case ClearPortFeature: /* 0x2301 */
++ switch (wValue) {
++ case USB_PORT_FEAT_ENABLE:
++ port->status_change &= USB_PORT_STAT_POWER;
++ break;
++ case USB_PORT_FEAT_SUSPEND:
++ case USB_PORT_FEAT_POWER:
++ case USB_PORT_FEAT_C_ENABLE:
++ case USB_PORT_FEAT_C_SUSPEND:
++ case USB_PORT_FEAT_C_CONNECTION:
++ case USB_PORT_FEAT_C_OVER_CURRENT:
++ case USB_PORT_FEAT_C_RESET: /* 0x14 */
++ break;
++ default:
++ goto error;
++ }
++ port->status_change &= ~(1 << wValue);
++ break;
++ case SetPortFeature: /* 0x2303 */
++ switch (wValue) {
++ case USB_PORT_FEAT_ENABLE:
++ case USB_PORT_FEAT_SUSPEND:
++ case USB_PORT_FEAT_POWER: /* 0x08 */
++ break;
++ case USB_PORT_FEAT_RESET: /* 0x04 */
++ /* REVISIT, free all related resources here */
++ break;
++ default:
++ goto error;
++ }
++ port->status_change |= 1 << wValue;
++ break;
++ default:
++ drv_printk(KERN_WARNING, "%s: request %04X not supported\n",
++ __func__, typeReq);
++error:
++ retval = -EPIPE;
++ break;
++ }
++
++ spin_unlock_irqrestore(&sthcd->lock, flags);
++
++ return retval;
++}
++
++static int sthcd_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
++ u16 wIndex, char *buf, u16 wLength)
++{
++ u8 bmRequestType;
++ int retval = -EINVAL;
++
++ /*
++ * starlet never answers to requests on device 0/0, so we emulate it.
++ */
++
++ bmRequestType = typeReq >> 8;
++
++ switch (bmRequestType & USB_TYPE_MASK) {
++ case USB_TYPE_STANDARD:
++ /* generic requests */
++ retval = sthcd_hub_control_standard(hcd, typeReq, wValue,
++ wIndex, buf, wLength);
++ break;
++ case USB_TYPE_CLASS:
++ /* hub-specific requests */
++ switch (bmRequestType & USB_RECIP_MASK) {
++ case USB_RECIP_DEVICE:
++ /* hub */
++ retval = sthcd_hub_control_hub(hcd, typeReq, wValue,
++ wIndex, buf, wLength);
++ break;
++ case USB_RECIP_OTHER:
++ /* port */
++ retval = sthcd_hub_control_port(hcd, typeReq, wValue,
++ wIndex, buf, wLength);
++ break;
++ default:
++ drv_printk(KERN_WARNING, "%s: request %04X"
++ " not supported\n", __func__, typeReq);
++ break;
++ }
++ break;
++ default:
++ drv_printk(KERN_WARNING, "%s: request %04X not supported\n",
++ __func__, typeReq);
++ break;
++ }
++
++ if (retval > 0)
++ retval = 0;
++ if (retval < 0)
++ DBG("%s: retval=%d (%x)\n", __func__, retval, retval);
++ return retval;
++}
++
++static int sthcd_hub_status_data(struct usb_hcd *hcd, char *buf)
++{
++ struct sthcd_hcd *sthcd = hcd_to_sthcd(hcd);
++ u16 *p = (u16 *)buf;
++ struct sthcd_port *port;
++ unsigned long flags;
++ int i, result;
++
++ if (!HC_IS_RUNNING(hcd->state))
++ return -ESHUTDOWN;
++
++#if 0
++ if (timer_pending(&hcd->rh_timer))
++ return 0;
++#endif
++
++ /* FIXME, this code assumes at least 9 and no more than 15 ports */
++ BUG_ON(sthcd->nr_ports > 15 || sthcd->nr_ports < 8);
++
++ spin_lock_irqsave(&sthcd->lock, flags);
++
++ port = sthcd->ports;
++ for (i = 0, *p = 0; i < sthcd->nr_ports; i++, port++) {
++ if ((port->status_change & 0xffff0000) != 0) {
++ *p |= 1 << (i+1);
++ /* REVISIT */
++ }
++ }
++ *p = le16_to_cpu(*p);
++ result = (*p != 0) ? 2 : 0;
++
++ spin_unlock_irqrestore(&sthcd->lock, flags);
++
++/* DBG("%s: poll cycle, changes=%04x\n", __func__, *p); */
++
++ return result;
++}
++
++
++/*
++ * "OH" abstraction.
++ *
++ */
++
++static int sthcd_oh_insert_udev(struct sthcd_oh *oh,
++ u16 idVendor, u16 idProduct)
++{
++ struct sthcd_hcd *sthcd = oh->hcd;
++ struct sthcd_udev *udev;
++ struct sthcd_port *port;
++ unsigned long flags;
++ int error;
++
++ drv_printk(KERN_INFO, "inserting device %04X.%04X\n",
++ idVendor, idProduct);
++
++ udev = sthcd_get_free_udev(sthcd);
++ if (!udev) {
++ drv_printk(KERN_ERR, "no free udevs!\n");
++ return -EBUSY;
++ }
++
++ error = sthcd_udev_init(udev, oh, idVendor, idProduct);
++ if (!error) {
++ spin_lock_irqsave(&sthcd->lock, flags);
++
++ port = udev_to_port(udev);
++ /* notify a connection event */
++ port->status_change = USB_PORT_STAT_POWER |
++ USB_PORT_STAT_CONNECTION |
++ (USB_PORT_STAT_C_CONNECTION<<16);
++
++ spin_unlock_irqrestore(&sthcd->lock, flags);
++ }
++ return error;
++}
++
++static int sthcd_oh_remove_udev(struct sthcd_oh *oh,
++ u16 idVendor, u16 idProduct)
++{
++ struct sthcd_hcd *sthcd = oh->hcd;
++ struct sthcd_udev *udev;
++ struct sthcd_port *port;
++ u32 old_status;
++ unsigned long flags;
++ int error = 0;
++
++ udev = sthcd_find_udev_by_ids(sthcd, idVendor, idProduct);
++ if (!udev) {
++ /* normally reached for ignored hubs */
++ error = -ENODEV;
++ } else {
++ drv_printk(KERN_INFO, "removing device %04X.%04X\n",
++ idVendor, idProduct);
++ sthcd_udev_exit(udev);
++
++ spin_lock_irqsave(&sthcd->lock, flags);
++
++ port = udev_to_port(udev);
++ clear_bit(__STHCD_PORT_INUSE, &port->flags);
++ clear_bit(__STHCD_PORT_DOOMED, &port->flags);
++ port->nr_resets = 0;
++ /* notify a disconnection event */
++ old_status = port->status_change;
++ port->status_change = USB_PORT_STAT_POWER;
++ if ((old_status & USB_PORT_STAT_CONNECTION) != 0)
++ port->status_change |= (USB_PORT_STAT_C_CONNECTION<<16);
++
++ spin_unlock_irqrestore(&sthcd->lock, flags);
++ }
++ return error;
++}
++
++
++/*
++ * Non-atomic context (synchronous call).
++ */
++static int sthcd_usb_control_msg(int fd,
++ __u8 request, __u8 requesttype,
++ __u16 value, __u16 index,
++ void *data, __u16 size,
++ int timeout)
++{
++ struct sthcd_ctrl_params_in *params_in;
++ struct starlet_ioh_sg in[6];
++ struct starlet_ioh_sg io[1];
++ int error;
++
++ params_in = starlet_ioh_kzalloc(sizeof(*params_in));
++ if (!params_in) {
++ error = -ENOMEM;
++ goto done;
++ }
++
++ params_in->req.bRequestType = requesttype;
++ params_in->req.bRequest = request;
++ params_in->req.wValue = cpu_to_le16p(&value);
++ params_in->req.wIndex = cpu_to_le16p(&index);
++ params_in->req.wLength = cpu_to_le16p(&size);
++ params_in->_unk1 = timeout; /* seconds? */
++
++ starlet_ioh_sg_init_table(in, 6);
++ starlet_ioh_sg_entry(&in[0], &params_in->req.bRequestType);
++ starlet_ioh_sg_entry(&in[1], &params_in->req.bRequest);
++ starlet_ioh_sg_entry(&in[2], &params_in->req.wValue);
++ starlet_ioh_sg_entry(&in[3], &params_in->req.wIndex);
++ starlet_ioh_sg_entry(&in[4], &params_in->req.wLength);
++ starlet_ioh_sg_entry(&in[5], &params_in->_unk1);
++
++ starlet_ioh_sg_init_table(io, 1);
++ starlet_ioh_sg_set_buf(&io[0], data, size);
++
++ error = starlet_ioh_ioctlv(fd, STHCD_IOCTLV_CONTROLREQ,
++ 6, in, 1, io);
++
++ starlet_ioh_kfree(params_in);
++
++ if (error > 0) {
++ /* adjust size for successful control xfers */
++ error -= sizeof(struct usb_ctrlrequest);
++ if (error < 0)
++ error = -EINVAL;
++ }
++
++done:
++ if (error < 0)
++ DBG("%s: error=%d (%x)\n", __func__, error, error);
++ return error;
++}
++
++
++static int sthcd_oh_check_hub(struct sthcd_oh *oh, u16 idVendor, u16 idProduct)
++{
++ char pathname[32];
++ struct usb_device_descriptor *descriptor;
++ int fd;
++ int i;
++ int retval;
++
++ descriptor = starlet_ioh_kzalloc(USB_DT_DEVICE_SIZE);
++ if (!descriptor) {
++ retval = -ENOMEM;
++ goto done;
++ }
++
++ snprintf(pathname, sizeof(pathname), "/dev/usb/oh%u/%04x/%04x",
++ oh->index, idVendor, idProduct);
++ retval = starlet_open(pathname, 0);
++ if (retval < 0) {
++ drv_printk(KERN_ERR, "open %s failed\n", pathname);
++ starlet_ioh_kfree(descriptor);
++ goto done;
++ }
++ fd = retval;
++
++ for (i = 0; i < 3; i++) {
++ retval = sthcd_usb_control_msg(fd, USB_REQ_GET_DESCRIPTOR,
++ USB_DIR_IN,
++ USB_DT_DEVICE << 8, 0,
++ descriptor, USB_DT_DEVICE_SIZE,
++ 0);
++ if (retval != -7005)
++ break;
++ DBG("%s: attempt %d, retval=%d (%x)\n", __func__,
++ i, retval, retval);
++ }
++
++ starlet_close(fd);
++
++ if (retval >= USB_DT_DEVICE_SIZE) {
++ /* tell if a hub was found */
++ retval = (descriptor->bDeviceClass == USB_CLASS_HUB) ? 1 : 0;
++ } else {
++ if (retval >= 0)
++ retval = -EINVAL; /* short descriptor */
++ }
++
++ starlet_ioh_kfree(descriptor);
++
++done:
++ if (retval < 0)
++ DBG("%s: retval=%d (%x)\n", __func__, retval, retval);
++ return retval;
++}
++
++struct sthcd_getdevicelist_params_in {
++ u8 devid_count;
++ u8 _type;
++};
++struct sthcd_getdevicelist_params_io {
++ u8 devid_count;
++ struct sthcd_devid devids[0];
++};
++
++static int sthcd_get_device_list(struct sthcd_hcd *sthcd, int fd,
++ struct sthcd_devid *devids, size_t nr_devids)
++{
++ struct starlet_ioh_sg in[2], io[2];
++ struct sthcd_getdevicelist_params_in *params_in;
++ struct sthcd_getdevicelist_params_io *params_io;
++ size_t size = nr_devids * sizeof(struct sthcd_devid);
++ int error;
++
++ if (!nr_devids)
++ return -EINVAL;
++
++ params_in = starlet_ioh_kzalloc(sizeof(*params_in));
++ if (!params_in)
++ return -ENOMEM;
++
++ params_io = starlet_ioh_kzalloc(sizeof(*params_io) + size);
++ if (!params_io) {
++ starlet_ioh_kfree(params_in);
++ return -ENOMEM;
++ }
++
++ params_in->devid_count = nr_devids;
++ params_in->_type = 0;
++
++ starlet_ioh_sg_init_table(in, 2);
++ starlet_ioh_sg_entry(&in[0], &params_in->devid_count);
++ starlet_ioh_sg_entry(&in[1], &params_in->_type);
++
++ starlet_ioh_sg_init_table(io, 2);
++ starlet_ioh_sg_entry(&io[0], &params_io->devid_count);
++ starlet_ioh_sg_set_buf(&io[1], &params_io->devids, size);
++
++ error = starlet_ioh_ioctlv(fd, STHCD_IOCTLV_GETDEVICELIST,
++ 2, in, 2, io);
++
++ if (error < 0) {
++ DBG("%s: error=%d (%x)\n", __func__, error, error);
++ } else {
++ memcpy(devids, params_io->devids, size);
++ error = params_io->devid_count;
++ }
++
++ starlet_ioh_kfree(params_in);
++ starlet_ioh_kfree(params_io);
++
++ return error;
++}
++
++static int sthcd_devid_match(struct sthcd_devid *id1, struct sthcd_devid *id2)
++{
++ return id1->idVendor == id2->idVendor &&
++ id1->idProduct == id2->idProduct;
++}
++
++static int sthcd_devid_find(struct sthcd_devid *haystack, size_t count,
++ struct sthcd_devid *needle)
++{
++ unsigned int i;
++
++ for (i = 0; i < count; i++) {
++ if (sthcd_devid_match(&haystack[i], needle))
++ return 1;
++ }
++ return 0;
++}
++
++static int sthcd_oh_rescan(struct sthcd_oh *oh)
++{
++ static unsigned int poll_cycles;
++ struct usb_hcd *hcd = sthcd_to_hcd(oh->hcd);
++ struct sthcd_devid *p;
++ int nr_new_devids, i;
++ int changes;
++ int error;
++
++ error = sthcd_get_device_list(oh->hcd, oh->fd, oh->new_devids,
++ oh->max_devids);
++ if (error < 0)
++ return error;
++
++ nr_new_devids = error;
++ changes = 0;
++
++ for (i = 0; i < oh->nr_devids; i++) {
++ p = &oh->devids[i];
++ if (!sthcd_devid_find(oh->new_devids, nr_new_devids, p)) {
++ /* removal */
++ error = sthcd_oh_remove_udev(oh, p->idVendor,
++ p->idProduct);
++ if (!error)
++ changes++;
++ }
++ }
++
++ for (i = 0; i < nr_new_devids; i++) {
++ p = &oh->new_devids[i];
++ if (!sthcd_devid_find(oh->devids, oh->nr_devids, p)) {
++ /* insertion */
++ error = sthcd_oh_check_hub(oh, p->idVendor,
++ p->idProduct);
++ if (error == 0) {
++ /* not a hub, register the usb device */
++ error = sthcd_oh_insert_udev(oh, p->idVendor,
++ p->idProduct);
++ if (!error)
++ changes++;
++ } else {
++ drv_printk(KERN_INFO,
++ "ignoring hub %04X.%04X\n",
++ p->idVendor, p->idProduct);
++ }
++ }
++ }
++
++ memcpy(oh->devids, oh->new_devids, nr_new_devids * sizeof(*p));
++ oh->nr_devids = nr_new_devids;
++
++ /*
++ * FIXME
++ * We ask here the USB layer to explicitly poll for root hub changes
++ * until we get at least two complete rescan cycles without changes.
++ *
++ * Otherwise, for unknown reasons, we end up missing the detection of
++ * some devices, even if the insertion/removal of these devices is
++ * properly signaled in port->status_change.
++ */
++ if (changes) {
++#if 1
++ if (!poll_cycles) {
++ hcd->poll_rh = 1;
++ usb_hcd_poll_rh_status(hcd);
++ }
++ poll_cycles = 2;
++ } else {
++ if (!poll_cycles)
++ hcd->poll_rh = 0;
++ else
++ poll_cycles--;
++#else
++ usb_hcd_poll_rh_status(hcd);
++#endif
++ }
++
++ return 0;
++}
++
++static int sthcd_oh_init(struct sthcd_oh *oh, unsigned int index,
++ struct sthcd_hcd *sthcd, size_t max_devids)
++{
++ char pathname[16];
++ int error;
++
++ if (index != 0 && index != 1)
++ return -EINVAL;
++
++ snprintf(pathname, sizeof(pathname), "/dev/usb/oh%u", index);
++ error = starlet_open(pathname, 0);
++ if (error < 0)
++ return error;
++
++ oh->fd = error;
++ oh->devids = kzalloc(2 * max_devids * sizeof(struct sthcd_devid),
++ GFP_KERNEL);
++ if (!oh->devids) {
++ starlet_close(oh->fd);
++ return -ENOMEM;
++ }
++
++ oh->new_devids = oh->devids + max_devids;
++
++ oh->max_devids = max_devids;
++ oh->nr_devids = 0;
++
++ oh->index = index;
++ oh->hcd = sthcd;
++
++ return 0;
++}
++
++static void sthcd_oh_exit(struct sthcd_oh *oh)
++{
++ starlet_close(oh->fd);
++ oh->fd = -1;
++ kfree(oh->devids);
++ oh->devids = NULL;
++}
++
++static int sthcd_rescan_thread(void *arg)
++{
++ struct sthcd_hcd *sthcd = arg;
++ struct sthcd_oh *oh;
++
++ /*
++ * REVISIT
++ * We may need to rescan oh1 if bluetooth dongle disconnects.
++ */
++
++ /* oh1 has non-removable devices only, so just scan it once */
++ sthcd_oh_rescan(&sthcd->oh[1]);
++
++ oh = &sthcd->oh[0];
++
++ while (!kthread_should_stop()) {
++ sthcd_oh_rescan(oh);
++
++ /* re-check again after the configured interval */
++ sleep_on_timeout(&sthcd->rescan_waitq,
++ STHCD_RESCAN_INTERVAL*HZ);
++ }
++ return 0;
++}
++
++
++/*
++ *
++ *
++ */
++
++static int sthcd_init(struct usb_hcd *hcd)
++{
++ return 0;
++}
++
++static int sthcd_start(struct usb_hcd *hcd)
++{
++ struct sthcd_hcd *sthcd = hcd_to_sthcd(hcd);
++ int error;
++
++ /*
++ * This is to prevent a spurious error from the kernel usb stack
++ * as we do not make use of interrupts.
++ */
++ set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags);
++
++ hcd->uses_new_polling = 1;
++
++ /* oh0 is the external bus */
++ error = sthcd_oh_init(&sthcd->oh[0], 0, sthcd, STHCD_MAX_DEVIDS);
++ if (error < 0) {
++ DBG("%s: error=%d (%x)\n", __func__, error, error);
++ return error;
++ }
++
++ /* oh1 is the internal bus, used only by the bluetooth dongle */
++ error = sthcd_oh_init(&sthcd->oh[1], 1, sthcd, 1);
++ if (error < 0) {
++ DBG("%s: error=%d (%x)\n", __func__, error, error);
++ sthcd_oh_exit(&sthcd->oh[0]);
++ return error;
++ }
++
++ hcd->state = HC_STATE_RUNNING;
++
++ /* device insertion/removal is managed by the rescan thread */
++ sthcd->rescan_task = kthread_run(sthcd_rescan_thread, sthcd, "ksthcd");
++ if (IS_ERR(sthcd->rescan_task))
++ drv_printk(KERN_ERR, "failed to start rescan thread\n");
++
++ return 0;
++}
++
++static void sthcd_stop(struct usb_hcd *hcd)
++{
++ struct sthcd_hcd *sthcd = hcd_to_sthcd(hcd);
++
++ if (!IS_ERR(sthcd->rescan_task)) {
++ kthread_stop(sthcd->rescan_task);
++ sthcd->rescan_task = ERR_PTR(-EINVAL);
++ }
++
++ sthcd_oh_exit(&sthcd->oh[0]);
++ sthcd_oh_exit(&sthcd->oh[1]);
++
++ hcd->state &= ~HC_STATE_RUNNING;
++}
++
++static int sthcd_get_frame_number(struct usb_hcd *hcd)
++{
++ DBG("%s: CALLED\n", __func__);
++ return 0;
++}
++
++
++static int sthcd_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
++ gfp_t mem_flags)
++{
++ struct sthcd_hcd *sthcd = hcd_to_sthcd(hcd);
++ struct usb_host_endpoint *ep;
++ struct sthcd_pep *pep;
++ unsigned long flags;
++ int error;
++
++ spin_lock_irqsave(&sthcd->lock, flags);
++
++ /* REVISIT, paranoid */
++ if (urb->status != -EINPROGRESS) {
++ DBG("%s: status != -EINPROGRESS\n", __func__);
++ error = urb->status;
++ goto done;
++ }
++
++ error = usb_hcd_link_urb_to_ep(hcd, urb);
++ if (error)
++ goto done;
++
++ ep = urb->ep;
++
++ /* allocate a pep for each endpoint on first use */
++ if (!ep->hcpriv) {
++ pep = sthcd_pep_alloc(sthcd, ep);
++ if (!pep) {
++ error = -ENOMEM;
++ goto err_linked;
++ }
++ ep->hcpriv = pep;
++ } else {
++ pep = ep->hcpriv;
++ }
++
++ error = sthcd_pep_send_urb(pep, urb);
++ if (!error)
++ goto done;
++
++err_linked:
++ usb_hcd_unlink_urb_from_ep(hcd, urb);
++done:
++ spin_unlock_irqrestore(&sthcd->lock, flags);
++ return error;
++}
++
++static int sthcd_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
++{
++ struct sthcd_hcd *sthcd = hcd_to_sthcd(hcd);
++ struct usb_host_endpoint *ep;
++ struct sthcd_pep *pep;
++ unsigned long flags;
++ int error;
++
++ spin_lock_irqsave(&sthcd->lock, flags);
++
++ error = usb_hcd_check_unlink_urb(hcd, urb, status);
++ if (error)
++ goto done;
++
++ ep = urb->ep;
++ pep = ep_to_pep(ep);
++ if (pep && pep->urb == urb) {
++ /*
++ * There is an urb in flight.
++ *
++ * We deattach the urb from the pep and leave the pep to the
++ * callback function, which will free it upon completion,
++ * without further action.
++ */
++ sthcd_pep_takeout_urb(pep);
++ ep->hcpriv = NULL;
++ }
++
++ usb_hcd_unlink_urb_from_ep(hcd, urb);
++ sthcd_giveback_urb(sthcd, urb, status);
++
++done:
++ spin_unlock_irqrestore(&sthcd->lock, flags);
++
++#if 0
++ if (error < 0)
++ DBG("%s: error=%d (%x)\n", __func__, error, error);
++#endif
++ return error;
++}
++
++static void sthcd_endpoint_disable(struct usb_hcd *hcd,
++ struct usb_host_endpoint *ep)
++{
++ struct sthcd_hcd *sthcd = hcd_to_sthcd(hcd);
++ struct sthcd_pep *pep;
++ unsigned long flags;
++
++ spin_lock_irqsave(&sthcd->lock, flags);
++ pep = ep->hcpriv;
++
++ /* do nothing if the pep was already freed */
++ if (!pep)
++ goto done;
++
++ if (pep->urb) {
++ /*
++ * There is an urb in flight.
++ *
++ * Disable the private endpoint and take the urb out of it.
++ * The callback function will take care of freeing the pep
++ * when the starlet call completes.
++ */
++ set_bit(__STHCD_PEP_DISABLED, &pep->flags);
++ sthcd_pep_takeout_urb(pep);
++ } else {
++ /* the pep can be freed immediately when no urb is in flight */
++ sthcd_pep_free(pep);
++ }
++ ep->hcpriv = NULL;
++
++done:
++ spin_unlock_irqrestore(&sthcd->lock, flags);
++}
++
++
++static const struct hc_driver starlet_hc_driver = {
++ .description = DRV_MODULE_NAME,
++ .product_desc = "Nintendo Wii USB Host Controller",
++ .hcd_priv_size = sizeof(struct sthcd_hcd),
++
++ .irq = NULL,
++ .flags = HCD_USB11,
++
++ /* REVISIT, power management calls not yet supported */
++
++ .reset = sthcd_init,
++ .start = sthcd_start,
++ .stop = sthcd_stop,
++
++ .get_frame_number = sthcd_get_frame_number,
++
++ .urb_enqueue = sthcd_urb_enqueue,
++ .urb_dequeue = sthcd_urb_dequeue,
++ .endpoint_disable = sthcd_endpoint_disable,
++
++ .hub_status_data = sthcd_hub_status_data,
++ .hub_control = sthcd_hub_control,
++};
++
++static int __devinit sthcd_driver_probe(struct device *dev)
++{
++ struct sthcd_hcd *sthcd;
++ struct usb_hcd *hcd;
++ int error = -ENOMEM;
++
++ /*
++ * We can't use normal dma as starlet requires MEM2 buffers
++ * to work properly in all cases.
++ */
++ dev->dma_mask = NULL;
++
++ hcd = usb_create_hcd(&starlet_hc_driver, dev, DRV_MODULE_NAME);
++ if (!hcd)
++ goto err;
++
++ sthcd = hcd_to_sthcd(hcd);
++ spin_lock_init(&sthcd->lock);
++
++ sthcd->nr_ports = STHCD_MAX_PORTS;
++ sthcd->ports = kzalloc(sthcd->nr_ports * sizeof(struct sthcd_port),
++ GFP_KERNEL);
++ if (!sthcd->ports)
++ goto err_alloc_ports;
++
++ INIT_LIST_HEAD(&sthcd->device_list);
++ init_waitqueue_head(&sthcd->rescan_waitq);
++
++ error = usb_add_hcd(hcd, 0, 0);
++ if (error) {
++ drv_printk(KERN_INFO, "%s: error %d adding hcd\n",
++ __func__, error);
++ goto err_add;
++ }
++
++ return 0;
++
++err_add:
++ kfree(sthcd->ports);
++err_alloc_ports:
++ usb_put_hcd(hcd);
++err:
++ return error;
++}
++
++static int __devexit sthcd_driver_remove(struct device *dev)
++{
++ struct usb_hcd *hcd = dev_get_drvdata(dev);
++ usb_remove_hcd(hcd);
++ usb_put_hcd(hcd);
++ return 0;
++}
++
++
++/*
++ * Open Firmware platform device routines
++ *
++ */
++
++static int __init sthcd_of_probe(struct of_device *odev,
++ const struct of_device_id *match)
++{
++ return sthcd_driver_probe(&odev->dev);
++}
++
++static int __exit sthcd_of_remove(struct of_device *odev)
++{
++ return sthcd_driver_remove(&odev->dev);
++}
++
++static struct of_device_id sthcd_of_match[] = {
++ { .compatible = "nintendo,starlet-hcd" },
++ { },
++};
++
++MODULE_DEVICE_TABLE(of, sthcd_of_match);
++
++static struct of_platform_driver sthcd_of_driver = {
++ .owner = THIS_MODULE,
++ .name = DRV_MODULE_NAME,
++ .match_table = sthcd_of_match,
++ .probe = sthcd_of_probe,
++ .remove = sthcd_of_remove,
++};
++
++
++/*
++ * Linux module framework
++ *
++ */
++
++static int __init sthcd_module_init(void)
++{
++ if (usb_disabled())
++ return -ENODEV;
++
++ drv_printk(KERN_INFO, "%s - version %s\n", DRV_DESCRIPTION,
++ sthcd_driver_version);
++
++ return of_register_platform_driver(&sthcd_of_driver);
++}
++
++static void __exit sthcd_module_exit(void)
++{
++ of_unregister_platform_driver(&sthcd_of_driver);
++}
++
++module_init(sthcd_module_init);
++module_exit(sthcd_module_exit);
++
++MODULE_AUTHOR(DRV_AUTHOR);
++MODULE_DESCRIPTION(DRV_DESCRIPTION);
++MODULE_LICENSE("GPL");
++
+diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
+index 3f3ce13..3e86331 100644
+--- a/drivers/video/Kconfig
++++ b/drivers/video/Kconfig
+@@ -1704,6 +1704,21 @@ config CARMINE_DRAM_CUSTOM
+ Use custom board timings.
+ endchoice
+
++config FB_GAMECUBE
++ bool "Nintendo GameCube/Wii frame buffer"
++ depends on FB && GAMECUBE_COMMON
++ select FB_CFB_FILLRECT
++ select FB_CFB_COPYAREA
++ select FB_CFB_IMAGEBLIT
++ help
++ This is the frame buffer device driver for the Nintendo GameCube.
++
++config FB_GAMECUBE_GX
++ bool "Nintendo GameCube hardware accelerated graphics support"
++ depends on FB_GAMECUBE && GAMECUBE && BROKEN
++ help
++ Say Y here to support the 3D hardware found in the Nintendo GameCube.
++
+ config FB_AU1100
+ bool "Au1100 LCD Driver"
+ depends on (FB = y) && MIPS && SOC_AU1100
+diff --git a/drivers/video/Makefile b/drivers/video/Makefile
+index e39e33e..45c7d0c 100644
+--- a/drivers/video/Makefile
++++ b/drivers/video/Makefile
+@@ -123,6 +123,8 @@ obj-$(CONFIG_FB_OMAP) += omap/
+ obj-$(CONFIG_XEN_FBDEV_FRONTEND) += xen-fbfront.o
+ obj-$(CONFIG_FB_CARMINE) += carminefb.o
+ obj-$(CONFIG_FB_MB862XX) += mb862xx/
++obj-$(CONFIG_FB_GAMECUBE) += gcnfb.o
++obj-$(CONFIG_FB_GAMECUBE_GX) += gcngx.o
+
+ # Platform or fallback drivers go here
+ obj-$(CONFIG_FB_UVESA) += uvesafb.o
+diff --git a/drivers/video/gcnfb.c b/drivers/video/gcnfb.c
+new file mode 100644
+index 0000000..d29fa01
+--- /dev/null
++++ b/drivers/video/gcnfb.c
+@@ -0,0 +1,1087 @@
++/*
++ * drivers/video/gcn-vifb.c
++ *
++ * Nintendo GameCube/Wii Video Interface (VI) frame buffer driver
++ * Copyright (C) 2004-2009 The GameCube Linux Team
++ * Copyright (C) 2004 Michael Steil <mist@c64.org>
++ * Copyright (C) 2004,2005 Todd Jeffreys <todd@voidpointer.org>
++ * Copyright (C) 2006,2007,2008,2009 Albert Herranz
++ *
++ * Based on vesafb (c) 1998 Gerd Knorr <kraxel@goldbach.in-berlin.de>
++ *
++ * 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/delay.h>
++#include <linux/errno.h>
++#include <linux/fb.h>
++#include <linux/init.h>
++#include <linux/interrupt.h>
++#include <linux/kernel.h>
++#include <linux/mm.h>
++#include <linux/module.h>
++#include <linux/of_platform.h>
++#include <linux/string.h>
++#include <linux/tty.h>
++#include <linux/wait.h>
++#include <linux/io.h>
++
++#define DRV_MODULE_NAME "gcn-vifb"
++#define DRV_DESCRIPTION "Nintendo GameCube/Wii Video Interface (VI) driver"
++#define DRV_AUTHOR "Michael Steil <mist@c64.org>, " \
++ "Todd Jeffreys <todd@voidpointer.org>, " \
++ "Albert Herranz"
++
++static char vifb_driver_version[] = "1.0i";
++
++#define drv_printk(level, format, arg...) \
++ printk(level DRV_MODULE_NAME ": " format , ## arg)
++
++
++/*
++ * Hardware registers.
++ */
++#define VI_DCR 0x02
++#define VI_HTR0 0x04
++#define VI_TFBL 0x1c
++#define VI_TFBR 0x20
++#define VI_BFBL 0x24
++#define VI_BFBR 0x28
++#define VI_DPV 0x2c
++
++#define VI_DI0 0x30
++#define VI_DI1 0x34
++#define VI_DI2 0x38
++#define VI_DI3 0x3C
++#define VI_DI_INT (1 << 31)
++#define VI_DI_ENB (1 << 28)
++#define VI_DI_VCT_SHIFT 16
++#define VI_DI_VCT_MASK 0x03FF0000
++#define VI_DI_HCT_SHIFT 0
++#define VI_DI_HCT_MASK 0x000003FF
++
++#define VI_VISEL 0x6e
++#define VI_VISEL_PROGRESSIVE (1 << 0)
++
++
++/*
++ * Video control data structure.
++ */
++struct vi_ctl {
++ spinlock_t lock;
++
++ void __iomem *io_base;
++ unsigned int irq;
++
++ int in_vtrace;
++ wait_queue_head_t vtrace_waitq;
++
++ int visible_page;
++ unsigned long page_address[2];
++ unsigned long flip_pending;
++
++ struct fb_info *info;
++};
++
++
++/*
++ * Video mode handling
++ */
++
++struct vi_video_mode {
++ char *name;
++ const u32 *regs;
++ int width;
++ int height;
++ int lines;
++};
++
++static const u32 vi_Mode640X480NtscYUV16[32] = {
++ 0x0F060001, 0x476901AD, 0x02EA5140, 0x00030018,
++ 0x00020019, 0x410C410C, 0x40ED40ED, 0x00435A4E,
++ 0x00000000, 0x00435A4E, 0x00000000, 0x00000000,
++ 0x110701AE, 0x10010001, 0x00010001, 0x00010001,
++ 0x00000000, 0x00000000, 0x28500100, 0x1AE771F0,
++ 0x0DB4A574, 0x00C1188E, 0xC4C0CBE2, 0xFCECDECF,
++ 0x13130F08, 0x00080C0F, 0x00FF0000, 0x00000000,
++ 0x02800000, 0x000000FF, 0x00FF00FF, 0x00FF00FF
++};
++
++static const u32 vi_Mode640x480NtscProgressiveYUV16[32] = {
++ 0x1e0c0005, 0x476901ad, 0x02ea5140, 0x00060030,
++ 0x00060030, 0x81d881d8, 0x81d881d8, 0x10000000,
++ 0x00000000, 0x00000000, 0x00000000, 0x037702b6,
++ 0x90010001, 0x00000000, 0x00000000, 0x00000000,
++ 0x00000000, 0x00000000, 0x28280100, 0x1ae771f0,
++ 0x0db4a574, 0x00c1188e, 0xc4c0cbe2, 0xfcecdecf,
++ 0x13130f08, 0x00080c0f, 0x00ff0000, 0x00010001,
++ 0x02800000, 0x000000ff, 0x00ff00ff, 0x00ff00ff,
++};
++
++static const u32 vi_Mode640X576Pal50YUV16[32] = {
++ 0x11F50101, 0x4B6A01B0, 0x02F85640, 0x00010023,
++ 0x00000024, 0x4D2B4D6D, 0x4D8A4D4C, 0x0066D480,
++ 0x00000000, 0x0066D980, 0x00000000, 0x00C901F3,
++ 0x913901B1, 0x90010001, 0x00010001, 0x00010001,
++ 0x00000000, 0x00000000, 0x28500100, 0x1AE771F0,
++ 0x0DB4A574, 0x00C1188E, 0xC4C0CBE2, 0xFCECDECF,
++ 0x13130F08, 0x00080C0F, 0x00FF0000, 0x00000000,
++ 0x02800000, 0x000000FF, 0x00FF00FF, 0x00FF00FF
++};
++
++static const u32 vi_Mode640X480Pal60YUV16[32] = {
++ 0x0F060001, 0x476901AD, 0x02EA5140, 0x00030018,
++ 0x00020019, 0x410C410C, 0x40ED40ED, 0x0066D480,
++ 0x00000000, 0x0066D980, 0x00000000, 0x00C9010F,
++ 0x910701AE, 0x90010001, 0x00010001, 0x00010001,
++ 0x00000000, 0x00000000, 0x28500100, 0x1AE771F0,
++ 0x0DB4A574, 0x00C1188E, 0xC4C0CBE2, 0xFCECDECF,
++ 0x13130F08, 0x00080C0F, 0x00FF0000, 0x00000000,
++ 0x02800000, 0x000000FF, 0x00FF00FF, 0x00FF00FF
++};
++
++static struct vi_video_mode vi_video_modes[] = {
++#define VI_VM_NTSC 0
++ [VI_VM_NTSC] = {
++ .name = "NTSC/PAL60 480i",
++ .regs = vi_Mode640X480NtscYUV16,
++ .width = 640,
++ .height = 480,
++ .lines = 525,
++ },
++#define VI_VM_NTSC_PROGRESSIVE (VI_VM_NTSC+1)
++ [VI_VM_NTSC_PROGRESSIVE] = {
++ .name = "NTSC 480p",
++ .regs = vi_Mode640x480NtscProgressiveYUV16,
++ .width = 640,
++ .height = 480,
++ .lines = 525,
++ },
++#define VI_VM_PAL50 (VI_VM_NTSC_PROGRESSIVE+1)
++ [VI_VM_PAL50] = {
++ .name = "PAL50 576i",
++ .regs = vi_Mode640X576Pal50YUV16,
++ .width = 640,
++ .height = 576,
++ .lines = 625,
++ },
++#define VI_VM_PAL60 (VI_VM_PAL50+1)
++ [VI_VM_PAL60] = {
++ /* this seems to be actually the same as NTSC 480i */
++ .name = "PAL60 480i",
++ .regs = vi_Mode640X480Pal60YUV16,
++ .width = 640,
++ .height = 480,
++ .lines = 525,
++ },
++};
++
++
++static struct fb_fix_screeninfo vifb_fix = {
++ .id = DRV_MODULE_NAME,
++ .type = FB_TYPE_PACKED_PIXELS,
++ .visual = FB_VISUAL_TRUECOLOR, /* lies, lies, lies, ... */
++ .accel = FB_ACCEL_NONE,
++};
++
++static struct fb_var_screeninfo vifb_var = {
++ .bits_per_pixel = 16,
++ .activate = FB_ACTIVATE_NOW,
++ .height = -1,
++ .width = -1,
++ .right_margin = 32,
++ .upper_margin = 16,
++ .lower_margin = 4,
++ .vsync_len = 4,
++ .vmode = FB_VMODE_INTERLACED,
++};
++
++/*
++ * setup parameters
++ */
++static struct vi_video_mode *vi_current_video_mode;
++static int ypan = 1; /* 0..nothing, 1..ypan */
++
++/* FIXME: is this really needed? */
++static u32 pseudo_palette[17];
++
++
++/* some glue to the gx side */
++static inline void gcngx_dispatch_vtrace(struct vi_ctl *ctl)
++{
++#ifdef CONFIG_FB_GAMECUBE_GX
++ gcngx_vtrace(ctl);
++#endif
++}
++
++
++/*
++ *
++ * Color space handling.
++ */
++
++/*
++ * RGB to YCbYCr conversion support bits.
++ * We are using here the ITU.BT-601 Y'CbCr standard.
++ *
++ * References:
++ * - "Colour Space Conversions" by Adrian Ford and Alan Roberts, 1998
++ * (google for coloureq.pdf)
++ *
++ */
++
++#define RGB2YUV_SHIFT 16
++#define RGB2YUV_LUMA 16
++#define RGB2YUV_CHROMA 128
++
++#define Yr ((int)(0.299 * (1<<RGB2YUV_SHIFT)))
++#define Yg ((int)(0.587 * (1<<RGB2YUV_SHIFT)))
++#define Yb ((int)(0.114 * (1<<RGB2YUV_SHIFT)))
++
++#define Ur ((int)(-0.169 * (1<<RGB2YUV_SHIFT)))
++#define Ug ((int)(-0.331 * (1<<RGB2YUV_SHIFT)))
++#define Ub ((int)(0.500 * (1<<RGB2YUV_SHIFT)))
++
++#define Vr ((int)(0.500 * (1<<RGB2YUV_SHIFT))) /* same as Ub */
++#define Vg ((int)(-0.419 * (1<<RGB2YUV_SHIFT)))
++#define Vb ((int)(-0.081 * (1<<RGB2YUV_SHIFT)))
++
++/*
++ * Converts two 16bpp rgb pixels into a dual yuy2 pixel.
++ */
++static inline uint32_t rgbrgb16toycbycr(uint16_t rgb1, uint16_t rgb2)
++{
++ register int Y1, Cb, Y2, Cr;
++ register int r1, g1, b1;
++ register int r2, g2, b2;
++ register int r, g, b;
++
++ /* fast path, thanks to bohdy */
++ if (!(rgb1 | rgb2))
++ return 0x00800080; /* black, black */
++
++ /* RGB565 */
++ r1 = ((rgb1 >> 11) & 0x1f);
++ g1 = ((rgb1 >> 5) & 0x3f);
++ b1 = ((rgb1 >> 0) & 0x1f);
++
++ /* fast (approximated) scaling to 8 bits, thanks to Masken */
++ r1 = (r1 << 3) | (r1 >> 2);
++ g1 = (g1 << 2) | (g1 >> 4);
++ b1 = (b1 << 3) | (b1 >> 2);
++
++ Y1 = clamp(((Yr * r1 + Yg * g1 + Yb * b1) >> RGB2YUV_SHIFT)
++ + RGB2YUV_LUMA, 16, 235);
++ if (rgb1 == rgb2) {
++ /* this is just another fast path */
++ Y2 = Y1;
++ r = r1;
++ g = g1;
++ b = b1;
++ } else {
++ /* same as we did for r1 before */
++ r2 = ((rgb2 >> 11) & 0x1f);
++ g2 = ((rgb2 >> 5) & 0x3f);
++ b2 = ((rgb2 >> 0) & 0x1f);
++ r2 = (r2 << 3) | (r2 >> 2);
++ g2 = (g2 << 2) | (g2 >> 4);
++ b2 = (b2 << 3) | (b2 >> 2);
++
++ Y2 = clamp(((Yr * r2 + Yg * g2 + Yb * b2) >> RGB2YUV_SHIFT)
++ + RGB2YUV_LUMA,
++ 16, 235);
++
++ r = (r1 + r2) / 2;
++ g = (g1 + g2) / 2;
++ b = (b1 + b2) / 2;
++ }
++
++ Cb = clamp(((Ur * r + Ug * g + Ub * b) >> RGB2YUV_SHIFT)
++ + RGB2YUV_CHROMA, 16, 240);
++ Cr = clamp(((Vr * r + Vg * g + Vb * b) >> RGB2YUV_SHIFT)
++ + RGB2YUV_CHROMA, 16, 240);
++
++ return (((uint8_t) Y1) << 24) | (((uint8_t) Cb) << 16) |
++ (((uint8_t) Y2) << 8) | (((uint8_t) Cr) << 0);
++}
++
++/*
++ *
++ * Video hardware support.
++ */
++
++/*
++ * Get video mode reported by hardware.
++ * 0=NTSC, 1=PAL, 2=MPAL, 3=debug
++ */
++static inline int vi_get_mode(struct vi_ctl *ctl)
++{
++ return (in_be16(ctl->io_base + VI_DCR) >> 8) & 3;
++}
++
++static inline int vi_is_mode_ntsc(struct vi_ctl *ctl)
++{
++ return vi_get_mode(ctl) == 0;
++}
++
++static inline int vi_is_mode_progressive(__u32 vmode)
++{
++ return (vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED;
++}
++
++static inline int vi_can_do_progressive(struct vi_ctl *ctl)
++{
++ return in_be16(ctl->io_base + VI_VISEL) & VI_VISEL_PROGRESSIVE;
++}
++
++static void vi_guess_mode(struct vi_ctl *ctl)
++{
++ void __iomem *io_base = ctl->io_base;
++ u16 mode;
++
++ if (vi_current_video_mode == NULL) {
++ /* auto detection */
++ if (in_be32(io_base + VI_HTR0) == 0x4B6A01B0) {
++ /* PAL50 */
++ vi_current_video_mode = vi_video_modes + VI_VM_PAL50;
++ } else {
++ /* NTSC/PAL60 */
++ mode = vi_get_mode(ctl);
++ switch (mode) {
++ case 0: /* NTSC */
++ /* check if we can support progressive */
++ vi_current_video_mode =
++ vi_video_modes +
++ (vi_can_do_progressive(ctl) ?
++ VI_VM_NTSC_PROGRESSIVE : VI_VM_NTSC);
++ break;
++ /* XXX this code is never reached */
++ case 1: /* PAL60 */
++ vi_current_video_mode =
++ vi_video_modes + VI_VM_PAL60;
++ break;
++ default: /* MPAL or DEBUG, we don't support */
++ break;
++ }
++ }
++ }
++
++ /* if we get here something wrong happened */
++ if (vi_current_video_mode == NULL) {
++ drv_printk(KERN_DEBUG, "failed to guess video mode,"
++ "using NTSC\n");
++ vi_current_video_mode = vi_video_modes + VI_VM_NTSC;
++ }
++}
++
++/*
++ * Set the address from where the video encoder will display data on screen.
++ */
++void vi_set_framebuffer(struct vi_ctl *ctl, u32 addr)
++{
++ struct fb_info *info = ctl->info;
++ void __iomem *io_base = ctl->io_base;
++
++ /* set top field */
++ out_be32(io_base + VI_TFBL, 0x10000000 | (addr >> 5));
++
++ /* set bottom field */
++ if (!vi_is_mode_progressive(info->var.vmode))
++ addr += info->fix.line_length;
++ out_be32(io_base + VI_BFBL, 0x10000000 | (addr >> 5));
++}
++
++/*
++ * Swap the visible and back pages.
++ */
++static inline void vi_flip_page(struct vi_ctl *ctl)
++{
++ ctl->visible_page ^= 1;
++ vi_set_framebuffer(ctl, ctl->page_address[ctl->visible_page]);
++
++ ctl->flip_pending = 0;
++}
++
++static void vi_enable_interrupts(struct vi_ctl *ctl, int enable)
++{
++ void __iomem *io_base = ctl->io_base;
++ u16 vtrap, htrap;
++
++ if (enable) {
++ /*
++ * The vertical retrace happens while the beam moves from
++ * the last drawn dot in the last line to the first dot in
++ * the first line.
++ */
++
++ /* XXX should we incorporate this in the video mode struct ? */
++ vtrap = vi_current_video_mode->lines;
++ htrap = vi_is_mode_ntsc(ctl) ? 430 : 433;
++
++ /* non-progressive needs interlacing */
++ if (!(vi_is_mode_progressive(ctl->info->var.vmode)
++ && vi_can_do_progressive(ctl))) {
++ vtrap /= 2;
++ }
++
++ /* first dot, first line */
++ out_be32(io_base + VI_DI0,
++ VI_DI_INT | VI_DI_ENB |
++ (1 << VI_DI_VCT_SHIFT) | (1 << VI_DI_HCT_SHIFT));
++ /* last dot, last line */
++ out_be32(io_base + VI_DI1,
++ VI_DI_INT | VI_DI_ENB |
++ (vtrap << VI_DI_VCT_SHIFT) | (htrap << VI_DI_HCT_SHIFT));
++ } else {
++ out_be32(io_base + VI_DI0, 0);
++ out_be32(io_base + VI_DI1, 0);
++ }
++ /* these two are currently not used */
++ out_be32(io_base + VI_DI2, 0);
++ out_be32(io_base + VI_DI3, 0);
++}
++
++static void vi_dispatch_vtrace(struct vi_ctl *ctl)
++{
++ unsigned long flags;
++
++ spin_lock_irqsave(&ctl->lock, flags);
++ if (ctl->flip_pending)
++ vi_flip_page(ctl);
++ spin_unlock_irqrestore(&ctl->lock, flags);
++
++ wake_up_interruptible(&ctl->vtrace_waitq);
++}
++
++static irqreturn_t vi_irq_handler(int irq, void *dev)
++{
++ struct fb_info *info = dev_get_drvdata((struct device *)dev);
++ struct vi_ctl *ctl = info->par;
++ void __iomem *io_base = ctl->io_base;
++ u32 val;
++
++ /* DI0 and DI1 are used to account for the vertical retrace */
++ val = in_be32(io_base + VI_DI0);
++ if (val & VI_DI_INT) {
++ ctl->in_vtrace = 0;
++ gcngx_dispatch_vtrace(ctl); /* backwards compatibility */
++
++ out_be32(io_base + VI_DI0, val & ~VI_DI_INT);
++ return IRQ_HANDLED;
++ }
++ val = in_be32(io_base + VI_DI1);
++ if (val & VI_DI_INT) {
++ ctl->in_vtrace = 1;
++ vi_dispatch_vtrace(ctl);
++ gcngx_dispatch_vtrace(ctl); /* backwards compatibility */
++
++ out_be32(io_base + VI_DI1, val & ~VI_DI_INT);
++ return IRQ_HANDLED;
++ }
++
++ /* currently unused, just in case */
++ val = in_be32(io_base + VI_DI2);
++ if (val & VI_DI_INT) {
++ out_be32(io_base + VI_DI2, val & ~VI_DI_INT);
++ return IRQ_HANDLED;
++ }
++ val = in_be32(io_base + VI_DI3);
++ if (val & VI_DI_INT) {
++ out_be32(io_base + VI_DI3, val & ~VI_DI_INT);
++ return IRQ_HANDLED;
++ }
++
++ return IRQ_NONE;
++}
++
++/*
++ * Linux framebuffer support routines.
++ *
++ */
++
++/*
++ * This is just a quick, dirty and cheap way of getting right colors on the
++ * linux framebuffer console.
++ */
++unsigned int vifb_writel(unsigned int rgbrgb, void *address)
++{
++ uint16_t *rgb = (uint16_t *)&rgbrgb;
++ return fb_writel_real(rgbrgb16toycbycr(rgb[0], rgb[1]), address);
++}
++
++/*
++ * Restore the video hardware to sane defaults.
++ */
++int vifb_restorefb(struct fb_info *info)
++{
++ struct vi_ctl *ctl = info->par;
++ void __iomem *io_base = ctl->io_base;
++ int i;
++ unsigned long flags;
++
++ /* set page 0 as the visible page and cancel pending flips */
++ spin_lock_irqsave(&ctl->lock, flags);
++ ctl->visible_page = 1;
++ vi_flip_page(ctl);
++ spin_unlock_irqrestore(&ctl->lock, flags);
++
++ /* initialize video registers */
++ for (i = 0; i < 7; i++) {
++ out_be32(io_base + i * sizeof(__u32),
++ vi_current_video_mode->regs[i]);
++ }
++ out_be32(io_base + VI_TFBR,
++ vi_current_video_mode->regs[VI_TFBR / sizeof(__u32)]);
++ out_be32(io_base + VI_BFBR,
++ vi_current_video_mode->regs[VI_BFBR / sizeof(__u32)]);
++ out_be32(io_base + VI_DPV,
++ vi_current_video_mode->regs[VI_DPV / sizeof(__u32)]);
++ for (i = 16; i < 32; i++) {
++ out_be32(io_base + i * sizeof(__u32),
++ vi_current_video_mode->regs[i]);
++ }
++
++ /* enable the video retrace handling */
++ vi_enable_interrupts(ctl, 1);
++
++ return 0;
++}
++EXPORT_SYMBOL(vifb_restorefb);
++
++/*
++ * FIXME: do we really need this?
++ */
++static int vifb_setcolreg(unsigned regno, unsigned red, unsigned green,
++ unsigned blue, unsigned transp, struct fb_info *info)
++{
++ /*
++ * Set a single color register. The values supplied are
++ * already rounded down to the hardware's capabilities
++ * (according to the entries in the `var' structure). Return
++ * != 0 for invalid regno.
++ */
++
++ if (regno >= info->cmap.len)
++ return 1;
++
++ switch (info->var.bits_per_pixel) {
++ case 16:
++ if (info->var.red.offset == 10) {
++ /* 1:5:5:5, not used currently */
++ ((u32 *) (info->pseudo_palette))[regno] =
++ ((red & 0xf800) >> 1) |
++ ((green & 0xf800) >> 6) | ((blue & 0xf800) >> 11);
++ } else {
++ /* 0:5:6:5 */
++ ((u32 *) (info->pseudo_palette))[regno] =
++ ((red & 0xf800)) |
++ ((green & 0xfc00) >> 5) | ((blue & 0xf800) >> 11);
++ }
++ break;
++ case 8:
++ case 15:
++ case 24:
++ case 32:
++ break;
++ }
++ return 0;
++}
++
++/*
++ * Pan the display by altering the framebuffer address in hardware.
++ */
++static int vifb_pan_display(struct fb_var_screeninfo *var,
++ struct fb_info *info)
++{
++ struct vi_ctl *ctl = info->par;
++ unsigned long flags;
++ int offset;
++
++ offset = (var->yoffset * info->fix.line_length) +
++ var->xoffset * (var->bits_per_pixel / 8);
++ vi_set_framebuffer(ctl, info->fix.smem_start + offset);
++
++ spin_lock_irqsave(&ctl->lock, flags);
++ ctl->visible_page = (offset) ? 1 : 0;
++ spin_unlock_irqrestore(&ctl->lock, flags);
++
++ return 0;
++}
++
++static int vifb_ioctl(struct fb_info *info,
++ unsigned int cmd, unsigned long arg)
++{
++ struct vi_ctl *ctl = info->par;
++ void __user *argp;
++ unsigned long flags;
++ int page;
++
++ switch (cmd) {
++ case FBIOWAITRETRACE:
++ interruptible_sleep_on(&ctl->vtrace_waitq);
++ return signal_pending(current) ? -EINTR : 0;
++ case FBIOFLIPHACK:
++ /*
++ * If arg == NULL then
++ * Try to flip the video page as soon as possible.
++ * Returns the current visible video page number.
++ */
++ if (!arg) {
++ spin_lock_irqsave(&ctl->lock, flags);
++ if (ctl->in_vtrace)
++ vi_flip_page(ctl);
++ else
++ ctl->flip_pending = 1;
++ spin_unlock_irqrestore(&ctl->lock, flags);
++ return ctl->visible_page;
++ }
++
++ /*
++ * If arg != NULL then
++ * Wait until the video page number pointed by arg
++ * is not visible.
++ * Returns the current visible video page number.
++ */
++ argp = (void __user *)arg;
++ if (copy_from_user(&page, argp, sizeof(int)))
++ return -EFAULT;
++
++ if (page != 0 && page != 1)
++ return -EINVAL;
++
++ spin_lock_irqsave(&ctl->lock, flags);
++ ctl->flip_pending = 0;
++ if (ctl->visible_page == page) {
++ if (ctl->in_vtrace) {
++ vi_flip_page(ctl);
++ } else {
++ ctl->flip_pending = 1;
++ spin_unlock_irqrestore(&ctl->lock, flags);
++ interruptible_sleep_on(&ctl->vtrace_waitq);
++ return signal_pending(current) ?
++ -EINTR : ctl->visible_page;
++ }
++ }
++ spin_unlock_irqrestore(&ctl->lock, flags);
++ return ctl->visible_page;
++ }
++#ifdef CONFIG_FB_GAMECUBE_GX
++ /* see if the GX module will handle it */
++ return gcngx_ioctl(info, cmd, arg);
++#else
++ return -EINVAL;
++#endif
++}
++
++/*
++ * Set the video mode according to info->var.
++ */
++static int vifb_set_par(struct fb_info *info)
++{
++ /* just load sane default here */
++ vifb_restorefb(info);
++ return 0;
++}
++
++/*
++ * Check var and eventually tweak it to something supported.
++ * Do not modify par here.
++ */
++static int vifb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
++{
++ struct vi_ctl *ctl = info->par;
++
++ /* check bpp */
++ if (var->bits_per_pixel != 16 || /* check bpp */
++ var->xres_virtual != vi_current_video_mode->width ||
++ var->xres != vi_current_video_mode->width ||
++ /* XXX isobel, do not break old sdl */
++ var->yres_virtual > 2 * vi_current_video_mode->height ||
++ var->yres > vi_current_video_mode->height ||
++ (vi_is_mode_progressive(var->vmode) &&
++ !vi_can_do_progressive(ctl))) { /* trying to set progressive? */
++ return -EINVAL;
++ }
++ return 0;
++}
++
++static int vifb_mmap(struct fb_info *info, struct vm_area_struct *vma)
++{
++ unsigned long off;
++ unsigned long start;
++ u32 len;
++
++ off = vma->vm_pgoff << PAGE_SHIFT;
++
++ /* frame buffer memory */
++ start = info->fix.smem_start;
++ len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.smem_len);
++ start &= PAGE_MASK;
++ if ((vma->vm_end - vma->vm_start + off) > len)
++ return -EINVAL;
++ off += start;
++ vma->vm_pgoff = off >> PAGE_SHIFT;
++
++ /* this is an IO map, tell maydump to skip this VMA */
++ vma->vm_flags |= VM_IO | VM_RESERVED;
++
++ /* we share RAM between the cpu and the video hardware */
++ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
++
++ if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
++ vma->vm_end - vma->vm_start,
++ vma->vm_page_prot))
++ return -EAGAIN;
++ return 0;
++}
++
++
++struct fb_ops vifb_ops = {
++ .owner = THIS_MODULE,
++ .fb_setcolreg = vifb_setcolreg,
++ .fb_pan_display = vifb_pan_display,
++ .fb_ioctl = vifb_ioctl,
++ .fb_set_par = vifb_set_par,
++ .fb_check_var = vifb_check_var,
++ .fb_mmap = vifb_mmap,
++ .fb_fillrect = cfb_fillrect,
++ .fb_copyarea = cfb_copyarea,
++ .fb_imageblit = cfb_imageblit,
++};
++
++/*
++ * Driver model helper routines.
++ *
++ */
++
++static int vifb_do_probe(struct device *dev,
++ struct resource *mem, unsigned int irq,
++ unsigned long xfb_start, unsigned long xfb_size)
++{
++ struct fb_info *info;
++ struct vi_ctl *ctl;
++
++ int video_cmap_len;
++ int err = -EINVAL;
++
++ info = framebuffer_alloc(sizeof(struct vi_ctl), dev);
++ if (!info)
++ goto err_framebuffer_alloc;
++
++ info->fbops = &vifb_ops;
++ info->var = vifb_var;
++ info->fix = vifb_fix;
++ ctl = info->par;
++ ctl->info = info;
++
++ /* first thing needed */
++ ctl->io_base = ioremap(mem->start, mem->end - mem->start + 1);
++ ctl->irq = irq;
++
++ vi_guess_mode(ctl);
++
++ info->var.xres = vi_current_video_mode->width;
++ info->var.yres = vi_current_video_mode->height;
++
++ /* enable non-interlaced if it supports progressive */
++ if (vi_can_do_progressive(ctl))
++ info->var.vmode = FB_VMODE_NONINTERLACED;
++
++ /* horizontal line in bytes */
++ info->fix.line_length = info->var.xres * (info->var.bits_per_pixel / 8);
++
++ /*
++ * Location and size of the external framebuffer.
++ */
++ info->fix.smem_start = xfb_start;
++ info->fix.smem_len = xfb_size;
++
++ if (!request_mem_region(info->fix.smem_start, info->fix.smem_len,
++ DRV_MODULE_NAME)) {
++ drv_printk(KERN_WARNING,
++ "failed to request video memory at %p\n",
++ (void *)info->fix.smem_start);
++ }
++
++ info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len);
++ if (!info->screen_base) {
++ drv_printk(KERN_ERR,
++ "failed to ioremap video memory at %p (%dk)\n",
++ (void *)info->fix.smem_start,
++ info->fix.smem_len / 1024);
++ err = -EIO;
++ goto err_ioremap;
++ }
++
++ spin_lock_init(&ctl->lock);
++ init_waitqueue_head(&ctl->vtrace_waitq);
++
++ ctl->visible_page = 0;
++ ctl->page_address[0] = info->fix.smem_start;
++ ctl->page_address[1] =
++ info->fix.smem_start + info->var.yres * info->fix.line_length;
++
++ ctl->flip_pending = 0;
++
++ drv_printk(KERN_INFO,
++ "framebuffer at 0x%p, mapped to 0x%p, size %dk\n",
++ (void *)info->fix.smem_start, info->screen_base,
++ info->fix.smem_len / 1024);
++ drv_printk(KERN_INFO,
++ "mode is %dx%dx%d, linelength=%d, pages=%d\n",
++ info->var.xres, info->var.yres,
++ info->var.bits_per_pixel,
++ info->fix.line_length,
++ info->fix.smem_len / (info->fix.line_length*info->var.yres));
++
++ info->var.xres_virtual = info->var.xres;
++ info->var.yres_virtual = info->fix.smem_len / info->fix.line_length;
++
++ if (ypan && info->var.yres_virtual > info->var.yres) {
++ drv_printk(KERN_INFO, "scrolling: pan, yres_virtual=%d\n",
++ info->var.yres_virtual);
++ } else {
++ drv_printk(KERN_INFO, "scrolling: redraw, yres_virtual=%d\n",
++ info->var.yres_virtual);
++ info->var.yres_virtual = info->var.yres;
++ ypan = 0;
++ }
++
++ info->fix.ypanstep = ypan ? 1 : 0;
++ info->fix.ywrapstep = 0;
++ if (!ypan)
++ info->fbops->fb_pan_display = NULL;
++
++ /* use some dummy values for timing to make fbset happy */
++ info->var.pixclock = 10000000 / info->var.xres * 1000 / info->var.yres;
++ info->var.left_margin = (info->var.xres / 8) & 0xf8;
++ info->var.hsync_len = (info->var.xres / 8) & 0xf8;
++
++ /* we support ony 16 bits per pixel */
++ info->var.red.offset = 11;
++ info->var.red.length = 5;
++ info->var.green.offset = 5;
++ info->var.green.length = 6;
++ info->var.blue.offset = 0;
++ info->var.blue.length = 5;
++ info->var.transp.offset = 0;
++ info->var.transp.length = 0;
++ video_cmap_len = 16;
++
++ info->pseudo_palette = pseudo_palette;
++ if (fb_alloc_cmap(&info->cmap, video_cmap_len, 0)) {
++ err = -ENOMEM;
++ goto err_alloc_cmap;
++ }
++
++ info->flags = FBINFO_FLAG_DEFAULT | (ypan) ? FBINFO_HWACCEL_YPAN : 0;
++
++ dev_set_drvdata(dev, info);
++
++ vi_enable_interrupts(ctl, 0);
++
++ err = request_irq(ctl->irq, vi_irq_handler, 0, DRV_MODULE_NAME, dev);
++ if (err) {
++ drv_printk(KERN_ERR, "unable to register IRQ %u\n", ctl->irq);
++ goto err_request_irq;
++ }
++
++ /* now register us */
++ if (register_framebuffer(info) < 0) {
++ err = -EINVAL;
++ goto err_register_framebuffer;
++ }
++
++ /* setup the framebuffer address */
++ vifb_restorefb(info);
++
++#ifdef CONFIG_FB_GAMECUBE_GX
++ err = gcngx_init(info);
++ if (err)
++ goto err_gcngx_init;
++#endif
++
++ drv_printk(KERN_INFO, "fb%d: %s frame buffer device\n",
++ info->node, info->fix.id);
++
++ return 0;
++
++#ifdef CONFIG_FB_GAMECUBE_GX
++err_gcngx_init:
++ unregister_framebuffer(info);
++#endif
++err_register_framebuffer:
++ free_irq(ctl->irq, 0);
++err_request_irq:
++ fb_dealloc_cmap(&info->cmap);
++err_alloc_cmap:
++ iounmap(info->screen_base);
++err_ioremap:
++ release_mem_region(info->fix.smem_start, info->fix.smem_len);
++
++ dev_set_drvdata(dev, NULL);
++ iounmap(ctl->io_base);
++ framebuffer_release(info);
++err_framebuffer_alloc:
++ return err;
++}
++
++static int vifb_do_remove(struct device *dev)
++{
++ struct fb_info *info = dev_get_drvdata(dev);
++ struct vi_ctl *ctl = info->par;
++
++ if (!info)
++ return -ENODEV;
++
++#ifdef CONFIG_FB_GAMECUBE_GX
++ gcngx_exit(info);
++#endif
++ free_irq(ctl->irq, dev);
++ unregister_framebuffer(info);
++ fb_dealloc_cmap(&info->cmap);
++ iounmap(info->screen_base);
++ release_mem_region(info->fix.smem_start, info->fix.smem_len);
++
++ dev_set_drvdata(dev, NULL);
++ iounmap(ctl->io_base);
++ framebuffer_release(info);
++ return 0;
++}
++
++#ifndef MODULE
++
++static int __devinit vifb_setup(char *options)
++{
++ char *this_opt;
++
++ if (!options || !*options)
++ return 0;
++
++ drv_printk(KERN_DEBUG, "options: %s\n", options);
++
++ while ((this_opt = strsep(&options, ",")) != NULL) {
++ if (!*this_opt)
++ continue;
++
++ if (!strcmp(this_opt, "redraw"))
++ ypan = 0;
++ else if (!strcmp(this_opt, "ypan"))
++ ypan = 1;
++ else if (!strcmp(this_opt, "ywrap"))
++ ypan = 2;
++ else if (!strncmp(this_opt, "tv=", 3)) {
++ if (!strncmp(this_opt + 3, "PAL", 3))
++ vi_current_video_mode =
++ vi_video_modes + VI_VM_PAL50;
++ else if (!strncmp(this_opt + 3, "NTSC", 4))
++ vi_current_video_mode =
++ vi_video_modes + VI_VM_NTSC;
++ }
++ }
++ return 0;
++}
++
++#endif /* MODULE */
++
++
++/*
++ * OF platform driver hooks.
++ *
++ */
++
++static int __init vifb_of_probe(struct of_device *odev,
++ const struct of_device_id *match)
++{
++ struct resource res;
++ const unsigned long *prop;
++ unsigned long xfb_start, xfb_size;
++ int retval;
++
++ retval = of_address_to_resource(odev->node, 0, &res);
++ if (retval) {
++ drv_printk(KERN_ERR, "no io memory range found\n");
++ return -ENODEV;
++ }
++
++ prop = of_get_property(odev->node, "xfb-start", NULL);
++ if (!prop) {
++ drv_printk(KERN_ERR, "no xfb start found\n");
++ return -ENODEV;
++ }
++ xfb_start = *prop;
++
++ prop = of_get_property(odev->node, "xfb-size", NULL);
++ if (!prop) {
++ drv_printk(KERN_ERR, "no xfb size found\n");
++ return -ENODEV;
++ }
++ xfb_size = *prop;
++
++ return vifb_do_probe(&odev->dev,
++ &res, irq_of_parse_and_map(odev->node, 0),
++ xfb_start, xfb_size);
++}
++
++static int __exit vifb_of_remove(struct of_device *odev)
++{
++ return vifb_do_remove(&odev->dev);
++}
++
++
++static struct of_device_id vifb_of_match[] = {
++ { .compatible = "nintendo,flipper-video", },
++ { .compatible = "nintendo,hollywood-video", },
++ { },
++};
++
++MODULE_DEVICE_TABLE(of, vifb_of_match);
++
++static struct of_platform_driver vifb_of_driver = {
++ .owner = THIS_MODULE,
++ .name = DRV_MODULE_NAME,
++ .match_table = vifb_of_match,
++ .probe = vifb_of_probe,
++ .remove = vifb_of_remove,
++};
++
++/*
++ * Module interface hooks
++ *
++ */
++
++static int __init vifb_init_module(void)
++{
++#ifndef MODULE
++ char *option = NULL;
++
++ if (fb_get_options(DRV_MODULE_NAME, &option)) {
++ /* for backwards compatibility */
++ if (fb_get_options("gcnfb", &option))
++ return -ENODEV;
++ }
++ vifb_setup(option);
++#endif
++
++ drv_printk(KERN_INFO, "%s - version %s\n", DRV_DESCRIPTION,
++ vifb_driver_version);
++
++ return of_register_platform_driver(&vifb_of_driver);
++}
++
++static void __exit vifb_exit_module(void)
++{
++ of_unregister_platform_driver(&vifb_of_driver);
++}
++
++module_init(vifb_init_module);
++module_exit(vifb_exit_module);
++
++MODULE_DESCRIPTION(DRV_DESCRIPTION);
++MODULE_AUTHOR(DRV_AUTHOR);
++MODULE_LICENSE("GPL");
++
+diff --git a/drivers/video/gcngx.c b/drivers/video/gcngx.c
+new file mode 100644
+index 0000000..3246617
+--- /dev/null
++++ b/drivers/video/gcngx.c
+@@ -0,0 +1,691 @@
++/*
++ * drivers/video/gcngx.c
++ *
++ * Nintendo GameCube GX driver extension
++ * Copyright (C) 2004-2007 The GameCube Linux Team
++ * Copyright (C) 2004,2005 Todd Jeffreys <todd@voidpointer.org>
++ * Copyright (C) 2007 Albert Herranz
++ *
++ * Parts borrowed heavily from libogc. This driver would not have
++ * been possible with this library. Thanks!
++ *
++ * 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.
++ *
++ */
++
++#ifdef CONFIG_FB_GAMECUBE_GX
++
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/errno.h>
++#include <linux/mm.h>
++#include <linux/fb.h>
++#include <linux/console.h>
++#include <linux/vt_kern.h>
++#include <linux/interrupt.h>
++#include <linux/wait.h>
++#include <asm/pgtable.h>
++#include <asm/atomic.h>
++#include <asm/cacheflush.h>
++
++#error This driver is broken since ARCH=powerpc changes. A rewrite is needed.
++
++#ifdef CONFIG_PPC_MERGE
++#include <platforms/embedded6xx/gamecube.h>
++#else
++#include <platforms/gamecube.h>
++#endif
++
++#include "gcngx.h"
++
++/* Function definitions */
++static inline void __GX_AckFifoInt(int isOver);
++static inline void __GX_WriteFifoIntEnable(int over,int under);
++static void gcngx_munmap(struct vm_area_struct *vma);
++static void gcngx_free_munmap(struct vm_area_struct *vma);
++static void gcngx_destroy_fifo(void);
++static void gcngx_init_fifo(void);
++
++extern void vi_set_framebuffer(struct vi_ctl *ctl, u32 addr);
++extern int gcnfb_restorefb(struct fb_info *info);
++
++extern struct fb_ops gcnfb_ops;
++
++/* Defines */
++#define mtwpar(v) mtspr(921,v)
++#define mfwpar(v) mfspr(921)
++
++#define GX_ENABLE 1
++#define GX_DISABLE 0
++#define GX_TRUE 1
++#define GX_FALSE 0
++#define _SHIFTL(v, s, w) \
++ ((u32) (((u32)(v) & ((0x01 << (w)) - 1)) << (s)))
++#define _SHIFTR(v, s, w) \
++ ((u32)(((u32)(v) >> (s)) & ((0x01 << (w)) - 1)))
++
++#define IRQ_VIDEO 8
++#define IRQ_PE_TOKEN 9
++#define IRQ_PE_FINISH 10
++#define IRQ_CP_FIFO 11
++
++#define VIDEO_MMAP_BASE 0x0C000000
++#define VIDEO_MMAP_LENGTH 0x9000
++
++#define KMALLOC_BASE 0x0D000000
++
++#define VIDEO_PE_INTERRUPT ((void __iomem *)0xcc00100a)
++#define VIDEO_PE_TOKEN ((void __iomem *)0xcc00100e)
++#define VIDEO_PE_INTERRUPT_TOKEN_ENABLE (1 << 0)
++#define VIDEO_PE_INTERRUPT_FINISH_ENABLE (1 << 1)
++#define VIDEO_PE_INTERRUPT_TOKEN_INTERRUPT (1 << 2)
++#define VIDEO_PE_INTERRUPT_FINISH_INTERRUPT (1 << 3)
++
++#define gcngx_disable_pe_interrupts() out_be16(VIDEO_PE_INTERRUPT,in_be16(VIDEO_PE_INTERRUPT) & ~(VIDEO_PE_INTERRUPT_TOKEN_ENABLE | VIDEO_PE_INTERRUPT_FINISH_ENABLE))
++#define gcngx_enable_pe_interrupts() { out_be16(VIDEO_PE_INTERRUPT,in_be16(VIDEO_PE_INTERRUPT) | (VIDEO_PE_INTERRUPT_TOKEN_ENABLE | VIDEO_PE_INTERRUPT_FINISH_ENABLE | VIDEO_PE_INTERRUPT_TOKEN_INTERRUPT | VIDEO_PE_INTERRUPT_FINISH_INTERRUPT)); out_be16(VIDEO_PE_TOKEN, 0); }
++
++#define VIDEO_CP_SR ((volatile u16 __iomem *)0xcc000000)
++#define VIDEO_CP_SR_OVERFLOW (1 << 0)
++#define VIDEO_CP_SR_UNDERFLOW (1 << 1)
++
++#define VIDEO_CP_CR ((volatile u16 __iomem *)0xcc000002)
++#define VIDEO_CP_CR_GP_FIFO_READ_ENABLE (1 << 0)
++#define VIDEO_CP_CR_CP_IRQ_ENABLE (1 << 1)
++#define VIDEO_CP_CR_OVERFLOW_IRQ_ENABLE (1 << 2)
++#define VIDEO_CP_CR_UNDERFLOW_IRQ_ENABLE (1 << 3)
++#define VIDEO_CP_CR_GP_LINK_ENABLE (1 << 4)
++#define VIDEO_CP_CR_MASK (0x1F)
++
++#define SIG_PE_FINISH (SIGRTMIN+14)
++#define SIG_PE_TOKEN (SIGRTMIN+15)
++#define SIG_VTRACE_COMPLETE (SIGRTMIN+16)
++
++#define FIFO_PUTU8(x) (*((volatile u8*) WGPIPE) = (x))
++#define FIFO_PUTU32(x) (*((volatile u32*)WGPIPE) = (x))
++
++#define LOAD_BP_REG(x) do { FIFO_PUTU8(0x61); FIFO_PUTU32(x); } while (0)
++
++/* Static data */
++static struct task_struct *mmap_task;
++static int overflow;
++static u32 xfb[2];
++static int currentFB = 0;
++static int flipRequest = 0;
++static u8 *mmap_fifo_base;
++static u8 *phys_fifo_base;
++static const u32 fifo_len = GCN_GX_FIFO_SIZE;
++static struct vm_operations_struct gcngx_vm_ops =
++{
++ .close = gcngx_munmap,
++};
++static struct vm_operations_struct gcngx_vm_free_ops =
++{
++ .close = gcngx_free_munmap,
++};
++
++static volatile u32* const _piReg = (volatile u32*)0xCC003000;
++static volatile u16* const _cpReg = (volatile u16*)0xCC000000;
++static volatile u16* const _peReg = (volatile u16*)0xCC001000;
++static volatile u16* const _memReg = (volatile u16*)0xCC004000;
++static volatile u32* const WGPIPE = (volatile u32*)0xCC008000;
++
++static irqreturn_t gcfb_fifo_irq_handler(int irq,void *dev_id)
++{
++ /* now handle the int */
++ u16 val = in_be16(VIDEO_CP_SR);
++
++ /* ENABLE_RUMBLE(); */
++
++ if (val & VIDEO_CP_SR_OVERFLOW)
++ {
++ /* fifo overflow, must halt the current application */
++ if (mmap_task)
++ {
++ printk(KERN_INFO "Man you are writing too fast! Slow down! I will make you!\n");
++ set_task_state(mmap_task,TASK_UNINTERRUPTIBLE);
++ overflow = 1;
++ }
++ __GX_AckFifoInt(1);
++ __GX_WriteFifoIntEnable(GX_DISABLE,GX_ENABLE);
++ return IRQ_HANDLED;
++ }
++ else if (val & VIDEO_CP_SR_UNDERFLOW)
++ {
++ /* underflow, resume the current application */
++ if (mmap_task && overflow)
++ {
++ printk(KERN_INFO "OK dude, the GX has crunched the data, you can resume now\n");
++ set_task_state(mmap_task,TASK_RUNNING);
++ overflow = 0;
++ }
++ __GX_AckFifoInt(0);
++ __GX_WriteFifoIntEnable(GX_ENABLE,GX_DISABLE);
++ return IRQ_HANDLED;
++ }
++ return IRQ_NONE;
++}
++
++void gcngx_vtrace(struct vi_ctl *ctl)
++{
++ struct siginfo sig;
++ /* ok flip the image if we have a flip request.
++ send signal on completion */
++ if (mmap_task && flipRequest)
++ {
++ /* do the flip! */
++ flipRequest = 0;
++ /* setup the signal info and flip buffer pointers */
++ currentFB = currentFB ? 0 : 1;
++ sig.si_errno = xfb[currentFB];
++ /* inform the hardware */
++ vi_set_framebuffer(ctl, xfb[currentFB]);
++ /* notify the process */
++ sig.si_signo = SIG_VTRACE_COMPLETE;
++ sig.si_code = 0;
++ send_sig_info(SIG_VTRACE_COMPLETE,&sig,mmap_task);
++ }
++}
++
++static irqreturn_t gcfb_pe_finish_irq_handler(int irq,void *dev_id)
++{
++ u16 val;
++ struct siginfo sig;
++ /* ack the interrupt */
++ val = in_be16(VIDEO_PE_INTERRUPT) | VIDEO_PE_INTERRUPT_FINISH_INTERRUPT;
++ out_be16(VIDEO_PE_INTERRUPT, val);
++
++ /* send SIG_PE_FINISH to the process */
++ if (mmap_task)
++ {
++ sig.si_signo = SIG_PE_FINISH;
++ sig.si_errno = 0;
++ sig.si_code = 0;
++ send_sig_info(SIG_PE_FINISH,&sig,mmap_task);
++ }
++ return IRQ_HANDLED;
++}
++
++static irqreturn_t gcfb_pe_token_irq_handler(int irq,void *dev_id)
++{
++ u16 val;
++ struct siginfo sig;
++ /* ack the interrupt */
++ val = in_be16(VIDEO_PE_INTERRUPT) | VIDEO_PE_INTERRUPT_TOKEN_INTERRUPT;
++ out_be16(VIDEO_PE_INTERRUPT, val);
++ /* send SIG_PE_TOKEN to the process */
++ if (mmap_task)
++ {
++ sig.si_signo = SIG_PE_TOKEN;
++ sig.si_errno = 0;
++ sig.si_code = _peReg[7];
++ send_sig_info(SIG_PE_TOKEN,&sig,mmap_task);
++ }
++ return IRQ_HANDLED;
++}
++
++/**
++ *
++ */
++static u32 gcngx_uvirt_to_phys(u32 virt)
++{
++ pgd_t *dir;
++ pmd_t *pmd;
++ pte_t *pte;
++ u32 ret = 0;
++ struct mm_struct *mm = get_task_mm(current);
++ u32 offset = virt & (PAGE_SIZE - 1);
++ virt &= PAGE_MASK;
++
++ if (!mm) {
++ return 0;
++ }
++ down_read(&mm->mmap_sem);
++ /* convert to kernel address */
++ if ((dir = pgd_offset(mm, virt)) && pgd_present(*dir)) {
++ if ((pmd = pmd_offset(dir, virt)) && pmd_present(*pmd)) {
++ pte = pte_offset_kernel(pmd, virt);
++ if (pte && pte_present(*pte)) {
++ ret =
++ (u32) page_address(pte_page(*pte)) + offset;
++ /* ok now we have the kern addr, map to phys */
++ ret = virt_to_phys((void *)ret);
++ }
++ }
++ }
++
++ up_read(&mm->mmap_sem);
++ mmput(mm);
++ return ret;
++}
++
++int gcngx_ioctl(struct fb_info *info,
++ unsigned int cmd, unsigned long arg)
++{
++ u32 phys;
++ void __user *argp;
++
++ if (cmd == FBIOFLIP)
++ {
++ flipRequest = 1;
++ return 0;
++ } else if (cmd == FBIOVIRTTOPHYS) {
++ argp = (void __user *)arg;
++ if (copy_from_user(&phys, argp, sizeof(void *)))
++ return -EFAULT;
++
++ phys = gcngx_uvirt_to_phys(phys);
++
++ if (copy_to_user(argp, &phys, sizeof(void *)))
++ return -EFAULT;
++ return 0;
++ }
++ return -EINVAL;
++}
++
++static void *mymalloc(unsigned int len)
++{
++ struct page *page;
++ void *p = kmalloc(len,GFP_KERNEL);
++ if (p && len)
++ {
++ /* reserve all the memory so remap_page_range works */
++ for (page=virt_to_page(p);page<virt_to_page(p+len);++page) {
++ SetPageReserved(page);
++ SetPageLocked(page);
++ }
++ }
++ return p;
++}
++
++static void myfree(void *p)
++{
++ struct page *page;
++ u32 len;
++ if (p)
++ {
++ len = ksize(p);
++ for (page=virt_to_page(p);page<virt_to_page(p+len);++page) {
++ ClearPageReserved(page);
++ ClearPageLocked(page);
++ }
++ kfree(p);
++ }
++}
++
++static void gcngx_free_munmap(struct vm_area_struct *vma)
++{
++ if (vma->vm_private_data)
++ {
++ myfree(vma->vm_private_data);
++ vma->vm_private_data = NULL;
++ }
++}
++
++static void gcngx_munmap(struct vm_area_struct *vma)
++{
++ struct fb_info *info = (struct fb_info*)vma->vm_private_data;
++ struct vc_data *vc;
++
++ gcngx_destroy_fifo();
++
++ /* nobody has up mapped anymore */
++ mmap_task = NULL;
++ overflow = 0;
++
++ /* restore the framebuffer */
++ gcnfb_restorefb(info);
++#ifdef CONFIG_FRAMEBUFFER_CONSOLE
++ acquire_console_sem();
++ vc = vc_cons[fg_console].d;
++ update_screen(vc);
++ unblank_screen();
++ release_console_sem();
++#endif
++}
++
++int gcngx_mmap(struct fb_info *info, struct vm_area_struct *vma)
++{
++ struct file *file = vma->vm_file;
++ int ret;
++// static spinlock_t lock = SPIN_LOCK_UNLOCKED;
++ u32 phys;
++ u32 len;
++
++
++ len = vma->vm_end - vma->vm_start;
++
++ if (vma->vm_pgoff == (VIDEO_MMAP_BASE >> PAGE_SHIFT) &&
++ len == VIDEO_MMAP_LENGTH)
++ {
++ /* our special case, map the memory info */
++ vma->vm_flags |= VM_IO;
++ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
++ if (io_remap_pfn_range(vma,vma->vm_start,
++ VIDEO_MMAP_BASE >> PAGE_SHIFT,
++ len,
++ vma->vm_page_prot))
++ {
++ return -EINVAL;
++ }
++ vma->vm_ops = &gcngx_vm_ops;
++ vma->vm_private_data = info;
++ /* store task for when fifo is overflown */
++ mmap_task = current;
++ overflow = 0;
++ /* init the fifo before we return */
++ gcngx_init_fifo();
++ return 0;
++ }
++ else if (vma->vm_pgoff >= (KMALLOC_BASE >> PAGE_SHIFT))
++ {
++ /* ok kmalloc the memory now */
++ vma->vm_private_data = mymalloc(len);
++ if (!vma->vm_private_data)
++ {
++ return -ENOMEM;
++ }
++ /* now setup the mapping */
++ phys = virt_to_phys(vma->vm_private_data);
++ vma->vm_flags |= (VM_RESERVED | VM_LOCKED);
++ if (remap_pfn_range(vma,vma->vm_start,
++ phys >> PAGE_SHIFT,len,vma->vm_page_prot))
++ {
++ kfree(vma->vm_private_data);
++ return -EINVAL;
++ }
++ vma->vm_ops = &gcngx_vm_free_ops;
++ /* now write the physical mapping in the first u32 */
++ *((u32*)vma->vm_private_data) = phys;
++ /* return successful */
++ return 0;
++ }
++
++ /* call the frame buffer mmap method */
++ if (file->f_op->mmap)
++ {
++ /*
++ * FIXME
++ * This seems to be broken.
++ * fb_mmap might sleep and we're getting a lock here.
++ */
++// spin_lock(&lock);
++ /* reset our mmap since the fb driver will call it */
++ gcnfb_ops.fb_mmap = NULL;
++ ret = file->f_op->mmap(file,vma);
++ /* reset our mmap */
++ gcnfb_ops.fb_mmap = gcngx_mmap;
++// spin_unlock(&lock);
++ return ret;
++ }
++ return -EINVAL;
++}
++
++static inline void __GX_AckFifoInt(int isOver)
++{
++ if (isOver)
++ _cpReg[2] |= (1 << 0);
++ else
++ _cpReg[2] |= (1 << 1);
++}
++
++static inline void __GX_Flush(void)
++{
++ /* write 8 32 bit values to the WGPIPE */
++ *WGPIPE = 0;
++ *WGPIPE = 0;
++ *WGPIPE = 0;
++ *WGPIPE = 0;
++ *WGPIPE = 0;
++ *WGPIPE = 0;
++ *WGPIPE = 0;
++ *WGPIPE = 0;
++}
++
++static inline void __GX_WriteFifoIntEnable(int over, int under)
++{
++ u16 val = _cpReg[1] & ~(VIDEO_CP_CR_GP_FIFO_READ_ENABLE |
++ VIDEO_CP_CR_CP_IRQ_ENABLE |
++ VIDEO_CP_CR_GP_LINK_ENABLE);
++
++ if (over) val |= VIDEO_CP_CR_OVERFLOW_IRQ_ENABLE;
++ if (under) val |= VIDEO_CP_CR_UNDERFLOW_IRQ_ENABLE;
++
++ _cpReg[1] = val;
++ /* ack it just for fun */
++ _cpReg[2] = 0x3;
++}
++
++static inline void __GX_FifoReadEnable(int enable)
++{
++ if (enable)
++ _cpReg[1] |= VIDEO_CP_CR_GP_FIFO_READ_ENABLE;
++ else
++ _cpReg[1] &= ~VIDEO_CP_CR_GP_FIFO_READ_ENABLE;
++}
++
++static inline void __GX_FifoLink(u8 enable)
++{
++ if (enable)
++ _cpReg[1] |= VIDEO_CP_CR_GP_LINK_ENABLE;
++ else
++ _cpReg[1] &= ~VIDEO_CP_CR_GP_LINK_ENABLE;
++}
++
++static void __GX_EnableWriteGatherPipe(u8 enable)
++{
++ u32 flags;
++ if (enable)
++ {
++ mtwpar(0x0C008000);
++ }
++
++ asm ("isync");
++ asm ("sync");
++
++ flags = mfspr(920);
++ if (enable)
++ {
++ flags |= 0x40000000;
++ }
++ else
++ {
++ flags &= ~0x40000000;
++ }
++
++ mtspr(920,flags);
++ asm ("isync");
++ asm ("sync");
++}
++
++static inline void __GX_DrawDone(void)
++{
++ LOAD_BP_REG(0x45000002);
++ __GX_Flush();
++}
++
++static void gcngx_destroy_fifo()
++{
++ gcngx_disable_pe_interrupts();
++ _peReg[7] = 0;
++
++ __GX_DrawDone();
++ /* wait for the buffer to empty? */
++ __GX_WriteFifoIntEnable(GX_DISABLE,GX_DISABLE);
++ __GX_FifoReadEnable(0);
++ __GX_FifoLink(GX_FALSE);
++
++ __GX_EnableWriteGatherPipe(0);
++}
++
++struct fifo_info
++{
++ u8 *base;
++ u8 *end;
++ u32 length;
++ u8 *lo_water_mark;
++ u8 *hi_water_mark;
++ u8 *write_ptr;
++ u8 *read_ptr;
++};
++
++static void gcngx_init_fifo(void)
++{
++ struct fifo_info fi;
++ int i;
++
++ fi.base = phys_fifo_base;
++ fi.end = phys_fifo_base + fifo_len - 4;
++ fi.length = fifo_len;
++ fi.lo_water_mark = phys_fifo_base + ((fifo_len / 2) & ~31);
++ fi.hi_water_mark = phys_fifo_base + fifo_len - (16*1024);
++ fi.write_ptr = phys_fifo_base;
++ fi.read_ptr = phys_fifo_base;
++
++ /* reset currentFB pointer */
++ currentFB = 0;
++ flipRequest = 0;
++
++ /* printk(KERN_INFO "Initializing Flipper FIFO at %p of length %u\n",
++ fi.base,fifo_len); */
++
++ __GX_FifoLink(GX_FALSE);
++ __GX_WriteFifoIntEnable(GX_DISABLE,GX_DISABLE);
++ __GX_FifoReadEnable(0);
++
++ /* clear the fifo */
++ for (i=0;i<fifo_len/4;++i)
++ {
++ ((u32*)mmap_fifo_base)[i] = 0;
++ }
++ /* flush it */
++ flush_dcache_range((u32)mmap_fifo_base,
++ (u32)(mmap_fifo_base+fifo_len));
++
++ _peReg[7] = 0;
++
++ /* fifo base start */
++ _piReg[3] = (u32)fi.base;
++ /* fifo base end */
++ _piReg[4] = (u32)fi.end;
++ /* fifo write pointer */
++ _piReg[5] = (u32)fi.write_ptr;
++
++ /* init and flush the write gather pipe */
++ __GX_EnableWriteGatherPipe(1);
++ __GX_Flush();
++
++ /* wait for all data to be flushed */
++ while (mfwpar() & 1);
++ _piReg[3] = (u32)fi.base;
++ _piReg[4] = (u32)fi.end;
++ _piReg[5] = (u32)fi.write_ptr;
++ while (mfwpar() & 1);
++
++ /* setup fifo base */
++ _cpReg[16] = _SHIFTL(fi.base,0,16);
++ _cpReg[17] = _SHIFTR(fi.base,16,16);
++
++ /* setup fifo end */
++ _cpReg[18] = _SHIFTL(fi.end,0,16);
++ _cpReg[19] = _SHIFTR(fi.end,16,16);
++
++ /* setup hiwater mark */
++ _cpReg[20] = _SHIFTL(fi.hi_water_mark,0,16);
++ _cpReg[21] = _SHIFTR(fi.hi_water_mark,16,16);
++
++ /* setup lowater mark */
++ _cpReg[22] = _SHIFTL(fi.lo_water_mark,0,16);
++ _cpReg[23] = _SHIFTR(fi.lo_water_mark,16,16);
++
++ /* setup rd<->wd dist */
++ /*_cpReg[24] = _SHIFTL((pad)[7],0,16);
++ _cpReg[25] = _SHIFTR((pad)[7],16,16);*/
++ _cpReg[24] = 0;
++ _cpReg[25] = 0;
++
++ /* setup wt ptr */
++ _cpReg[26] = _SHIFTL(fi.write_ptr,0,16);
++ _cpReg[27] = _SHIFTR(fi.write_ptr,16,16);
++
++ /* setup rd ptr */
++ _cpReg[28] = _SHIFTL(fi.read_ptr,0,16);
++ _cpReg[29] = _SHIFTR(fi.read_ptr,16,16);
++
++ asm ("sync");
++ asm ("isync");
++ /* enable the write gather pipe */
++ __GX_WriteFifoIntEnable(GX_ENABLE,GX_DISABLE);
++ __GX_FifoLink(GX_TRUE);
++ __GX_FifoReadEnable(1);
++ /* enable interrupts */
++ gcngx_enable_pe_interrupts();
++
++ asm("sync");
++ asm("isync");
++}
++
++int gcngx_init(struct fb_info *info)
++{
++ int err;
++ /* compute framebuffer pointers */
++ xfb[0] = (u32)info->fix.smem_start;
++ xfb[1] = (u32)info->fix.smem_start + info->fix.smem_len/2;
++ /* disable the interrupts */
++ gcngx_disable_pe_interrupts();
++ __GX_WriteFifoIntEnable(GX_DISABLE,GX_DISABLE);
++
++ /* map the fifo area */
++ phys_fifo_base = (u8*)GCN_GX_FIFO_START;
++ if (!request_mem_region((u32)phys_fifo_base,fifo_len,"GX FIFO")) {
++ printk(KERN_ERR "Cannot reserve fifo memory area at %p\n",phys_fifo_base);
++ return -EIO;
++ }
++ if (!(mmap_fifo_base = ioremap((u32)phys_fifo_base,fifo_len))) {
++ printk(KERN_ERR "Cannot map the fifo area at %p\n",phys_fifo_base);
++ err = -EIO;
++ goto free_mem;
++ }
++
++ if ((err=request_irq(IRQ_PE_TOKEN,gcfb_pe_token_irq_handler,IRQF_DISABLED,"PE Token",0)))
++ {
++ goto free_iounmap;
++ }
++ if ((err=request_irq(IRQ_PE_FINISH,gcfb_pe_finish_irq_handler,IRQF_DISABLED,"PE Finish",0)))
++ {
++ goto free_pe_token;
++ }
++ if ((err=request_irq(IRQ_CP_FIFO,gcfb_fifo_irq_handler,IRQF_DISABLED,"CP FIFO",0)))
++ {
++ goto free_pe_finish;
++ }
++ return 0;
++
++ free_pe_finish:
++ free_irq(IRQ_PE_FINISH,0);
++ free_pe_token:
++ free_irq(IRQ_PE_TOKEN,0);
++ free_iounmap:
++ iounmap(mmap_fifo_base);
++ free_mem:
++ release_mem_region((u32)phys_fifo_base,fifo_len);
++
++ return err;
++}
++
++void gcngx_exit(struct fb_info *info)
++{
++ gcngx_destroy_fifo();
++
++ free_irq(IRQ_PE_FINISH,0);
++ free_irq(IRQ_PE_TOKEN,0);
++ free_irq(IRQ_CP_FIFO,0);
++
++ iounmap(mmap_fifo_base);
++ release_mem_region((u32)phys_fifo_base,fifo_len);
++}
++
++#endif /* CONFIG_FB_GAMECUBE_GX */
++
+diff --git a/drivers/video/gcngx.h b/drivers/video/gcngx.h
+new file mode 100644
+index 0000000..9722349
+--- /dev/null
++++ b/drivers/video/gcngx.h
+@@ -0,0 +1,17 @@
++#ifndef __GCGX__
++#define __GCGX__
++
++#ifdef CONFIG_FB_GAMECUBE_GX
++
++int gcngx_mmap(struct fb_info *info, struct vm_area_struct *vma);
++int gcngx_ioctl(struct fb_info *info, unsigned int cmd,unsigned long arg);
++
++int gcngx_init(struct fb_info *info);
++void gcngx_exit(struct fb_info *info);
++
++struct vi_ctl;
++void gcngx_vtrace(struct vi_ctl *ctl);
++
++#endif
++
++#endif
+diff --git a/drivers/video/logo/Kconfig b/drivers/video/logo/Kconfig
+index 39ac49e..6fa54c6 100644
+--- a/drivers/video/logo/Kconfig
++++ b/drivers/video/logo/Kconfig
+@@ -42,6 +42,11 @@ config LOGO_DEC_CLUT224
+ depends on MACH_DECSTATION || ALPHA
+ default y
+
++config LOGO_GAMECUBE_CLUT224
++ bool "224-color GameCube Linux logo"
++ depends on GAMECUBE
++ default y
++
+ config LOGO_MAC_CLUT224
+ bool "224-color Macintosh Linux logo"
+ depends on MAC
+diff --git a/drivers/video/logo/Makefile b/drivers/video/logo/Makefile
+index b91251d..a88ea9f 100644
+--- a/drivers/video/logo/Makefile
++++ b/drivers/video/logo/Makefile
+@@ -7,6 +7,7 @@ obj-$(CONFIG_LOGO_LINUX_CLUT224) += logo_linux_clut224.o
+ obj-$(CONFIG_LOGO_BLACKFIN_CLUT224) += logo_blackfin_clut224.o
+ obj-$(CONFIG_LOGO_BLACKFIN_VGA16) += logo_blackfin_vga16.o
+ obj-$(CONFIG_LOGO_DEC_CLUT224) += logo_dec_clut224.o
++obj-$(CONFIG_LOGO_GAMECUBE_CLUT224) += logo_gcn_clut224.o
+ obj-$(CONFIG_LOGO_MAC_CLUT224) += logo_mac_clut224.o
+ obj-$(CONFIG_LOGO_PARISC_CLUT224) += logo_parisc_clut224.o
+ obj-$(CONFIG_LOGO_SGI_CLUT224) += logo_sgi_clut224.o
+diff --git a/drivers/video/logo/logo.c b/drivers/video/logo/logo.c
+index 2e85a2b..bd608bf 100644
+--- a/drivers/video/logo/logo.c
++++ b/drivers/video/logo/logo.c
+@@ -27,6 +27,7 @@ extern const struct linux_logo logo_linux_clut224;
+ extern const struct linux_logo logo_blackfin_vga16;
+ extern const struct linux_logo logo_blackfin_clut224;
+ extern const struct linux_logo logo_dec_clut224;
++extern const struct linux_logo logo_gcn_clut224;
+ extern const struct linux_logo logo_mac_clut224;
+ extern const struct linux_logo logo_parisc_clut224;
+ extern const struct linux_logo logo_sgi_clut224;
+@@ -90,6 +91,10 @@ const struct linux_logo * __init_refok fb_find_logo(int depth)
+ /* DEC Linux logo on MIPS/MIPS64 or ALPHA */
+ logo = &logo_dec_clut224;
+ #endif
++#ifdef CONFIG_LOGO_GAMECUBE_CLUT224
++ /* GameCube Linux logo */
++ logo = &logo_gcn_clut224;
++#endif
+ #ifdef CONFIG_LOGO_MAC_CLUT224
+ /* Macintosh Linux logo on m68k */
+ if (MACH_IS_MAC)
+diff --git a/drivers/video/logo/logo_gcn_clut224.ppm b/drivers/video/logo/logo_gcn_clut224.ppm
+new file mode 100644
+index 0000000..08e12b3
+--- /dev/null
++++ b/drivers/video/logo/logo_gcn_clut224.ppm
+@@ -0,0 +1,1123 @@
++P3
++80 80
++255
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++6 6 6 6 6 6 10 10 10 10 10 10 10 10 10 6 6 6
++6 6 6 6 6 6 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 6 6 6 10 10 10 14 14 14
++22 22 22 26 26 26 30 30 30 34 34 34 30 30 30 30 30 30
++26 26 26 18 18 17 14 14 14 10 10 10 6 6 6 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 6 6 6 14 14 14 26 26 26 42 42 42
++54 54 55 66 66 66 78 78 78 78 78 78 78 78 78 74 74 74
++66 66 66 54 54 55 42 42 42 26 26 26 18 18 17 10 10 10
++6 6 6 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 10 10 10 22 22 22 42 42 42 66 66 66 87 86 85
++66 66 66 38 38 38 38 38 38 22 22 22 26 26 26 34 34 34
++54 54 55 66 66 66 87 86 85 70 70 70 46 46 46 26 26 26
++14 14 14 6 6 6 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++10 10 10 26 26 26 50 50 50 82 82 82 58 58 58 6 6 6
++2 2 6 2 2 6 2 2 6 2 2 6 2 2 6 2 2 6
++2 2 6 2 2 6 6 6 6 54 54 55 87 86 85 66 66 66
++38 38 38 18 18 17 6 6 6 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 6 6 6
++22 22 22 50 50 50 78 78 78 34 34 34 2 2 6 2 2 6
++2 2 6 2 2 6 2 2 6 2 2 6 2 2 6 2 2 6
++2 2 6 2 2 6 2 2 6 2 2 6 6 6 6 70 70 70
++78 78 78 46 46 46 22 22 22 6 6 6 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 6 6 6 18 18 17
++42 42 42 82 82 82 26 26 26 2 2 6 2 2 6 2 2 6
++2 2 6 2 2 6 2 2 6 2 2 6 2 2 6 2 2 6
++2 2 6 14 14 14 46 46 46 34 34 34 6 6 6 2 2 6
++42 42 42 78 78 78 42 42 42 18 18 17 6 6 6 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 10 10 10 30 30 30
++66 66 66 58 58 58 2 2 6 2 2 6 2 2 6 2 2 6
++2 2 6 2 2 6 2 2 6 2 2 6 2 2 6 2 2 6
++2 2 6 26 26 26 87 86 85 102 98 90 46 46 46 10 10 10
++2 2 6 58 58 58 70 70 70 34 34 34 10 10 10 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 14 14 14 42 42 42
++87 86 85 10 10 10 2 2 6 2 2 6 2 2 6 2 2 6
++2 2 6 2 2 6 2 2 6 2 2 6 2 2 6 2 2 6
++2 2 6 30 30 30 94 94 98 94 94 94 58 58 58 26 26 26
++2 2 6 6 6 6 78 78 78 54 54 55 22 22 22 6 6 6
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 6 6 6 22 22 22 62 62 62
++62 62 62 2 2 6 2 2 6 2 2 6 2 2 6 2 2 6
++2 2 6 2 2 6 2 2 6 2 2 6 2 2 6 2 2 6
++2 2 6 26 26 26 54 54 55 38 38 38 18 18 17 10 10 10
++2 2 6 2 2 6 34 34 34 82 82 82 38 38 38 14 14 14
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 6 6 6 30 30 30 78 78 78
++30 30 30 2 2 6 2 2 6 2 2 6 2 2 6 2 2 6
++2 2 6 2 2 6 2 2 6 2 2 6 2 2 6 2 2 6
++2 2 6 10 10 10 10 10 10 2 2 6 2 2 6 2 2 6
++2 2 6 2 2 6 2 2 6 78 78 78 50 50 50 18 18 17
++6 6 6 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 10 10 10 38 38 38 87 86 85
++14 14 14 2 2 6 2 2 6 2 2 6 2 2 6 2 2 6
++2 2 6 2 2 6 2 2 6 2 2 6 2 2 6 2 2 6
++2 2 6 2 2 6 2 2 6 2 2 6 2 2 6 2 2 6
++2 2 6 2 2 6 2 2 2 54 54 55 66 66 66 26 26 26
++6 6 6 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 14 14 14 42 42 42 82 82 82
++2 2 6 2 2 6 2 2 6 6 6 6 10 10 10 2 2 6
++2 2 6 2 2 6 2 2 6 2 2 6 2 2 6 2 2 6
++2 2 6 6 6 6 14 14 14 10 10 10 2 2 6 2 2 6
++2 2 6 2 2 6 2 2 6 18 18 17 82 82 82 34 34 34
++10 10 10 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 14 14 14 46 46 46 87 86 85
++2 2 6 2 2 6 6 6 6 6 6 6 22 22 22 34 34 34
++6 6 6 2 2 6 2 2 6 2 2 6 2 2 6 2 2 6
++18 18 17 34 34 34 10 10 10 50 50 50 22 22 22 2 2 6
++2 2 6 2 2 6 2 2 6 10 10 10 87 86 85 42 42 42
++14 14 14 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 14 14 14 46 46 46 87 86 85
++2 2 6 2 2 6 38 38 38 118 118 118 94 94 94 22 22 22
++22 22 22 2 2 6 2 2 6 2 2 6 14 14 14 87 86 85
++141 139 143 160 158 162 152 152 152 38 38 38 26 26 26 6 6 6
++2 2 6 2 2 6 2 2 6 2 2 6 87 86 85 46 46 46
++14 14 14 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 14 14 14 46 46 46 87 86 85
++2 2 6 14 14 14 134 133 135 199 199 199 194 193 197 118 118 118
++10 10 10 2 2 6 2 2 6 6 6 6 102 98 90 190 190 190
++209 208 212 219 220 223 215 214 215 134 133 135 14 14 14 6 6 6
++2 2 6 2 2 6 2 2 6 2 2 6 87 86 85 50 50 50
++18 18 17 6 6 6 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 14 14 14 46 46 46 87 86 85
++2 2 6 54 54 55 219 220 223 199 199 199 219 220 223 246 246 246
++58 58 58 2 2 6 2 2 6 30 30 30 209 208 212 254 254 254
++173 173 174 121 121 122 219 220 223 236 233 239 74 74 74 2 2 6
++2 2 6 2 2 6 2 2 6 2 2 6 70 70 70 58 58 58
++22 22 22 6 6 6 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 14 14 14 46 46 46 82 82 82
++2 2 6 104 103 100 173 173 174 26 26 26 90 90 90 229 226 233
++121 121 122 10 10 10 14 14 14 46 46 46 229 231 235 190 190 190
++6 6 6 74 74 74 90 90 90 239 238 242 160 158 162 2 2 6
++2 2 6 2 2 6 2 2 6 2 2 6 70 70 70 58 58 58
++22 22 22 6 6 6 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 14 14 14 42 42 42 87 86 85
++6 6 6 118 118 118 104 103 100 6 6 6 70 70 70 152 152 152
++122 122 130 18 18 17 38 38 38 54 54 55 219 220 223 104 103 100
++2 2 2 14 14 14 46 46 46 190 190 190 199 199 199 2 2 2
++2 2 6 2 2 6 2 2 6 2 2 6 74 74 74 62 62 62
++22 22 22 6 6 6 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 14 14 14 42 42 42 94 94 94
++14 14 14 104 103 100 122 122 130 2 2 2 18 18 17 118 118 118
++124 98 46 122 94 10 122 94 10 101 78 10 163 163 162 107 107 108
++2 2 6 2 2 2 2 2 2 194 193 197 194 193 197 6 6 6
++2 2 6 2 2 6 2 2 6 2 2 6 74 74 74 62 62 62
++22 22 22 6 6 6 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 10 10 10 38 38 38 90 90 90
++14 14 14 62 62 62 209 208 212 26 26 26 44 31 8 158 118 10
++226 171 11 238 183 13 214 174 14 188 146 14 214 174 14 174 146 62
++26 26 26 2 2 2 70 70 70 246 246 246 141 139 143 2 2 2
++2 2 6 2 2 6 2 2 6 2 2 6 70 70 70 66 66 66
++26 26 26 6 6 6 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 10 10 10 38 38 38 87 86 85
++14 14 14 6 6 6 199 199 199 190 166 114 186 134 10 226 171 11
++238 178 14 234 193 17 234 193 17 236 202 20 246 206 46 242 210 18
++234 193 17 188 146 14 218 194 134 210 206 186 42 42 42 2 2 6
++2 2 6 2 2 6 2 2 6 2 2 6 50 50 50 74 74 74
++30 30 30 6 6 6 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 10 10 10 34 34 34 87 86 85
++14 14 14 2 2 2 122 86 26 194 134 10 226 166 10 238 183 13
++226 186 14 234 193 17 236 202 20 246 216 61 246 217 39 246 217 39
++246 214 22 242 210 18 242 210 18 226 186 14 122 86 26 2 2 6
++2 2 6 2 2 6 2 2 6 2 2 6 50 50 50 82 82 82
++34 34 34 10 10 10 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 10 10 10 34 34 34 82 82 82
++30 30 30 63 43 6 182 122 6 204 146 10 231 174 11 238 183 13
++234 193 17 236 202 20 242 210 18 246 216 61 246 217 39 246 214 22
++246 214 22 242 210 18 226 186 14 214 174 14 188 146 14 6 6 6
++2 2 6 2 2 6 2 2 6 2 2 6 26 26 26 94 94 94
++42 42 42 14 14 14 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 10 10 10 30 30 30 78 78 78
++50 50 50 104 70 6 186 134 10 218 158 10 238 178 14 242 186 14
++236 202 20 236 202 20 246 216 61 246 217 39 246 217 39 246 214 22
++242 210 18 198 154 10 198 138 10 218 158 10 154 114 10 2 2 6
++2 2 6 2 2 6 2 2 6 2 2 6 6 6 6 90 90 90
++54 54 55 18 18 17 6 6 6 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 10 10 10 30 30 30 78 78 78
++46 46 46 22 22 22 138 93 6 198 154 10 238 183 13 238 183 13
++236 202 20 242 210 18 246 214 22 246 214 22 242 210 18 204 166 16
++186 134 10 210 150 10 216 162 10 210 150 10 101 78 10 2 2 6
++6 6 6 54 54 55 14 14 14 2 2 6 2 2 6 62 62 62
++74 74 74 30 30 30 10 10 10 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 10 10 10 34 34 34 78 78 78
++50 50 50 6 6 6 94 70 30 138 102 14 188 146 14 226 186 14
++236 202 20 234 193 17 214 174 14 188 146 14 173 119 7 186 134 10
++210 150 10 214 154 10 202 150 34 182 158 106 102 98 90 2 2 2
++2 2 6 78 78 78 118 118 118 54 54 55 2 2 6 22 22 22
++90 90 90 46 46 46 18 18 17 6 6 6 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 10 10 10 38 38 38 87 86 85
++50 50 50 6 6 6 132 131 125 174 154 114 160 108 10 173 119 7
++198 154 10 188 146 14 198 138 10 198 138 10 204 146 10 204 146 10
++198 138 10 190 166 114 194 193 197 199 199 199 173 173 174 14 14 14
++2 2 6 18 18 17 118 118 118 118 118 118 22 22 22 2 2 6
++74 74 74 70 70 70 30 30 30 10 10 10 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 6 6 6 18 18 17 50 50 50 104 103 100
++26 26 26 10 10 10 141 139 143 190 190 190 174 154 114 160 108 10
++198 138 10 188 146 14 198 138 10 194 134 10 182 122 6 190 142 34
++186 174 146 185 185 187 199 199 199 219 220 223 215 214 215 66 66 66
++2 2 6 2 2 6 50 50 50 62 62 62 6 6 6 2 2 2
++10 10 10 90 90 90 50 50 50 18 18 17 6 6 6 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 10 10 10 34 34 34 74 74 74 74 74 74
++2 2 2 6 6 6 141 139 143 199 199 199 190 190 190 163 163 162
++154 122 54 160 108 10 160 108 10 164 122 42 174 154 114 185 185 187
++194 193 197 209 208 212 250 250 250 254 254 254 250 250 250 182 182 182
++6 6 6 2 2 6 2 2 6 2 2 6 2 2 6 2 2 6
++2 2 6 62 62 62 74 74 74 34 34 34 14 14 14 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 10 10 10 22 22 22 54 54 55 94 94 94 18 18 17
++2 2 6 50 50 50 229 231 235 219 220 223 194 193 197 190 190 190
++190 190 190 190 190 190 190 190 190 190 190 190 190 190 190 194 193 197
++215 214 215 242 242 242 254 254 254 254 254 254 250 250 250 254 254 254
++82 82 82 2 2 6 2 2 6 2 2 6 2 2 6 2 2 6
++2 2 6 14 14 14 87 86 85 54 54 55 22 22 22 6 6 6
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++6 6 6 18 18 17 46 46 46 90 90 90 46 46 46 18 18 17
++6 6 6 182 182 182 254 254 254 250 250 250 210 206 186 190 190 190
++190 190 190 190 190 190 190 190 190 190 190 190 210 206 186 229 231 235
++254 254 254 250 250 250 250 250 250 254 254 254 254 254 254 254 254 254
++198 200 208 14 14 14 2 2 6 2 2 6 2 2 6 2 2 6
++2 2 6 2 2 6 42 42 42 87 86 85 42 42 42 18 18 17
++6 6 6 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 6 6 6
++14 14 14 38 38 38 74 74 74 66 66 66 2 2 6 6 6 6
++90 90 90 250 250 250 250 250 250 254 254 254 239 238 242 199 199 199
++190 190 190 190 190 190 194 193 197 219 220 223 183 174 199 134 114 171
++207 201 219 254 254 254 254 254 254 254 254 254 250 250 250 254 254 254
++250 250 250 82 82 82 2 2 2 2 2 6 2 2 6 2 2 6
++2 2 6 2 2 6 2 2 6 78 78 78 70 70 70 34 34 34
++14 14 14 6 6 6 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 14 14 14
++34 34 34 66 66 66 78 78 78 6 6 6 2 2 2 18 18 17
++219 220 223 254 254 254 254 254 254 250 250 250 254 254 254 246 246 246
++222 223 236 229 231 235 229 226 233 140 131 164 109 96 159 109 96 159
++120 106 166 170 156 193 236 233 239 254 254 254 254 254 254 254 254 254
++254 254 254 182 182 182 2 2 6 2 2 6 2 2 6 2 2 6
++2 2 6 2 2 6 2 2 6 18 18 17 90 90 90 62 62 62
++30 30 30 10 10 10 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 10 10 10 26 26 26
++58 58 58 90 90 90 18 18 17 2 2 6 2 2 6 107 107 108
++254 254 254 254 254 254 254 254 254 250 250 250 250 250 250 254 254 254
++250 250 250 189 183 204 121 102 164 116 94 159 117 98 162 114 103 163
++114 103 163 120 106 166 136 121 175 146 139 165 107 107 108 118 118 118
++141 139 143 182 182 182 219 220 223 2 2 6 2 2 6 2 2 6
++2 2 6 2 2 6 2 2 6 2 2 6 18 18 17 94 94 94
++54 54 55 26 26 26 10 10 10 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 6 6 6 22 22 22 50 50 50
++90 90 90 26 26 26 2 2 6 2 2 2 14 14 14 199 199 199
++250 250 250 254 254 254 254 254 254 254 254 254 254 254 254 229 226 233
++147 132 180 109 90 154 158 147 190 198 200 208 137 128 178 120 106 166
++121 102 164 120 106 166 130 120 175 130 120 175 127 110 169 76 72 88
++58 58 58 58 58 58 74 74 74 118 118 118 194 193 197 2 2 6
++2 2 6 2 2 6 2 2 6 2 2 6 2 2 6 38 38 38
++87 86 85 50 50 50 22 22 22 6 6 6 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 6 6 6 14 14 14 38 38 38 82 82 82
++34 34 34 2 2 6 2 2 6 2 2 2 42 42 42 194 193 197
++246 246 246 254 254 254 254 254 254 254 254 254 200 193 212 122 98 164
++113 86 148 109 96 159 128 114 172 158 147 190 130 120 175 120 106 166
++127 110 169 127 110 169 130 120 175 130 120 175 142 128 179 140 131 164
++102 98 122 58 50 84 54 54 55 62 62 62 74 74 74 134 133 135
++236 233 239 2 2 2 2 2 6 2 2 6 2 2 6 2 2 6
++38 38 38 82 82 82 42 42 42 14 14 14 6 6 6 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 10 10 10 26 26 26 62 62 62 66 66 66
++2 2 6 2 2 6 2 2 6 6 6 6 70 70 70 169 165 179
++210 206 186 229 231 235 236 233 239 146 139 165 105 86 155 105 86 155
++109 96 159 109 90 154 109 96 159 114 103 163 114 103 163 120 106 166
++120 106 166 128 114 172 130 120 175 137 128 178 137 128 178 142 134 183
++155 141 181 140 131 164 70 70 70 58 50 84 66 66 66 84 82 94
++118 118 118 229 231 235 2 2 6 2 2 6 2 2 6 2 2 6
++2 2 6 62 62 62 66 66 66 30 30 30 10 10 10 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 14 14 14 42 42 42 82 82 82 18 18 17
++2 2 6 2 2 6 2 2 6 10 10 10 94 94 94 182 182 182
++219 220 223 200 193 212 122 98 164 102 82 152 105 86 155 109 90 154
++109 96 159 109 90 154 109 96 159 114 103 163 114 103 163 127 110 169
++128 114 172 128 114 172 130 120 175 137 128 178 142 128 179 148 140 189
++148 140 189 158 147 190 158 147 190 118 110 134 76 72 88 94 90 106
++94 94 98 132 131 125 2 2 6 2 2 6 2 2 6 2 2 6
++2 2 6 6 6 6 87 86 85 46 46 46 18 18 17 6 6 6
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 6 6 6 22 22 22 54 54 55 70 70 70 2 2 6
++2 2 6 10 10 10 2 2 2 22 22 22 173 173 174 236 233 239
++155 141 181 102 82 152 102 82 152 102 82 152 109 90 154 105 86 155
++109 90 154 87 78 126 58 50 84 45 38 66 45 38 66 54 46 76
++82 70 114 114 103 163 130 120 175 136 121 175 137 128 178 142 128 179
++142 134 183 148 140 189 158 147 190 158 147 190 146 139 165 118 106 138
++126 122 142 87 86 85 199 199 199 2 2 6 2 2 6 2 2 6
++2 2 6 2 2 6 62 62 62 66 66 66 26 26 26 10 10 10
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 10 10 10 30 30 30 74 74 74 50 50 50 2 2 6
++26 26 26 26 26 26 2 2 6 107 107 108 207 201 219 120 106 166
++103 83 144 102 82 152 105 86 155 102 82 152 94 82 138 87 78 126
++34 26 54 6 6 6 6 6 6 2 2 6 2 2 6 2 2 2
++2 2 2 10 6 18 64 60 89 130 120 175 137 128 178 137 128 178
++142 128 179 148 140 189 142 134 183 146 140 180 142 134 183 148 140 189
++155 141 181 110 106 126 146 146 147 18 18 17 2 2 6 2 2 6
++2 2 6 2 2 6 18 18 17 87 86 85 42 42 42 14 14 14
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 14 14 14 42 42 42 90 90 90 22 22 22 2 2 6
++42 42 42 2 2 2 78 78 78 166 150 188 102 82 152 99 78 147
++111 77 141 102 82 152 99 78 147 105 86 155 87 78 126 10 10 10
++6 6 6 2 2 6 2 2 6 6 2 2 2 2 2 2 2 2
++2 2 6 6 6 6 2 2 6 45 38 66 130 120 175 136 121 175
++137 128 178 137 128 178 137 128 178 137 128 178 137 128 178 142 128 179
++142 134 183 140 131 164 138 131 154 38 38 38 10 10 10 2 2 6
++2 2 6 2 2 6 2 2 6 78 78 78 58 58 58 22 22 22
++6 6 6 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++6 6 6 18 18 17 54 54 55 82 82 82 2 2 6 26 26 26
++22 22 22 216 211 227 127 110 169 97 74 146 99 78 147 99 78 147
++102 82 152 102 82 152 99 78 147 94 82 138 34 26 54 2 2 6
++2 2 6 6 2 7 50 50 50 30 30 30 6 6 6 6 2 2
++2 2 2 2 2 2 2 2 6 2 2 6 87 78 126 130 120 175
++128 114 172 130 120 175 130 120 175 136 121 175 137 128 178 130 120 175
++130 120 175 137 128 178 142 134 183 213 206 226 38 38 38 2 2 6
++2 2 6 2 2 6 2 2 6 46 46 46 78 78 78 30 30 30
++10 10 10 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++10 10 10 30 30 30 74 74 74 58 58 58 2 2 6 42 42 42
++189 183 204 105 86 155 97 74 146 97 74 146 93 70 140 97 74 146
++105 86 155 99 78 147 102 82 152 94 82 138 10 6 18 6 2 7
++6 6 6 2 2 2 10 6 18 50 50 50 54 54 55 18 18 17
++6 2 2 6 2 7 6 2 7 2 2 6 54 46 76 120 106 166
++127 110 169 127 110 169 127 110 169 128 114 172 127 110 169 128 114 172
++128 114 172 127 110 169 128 114 172 130 120 175 38 38 38 14 14 14
++2 2 6 2 2 6 2 2 6 6 6 6 87 86 85 46 46 46
++14 14 14 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 6 6 6
++14 14 14 42 42 42 90 90 90 18 18 17 18 18 17 26 26 26
++183 174 199 122 98 164 97 74 146 99 78 147 97 74 146 97 74 146
++99 78 147 99 78 147 102 82 152 99 78 147 14 14 14 26 26 26
++26 26 26 6 2 7 6 2 7 6 2 7 22 22 22 66 66 66
++30 30 30 2 2 6 2 2 6 2 2 6 58 50 84 120 106 166
++114 103 163 114 103 163 114 103 163 114 103 163 114 103 163 114 103 163
++114 103 163 120 106 166 109 90 154 134 120 165 10 10 10 34 34 34
++2 2 6 2 2 6 2 2 6 2 2 6 74 74 74 58 58 58
++22 22 22 6 6 6 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 10 10 10
++26 26 26 66 66 66 82 82 82 2 2 6 38 38 38 6 2 7
++196 186 211 154 134 184 127 110 169 99 78 147 97 74 146 97 74 146
++99 78 147 99 78 147 99 78 147 102 82 152 45 38 66 58 50 84
++54 54 55 22 22 22 6 2 7 6 2 7 6 2 7 10 10 10
++14 14 14 6 2 2 2 2 2 10 6 18 94 82 138 109 96 159
++109 96 159 109 96 159 109 96 159 109 96 159 109 96 159 109 96 159
++109 96 159 105 86 155 116 94 159 147 132 180 2 2 6 46 46 46
++2 2 6 2 2 6 2 2 6 2 2 6 42 42 42 74 74 74
++30 30 30 10 10 10 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 6 6 6 14 14 14
++42 42 42 90 90 90 26 26 26 6 6 6 42 42 42 2 2 6
++200 193 212 154 134 184 154 134 184 136 121 175 105 86 155 97 74 146
++97 74 146 99 78 147 99 78 147 97 74 146 95 75 136 40 30 56
++94 90 106 104 103 100 50 50 50 26 26 26 6 2 7 6 2 7
++2 2 6 6 2 2 10 6 18 64 60 89 109 90 154 105 86 155
++105 86 155 105 86 155 105 86 155 105 86 155 105 86 155 102 82 152
++109 90 154 116 94 159 116 94 159 157 140 187 2 2 6 46 46 46
++2 2 6 2 2 6 2 2 6 2 2 6 10 10 10 87 86 85
++38 38 38 10 10 10 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 10 10 10 26 26 26
++66 66 66 82 82 82 2 2 6 22 22 22 18 18 17 6 2 7
++207 201 219 154 134 184 147 132 180 147 132 180 147 126 185 114 90 155
++97 74 146 97 74 146 111 77 141 130 90 130 99 78 147 95 75 136
++58 50 84 84 82 94 87 86 85 38 38 38 6 2 7 6 2 7
++10 6 18 34 26 54 86 66 120 102 82 152 99 78 147 102 82 152
++102 82 152 102 82 152 102 82 152 99 78 147 99 78 147 109 90 154
++114 90 155 116 94 159 116 94 159 170 156 193 2 2 6 38 38 38
++2 2 6 2 2 6 2 2 6 2 2 6 6 6 6 87 86 85
++46 46 46 14 14 14 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 6 6 6 18 18 17 46 46 46
++87 86 85 18 18 17 2 2 6 34 34 34 10 10 10 10 6 18
++213 206 226 162 146 182 183 174 199 147 132 180 142 134 183 147 132 180
++126 102 165 97 74 146 97 74 146 130 90 130 166 110 126 118 78 130
++93 70 140 97 74 146 86 66 120 70 56 108 70 56 108 70 56 108
++87 78 126 94 82 138 99 78 147 99 78 147 99 78 147 99 78 147
++97 74 146 97 74 146 97 74 146 102 82 152 114 90 155 116 94 159
++116 94 159 122 98 164 122 98 164 177 168 195 6 6 6 30 30 30
++2 2 6 2 2 6 2 2 6 2 2 6 2 2 6 82 82 82
++54 54 55 18 18 17 6 6 6 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 10 10 10 26 26 26 66 66 66
++62 62 62 2 2 6 2 2 2 38 38 38 10 10 10 22 22 22
++226 218 234 170 156 193 207 201 219 194 193 197 146 139 165 147 126 185
++147 132 180 134 114 171 99 78 147 99 78 147 118 78 130 113 86 148
++97 74 146 97 74 146 97 74 146 97 74 146 97 74 146 99 78 147
++97 74 146 97 74 146 97 74 146 97 74 146 97 74 146 93 70 140
++97 74 146 93 70 140 105 86 155 109 90 154 93 70 140 116 94 159
++122 98 164 122 98 164 126 102 165 189 183 204 10 10 10 30 30 30
++2 2 6 2 2 6 2 2 6 2 2 6 2 2 6 66 66 66
++58 58 58 22 22 22 6 6 6 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 10 10 10 38 38 38 78 78 78
++6 6 6 2 2 6 2 2 6 46 46 46 14 14 14 42 42 42
++229 226 233 170 156 193 183 174 199 132 131 125 198 200 208 158 147 190
++140 131 164 142 134 183 136 121 175 113 86 148 95 75 136 97 74 146
++97 74 146 95 75 136 93 70 140 93 70 140 97 74 146 102 82 152
++97 74 146 93 70 140 93 70 140 93 70 140 93 70 140 93 70 140
++97 74 146 105 86 155 99 78 147 88 65 130 92 71 128 116 94 159
++122 98 164 126 102 165 127 106 167 196 186 211 22 22 22 14 14 14
++2 2 6 2 2 6 2 2 6 2 2 6 2 2 6 66 66 66
++62 62 62 22 22 22 6 6 6 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 6 6 6 18 18 17 50 50 50 74 74 74
++2 2 6 2 2 6 14 14 14 70 70 70 34 34 34 62 62 62
++236 233 239 170 156 193 194 193 197 46 42 70 200 193 212 199 199 199
++177 162 197 137 128 178 147 132 180 147 126 185 121 102 164 97 74 146
++93 70 140 93 70 140 97 74 146 93 70 140 93 70 140 88 65 130
++88 65 130 93 70 140 93 70 140 93 70 140 93 70 140 97 74 146
++113 86 148 97 74 146 86 66 120 92 71 128 93 70 140 122 98 164
++126 102 165 127 106 167 127 106 167 207 201 219 30 30 30 2 2 6
++2 2 6 2 2 6 2 2 6 2 2 6 2 2 6 66 66 66
++62 62 62 22 22 22 6 6 6 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 6 6 6 18 18 17 54 54 55 62 62 62
++2 2 6 2 2 6 2 2 6 30 30 30 46 46 46 74 74 74
++254 254 254 158 147 190 236 233 239 199 199 199 215 214 215 190 190 190
++163 163 162 183 174 199 138 131 154 142 128 179 147 126 185 127 110 169
++99 78 147 93 70 140 97 74 146 93 70 140 93 70 140 88 65 130
++88 65 130 88 65 130 93 70 140 88 65 130 102 82 152 105 86 155
++92 71 128 86 66 120 86 66 120 92 71 128 95 75 136 126 102 165
++127 106 167 127 106 167 127 106 167 213 206 226 30 30 30 2 2 6
++2 2 6 2 2 6 2 2 6 2 2 6 2 2 6 66 66 66
++58 58 58 22 22 22 6 6 6 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 6 6 6 22 22 22 58 58 58 62 62 62
++2 2 6 2 2 6 2 2 2 6 2 7 30 30 30 78 78 78
++250 250 250 162 146 182 207 201 219 222 223 236 229 231 235 173 173 174
++38 38 38 194 193 197 189 183 204 146 139 165 137 128 178 147 132 180
++136 121 175 105 86 155 88 65 130 93 70 140 93 70 140 88 65 130
++88 65 130 88 65 130 88 65 130 105 86 155 102 82 152 88 65 130
++86 66 120 88 65 130 82 70 114 92 71 128 99 78 147 127 106 167
++126 102 165 126 102 165 127 110 169 226 218 234 14 14 14 22 22 22
++26 26 26 18 18 17 6 6 6 2 2 6 2 2 2 82 82 82
++54 54 55 18 18 17 6 6 6 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 6 6 6 26 26 26 62 62 62 107 107 108
++74 54 14 186 134 10 216 162 10 122 94 10 6 6 6 62 62 62
++239 238 242 170 156 193 155 141 181 200 193 212 222 223 236 229 231 235
++134 133 135 198 200 208 194 193 197 183 174 199 152 152 152 136 121 175
++142 128 179 142 128 179 117 98 162 88 65 130 88 65 130 93 70 140
++88 65 130 99 78 147 109 90 154 114 90 155 95 75 136 86 66 120
++92 71 128 88 65 130 92 71 128 95 75 136 103 83 144 120 106 166
++127 106 167 127 110 169 155 141 181 160 158 162 2 2 2 2 2 2
++6 6 6 18 18 17 66 66 66 38 38 38 6 6 6 94 94 94
++50 50 50 18 18 17 6 6 6 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 6 6 6
++10 10 10 10 10 10 18 18 17 38 38 38 78 78 78 132 131 125
++218 158 10 242 186 14 246 190 14 246 190 14 158 118 10 10 10 10
++90 90 90 226 218 234 166 150 188 157 140 187 189 183 204 216 211 227
++229 231 235 219 220 223 173 173 174 74 74 74 189 183 204 169 165 179
++134 120 165 136 121 175 137 128 178 127 110 169 93 70 140 88 65 130
++102 82 152 113 86 148 114 90 155 114 90 155 92 71 128 86 66 120
++92 71 128 95 75 136 92 71 128 95 75 136 117 98 162 127 106 167
++127 110 169 177 162 197 6 2 7 6 2 7 2 2 6 2 2 6
++2 2 6 2 2 6 38 38 38 46 46 46 22 22 22 107 107 108
++54 54 55 18 18 17 6 6 6 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 6 6 6 14 14 14 22 22 22
++30 30 30 38 38 38 50 50 50 70 70 70 107 107 108 190 142 34
++226 171 11 242 186 14 246 190 14 246 190 14 246 190 14 154 114 10
++6 6 6 74 74 74 236 233 239 136 121 175 157 140 187 177 162 197
++216 211 227 236 233 239 209 208 212 66 66 66 169 165 179 194 193 197
++177 168 195 138 131 154 136 121 175 137 128 178 127 106 167 102 82 152
++109 90 154 109 90 154 109 90 154 116 94 159 99 78 147 86 66 120
++92 71 128 95 75 136 103 83 144 116 94 159 127 106 167 134 120 165
++196 186 211 44 31 8 2 2 2 2 2 6 2 2 6 2 2 6
++2 2 6 6 6 6 30 30 30 26 26 26 204 166 16 154 142 90
++66 66 66 26 26 26 6 6 6 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 6 6 6 18 18 17 38 38 38 58 58 58
++78 78 78 87 86 85 102 98 90 121 121 122 174 146 62 210 150 10
++231 174 11 246 186 14 246 190 14 246 190 14 246 186 14 234 193 17
++101 78 10 2 2 6 46 46 46 215 214 215 177 168 195 148 140 189
++158 147 190 222 223 236 239 238 242 215 214 215 215 214 215 185 185 187
++122 122 130 183 174 199 138 131 154 136 121 175 127 110 169 113 86 148
++109 90 154 114 90 155 116 94 159 122 98 164 99 78 147 95 75 136
++87 78 126 118 78 130 116 94 159 122 98 164 136 121 175 213 206 226
++204 166 16 18 18 17 2 2 6 2 2 6 2 2 6 2 2 6
++2 2 6 2 2 6 6 6 6 122 94 10 236 202 20 234 193 17
++82 82 82 34 34 34 10 10 10 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 14 14 14 38 38 38 70 70 70 154 122 54
++190 142 34 204 146 10 198 138 10 198 138 10 214 154 10 226 171 11
++242 186 14 246 190 14 246 190 14 246 190 14 246 190 14 246 186 14
++226 171 11 44 31 8 6 2 7 22 22 22 160 158 162 200 193 212
++157 140 187 157 140 187 207 201 219 209 208 212 222 223 236 194 193 197
++30 30 30 146 139 165 146 139 165 134 120 165 134 114 171 114 90 155
++116 94 159 122 98 164 122 98 164 122 98 164 111 77 141 92 71 128
++109 90 154 122 98 164 126 102 165 142 128 179 229 226 233 242 186 14
++214 154 10 44 31 8 2 2 2 2 2 6 2 2 6 2 2 6
++2 2 6 2 2 6 63 43 6 231 174 11 234 193 17 238 183 13
++114 102 78 38 38 38 14 14 14 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 6 6 6 22 22 22 54 54 55 154 122 54 214 154 10
++226 171 11 231 174 11 226 171 11 226 171 11 238 178 14 242 186 14
++246 190 14 246 190 14 246 190 14 246 190 14 246 190 14 246 190 14
++242 198 14 188 146 14 10 10 10 6 2 7 6 2 7 118 118 118
++216 211 227 157 140 187 154 134 184 183 174 199 215 214 215 222 223 236
++169 165 179 173 173 174 138 131 154 128 114 172 134 120 165 116 94 159
++122 98 164 122 98 164 121 102 164 126 102 165 103 83 144 116 94 159
++127 106 167 127 106 167 154 134 184 236 233 239 238 178 14 238 178 14
++210 150 10 138 93 6 14 14 14 2 2 6 2 2 6 2 2 6
++6 6 6 63 43 6 198 138 10 238 178 14 238 178 14 238 183 13
++126 114 90 58 58 58 22 22 22 6 6 6 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 10 10 10 30 30 30 70 70 70 179 134 43 226 171 11
++238 183 13 242 186 14 242 186 14 246 186 14 246 190 14 246 190 14
++246 190 14 246 190 14 246 190 14 246 190 14 246 190 14 246 190 14
++246 190 14 234 193 17 94 70 30 2 2 2 2 2 6 2 2 6
++66 66 66 229 226 233 170 156 193 147 132 180 170 156 193 207 201 219
++219 220 223 219 220 223 138 131 154 128 114 172 134 114 171 117 98 162
++121 102 164 121 102 164 121 102 164 120 106 166 116 94 159 127 106 167
++128 114 172 169 165 179 160 158 162 214 166 58 231 174 11 231 174 11
++218 158 10 194 134 10 160 108 10 118 82 10 101 78 10 118 82 10
++166 114 6 198 138 10 226 171 11 238 183 13 242 186 14 242 186 14
++162 146 94 78 78 78 34 34 34 14 14 14 6 6 6 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 6 6 6 30 30 30 78 78 78 190 142 34 226 166 10
++238 183 13 246 190 14 246 190 14 246 190 14 246 190 14 246 190 14
++246 190 14 246 190 14 246 190 14 246 190 14 246 190 14 246 190 14
++246 190 14 242 198 14 204 166 16 18 18 17 2 2 6 2 2 6
++2 2 6 38 38 38 160 158 162 177 168 195 142 134 183 155 141 181
++200 193 212 222 223 236 146 139 165 128 114 172 136 121 175 122 98 164
++122 98 164 122 98 164 126 102 165 114 90 155 122 98 164 128 114 172
++196 186 211 210 206 186 200 193 212 206 162 42 226 171 11 238 178 14
++226 166 10 204 146 10 204 146 10 194 134 10 186 134 10 198 138 10
++210 150 10 231 174 11 242 186 14 246 190 14 246 190 14 242 186 14
++226 171 11 126 114 90 62 62 62 30 30 30 14 14 14 6 6 6
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 10 10 10 30 30 30 78 78 78 179 134 43 226 166 10
++238 183 13 246 190 14 246 190 14 246 190 14 246 190 14 246 190 14
++246 190 14 246 190 14 246 190 14 246 190 14 246 190 14 246 190 14
++246 190 14 246 190 14 242 198 14 138 102 14 2 2 6 2 2 6
++2 2 6 2 2 6 78 78 78 250 250 250 196 186 211 147 132 180
++154 134 184 207 201 219 169 165 179 136 121 175 136 121 175 122 98 164
++126 102 165 122 98 164 114 90 155 121 102 164 134 120 165 213 206 226
++250 250 250 219 220 223 194 193 197 190 150 46 216 162 10 238 178 14
++231 174 11 226 166 10 218 158 10 214 154 10 214 154 10 218 158 10
++226 171 11 238 183 13 246 190 14 246 190 14 246 190 14 246 190 14
++242 186 14 206 162 42 102 98 90 58 58 58 30 30 30 14 14 14
++6 6 6 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 10 10 10 30 30 30 74 74 74 179 134 43 218 158 10
++238 178 14 246 190 14 246 190 14 246 190 14 246 190 14 246 190 14
++246 190 14 246 190 14 246 190 14 246 190 14 246 190 14 246 190 14
++246 190 14 246 186 14 242 198 14 226 186 14 63 43 6 2 2 6
++2 2 6 2 2 6 22 22 22 239 238 242 254 254 254 213 206 226
++157 140 187 147 132 180 155 141 181 136 121 175 136 121 175 121 102 164
++117 98 162 116 94 159 127 106 167 147 126 185 226 218 234 250 250 250
++250 250 250 222 223 236 190 190 190 179 134 43 218 158 10 238 178 14
++238 183 13 238 178 14 231 174 11 226 166 10 226 171 11 231 174 11
++238 178 14 242 186 14 246 190 14 246 190 14 246 190 14 246 190 14
++238 183 13 238 183 13 206 162 42 107 107 108 66 66 66 34 34 34
++14 14 14 6 6 6 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 6 6 6 26 26 26 70 70 70 162 134 66 210 150 10
++238 178 14 246 190 14 246 190 14 246 190 14 246 190 14 246 190 14
++246 190 14 246 190 14 246 190 14 246 190 14 246 190 14 246 190 14
++246 190 14 246 190 14 246 186 14 234 193 17 188 146 14 14 14 14
++2 2 6 2 2 6 46 46 46 246 246 246 254 254 254 254 254 254
++229 226 233 157 140 187 147 132 180 136 121 175 127 110 169 116 94 159
++121 102 164 121 102 164 162 146 182 236 233 239 254 254 254 254 254 254
++254 254 254 219 220 223 87 86 85 160 108 10 218 158 10 238 178 14
++242 186 14 246 186 14 242 186 14 238 183 13 238 183 13 242 186 14
++242 186 14 242 186 14 246 190 14 246 190 14 246 190 14 246 190 14
++246 190 14 246 190 14 242 186 14 226 171 11 142 122 74 66 66 66
++30 30 30 10 10 10 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 6 6 6 26 26 26 70 70 70 162 134 66 210 150 10
++238 178 14 246 190 14 246 190 14 246 190 14 246 190 14 246 190 14
++246 190 14 246 190 14 246 190 14 246 190 14 246 190 14 246 190 14
++246 190 14 246 190 14 246 190 14 246 190 14 234 193 17 122 94 10
++30 30 30 107 107 108 219 220 223 254 254 254 250 250 250 250 250 250
++250 250 250 216 211 227 118 106 138 147 132 180 134 114 171 126 102 165
++127 106 167 177 168 195 250 250 250 254 254 254 254 254 254 254 254 254
++242 242 242 82 82 82 14 14 14 160 108 10 218 158 10 238 178 14
++242 186 14 246 190 14 246 190 14 246 190 14 246 190 14 246 190 14
++246 190 14 246 190 14 246 190 14 246 190 14 246 190 14 246 190 14
++246 190 14 246 190 14 246 190 14 246 190 14 238 183 13 162 134 66
++46 46 46 18 18 17 6 6 6 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 10 10 10 30 30 30 78 78 78 162 134 66 210 150 10
++238 178 14 242 186 14 246 190 14 246 190 14 246 190 14 246 190 14
++246 190 14 246 190 14 246 190 14 246 190 14 246 190 14 246 190 14
++246 190 14 246 190 14 246 190 14 246 190 14 242 198 14 214 174 14
++186 174 146 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254
++254 254 254 250 250 250 250 250 250 196 186 211 136 121 175 134 114 171
++200 193 212 254 254 254 254 254 254 254 254 254 250 250 250 219 220 223
++58 58 58 2 2 2 18 18 17 166 114 6 218 158 10 231 174 11
++246 186 14 246 190 14 246 190 14 246 190 14 246 190 14 246 190 14
++246 190 14 246 190 14 246 190 14 246 190 14 246 190 14 246 190 14
++246 190 14 246 190 14 246 190 14 246 186 14 242 186 14 190 150 46
++54 54 55 22 22 22 6 6 6 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 14 14 14 38 38 38 87 86 85 179 134 43 214 154 10
++238 178 14 246 186 14 246 190 14 246 190 14 246 190 14 246 190 14
++246 190 14 246 190 14 246 190 14 246 190 14 246 190 14 246 190 14
++246 190 14 246 190 14 246 190 14 246 190 14 246 190 14 234 193 17
++188 146 14 215 214 215 250 250 250 254 254 254 254 254 254 254 254 254
++254 254 254 254 254 254 254 254 254 250 250 250 216 211 227 226 218 234
++250 250 250 254 254 254 254 254 254 250 250 250 173 173 174 26 26 26
++2 2 2 2 2 2 44 31 8 160 108 10 216 162 10 242 186 14
++246 186 14 246 190 14 246 190 14 246 190 14 246 190 14 246 190 14
++246 190 14 246 190 14 246 190 14 246 190 14 246 190 14 246 190 14
++246 190 14 246 190 14 246 190 14 238 178 14 226 166 10 142 122 74
++46 46 46 18 18 17 6 6 6 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++6 6 6 18 18 17 50 50 50 107 107 108 186 134 10 226 166 10
++242 186 14 246 190 14 246 190 14 246 190 14 246 190 14 246 190 14
++246 190 14 246 190 14 246 190 14 246 190 14 246 190 14 246 190 14
++246 190 14 246 190 14 246 190 14 246 190 14 246 190 14 226 186 14
++216 162 10 141 110 47 229 226 233 254 254 254 254 254 254 250 250 250
++254 254 254 254 254 254 254 254 254 250 250 250 250 250 250 254 254 254
++254 254 254 250 250 250 199 199 199 62 62 62 2 2 2 2 2 2
++2 2 2 2 2 6 44 31 8 160 108 10 216 162 10 238 183 13
++246 186 14 246 190 14 246 190 14 246 190 14 246 190 14 246 190 14
++246 190 14 246 190 14 246 190 14 246 190 14 246 190 14 246 190 14
++246 190 14 242 186 14 231 174 11 214 154 10 154 122 54 66 66 66
++30 30 30 10 10 10 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++6 6 6 22 22 22 54 54 55 154 122 54 204 146 10 231 174 11
++242 186 14 246 186 14 246 190 14 246 190 14 246 190 14 246 190 14
++246 190 14 246 190 14 246 190 14 246 190 14 246 190 14 246 190 14
++246 190 14 246 190 14 246 190 14 246 190 14 242 186 14 238 178 14
++216 162 10 160 108 10 63 43 6 134 133 135 219 220 223 250 250 250
++254 254 254 254 254 254 254 254 254 250 250 250 242 242 242 209 208 212
++141 139 143 66 66 66 6 6 6 6 2 7 2 2 6 2 2 6
++2 2 6 2 2 2 63 43 6 160 108 10 218 158 10 238 178 14
++246 190 14 246 190 14 246 190 14 246 190 14 246 190 14 246 190 14
++246 190 14 246 190 14 246 190 14 246 190 14 246 190 14 238 183 13
++231 174 11 218 158 10 190 142 34 126 114 90 70 70 70 38 38 38
++18 18 17 6 6 6 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++6 6 6 22 22 22 62 62 62 164 122 42 204 146 10 226 166 10
++238 178 14 238 183 13 238 183 13 242 186 14 246 186 14 246 190 14
++246 190 14 246 190 14 246 190 14 246 190 14 246 190 14 246 190 14
++246 190 14 246 190 14 246 190 14 246 190 14 246 190 14 238 178 14
++216 162 10 173 119 7 82 54 6 2 2 2 6 6 6 30 30 30
++54 54 55 62 62 62 50 50 50 38 38 38 18 18 17 6 6 6
++6 2 2 2 2 2 2 2 2 2 2 6 2 2 6 2 2 6
++2 2 6 6 6 6 82 54 6 166 114 6 214 154 10 238 178 14
++246 190 14 246 190 14 246 190 14 246 190 14 246 190 14 246 190 14
++246 190 14 246 190 14 238 183 13 238 183 13 226 171 11 210 150 10
++179 134 43 126 114 90 78 78 78 50 50 50 34 34 34 18 18 17
++6 6 6 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++6 6 6 18 18 17 46 46 46 164 122 42 194 134 10 198 138 10
++218 158 10 216 162 10 226 166 10 226 171 11 231 174 11 238 178 14
++238 183 13 238 183 13 242 186 14 246 186 14 246 190 14 246 190 14
++246 190 14 246 190 14 246 190 14 246 190 14 242 186 14 231 174 11
++210 150 10 160 108 10 104 70 6 10 10 10 6 2 2 2 2 2
++2 2 2 2 2 2 6 2 2 6 2 2 2 2 2 2 2 6
++2 2 6 2 2 6 2 2 6 2 2 6 2 2 6 2 2 6
++2 2 6 6 6 6 90 62 6 166 114 6 204 146 10 231 174 11
++242 186 14 246 190 14 246 190 14 246 190 14 246 186 14 242 186 14
++238 183 13 231 174 11 226 166 10 214 154 10 179 134 43 126 114 90
++87 86 85 58 58 58 38 38 38 22 22 22 10 10 10 6 6 6
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 14 14 14 34 34 34 66 66 66 141 110 47 158 118 10
++166 114 6 182 122 6 186 134 10 198 138 10 204 146 10 204 146 10
++210 150 10 216 162 10 226 166 10 231 174 11 238 183 13 246 186 14
++246 186 14 246 186 14 246 186 14 246 186 14 238 183 13 218 158 10
++186 134 10 154 98 6 104 70 6 14 14 14 2 2 2 2 2 6
++2 2 6 2 2 6 2 2 6 2 2 6 2 2 6 2 2 6
++2 2 6 2 2 6 2 2 6 2 2 6 2 2 6 2 2 6
++2 2 6 6 6 6 82 54 6 154 98 6 186 134 10 216 162 10
++238 178 14 238 183 13 246 186 14 242 186 14 238 183 13 231 174 11
++226 166 10 204 146 10 186 134 10 154 122 54 90 90 90 62 62 62
++42 42 42 22 22 22 14 14 14 6 6 6 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 6 6 6 18 18 17 34 34 34 62 62 62 78 78 78
++102 98 90 126 114 90 141 110 47 160 108 10 160 108 10 166 114 6
++173 119 7 182 122 6 186 134 10 198 138 10 210 150 10 216 162 10
++226 171 11 238 178 14 238 178 14 231 174 11 216 162 10 198 138 10
++160 108 10 127 82 6 90 62 6 10 10 10 2 2 6 2 2 6
++18 18 17 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38
++38 38 38 38 38 38 38 38 38 38 38 38 26 26 26 2 2 6
++2 2 2 6 6 6 63 43 6 138 93 6 173 119 7 204 146 10
++216 162 10 231 174 11 231 174 11 231 174 11 216 162 10 210 150 10
++186 134 10 160 108 10 126 114 90 82 82 82 50 50 50 30 30 30
++14 14 14 6 6 6 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 6 6 6 14 14 14 22 22 22 34 34 34
++42 42 42 58 58 58 74 74 74 87 86 85 102 98 90 122 102 70
++124 98 46 122 86 26 138 93 6 154 98 6 160 108 10 182 122 6
++186 134 10 194 134 10 204 146 10 204 146 10 182 122 6 160 108 10
++134 86 6 104 70 6 44 31 8 54 54 55 107 107 108 102 98 90
++87 86 85 82 82 82 78 78 78 78 78 78 78 78 78 78 78 78
++78 78 78 78 78 78 78 78 78 82 82 82 87 86 85 94 94 94
++107 107 108 104 103 100 85 65 33 127 82 6 160 108 10 182 122 6
++186 134 10 204 146 10 204 146 10 204 146 10 194 134 10 173 119 7
++154 98 6 107 107 108 66 66 66 42 42 42 22 22 22 10 10 10
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 6 6 6 10 10 10
++14 14 14 22 22 22 30 30 30 38 38 38 50 50 50 62 62 62
++74 74 74 90 90 90 102 98 90 114 102 78 122 86 26 127 82 6
++138 93 6 154 98 6 154 98 6 154 98 6 134 86 6 118 82 10
++104 70 6 85 65 33 102 98 90 82 82 82 58 58 58 46 46 46
++38 38 38 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34
++34 34 34 34 34 34 34 34 34 34 34 34 38 38 38 42 42 42
++54 54 55 82 82 82 91 83 66 90 62 6 127 82 6 160 108 10
++166 114 6 166 114 6 173 119 7 166 114 6 154 98 6 122 86 26
++102 98 90 62 62 62 34 34 34 18 18 17 6 6 6 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 6 6 6 6 6 6 10 10 10 18 18 17 22 22 22
++30 30 30 42 42 42 50 50 50 70 70 70 87 86 85 102 98 90
++104 84 56 104 70 6 104 70 6 104 70 6 104 70 6 90 62 6
++82 54 6 94 94 94 62 62 62 38 38 38 22 22 22 14 14 14
++10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
++6 6 6 10 10 10 10 10 10 10 10 10 10 10 10 14 14 14
++22 22 22 42 42 42 70 70 70 91 83 66 82 54 6 104 70 6
++127 82 6 138 93 6 134 86 6 118 82 10 104 84 56 87 86 85
++58 58 58 30 30 30 14 14 14 6 6 6 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 6 6 6
++10 10 10 14 14 14 18 18 17 26 26 26 38 38 38 54 54 55
++74 74 74 87 86 85 91 83 66 91 83 66 91 83 66 87 86 85
++78 78 78 50 50 50 30 30 30 14 14 14 6 6 6 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++6 6 6 18 18 17 34 34 34 58 58 58 78 78 78 78 78 78
++91 83 66 91 83 66 91 83 66 91 83 66 74 74 74 50 50 50
++26 26 26 14 14 14 10 6 18 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 6 6 6 6 6 6 14 14 14 18 18 17
++30 30 30 38 38 38 46 46 46 50 50 50 46 46 46 42 42 42
++30 30 30 18 18 17 10 10 10 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 6 6 6 14 14 14 26 26 26 38 38 38 50 50 50
++54 54 55 58 58 58 54 54 55 42 42 42 30 30 30 18 18 17
++10 10 10 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 6 6 6
++6 6 6 10 10 10 14 14 14 18 18 17 18 18 17 14 14 14
++10 10 10 6 6 6 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 6 6 6 14 14 14 18 18 17
++22 22 22 22 22 22 18 18 17 14 14 14 10 10 10 6 6 6
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
++2 2 2 2 2 2
+diff --git a/fs/Kconfig b/fs/Kconfig
+index 522469a..696a86f 100644
+--- a/fs/Kconfig
++++ b/fs/Kconfig
+@@ -485,6 +485,18 @@ config UDF_NLS
+ default y
+ depends on (UDF_FS=m && NLS) || (UDF_FS=y && NLS=y)
+
++config GCDVD_FS
++ tristate "GCDVD file system support"
++ depends on BROKEN
++ help
++ This is the filesystem used on commercial Gamecube games. Say Y if
++ you intend to mount GC DVD discs.
++
++ To compile this file system support as a module, choose M here: the
++ module will be called gcdvdfs
++
++ If unsure, say N.
++
+ endmenu
+ endif # BLOCK
+
+diff --git a/fs/Makefile b/fs/Makefile
+index d9f8afe..b36b461 100644
+--- a/fs/Makefile
++++ b/fs/Makefile
+@@ -83,6 +83,7 @@ obj-$(CONFIG_MINIX_FS) += minix/
+ obj-$(CONFIG_FAT_FS) += fat/
+ obj-$(CONFIG_BFS_FS) += bfs/
+ obj-$(CONFIG_ISO9660_FS) += isofs/
++obj-$(CONFIG_GCDVD_FS) += gcdvdfs/
+ obj-$(CONFIG_HFSPLUS_FS) += hfsplus/ # Before hfs to find wrapped HFS+
+ obj-$(CONFIG_HFS_FS) += hfs/
+ obj-$(CONFIG_ECRYPT_FS) += ecryptfs/
+diff --git a/fs/gcdvdfs/Makefile b/fs/gcdvdfs/Makefile
+new file mode 100644
+index 0000000..2ac5b5a
+--- /dev/null
++++ b/fs/gcdvdfs/Makefile
+@@ -0,0 +1,6 @@
++obj-$(CONFIG_GCDVD_FS) := gcdvdfs.o
++
++gcdvdfs-objs-y := main.o inode.o dir.o namei.o fst.o dol.o
++
++gcdvdfs-objs := $(gcdvdfs-objs-y)
++
+diff --git a/fs/gcdvdfs/dir.c b/fs/gcdvdfs/dir.c
+new file mode 100644
+index 0000000..51c7cff
+--- /dev/null
++++ b/fs/gcdvdfs/dir.c
+@@ -0,0 +1,120 @@
++/*
++ * fs/gcdvdfs/dir.c
++ *
++ * Nintendo GameCube Filesystem driver
++ * Copyright (C) 2006 The GameCube Linux Team
++ *
++ * 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/fs.h>
++#include "fst.h"
++#include "dir.h"
++#include "inode.h"
++#include "namei.h"
++
++struct readdir_data
++{
++ struct gc_dvdfs_fst *fst;
++ struct file *filp;
++ filldir_t filldir;
++ void *dirent;
++ u32 idx;
++};
++
++static int gc_dvdfs_readdir_callback(struct gc_dvdfs_file_entry *pfe,void *param)
++{
++ struct readdir_data *rdd = (struct readdir_data*)param;
++ int len;
++ const char *pname;
++
++ if ((gc_dvdfs_valid_file_entry(rdd->fst,pfe) == 0) &&
++ (rdd->idx == rdd->filp->f_pos))
++ {
++ /* add this item to the list now */
++ pname = FILENAME(rdd->fst,pfe);
++ len = strlen(pname);
++
++ if (rdd->filldir(rdd->dirent,pname,len,rdd->filp->f_pos,
++ PFE_TO_INO(rdd->fst,pfe),
++ (pfe->type == FST_DIRECTORY) ? DT_DIR : DT_REG) < 0)
++ {
++ /* failure, so stop enumerating */
++ return -1;
++ }
++ rdd->filp->f_pos++;
++ }
++ /* increment count */
++ rdd->idx++;
++ return 0;
++}
++
++static int gc_dvdfs_readdir(struct file *filp,void *dirent,filldir_t filldir)
++{
++ struct inode *inode = filp->f_dentry->d_inode;
++ struct gc_dvdfs_fst *fst = (struct gc_dvdfs_fst*)inode->i_sb->s_fs_info;
++ struct gc_dvdfs_file_entry *pfe;
++ struct readdir_data rdd;
++ int i;
++
++ /* first entry is . */
++ switch ((u32)filp->f_pos)
++ {
++ case 0:
++ if (filldir(dirent,".",1,0,inode->i_ino,DT_DIR) < 0)
++ return 0;
++ filp->f_pos = 1;
++ /* fall through */
++ case 1:
++ if (filldir(dirent,"..",2,1,parent_ino(filp->f_dentry),DT_DIR) < 0)
++ return 0;
++ filp->f_pos = 2;
++ /* fall through */
++ default:
++ if (inode->i_ino == ROOT_INO)
++ {
++ for (i=filp->f_pos-2;i<num_root_dir_entries;++i)
++ {
++ if (filldir(dirent,root_dir_entries[i].name,
++ root_dir_entries[i].name_length,filp->f_pos,
++ root_dir_entries[i].ino,
++ root_dir_entries[i].filldir_type) < 0)
++ {
++ return 0;
++ }
++
++ filp->f_pos++;
++ }
++ }
++ else if (inode->i_ino >= DATA_INO)
++ {
++ /* use enumerate, the function will check for the FST_DIRECTORY flag */
++ pfe = INO_TO_PFE(fst,inode->i_ino);
++
++ rdd.fst = fst;
++ rdd.filp = filp;
++ rdd.filldir = filldir;
++ rdd.dirent = dirent;
++ rdd.idx = 2;
++
++ gc_dvdfs_enumerate(fst,pfe,gc_dvdfs_readdir_callback,&rdd);
++ }
++ }
++ return 0;
++}
++
++struct file_operations gc_dvdfs_dir_operations =
++{
++ .read = generic_read_dir,
++ .readdir = gc_dvdfs_readdir,
++};
++
++struct inode_operations gc_dvdfs_dir_inode_operations =
++{
++ .lookup = gc_dvdfs_lookup,
++};
++
+diff --git a/fs/gcdvdfs/dir.h b/fs/gcdvdfs/dir.h
+new file mode 100644
+index 0000000..f415510
+--- /dev/null
++++ b/fs/gcdvdfs/dir.h
+@@ -0,0 +1,20 @@
++/*
++ * fs/gcdvdfs/dir.h
++ *
++ * Nintendo GameCube Filesystem driver
++ * Copyright (C) 2006 The GameCube Linux Team
++ *
++ * 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.
++ *
++ */
++
++#ifndef __dir__gc__
++#define __dir__gc__
++
++extern struct file_operations gc_dvdfs_dir_operations;
++extern struct inode_operations gc_dvdfs_dir_inode_operations;
++
++#endif
+diff --git a/fs/gcdvdfs/dol.c b/fs/gcdvdfs/dol.c
+new file mode 100644
+index 0000000..c2dc6ac
+--- /dev/null
++++ b/fs/gcdvdfs/dol.c
+@@ -0,0 +1,63 @@
++/*
++ * fs/gcdvdfs/dol.c
++ *
++ * Nintendo GameCube Filesystem driver
++ * Copyright (C) 2006 The GameCube Linux Team
++ *
++ * 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/types.h>
++#include "fst.h"
++#include "dol.h"
++
++void gc_dvdfs_fix_raw_dol_header(struct gc_dvdfs_dol_header *pdh)
++{
++#ifdef __LITTLE_ENDIAN
++#define SWAP(a) (a) = be32_to_cpu(a)
++ unsigned int i;
++
++ for (i=0;i<7;++i)
++ {
++ SWAP(pdh->text_file_pos[i]);
++ SWAP(pdh->text_mem_pos[i]);
++ SWAP(pdh->text_section_size[i]);
++ }
++
++ for (i=0;i<11;++i)
++ {
++ SWAP(pdh->data_file_pos[i]);
++ SWAP(pdh->data_mem_pos[i]);
++ SWAP(pdh->data_section_size[i]);
++ }
++
++ SWAP(pdh->bss_mem_address);
++ SWAP(pdh->bss_size);
++ SWAP(pdh->entry_point);
++#endif
++}
++
++u32 gc_dvdfs_get_dol_file_size(struct gc_dvdfs_dol_header *pdh)
++{
++ unsigned int tmp;
++ unsigned int i;
++ unsigned int max = 0;
++
++ for (i=0;i<7;++i)
++ {
++ tmp = pdh->text_file_pos[i] + pdh->text_section_size[i];
++ if (tmp > max)
++ max = tmp;
++ }
++ for (i=0;i<11;++i)
++ {
++ tmp = pdh->data_file_pos[i] + pdh->data_section_size[i];
++ if (tmp > max)
++ max = tmp;
++ }
++ return max;
++}
+diff --git a/fs/gcdvdfs/dol.h b/fs/gcdvdfs/dol.h
+new file mode 100644
+index 0000000..32c6b43
+--- /dev/null
++++ b/fs/gcdvdfs/dol.h
+@@ -0,0 +1,20 @@
++/*
++ * fs/gcdvdfs/dol.h
++ *
++ * Nintendo GameCube Filesystem driver
++ * Copyright (C) 2006 The GameCube Linux Team
++ *
++ * 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.
++ *
++ */
++#ifndef __dol__h
++#define __dol__h
++
++void gc_dvdfs_fix_raw_dol_header(struct gc_dvdfs_dol_header *pdh);
++
++u32 gc_dvdfs_get_dol_file_size(struct gc_dvdfs_dol_header *pdh);
++
++#endif
+diff --git a/fs/gcdvdfs/fst.c b/fs/gcdvdfs/fst.c
+new file mode 100644
+index 0000000..a2f8cda
+--- /dev/null
++++ b/fs/gcdvdfs/fst.c
+@@ -0,0 +1,105 @@
++/*
++ * fs/gcdvdfs/fst.c
++ *
++ * Nintendo GameCube Filesystem driver
++ * Copyright (C) 2006 The GameCube Linux Team
++ *
++ * 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/types.h>
++#include <linux/errno.h>
++#include <linux/fs.h>
++#include <linux/init.h>
++#include "fst.h"
++
++int gc_dvdfs_valid_file_entry(struct gc_dvdfs_fst *fst,struct gc_dvdfs_file_entry *pfe)
++{
++ unsigned int foffset = FILENAME_OFFSET(pfe);
++
++ if (((pfe->type != FST_FILE) && (pfe->type != FST_DIRECTORY)) ||
++ (foffset >= fst->str_table_size))
++ {
++ return -EINVAL;
++ }
++ return 0;
++}
++
++int gc_dvdfs_enumerate(struct gc_dvdfs_fst *fst,struct gc_dvdfs_file_entry *pfe,int (*callback)(struct gc_dvdfs_file_entry *pfe,void *param),void *param)
++{
++ /* get the filename */
++ unsigned int i;
++ unsigned int entries;
++ int r;
++
++ /* only enumerate directories */
++ if (pfe->type != FST_DIRECTORY)
++ {
++ return -EINVAL;
++ }
++
++ entries = pfe->dir.offset_next;
++ i=((unsigned int)pfe - (unsigned int)fst->root)/sizeof(struct gc_dvdfs_file_entry) + 1;
++ /* check if out of bounds */
++ if (i >= MAX_ENTRIES(fst) || entries > MAX_ENTRIES(fst))
++ {
++ return -EINVAL;
++ }
++
++ /* loop through the files */
++ while (i < entries)
++ {
++ /* do the callback */
++ if ((r=callback(fst->root + i,param)) < 0)
++ {
++ return r;
++ }
++
++ if (fst->root[i].type == FST_DIRECTORY)
++ {
++ if (fst->root[i].dir.offset_next <= i)
++ {
++ /* we're going backwards or looping, abort */
++ return -EINVAL;
++ }
++ i = fst->root[i].dir.offset_next;
++ }
++ else
++ {
++ ++i;
++ }
++ }
++ return 0;
++}
++
++static int gc_dvdfs_get_directory_info_callback(struct gc_dvdfs_file_entry *pfe,void *param)
++{
++ struct gc_dvdfs_directory_info *di = (struct gc_dvdfs_directory_info*)param;
++
++ if (gc_dvdfs_valid_file_entry(di->fst,pfe) == 0)
++ {
++ if (pfe->type == FST_FILE)
++ {
++ di->total_files++;
++ di->total_file_size += pfe->file.length;
++ }
++ else if (pfe->type == FST_DIRECTORY)
++ {
++ di->total_directories++;
++ }
++ }
++ return 0;
++}
++
++int gc_dvdfs_get_directory_info(struct gc_dvdfs_directory_info *di)
++{
++ di->total_files = 0;
++ di->total_directories = 0;
++ di->total_file_size = 0;
++
++ return gc_dvdfs_enumerate(di->fst,di->pfe,gc_dvdfs_get_directory_info_callback,di);
++}
+diff --git a/fs/gcdvdfs/fst.h b/fs/gcdvdfs/fst.h
+new file mode 100644
+index 0000000..ca3f5e6
+--- /dev/null
++++ b/fs/gcdvdfs/fst.h
+@@ -0,0 +1,126 @@
++/*
++ * fs/gcdvdfs/fst.h
++ *
++ * Nintendo GameCube Filesystem driver
++ * Copyright (C) 2006 The GameCube Linux Team
++ *
++ * 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.
++ *
++ */
++#ifndef __fst__h
++#define __fst__h
++
++#define FST_OFFSET 0x0424
++
++#define FST_FILE 0
++#define FST_DIRECTORY 1
++
++#pragma pack(1)
++struct gc_dvdfs_disc_header
++{
++ u32 game_code;
++ u16 maker_code;
++ u8 disc_id;
++ u8 version;
++ u8 streaming;
++ u8 streamBufSize;
++ u8 padding1[22];
++ u8 game_name[992];
++ u32 offset_dh_bin;
++ u32 addr_debug_monitor;
++ u8 padding2[24];
++ u32 offset_bootfile;
++ u32 offset_fst;
++ u32 fst_size;
++ u32 max_fst_size;
++ u32 user_position;
++ u32 user_length;
++ u8 padding[7];
++};
++
++struct gc_dvdfs_file_entry
++{
++ u8 type;
++ u8 offset_filename[3];
++ union
++ {
++ struct
++ {
++ u32 offset;
++ u32 length; /* if root, number of entries */
++ } file;
++ struct
++ {
++ u32 offset_parent;
++ u32 offset_next;
++ } dir;
++ };
++};
++
++#define APPLOADER_OFFSET 0x2440
++struct gc_dvdfs_apploader
++{
++ u8 version[10];
++ u8 padding[6];
++ u32 entry_point;
++ u32 size;
++};
++
++struct gc_dvdfs_dol_header
++{
++ u32 text_file_pos[7];
++ u32 data_file_pos[11];
++ u32 text_mem_pos[7];
++ u32 data_mem_pos[11];
++ u32 text_section_size[7];
++ u32 data_section_size[11];
++ u32 bss_mem_address;
++ u32 bss_size;
++ u32 entry_point;
++};
++
++#pragma pack()
++
++struct gc_dvdfs_fst;
++
++struct gc_dvdfs_directory_info
++{
++ struct gc_dvdfs_fst *fst;
++ struct gc_dvdfs_file_entry *pfe;
++
++ u32 total_files;
++ u32 total_directories;
++ u32 total_file_size;
++};
++
++struct gc_dvdfs_fst
++{
++ struct gc_dvdfs_file_entry *root;
++ const char *str_table;
++ u32 size;
++ u32 str_table_size;
++ u32 dol_length;
++ u32 dol_offset;
++ u32 total_files;
++ u32 total_directories;
++ u32 total_file_size;
++ struct gc_dvdfs_apploader apploader;
++ struct gc_dvdfs_dol_header dol_header;
++};
++
++#define MAX_ENTRIES(fst) (fst)->root->dir.offset_next
++#define FILENAME_OFFSET(pfe) (((pfe)->offset_filename[0] << 16) | \
++ ((pfe)->offset_filename[1] << 8) | \
++ (pfe)->offset_filename[2])
++
++#define FILENAME(fst,pfe) ((fst)->str_table + FILENAME_OFFSET(pfe))
++
++int gc_dvdfs_valid_file_entry(struct gc_dvdfs_fst *fst,struct gc_dvdfs_file_entry *pfe);
++int gc_dvdfs_enumerate(struct gc_dvdfs_fst *fst,struct gc_dvdfs_file_entry *pfe,int (*callback)(struct gc_dvdfs_file_entry *pfe,void *param),void *param);
++
++int gc_dvdfs_get_directory_info(struct gc_dvdfs_directory_info *di);
++
++#endif
+diff --git a/fs/gcdvdfs/inode.c b/fs/gcdvdfs/inode.c
+new file mode 100644
+index 0000000..ee490e1
+--- /dev/null
++++ b/fs/gcdvdfs/inode.c
+@@ -0,0 +1,105 @@
++/*
++ * fs/gcdvdfs/inode.c
++ *
++ * Nintendo GameCube Filesystem driver
++ * Copyright (C) 2006 The GameCube Linux Team
++ *
++ * 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/fs.h>
++#include <linux/mm.h>
++#include <linux/types.h>
++#include <linux/errno.h>
++#include <linux/vfs.h>
++#include <linux/highmem.h>
++#include <linux/blkdev.h>
++
++#include "fst.h"
++#include "inode.h"
++#include "dir.h"
++#include "namei.h"
++
++extern int gc_dvdfs_read_into_memory(struct super_block *s,u32 offset,
++ u32 size,unsigned char *data);
++
++static int gc_dvdfs_readpage(struct file *file,struct page *page)
++{
++ struct inode *inode = (struct inode*)page->mapping->host;
++ struct gc_dvdfs_fst *fst = (struct gc_dvdfs_fst*)inode->i_sb->s_fs_info;
++ struct gc_dvdfs_file_entry *pfe;
++ void *buf;
++ loff_t offset;
++ loff_t block_base;
++ loff_t len;
++ int ret = 0;
++
++ switch (inode->i_ino)
++ {
++ case ROOT_INO:
++ return -EIO;
++ case APPLOADER_INO:
++ block_base = APPLOADER_OFFSET;
++ break;
++ case BOOTDOL_INO:
++ block_base = fst->dol_offset;
++ break;
++ default:
++ pfe = INO_TO_PFE(fst,inode->i_ino);
++ block_base = pfe->file.offset;
++ break;
++ }
++
++ get_page(page);
++ ClearPageUptodate(page);
++ ClearPageError(page);
++ /* do a lock here */
++
++ offset = (page->index << PAGE_CACHE_SHIFT);
++ block_base += offset;
++ /* now map into kernel space and fill the page */
++ kmap(page);
++ buf = page_address(page);
++ if (offset < inode->i_size)
++ {
++ len = min((loff_t)PAGE_SIZE,inode->i_size - offset);
++ if (gc_dvdfs_read_into_memory(inode->i_sb,block_base,len,buf))
++ {
++ ret = -EIO;
++ }
++ }
++ flush_dcache_page(page);
++ kunmap(page);
++
++ /* unlock */
++
++ if (ret)
++ {
++ SetPageError(page);
++ }
++ else
++ {
++ SetPageUptodate(page);
++ }
++ page_cache_release(page);
++
++ unlock_page(page);
++ return ret;
++}
++
++struct address_space_operations gc_dvdfs_addr_operations =
++{
++ .readpage = gc_dvdfs_readpage,
++};
++
++struct root_dir_entry root_dir_entries[] = {
++ { "apploader", 9, DT_REG, APPLOADER_INO },
++ { "boot.dol" , 8, DT_REG, BOOTDOL_INO },
++ { "data" , 4, DT_DIR, DATA_INO }
++};
++
++unsigned int num_root_dir_entries = sizeof(root_dir_entries) / sizeof(root_dir_entries[0]);
+diff --git a/fs/gcdvdfs/inode.h b/fs/gcdvdfs/inode.h
+new file mode 100644
+index 0000000..9e33e76
+--- /dev/null
++++ b/fs/gcdvdfs/inode.h
+@@ -0,0 +1,37 @@
++/*
++ * fs/gcdvdfs/inode.h
++ *
++ * Nintendo GameCube Filesystem driver
++ * Copyright (C) 2006 The GameCube Linux Team
++ *
++ * 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.
++ *
++ */
++#ifndef __inode_fst__
++#define __inode_fst__
++
++#define ROOT_INO 1
++#define APPLOADER_INO 2
++#define BOOTDOL_INO 3
++#define DATA_INO 4
++
++#define PFE_TO_INO(fst,pfe) (((unsigned long)(pfe) - (unsigned long)(fst)->root)/sizeof(struct gc_dvdfs_file_entry)+DATA_INO)
++#define INO_TO_PFE(fst,ino) ((fst)->root + ((ino)-DATA_INO))
++
++struct root_dir_entry
++{
++ const char *name;
++ unsigned int name_length;
++ unsigned int filldir_type;
++ unsigned int ino;
++};
++
++extern struct root_dir_entry root_dir_entries[];
++extern unsigned int num_root_dir_entries;
++
++extern struct address_space_operations gc_dvdfs_addr_operations;
++
++#endif
+diff --git a/fs/gcdvdfs/main.c b/fs/gcdvdfs/main.c
+new file mode 100644
+index 0000000..a69807b
+--- /dev/null
++++ b/fs/gcdvdfs/main.c
+@@ -0,0 +1,346 @@
++/*
++ * fs/gcdvdfs/main.c
++ *
++ * Nintendo GameCube Filesystem driver
++ * Copyright (C) 2006 The GameCube Linux Team
++ *
++ * 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/types.h>
++#include <linux/errno.h>
++#include <linux/vmalloc.h>
++#include <linux/fs.h>
++#include <linux/init.h>
++#include <linux/genhd.h>
++#include <linux/buffer_head.h>
++#include <linux/statfs.h>
++#include "fst.h"
++#include "inode.h"
++#include "dir.h"
++#include "dol.h"
++
++#define GC_DVD_SECTOR_SIZE 2048
++#define GC_DVD_MAX_SECTORS 712880
++
++#define FST_MAGIC 0x78B39EA1
++#define DEBUG
++
++int gc_dvdfs_read_into_memory(struct super_block *s,u32 offset,u32 size,unsigned char *data)
++{
++ struct buffer_head *bh;
++ u32 sector;
++ u32 sector_end;
++ u32 byte_start;
++ u32 byte_len;
++ unsigned char *start;
++
++ sector = offset >> s->s_blocksize_bits;
++ sector_end = (offset + size - 1) >> s->s_blocksize_bits;
++ while (sector <= sector_end)
++ {
++ if (!(bh = sb_bread(s,sector)))
++ {
++ return -EINVAL;
++ }
++ /* store data into the memory buffer */
++ byte_start = sector << s->s_blocksize_bits;
++ byte_len = bh->b_size;
++ start = bh->b_data;
++ /* check if not in the middle */
++ if (byte_start < offset)
++ {
++ start = bh->b_data + (offset - byte_start);
++ byte_len -= (offset - byte_start);
++ }
++ /* check if we will overflow */
++ if (byte_len > size)
++ {
++ byte_len = size;
++ }
++ /* now copy the data */
++ memcpy(data,start,byte_len);
++ data += byte_len;
++ size -= byte_len;
++ /* move the sector along */
++ sector += (bh->b_size >> s->s_blocksize_bits);
++ brelse(bh);
++ }
++#ifdef DEBUG
++ if (size != 0)
++ {
++ printk(KERN_INFO "WARNING - read_into_memory still has a size value %u\n",
++ size);
++ }
++#endif
++ return 0;
++}
++
++static void gc_dvdfs_read_inode(struct inode *i)
++{
++ struct gc_dvdfs_directory_info di;
++ unsigned int size;
++
++ di.fst = (struct gc_dvdfs_fst*)i->i_sb->s_fs_info;
++ /* load the defaults for all inodes */
++ i->i_mtime.tv_sec = i->i_atime.tv_sec = i->i_ctime.tv_sec = 0;
++ i->i_mtime.tv_nsec = i->i_atime.tv_nsec = i->i_ctime.tv_nsec = 0;
++ i->i_uid = 0;
++ i->i_gid = 0;
++ /* load based on type */
++ if (i->i_ino == ROOT_INO)
++ {
++ i->i_fop = &gc_dvdfs_dir_operations;
++ i->i_op = &gc_dvdfs_dir_inode_operations;
++ i->i_mode = S_IFDIR | 0111;
++ i->i_nlink = 3;
++ size = 0;
++ }
++ else
++ {
++ if ((i->i_ino >= DATA_INO) &&
++ (di.pfe = INO_TO_PFE(di.fst,i->i_ino)) &&
++ (di.pfe->type == FST_DIRECTORY))
++ {
++ i->i_fop = &gc_dvdfs_dir_operations;
++ i->i_op = &gc_dvdfs_dir_inode_operations;
++ i->i_mode = S_IFDIR | 0111;
++ /* compute the number of links */
++ gc_dvdfs_get_directory_info(&di);
++ i->i_nlink = 2 + di.total_directories;
++
++ size = sizeof(struct gc_dvdfs_file_entry);
++ }
++ else
++ {
++ i->i_fop = &generic_ro_fops;
++ i->i_data.a_ops = &gc_dvdfs_addr_operations;
++ i->i_mode = S_IFREG;
++ i->i_nlink = 1;
++ switch (i->i_ino)
++ {
++ case APPLOADER_INO:
++ size = di.fst->apploader.size;
++ break;
++ case BOOTDOL_INO:
++ size = di.fst->dol_length;
++ break;
++ default:
++ size = di.pfe->file.length;
++ break;
++ }
++ }
++ }
++
++ i->i_mode |= 0444;
++ i_size_write(i,size);
++}
++
++static int gc_dvdfs_statfs(struct dentry * dentry,struct kstatfs *sfs)
++{
++ struct super_block *sb = dentry->d_sb;
++ struct gc_dvdfs_fst *fst = (struct gc_dvdfs_fst*)sb->s_fs_info;
++
++ sfs->f_type = sb->s_magic;
++ sfs->f_bsize = sb->s_blocksize;
++ sfs->f_blocks = fst->total_file_size >> sb->s_blocksize_bits;
++ sfs->f_bfree = 0;
++ sfs->f_bavail = 0;
++ sfs->f_files = fst->total_files;
++ sfs->f_ffree = 0;
++ /* sfs->f_fsid = 0; */
++ sfs->f_namelen = 256;
++ sfs->f_frsize = 0;
++ return 0;
++}
++
++static void gc_dvdfs_free_fst(struct gc_dvdfs_fst *fst)
++{
++ if (fst)
++ {
++ vfree(fst);
++ }
++}
++
++static void gc_dvdfs_put_super(struct super_block *sb)
++{
++ /* ok free my FST */
++ if (sb->s_fs_info)
++ {
++ gc_dvdfs_free_fst((struct gc_dvdfs_fst*)sb->s_fs_info);
++ sb->s_fs_info = NULL;
++ }
++}
++
++static struct super_operations gcdvdfs_ops = {
++ .read_inode = gc_dvdfs_read_inode,
++ .put_super = gc_dvdfs_put_super,
++ .statfs = gc_dvdfs_statfs
++};
++
++static int gc_dvdfs_validate_fst(struct gc_dvdfs_fst *fst)
++{
++ unsigned int entries;
++ unsigned int i;
++
++ /* make sure the FST is completely valid */
++ if (fst->root->type != FST_DIRECTORY)
++ {
++ printk(KERN_ERR "gcdvdfs: Root entry is not a directory!\n");
++ return -EINVAL;
++ }
++
++ entries = be32_to_cpu(fst->root->dir.offset_next);
++ if (entries >= (fst->size / sizeof(struct gc_dvdfs_file_entry)))
++ {
++ printk(KERN_ERR "gcdvdfs: Too many entries, will overflow the FST!\n");
++ return -EINVAL;
++ }
++ /* ok let's convert all the data to native format and compute total size*/
++ for (i=0;i<entries;++i)
++ {
++#ifdef __LITTLE_ENDIAN
++ fst->root[i].file.length = be32_to_cpu(fst->root[i].file.length);
++ fst->root[i].file.offset = be32_to_cpu(fst->root[i].file.offset);
++#endif
++ if (fst->root[i].type == FST_FILE)
++ {
++ fst->total_files++;
++ fst->total_file_size += fst->root[i].file.length;
++ }
++ else if (fst->root[i].type == FST_DIRECTORY)
++ {
++ fst->total_directories++;
++ }
++ }
++
++ return 0;
++}
++
++static int gc_dvdfs_fill_super(struct super_block *s,void *data,int silent)
++{
++ struct buffer_head *bh;
++ struct gc_dvdfs_disc_header *dh;
++ struct gc_dvdfs_fst *fst;
++ unsigned int fst_offset;
++ unsigned int fst_size;
++ unsigned int dol_offset;
++
++ sb_min_blocksize(s,GC_DVD_SECTOR_SIZE);
++ /* s->s_maxbytes = 4*GC_DVD_SECTOR_SIZE; */
++
++ /* read the header and check results */
++ if (!(bh = sb_bread(s,0)))
++ {
++ return -EINVAL;
++ }
++ else if (bh->b_size < sizeof(struct gc_dvdfs_disc_header))
++ {
++ brelse(bh);
++ return -EINVAL;
++ }
++
++ /* read the FST into memory */
++ dh = (struct gc_dvdfs_disc_header*)bh->b_data;
++ fst_offset = be32_to_cpu(dh->offset_fst);
++ fst_size = be32_to_cpu(dh->fst_size);
++ dol_offset = be32_to_cpu(dh->offset_bootfile);
++ brelse(bh);
++
++ /* now allocate the fst */
++ if (!(fst = vmalloc(sizeof(struct gc_dvdfs_fst) + fst_size)))
++ {
++ return -ENOMEM;
++ }
++ fst->size = fst_size;
++ fst->root = (struct gc_dvdfs_file_entry*)((unsigned int)fst + sizeof(struct gc_dvdfs_fst));
++ /* now try to read the fst */
++ if (gc_dvdfs_read_into_memory(s,fst_offset,fst_size,(unsigned char*)fst->root))
++ {
++ printk(KERN_ERR "gcdvdfs: Unable to read FST into memory\n");
++ goto fst_error;
++ }
++ /* now try to read the apploader */
++ if (gc_dvdfs_read_into_memory(s,APPLOADER_OFFSET,sizeof(struct gc_dvdfs_apploader),(unsigned char*)&fst->apploader))
++ {
++ printk(KERN_ERR "gcdvdfs: Unable to read apploader into memory\n");
++ goto fst_error;
++ }
++ /* fix up the apploader */
++ fst->apploader.entry_point = be32_to_cpu(fst->apploader.entry_point);
++ fst->apploader.size = be32_to_cpu(fst->apploader.size);
++ /* now try to read the dol header */
++ if (gc_dvdfs_read_into_memory(s,dol_offset,sizeof(struct gc_dvdfs_dol_header),(unsigned char*)&fst->dol_header))
++ {
++ printk(KERN_ERR "gcdvdfs: Unable to read DOL Header\n");
++ goto fst_error;
++ }
++ gc_dvdfs_fix_raw_dol_header(&fst->dol_header);
++
++ fst->dol_offset = dol_offset;
++ fst->dol_length = gc_dvdfs_get_dol_file_size(&fst->dol_header);
++ /* compute the location of the string table */
++ fst_offset = be32_to_cpu(fst->root->dir.offset_next) * sizeof(struct gc_dvdfs_file_entry);
++ fst->str_table = (unsigned char*)fst->root + fst_offset;
++ fst->str_table_size = fst->size - fst_offset;
++ fst->total_files = 0;
++ fst->total_directories = 0;
++ fst->total_file_size = 0;
++ /* now validate the fst */
++ if (gc_dvdfs_validate_fst(fst))
++ {
++ goto fst_error;
++ }
++
++ /* store my FST in s->s_fs_info */
++ s->s_flags |= MS_RDONLY | MS_NOSUID | MS_NODEV | MS_NOATIME | MS_NODIRATIME;
++ s->s_fs_info = fst;
++ s->s_magic = FST_MAGIC;
++ s->s_op = &gcdvdfs_ops;
++ if (!(s->s_root = d_alloc_root(iget(s,ROOT_INO))))
++ {
++ goto fst_error;
++ }
++ return 0;
++
++ fst_error:
++ gc_dvdfs_free_fst(fst);
++ return -EINVAL;
++}
++
++static int gc_dvdfs_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,gc_dvdfs_fill_super,mnt);
++}
++
++static struct file_system_type gcdvdfs_type = {
++ .owner = THIS_MODULE,
++ .name = "gcdvdfs",
++ .get_sb = gc_dvdfs_get_sb,
++ /*.kill_sb = gc_dvdfs_kill_sb, */
++ .kill_sb = kill_block_super,
++ .fs_flags = FS_REQUIRES_DEV
++};
++
++static int __init gc_dvdfs_init(void)
++{
++ printk(KERN_INFO "Gamecube DVD filesystem: by Todd Jeffreys\n");
++ return register_filesystem(&gcdvdfs_type);
++}
++
++static void __exit gc_dvdfs_exit(void)
++{
++ unregister_filesystem(&gcdvdfs_type);
++}
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Todd Jeffreys");
++MODULE_DESCRIPTION("Gamecube DVD filesystem");
++
++module_init(gc_dvdfs_init);
++module_exit(gc_dvdfs_exit);
+diff --git a/fs/gcdvdfs/namei.c b/fs/gcdvdfs/namei.c
+new file mode 100644
+index 0000000..2488406
+--- /dev/null
++++ b/fs/gcdvdfs/namei.c
+@@ -0,0 +1,100 @@
++/*
++ * fs/gcdvdfs/namei.c
++ *
++ * Nintendo GameCube Filesystem driver
++ * Copyright (C) 2006 The GameCube Linux Team
++ *
++ * 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/types.h>
++#include <linux/errno.h>
++#include <linux/fs.h>
++#include <linux/init.h>
++#include <linux/genhd.h>
++#include <linux/buffer_head.h>
++#include <linux/statfs.h>
++#include "fst.h"
++#include "inode.h"
++
++/*
++ i is the parent directory
++ dentry I must complete
++ nid is lookup nameidata
++
++ Complete by calling d_add(dentry,inode)
++
++ If name is not found, inode must be set to null.
++
++ Return an error only when the lookup fails due to hardware/other error
++
++*/
++
++struct gc_dvdfs_lookup_data
++{
++ struct gc_dvdfs_fst *fst;
++ const char *pname;
++ unsigned long ino;
++};
++
++static int gc_dvdfs_lookup_callback(struct gc_dvdfs_file_entry *pfe,void *param)
++{
++ struct gc_dvdfs_lookup_data *data = (struct gc_dvdfs_lookup_data*)param;
++
++ if (gc_dvdfs_valid_file_entry(data->fst,pfe) == 0)
++ {
++ if (strcmp(FILENAME(data->fst,pfe),data->pname) == 0)
++ {
++ data->ino = PFE_TO_INO(data->fst,pfe);
++ /* this will stop enumeration */
++ return -1;
++ }
++ }
++ return 0;
++}
++
++struct dentry *gc_dvdfs_lookup(struct inode *dir,struct dentry *dentry,struct nameidata *nid)
++{
++ struct inode *inode = NULL;
++ struct gc_dvdfs_lookup_data data;
++ unsigned int i;
++
++ data.ino = 0;
++ data.pname = dentry->d_name.name;
++ /* handle special case of the root directory */
++ if (dir->i_ino == ROOT_INO)
++ {
++ for (i=0;i<num_root_dir_entries;++i)
++ {
++ if (strcmp(data.pname,root_dir_entries[i].name) == 0)
++ {
++ data.ino = root_dir_entries[i].ino;
++ break;
++ }
++ }
++ }
++ else if (dir->i_ino >= DATA_INO)
++ {
++ data.fst = (struct gc_dvdfs_fst*)dir->i_sb->s_fs_info;
++
++ gc_dvdfs_enumerate(data.fst,INO_TO_PFE(data.fst,dir->i_ino),
++ gc_dvdfs_lookup_callback,&data);
++ }
++
++ /* now convert the inode number into the structure */
++ if (data.ino)
++ {
++ if (!(inode = iget(dir->i_sb,data.ino)))
++ {
++ return ERR_PTR(-EACCES);
++ }
++ }
++
++ d_add(dentry,inode);
++ return NULL;
++}
+diff --git a/fs/gcdvdfs/namei.h b/fs/gcdvdfs/namei.h
+new file mode 100644
+index 0000000..19e3da9
+--- /dev/null
++++ b/fs/gcdvdfs/namei.h
+@@ -0,0 +1,18 @@
++/*
++ * fs/gcdvdfs/namei.h
++ *
++ * Nintendo GameCube Filesystem driver
++ * Copyright (C) 2006 The GameCube Linux Team
++ *
++ * 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.
++ *
++ */
++#ifndef __gc_lookup__
++#define __gc_lookup__
++
++struct dentry *gc_dvdfs_lookup(struct inode *dir,struct dentry *dentry,struct nameidata *nid);
++
++#endif
+diff --git a/include/linux/exi.h b/include/linux/exi.h
+new file mode 100644
+index 0000000..e5fc002
+--- /dev/null
++++ b/include/linux/exi.h
+@@ -0,0 +1,331 @@
++/*
++ * include/linux/exi.h
++ *
++ * Nintendo GameCube EXpansion Interface definitions
++ * Copyright (C) 2004-2009 The GameCube Linux Team
++ * Copyright (C) 2004 Arthur Othieno <a.othieno@bluewin.ch>
++ * Copyright (C) 2004,2005 Todd Jeffreys <todd@voidpointer.org>
++ * Copyright (C) 2005,2007,2008,2009 Albert Herranz
++ *
++ * 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.
++ *
++ */
++
++#ifndef __EXI_H
++#define __EXI_H
++
++#include <linux/device.h>
++#include <linux/io.h>
++
++
++struct exi_channel;
++
++/*
++ *
++ */
++struct exi_device_id {
++ unsigned int channel;
++#define EXI_CHANNEL_ANY (~0)
++
++ unsigned int device;
++#define EXI_DEVICE_ANY (~0)
++
++ u32 id;
++#define EXI_ID_INVALID (~0)
++#define EXI_ID_NONE (EXI_ID_INVALID-1)
++};
++
++/*
++ *
++ */
++struct exi_device {
++ struct exi_channel *exi_channel;
++
++ struct exi_device_id eid;
++ int frequency;
++
++ unsigned flags;
++#define EXI_DEV_DYING (1<<0)
++
++ struct device dev;
++};
++
++#define to_exi_device(n) container_of(n, struct exi_device, dev)
++
++struct exi_device *exi_get_exi_device(struct exi_channel *exi_channel,
++ int device);
++
++/*
++ *
++ */
++struct exi_driver {
++ char *name;
++ struct exi_device_id *eid_table;
++ int frequency;
++
++ int (*probe) (struct exi_device *dev);
++ void (*remove) (struct exi_device *dev);
++
++ struct device_driver driver;
++};
++
++#define to_exi_driver(n) container_of(n, struct exi_driver, driver)
++
++
++/*
++ * EXpansion Interface devices and drivers.
++ *
++ */
++extern struct exi_device *exi_device_get(struct exi_device *exi_device);
++extern void exi_device_put(struct exi_device *exi_device);
++
++extern int exi_driver_register(struct exi_driver *exi_driver);
++extern void exi_driver_unregister(struct exi_driver *exi_driver);
++
++static inline void *exi_get_drvdata(struct exi_device *exi_dev)
++{
++ return dev_get_drvdata(&exi_dev->dev);
++}
++
++static inline void exi_set_drvdata(struct exi_device *exi_dev, void *data)
++{
++ dev_set_drvdata(&exi_dev->dev, data);
++}
++
++static inline int exi_is_dying(struct exi_device *exi_device)
++{
++ return exi_device->flags & EXI_DEV_DYING;
++}
++
++static inline int exi_set_dying(struct exi_device *exi_device, int status)
++{
++ if (status)
++ exi_device->flags |= EXI_DEV_DYING;
++ else
++ exi_device->flags &= ~EXI_DEV_DYING;
++
++ return exi_is_dying(exi_device);
++}
++
++extern u32 exi_get_id(struct exi_device *exi_device);
++
++/*
++ * EXpansion Interface channels.
++ *
++ */
++
++extern void exi_channel_init(struct exi_channel *exi_channel,
++ unsigned int channel);
++
++extern struct exi_channel *to_exi_channel(unsigned int channel);
++extern unsigned int to_channel(struct exi_channel *exi_channel);
++
++static inline struct exi_channel *exi_get_exi_channel(struct exi_device *dev)
++{
++ return dev->exi_channel;
++}
++
++#define EXI_EVENT_IRQ 0
++#define EXI_EVENT_INSERT 1
++#define EXI_EVENT_TC 2
++
++typedef int (*exi_event_handler_t)(struct exi_channel *exi_channel,
++ unsigned int event_id, void *data);
++
++extern int exi_event_register(struct exi_channel *exi_channel,
++ unsigned int event_id,
++ struct exi_device *exi_device,
++ exi_event_handler_t handler, void *data,
++ unsigned int channel_mask);
++extern int exi_event_unregister(struct exi_channel *exi_channel,
++ unsigned int event_id);
++
++
++/*
++ * Commands.
++ *
++ *
++ */
++struct exi_command {
++ int opcode;
++#define EXI_OP_READ (0x00<<2) /* same as in EXIxCR */
++#define EXI_OP_WRITE (0x01<<2) /* same as in EXIxCR */
++#define EXI_OP_READWRITE (0x02<<2) /* same as in EXIxCR */
++
++#define EXI_OP_TAKE 0x0100
++#define EXI_OP_GIVE 0x0200
++#define EXI_OP_SELECT 0x0400
++#define EXI_OP_DESELECT 0x0800
++
++#define EXI_OP_NOP -1
++
++ unsigned long flags;
++#define EXI_CMD_NOWAIT (1<<0)
++#define EXI_CMD_NODMA (1<<1)
++#define EXI_CMD_IDI (1<<2)
++
++ void *data;
++ size_t len;
++ size_t bytes_left;
++
++ dma_addr_t dma_addr;
++ size_t dma_len;
++
++ void *done_data;
++ void (*done)(struct exi_command *cmd);
++
++ struct exi_channel *exi_channel;
++ struct exi_device *exi_device;
++};
++
++#include "../drivers/exi/exi-hw.h"
++
++static inline void exi_op_basic(struct exi_command *cmd,
++ struct exi_channel *exi_channel)
++{
++ memset(cmd, 0, sizeof(*cmd));
++ cmd->exi_channel = exi_channel;
++ cmd->exi_device = exi_channel_owner(exi_channel);
++}
++
++static inline void exi_op_nop(struct exi_command *cmd,
++ struct exi_channel *exi_channel)
++{
++ exi_op_basic(cmd, exi_channel);
++ cmd->opcode = EXI_OP_NOP;
++}
++
++static inline void exi_op_take(struct exi_command *cmd,
++ struct exi_device *exi_device)
++{
++ exi_op_basic(cmd, exi_device->exi_channel);
++ cmd->opcode = EXI_OP_TAKE;
++ cmd->exi_device = exi_device;
++}
++
++static inline void exi_op_give(struct exi_command *cmd,
++ struct exi_channel *exi_channel)
++{
++ exi_op_basic(cmd, exi_channel);
++ cmd->opcode = EXI_OP_GIVE;
++}
++
++static inline void exi_op_select(struct exi_command *cmd,
++ struct exi_device *exi_device)
++{
++ exi_op_basic(cmd, exi_device->exi_channel);
++ cmd->opcode = EXI_OP_SELECT;
++ cmd->exi_device = exi_device;
++}
++
++static inline void exi_op_deselect(struct exi_command *cmd,
++ struct exi_channel *exi_channel)
++{
++ exi_op_basic(cmd, exi_channel);
++ cmd->opcode = EXI_OP_DESELECT;
++}
++
++static inline void exi_op_transfer(struct exi_command *cmd,
++ struct exi_channel *exi_channel,
++ void *data, size_t len, int opcode)
++{
++ exi_op_basic(cmd, exi_channel);
++ cmd->opcode = opcode;
++ cmd->data = data;
++ cmd->len = len;
++}
++
++
++/*
++ * EXpansion Interface interfaces.
++ *
++ */
++
++/*
++ * Raw.
++ */
++extern void exi_select_raw(struct exi_channel *exi_channel,
++ unsigned int device, unsigned int freq);
++extern void exi_deselect_raw(struct exi_channel *exi_channel);
++
++#define exi_transfer_u8_raw __exi_transfer_raw_u8
++#define exi_transfer_u16_raw __exi_transfer_raw_u16
++#define exi_transfer_u32_raw __exi_transfer_raw_u32
++
++extern void exi_transfer_raw(struct exi_channel *exi_channel,
++ void *data, size_t len, int mode);
++extern void exi_dma_transfer_raw(struct exi_channel *channel,
++ dma_addr_t data, size_t len, int mode);
++
++/*
++ * Standard.
++ */
++
++int exi_take(struct exi_device *exi_device, int wait);
++int exi_give(struct exi_device *exi_device);
++void exi_select(struct exi_device *exi_device);
++void exi_deselect(struct exi_channel *exi_channel);
++void exi_transfer(struct exi_channel *exi_channel,
++ void *data, size_t len, int opcode, unsigned long flags);
++
++static inline int exi_dev_take(struct exi_device *exi_device)
++{
++ return exi_take(exi_device, 1);
++}
++
++static inline int exi_dev_try_take(struct exi_device *exi_device)
++{
++ return exi_take(exi_device, 0);
++}
++
++static inline int exi_dev_give(struct exi_device *exi_device)
++{
++ return exi_give(exi_device);
++}
++
++static inline void exi_dev_select(struct exi_device *exi_device)
++{
++ exi_select(exi_device);
++}
++
++static inline void exi_dev_deselect(struct exi_device *exi_device)
++{
++ exi_deselect(exi_device->exi_channel);
++}
++
++static inline void exi_dev_transfer(struct exi_device *exi_device,
++ void *data, size_t len, int opcode, unsigned long flags)
++{
++ exi_transfer(exi_device->exi_channel, data, len, opcode, flags);
++}
++
++static inline void exi_dev_read(struct exi_device *dev, void *data, size_t len)
++{
++ exi_dev_transfer(dev, data, len, EXI_OP_READ, 0);
++}
++
++static inline void exi_dev_write(struct exi_device *dev, void *data, size_t len)
++{
++ exi_dev_transfer(dev, data, len, EXI_OP_WRITE, 0);
++}
++
++static inline void exi_dev_readwrite(struct exi_device *dev, void *data,
++ size_t len)
++{
++ exi_dev_transfer(dev, data, len, EXI_OP_READWRITE, 0);
++}
++
++static inline int exi_dev_set_freq(struct exi_device *dev, unsigned int freq)
++{
++ BUG_ON(freq > EXI_MAX_FREQ);
++
++ dev->frequency = freq;
++
++ return freq;
++}
++
++#endif /* __EXI_H */
++
+diff --git a/include/linux/fb.h b/include/linux/fb.h
+index 75a81ea..98ffee5 100644
+--- a/include/linux/fb.h
++++ b/include/linux/fb.h
+@@ -38,6 +38,11 @@ struct dentry;
+ #define FBIOPUT_MODEINFO 0x4617
+ #define FBIOGET_DISPINFO 0x4618
+
++#define FBIOWAITRETRACE 0x4619
++#define FBIOWAITPEFINISH 0x4620
++#define FBIOVIRTTOPHYS 0x4621
++#define FBIOFLIP 0x4622
++#define FBIOFLIPHACK 0x4623 /* libsdl */
+
+ #define FB_TYPE_PACKED_PIXELS 0 /* Packed Pixels */
+ #define FB_TYPE_PLANES 1 /* Non interleaved planes */
+@@ -896,7 +901,13 @@ struct fb_info {
+ #define fb_readq __raw_readq
+ #define fb_writeb __raw_writeb
+ #define fb_writew __raw_writew
+-#define fb_writel __raw_writel
++#ifndef CONFIG_FB_GAMECUBE /* XXX Why? O' why? */
++# define fb_writel __raw_writel
++#else
++ extern unsigned int vifb_writel(unsigned int, void *);
++# define fb_writel(b, addr) vifb_writel(b, addr)
++# define fb_writel_real(b, addr) (*(/*volatile*/ u32 __iomem *)(addr) = (b))
++#endif
+ #define fb_writeq __raw_writeq
+ #define fb_memset memset_io
+
+diff --git a/sound/ppc/Kconfig b/sound/ppc/Kconfig
+index 777de2b..82c5ad3 100644
+--- a/sound/ppc/Kconfig
++++ b/sound/ppc/Kconfig
+@@ -48,4 +48,22 @@ config SND_PS3_DEFAULT_START_DELAY
+ depends on SND_PS3
+ default "2000"
+
++config SND_GAMECUBE
++ tristate "Nintendo GameCube/Wii"
++ depends on SND && GAMECUBE_COMMON
++ help
++ Say Y here to include support for audio on the Nintendo GameCube/Wii.
++
++ To compile this driver as a module, choose M here: the module
++ will be called snd-gcn.
++
++config SND_GAMECUBE_MIC
++ tristate "Nintendo GameCube Microphone (DOL-022)"
++ depends on SND && GAMECUBE_EXI && EXPERIMENTAL
++ help
++ If you say yes to this option, support will be included for the
++ Nintendo GameCube Microphone (DOL-022).
++
++ If in doubt, say N here.
++
+ endif # SND_PPC
+diff --git a/sound/ppc/Makefile b/sound/ppc/Makefile
+index 679c45a..fa77f53 100644
+--- a/sound/ppc/Makefile
++++ b/sound/ppc/Makefile
+@@ -4,7 +4,10 @@
+ #
+
+ snd-powermac-objs := powermac.o pmac.o awacs.o burgundy.o daca.o tumbler.o keywest.o beep.o
++snd-gcn-objs := gcn-ai.o
+
+ # Toplevel Module Dependency
+ obj-$(CONFIG_SND_POWERMAC) += snd-powermac.o
+ obj-$(CONFIG_SND_PS3) += snd_ps3.o
++obj-$(CONFIG_SND_GAMECUBE) += snd-gcn.o
++obj-$(CONFIG_SND_GAMECUBE_MIC) += gcn-mic.o
+diff --git a/sound/ppc/gcn-ai.c b/sound/ppc/gcn-ai.c
+new file mode 100644
+index 0000000..92dc264
+--- /dev/null
++++ b/sound/ppc/gcn-ai.c
+@@ -0,0 +1,598 @@
++/*
++ * sound/ppc/gcn-ai.c
++ *
++ * Nintendo GameCube/Wii Audio Interface (AI) driver
++ * Copyright (C) 2004-2009 The GameCube Linux Team
++ * Copyright (C) 2007,2008,2009 Albert Herranz
++ *
++ * Based on work from mist, kirin, groepaz, Steve_-, isobel and others.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version 2
++ * of the License, or (at your option) any later version.
++ *
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/of_platform.h>
++#include <linux/interrupt.h>
++#include <linux/dma-mapping.h>
++#include <linux/io.h>
++#include <sound/core.h>
++#include <sound/pcm.h>
++#define SNDRV_GET_ID
++#include <sound/initval.h>
++
++
++#define DRV_MODULE_NAME "gcn-ai"
++#define DRV_DESCRIPTION "Nintendo GameCube/Wii Audio Interface (AI) driver"
++#define DRV_AUTHOR "Michael Steil, " \
++ "(kirin), " \
++ "(groepaz), " \
++ "Steven Looman, " \
++ "Albert Herranz"
++
++static char ai_driver_version[] = "1.0i";
++
++#define drv_printk(level, format, arg...) \
++ printk(level DRV_MODULE_NAME ": " format , ## arg)
++
++
++/*
++ * Hardware.
++ *
++ */
++
++/*
++ * DSP registers.
++ */
++#define AI_DSP_CSR 0x0a /* 16 bits */
++#define AI_CSR_RES (1<<0)
++#define AI_CSR_PIINT (1<<1)
++#define AI_CSR_HALT (1<<2)
++#define AI_CSR_AIDINT (1<<3)
++#define AI_CSR_AIDINTMASK (1<<4)
++#define AI_CSR_ARINT (1<<5)
++#define AI_CSR_ARINTMASK (1<<6)
++#define AI_CSR_DSPINT (1<<7)
++#define AI_CSR_DSPINTMASK (1<<8)
++#define AI_CSR_DSPDMA (1<<9)
++#define AI_CSR_RESETXXX (1<<11)
++
++#define AI_DSP_DMA_ADDRH 0x30 /* 16 bits */
++
++#define AI_DSP_DMA_ADDRL 0x32 /* 16 bits */
++
++#define AI_DSP_DMA_CTLLEN 0x36 /* 16 bits */
++#define AI_CTLLEN_PLAY (1<<15)
++
++#define AI_DSP_DMA_LEFT 0x3a /* 16 bits */
++
++/*
++ * AI registers.
++ */
++#define AI_AICR 0x00 /* 32 bits */
++#define AI_AICR_RATE (1<<6)
++
++
++/*
++ * Sound chip.
++ */
++struct snd_gcn {
++ struct snd_card *card;
++ struct snd_pcm *pcm;
++ struct snd_pcm_substream *playback_substream;
++ struct snd_pcm_substream *capture_substream;
++
++ int start_play;
++ int stop_play;
++
++ dma_addr_t dma_addr;
++ size_t period_size;
++ int nperiods;
++ int cur_period;
++
++ void __iomem *dsp_base;
++ void __iomem *ai_base;
++ unsigned int irq;
++
++ struct device *dev;
++};
++
++
++/*
++ * Hardware functions.
++ *
++ */
++
++static void ai_dsp_load_sample(void __iomem *dsp_base,
++ void *addr, size_t size)
++{
++ u32 daddr = (unsigned long)addr;
++
++ out_be16(dsp_base + AI_DSP_DMA_ADDRH, daddr >> 16);
++ out_be16(dsp_base + AI_DSP_DMA_ADDRL, daddr & 0xffff);
++ out_be16(dsp_base + AI_DSP_DMA_CTLLEN,
++ (in_be16(dsp_base + AI_DSP_DMA_CTLLEN) & AI_CTLLEN_PLAY) |
++ size >> 5);
++}
++
++static void ai_dsp_start_sample(void __iomem *dsp_base)
++{
++ out_be16(dsp_base + AI_DSP_DMA_CTLLEN,
++ in_be16(dsp_base + AI_DSP_DMA_CTLLEN) | AI_CTLLEN_PLAY);
++}
++
++static void ai_dsp_stop_sample(void __iomem *dsp_base)
++{
++ out_be16(dsp_base + AI_DSP_DMA_CTLLEN,
++ in_be16(dsp_base + AI_DSP_DMA_CTLLEN) & ~AI_CTLLEN_PLAY);
++}
++
++static int ai_dsp_get_remaining_byte_count(void __iomem *dsp_base)
++{
++ return in_be16(dsp_base + AI_DSP_DMA_LEFT) << 5;
++}
++
++static void ai_enable_interrupts(void __iomem *dsp_base)
++{
++ unsigned long flags;
++
++ /* enable AI DMA and DSP interrupts */
++ local_irq_save(flags);
++ out_be16(dsp_base + AI_DSP_CSR,
++ in_be16(dsp_base + AI_DSP_CSR) |
++ AI_CSR_AIDINTMASK | AI_CSR_PIINT);
++ local_irq_restore(flags);
++}
++
++static void ai_disable_interrupts(void __iomem *dsp_base)
++{
++ unsigned long flags;
++
++ /* disable AI interrupts */
++ local_irq_save(flags);
++ out_be16(dsp_base + AI_DSP_CSR,
++ in_be16(dsp_base + AI_DSP_CSR) & ~AI_CSR_AIDINTMASK);
++ local_irq_restore(flags);
++}
++
++static void ai_set_rate(void __iomem *ai_base, int fortyeight)
++{
++ /* set rate to 48KHz or 32KHz */
++ if (fortyeight)
++ out_be32(ai_base + AI_AICR,
++ in_be32(ai_base + AI_AICR) & ~AI_AICR_RATE);
++ else
++ out_be32(ai_base + AI_AICR,
++ in_be32(ai_base + AI_AICR) | AI_AICR_RATE);
++}
++
++
++static int index = SNDRV_DEFAULT_IDX1; /* index 0-MAX */
++static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
++
++static struct snd_gcn *gcn_audio;
++
++static struct snd_pcm_hardware snd_gcn_playback = {
++ .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
++ SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID),
++ .formats = SNDRV_PCM_FMTBIT_S16_BE,
++ .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
++ .rate_min = 32000,
++ .rate_max = 48000,
++ .channels_min = 2,
++ .channels_max = 2,
++ .buffer_bytes_max = 32768,
++ .period_bytes_min = 32,
++ .period_bytes_max = 32768,
++ .periods_min = 1,
++ .periods_max = 1024,
++};
++
++static int snd_gcn_open(struct snd_pcm_substream *substream)
++{
++ struct snd_gcn *chip = snd_pcm_substream_chip(substream);
++ struct snd_pcm_runtime *runtime = substream->runtime;
++
++ chip->playback_substream = substream;
++ runtime->hw = snd_gcn_playback;
++
++ /* align to 32 bytes */
++ snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
++ 32);
++ snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
++ 32);
++
++ return 0;
++}
++
++static int snd_gcn_close(struct snd_pcm_substream *substream)
++{
++ struct snd_gcn *chip = snd_pcm_substream_chip(substream);
++
++ chip->playback_substream = NULL;
++ return 0;
++}
++
++static int snd_gcn_hw_params(struct snd_pcm_substream *substream,
++ struct snd_pcm_hw_params *hw_params)
++{
++ return snd_pcm_lib_malloc_pages(substream,
++ params_buffer_bytes(hw_params));
++}
++
++static int snd_gcn_hw_free(struct snd_pcm_substream *substream)
++{
++ return snd_pcm_lib_free_pages(substream);
++}
++
++static int snd_gcn_prepare(struct snd_pcm_substream *substream)
++{
++ struct snd_gcn *chip = snd_pcm_substream_chip(substream);
++ struct snd_pcm_runtime *runtime = substream->runtime;
++
++ /* set requested sample rate */
++ switch (runtime->rate) {
++ case 32000:
++ ai_set_rate(chip->ai_base, 0);
++ break;
++ case 48000:
++ ai_set_rate(chip->ai_base, 1);
++ break;
++ default:
++ drv_printk(KERN_ERR, "unsupported rate %i\n", runtime->rate);
++ return -EINVAL;
++ }
++
++ return 0;
++}
++
++static int snd_gcn_trigger(struct snd_pcm_substream *substream, int cmd)
++{
++ struct snd_gcn *chip = snd_pcm_substream_chip(substream);
++ struct snd_pcm_runtime *runtime = substream->runtime;
++
++ switch (cmd) {
++ case SNDRV_PCM_TRIGGER_START:
++ /* do something to start the PCM engine */
++ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
++ chip->period_size = snd_pcm_lib_period_bytes(substream);
++ chip->nperiods = snd_pcm_lib_buffer_bytes(substream) /
++ chip->period_size;
++ chip->cur_period = 0;
++ chip->stop_play = 0;
++ chip->start_play = 1;
++
++ chip->dma_addr = dma_map_single(chip->dev,
++ runtime->dma_area,
++ chip->period_size,
++ DMA_TO_DEVICE);
++ ai_dsp_load_sample(chip->dsp_base, runtime->dma_area,
++ chip->period_size);
++ ai_dsp_start_sample(chip->dsp_base);
++ }
++ break;
++ case SNDRV_PCM_TRIGGER_STOP:
++ chip->stop_play = 1;
++ break;
++ default:
++ return -EINVAL;
++ }
++
++ return 0;
++}
++
++static snd_pcm_uframes_t snd_gcn_pointer(struct snd_pcm_substream *substream)
++{
++ struct snd_gcn *chip = snd_pcm_substream_chip(substream);
++ struct snd_pcm_runtime *runtime = substream->runtime;
++ int left, bytes;
++
++ left = ai_dsp_get_remaining_byte_count(chip->dsp_base);
++ bytes = chip->period_size * (chip->cur_period + 1);
++
++ return bytes_to_frames(runtime, bytes - left);
++}
++
++static irqreturn_t snd_gcn_interrupt(int irq, void *dev)
++{
++ struct snd_gcn *chip = dev;
++ void *addr;
++ unsigned long flags;
++ u16 csr;
++
++ /*
++ * This is a shared interrupt. Do nothing if it ain't ours.
++ */
++ csr = in_be16(chip->dsp_base + AI_DSP_CSR);
++ if (!(csr & AI_CSR_AIDINT))
++ return IRQ_NONE;
++
++ if (chip->start_play) {
++ chip->start_play = 0;
++ } else {
++ /* stop current sample */
++ ai_dsp_stop_sample(chip->dsp_base);
++ dma_unmap_single(chip->dev, chip->dma_addr, chip->period_size,
++ DMA_TO_DEVICE);
++
++ /* load next sample if we are not stopping */
++ if (!chip->stop_play) {
++ if (chip->cur_period < (chip->nperiods - 1))
++ chip->cur_period++;
++ else
++ chip->cur_period = 0;
++
++ addr = chip->playback_substream->runtime->dma_area
++ + (chip->cur_period * chip->period_size);
++ chip->dma_addr = dma_map_single(chip->dev,
++ addr,
++ chip->period_size,
++ DMA_TO_DEVICE);
++ ai_dsp_load_sample(chip->dsp_base, addr,
++ chip->period_size);
++ ai_dsp_start_sample(chip->dsp_base);
++
++ snd_pcm_period_elapsed(chip->playback_substream);
++ }
++ }
++ /*
++ * Ack the AI DMA interrupt, going through lengths to only ack
++ * the audio part.
++ */
++ local_irq_save(flags);
++ csr = in_be16(chip->dsp_base + AI_DSP_CSR);
++ csr &= ~(AI_CSR_PIINT | AI_CSR_ARINT | AI_CSR_DSPINT);
++ out_be16(chip->dsp_base + AI_DSP_CSR, csr);
++ local_irq_restore(flags);
++
++ return IRQ_HANDLED;
++}
++
++
++static struct snd_pcm_ops snd_gcn_playback_ops = {
++ .open = snd_gcn_open,
++ .close = snd_gcn_close,
++ .ioctl = snd_pcm_lib_ioctl,
++ .hw_params = snd_gcn_hw_params,
++ .hw_free = snd_gcn_hw_free,
++ .prepare = snd_gcn_prepare,
++ .trigger = snd_gcn_trigger,
++ .pointer = snd_gcn_pointer,
++};
++
++static int __devinit snd_gcn_new_pcm(struct snd_gcn *chip)
++{
++ struct snd_pcm *pcm;
++ int retval;
++
++ retval = snd_pcm_new(chip->card, chip->card->shortname, 0, 1, 0, &pcm);
++ if (retval < 0)
++ return retval;
++
++ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
++ &snd_gcn_playback_ops);
++
++ /* preallocate 64k buffer */
++ snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
++ snd_dma_continuous_data
++ (GFP_KERNEL), 64 * 1024,
++ 64 * 1024);
++
++ pcm->info_flags = 0;
++ pcm->private_data = chip;
++ strcpy(pcm->name, chip->card->shortname);
++
++ chip->pcm = pcm;
++
++ return 0;
++}
++
++static void ai_shutdown(struct snd_gcn *chip)
++{
++ ai_dsp_stop_sample(chip->dsp_base);
++ ai_disable_interrupts(chip->dsp_base);
++}
++
++static int __devinit ai_init(struct snd_gcn *chip,
++ struct resource *dsp, struct resource *ai,
++ unsigned int irq)
++{
++ struct snd_card *card;
++ int retval;
++
++ chip->dsp_base = ioremap(dsp->start, dsp->end - dsp->start + 1);
++ chip->ai_base = ioremap(ai->start, ai->end - ai->start + 1);
++ chip->irq = irq;
++
++ chip->stop_play = 1;
++ card = chip->card;
++
++ strcpy(card->driver, DRV_MODULE_NAME);
++ strcpy(card->shortname, card->driver);
++ sprintf(card->longname, "Nintendo GameCube Audio Interface");
++
++ /* PCM */
++ retval = snd_gcn_new_pcm(chip);
++ if (retval < 0)
++ goto err_new_pcm;
++
++ retval = request_irq(chip->irq, snd_gcn_interrupt,
++ IRQF_DISABLED | IRQF_SHARED,
++ card->shortname, chip);
++ if (retval) {
++ drv_printk(KERN_ERR, "unable to request IRQ %d\n", chip->irq);
++ goto err_request_irq;
++ }
++ ai_enable_interrupts(chip->dsp_base);
++
++ gcn_audio = chip;
++ retval = snd_card_register(card);
++ if (retval) {
++ drv_printk(KERN_ERR, "failed to register card\n");
++ goto err_card_register;
++ }
++
++ return 0;
++
++err_card_register:
++ ai_disable_interrupts(chip->dsp_base);
++ free_irq(chip->irq, chip);
++err_request_irq:
++err_new_pcm:
++ iounmap(chip->dsp_base);
++ iounmap(chip->ai_base);
++ return retval;
++}
++
++static void ai_exit(struct snd_gcn *chip)
++{
++ ai_dsp_stop_sample(chip->dsp_base);
++ ai_disable_interrupts(chip->dsp_base);
++
++ free_irq(chip->irq, chip);
++ iounmap(chip->dsp_base);
++ iounmap(chip->ai_base);
++}
++
++
++/*
++ * Device interfaces.
++ *
++ */
++
++static int ai_do_shutdown(struct device *dev)
++{
++ struct snd_gcn *chip;
++
++ chip = dev_get_drvdata(dev);
++ if (chip) {
++ ai_shutdown(chip);
++ return 0;
++ }
++ return -ENODEV;
++}
++
++static int __devinit ai_do_probe(struct device *dev,
++ struct resource *dsp, struct resource *ai,
++ unsigned int irq)
++{
++ struct snd_card *card;
++ struct snd_gcn *chip;
++ int retval;
++
++ card = snd_card_new(index, id, THIS_MODULE, sizeof(struct snd_gcn));
++ if (!card) {
++ drv_printk(KERN_ERR, "failed to allocate card\n");
++ return -ENOMEM;
++ }
++ chip = (struct snd_gcn *)card->private_data;
++ memset(chip, 0, sizeof(*chip));
++ chip->card = card;
++ dev_set_drvdata(dev, chip);
++ chip->dev = dev;
++
++ retval = ai_init(chip, dsp, ai, irq);
++ if (retval)
++ snd_card_free(card);
++
++ return retval;
++}
++
++static int ai_do_remove(struct device *dev)
++{
++ struct snd_gcn *chip;
++
++ chip = dev_get_drvdata(dev);
++ if (chip) {
++ ai_exit(chip);
++ dev_set_drvdata(dev, NULL);
++ snd_card_free(chip->card);
++ return 0;
++ }
++ return -ENODEV;
++}
++
++/*
++ * OF Platform device interfaces.
++ *
++ */
++
++static int __init ai_of_probe(struct of_device *odev,
++ const struct of_device_id *match)
++{
++ struct resource dsp, ai;
++ int retval;
++
++ retval = of_address_to_resource(odev->node, 0, &dsp);
++ if (retval) {
++ drv_printk(KERN_ERR, "no dsp io memory range found\n");
++ return -ENODEV;
++ }
++ retval = of_address_to_resource(odev->node, 1, &ai);
++ if (retval) {
++ drv_printk(KERN_ERR, "no ai io memory range found\n");
++ return -ENODEV;
++ }
++
++ return ai_do_probe(&odev->dev,
++ &dsp, &ai, irq_of_parse_and_map(odev->node, 0));
++}
++
++static int __exit ai_of_remove(struct of_device *odev)
++{
++ return ai_do_remove(&odev->dev);
++}
++
++static int ai_of_shutdown(struct of_device *odev)
++{
++ return ai_do_shutdown(&odev->dev);
++}
++
++
++static struct of_device_id ai_of_match[] = {
++ { .compatible = "nintendo,flipper-audio" },
++ { .compatible = "nintendo,hollywood-audio" },
++ { },
++};
++
++MODULE_DEVICE_TABLE(of, ai_of_match);
++
++static struct of_platform_driver ai_of_driver = {
++ .owner = THIS_MODULE,
++ .name = DRV_MODULE_NAME,
++ .match_table = ai_of_match,
++ .probe = ai_of_probe,
++ .remove = ai_of_remove,
++ .shutdown = ai_of_shutdown,
++};
++
++/*
++ * Module interfaces.
++ *
++ */
++
++static int __init ai_init_module(void)
++{
++ drv_printk(KERN_INFO, "%s - version %s\n", DRV_DESCRIPTION,
++ ai_driver_version);
++
++ return of_register_platform_driver(&ai_of_driver);
++}
++
++static void __exit ai_exit_module(void)
++{
++ of_unregister_platform_driver(&ai_of_driver);
++}
++
++module_init(ai_init_module);
++module_exit(ai_exit_module);
++
++MODULE_DESCRIPTION(DRV_DESCRIPTION);
++MODULE_AUTHOR(DRV_AUTHOR);
++MODULE_LICENSE("GPL");
++
+diff --git a/sound/ppc/gcn-mic.c b/sound/ppc/gcn-mic.c
+new file mode 100644
+index 0000000..9445a46
+--- /dev/null
++++ b/sound/ppc/gcn-mic.c
+@@ -0,0 +1,832 @@
++/*
++ * sound/ppc/gcn-mic.c
++ *
++ * Nintendo Microphone (DOL-022) driver
++ * Copyright (C) 2006-2009 The GameCube Linux Team
++ * Copyright (C) 2006,2007,2008,2009 Albert Herranz
++ *
++ * 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.
++ *
++ */
++
++#define MIC_DEBUG
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/kthread.h>
++#include <linux/delay.h>
++#include <linux/freezer.h>
++#include <linux/proc_fs.h>
++#include <linux/exi.h>
++
++#include <sound/core.h>
++#include <sound/pcm.h>
++#define SNDRV_GET_ID
++#include <sound/initval.h>
++
++#define DRV_MODULE_NAME "gcn-mic"
++#define DRV_DESCRIPTION "Nintendo Microphone (DOL-022) driver"
++#define DRV_AUTHOR "Albert Herranz"
++
++MODULE_AUTHOR(DRV_AUTHOR);
++MODULE_DESCRIPTION(DRV_DESCRIPTION);
++MODULE_LICENSE("GPL");
++
++static char mic_driver_version[] = "0.1i";
++
++#define mic_printk(level, format, arg...) \
++ printk(level DRV_MODULE_NAME ": " format , ## arg)
++
++#ifdef MIC_DEBUG
++# define DBG(fmt, args...) \
++ printk(KERN_ERR "%s: " fmt, __func__ , ## args)
++#else
++# define DBG(fmt, args...)
++#endif
++
++
++#define MIC_EXI_ID 0x0a000000
++
++#define MIC_SLOTA_CHANNEL 0 /* EXI0xxx */
++#define MIC_SLOTA_DEVICE 0 /* chip select, EXI0CSB0 */
++
++#define MIC_SLOTB_CHANNEL 1 /* EXI1xxx */
++#define MIC_SLOTB_DEVICE 0 /* chip select, EXI1CSB0 */
++
++#define MIC_SPI_CLK_IDX EXI_CLK_16MHZ
++
++
++struct mic_device {
++ spinlock_t lock;
++ unsigned long flags;
++
++ u16 status;
++ u16 control;
++#define MIC_CTL_RATE_MASK (0x3<<11)
++#define MIC_CTL_RATE_11025 (0x0<<11)
++#define MIC_CTL_RATE_22050 (0x1<<11)
++#define MIC_CTL_RATE_44100 (0x2<<11)
++#define MIC_CTL_PERIOD_MASK (0x3<<13)
++#define MIC_CTL_PERIOD_32 (0x0<<13)
++#define MIC_CTL_PERIOD_64 (0x1<<13)
++#define MIC_CTL_PERIOD_128 (0x2<<13)
++#define MIC_CTL_START_SAMPLING (1<<15)
++
++ struct task_struct *io_thread;
++ wait_queue_head_t io_waitq;
++ atomic_t io_pending;
++
++ struct snd_card *card;
++ struct snd_pcm *pcm;
++
++ struct snd_pcm_substream *c_substream;
++ u8 *c_orig, *c_cur;
++ int c_left;
++
++ int running;
++
++#ifdef CONFIG_PROC_FS
++ struct proc_dir_entry *proc;
++#endif /* CONFIG_PROC_FS */
++
++ int refcnt;
++ struct exi_device *exi_device;
++};
++
++
++/*
++ *
++ */
++static void mic_hey(struct mic_device *dev)
++{
++ struct exi_device *exi_device = dev->exi_device;
++ u8 cmd = 0xff;
++
++ exi_dev_select(exi_device);
++ exi_dev_write(exi_device, &cmd, sizeof(cmd));
++ exi_dev_deselect(exi_device);
++}
++
++/*
++ *
++ */
++static int mic_get_status(struct mic_device *dev)
++{
++ struct exi_device *exi_device = dev->exi_device;
++ u8 cmd = 0x40;
++
++ exi_dev_select(exi_device);
++ exi_dev_write(exi_device, &cmd, sizeof(cmd));
++ exi_dev_read(exi_device, &dev->status, sizeof(dev->status));
++ exi_dev_deselect(exi_device);
++
++ return dev->status;
++}
++
++/*
++ *
++ */
++static void mic_control(struct mic_device *dev)
++{
++ struct exi_device *exi_device = dev->exi_device;
++ u8 cmd[3];
++
++ cmd[0] = 0x80;
++ cmd[1] = dev->control >> 8;
++ cmd[2] = dev->control & 0xff;
++
++ DBG("control 0x80%02x%02x\n", cmd[1], cmd[2]);
++
++ exi_dev_select(exi_device);
++ exi_dev_write(exi_device, cmd, sizeof(cmd));
++ exi_dev_deselect(exi_device);
++
++}
++
++/*
++ *
++ */
++static void mic_read_period(struct mic_device *dev, void *buf, size_t len)
++{
++ struct exi_device *exi_device = dev->exi_device;
++ u8 cmd = 0x20;
++
++ exi_dev_select(exi_device);
++ exi_dev_write(exi_device, &cmd, sizeof(cmd));
++ exi_dev_read(exi_device, buf, len);
++ exi_dev_deselect(exi_device);
++
++/* DBG("mic cmd 0x20\n"); */
++}
++
++/*
++ *
++ */
++static void mic_enable_sampling(struct mic_device *dev, int enable)
++{
++ if (enable)
++ dev->control |= MIC_CTL_START_SAMPLING;
++ else
++ dev->control &= ~MIC_CTL_START_SAMPLING;
++}
++
++/*
++ *
++ */
++static int mic_set_sample_rate(struct mic_device *dev, int rate)
++{
++ u16 control;
++
++ switch (rate) {
++ case 11025:
++ control = MIC_CTL_RATE_11025;
++ break;
++ case 22050:
++ control = MIC_CTL_RATE_22050;
++ break;
++ case 44100:
++ control = MIC_CTL_RATE_44100;
++ break;
++ default:
++ mic_printk(KERN_ERR, "unsupported rate: %d\n", rate);
++ return -EINVAL;
++ }
++ dev->control &= ~MIC_CTL_RATE_MASK;
++ dev->control |= control;
++ return 0;
++}
++
++/*
++ *
++ */
++static int mic_set_period(struct mic_device *dev, int period_bytes)
++{
++ u16 control;
++
++ switch (period_bytes) {
++ case 32:
++ control = MIC_CTL_PERIOD_32;
++ break;
++ case 64:
++ control = MIC_CTL_PERIOD_64;
++ break;
++ case 128:
++ control = MIC_CTL_PERIOD_128;
++ break;
++ default:
++ mic_printk(KERN_ERR, "unsupported period: %d bytes\n",
++ period_bytes);
++ return -EINVAL;
++ }
++ dev->control &= ~MIC_CTL_PERIOD_MASK;
++ dev->control |= control;
++ return 0;
++}
++
++/*
++ * /proc support
++ *
++ */
++
++/*
++ *
++ */
++static int mic_init_proc(struct mic_device *dev)
++{
++ return 0;
++}
++
++/*
++ *
++ */
++static void mic_exit_proc(struct mic_device *dev)
++{
++}
++
++
++
++/*
++ * Driver
++ *
++ */
++
++static int index = SNDRV_DEFAULT_IDX1;
++static char *id = SNDRV_DEFAULT_STR1;
++
++static struct snd_pcm_hardware mic_snd_capture = {
++#if 0
++ .info = (SNDRV_PCM_INFO_MMAP |
++ SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_NONINTERLEAVED |
++ SNDRV_PCM_INFO_BLOCK_TRANSFER |
++ SNDRV_PCM_INFO_MMAP_VALID),
++#endif
++ .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_NONINTERLEAVED),
++ .formats = SNDRV_PCM_FMTBIT_S16_BE,
++ .rates = SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_22050 |
++ SNDRV_PCM_RATE_44100,
++ .rate_min = 11025,
++ .rate_max = 44100,
++ .channels_min = 1,
++ .channels_max = 1,
++ .buffer_bytes_max = 32768,
++ .period_bytes_min = 32,
++ .period_bytes_max = 128,
++ .periods_min = 1,
++ .periods_max = 1024,
++};
++
++#if 0
++static unsigned int period_bytes[] = { 32, 64, 128 };
++static struct snd_pcm_hw_constraint_list constraints_period_bytes = {
++ .count = ARRAY_SIZE(period_bytes),
++ .list = period_bytes,
++ .mask = 0,
++};
++#endif
++
++/*
++ *
++ */
++static void mic_wakeup_io_thread(struct mic_device *dev)
++{
++ if (!IS_ERR(dev->io_thread)) {
++ atomic_inc(&dev->io_pending);
++ wake_up(&dev->io_waitq);
++ }
++}
++
++/*
++ *
++ */
++static void mic_stop_io_thread(struct mic_device *dev)
++{
++ if (!IS_ERR(dev->io_thread)) {
++ atomic_inc(&dev->io_pending);
++ kthread_stop(dev->io_thread);
++ }
++}
++
++/*
++ * Input/Output thread. Receives audio samples from the microphone.
++ */
++static int mic_io_thread(void *param)
++{
++ struct mic_device *dev = param;
++ struct snd_pcm_substream *substream;
++ int period_bytes;
++ u16 status;
++
++ set_user_nice(current, -20);
++ set_current_state(TASK_RUNNING);
++
++ for (;;) {
++ wait_event(dev->io_waitq, atomic_read(&dev->io_pending) > 0);
++ atomic_dec(&dev->io_pending);
++
++ if (kthread_should_stop())
++ break;
++
++ if (try_to_freeze())
++ continue;
++
++ exi_dev_take(dev->exi_device);
++ status = mic_get_status(dev);
++ if (dev->running) {
++ substream = dev->c_substream;
++
++ if (!dev->c_left) {
++ dev->c_cur = dev->c_orig;
++ dev->c_left =
++ snd_pcm_lib_buffer_bytes(substream);
++ }
++
++ period_bytes = snd_pcm_lib_period_bytes(substream);
++ if (period_bytes > dev->c_left)
++ period_bytes = dev->c_left;
++ mic_read_period(dev, dev->c_cur, period_bytes);
++ dev->c_cur += period_bytes;
++ dev->c_left -= period_bytes;
++
++ exi_dev_give(dev->exi_device);
++ snd_pcm_period_elapsed(substream);
++ exi_dev_take(dev->exi_device);
++
++ if (status & 0x0200) {
++ DBG("0x0200\n");
++ mic_hey(dev);
++ mic_enable_sampling(dev, 1);
++ mic_control(dev);
++ }
++ } else {
++ /* mic_enable_sampling(dev, 0); */
++ dev->control = 0;
++ mic_control(dev);
++ }
++ exi_dev_give(dev->exi_device);
++ }
++ return 0;
++}
++
++/*
++ *
++ */
++static int mic_event_handler(struct exi_channel *exi_channel,
++ unsigned int event, void *dev0)
++{
++ struct mic_device *dev = (struct mic_device *)dev0;
++
++ /* exi channel is not taken, no exi operations here please */
++ mic_wakeup_io_thread(dev);
++
++ return 0;
++}
++
++static int hw_rule_period_bytes_by_rate(struct snd_pcm_hw_params *params,
++ struct snd_pcm_hw_rule *rule)
++{
++ struct snd_interval *period_bytes =
++ hw_param_interval(params, SNDRV_PCM_HW_PARAM_PERIOD_BYTES);
++ struct snd_interval *rate =
++ hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
++
++ DBG("rate: min %d, max %d\n", rate->min, rate->max);
++
++ if (rate->min == rate->max) {
++ if (rate->min >= 44100) {
++ struct snd_interval t = {
++ .min = 128,
++ .max = 128,
++ .integer = 1,
++ };
++ return snd_interval_refine(period_bytes, &t);
++ } else if (rate->min >= 22050) {
++ struct snd_interval t = {
++ .min = 32,
++ .max = 32,
++ .integer = 1,
++ };
++ return snd_interval_refine(period_bytes, &t);
++ } else {
++ struct snd_interval t = {
++ .min = 32,
++ .max = 32,
++ .integer = 1,
++ };
++ return snd_interval_refine(period_bytes, &t);
++ }
++ }
++ return 0;
++}
++
++static int mic_snd_pcm_capture_open(struct snd_pcm_substream *substream)
++{
++ struct mic_device *dev = snd_pcm_substream_chip(substream);
++ struct snd_pcm_runtime *runtime = substream->runtime;
++ unsigned long flags;
++ int retval;
++
++ DBG("enter\n");
++
++ spin_lock_irqsave(&dev->lock, flags);
++ dev->running = 0;
++ dev->c_substream = substream;
++ spin_unlock_irqrestore(&dev->lock, flags);
++
++ runtime->hw = mic_snd_capture;
++
++#if 0
++ /* only 32, 64 and 128 */
++ retval = snd_pcm_hw_constraint_list(runtime, 0,
++ SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
++ &constraints_period_bytes);
++ if (retval < 0)
++ return retval;
++#endif
++ snd_pcm_hw_rule_add(runtime, 0,
++ SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
++ hw_rule_period_bytes_by_rate, 0,
++ SNDRV_PCM_HW_PARAM_RATE, -1);
++
++ /* align to 32 bytes */
++ retval = snd_pcm_hw_constraint_step(runtime, 0,
++ SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
++ 32);
++ return retval;
++
++}
++
++static int mic_snd_pcm_capture_close(struct snd_pcm_substream *substream)
++{
++ struct mic_device *dev = snd_pcm_substream_chip(substream);
++ unsigned long flags;
++
++DBG("enter\n");
++
++ spin_lock_irqsave(&dev->lock, flags);
++ dev->running = 0;
++ dev->c_substream = NULL;
++ spin_unlock_irqrestore(&dev->lock, flags);
++
++ mic_wakeup_io_thread(dev);
++
++ return 0;
++}
++
++static int mic_snd_pcm_hw_params(struct snd_pcm_substream *substream,
++ struct snd_pcm_hw_params *hw_params)
++{
++DBG("enter\n");
++
++ return snd_pcm_lib_malloc_pages(substream,
++ params_buffer_bytes(hw_params));
++}
++
++static int mic_snd_pcm_hw_free(struct snd_pcm_substream *substream)
++{
++DBG("enter\n");
++
++ snd_pcm_lib_free_pages(substream);
++ return 0;
++}
++
++static int mic_snd_pcm_prepare(struct snd_pcm_substream *substream)
++{
++ struct mic_device *dev = snd_pcm_substream_chip(substream);
++ struct snd_pcm_runtime *runtime = substream->runtime;
++ unsigned long flags;
++ int retval;
++
++DBG("enter\n");
++
++ mic_printk(KERN_INFO, "rate=%d, channels=%d, sample_bits=%d\n",
++ runtime->rate, runtime->channels,
++ runtime->sample_bits);
++ mic_printk(KERN_INFO, "format=%d, access=%d\n",
++ runtime->format, runtime->access);
++ mic_printk(KERN_INFO, "buffer_bytes=%d, period_bytes=%d\n",
++ snd_pcm_lib_buffer_bytes(substream),
++ snd_pcm_lib_period_bytes(substream));
++
++ spin_lock_irqsave(&dev->lock, flags);
++ dev->c_orig = runtime->dma_area;
++ dev->c_left = 0;
++ spin_unlock_irqrestore(&dev->lock, flags);
++
++ retval = mic_set_sample_rate(dev, runtime->rate);
++ if (retval < 0)
++ return retval;
++
++ retval = mic_set_period(dev, snd_pcm_lib_period_bytes(substream));
++
++ return retval;
++}
++
++static int mic_snd_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
++{
++ struct mic_device *dev = snd_pcm_substream_chip(substream);
++
++ switch (cmd) {
++ case SNDRV_PCM_TRIGGER_START:
++ if (!dev->running) {
++ DBG("trigger start\n");
++ dev->running = 1;
++ exi_dev_take(dev->exi_device);
++ mic_hey(dev);
++ mic_enable_sampling(dev, 1);
++ mic_control(dev);
++ exi_dev_give(dev->exi_device);
++ }
++ break;
++ case SNDRV_PCM_TRIGGER_STOP:
++ DBG("trigger stop\n");
++ dev->running = 0;
++ break;
++ }
++ return 0;
++}
++
++static snd_pcm_uframes_t
++mic_snd_pcm_pointer(struct snd_pcm_substream *substream)
++{
++ struct mic_device *dev = snd_pcm_substream_chip(substream);
++ size_t ptr;
++
++ if (!dev->running || !dev->c_left)
++ return 0;
++
++ ptr = dev->c_cur - dev->c_orig;
++ return bytes_to_frames(substream->runtime, ptr);
++}
++
++
++static struct snd_pcm_ops mic_snd_pcm_capture_ops = {
++ .open = mic_snd_pcm_capture_open,
++ .close = mic_snd_pcm_capture_close,
++ .ioctl = snd_pcm_lib_ioctl,
++ .hw_params = mic_snd_pcm_hw_params,
++ .hw_free = mic_snd_pcm_hw_free,
++ .prepare = mic_snd_pcm_prepare,
++ .trigger = mic_snd_pcm_trigger,
++ .pointer = mic_snd_pcm_pointer,
++};
++
++/*
++ *
++ */
++static int mic_snd_new_pcm(struct mic_device *dev)
++{
++ struct snd_pcm *pcm;
++ int retval;
++
++DBG("enter\n");
++
++ retval = snd_pcm_new(dev->card, dev->card->shortname, 0, 0, 1, &pcm);
++ if (retval < 0)
++ return retval;
++
++ pcm->private_data = dev;
++ strcpy(pcm->name, dev->card->shortname);
++ dev->pcm = pcm;
++
++ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
++ &mic_snd_pcm_capture_ops);
++
++ snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
++ snd_dma_continuous_data
++ (GFP_KERNEL),
++ 32*1024, 32*1024);
++ return 0;
++}
++
++/*
++ *
++ */
++static int mic_init_snd(struct mic_device *dev)
++{
++ struct snd_card *card;
++ int retval = -ENOMEM;
++
++DBG("enter\n");
++
++ card = snd_card_new(index, id, THIS_MODULE, 0);
++ if (!card) {
++ mic_printk(KERN_ERR, "unable to create sound card\n");
++ goto err_card;
++ }
++
++ strcpy(card->driver, DRV_MODULE_NAME);
++ strcpy(card->shortname, DRV_MODULE_NAME);
++ strcpy(card->longname, "Nintendo GameCube Microphone");
++
++ dev->card = card;
++
++ retval = mic_snd_new_pcm(dev);
++ if (retval < 0)
++ goto err_new_pcm;
++
++ retval = snd_card_register(card);
++ if (retval) {
++ mic_printk(KERN_ERR, "unable to register sound card\n");
++ goto err_card_register;
++ }
++
++ return 0;
++
++err_card_register:
++err_new_pcm:
++ snd_card_free(card);
++ dev->card = NULL;
++err_card:
++ return retval;
++}
++
++/*
++ *
++ */
++static void mic_exit_snd(struct mic_device *dev)
++{
++DBG("enter\n");
++
++ if (dev->card) {
++ snd_card_disconnect(dev->card);
++ snd_card_free_when_closed(dev->card);
++
++ dev->card = NULL;
++ dev->pcm = NULL;
++ dev->c_substream = NULL;
++ }
++}
++
++/*
++ *
++ */
++static int mic_init(struct mic_device *dev)
++{
++ struct exi_device *exi_device = dev->exi_device;
++ struct exi_channel *exi_channel = exi_get_exi_channel(exi_device);
++ int channel;
++ int retval = -ENOMEM;
++
++DBG("enter\n");
++
++ spin_lock_init(&dev->lock);
++
++ dev->running = 0;
++
++ retval = mic_init_snd(dev);
++ if (retval)
++ goto err_init_snd;
++
++ init_waitqueue_head(&dev->io_waitq);
++ channel = to_channel(exi_get_exi_channel(dev->exi_device));
++ dev->io_thread = kthread_run(mic_io_thread, dev, "kmicd/%d", channel);
++ if (IS_ERR(dev->io_thread)) {
++ mic_printk(KERN_ERR, "error creating io thread\n");
++ goto err_io_thread;
++ }
++
++ retval = exi_event_register(exi_channel, EXI_EVENT_IRQ,
++ exi_device,
++ mic_event_handler, dev,
++ 0 /*(1 << to_channel(exi_channel))*/);
++ if (retval) {
++ mic_printk(KERN_ERR, "error registering exi event\n");
++ goto err_event_register;
++ }
++
++ retval = mic_init_proc(dev);
++ if (retval)
++ goto err_init_proc;
++
++ return 0;
++
++err_init_proc:
++ exi_event_unregister(exi_channel, EXI_EVENT_IRQ);
++err_event_register:
++ mic_stop_io_thread(dev);
++err_io_thread:
++ mic_exit_snd(dev);
++err_init_snd:
++ return retval;
++
++}
++
++/*
++ *
++ */
++static void mic_exit(struct mic_device *dev)
++{
++ struct exi_device *exi_device = dev->exi_device;
++ struct exi_channel *exi_channel = exi_get_exi_channel(exi_device);
++
++DBG("enter\n");
++
++ dev->running = 0;
++
++ mic_exit_proc(dev);
++
++ exi_event_unregister(exi_channel, EXI_EVENT_IRQ);
++
++ if (!IS_ERR(dev->io_thread))
++ mic_stop_io_thread(dev);
++
++ mic_exit_snd(dev);
++}
++
++/*
++ *
++ */
++static int mic_probe(struct exi_device *exi_device)
++{
++ struct mic_device *dev;
++ int retval;
++
++ /* we only care about the microphone */
++ if (exi_device->eid.id != MIC_EXI_ID)
++ return -ENODEV;
++
++ DBG("Microphone inserted\n");
++
++ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
++ if (!dev)
++ return -ENOMEM;
++
++ dev->exi_device = exi_device_get(exi_device);
++ exi_set_drvdata(exi_device, dev);
++
++ retval = mic_init(dev);
++ if (retval) {
++ exi_set_drvdata(exi_device, NULL);
++ exi_device_put(exi_device);
++ dev->exi_device = NULL;
++ kfree(dev);
++ }
++
++ return retval;
++}
++
++/*
++ *
++ */
++static void mic_remove(struct exi_device *exi_device)
++{
++ struct mic_device *dev = exi_get_drvdata(exi_device);
++
++ DBG("Microphone removed\n");
++
++ if (dev) {
++ mic_exit(dev);
++ if (dev->exi_device)
++ exi_device_put(dev->exi_device);
++ dev->exi_device = NULL;
++ kfree(dev);
++ }
++ exi_set_drvdata(exi_device, NULL);
++}
++
++static struct exi_device_id mic_eid_table[] = {
++ [0] = {
++ .channel = MIC_SLOTA_CHANNEL,
++ .device = MIC_SLOTA_DEVICE,
++ .id = MIC_EXI_ID,
++ },
++ [1] = {
++ .channel = MIC_SLOTB_CHANNEL,
++ .device = MIC_SLOTB_DEVICE,
++ .id = MIC_EXI_ID,
++ },
++ {.id = 0}
++};
++
++static struct exi_driver mic_driver = {
++ .name = DRV_MODULE_NAME,
++ .eid_table = mic_eid_table,
++ .frequency = MIC_SPI_CLK_IDX,
++ .probe = mic_probe,
++ .remove = mic_remove,
++};
++
++static int __init mic_init_module(void)
++{
++ int retval = 0;
++
++ mic_printk(KERN_INFO, "%s - version %s\n", DRV_DESCRIPTION,
++ mic_driver_version);
++
++ retval = exi_driver_register(&mic_driver);
++
++ return retval;
++}
++
++static void __exit mic_exit_module(void)
++{
++ exi_driver_unregister(&mic_driver);
++}
++
++module_init(mic_init_module);
++module_exit(mic_exit_module);
++
diff --git a/recipes/linux/linux/progear/defconfig b/recipes/linux/linux/progear/defconfig
new file mode 100644
index 0000000000..b014773b0f
--- /dev/null
+++ b/recipes/linux/linux/progear/defconfig
@@ -0,0 +1,1832 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.27
+# Thu Nov 27 20:04:05 2008
+#
+# CONFIG_64BIT is not set
+CONFIG_X86_32=y
+# CONFIG_X86_64 is not set
+CONFIG_X86=y
+CONFIG_ARCH_DEFCONFIG="arch/x86/configs/i386_defconfig"
+# CONFIG_GENERIC_LOCKBREAK is not set
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_CLOCKSOURCE_WATCHDOG=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_FAST_CMPXCHG_LOCAL=y
+CONFIG_MMU=y
+CONFIG_ZONE_DMA=y
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_GENERIC_IOMAP=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_HWEIGHT=y
+# CONFIG_GENERIC_GPIO is not set
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+# CONFIG_GENERIC_TIME_VSYSCALL is not set
+CONFIG_ARCH_HAS_CPU_RELAX=y
+CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y
+# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_HAVE_CPUMASK_OF_CPU_MAP is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+# CONFIG_ZONE_DMA32 is not set
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+# CONFIG_AUDIT_ARCH is not set
+CONFIG_ARCH_SUPPORTS_AOUT=y
+CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_X86_BIOS_REBOOT=y
+CONFIG_KTIME_SCALAR=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+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_AUDIT=y
+# CONFIG_AUDITSYSCALL is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+# CONFIG_BLK_DEV_INITRD is not set
+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_PCSPKR_PLATFORM=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_BASE_FULL=y
+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_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+# CONFIG_HAVE_ARCH_TRACEHOOK is not set
+# CONFIG_HAVE_DMA_ATTRS is not set
+# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+# CONFIG_HAVE_CLK is not set
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_MODVERSIONS=y
+# 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
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+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"
+# CONFIG_CLASSIC_RCU is not set
+
+#
+# Processor type and features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+# CONFIG_SMP is not set
+CONFIG_X86_PC=y
+# CONFIG_X86_ELAN is not set
+# CONFIG_X86_VOYAGER is not set
+# CONFIG_X86_GENERICARCH is not set
+# CONFIG_X86_VSMP is not set
+# CONFIG_X86_RDC321X is not set
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+# CONFIG_PARAVIRT_GUEST is not set
+# CONFIG_MEMTEST is not set
+# CONFIG_M386 is not set
+# CONFIG_M486 is not set
+# CONFIG_M586 is not set
+# CONFIG_M586TSC is not set
+# CONFIG_M586MMX is not set
+# CONFIG_M686 is not set
+# CONFIG_MPENTIUMII is not set
+# CONFIG_MPENTIUMIII is not set
+# CONFIG_MPENTIUMM is not set
+# CONFIG_MPENTIUM4 is not set
+# CONFIG_MK6 is not set
+# CONFIG_MK7 is not set
+# CONFIG_MK8 is not set
+CONFIG_MCRUSOE=y
+# CONFIG_MEFFICEON is not set
+# CONFIG_MWINCHIPC6 is not set
+# CONFIG_MWINCHIP2 is not set
+# CONFIG_MWINCHIP3D is not set
+# CONFIG_MGEODEGX1 is not set
+# CONFIG_MGEODE_LX is not set
+# CONFIG_MCYRIXIII is not set
+# CONFIG_MVIAC3_2 is not set
+# CONFIG_MVIAC7 is not set
+# CONFIG_MPSC is not set
+# CONFIG_MCORE2 is not set
+# CONFIG_GENERIC_CPU is not set
+# CONFIG_X86_GENERIC is not set
+CONFIG_X86_CPU=y
+CONFIG_X86_CMPXCHG=y
+CONFIG_X86_L1_CACHE_SHIFT=5
+CONFIG_X86_XADD=y
+CONFIG_X86_WP_WORKS_OK=y
+CONFIG_X86_INVLPG=y
+CONFIG_X86_BSWAP=y
+CONFIG_X86_POPAD_OK=y
+CONFIG_X86_TSC=y
+CONFIG_X86_MINIMUM_CPU_FAMILY=4
+CONFIG_X86_DEBUGCTLMSR=y
+CONFIG_HPET_TIMER=y
+CONFIG_HPET_EMULATE_RTC=y
+CONFIG_DMI=y
+# CONFIG_IOMMU_HELPER is not set
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_PREEMPT_RCU=y
+CONFIG_RCU_TRACE=y
+# CONFIG_X86_UP_APIC is not set
+# CONFIG_X86_MCE is not set
+# CONFIG_VM86 is not set
+# CONFIG_TOSHIBA is not set
+# CONFIG_I8K is not set
+# CONFIG_X86_REBOOTFIXUPS is not set
+# CONFIG_MICROCODE is not set
+CONFIG_X86_MSR=m
+# CONFIG_X86_CPUID is not set
+CONFIG_NOHIGHMEM=y
+# CONFIG_HIGHMEM4G is not set
+# CONFIG_HIGHMEM64G is not set
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_3G_OPT is not set
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_2G_OPT is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+# CONFIG_X86_PAE is not set
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+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=y
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_RESOURCES_64BIT=y
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_MATH_EMULATION is not set
+# CONFIG_MTRR is not set
+# CONFIG_EFI is not set
+CONFIG_SECCOMP=y
+# CONFIG_HZ_100 is not set
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_300 is not set
+CONFIG_HZ_1000=y
+CONFIG_HZ=1000
+CONFIG_SCHED_HRTICK=y
+CONFIG_KEXEC=y
+# CONFIG_KEXEC_JUMP is not set
+CONFIG_PHYSICAL_START=0x100000
+# CONFIG_RELOCATABLE is not set
+CONFIG_PHYSICAL_ALIGN=0x100000
+# CONFIG_COMPAT_VDSO is not set
+
+#
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+CONFIG_HIBERNATION=y
+CONFIG_PM_STD_PARTITION=""
+CONFIG_ACPI=y
+CONFIG_ACPI_SLEEP=y
+# CONFIG_ACPI_PROCFS is not set
+# CONFIG_ACPI_PROCFS_POWER is not set
+CONFIG_ACPI_SYSFS_POWER=y
+# CONFIG_ACPI_PROC_EVENT is not set
+# CONFIG_ACPI_AC is not set
+CONFIG_ACPI_BATTERY=m
+# CONFIG_ACPI_BUTTON is not set
+# CONFIG_ACPI_FAN is not set
+# CONFIG_ACPI_DOCK is not set
+# CONFIG_ACPI_PROCESSOR is not set
+# CONFIG_ACPI_WMI is not set
+# CONFIG_ACPI_ASUS is not set
+# CONFIG_ACPI_TOSHIBA is not set
+# CONFIG_ACPI_CUSTOM_DSDT is not set
+CONFIG_ACPI_BLACKLIST_YEAR=0
+# CONFIG_ACPI_DEBUG is not set
+CONFIG_ACPI_EC=y
+# CONFIG_ACPI_PCI_SLOT is not set
+CONFIG_ACPI_POWER=y
+CONFIG_ACPI_SYSTEM=y
+CONFIG_X86_PM_TIMER=y
+# CONFIG_ACPI_CONTAINER is not set
+CONFIG_ACPI_SBS=m
+# CONFIG_APM is not set
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_IDLE_GOV_LADDER=y
+CONFIG_CPU_IDLE_GOV_MENU=y
+
+#
+# Bus options (PCI etc.)
+#
+CONFIG_PCI=y
+# CONFIG_PCI_GOBIOS is not set
+# CONFIG_PCI_GOMMCONFIG is not set
+# CONFIG_PCI_GODIRECT is not set
+# CONFIG_PCI_GOOLPC is not set
+CONFIG_PCI_GOANY=y
+CONFIG_PCI_BIOS=y
+CONFIG_PCI_DIRECT=y
+CONFIG_PCI_MMCONFIG=y
+CONFIG_PCI_DOMAINS=y
+# CONFIG_PCIEPORTBUS is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCI_LEGACY is not set
+# CONFIG_PCI_DEBUG is not set
+CONFIG_ISA_DMA_API=y
+# CONFIG_ISA is not set
+# CONFIG_MCA is not set
+# CONFIG_SCx200 is not set
+# CONFIG_OLPC is not set
+CONFIG_PCCARD=m
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=m
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
+CONFIG_CARDBUS=y
+
+#
+# PC-card bridges
+#
+CONFIG_YENTA=m
+CONFIG_YENTA_O2=y
+CONFIG_YENTA_RICOH=y
+CONFIG_YENTA_TI=y
+CONFIG_YENTA_ENE_TUNE=y
+CONFIG_YENTA_TOSHIBA=y
+# CONFIG_PD6729 is not set
+# CONFIG_I82092 is not set
+CONFIG_PCCARD_NONSTATIC=m
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats / Emulations
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_MISC=m
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+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_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=m
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE 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 is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_IPV6_OPTIMISTIC_DAD=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_IPV6_MIP6=m
+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=m
+CONFIG_IPV6_SIT=m
+CONFIG_IPV6_NDISC_NODETYPE=y
+CONFIG_IPV6_TUNNEL=m
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_MROUTE 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
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+CONFIG_IRDA=m
+
+#
+# IrDA protocols
+#
+CONFIG_IRLAN=m
+CONFIG_IRCOMM=m
+# CONFIG_IRDA_ULTRA is not set
+
+#
+# IrDA options
+#
+# CONFIG_IRDA_CACHE_LAST_LSAP is not set
+# CONFIG_IRDA_FAST_RR is not set
+# CONFIG_IRDA_DEBUG is not set
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+CONFIG_IRTTY_SIR=m
+
+#
+# Dongle support
+#
+# CONFIG_DONGLE is not set
+# CONFIG_KINGSUN_DONGLE is not set
+# CONFIG_KSDAZZLE_DONGLE is not set
+# CONFIG_KS959_DONGLE is not set
+
+#
+# FIR device drivers
+#
+# CONFIG_USB_IRDA is not set
+# CONFIG_SIGMATEL_FIR is not set
+# CONFIG_NSC_FIR is not set
+# CONFIG_WINBOND_FIR is not set
+# CONFIG_TOSHIBA_FIR is not set
+# CONFIG_SMC_IRCC_FIR is not set
+CONFIG_ALI_FIR=m
+# CONFIG_VLSI_FIR is not set
+# CONFIG_VIA_FIR is not set
+# CONFIG_MCS_FIR 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_HCIBTUSB=m
+# CONFIG_BT_HCIUART is not set
+# CONFIG_BT_HCIBCM203X is not set
+# CONFIG_BT_HCIBPA10X is not set
+# CONFIG_BT_HCIBFUSB is not set
+# CONFIG_BT_HCIDTL1 is not set
+# CONFIG_BT_HCIBT3C is not set
+# CONFIG_BT_HCIBLUECARD is not set
+# CONFIG_BT_HCIBTUART is not set
+# CONFIG_BT_HCIVHCI is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+CONFIG_CFG80211=m
+CONFIG_NL80211=y
+CONFIG_WIRELESS_EXT=y
+CONFIG_WIRELESS_EXT_SYSFS=y
+CONFIG_MAC80211=m
+
+#
+# Rate control algorithm selection
+#
+CONFIG_MAC80211_RC_PID=y
+CONFIG_MAC80211_RC_DEFAULT_PID=y
+CONFIG_MAC80211_RC_DEFAULT="pid"
+# CONFIG_MAC80211_MESH is not set
+# CONFIG_MAC80211_LEDS is not set
+# CONFIG_MAC80211_DEBUGFS is not set
+# CONFIG_MAC80211_DEBUG_MENU 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_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=m
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+CONFIG_PNP=y
+# CONFIG_PNP_DEBUG is not set
+
+#
+# Protocols
+#
+CONFIG_PNPACPI=y
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_FD is not set
+# 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=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+# 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 is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_BLK_DEV_HD is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# 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=m
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+CONFIG_CHR_DEV_SG=m
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+CONFIG_SCSI_SCAN_ASYNC=y
+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_SRP_ATTRS is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
+# CONFIG_SCSI_DH is not set
+CONFIG_ATA=y
+# CONFIG_ATA_NONSTANDARD is not set
+# CONFIG_ATA_ACPI is not set
+# CONFIG_SATA_PMP is not set
+# CONFIG_SATA_AHCI is not set
+# CONFIG_SATA_SIL24 is not set
+CONFIG_ATA_SFF=y
+# CONFIG_SATA_SVW is not set
+# CONFIG_ATA_PIIX is not set
+# CONFIG_SATA_MV is not set
+# CONFIG_SATA_NV is not set
+# CONFIG_PDC_ADMA is not set
+# CONFIG_SATA_QSTOR is not set
+# CONFIG_SATA_PROMISE is not set
+# CONFIG_SATA_SX4 is not set
+# CONFIG_SATA_SIL is not set
+# CONFIG_SATA_SIS is not set
+# CONFIG_SATA_ULI is not set
+# CONFIG_SATA_VIA is not set
+# CONFIG_SATA_VITESSE is not set
+# CONFIG_SATA_INIC162X is not set
+CONFIG_PATA_ALI=y
+# CONFIG_PATA_AMD is not set
+# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATIIXP is not set
+# CONFIG_PATA_CMD640_PCI is not set
+# CONFIG_PATA_CMD64X is not set
+# CONFIG_PATA_CS5520 is not set
+# CONFIG_PATA_CS5530 is not set
+# CONFIG_PATA_CS5535 is not set
+# CONFIG_PATA_CS5536 is not set
+# CONFIG_PATA_CYPRESS is not set
+# CONFIG_PATA_EFAR is not set
+# CONFIG_ATA_GENERIC is not set
+# CONFIG_PATA_HPT366 is not set
+# CONFIG_PATA_HPT37X is not set
+# CONFIG_PATA_HPT3X2N is not set
+# CONFIG_PATA_HPT3X3 is not set
+# CONFIG_PATA_IT821X is not set
+# CONFIG_PATA_IT8213 is not set
+# CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_TRIFLEX is not set
+# CONFIG_PATA_MARVELL is not set
+# CONFIG_PATA_MPIIX is not set
+# CONFIG_PATA_OLDPIIX is not set
+# CONFIG_PATA_NETCELL is not set
+# CONFIG_PATA_NINJA32 is not set
+# CONFIG_PATA_NS87410 is not set
+# CONFIG_PATA_NS87415 is not set
+# CONFIG_PATA_OPTI is not set
+# CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PCMCIA is not set
+# CONFIG_PATA_PDC_OLD is not set
+# CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RZ1000 is not set
+# CONFIG_PATA_SC1200 is not set
+# CONFIG_PATA_SERVERWORKS is not set
+# CONFIG_PATA_PDC2027X is not set
+# CONFIG_PATA_SIL680 is not set
+# CONFIG_PATA_SIS is not set
+# CONFIG_PATA_VIA is not set
+# CONFIG_PATA_WINBOND is not set
+# CONFIG_PATA_PLATFORM is not set
+# CONFIG_PATA_SCH is not set
+# CONFIG_MD is not set
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# Enable only one of the two stacks, unless you know what you are doing
+#
+# CONFIG_FIREWIRE is not set
+# CONFIG_IEEE1394 is not set
+# CONFIG_I2O is not set
+# CONFIG_MACINTOSH_DRIVERS is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_NET_SB1000 is not set
+# CONFIG_ARCNET is not set
+# CONFIG_NET_ETHERNET is not set
+CONFIG_MII=m
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_TR is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+CONFIG_WLAN_80211=y
+# CONFIG_PCMCIA_RAYCS is not set
+# CONFIG_IPW2100 is not set
+# CONFIG_IPW2200 is not set
+CONFIG_LIBERTAS=m
+# CONFIG_LIBERTAS_USB is not set
+CONFIG_LIBERTAS_CS=m
+# CONFIG_LIBERTAS_DEBUG is not set
+# CONFIG_AIRO is not set
+CONFIG_HERMES=m
+# CONFIG_PLX_HERMES is not set
+# CONFIG_TMD_HERMES is not set
+# CONFIG_NORTEL_HERMES is not set
+# CONFIG_PCI_HERMES is not set
+CONFIG_PCMCIA_HERMES=m
+CONFIG_PCMCIA_SPECTRUM=m
+# CONFIG_ATMEL is not set
+# CONFIG_AIRO_CS is not set
+# CONFIG_PCMCIA_WL3501 is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_USB_NET_RNDIS_WLAN is not set
+# CONFIG_RTL8180 is not set
+# CONFIG_RTL8187 is not set
+# CONFIG_ADM8211 is not set
+# CONFIG_MAC80211_HWSIM is not set
+# CONFIG_P54_COMMON is not set
+# CONFIG_ATH5K is not set
+# CONFIG_ATH9K is not set
+# CONFIG_IWLCORE is not set
+# CONFIG_IWLWIFI_LEDS is not set
+# CONFIG_IWLAGN is not set
+# CONFIG_IWL3945 is not set
+CONFIG_HOSTAP=m
+CONFIG_HOSTAP_FIRMWARE=y
+# CONFIG_HOSTAP_FIRMWARE_NVRAM is not set
+# CONFIG_HOSTAP_PLX is not set
+# CONFIG_HOSTAP_PCI is not set
+CONFIG_HOSTAP_CS=m
+# CONFIG_B43 is not set
+# CONFIG_B43LEGACY is not set
+# CONFIG_ZD1211RW is not set
+# CONFIG_RT2X00 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=m
+# CONFIG_USB_NET_AX8817X is not set
+CONFIG_USB_NET_CDCETHER=m
+CONFIG_USB_NET_DM9601=m
+# CONFIG_USB_NET_GL620A is not set
+# CONFIG_USB_NET_NET1080 is not set
+# CONFIG_USB_NET_PLUSB is not set
+# CONFIG_USB_NET_MCS7830 is not set
+# CONFIG_USB_NET_RNDIS_HOST is not set
+CONFIG_USB_NET_CDC_SUBSET=m
+# CONFIG_USB_ALI_M5632 is not set
+# CONFIG_USB_AN2720 is not set
+# CONFIG_USB_BELKIN is not set
+CONFIG_USB_ARMLINUX=y
+# CONFIG_USB_EPSON2888 is not set
+# CONFIG_USB_KC2190 is not set
+CONFIG_USB_NET_ZAURUS=m
+# CONFIG_NET_PCMCIA is not set
+# 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_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE 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_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_INPUT_MOUSE=y
+# CONFIG_MOUSE_PS2 is not set
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_APPLETOUCH is not set
+# CONFIG_MOUSE_BCM5974 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_FUJITSU is not set
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+CONFIG_TOUCHSCREEN_MTOUCH=m
+# CONFIG_TOUCHSCREEN_INEXIO 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 is not set
+# CONFIG_TOUCHSCREEN_WM97XX is not set
+# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
+# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_PCSPKR=m
+# CONFIG_INPUT_WISTRON_BTNS is not set
+# CONFIG_INPUT_ATLAS_BTNS is not set
+# 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
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+# CONFIG_DEVKMEM is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_NOZOMI is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=m
+CONFIG_FIX_EARLYCON_MEM=y
+# CONFIG_SERIAL_8250_PCI is not set
+CONFIG_SERIAL_8250_PNP=m
+CONFIG_SERIAL_8250_CS=m
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=m
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_NVRAM is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_SONYPI 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_IPWIRELESS is not set
+# CONFIG_MWAVE is not set
+# CONFIG_PC8736x_GPIO is not set
+# CONFIG_NSC_GPIO is not set
+# CONFIG_CS5535_GPIO is not set
+# CONFIG_RAW_DRIVER is not set
+CONFIG_HPET=y
+CONFIG_HPET_MMAP=y
+# CONFIG_HANGCHECK_TIMER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+CONFIG_DEVPORT=y
+CONFIG_I2C=m
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=m
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# PC SMBus host controller drivers
+#
+CONFIG_I2C_ALI1535=m
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_ISCH is not set
+# CONFIG_I2C_PIIX4 is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Graphics adapter I2C/DDC channel drivers
+#
+# CONFIG_I2C_VOODOO3 is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_SCx200_ACB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_AT24 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 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
+# CONFIG_SPI is not set
+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
+# CONFIG_GPIOLIB is not set
+# CONFIG_W1 is not set
+CONFIG_POWER_SUPPLY=y
+CONFIG_POWER_SUPPLY_DEBUG=y
+# CONFIG_PDA_POWER is not set
+# CONFIG_BATTERY_DS2760 is not set
+CONFIG_PROGEAR_POWER=m
+# CONFIG_HWMON is not set
+CONFIG_THERMAL=m
+# CONFIG_WATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+CONFIG_AGP=m
+CONFIG_AGP_ALI=m
+# CONFIG_AGP_ATI is not set
+# CONFIG_AGP_AMD is not set
+# CONFIG_AGP_AMD64 is not set
+# CONFIG_AGP_INTEL is not set
+# CONFIG_AGP_NVIDIA is not set
+# CONFIG_AGP_SIS is not set
+# CONFIG_AGP_SWORKS is not set
+# CONFIG_AGP_VIA is not set
+# CONFIG_AGP_EFFICEON is not set
+# CONFIG_DRM 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_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_CIRRUS is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_ARC is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_VGA16 is not set
+CONFIG_FB_VESA=y
+# CONFIG_FB_EFI is not set
+# CONFIG_FB_N411 is not set
+# CONFIG_FB_HGA is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_NVIDIA is not set
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_I810 is not set
+# CONFIG_FB_LE80578 is not set
+# CONFIG_FB_INTEL 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_VT8623 is not set
+# CONFIG_FB_CYBLA is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_ARK is not set
+# CONFIG_FB_PM3 is not set
+# CONFIG_FB_CARMINE is not set
+# CONFIG_FB_GEODE is not set
+# CONFIG_FB_VIRTUAL is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=m
+# CONFIG_BACKLIGHT_CORGI is not set
+CONFIG_BACKLIGHT_PROGEAR=m
+# CONFIG_BACKLIGHT_MBP_NVIDIA is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+CONFIG_VGA_CONSOLE=y
+# CONFIG_VGACON_SOFT_SCROLLBACK is not set
+CONFIG_VIDEO_SELECT=y
+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 is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_LOGO_LINUX_CLUT224=y
+CONFIG_SOUND=m
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+CONFIG_SND_RAWMIDI=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 is not set
+# CONFIG_SND_VERBOSE_PROCFS is not set
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+CONFIG_SND_VMASTER=y
+CONFIG_SND_MPU401_UART=m
+CONFIG_SND_AC97_CODEC=m
+# CONFIG_SND_DRIVERS is not set
+CONFIG_SND_PCI=y
+# CONFIG_SND_AD1889 is not set
+# CONFIG_SND_ALS300 is not set
+# CONFIG_SND_ALS4000 is not set
+CONFIG_SND_ALI5451=m
+# 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_AW2 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_OXYGEN is not set
+# CONFIG_SND_CS4281 is not set
+# CONFIG_SND_CS46XX is not set
+# CONFIG_SND_CS5530 is not set
+# CONFIG_SND_CS5535AUDIO 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_HIFIER 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_SIS7019 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_VIRTUOSO is not set
+# CONFIG_SND_VX222 is not set
+# CONFIG_SND_YMFPCI is not set
+# CONFIG_SND_USB is not set
+# CONFIG_SND_PCMCIA is not set
+# CONFIG_SND_SOC is not set
+# CONFIG_SOUND_PRIME is not set
+CONFIG_AC97_BUS=m
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+CONFIG_HIDRAW=y
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
+# CONFIG_HID_FF is not set
+CONFIG_USB_HIDDEV=y
+CONFIG_USB_SUPPORT=y
+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
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES 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=y
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_MON is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_EHCI_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_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
+# CONFIG_USB_R8A66597_HCD is not set
+
+#
+# USB Device Class drivers
+#
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+# CONFIG_USB_WDM 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_ISD200 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_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+CONFIG_USB_SERIAL=m
+# CONFIG_USB_EZUSB is not set
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_AIRCABLE is not set
+# CONFIG_USB_SERIAL_ARK3116 is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_CH341 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=m
+# 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_IUU is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN 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_MOTOROLA is not set
+# CONFIG_USB_SERIAL_NAVMAN is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_OTI6858 is not set
+# CONFIG_USB_SERIAL_SPCP8X5 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_SERIAL_DEBUG 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_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
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_GADGET is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_INFINIBAND is not set
+# CONFIG_EDAC is not set
+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 is not set
+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_DS1374 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
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+CONFIG_RTC_DRV_CMOS=y
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_DMADEVICES is not set
+# CONFIG_UIO is not set
+
+#
+# Firmware Drivers
+#
+# CONFIG_EDD is not set
+CONFIG_FIRMWARE_MEMMAP=y
+# CONFIG_DELL_RBU is not set
+# CONFIG_DCDBAS is not set
+CONFIG_DMIID=y
+# CONFIG_ISCSI_IBFT_FIND 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_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=m
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+CONFIG_REISERFS_FS_XATTR=y
+# CONFIG_REISERFS_FS_POSIX_ACL is not set
+# CONFIG_REISERFS_FS_SECURITY is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=m
+# CONFIG_XFS_QUOTA is not set
+CONFIG_XFS_POSIX_ACL=y
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_DEBUG is not set
+# CONFIG_OCFS2_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=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=m
+# CONFIG_NTFS_DEBUG is not set
+# CONFIG_NTFS_RW is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLBFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+# 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_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V2_ACL=y
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=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_RPCSEC_GSS_KRB5=m
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+# 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
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf-8"
+CONFIG_NLS_CODEPAGE_437=m
+# 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=m
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+CONFIG_NLS_CODEPAGE_1250=m
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+# 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
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_PRINTK_TIME=y
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=1024
+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=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_SCHEDSTATS is not set
+CONFIG_TIMER_STATS=y
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_PREEMPT is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_FRAME_POINTER is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_HAVE_FTRACE=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+# CONFIG_FTRACE is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_PREEMPT_TRACER is not set
+# CONFIG_SYSPROF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_PROVIDE_OHCI1394_DMA_INIT is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_STRICT_DEVMEM is not set
+CONFIG_X86_VERBOSE_BOOTUP=y
+# CONFIG_EARLY_PRINTK is not set
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_PAGEALLOC is not set
+# CONFIG_X86_PTDUMP is not set
+CONFIG_DEBUG_RODATA=y
+# CONFIG_DEBUG_RODATA_TEST is not set
+# CONFIG_DEBUG_NX_TEST is not set
+CONFIG_4KSTACKS=y
+CONFIG_DOUBLEFAULT=y
+# CONFIG_MMIOTRACE is not set
+CONFIG_IO_DELAY_TYPE_0X80=0
+CONFIG_IO_DELAY_TYPE_0XED=1
+CONFIG_IO_DELAY_TYPE_UDELAY=2
+CONFIG_IO_DELAY_TYPE_NONE=3
+CONFIG_IO_DELAY_0X80=y
+# CONFIG_IO_DELAY_0XED is not set
+# CONFIG_IO_DELAY_UDELAY is not set
+# CONFIG_IO_DELAY_NONE is not set
+CONFIG_DEFAULT_IO_DELAY_TYPE=0
+# CONFIG_DEBUG_BOOT_PARAMS is not set
+# CONFIG_CPA_DEBUG is not set
+# CONFIG_OPTIMIZE_INLINING is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_AEAD=m
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=m
+CONFIG_CRYPTO_MANAGER=m
+# CONFIG_CRYPTO_GF128MUL is not set
+CONFIG_CRYPTO_NULL=m
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_AUTHENC=m
+CONFIG_CRYPTO_TEST=m
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=m
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=m
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=m
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_MICHAEL_MIC=m
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_WP512=m
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_AES_586=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_BLOWFISH=m
+# CONFIG_CRYPTO_CAMELLIA is not set
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_DES=m
+# CONFIG_CRYPTO_FCRYPT is not set
+CONFIG_CRYPTO_KHAZAD=m
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SALSA20_586 is not set
+# CONFIG_CRYPTO_SEED is not set
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
+# CONFIG_CRYPTO_TWOFISH_586 is not set
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=m
+# CONFIG_CRYPTO_LZO is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_CRYPTO_DEV_PADLOCK is not set
+CONFIG_CRYPTO_DEV_GEODE=m
+# CONFIG_CRYPTO_DEV_HIFN_795X is not set
+CONFIG_HAVE_KVM=y
+# CONFIG_VIRTUALIZATION is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_FIRST_BIT=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_CRC_CCITT=m
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+CONFIG_CRC_ITU_T=m
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+CONFIG_LIBCRC32C=m
+CONFIG_AUDIT_GENERIC=y
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/recipes/linux/linux/sarge-at91/2.6.21-sarge-kernel.patch b/recipes/linux/linux/sarge-at91/2.6.21-sarge-kernel.patch
new file mode 100644
index 0000000000..7b5f408c37
--- /dev/null
+++ b/recipes/linux/linux/sarge-at91/2.6.21-sarge-kernel.patch
@@ -0,0 +1,238 @@
+diff -Nurp ../linux-2.6.21.4/arch/arm/boot/compressed/head-at91rm9200.S ./arch/arm/boot/compressed/head-at91rm9200.S
+--- ../linux-2.6.21.4/arch/arm/boot/compressed/head-at91rm9200.S 2007-06-12 22:29:12.000000000 +0200
++++ ./arch/arm/boot/compressed/head-at91rm9200.S 2007-06-12 02:57:07.000000000 +0200
+@@ -73,6 +73,12 @@
+ cmp r7, r3
+ beq 99f
+
++ @ AT91RM9200
++ mov r3, #(MACH_TYPE_AT91RM9200 & 0xff)
++ orr r3, r3, #(MACH_TYPE_AT91RM9200 & 0xff00)
++ cmp r7, r3
++ beq 99f
++
+ @ Unknown board, use the AT91RM9200DK board
+ @ mov r7, #MACH_TYPE_AT91RM9200
+ mov r7, #(MACH_TYPE_AT91RM9200DK & 0xff)
+diff -Nurp ../linux-2.6.21.4/arch/arm/mach-at91/board-sarge.c ./arch/arm/mach-at91/board-sarge.c
+--- ../linux-2.6.21.4/arch/arm/mach-at91/board-sarge.c 1970-01-01 01:00:00.000000000 +0100
++++ ./arch/arm/mach-at91/board-sarge.c 2007-06-12 02:57:07.000000000 +0200
+@@ -0,0 +1,190 @@
++/*
++ * linux/arch/arm/mach-at91/board-sarge.c
++ *
++ * Copyright (C) 2007 BlackMesaEast staff
++ *
++ * mcgregor@blackmesaeast.com.pl
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++
++#include <linux/types.h>
++#include <linux/init.h>
++#include <linux/mm.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/spi/spi.h>
++#include <linux/mtd/physmap.h>
++
++#include <asm/hardware.h>
++#include <asm/setup.h>
++#include <asm/mach-types.h>
++#include <asm/irq.h>
++
++#include <asm/mach/arch.h>
++#include <asm/mach/map.h>
++#include <asm/mach/irq.h>
++
++#include <asm/arch/board.h>
++#include <asm/arch/gpio.h>
++#include <asm/arch/at91rm9200_mc.h>
++
++#include "generic.h"
++
++
++/*
++ * Serial port configuration.
++ * 0 .. 3 = USART0 .. USART3
++ * 4 = DBGU
++ */
++static struct at91_uart_config __initdata sarge_uart_config = {
++ .console_tty = 0, /* ttyS0 */
++ .nr_tty = 5,
++ .tty_map = { 4, 1, 0, 2, 3 } /* ttyS0, ..., ttyS4 */
++};
++
++static void __init sarge_map_io(void)
++{
++ /* Initialize processor: 18.432 MHz crystal */
++ at91rm9200_initialize(18432000, AT91RM9200_PQFP);
++
++ /* Setup the serial ports and console */
++ at91_init_serial(&sarge_uart_config);
++}
++
++static void __init sarge_init_irq(void)
++{
++ at91rm9200_init_interrupts(NULL);
++}
++
++static struct at91_eth_data __initdata sarge_eth_data = {
++ .phy_irq_pin = AT91_PIN_PB1,
++ .is_rmii = 0,
++};
++
++static struct at91_usbh_data __initdata sarge_usbh_data = {
++ .ports = 1,
++};
++
++static struct at91_udc_data __initdata sarge_udc_data = {
++ .vbus_pin = AT91_PIN_PA20,
++ .pullup_pin = AT91_PIN_PA21,
++};
++
++static struct at91_cf_data __initdata sarge_cf_data = {
++ .det_pin = AT91_PIN_PB24,
++ .rst_pin = AT91_PIN_PB23,
++ // .irq_pin = ... not connected
++ // .vcc_pin = ... always powered
++};
++
++static struct at91_mmc_data __initdata sarge_mmc_data = {
++ .det_pin = AT91_PIN_PB0,
++ .slot_b = 0,
++ .wire4 = 1,
++ .wp_pin = AT91_PIN_PB2,
++};
++
++
++
++static struct spi_board_info sarge_spi_devices[] = {
++ { /* DataFlash chip */
++ .modalias = "mtd_dataflash",
++ .chip_select = 0,
++ .max_speed_hz = 15 * 1000 * 1000,
++ }
++};
++
++static struct mtd_partition __initdata sarge_nand_partition[] = {
++ {
++ .name = "NAND Partition 1",
++ .offset = 0,
++ .size = MTDPART_SIZ_FULL,
++ },
++};
++
++static struct mtd_partition *nand_partitions(int size, int *num_partitions)
++{
++ *num_partitions = ARRAY_SIZE(sarge_nand_partition);
++ return sarge_nand_partition;
++}
++
++static struct at91_nand_data __initdata sarge_nand_data = {
++ .ale = 22,
++ .cle = 21,
++ .det_pin = AT91_PIN_PB22,
++ .rdy_pin = AT91_PIN_PB22,
++ // .enable_pin = ... not there
++ .partition_info = nand_partitions,
++};
++
++#define SARGE_FLASH_BASE AT91_CHIPSELECT_0
++#define SARGE_FLASH_SIZE 0x200000
++
++static struct physmap_flash_data sarge_flash_data = {
++ .width = 2,
++};
++
++static struct resource sarge_flash_resource = {
++ .start = SARGE_FLASH_BASE,
++ .end = SARGE_FLASH_BASE + SARGE_FLASH_SIZE - 1,
++ .flags = IORESOURCE_MEM,
++};
++
++static struct platform_device sarge_flash = {
++ .name = "physmap-flash",
++ .id = 0,
++ .dev = {
++ .platform_data = &sarge_flash_data,
++ },
++ .resource = &sarge_flash_resource,
++ .num_resources = 1,
++};
++
++static void __init sarge_board_init(void)
++{
++ /* Serial */
++ at91_add_device_serial();
++ /* Ethernet */
++ at91_add_device_eth(&sarge_eth_data);
++ /* USB Host */
++ at91_add_device_usbh(&sarge_usbh_data);
++ /* USB Device */
++ at91_add_device_udc(&sarge_udc_data);
++ at91_set_multi_drive(sarge_udc_data.pullup_pin, 1); /* pullup_pin is connected to reset */
++ /* Compact Flash */
++ at91_add_device_cf(&sarge_cf_data);
++ /* I2C */
++ at91_add_device_i2c();
++ /* SPI */
++ at91_add_device_spi(sarge_spi_devices, ARRAY_SIZE(sarge_spi_devices));
++
++ /* MMC */
++ at91_add_device_mmc(0, &sarge_mmc_data);
++ /* NAND */
++ at91_add_device_nand(&sarge_nand_data);
++ /* NOR Flash */
++ platform_device_register(&sarge_flash);
++}
++MACHINE_START(AT91RM9200, "Sarge AT91RM9200 SBC")
++ /* Maintainer: mcgregor@blackmesaeast.com.pl */
++ .phys_io = AT91_BASE_SYS,
++ .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
++ .boot_params = AT91_SDRAM_BASE + 0x100,
++ .timer = &at91rm9200_timer,
++ .map_io = sarge_map_io,
++ .init_irq = sarge_init_irq,
++ .init_machine = sarge_board_init,
++MACHINE_END
+diff -Nurp ../linux-2.6.21.4/arch/arm/mach-at91/Kconfig ./arch/arm/mach-at91/Kconfig
+--- ../linux-2.6.21.4/arch/arm/mach-at91/Kconfig 2007-06-12 22:29:12.000000000 +0200
++++ ./arch/arm/mach-at91/Kconfig 2007-06-12 03:00:28.000000000 +0200
+@@ -90,6 +90,13 @@ config MACH_KAFA
+ help
+ Select this if you are using Sperry-Sun's KAFA board.
+
++config MACH_SARGE
++ bool "Black Mesa East Sarge SBC"
++ depends on ARCH_AT91RM9200
++ help
++ Select this if you are using BlackMesaEast Sarge PCB
++ <http://blackmesaeast.com.pl>
++
+ config MACH_CHUB
+ bool "Promwad Chub board"
+ depends on ARCH_AT91RM9200
+diff -Nurp ../linux-2.6.21.4/arch/arm/mach-at91/Makefile ./arch/arm/mach-at91/Makefile
+--- ../linux-2.6.21.4/arch/arm/mach-at91/Makefile 2007-06-12 22:29:12.000000000 +0200
++++ ./arch/arm/mach-at91/Makefile 2007-06-12 03:00:47.000000000 +0200
+@@ -29,6 +29,7 @@ obj-$(CONFIG_MACH_KB9200) += board-kb920
+ obj-$(CONFIG_MACH_ATEB9200) += board-eb9200.o
+ obj-$(CONFIG_MACH_KAFA) += board-kafa.o
+ obj-$(CONFIG_MACH_CHUB) += board-chub.o
++obj-$(CONFIG_MACH_SARGE) += board-sarge.o
+
+ # AT91SAM9260 board-specific support
+ obj-$(CONFIG_MACH_AT91SAM9260EK) += board-sam9260ek.o
diff --git a/recipes/linux/linux/sarge-at91/2.6.21-sarge-mmc.patch b/recipes/linux/linux/sarge-at91/2.6.21-sarge-mmc.patch
new file mode 100644
index 0000000000..01bbaeb73e
--- /dev/null
+++ b/recipes/linux/linux/sarge-at91/2.6.21-sarge-mmc.patch
@@ -0,0 +1,87 @@
+diff -Nurp ../linux-2.6.21.4/drivers/mmc/at91_mci.c ./drivers/mmc/at91_mci.c
+--- ../linux-2.6.21.4/drivers/mmc/at91_mci.c 2007-06-12 22:29:12.000000000 +0200
++++ ./drivers/mmc/at91_mci.c 2007-06-12 03:52:55.000000000 +0200
+@@ -421,8 +421,11 @@ static unsigned int at91_mci_send_comman
+ if (cmd->opcode == MMC_STOP_TRANSMISSION)
+ cmdr |= AT91_MCI_TRCMD_STOP;
+
+- if (host->bus_mode == MMC_BUSMODE_OPENDRAIN)
+- cmdr |= AT91_MCI_OPDCMD;
++ //if (host->bus_mode == MMC_BUSMODE_OPENDRAIN)
++ // cmdr |= AT91_MCI_OPDCMD;
++
++ if (!(1/**machine_is_sarge*/) && host->bus_mode == MMC_BUSMODE_OPENDRAIN)
++ cmdr |= AT91_MCI_OPDCMD;
+
+ /*
+ * Set the arguments and send the command
+@@ -739,7 +742,13 @@ static irqreturn_t at91_mci_irq(int irq,
+ at91_mci_write(host, AT91_MCI_IDR, 0xffffffff);
+ at91mci_completed_command(host);
+ } else
++// at91_mci_write(host, AT91_MCI_IDR, int_status);
++ {
++ if (1 /*machine_is_sarge()*/)
++ at91_mci_write(host, AT91_MCI_IDR, (int_status & ~AT91_MCI_TXRDY) );
++ else
+ at91_mci_write(host, AT91_MCI_IDR, int_status);
++ }
+
+ return IRQ_HANDLED;
+ }
+diff -Nurp ../linux-2.6.21.4/drivers/mmc/mmc_block.c ./drivers/mmc/mmc_block.c
+--- ../linux-2.6.21.4/drivers/mmc/mmc_block.c 2007-06-07 23:27:31.000000000 +0200
++++ ./drivers/mmc/mmc_block.c 2007-06-12 04:19:36.000000000 +0200
+@@ -256,10 +256,24 @@ static int mmc_blk_issue_rq(struct mmc_q
+ * this rule as they support querying the number of
+ * successfully written sectors.
+ */
+- if (rq_data_dir(req) != READ &&
++// if (rq_data_dir(req) != READ &&
++ if ((1/**machine_is_sarge*/))
++ {
++ if (rq_data_dir(req) != READ)
++ brq.data.blocks = 1;
++ }
++ else if (rq_data_dir(req) != READ &&
++
+ !(card->host->caps & MMC_CAP_MULTIWRITE) &&
+ !mmc_card_sd(card))
+ brq.data.blocks = 1;
++
++
++
++
++
++
++
+
+ if (brq.data.blocks > 1) {
+ brq.data.flags |= MMC_DATA_MULTI;
+diff -Nurp ../linux-2.6.21.4/drivers/mmc/mmc.c ./drivers/mmc/mmc.c
+--- ../linux-2.6.21.4/drivers/mmc/mmc.c 2007-06-07 23:27:31.000000000 +0200
++++ ./drivers/mmc/mmc.c 2007-06-12 04:10:05.000000000 +0200
+@@ -1500,12 +1500,22 @@ static void mmc_setup(struct mmc_host *h
+ mmc_set_ios(host);
+
+ mmc_read_csds(host);
+-
++ /*
+ if (host->mode == MMC_MODE_SD) {
+ mmc_read_scrs(host);
+ mmc_read_switch_caps(host);
+ } else
+ mmc_process_ext_csds(host);
++ */
++
++ if (!(1/*machine_is_sarge*/))
++ {
++ if (host->mode == MMC_MODE_SD) {
++ mmc_read_scrs(host);
++ mmc_read_switch_caps(host);
++ } else
++ mmc_process_ext_csds(host);
++ }
+ }
+
+
diff --git a/recipes/linux/linux/sarge-at91/2.6.21-sarge-phy.patch b/recipes/linux/linux/sarge-at91/2.6.21-sarge-phy.patch
new file mode 100644
index 0000000000..25ce15eb94
--- /dev/null
+++ b/recipes/linux/linux/sarge-at91/2.6.21-sarge-phy.patch
@@ -0,0 +1,400 @@
+diff -Nurp ../linux-2.6.21.4/drivers/net/arm/at91_ether.c ./drivers/net/arm/at91_ether.c
+--- ../linux-2.6.21.4/drivers/net/arm/at91_ether.c 2007-06-12 22:29:12.000000000 +0200
++++ ./drivers/net/arm/at91_ether.c 2007-06-12 03:11:16.000000000 +0200
+@@ -235,6 +235,11 @@ static irqreturn_t at91ether_phy_interru
+ if (!(phy & (1 << 7)))
+ goto done;
+ }
++ else if (lp->phy_type == MII_STE100P_ID) {
++ read_phy(lp->phy_address, MII_STE100P_XCSIIS_REG, &phy); /* ack interrupt in STE100P PHY */
++ if (!(phy & 0x007F))
++ goto done;
++ }
+
+ update_linkspeed(dev, 0);
+
+@@ -303,6 +308,11 @@ static void enable_phyirq(struct net_dev
+ dsintr = dsintr | 0x3; /* set bits 0,1 */
+ write_phy(lp->phy_address, MII_DPMICR_REG, dsintr);
+ }
++ else if (lp->phy_type == MII_STE100P_ID) { /* for STE100P PHY */
++ read_phy(lp->phy_address, MII_STE100P_XIE_REG, &dsintr);
++
++ dsintr |= 0x007F;
++ }
+
+ disable_mdi();
+ spin_unlock_irq(&lp->lock);
+@@ -359,6 +369,11 @@ static void disable_phyirq(struct net_de
+ dsintr = dsintr & ~0x3c; /* clear bits 2..5 */
+ write_phy(lp->phy_address, MII_DPMISR_REG, dsintr);
+ }
++ else if (lp->phy_type == MII_STE100P_ID) { /* for STE100P PHY */
++ read_phy(lp->phy_address, MII_STE100P_XIE_REG, &dsintr);
++ dsintr &= 0xFF80;
++ write_phy(lp->phy_address, MII_STE100P_XIE_REG, dsintr);
++ }
+
+ disable_mdi();
+ spin_unlock_irq(&lp->lock);
+@@ -1117,6 +1132,8 @@ static int __init at91ether_setup(unsign
+ printk(KERN_INFO "%s: Teridian 78Q21x3 PHY\n", dev->name);
+ else if (phy_type == MII_LAN83C185_ID)
+ printk(KERN_INFO "%s: SMSC LAN83C185 PHY\n", dev->name);
++ else if (phy_type == MII_STE100P_ID)
++ printk(KERN_INFO "%s: STE100P PHY\n", dev->name);
+
+ return 0;
+ }
+@@ -1159,6 +1176,7 @@ static int __init at91ether_probe(struct
+ case MII_KS8721_ID: /* Micrel KS8721: PHY_ID1 = 0x22, PHY_ID2 = 0x1610 */
+ case MII_T78Q21x3_ID: /* Teridian 78Q21x3: PHY_ID1 = 0x0E, PHY_ID2 = 7237 */
+ case MII_LAN83C185_ID: /* SMSC LAN83C185: PHY_ID1 = 0x0007, PHY_ID2 = 0xC0A1 */
++ case MII_STE100P_ID: /* STE100P: PHY_ID1 = 0x1C04, PHY_ID2 = 0x0000 */
+ detected = at91ether_setup(phy_id, phy_address, pdev, ether_clk);
+ break;
+ }
+diff -Nurp ../linux-2.6.21.4/drivers/net/arm/at91_ether.h ./drivers/net/arm/at91_ether.h
+--- ../linux-2.6.21.4/drivers/net/arm/at91_ether.h 2007-06-12 22:29:12.000000000 +0200
++++ ./drivers/net/arm/at91_ether.h 2007-06-12 03:07:54.000000000 +0200
+@@ -29,6 +29,15 @@
+ #define MII_ISINTS_REG 19
+ #define MII_LEDCTRL_REG 20
+
++/* STE100P specific registers */
++#define MII_STE100P_XCSIIS_REG 0x11
++#define MII_STE100P_XIE_REG 0x12
++#define MII_XCR_REG 0x00
++#define MII_XCR_ISOLATE 0x0400
++
++/* STE100P PHY */
++#define MII_STE100P_ID 0x1c040010
++
+ /* Realtek RTL8201 PHY */
+ #define MII_RTL8201_ID 0x00008200
+
+diff -Nurp ../linux-2.6.21.4/drivers/net/phy/Kconfig ./drivers/net/phy/Kconfig
+--- ../linux-2.6.21.4/drivers/net/phy/Kconfig 2007-06-07 23:27:31.000000000 +0200
++++ ./drivers/net/phy/Kconfig 2007-06-12 03:12:16.000000000 +0200
+@@ -62,6 +62,12 @@ config BROADCOM_PHY
+ ---help---
+ Currently supports the BCM5411, BCM5421 and BCM5461 PHYs.
+
++config STE100P_PHY
++ tristate "Drivers for the STE100P PHY"
++ depends on PHYLIB
++ ---help---
++ Currently supports the ste100p
++
+ config FIXED_PHY
+ tristate "Drivers for PHY emulation on fixed speed/link"
+ depends on PHYLIB
+diff -Nurp ../linux-2.6.21.4/drivers/net/phy/Makefile ./drivers/net/phy/Makefile
+--- ../linux-2.6.21.4/drivers/net/phy/Makefile 2007-06-07 23:27:31.000000000 +0200
++++ ./drivers/net/phy/Makefile 2007-06-12 03:12:29.000000000 +0200
+@@ -12,3 +12,4 @@ obj-$(CONFIG_SMSC_PHY) += smsc.o
+ obj-$(CONFIG_VITESSE_PHY) += vitesse.o
+ obj-$(CONFIG_BROADCOM_PHY) += broadcom.o
+ obj-$(CONFIG_FIXED_PHY) += fixed.o
++obj-$(CONFIG_STE100P_PHY) += ste100p.o
+diff -Nurp ../linux-2.6.21.4/drivers/net/phy/ste100p.c ./drivers/net/phy/ste100p.c
+--- ../linux-2.6.21.4/drivers/net/phy/ste100p.c 1970-01-01 01:00:00.000000000 +0100
++++ ./drivers/net/phy/ste100p.c 2007-06-12 02:52:31.000000000 +0200
+@@ -0,0 +1,297 @@
++/*
++ * drivers/net/phy/ste100p.c
++ *
++ * Driver for STE100P PHYs
++ *
++ * Author: Grzegorz Rajtar mcgregor@blackmesaeast.com.pl
++ *
++ * Copyright (c) 2007 Black Mesa East
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ *
++ */
++
++#include <linux/kernel.h>
++#include <linux/sched.h>
++#include <linux/string.h>
++#include <linux/errno.h>
++#include <linux/unistd.h>
++#include <linux/slab.h>
++#include <linux/interrupt.h>
++#include <linux/init.h>
++#include <linux/delay.h>
++#include <linux/netdevice.h>
++#include <linux/etherdevice.h>
++#include <linux/skbuff.h>
++#include <linux/spinlock.h>
++#include <linux/mm.h>
++#include <linux/module.h>
++#include <linux/mii.h>
++#include <linux/ethtool.h>
++#include <linux/phy.h>
++
++#include <asm/io.h>
++#include <asm/irq.h>
++#include <asm/uaccess.h>
++
++/* Control register and bitmasks*/
++#define MII_STE100P_XCR_REG 0x00
++#define MII_STE100P_XCR_RESET 1 << 15
++#define MII_STE100P_XCR_LOOPBACK 1 << 14
++#define MII_STE100P_XCR_SPEED 1 << 13
++#define MII_STE100P_XCR_AN 1 << 12
++#define MII_STE100P_XCR_PWRDN 1 << 11
++#define MII_STE100P_XCR_ISOLATE 1 << 10
++#define MII_STE100P_XCR_RSTRT_AN 1 << 9
++#define MII_STE100P_XCR_FULL_DUP 1 << 8
++#define MII_STE100P_XCR_COLLEN 1 << 7
++
++
++/* Iinterrupt register and bitmasks */
++#define MII_STE100P_XIE_REG 0x12
++#define MII_STE100P_XIE_ANCE 1 << 6
++#define MII_STE100P_XIE_RFE 1 << 5
++#define MII_STE100P_XIE_LDE 1 << 4
++#define MII_STE100P_XIE_ANAE 1 << 3
++#define MII_STE100P_XIE_PDFE 1 << 2
++#define MII_STE100P_XIE_ANPE 1 << 1
++#define MII_STE100P_XIE_REFE 1
++#define MII_STE100P_XIE_ALL \
++(MII_STE100P_XIE_ANCE | MII_STE100P_XIE_RFE | MII_STE100P_XIE_LDE | \
++ MII_STE100P_XIE_ANAE | MII_STE100P_XIE_PDFE | MII_STE100P_XIE_ANPE | MII_STE100P_XIE_REFE)
++
++/* Iinterrupt status register and bitmasks */
++#define MII_STE100P_XCSIIS_REG 0x11
++#define MII_STE100P_XCSIIS_SPEED 1 << 9
++#define MII_STE100P_XCSIIS_DUPLEX 1 << 8
++#define MII_STE100P_XCSIIS_PAUSE 1 << 7
++#define MII_STE100P_XCSIIS_ANC 1 << 6
++#define MII_STE100P_XCSIIS_RFD 1 << 5
++#define MII_STE100P_XCSIIS_LS 1 << 4
++#define MII_STE100P_XCSIIS_ANAR 1 << 3
++#define MII_STE100P_XCSIIS_PDF 1 << 2
++#define MII_STE100P_XCSIIS_ANPR 1 << 1
++#define MII_STE100P_XCSIIS_REF 1
++
++/* 100-TX register and bitmasks*/
++#define MII_STE100P_100CTR_REG 0x13
++#define MII_STE100P_100CTR_DISERR 1 << 13
++#define MII_STE100P_100CTR_ANC 1 << 12
++#define MII_STE100P_100CTR_ENRLB 1 << 9
++#define MII_STE100P_100CTR_ENDCR 1 << 8
++#define MII_STE100P_100CTR_ENRZI 1 << 7
++#define MII_STE100P_100CTR_EN4B5B 1 << 6
++#define MII_STE100P_100CTR_ISOTX 1 << 5
++#define MII_STE100P_100CTR_CMODE_MASK 0x001C
++#define MII_STE100P_100CTR_DISMLT 1 << 1
++#define MII_STE100P_100CTR_DISCRM 1
++
++/* Auto-negotiation register and bitmasks*/
++#define MII_STE100P_ANA_REG 0x04
++#define MII_STE100P_ANA_NXTPG 1 << 15
++#define MII_STE100P_ANA_RF 1 << 13
++#define MII_STE100P_ANA_FC 1 << 10
++#define MII_STE100P_ANA_T4 1 << 9
++#define MII_STE100P_ANA_TXF 1 << 8
++#define MII_STE100P_ANA_TXH 1 << 7
++#define MII_STE100P_ANA_10F 1 << 6
++#define MII_STE100P_ANA_10H 1 << 5
++#define MII_STE100P_ANA_SF 0x0000
++#define MII_STE100P_ANA_SF_MASK 0x000F
++
++/* PHY chip ID regs */
++#define MII_STE100P_PID1_REG 0x02
++#define MII_STE100P_PID2_REG 0x03
++
++#define MII_STE100P_PHYID_VAL 0x1C040000
++#define MII_STE100P_PHYID_MASK 0xFFFF0000
++
++
++
++MODULE_DESCRIPTION("STE100P PHY driver");
++MODULE_AUTHOR("Grzegorz Rajtar <mcgregor@blackmesaeast.com.pl>");
++MODULE_LICENSE("GPL");
++
++static int ste100p_config_intr(struct phy_device *phydev)
++{
++ int temp;
++ temp = phy_read(phydev, MII_STE100P_XIE_REG);
++
++ if(PHY_INTERRUPT_ENABLED == phydev->interrupts )
++ temp |= MII_STE100P_XIE_ALL;
++ else
++ {
++ temp &= ~(MII_STE100P_XIE_ALL);
++ //clear interrupt status register
++ phy_read(phydev, MII_STE100P_XCSIIS_REG);
++ }
++
++ temp = phy_write(phydev, MII_STE100P_XIE_REG, temp);
++
++ return temp;
++}
++
++static int ste100p_config_aneg(struct phy_device *phydev)
++{
++ int err;
++
++ int temp = phy_read(phydev, MII_STE100P_XCR_REG);
++ int temp2;
++
++ /* Isolate the PHY */
++
++ err = phy_write(phydev, MII_STE100P_XCR_REG, temp | MII_STE100P_XCR_ISOLATE);
++
++ //read for isolate latch
++ temp = phy_read(phydev, MII_STE100P_XCR_REG);
++
++ if (err < 0)
++ return err;
++
++ /* Set the Auto_negotiation Advertisement Register */
++ /* MII advertising for Next page, 100BaseTxFD and HD, 10BaseTFD and HD, IEEE 802.3 */
++ err = phy_write(phydev, MII_STE100P_ANA_REG,
++ MII_STE100P_ANA_NXTPG | MII_STE100P_ANA_TXF | MII_STE100P_ANA_TXH |
++ MII_STE100P_ANA_10F | MII_STE100P_ANA_10H | MII_STE100P_ANA_SF);
++
++ if (err < 0)
++ return err;
++
++ err = phy_write(phydev, MII_STE100P_XCR_REG,
++ temp | MII_STE100P_XCR_AN /*| MII_STE100P_XCR_SPEED */ | MII_STE100P_XCR_FULL_DUP);
++
++ if (err < 0)
++ return err;
++
++ /* Restart auto negotiation */
++
++ err = phy_write(phydev, MII_STE100P_XCR_REG,
++ (temp | MII_STE100P_XCR_AN | MII_STE100P_XCR_RSTRT_AN) & (~MII_STE100P_XCR_ISOLATE));
++
++ //read for isolate latch
++ phy_read(phydev, MII_STE100P_XCR_REG);
++
++ if (err < 0)
++ return err;
++
++ /* Configure the new settings */
++ err = genphy_config_aneg(phydev);
++
++ if (err < 0)
++ return err;
++
++ return 0;
++}
++
++static int ste100p_config_init(struct phy_device *phydev)
++{
++ int err;
++ int temp;
++ int temp_xcr;
++
++ /* Isolate the PHY */
++
++ temp_xcr = phy_read(phydev, MII_STE100P_XCR_REG);
++
++ err = phy_write(phydev, MII_STE100P_XCR_REG,
++ ((temp_xcr | MII_STE100P_XCR_ISOLATE) & (~MII_STE100P_XCR_AN)));
++
++ //read for isolate latch
++ temp_xcr = phy_read(phydev, MII_STE100P_XCR_REG);
++
++ err = phy_write(phydev, MII_STE100P_XCR_REG,
++ temp_xcr & (~MII_STE100P_XCR_ISOLATE));
++
++ //read for isolate latch
++ phy_read(phydev, MII_STE100P_XCR_REG);
++
++ if (err < 0)
++ return err;
++
++ temp = phy_read(phydev, MII_STE100P_ANA_REG);
++
++ err = phy_write(phydev, MII_STE100P_ANA_REG, temp
++ | MII_STE100P_ANA_FC | MII_STE100P_ANA_TXF
++ | MII_STE100P_ANA_TXH | MII_STE100P_ANA_10F | MII_STE100P_ANA_10H);
++
++ if (err < 0)
++ return err;
++
++ /* Reconnect the PHY, and enable Autonegotiation */
++ err = phy_write(phydev, MII_STE100P_XCR_REG, (temp_xcr | MII_STE100P_XCR_AN
++ | MII_STE100P_XCR_RSTRT_AN) & (~MII_STE100P_XCR_ISOLATE));
++
++ //read for isolate latch
++ phy_read(phydev, MII_STE100P_XCR_REG);
++
++ if (err < 0)
++ return err;
++
++ return 0;
++}
++
++static int ste100p_ack_interrupt(struct phy_device *phydev)
++{
++ int intmask = 1;
++ int rep = 0;
++
++ //clear multiple interrupts;
++ do
++ {
++ intmask = phy_read(phydev, MII_STE100P_XCSIIS_REG);
++ rep++;
++ } while ((intmask & MII_STE100P_XIE_ALL) != 0 && rep < 25);
++
++ return 0;
++}
++
++
++static int ste100p_suspend(struct phy_device *phydev)
++{
++ int temp = phy_read(phydev, MII_STE100P_XCR_REG);
++ temp = phy_write(phydev, MII_STE100P_XCR_REG, temp | MII_STE100P_XCR_PWRDN);
++ //read for latch XCR REG
++ phy_read(phydev, MII_STE100P_XCR_REG);
++ return temp;
++}
++
++static int ste100p_resume(struct phy_device *phydev)
++{
++ int temp;
++ temp = phy_write(phydev, MII_STE100P_XCR_REG, temp & (~MII_STE100P_XCR_PWRDN));
++ //read for latch XCR REG
++ phy_read(phydev, MII_STE100P_XCR_REG);
++ return temp;
++}
++
++static struct phy_driver ste100p_driver = {
++ .phy_id = MII_STE100P_PHYID_VAL,
++ .name = "STE100P",
++ .phy_id_mask = MII_STE100P_PHYID_MASK,
++ .features = PHY_BASIC_FEATURES,
++ .flags = PHY_HAS_INTERRUPT,
++ .config_init = &ste100p_config_init,
++ .config_intr = &ste100p_config_intr,
++ .config_aneg = &ste100p_config_aneg,
++ .suspend = &ste100p_suspend,
++ .resume = &ste100p_resume,
++ .ack_interrupt = &ste100p_ack_interrupt,
++ .read_status = &genphy_read_status,
++ .driver = { .owner = THIS_MODULE,},
++};
++
++static int __init ste100p_init(void)
++{
++ return phy_driver_register(&ste100p_driver);
++}
++
++static void __exit ste100p_exit(void)
++{
++ phy_driver_unregister(&ste100p_driver);
++}
++
++module_init(ste100p_init);
++module_exit(ste100p_exit);
diff --git a/recipes/linux/linux/sarge-at91/defconfig b/recipes/linux/linux/sarge-at91/defconfig
new file mode 100644
index 0000000000..36d48a7b49
--- /dev/null
+++ b/recipes/linux/linux/sarge-at91/defconfig
@@ -0,0 +1,1909 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.21.4
+# Wed Jun 13 02:03:51 2007
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+# CONFIG_GENERIC_TIME is not set
+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_VECTORS_BASE=0xffff0000
+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=y
+CONFIG_SWAP=y
+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_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 is not set
+# 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 is not set
+# CONFIG_IOSCHED_CFQ is not set
+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=y
+# 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 is not set
+# 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
+
+#
+# Atmel AT91 System-on-Chip
+#
+CONFIG_ARCH_AT91RM9200=y
+# CONFIG_ARCH_AT91SAM9260 is not set
+# CONFIG_ARCH_AT91SAM9261 is not set
+# CONFIG_ARCH_AT91SAM9263 is not set
+# CONFIG_ARCH_AT91SAM9RL is not set
+
+#
+# AT91RM9200 Board Type
+#
+# CONFIG_MACH_ONEARM is not set
+# CONFIG_ARCH_AT91RM9200DK is not set
+# CONFIG_MACH_AT91RM9200EK is not set
+# CONFIG_MACH_CSB337 is not set
+# CONFIG_MACH_CSB637 is not set
+# CONFIG_MACH_CARMEVA is not set
+# CONFIG_MACH_ATEB9200 is not set
+# CONFIG_MACH_KB9200 is not set
+# CONFIG_MACH_KAFA is not set
+CONFIG_MACH_SARGE=y
+# CONFIG_MACH_CHUB is not set
+
+#
+# AT91 Board Options
+#
+
+#
+# AT91 Feature Selections
+#
+CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
+CONFIG_ATMEL_TCLIB=y
+CONFIG_AT91_SLOW_CLOCK=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM920T=y
+CONFIG_CPU_32v4T=y
+CONFIG_CPU_ABRT_EV4T=y
+CONFIG_CPU_CACHE_V4WT=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_OUTER_CACHE is not set
+
+#
+# Bus support
+#
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+CONFIG_PCCARD=y
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
+
+#
+# PC-card bridges
+#
+CONFIG_AT91_CF=y
+
+#
+# Kernel Features
+#
+CONFIG_PREEMPT=y
+# 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_ZONE_DMA_FLAG=1
+CONFIG_LEDS=y
+CONFIG_LEDS_TIMER=y
+CONFIG_LEDS_CPU=y
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="mem=32M console=ttyS0,115200 root=fe01 rw"
+# 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
+
+#
+# Power management options
+#
+CONFIG_PM=y
+CONFIG_PM_LEGACY=y
+CONFIG_PM_DEBUG=y
+# CONFIG_DISABLE_CONSOLE_SUSPEND 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=y
+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=y
+# 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=y
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+# CONFIG_IP_PIMSM_V1 is not set
+# CONFIG_IP_PIMSM_V2 is not set
+CONFIG_ARPD=y
+# CONFIG_SYN_COOKIES is not set
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_TUNNEL=m
+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_IPV6=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+# CONFIG_IPV6_ROUTE_INFO is not set
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+# CONFIG_IPV6_MIP6 is not set
+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=m
+# CONFIG_IPV6_MULTIPLE_TABLES 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=m
+CONFIG_VLAN_8021Q=m
+CONFIG_DECNET=m
+CONFIG_DECNET_ROUTER=y
+CONFIG_LLC=m
+CONFIG_LLC2=m
+CONFIG_IPX=m
+CONFIG_IPX_INTERN=y
+CONFIG_ATALK=m
+CONFIG_DEV_APPLETALK=m
+CONFIG_IPDDP=m
+CONFIG_IPDDP_ENCAP=y
+CONFIG_IPDDP_DECAP=y
+# CONFIG_X25 is not set
+CONFIG_LAPB=m
+CONFIG_ECONET=m
+CONFIG_ECONET_AUNUDP=y
+CONFIG_ECONET_NATIVE=y
+CONFIG_WAN_ROUTER=m
+
+#
+# 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=m
+
+#
+# IrDA protocols
+#
+CONFIG_IRLAN=m
+CONFIG_IRNET=m
+CONFIG_IRCOMM=m
+# CONFIG_IRDA_ULTRA is not set
+
+#
+# IrDA options
+#
+# CONFIG_IRDA_CACHE_LAST_LSAP is not set
+# CONFIG_IRDA_FAST_RR is not set
+# CONFIG_IRDA_DEBUG is not set
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+CONFIG_IRTTY_SIR=m
+
+#
+# Dongle support
+#
+CONFIG_DONGLE=y
+# CONFIG_ESI_DONGLE is not set
+# CONFIG_ACTISYS_DONGLE is not set
+# CONFIG_TEKRAM_DONGLE is not set
+# CONFIG_TOIM3232_DONGLE is not set
+# CONFIG_LITELINK_DONGLE is not set
+# CONFIG_MA600_DONGLE is not set
+# CONFIG_GIRBIL_DONGLE is not set
+# CONFIG_MCP2120_DONGLE is not set
+# CONFIG_OLD_BELKIN_DONGLE is not set
+# CONFIG_ACT200L_DONGLE is not set
+
+#
+# Old SIR device drivers
+#
+CONFIG_IRPORT_SIR=m
+
+#
+# Old Serial dongle support
+#
+# CONFIG_DONGLE_OLD is not set
+
+#
+# FIR device drivers
+#
+CONFIG_USB_IRDA=m
+# CONFIG_SIGMATEL_FIR is not set
+# CONFIG_MCS_FIR 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_CMTP=m
+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=m
+CONFIG_BT_HCIBPA10X=m
+CONFIG_BT_HCIBFUSB=m
+CONFIG_BT_HCIDTL1=m
+CONFIG_BT_HCIBT3C=m
+CONFIG_BT_HCIBLUECARD=m
+CONFIG_BT_HCIBTUART=m
+CONFIG_BT_HCIVHCI=m
+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_WIRELESS_EXT=y
+CONFIG_FIB_RULES=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=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=y
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+# CONFIG_MTD_BLKDEVS is not set
+# CONFIG_MTD_BLOCK is not set
+# 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=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 is not set
+# CONFIG_MTD_CFI_STAA 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=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_START=0x8000000
+CONFIG_MTD_PHYSMAP_LEN=0
+CONFIG_MTD_PHYSMAP_BANKWIDTH=2
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+CONFIG_MTD_DATAFLASH=y
+CONFIG_MTD_M25P80=y
+# 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=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+CONFIG_MTD_NAND_AT91=y
+# CONFIG_MTD_NAND_NANDSIM is not set
+
+#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
+#
+# Parallel port support
+#
+CONFIG_PARPORT=m
+# CONFIG_PARPORT_PC is not set
+# CONFIG_PARPORT_GSC is not set
+# CONFIG_PARPORT_AX88796 is not set
+# CONFIG_PARPORT_1284 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=y
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+# 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
+
+#
+# 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 is not set
+CONFIG_IDEDISK_MULTI_MODE=y
+CONFIG_BLK_DEV_IDECS=m
+CONFIG_BLK_DEV_IDECD=m
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+CONFIG_BLK_DEV_IDESCSI=m
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=m
+# CONFIG_IDE_ARM is not set
+# CONFIG_BLK_DEV_IDEDMA is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+CONFIG_RAID_ATTRS=m
+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=m
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+CONFIG_CHR_DEV_SG=y
+# 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_SCSI_DEBUG 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
+
+#
+# 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=m
+
+#
+# PHY device support
+#
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+CONFIG_STE100P_PHY=m
+# CONFIG_FIXED_PHY is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_ARM_AT91_ETHER=y
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_NET_POCKET 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=m
+CONFIG_PCMCIA_WAVELAN=m
+CONFIG_PCMCIA_NETWAVE=m
+
+#
+# Wireless 802.11 Frequency Hopping cards support
+#
+CONFIG_PCMCIA_RAYCS=m
+
+#
+# Wireless 802.11b ISA/PCI cards support
+#
+CONFIG_HERMES=m
+CONFIG_ATMEL=m
+
+#
+# Wireless 802.11b Pcmcia/Cardbus cards support
+#
+CONFIG_PCMCIA_HERMES=m
+CONFIG_PCMCIA_SPECTRUM=m
+CONFIG_AIRO_CS=m
+CONFIG_PCMCIA_ATMEL=m
+CONFIG_PCMCIA_WL3501=m
+# CONFIG_USB_ZD1201 is not set
+CONFIG_HOSTAP=m
+CONFIG_HOSTAP_FIRMWARE=y
+CONFIG_HOSTAP_FIRMWARE_NVRAM=y
+CONFIG_HOSTAP_CS=m
+# CONFIG_ZD1211RW is not set
+CONFIG_NET_WIRELESS=y
+
+#
+# PCMCIA network device support
+#
+CONFIG_NET_PCMCIA=y
+CONFIG_PCMCIA_3C589=m
+CONFIG_PCMCIA_3C574=m
+CONFIG_PCMCIA_FMVJ18X=m
+CONFIG_PCMCIA_PCNET=m
+CONFIG_PCMCIA_NMCLAN=m
+CONFIG_PCMCIA_SMC91C92=m
+CONFIG_PCMCIA_XIRC2PS=m
+CONFIG_PCMCIA_AXNET=m
+
+#
+# Wan interfaces
+#
+CONFIG_WAN=y
+# CONFIG_HDLC is not set
+# CONFIG_DLCI is not set
+# CONFIG_WAN_ROUTER_DRIVERS is not set
+# CONFIG_PLIP is not set
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLHC=m
+# CONFIG_SLIP_SMART is not set
+# CONFIG_SLIP_MODE_SLIP6 is not set
+# CONFIG_SHAPER is not set
+CONFIG_NETCONSOLE=m
+CONFIG_NETPOLL=y
+# CONFIG_NETPOLL_TRAP is not set
+CONFIG_NET_POLL_CONTROLLER=y
+
+#
+# ISDN subsystem
+#
+CONFIG_ISDN=m
+
+#
+# Old ISDN4Linux
+#
+CONFIG_ISDN_I4L=m
+# CONFIG_ISDN_PPP is not set
+# CONFIG_ISDN_AUDIO is not set
+
+#
+# ISDN feature submodules
+#
+# CONFIG_ISDN_DRV_LOOP is not set
+# CONFIG_ISDN_DIVERSION is not set
+
+#
+# ISDN4Linux hardware drivers
+#
+
+#
+# Passive cards
+#
+# CONFIG_ISDN_DRV_HISAX is not set
+
+#
+# Active cards
+#
+
+#
+# Siemens Gigaset
+#
+# CONFIG_ISDN_DRV_GIGASET is not set
+
+#
+# CAPI subsystem
+#
+CONFIG_ISDN_CAPI=m
+# CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON is not set
+CONFIG_CAPI_TRACE=y
+# CONFIG_ISDN_CAPI_MIDDLEWARE is not set
+CONFIG_ISDN_CAPI_CAPI20=m
+CONFIG_ISDN_CAPI_CAPIDRV=m
+
+#
+# CAPI hardware drivers
+#
+
+#
+# Active AVM cards
+#
+# CONFIG_CAPI_AVM is not set
+
+#
+# Active Eicon DIVA Server cards
+#
+# CONFIG_CAPI_EICON 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 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 is not set
+# 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 is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_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_ATMEL=y
+CONFIG_SERIAL_ATMEL_CONSOLE=y
+# CONFIG_SERIAL_ATMEL_TTYAT is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+CONFIG_PRINTER=m
+# CONFIG_LP_CONSOLE is not set
+# CONFIG_PPDEV is not set
+# CONFIG_TIPAR is not set
+
+#
+# IPMI
+#
+CONFIG_IPMI_HANDLER=m
+# CONFIG_IPMI_PANIC_EVENT is not set
+# CONFIG_IPMI_DEVICE_INTERFACE is not set
+# CONFIG_IPMI_SI is not set
+# CONFIG_IPMI_WATCHDOG is not set
+# CONFIG_IPMI_POWEROFF is not set
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_AT91RM9200_WATCHDOG=y
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+CONFIG_HW_RANDOM=m
+# CONFIG_NVRAM is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+CONFIG_CARDMAN_4000=m
+CONFIG_CARDMAN_4040=m
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_AT91_SPI is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=m
+CONFIG_I2C_ALGOPCF=m
+CONFIG_I2C_ALGOPCA=m
+
+#
+# I2C Hardware Bus support
+#
+CONFIG_I2C_AT91=y
+CONFIG_I2C_AT91_CLOCKRATE=100000
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PARPORT is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_PCA is not set
+# CONFIG_I2C_PCA_ISA is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+CONFIG_SENSORS_DS1337=m
+CONFIG_SENSORS_DS1374=m
+CONFIG_SENSORS_EEPROM=m
+CONFIG_SENSORS_PCF8574=m
+CONFIG_SENSORS_PCA9539=m
+CONFIG_SENSORS_PCF8591=m
+CONFIG_SENSORS_MAX6875=m
+# 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_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_ATMEL is not set
+CONFIG_SPI_BITBANG=y
+# CONFIG_SPI_BUTTERFLY is not set
+CONFIG_SPI_AT91=y
+CONFIG_SPI_AT91_MANUAL_CS=y
+
+#
+# SPI Protocol Masters
+#
+CONFIG_SPI_AT25=m
+
+#
+# Dallas's 1-wire bus
+#
+CONFIG_W1=m
+
+#
+# 1-wire Bus Masters
+#
+# CONFIG_W1_MASTER_DS2490 is not set
+CONFIG_W1_MASTER_DS2482=m
+
+#
+# 1-wire Slaves
+#
+CONFIG_W1_SLAVE_THERM=m
+CONFIG_W1_SLAVE_SMEM=m
+CONFIG_W1_SLAVE_DS2433=m
+# CONFIG_W1_SLAVE_DS2433_CRC is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU 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=m
+# 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_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
+
+#
+# Misc devices
+#
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
+# LED devices
+#
+CONFIG_NEW_LEDS=y
+# CONFIG_LEDS_CLASS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+# CONFIG_LEDS_TRIGGERS is not set
+
+#
+# Multimedia devices
+#
+CONFIG_VIDEO_DEV=y
+CONFIG_VIDEO_V4L1=y
+CONFIG_VIDEO_V4L1_COMPAT=y
+CONFIG_VIDEO_V4L2=y
+
+#
+# Video Capture Adapters
+#
+
+#
+# Video Capture Adapters
+#
+# CONFIG_VIDEO_ADV_DEBUG is not set
+CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
+# CONFIG_VIDEO_BWQCAM is not set
+# CONFIG_VIDEO_CQCAM is not set
+# 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
+
+#
+# V4L USB devices
+#
+# 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
+
+#
+# Radio Adapters
+#
+# CONFIG_USB_DSBR 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 is not set
+# CONFIG_FB_CFB_COPYAREA is not set
+# CONFIG_FB_CFB_IMAGEBLIT is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_S1D15605 is not set
+# CONFIG_FB_S1D13XXX 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 is not set
+
+#
+# Logo configuration
+#
+# CONFIG_LOGO is not set
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+CONFIG_SND_HWDEP=m
+CONFIG_SND_RAWMIDI=m
+CONFIG_SND_SEQUENCER=m
+# CONFIG_SND_SEQ_DUMMY 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_SEQUENCER_OSS=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_MPU401_UART=m
+CONFIG_SND_VX_LIB=m
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_VIRMIDI is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_MTS64 is not set
+CONFIG_SND_SERIAL_U16550=m
+CONFIG_SND_MPU401=m
+# CONFIG_SND_PORTMAN2X4 is not set
+
+#
+# ALSA ARM devices
+#
+
+#
+# USB devices
+#
+CONFIG_SND_USB_AUDIO=m
+
+#
+# PCMCIA devices
+#
+CONFIG_SND_VXPOCKET=m
+CONFIG_SND_PDAUDIOCF=m
+
+#
+# SoC audio support
+#
+CONFIG_SND_SOC=m
+
+#
+# SoC Platforms
+#
+
+#
+# SoC Audio for the Atmel AT91
+#
+CONFIG_SND_AT91_SOC=m
+
+#
+# SoC Audio for the Intel PXA2xx
+#
+
+#
+# Open Sound System
+#
+CONFIG_SOUND_PRIME=m
+CONFIG_OBSOLETE_OSS=y
+# CONFIG_SOUND_MSNDCLAS is not set
+# CONFIG_SOUND_MSNDPIN is not set
+CONFIG_SOUND_TVMIXER=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 is not set
+CONFIG_USB=m
+CONFIG_USB_DEBUG=y
+
+#
+# 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_ISP116X_HCD is not set
+CONFIG_USB_OHCI_HCD=m
+# 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
+
+#
+# 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=y
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+# CONFIG_USB_STORAGE_ISD200 is not set
+CONFIG_USB_STORAGE_DPCM=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_STORAGE_ALAUDA=y
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_LIBUSUAL 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
+# 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
+#
+# CONFIG_USB_USS720 is not set
+
+#
+# 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=m
+# 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 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_SERIAL_DEBUG 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=m
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+CONFIG_USB_GADGET_SELECTED=y
+# 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=y
+CONFIG_USB_AT91=m
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+# CONFIG_USB_GADGET_DUALSPEED is not set
+CONFIG_USB_ZERO=m
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_RNDIS=y
+CONFIG_USB_GADGETFS=m
+# CONFIG_USB_FILE_STORAGE is not set
+CONFIG_USB_G_SERIAL=m
+# 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_AT91=y
+
+#
+# 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_X1205 is not set
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+CONFIG_RTC_DRV_AT91RM9200=y
+# CONFIG_RTC_DRV_TEST is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+# 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=m
+# CONFIG_REISERFS_CHECK is not set
+CONFIG_REISERFS_PROC_INFO=y
+CONFIG_REISERFS_FS_XATTR=y
+# CONFIG_REISERFS_FS_POSIX_ACL is not set
+# CONFIG_REISERFS_FS_SECURITY is not set
+CONFIG_JFS_FS=m
+CONFIG_JFS_POSIX_ACL=y
+CONFIG_JFS_SECURITY=y
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=m
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_SECURITY is not set
+# CONFIG_XFS_POSIX_ACL is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+CONFIG_MINIX_FS=y
+CONFIG_ROMFS_FS=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_QUOTA=y
+CONFIG_QFMT_V1=y
+CONFIG_QFMT_V2=y
+CONFIG_QUOTACTL=y
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=y
+CONFIG_AUTOFS4_FS=y
+# CONFIG_FUSE_FS is not set
+
+#
+# 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=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+CONFIG_NTFS_FS=m
+# CONFIG_NTFS_DEBUG is not set
+CONFIG_NTFS_RW=y
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_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=m
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_SUMMARY is not set
+# 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=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=m
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+# CONFIG_NFS_DIRECTIO is not set
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
+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_RPCSEC_GSS_KRB5=m
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+CONFIG_SMB_FS=m
+# 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=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+CONFIG_MINIX_SUBPARTITION=y
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+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=m
+CONFIG_NLS_CODEPAGE_852=m
+# 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=m
+# 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=m
+
+#
+# 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=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_SLAB is not set
+CONFIG_DEBUG_PREEMPT=y
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+CONFIG_DEBUG_SPINLOCK=y
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+CONFIG_DEBUG_KOBJECT=y
+# 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 is not set
+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=m
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+# 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=y
+# CONFIG_CRYPTO_FCRYPT is not set
+CONFIG_CRYPTO_BLOWFISH=m
+# 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=y
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/recipes/linux/linux/simpad/collie-kexec.patch b/recipes/linux/linux/simpad/collie-kexec.patch
new file mode 100644
index 0000000000..2c8fa9352b
--- /dev/null
+++ b/recipes/linux/linux/simpad/collie-kexec.patch
@@ -0,0 +1,13 @@
+--- linux-2.6.20.4.orig/include/asm-arm/kexec.h 2007-04-10 19:16:39.000000000 +0200
++++ linux-2.6.20.4/include/asm-arm/kexec.h 2007-04-03 05:01:09.000000000 +0200
+@@ -8,8 +8,8 @@
+ /* Maximum address we can reach in physical address mode */
+ #define KEXEC_DESTINATION_MEMORY_LIMIT (-1UL)
+ /* Maximum address we can use for the control code buffer */
+-#define KEXEC_CONTROL_MEMORY_LIMIT TASK_SIZE
+-
++//#define KEXEC_CONTROL_MEMORY_LIMIT TASK_SIZE
++#define KEXEC_CONTROL_MEMORY_LIMIT (-1UL)
+ #define KEXEC_CONTROL_CODE_SIZE 4096
+
+ #define KEXEC_ARCH KEXEC_ARCH_ARM
diff --git a/recipes/linux/linux/simpad/connectplus-remove-ide-HACK.patch b/recipes/linux/linux/simpad/connectplus-remove-ide-HACK.patch
new file mode 100644
index 0000000000..4414b21191
--- /dev/null
+++ b/recipes/linux/linux/simpad/connectplus-remove-ide-HACK.patch
@@ -0,0 +1,12 @@
+Index: linux-2.6.13/drivers/ide/legacy/ide-cs.c
+===================================================================
+--- linux-2.6.13.orig/drivers/ide/legacy/ide-cs.c 2005-09-01 22:43:46.000000000 +0100
++++ linux-2.6.13/drivers/ide/legacy/ide-cs.c 2005-09-01 22:45:46.000000000 +0100
+@@ -488,7 +488,6 @@
+ PCMCIA_DEVICE_PROD_ID123("KODAK Picture Card ", "KODAK ", "V100K", 0x94a0d8f3, 0xe4fc3ea0, 0xe5e7eed4),
+ PCMCIA_DEVICE_PROD_ID1("STI Flash", 0xe4a13209),
+ PCMCIA_DEVICE_PROD_ID12("STI", "Flash 5.0", 0xbf2df18d, 0x8cb57a0e),
+- PCMCIA_MFC_DEVICE_PROD_ID12(1, "SanDisk", "ConnectPlus", 0x7a954bd9, 0x74be00c6),
+ PCMCIA_DEVICE_NULL,
+ };
+ MODULE_DEVICE_TABLE(pcmcia, ide_ids);
diff --git a/recipes/linux/linux/simpad/export_atags-r2.patch b/recipes/linux/linux/simpad/export_atags-r2.patch
new file mode 100644
index 0000000000..e6fd85cf20
--- /dev/null
+++ b/recipes/linux/linux/simpad/export_atags-r2.patch
@@ -0,0 +1,320 @@
+[PATCH] Export atags to userspace and allow kexec to use customised atags
+
+Currently, the atags used by kexec are fixed to the ones originally used
+to boot the kernel. This is less than ideal as changing the commandline,
+initrd and other options would be a useful feature.
+
+This patch exports the atags used for the current kernel to userspace
+through an "atags" file in procfs. The presence of the file is
+controlled by its own Kconfig option and cleans up several ifdef blocks
+into a separate file. The tags for the new kernel are assumed to be at
+a fixed location before the kernel image itself. The location of the
+tags used to boot the original kernel is unimportant and no longer
+saved.
+
+Based on a patch from Uli Luckas <u.luckas@road.de>
+
+Signed-off-by: Richard Purdie <rpurdie@rpsys.net>
+
+---
+ arch/arm/Kconfig | 7 +++
+ arch/arm/kernel/Makefile | 1
+ arch/arm/kernel/atags.c | 86 ++++++++++++++++++++++++++++++++++++++
+ arch/arm/kernel/atags.h | 5 ++
+ arch/arm/kernel/machine_kexec.c | 2
+ arch/arm/kernel/relocate_kernel.S | 30 +------------
+ arch/arm/kernel/setup.c | 32 --------------
+ include/asm-arm/kexec.h | 3 +
+ 8 files changed, 110 insertions(+), 56 deletions(-)
+
+Index: linux-2.6.23/arch/arm/kernel/atags.c
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.23/arch/arm/kernel/atags.c 2008-01-20 15:56:02.000000000 +0000
+@@ -0,0 +1,86 @@
++#include <linux/slab.h>
++#include <linux/kexec.h>
++#include <linux/proc_fs.h>
++#include <asm/setup.h>
++#include <asm/types.h>
++#include <asm/page.h>
++
++struct buffer {
++ size_t size;
++ char *data;
++};
++static struct buffer tags_buffer;
++
++static int
++read_buffer(char* page, char** start, off_t off, int count,
++ int* eof, void* data)
++{
++ struct buffer *buffer = (struct buffer *)data;
++
++ if (off >= buffer->size) {
++ *eof = 1;
++ return 0;
++ }
++
++ count = min((int) (buffer->size - off), count);
++
++ memcpy(page, &buffer->data[off], count);
++
++ return count;
++}
++
++
++static int
++create_proc_entries(void)
++{
++ struct proc_dir_entry* tags_entry;
++
++ tags_entry = create_proc_read_entry("atags", 0400, &proc_root, read_buffer, &tags_buffer);
++ if (!tags_entry)
++ return -ENOMEM;
++
++ return 0;
++}
++
++
++static char __initdata atags_copy_buf[KEXEC_BOOT_PARAMS_SIZE];
++static char __initdata *atags_copy;
++
++void __init save_atags(const struct tag *tags)
++{
++ atags_copy = atags_copy_buf;
++ memcpy(atags_copy, tags, KEXEC_BOOT_PARAMS_SIZE);
++}
++
++
++static int __init init_atags_procfs(void)
++{
++ struct tag *tag;
++ int error;
++
++ if (!atags_copy) {
++ printk(KERN_WARNING "Exporting ATAGs: No saved tags found\n");
++ return -EIO;
++ }
++
++ for (tag = (struct tag *) atags_copy; tag->hdr.size; tag = tag_next(tag))
++ ;
++
++ tags_buffer.size = ((char *) tag - atags_copy) + sizeof(tag->hdr);
++ tags_buffer.data = kmalloc(tags_buffer.size, GFP_KERNEL);
++ if (tags_buffer.data == NULL)
++ return -ENOMEM;
++ memcpy(tags_buffer.data, atags_copy, tags_buffer.size);
++
++ error = create_proc_entries();
++ if (error) {
++ printk(KERN_ERR "Exporting ATAGs: not enough memory\n");
++ kfree(tags_buffer.data);
++ tags_buffer.size = 0;
++ tags_buffer.data = NULL;
++ }
++
++ return error;
++}
++
++arch_initcall(init_atags_procfs);
+Index: linux-2.6.23/arch/arm/kernel/atags.h
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.23/arch/arm/kernel/atags.h 2008-01-20 15:56:02.000000000 +0000
+@@ -0,0 +1,5 @@
++#ifdef CONFIG_ATAGS_PROC
++extern void save_atags(struct tag *tags);
++#else
++static inline void save_atags(struct tag *tags) { }
++#endif
+Index: linux-2.6.23/arch/arm/kernel/Makefile
+===================================================================
+--- linux-2.6.23.orig/arch/arm/kernel/Makefile 2007-10-09 21:31:38.000000000 +0100
++++ linux-2.6.23/arch/arm/kernel/Makefile 2008-01-20 15:56:02.000000000 +0000
+@@ -19,6 +19,7 @@ obj-$(CONFIG_ISA_DMA) += dma-isa.o
+ obj-$(CONFIG_PCI) += bios32.o isa.o
+ obj-$(CONFIG_SMP) += smp.o
+ obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
++obj-$(CONFIG_ATAGS_PROC) += atags.o
+ obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o
+
+ obj-$(CONFIG_CRUNCH) += crunch.o crunch-bits.o
+Index: linux-2.6.23/arch/arm/kernel/setup.c
+===================================================================
+--- linux-2.6.23.orig/arch/arm/kernel/setup.c 2008-01-20 15:55:43.000000000 +0000
++++ linux-2.6.23/arch/arm/kernel/setup.c 2008-01-20 15:56:02.000000000 +0000
+@@ -24,7 +24,6 @@
+ #include <linux/interrupt.h>
+ #include <linux/smp.h>
+ #include <linux/fs.h>
+-#include <linux/kexec.h>
+
+ #include <asm/cpu.h>
+ #include <asm/elf.h>
+@@ -39,6 +38,7 @@
+ #include <asm/mach/time.h>
+
+ #include "compat.h"
++#include "atags.h"
+
+ #ifndef MEM_SIZE
+ #define MEM_SIZE (16*1024*1024)
+@@ -784,23 +784,6 @@ static int __init customize_machine(void
+ }
+ arch_initcall(customize_machine);
+
+-#ifdef CONFIG_KEXEC
+-
+-/* Physical addr of where the boot params should be for this machine */
+-extern unsigned long kexec_boot_params_address;
+-
+-/* Physical addr of the buffer into which the boot params are copied */
+-extern unsigned long kexec_boot_params_copy;
+-
+-/* Pointer to the boot params buffer, for manipulation and display */
+-unsigned long kexec_boot_params;
+-EXPORT_SYMBOL(kexec_boot_params);
+-
+-/* The buffer itself - make sure it is sized correctly */
+-static unsigned long kexec_boot_params_buf[(KEXEC_BOOT_PARAMS_SIZE + 3) / 4];
+-
+-#endif
+-
+ void __init setup_arch(char **cmdline_p)
+ {
+ struct tag *tags = (struct tag *)&init_tags;
+@@ -819,18 +802,6 @@ void __init setup_arch(char **cmdline_p)
+ else if (mdesc->boot_params)
+ tags = phys_to_virt(mdesc->boot_params);
+
+-#ifdef CONFIG_KEXEC
+- kexec_boot_params_copy = virt_to_phys(kexec_boot_params_buf);
+- kexec_boot_params = (unsigned long)kexec_boot_params_buf;
+- if (__atags_pointer) {
+- kexec_boot_params_address = __atags_pointer;
+- memcpy((void *)kexec_boot_params, tags, KEXEC_BOOT_PARAMS_SIZE);
+- } else if (mdesc->boot_params) {
+- kexec_boot_params_address = mdesc->boot_params;
+- memcpy((void *)kexec_boot_params, tags, KEXEC_BOOT_PARAMS_SIZE);
+- }
+-#endif
+-
+ /*
+ * If we have the old style parameters, convert them to
+ * a tag list.
+@@ -846,6 +817,7 @@ void __init setup_arch(char **cmdline_p)
+ if (tags->hdr.tag == ATAG_CORE) {
+ if (meminfo.nr_banks != 0)
+ squash_mem_tags(tags);
++ save_atags(tags);
+ parse_tags(tags);
+ }
+
+Index: linux-2.6.23/arch/arm/Kconfig
+===================================================================
+--- linux-2.6.23.orig/arch/arm/Kconfig 2008-01-20 15:55:43.000000000 +0000
++++ linux-2.6.23/arch/arm/Kconfig 2008-01-20 15:58:52.000000000 +0000
+@@ -865,6 +865,13 @@ config KEXEC
+ initially work for you. It may help to enable device hotplugging
+ support.
+
++config ATAGS_PROC
++ bool "Export atags in procfs"
++ default n
++ help
++ Should the atags used to boot the kernel be exported in an "atags"
++ file in procfs. Useful with kexec.
++
+ endmenu
+
+ if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP || ARCH_IMX )
+Index: linux-2.6.23/arch/arm/kernel/machine_kexec.c
+===================================================================
+--- linux-2.6.23.orig/arch/arm/kernel/machine_kexec.c 2007-10-09 21:31:38.000000000 +0100
++++ linux-2.6.23/arch/arm/kernel/machine_kexec.c 2008-01-20 15:56:03.000000000 +0000
+@@ -21,6 +21,7 @@ extern void setup_mm_for_reboot(char mod
+ extern unsigned long kexec_start_address;
+ extern unsigned long kexec_indirection_page;
+ extern unsigned long kexec_mach_type;
++extern unsigned long kexec_boot_atags;
+
+ /*
+ * Provide a dummy crash_notes definition while crash dump arrives to arm.
+@@ -62,6 +63,7 @@ void machine_kexec(struct kimage *image)
+ kexec_start_address = image->start;
+ kexec_indirection_page = page_list;
+ kexec_mach_type = machine_arch_type;
++ kexec_boot_atags = image->start - KEXEC_ARM_ZIMAGE_OFFSET + KEXEC_ARM_ATAGS_OFFSET;
+
+ /* copy our kernel relocation code to the control code page */
+ memcpy(reboot_code_buffer,
+Index: linux-2.6.23/arch/arm/kernel/relocate_kernel.S
+===================================================================
+--- linux-2.6.23.orig/arch/arm/kernel/relocate_kernel.S 2008-01-20 15:55:43.000000000 +0000
++++ linux-2.6.23/arch/arm/kernel/relocate_kernel.S 2008-01-20 15:56:03.000000000 +0000
+@@ -7,23 +7,6 @@
+ .globl relocate_new_kernel
+ relocate_new_kernel:
+
+- /* Move boot params back to where the kernel expects them */
+-
+- ldr r0,kexec_boot_params_address
+- teq r0,#0
+- beq 8f
+-
+- ldr r1,kexec_boot_params_copy
+- mov r6,#KEXEC_BOOT_PARAMS_SIZE/4
+-7:
+- ldr r5,[r1],#4
+- str r5,[r0],#4
+- subs r6,r6,#1
+- bne 7b
+-
+-8:
+- /* Boot params moved, now go on with the kernel */
+-
+ ldr r0,kexec_indirection_page
+ ldr r1,kexec_start_address
+
+@@ -67,7 +50,7 @@ relocate_new_kernel:
+ mov lr,r1
+ mov r0,#0
+ ldr r1,kexec_mach_type
+- ldr r2,kexec_boot_params_address
++ ldr r2,kexec_boot_atags
+ mov pc,lr
+
+ .globl kexec_start_address
+@@ -82,14 +65,9 @@ kexec_indirection_page:
+ kexec_mach_type:
+ .long 0x0
+
+- /* phy addr where new kernel will expect to find boot params */
+- .globl kexec_boot_params_address
+-kexec_boot_params_address:
+- .long 0x0
+-
+- /* phy addr where old kernel put a copy of orig boot params */
+- .globl kexec_boot_params_copy
+-kexec_boot_params_copy:
++ /* phy addr of the atags for the new kernel */
++ .globl kexec_boot_atags
++kexec_boot_atags:
+ .long 0x0
+
+ relocate_new_kernel_end:
+Index: linux-2.6.23/include/asm-arm/kexec.h
+===================================================================
+--- linux-2.6.23.orig/include/asm-arm/kexec.h 2008-01-20 15:55:57.000000000 +0000
++++ linux-2.6.23/include/asm-arm/kexec.h 2008-01-20 15:56:03.000000000 +0000
+@@ -16,6 +16,9 @@
+
+ #define KEXEC_BOOT_PARAMS_SIZE 1536
+
++#define KEXEC_ARM_ATAGS_OFFSET 0x1000
++#define KEXEC_ARM_ZIMAGE_OFFSET 0x8000
++
+ #ifndef __ASSEMBLY__
+
+ struct kimage;
diff --git a/recipes/linux/linux/simpad/linux-2.6.21-SIMpad-GPIO-MMC-mod.patch b/recipes/linux/linux/simpad/linux-2.6.21-SIMpad-GPIO-MMC-mod.patch
new file mode 100644
index 0000000000..22f220de8a
--- /dev/null
+++ b/recipes/linux/linux/simpad/linux-2.6.21-SIMpad-GPIO-MMC-mod.patch
@@ -0,0 +1,1650 @@
+diff -uNr linux-2.6.21.vanilla/drivers/mmc/Kconfig linux-2.6.21/drivers/mmc/Kconfig
+--- linux-2.6.21.vanilla/drivers/mmc/Kconfig 2007-05-30 18:00:30.000000000 +0200
++++ linux-2.6.21/drivers/mmc/Kconfig 2007-05-30 18:26:18.000000000 +0200
+@@ -4,6 +4,12 @@
+
+ menu "MMC/SD Card support"
+
++config MMC_SPI_BLOCK
++ tristate "MMC support for SIMpad over GPIO"
++ help
++ Say Y here to enable MMC block device over GPIO
++ if you have done the MMC-Mod. For Module say M.
++
+ config MMC
+ tristate "MMC support"
+ help
+diff -uNr linux-2.6.21.vanilla/drivers/mmc/Makefile linux-2.6.21/drivers/mmc/Makefile
+--- linux-2.6.21.vanilla/drivers/mmc/Makefile 2007-05-30 18:00:30.000000000 +0200
++++ linux-2.6.21/drivers/mmc/Makefile 2007-05-30 18:26:18.000000000 +0200
+@@ -2,6 +2,8 @@
+ # Makefile for the kernel mmc device drivers.
+ #
+
++obj-$(CONFIG_MMC_SPI_BLOCK) += mmc_spi_block.o
++
+ #
+ # Core
+ #
+diff -uNr linux-2.6.21.vanilla/drivers/mmc/mmc_spi_block.c linux-2.6.21/drivers/mmc/mmc_spi_block.c
+--- linux-2.6.21.vanilla/drivers/mmc/mmc_spi_block.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.21/drivers/mmc/mmc_spi_block.c 2007-05-30 18:30:58.000000000 +0200
+@@ -0,0 +1,1618 @@
++/*
++ * Copyright (c) Cl�ent Ballabriga, 2005 - GPL
++ * Copyright (c) Guylhem Aznar, 2005 - GPL
++ *
++ * Please check http://externe.net/zaurus/simpad-bluetooth reference design first.
++ *
++ * Based on Madsuk/Rohde work on a MMC driver for the WRT54G.
++ *
++ * This is an ugly hack of a driver. I am surprised if it ever works!
++ * So please use a real driver or contribute one to the 2.4/2.6 mmc framework
++ *
++ * mrdata: ported to 2.6
++ */
++
++#include <linux/module.h>
++#include <linux/init.h>
++
++#include <linux/sched.h>
++#include <linux/kernel.h>
++#include <linux/fs.h>
++#include <linux/errno.h>
++#include <linux/hdreg.h>
++#include <linux/kdev_t.h>
++#include <linux/blkdev.h>
++#include <linux/spinlock.h>
++#include <linux/time.h>
++#include <linux/delay.h>
++#include <linux/timer.h>
++
++#include <linux/platform_device.h>
++
++#include <asm/hardware.h>
++#include <asm/arch/simpad.h>
++#include <asm/arch/gpio.h>
++
++static int major = 121;
++
++#define DEVICE_NAME "mmc_spi"
++
++static int hd_sizes[1<<6];
++static int hd_blocksizes[1<<6];
++static int hd_hardsectsizes[1<<6];
++static int hd_maxsect[1<<6];
++static struct hd_struct hd[1<<6];
++
++static struct gendisk *mmc_disk;
++
++static struct platform_device *mmc_dev; /* the one and only instance */
++
++static spinlock_t mmc_spi_lock;
++
++/*
++ * *******************************************************************
++ *
++ * This is the only configurable part.
++ *
++ * *******************************************************************
++ *
++ */
++
++// #define DEBUG 1
++// #define DEBUG_HD 1
++// #define CHECK_MEDIA_CHANGE // for developement ONLY, not working yet
++
++/* Let that include where it is or compilation fails on INIT_REQUEST/CURRENT */
++
++
++/*
++ * If you are using different GPIOs in your hardware hack, you must
++ * first make sure they are unused for other functions and then
++ * configure them here.
++ *
++ * On the simpad I use spare pins from the UART1 (internal serial port -> DECT 20-polig):
++ *
++ * Funktion PIN ## Original direction GPIO ## SPI function New direction SD/MMC
++ * - DCD PIN 08 (in) GPIO 23 DO - new name: DI -> MISO (in) PIN 7 Data Out
++ * - DTR PIN 11 (out) GPIO 07 CS (out) PIN 1 Chip Select
++ * - RI PIN 14 (in) GPIO 19 CLK (out) PIN 5 Clock
++ * - DSR PIN 16 (in) GPIO 06 DI - new name: DO -> MOSI (out) PIN 2 Data In
++ *
++ *
++ * SPI: MISO = Master In / Slave OUT MOSI = Master Out / Slave In
++ *
++ * Don't worry about in/out original function - the GPIOs will be
++ * reprogrammed.
++ */
++
++#define GPIO_SD_DI 23
++#define GPIO_SD_CS 7
++#define GPIO_SD_CLK 19
++#define GPIO_SD_DO 6
++
++// #define FAST_GPIO_SD_DI GPIO_GPIO23
++// #define FAST_GPIO_SD_CS GPIO_GPIO7
++// #define FAST_GPIO_SD_CLK GPIO_GPIO19
++// #define FAST_GPIO_SD_DO GPIO_GPIO6
++
++#define FAST_GPIO_SD_DI GPIO_UART1_DCD
++#define FAST_GPIO_SD_CS GPIO_UART1_DTR
++#define FAST_GPIO_SD_CLK GPIO_UART1_RI
++#define FAST_GPIO_SD_DO GPIO_UART1_DSR
++
++/*
++ * *******************************************************************
++ *
++ * Do not change anything below !
++ *
++ * *******************************************************************
++ *
++ */
++
++/* GPIO states */
++#define LOW 0
++#define HIGH 1
++
++#define INPUT 0
++#define OUTPUT 1
++
++#define PRESENT 1
++#define ABSENT 0
++
++typedef unsigned int uint32;
++typedef unsigned long u32_t;
++typedef unsigned short u16_t;
++typedef unsigned char u8_t;
++
++static struct timer_list mmc_timer;
++
++// static struct timeval s_zeit, e_zeit;
++
++/* start with no card */
++static int mmc_media_detect = 0;
++static int mmc_media_changed = 1;
++
++
++/////////////////////
++// prototypes
++static int mmc_open(struct inode *inode, struct file *filp);
++static int mmc_release(struct inode *inode, struct file *filp);
++static int mmc_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg);
++static void mmc_request(request_queue_t *q);
++
++
++/*
++ * *******************************************************************
++ *
++ * Begin GPIO hardware access functions.
++ *
++ * *******************************************************************
++ *
++ */
++
++#define gpio_read(a) ((GPLR & a) ? 1 : 0)
++#define gpio_write_high(a) GPSR = a
++#define gpio_write_low(a) GPCR = a
++
++/* set MMC_Chip_Select to HIGH (MMC/SD-Card inaktiv) */
++#define MMC_Disable() gpio_write_high( FAST_GPIO_SD_CS)
++
++/* set MMC_Chip_Select to LOW (MMC/SD-Card aktiv) */
++#define MMC_Enable() gpio_write_low( FAST_GPIO_SD_CS)
++
++/*
++ * *******************************************************************
++ *
++ * Begin SPI hardware access functions.
++ *
++ * *******************************************************************
++ *
++ */
++static int mmc_spi_media_detect(void)
++{
++// FIXME: add card detection/test by SPI
++
++ return 1;
++}
++
++static int mmc_spi_hardware_init(void)
++{
++ printk("\nmmc: GPIO init\n");
++
++ /* cut existing functions */
++ gpio_set_alternative_function(GPIO_SD_CLK, 0);
++ gpio_set_alternative_function(GPIO_SD_DI, 0);
++ gpio_set_alternative_function(GPIO_SD_DO, 0);
++ gpio_set_alternative_function(GPIO_SD_CS, 0);
++
++ /* remap directions and set state of spi pins */
++ gpio_direction_output(GPIO_SD_CLK, 0);
++ gpio_direction_input(GPIO_SD_DI);
++ gpio_direction_output(GPIO_SD_DO, 0);
++ gpio_direction_output(GPIO_SD_CS, 0);
++
++ printk("mmc: initialising MMC\n");
++
++ /* Start */
++ MMC_Disable();
++ gpio_write_low( FAST_GPIO_SD_CLK);
++ gpio_write_high( FAST_GPIO_SD_DO);
++ return 0;
++}
++
++/* return what has been read, write the parameter */
++/* Clockrate round about 1,2 MHz */
++
++static unsigned char mmc_spi_readwrite(unsigned char data_out)
++{
++ unsigned char i;
++ unsigned char result = 0;
++
++ for(i = 0x80 ; i != 0 ; i >>= 1)
++ {
++ if (data_out & i)
++ {
++ gpio_write_high( FAST_GPIO_SD_DO);
++ }
++ else
++ {
++ gpio_write_low( FAST_GPIO_SD_DO);
++ }
++
++ gpio_write_high( FAST_GPIO_SD_CLK);
++
++ if (gpio_read( FAST_GPIO_SD_DI) == 1)
++ {
++ result |= i;
++ }
++
++ gpio_write_low( FAST_GPIO_SD_CLK);
++
++ }
++
++ gpio_write_high( FAST_GPIO_SD_DO);
++
++ return (result);
++}
++
++/* return what has been read, write the parameter */
++/* Clockrate round 200 kHz */
++
++static unsigned char mmc_spi_readwrite_slow(unsigned char data_out)
++{
++ unsigned char i;
++ unsigned char result = 0;
++
++ for(i = 0x80 ; i != 0 ; i >>= 1)
++ {
++ if (data_out & i)
++ {
++ gpio_write_high( FAST_GPIO_SD_DO);
++ }
++ else
++ {
++ gpio_write_low( FAST_GPIO_SD_DO);
++ }
++
++ udelay(10);
++
++ gpio_write_high( FAST_GPIO_SD_CLK);
++
++ udelay(10);
++
++ if (gpio_read( FAST_GPIO_SD_DI) == 1)
++ {
++ result |= i;
++ }
++
++ udelay(10);
++
++ gpio_write_low( FAST_GPIO_SD_CLK);
++
++ udelay(10);
++
++ }
++
++ gpio_write_high( FAST_GPIO_SD_DO);
++
++ udelay(10);
++
++ // printk("Send Byte = 0x%2X Receive Byte = 0x%2X \n", data_out, result);
++
++ return (result);
++}
++
++/* return what has been read */
++
++static unsigned char mmc_spi_read_only(void)
++{
++ unsigned char i;
++ unsigned char result = 0;
++
++ for(i = 0x80 ; i != 0 ; i >>= 1)
++ {
++
++ gpio_write_high( FAST_GPIO_SD_CLK);
++
++ if (gpio_read( FAST_GPIO_SD_DI) == 1)
++ {
++ result |= i;
++ }
++
++ gpio_write_low( FAST_GPIO_SD_CLK);
++
++ }
++
++ return (result);
++}
++
++/* write the parameter */
++/* Clockrate round about 3,6 MHz */
++
++static unsigned char mmc_spi_write_only(unsigned char data_out)
++{
++ unsigned char i;
++ unsigned char result = 0;
++
++ for(i = 0x80 ; i != 0 ; i >>= 1)
++ {
++
++ if (data_out & i)
++ {
++ gpio_write_high( FAST_GPIO_SD_DO);
++ }
++ else
++ {
++ gpio_write_low( FAST_GPIO_SD_DO);
++ }
++
++ gpio_write_high( FAST_GPIO_SD_CLK);
++
++ gpio_write_low( FAST_GPIO_SD_CLK);
++
++ }
++
++ gpio_write_high( FAST_GPIO_SD_DO);
++
++ return (result);
++}
++
++
++/**
++ * this function was contributed by: rcichielo from openwrt forums
++ *
++ * Comments added by Marc DENTY on 2007-03-20
++ *
++ * Sequence to read a card's "CID" bytes (name, serial number etc)
++ *
++ * Send: 4ah,00h,00h,00h,00h,00h - CMD10, no args, null CRC
++ * Read: xx - NCR Time
++ * Read: xx - Command Response (Should be 00h)
++ * Read: until FEh is received - Wait for Data token
++ * Read: yy * 16 - Get 16 bytes from CID
++ * Read: zz - Read CRC lo byte
++ * Read: zz - Read CRC hi byte
++ *
++ * Useful locations in the returned data packet:
++ *
++ * 03h-08h Manufacturers's name in ascii
++ * 0ah-0dh Card's 32 bit serial number
++ */
++/**
++ * Comments added by Cyril CATTIAUX on 2007-03-21
++ *
++ * CID format specification (from Sandisk SD Product Manual v1.9)
++ *
++ * cid[00 ] Manufacturer ID (unsigned byte)
++ * cid[01-02] OEM/Application ID (ASCII)
++ * cid[03-07] Product Name (ASCII)
++ * cid[08 ] Product Revistion (BCD coded number)
++ * cid[09-12] Serial Number (32-bit unsigned int)
++ * cid[13-14] Reserved(bit 12->15) - Manufacture Date(bit 0->11)
++ * cid[15 ] CRC7(bit 1->7) - Not used, allways 1 (bit 0)
++*/
++static int mmc_read_cid(unsigned char *cid)
++{
++ unsigned char result = 0;
++ int i;
++
++ MMC_Enable();
++
++ /* wait */
++ for (i = 0; i < 4; i++)
++ {
++ result=mmc_spi_readwrite(0xff);
++ }
++
++ /* issue CID (card identification data) read request */
++ mmc_spi_readwrite(0xff);
++ mmc_spi_readwrite(0x40 | 10);
++ mmc_spi_readwrite(0x00);
++ mmc_spi_readwrite(0x00);
++ mmc_spi_readwrite(0x00);
++ mmc_spi_readwrite(0x00);
++ mmc_spi_readwrite(0x95);
++
++ for (i = 0; i < 8; i++)
++ {
++ result=mmc_spi_readwrite(0xff);
++
++ if(result == 0x00)
++ break;
++ }
++
++ if (result != 0x00) {
++ MMC_Disable();
++ mmc_spi_readwrite(0xff);
++ return(1);
++ }
++
++ for (i = 0; i < 8; i++) {
++ result = mmc_spi_readwrite(0xff);
++ if (result == 0xfe) break;
++ }
++
++ if (result != 0xfe) {
++ MMC_Disable();
++ mmc_spi_readwrite(0xff);
++ return(2);
++ }
++
++ for (i = 0; i < 16; i++) {
++ result = mmc_spi_readwrite(0xff);
++ cid[i] = result;
++ }
++
++ mmc_spi_readwrite(0xff);
++ mmc_spi_readwrite(0xff);
++
++ MMC_Disable();
++ mmc_spi_readwrite(0xff);
++
++ return 0;
++}
++
++
++/**
++ * Comments added by Cyril CATTIAUX on 2007-03-21
++ *
++ * CID format specification (from Sandisk SD Product Manual v1.9)
++ *
++ * cid[00 ] Manufacturer ID (unsigned byte)
++ * cid[01-02] OEM/Application ID (ASCII)
++ * cid[03-07] Product Name (ASCII)
++ * cid[08 ] Product Revision (BCD coded 2 digit number)
++ * cid[09-12] Serial Number (32-bit unsigned int)
++ * cid[13-14] Manufacture Date(bit 0->11) (BCD coded 3 digit number YYM offset from 2000) - Reserved(bit 12->15)
++ * cid[15 ] Not used, allways 1 (bit 0) - CRC7(bit 1->7)
++*/
++static void mmc_show_cid_info(void)
++{
++ int i, result;
++ unsigned short tmps;
++ unsigned char cid[16];
++
++ char manufacturer_id;
++ char oem_id[3];
++ char product_name[6];
++ unsigned char product_revision_h, product_revision_l;
++ unsigned int product_sn;
++ unsigned short product_date_y;
++ unsigned char product_date_m;
++
++ result = mmc_read_cid(cid);
++
++ if (result == 0)
++ {
++ printk("mmc_init: MMC/SD Card ID: ");
++ for (i=0; i<16; i++) {
++ printk("%02X ", cid[i]);
++ }
++ manufacturer_id=cid[0];
++ strncpy(oem_id, &cid[1], 2);
++ oem_id[2]='\0';
++ strncpy(product_name, &cid[3], 5);
++ product_name[5]='\0';
++ product_revision_h=(cid[8] >> 4) & 0xf;
++ product_revision_l=cid[8] & 0xf;
++ product_sn=(cid[9]<<24) + (cid[10]<<16) + (cid[11]<<8) + cid[12];
++ tmps=((cid[13]<<8) + cid[14]) & 0x0fff;
++ product_date_y=2000 + (((tmps >> 8) & 0xf) * 10) + ((tmps >> 4) & 0xf);
++ product_date_m=tmps & 0xf;
++
++ printk("\nManufacturer ID : %02X\n", manufacturer_id);
++ printk("OEM/Application ID: %s\n", oem_id);
++ printk("Product name : %s\n", product_name);
++ printk("Product revision : %d.%d\n", product_revision_h, product_revision_l);
++ printk("Product SN : %08X\n", product_sn);
++ printk("Product Date : %d-%d\n", product_date_y, product_date_m);
++
++ } else {
++ printk("mmc_init: impossible to get card indentification info for reason code: %02x", result);
++ }
++}
++
++
++/*
++static int mmc_spi_hw_test(void)
++{
++ unsigned char result, k;
++
++ unsigned int i, j, t;
++
++ printk("mmc_spi_hw_test -> \n\n");
++ k = 0x55;
++ for ( i = 0 ; i < 5; i++) {
++
++ printk("\n0x%2X - ", k);
++ for ( j = 0 ; j < 8; j++ ) {
++ do_gettimeofday( &s_zeit );
++ result = mmc_spi_readwrite_slow(k);
++ do_gettimeofday( &e_zeit );
++
++ if ( result != k ) {
++ printk("!>ERROR<! Transfer = 0x%2X Receive = 0x%2X Trail = %d \n", k, result, j);
++ // i = 255; j = 1000;
++ }
++
++ t = (e_zeit.tv_sec-s_zeit.tv_sec)*1000000+(e_zeit.tv_usec-s_zeit.tv_usec);
++ printk("Durchlauf: %i Versuch: %i von 8 -> Laufzeit: 0x%X s\n", i , j, t);
++ udelay(200);
++ }
++ printk("ready ");
++
++ // k++;
++ }
++ printk("ready ");
++ printk("\n\n");
++ return (0);
++}
++*/
++
++/*
++static int mmc_spi_speed_test(void)
++{
++ unsigned int i, j, k, l, t;
++
++ MMC_Disable();
++
++ for (k = 1; k < 6; k++)
++ {
++ l = 10000 * k;
++ for (j = 0; j < 5; j++)
++ {
++ do_gettimeofday( &s_zeit );
++ for (i = 0; i < l; i++)
++ mmc_spi_readwrite(0xff);
++ do_gettimeofday( &e_zeit );
++ t = (e_zeit.tv_sec-s_zeit.tv_sec)*1000000+(e_zeit.tv_usec-s_zeit.tv_usec);
++ printk("mmc_spi_readwrite: Laufzeit %u x : 0x%X \n", l, t);
++ }
++ }
++
++ for (k = 1; k < 1; k++)
++ {
++ l = 10000 * k;
++ for (j = 0; j < 1; j++)
++ {
++ do_gettimeofday( &s_zeit );
++ for (i = 0; i < l; i++)
++ mmc_spi_readwrite_slow(0xff);
++ do_gettimeofday( &e_zeit );
++ t = (e_zeit.tv_sec-s_zeit.tv_sec)*1000000+(e_zeit.tv_usec-s_zeit.tv_usec);
++ printk("mmc_spi_readwrite_slow: Laufzeit %u x : 0x%X \n", l, t);
++ }
++ }
++
++ for (k = 1; k < 6; k++)
++ {
++ l = 10000 * k;
++ for (j = 0; j < 5; j++)
++ {
++ do_gettimeofday( &s_zeit );
++ for (i = 0; i < l; i++)
++ mmc_spi_read_only();
++ do_gettimeofday( &e_zeit );
++ t = (e_zeit.tv_sec-s_zeit.tv_sec)*1000000+(e_zeit.tv_usec-s_zeit.tv_usec);
++ printk("mmc_spi_read_only: Laufzeit %u x : 0x%X \n", l, t);
++ }
++ }
++
++ for (k = 1; k < 6; k++)
++ {
++ l = 10000 * k;
++ for (j = 0; j < 5; j++)
++ {
++ do_gettimeofday( &s_zeit );
++ for (i = 0; i < l; i++)
++ mmc_spi_write_only(0xff);
++ do_gettimeofday( &e_zeit );
++ t = (e_zeit.tv_sec-s_zeit.tv_sec)*1000000+(e_zeit.tv_usec-s_zeit.tv_usec);
++ printk("mmc_spi_write_only: Laufzeit %u x : 0x%X \n", l, t);
++ }
++ }
++
++ return (1);
++
++}
++*/
++
++
++static int mmc_spi_card_init(void)
++{
++ unsigned char result = 0;
++ short i, j;
++
++// unsigned long flags;
++
++ // save_flags(flags);
++ // cli();
++
++/*
++ printk("GPIO_SD_CS dir: %u alt: %u\n", gpio_getdir(&gp, GPIO_SD_CS), gpio_getalt(&gp, GPIO_SD_CS));
++ printk("GPIO_SD_DI dir: %u alt: %u\n", gpio_getdir(&gp, GPIO_SD_DI), gpio_getalt(&gp, GPIO_SD_DI));
++ printk("GPIO_SD_DO dir: %u alt: %u\n", gpio_getdir(&gp, GPIO_SD_DO), gpio_getalt(&gp, GPIO_SD_DO));
++ printk("GPIO_SD_CS dir: %u alt: %u\n", gpio_getdir(&gp, GPIO_SD_CLK), gpio_getalt(&gp, GPIO_SD_CLK));
++*/
++
++ // printk("\nmmc: mmc_spi_hw_test() *START*\n");
++
++ // mmc_spi_hw_test();
++
++ printk("\nmmc: card init 1/2 (CMD0)\n");
++
++ for (j = 0; j < 10; j++)
++ {
++ MMC_Disable();
++
++ for (i = 0; i < 10; i++)
++ mmc_spi_readwrite_slow(0xff);
++
++ MMC_Enable();
++
++ mmc_spi_readwrite_slow(0xff);
++
++ mmc_spi_readwrite_slow(0x40);
++
++ for (i = 0; i < 4; i++) {
++
++ mmc_spi_readwrite_slow(0x00);
++
++ }
++
++ mmc_spi_readwrite_slow(0x95);
++
++ for (i = 0; i < 8; i++) {
++
++ result = mmc_spi_readwrite_slow(0xff);
++
++#ifdef DEBUG_HD
++ if (result != 0xff) {
++ if (result > 0x1F && result < 0x80)
++ printk("mmc: resp. (CMD0) Versuch(%d) BYTE: %d result = 0x%X Zeichen = %c\n", j, i, result, result);
++ else
++ printk("mmc: resp. (CMD0) Versuch(%d) BYTE: %d result = 0x%X\n", j, i, result);
++ }
++#endif
++ if (result == 0x01)
++ break;
++ }
++
++ if (result == 0x01)
++ break;
++
++ MMC_Disable();
++ mmc_spi_readwrite_slow(0xff);
++
++ mdelay(60);
++ }
++
++ if (result != 0x01) {
++
++ printk("mmc: card init 1/2 error: %d (CMD0) failed\n", result);
++ printk(" -> Hint: MMC/SD-Card realy (fully) inserted ?\n");
++
++ return (1);
++ }
++
++ printk("mmc: card init 1/2 (CMD0) success\n\n");
++
++ mdelay(1);
++
++ printk("mmc: card init 2/2 (CMD1)\n");
++ for (j = 0; j < 10; j++) {
++
++ mmc_spi_readwrite_slow(0xff);
++ mmc_spi_readwrite_slow(0x41);
++ for (i = 0; i < 4; i++)
++ mmc_spi_readwrite_slow(0x00);
++ mmc_spi_readwrite_slow(0x95);
++ for (i = 0; i < 8; i++) {
++ result = mmc_spi_readwrite_slow(0xff);
++#ifdef DEBUG_HD
++ // if (result >= 32 && result <= 127)
++ // printk("mmc: response (CMD1) Versuch(%d) start token BYTE: %d result = 0x%X Zeichen = %c\n", j, i, result, result);
++ // else
++ // printk("mmc: response (CMD1) Versuch(%d) start token BYTE: %d result = 0x%X\n", j, i, result);
++#endif
++ if (result == 0x00)
++ break;
++ }
++
++ mmc_spi_readwrite_slow(0xff);
++
++ if (result == 0x00) {
++ printk("mmc: card init 2/2 (CMD1) success\n\n");
++
++ mmc_spi_readwrite_slow(0xff);
++ mmc_spi_readwrite_slow(0x4d);
++ mmc_spi_readwrite_slow(0x00);
++ mmc_spi_readwrite_slow(0x00);
++ mmc_spi_readwrite_slow(0x00);
++ mmc_spi_readwrite_slow(0x00);
++ mmc_spi_readwrite_slow(0x95);
++ for (i = 0; i < 6; i++) {
++ result = mmc_spi_readwrite_slow(0xff);
++#ifdef DEBUG_HD
++ // if (result > 31 && result < 128)
++ // printk("mmc: response (CMD13) Versuch(%d) start token BYTE: %d result = 0x%X Zeichen = %c\n", j, i, result, result);
++ // else
++ // printk("mmc: response (CMD13) Versuch(%d) start token BYTE: %d result = 0x%X\n", j, i, result);
++#endif
++ // if (result == 0x00)
++ // break;
++ }
++ // mdelay(60);
++ MMC_Disable();
++ mmc_spi_readwrite_slow(0xff);
++ // mmc_spi_readwrite_slow(0xff);
++ // mdelay(10);
++
++ // restore_flags(flags);
++
++ return (0);
++ }
++ mdelay(60);
++ }
++ return (2);
++}
++
++
++static int mmc_spi_card_config(void)
++{
++ unsigned char result = 0;
++ short i, j;
++ unsigned char csd[32];
++ unsigned int c_size;
++ unsigned int c_size_mult;
++ unsigned int mult;
++ unsigned int read_bl_len;
++ unsigned int blocknr = 0;
++ unsigned int block_len = 0;
++ unsigned int size = 0;
++ unsigned char rd_buffer[528];
++// unsigned long flags;
++
++ MMC_Enable();
++
++ mmc_spi_readwrite_slow(0xff);
++ result = mmc_spi_readwrite_slow(0x51);
++ // mmc_spi_readwrite_slow(0x4A);
++ // mmc_spi_readwrite_slow(0x40+0x0D);
++ // mmc_spi_readwrite_slow(0x42);
++ for (i = 0; i < 4; i++)
++ mmc_spi_readwrite_slow(0x00);
++ mmc_spi_readwrite_slow(0x95);
++
++ // printk("mmc: (CMD17) response von 0x51 result = 0x%X\n", result);
++
++ for (i = 0; i < 8; i++) {
++ result = mmc_spi_readwrite_slow(0xff);
++#ifdef DEBUG_HD
++ // printk("mmc: (CMD17) response (start token) result = 0x%X\n", result);
++#endif
++ if (result == 0x00)
++ break;
++ }
++ if (result != 0x00) {
++ MMC_Disable();
++ mmc_spi_readwrite_slow(0xff);
++ // restore_flags(flags);
++ // mmc_spi_readwrite_slow(0xff);
++ return (1);
++ }
++ // restore_flags(flags);
++ for (i = 0; i < 8; i++) {
++ result = mmc_spi_readwrite_slow(0xff);
++ rd_buffer[i] = result;
++#ifdef DEBUG_HD
++ /*
++ if (result >= 32 && result <= 127)
++ printk("mmc: CMD17 response (start token) result = 0x%X Zeichen = %c\n", result, result);
++ else
++ printk("mmc: CMD17 response (start token) result = 0x%X\n", result);
++ */
++#endif
++ // if (result == 0xfe)
++ // break;
++ }
++ /*
++ if (result != 0xfe) {
++ MMC_Disable();
++ mmc_spi_readwrite_slow(0xff);
++ mmc_spi_readwrite_slow(0xff);
++ return(1);
++ }
++ */
++
++ for (i = 8; i < 520; i++) {
++ result = mmc_spi_readwrite_slow(0xff);
++ rd_buffer[i] = result;
++ }
++ for (i = 0; i < 2; i++) {
++ result = mmc_spi_readwrite_slow(0xff);
++ }
++ MMC_Disable();
++ mmc_spi_readwrite_slow(0xff);
++ // mmc_spi_readwrite_slow(0xff);
++
++ printk("Buffer - Start\n");
++
++ for ( i = 0 ; i < 33 ; i++) {
++ printk("\r\n%4X - ", i*16);
++ for ( j = 0 ; j < 16 ; j++) {
++ if ( rd_buffer[i*16+j] < 16)
++ printk("0%X ", rd_buffer[i*16+j]);
++ else
++ printk("%2X ", rd_buffer[i*16+j]);
++ }
++ for ( j = 0 ; j < 16 ; j++) {
++ if ( rd_buffer[i*16+j] < ' ')
++ printk(".");
++ else
++ printk("%c", rd_buffer[i*16+j]);
++ }
++ }
++
++ printk("\nBuffer - Ende\n");
++
++ mmc_show_cid_info();
++
++ for(j = 0 ; j < 1; j++) {
++ MMC_Enable();
++
++ // mdelay(1);
++
++ // save_flags(flags);
++ // cli();
++ mmc_spi_readwrite_slow(0xff);
++ mmc_spi_readwrite_slow(0x49);
++ // mmc_spi_readwrite_slow(0x4A);
++ // mmc_spi_readwrite_slow(0x40+0x0D);
++ // mmc_spi_readwrite_slow(0x42);
++ for (i = 0; i < 4; i++)
++ mmc_spi_readwrite_slow(0x00);
++ mmc_spi_readwrite_slow(0x95);
++ for (i = 0; i < 8; i++) {
++ result = mmc_spi_readwrite_slow(0xff);
++#ifdef DEBUG_HD
++ // printk("mmc: (CMD9) response (start token) result = 0x%X\n", result);
++#endif
++ if (result == 0x00)
++ break;
++ }
++ // restore_flags(flags);
++ if (result != 0x00) {
++ MMC_Disable();
++ mmc_spi_readwrite_slow(0xff);
++ // mmc_spi_readwrite_slow(0xff);
++ return (1);
++ }
++ for (i = 0; i < 22; i++) {
++ result = mmc_spi_readwrite_slow(0xff);
++#ifdef DEBUG_HD
++ if (result >= 32 && result <= 127)
++ printk("mmc: response (start token) result = 0x%X Zeichen = %c\n", result, result);
++ else
++ printk("mmc: response (start token) result = 0x%X\n", result);
++#endif
++ if (result == 0xfe)
++ break;
++ }
++ if (result == 0xfe)
++ break;
++
++ if (result != 0xfe) {
++ MMC_Disable();
++ mmc_spi_readwrite_slow(0xff);
++ // mmc_spi_readwrite_slow(0xff);
++ }
++ mdelay(60);
++ }
++
++ if (result != 0xfe) {
++ MMC_Disable();
++ mmc_spi_readwrite_slow(0xff);
++ printk("mmc: mmc card config (CMD9) failed result = 0x%X\n\n", result);
++ return (2);
++ }
++ for (i = 0; i < 16; i++) {
++ result = mmc_spi_readwrite_slow(0xff);
++ csd[i] = result;
++ }
++ for (i = 0; i < 2; i++) {
++ result = mmc_spi_readwrite_slow(0xff);
++ }
++ MMC_Disable();
++ mmc_spi_readwrite_slow(0xff);
++ // mmc_spi_readwrite_slow(0xff);
++
++ if (result == 0x00)
++ return (3);
++
++ c_size = (csd[8] & 0xC0) + (csd[7] << 8) + ((csd[6] & 0x03) << 16);
++ c_size >>= 6;
++ c_size_mult = (csd[10] & 0x80) + ((csd[9] & 0x03) << 8);
++ c_size_mult >>= 7;
++ read_bl_len = csd[5] & 0x0f;
++ mult = 1;
++ mult <<= c_size_mult + 2;
++ blocknr = (c_size + 1) * mult;
++ block_len = 1;
++ block_len <<= read_bl_len;
++ size = block_len * blocknr;
++ size >>= 10;
++
++ for (i = 0; i < (1 << 6); i++) {
++ hd_blocksizes[i] = 1024;
++ hd_hardsectsizes[i] = block_len;
++ hd_maxsect[i] = 256;
++ }
++ hd_sizes[0] = size;
++ hd[0].nr_sects = blocknr;
++
++ printk("Size = %d, hardsectsize = %d, sectors = %d\n",
++ size, block_len, blocknr);
++
++ return 0;
++}
++
++
++/*
++ * *******************************************************************
++ *
++ * End of SPI hardware access functions.
++ *
++ * *******************************************************************
++ */
++
++
++static int mmc_spi_write_block(unsigned int dest_addr, unsigned char *data)
++{
++ unsigned int address;
++ unsigned char result = 0;
++ unsigned char ab0, ab1, ab2, ab3;
++ int i;
++
++ address = dest_addr;
++
++ ab3 = 0xff & (address >> 24);
++ ab2 = 0xff & (address >> 16);
++ ab1 = 0xff & (address >> 8);
++ ab0 = 0xff & address;
++
++ MMC_Enable();
++
++ mmc_spi_readwrite(0xff);
++
++ mmc_spi_readwrite(0x58);
++ mmc_spi_readwrite(ab3); /* msb */
++ mmc_spi_readwrite(ab2);
++ mmc_spi_readwrite(ab1);
++ mmc_spi_readwrite(ab0); /* lsb */
++ mmc_spi_readwrite(0xff);
++
++ for (i = 0; i < 8; i++)
++ {
++ result = mmc_spi_readwrite(0xff);
++ if (result == 0x00)
++ {
++ break;
++ }
++ }
++
++ if (result != 0x00)
++ {
++ MMC_Disable();
++ mmc_spi_readwrite(0xff);
++ return (1);
++ }
++
++ mmc_spi_readwrite(0xfe);
++
++ for (i = 0; i < 512; i += 32)
++ {
++ mmc_spi_write_only(data[i]);
++ mmc_spi_write_only(data[i+1]);
++ mmc_spi_write_only(data[i+2]);
++ mmc_spi_write_only(data[i+3]);
++ mmc_spi_write_only(data[i+4]);
++ mmc_spi_write_only(data[i+5]);
++ mmc_spi_write_only(data[i+6]);
++ mmc_spi_write_only(data[i+7]);
++ mmc_spi_write_only(data[i+8]);
++ mmc_spi_write_only(data[i+9]);
++ mmc_spi_write_only(data[i+10]);
++ mmc_spi_write_only(data[i+11]);
++ mmc_spi_write_only(data[i+12]);
++ mmc_spi_write_only(data[i+13]);
++ mmc_spi_write_only(data[i+14]);
++ mmc_spi_write_only(data[i+15]);
++ mmc_spi_write_only(data[i+16]);
++ mmc_spi_write_only(data[i+17]);
++ mmc_spi_write_only(data[i+18]);
++ mmc_spi_write_only(data[i+19]);
++ mmc_spi_write_only(data[i+20]);
++ mmc_spi_write_only(data[i+21]);
++ mmc_spi_write_only(data[i+22]);
++ mmc_spi_write_only(data[i+23]);
++ mmc_spi_write_only(data[i+24]);
++ mmc_spi_write_only(data[i+25]);
++ mmc_spi_write_only(data[i+26]);
++ mmc_spi_write_only(data[i+27]);
++ mmc_spi_write_only(data[i+28]);
++ mmc_spi_write_only(data[i+29]);
++ mmc_spi_write_only(data[i+30]);
++ mmc_spi_write_only(data[i+31]);
++ }
++
++ mmc_spi_readwrite(0xff);
++ mmc_spi_readwrite(0xff);
++
++ for (i = 0; i < 1000000; i++)
++ {
++ result = mmc_spi_readwrite(0xff);
++ if (result == 0xff)
++ {
++ break;
++ }
++ }
++
++ if (result != 0xff)
++ {
++ MMC_Disable();
++ mmc_spi_readwrite(0xff);
++ return (3);
++ }
++
++ MMC_Disable();
++ mmc_spi_readwrite(0xff);
++ return (0);
++}
++
++static int mmc_spi_read_block(unsigned char *data, unsigned int src_addr)
++{
++ unsigned int address;
++ unsigned char result = 0;
++ unsigned char ab0, ab1, ab2, ab3;
++ unsigned long flags;
++ int i, j;
++
++ address = src_addr;
++
++ ab3 = 0xff & (address >> 24);
++ ab2 = 0xff & (address >> 16);
++ ab1 = 0xff & (address >> 8);
++ ab0 = 0xff & address;
++
++ MMC_Enable();
++
++ mmc_spi_readwrite(0xff);
++
++ mmc_spi_readwrite(0x51);
++ mmc_spi_readwrite(ab3); /* msb */
++ mmc_spi_readwrite(ab2);
++ mmc_spi_readwrite(ab1);
++ mmc_spi_readwrite(ab0); /* lsb */
++ mmc_spi_readwrite(0xff);
++
++ for (i = 0; i < 8; i++)
++ {
++ result = mmc_spi_readwrite(0xff);
++ if (result == 0x00)
++ {
++ break;
++ }
++ }
++
++ if (result != 0x00)
++ {
++ MMC_Disable();
++ mmc_spi_readwrite(0xff);
++ return (1);
++ }
++
++ for (i = 0; i < 100000; i++)
++ {
++ result = mmc_spi_readwrite(0xff);
++ if (result == 0xfe)
++ {
++ break;
++ }
++ }
++
++ if (result != 0xfe)
++ {
++ MMC_Disable();
++ mmc_spi_readwrite(0xff);
++ return (2);
++ }
++
++ for (i = 0; i < 512; i += 32 )
++ {
++ data[i] = mmc_spi_read_only();
++ data[i+1] = mmc_spi_read_only();
++ data[i+2] = mmc_spi_read_only();
++ data[i+3] = mmc_spi_read_only();
++ data[i+4] = mmc_spi_read_only();
++ data[i+5] = mmc_spi_read_only();
++ data[i+6] = mmc_spi_read_only();
++ data[i+7] = mmc_spi_read_only();
++ data[i+8] = mmc_spi_read_only();
++ data[i+9] = mmc_spi_read_only();
++ data[i+10] = mmc_spi_read_only();
++ data[i+11] = mmc_spi_read_only();
++ data[i+12] = mmc_spi_read_only();
++ data[i+13] = mmc_spi_read_only();
++ data[i+14] = mmc_spi_read_only();
++ data[i+15] = mmc_spi_read_only();
++ data[i+16] = mmc_spi_read_only();
++ data[i+17] = mmc_spi_read_only();
++ data[i+18] = mmc_spi_read_only();
++ data[i+19] = mmc_spi_read_only();
++ data[i+20] = mmc_spi_read_only();
++ data[i+21] = mmc_spi_read_only();
++ data[i+22] = mmc_spi_read_only();
++ data[i+23] = mmc_spi_read_only();
++ data[i+24] = mmc_spi_read_only();
++ data[i+25] = mmc_spi_read_only();
++ data[i+26] = mmc_spi_read_only();
++ data[i+27] = mmc_spi_read_only();
++ data[i+28] = mmc_spi_read_only();
++ data[i+29] = mmc_spi_read_only();
++ data[i+30] = mmc_spi_read_only();
++ data[i+31] = mmc_spi_read_only();
++ }
++
++ result = mmc_spi_readwrite(0xff);
++ result = mmc_spi_readwrite(0xff);
++
++ MMC_Disable();
++ mmc_spi_readwrite(0xff);
++
++ return (0);
++}
++
++/*
++static int mmc_revalidate(kdev_t dev)
++{
++ int target, max_p, start, i;
++
++ mmc_media_detect = mmc_spi_media_detect();
++
++ if (mmc_media_detect == 0)
++ {
++ return -ENODEV;
++ }
++
++ target = DEVICE_NR(dev);
++
++ max_p = hd_gendisk.max_p;
++ start = target << 6;
++ for (i = max_p - 1; i >= 0; i--)
++ {
++ int minor = start + i;
++ invalidate_device(MKDEV(MAJOR_NR, minor), 1);
++ hd_gendisk.part[minor].start_sect = 0;
++ hd_gendisk.part[minor].nr_sects = 0;
++ }
++
++ grok_partitions(&hd_gendisk, target, 1 << 6, hd_sizes[0] * 2);
++
++ return 0;
++}
++*/
++
++
++static int mmc_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
++ unsigned long arg)
++{
++ if (!inode || !inode->i_rdev)
++ return -EINVAL;
++
++ switch (cmd) {
++#if 0
++ case BLKGETSIZE:
++ return put_user(hd[MINOR(inode->i_rdev)].nr_sects,
++ (unsigned long *)arg);
++ case BLKGETSIZE64:
++ return put_user((u64) hd[MINOR(inode->i_rdev)].
++ nr_sects, (u64 *) arg);
++ case BLKRRPART:
++ if (!capable(CAP_SYS_ADMIN))
++ return -EACCES;
++
++ return mmc_revalidate(inode->i_rdev);
++#endif
++ case HDIO_GETGEO:
++ {
++ struct block_device *bdev = inode->i_bdev;
++ struct hd_geometry *loc, g;
++ loc = (struct hd_geometry *)arg;
++ if (!loc)
++ return -EINVAL;
++ memset(loc, 0, sizeof(struct hd_geometry));
++ g.heads = 4;
++ g.sectors = 16;
++ g.cylinders = get_capacity(bdev->bd_disk) / (4*16);
++ g.start = get_start_sect(bdev);
++ return copy_to_user(loc, &g, sizeof(g)) ? -EFAULT : 0;
++ }
++ default:
++ return -ENOTTY;
++ }
++}
++
++
++/*
++static int mmc_check_media_change(kdev_t dev)
++{
++ (void) dev;
++ if (mmc_media_changed == 1)
++ {
++ mmc_media_changed = 0;
++ return 1;
++ }
++ else
++ {
++ return 0;
++ }
++}
++*/
++
++
++/*
++static int mmc_init(void)
++{
++ int result;
++
++ result = mmc_spi_hardware_init();
++
++ if (result != 0)
++ {
++ printk("mmc: error %d in mmc_spi_hardware_init\n", result);
++ return -1;
++ }
++
++
++ result = mmc_spi_hw_test();
++
++ if (result != 0)
++ {
++ printk("\n mmc: mmc_spi_hw_test i.O. \n\n");
++ return -1;
++ }
++
++
++ result = mmc_spi_speed_test();
++
++ if (result != 0)
++ {
++ printk("\n mmc: mmc_spi_speed_test i.O. \n\n");
++ return -1;
++ }
++
++
++ result = mmc_spi_card_init();
++ mdelay(50);
++ if (result != 0)
++ {
++ // Give it an extra shot
++ // result = mmc_spi_card_init();
++ if (result != 0)
++ {
++ printk("mmc: error %d in mmc_card_init\n", result);
++ return -1;
++ }
++ }
++
++ result = mmc_spi_card_config();
++ if (result != 0)
++ {
++ printk("mmc: error %d in mmc_card_config\n", result);
++ return -1;
++ }
++
++
++ return 0;
++}
++*/
++
++/*
++static void mmc_exit(void)
++{
++}
++*/
++
++
++/*
++static void mmc_check_media(void)
++{
++ int old_state, new_state;
++ int result;
++
++ old_state = mmc_media_detect;
++ new_state = mmc_spi_media_detect();
++
++ if (old_state != new_state)
++ {
++ mmc_media_changed = 1;
++ if (new_state == PRESENT)
++ {
++ result = mmc_init();
++ if (result != 0)
++ {
++ printk("mmc: error %d in mmc_init\n", result);
++ }
++ else
++ {
++ mmc_exit();
++ }
++ }
++ }
++
++#ifdef CHECK_MEDIA_CHANGE
++ del_timer(&mmc_timer);
++ mmc_timer.expires = jiffies + 10*HZ;
++ add_timer(&mmc_timer);
++#endif
++
++}
++*/
++
++
++/* NB: There might be several requests in the queue, simply dequeuing only one
++ and not checking for more will cause a stall because the block subsystem
++ will not call this function again unless the queue is "plugged" which can
++ only happen if it runs empty... */
++static void mmc_spi_request(struct request_queue *q)
++{
++ struct request *req;
++ int ret;
++
++ unsigned int mmc_address;
++ unsigned char *buffer_address;
++ int nr_sectors;
++ int i;
++ int result, success;
++
++ if (blk_queue_plugged(q)) {
++ return;
++ }
++
++ spin_lock(&mmc_spi_lock);
++ for(;;) {
++ req = elv_next_request(q);
++ if (!req)
++ break;
++
++ if (!blk_fs_request(req)) {
++ printk("not a blk_fs_request\n");
++ spin_unlock(&mmc_spi_lock);
++ continue;
++ }
++
++ mmc_address = req->sector * hd_hardsectsizes[0];
++ buffer_address = req->buffer;
++ nr_sectors = req->current_nr_sectors;
++ success = 1;
++ if (rq_data_dir(req) == READ) {
++ spin_unlock_irq(q->queue_lock);
++ for (i = 0; i < nr_sectors; i++) {
++ result = mmc_spi_read_block(buffer_address, mmc_address);
++ if (unlikely(result < 0)) {
++ printk(KERN_ERR "mmi_spi_block: error reading block (%d)\n", result);
++ success = 0;
++ break;
++ }
++ mmc_address += hd_hardsectsizes[0];
++ buffer_address += hd_hardsectsizes[0];
++ }
++ spin_lock_irq(q->queue_lock);
++ } else {
++ spin_unlock_irq(q->queue_lock);
++ for (i = 0; i < nr_sectors; i++) {
++ result = mmc_spi_write_block(mmc_address, buffer_address);
++ if (unlikely(result < 0)) {
++ printk(KERN_ERR "mmi_spi_block: error writing block (%d)\n", result);
++ success = 0;
++ break;
++ }
++ mmc_address += hd_hardsectsizes[0];
++ buffer_address += hd_hardsectsizes[0];
++ }
++ spin_lock_irq(q->queue_lock);
++ }
++ ret = end_that_request_chunk(req, success, nr_sectors * hd_hardsectsizes[0]);
++ if (!ret) {
++ blkdev_dequeue_request(req);
++ end_that_request_last(req, 0);
++ }
++ }
++ spin_unlock(&mmc_spi_lock);
++}
++
++
++static int mmc_open(struct inode *inode, struct file *filp)
++{
++ // int device;
++ (void) filp;
++ mmc_media_detect = mmc_spi_media_detect();
++
++ if (mmc_media_detect == 0)
++ return -ENODEV;
++
++ return 0;
++}
++
++static int mmc_release(struct inode *inode, struct file *filp)
++{
++ return 0;
++}
++
++
++static struct block_device_operations mmc_spi_bdops = {
++ .open = mmc_open,
++ .release = mmc_release,
++ .ioctl = mmc_ioctl,
++ .owner = THIS_MODULE,
++#if 0
++ .check_media_change = mmc_check_media_change,
++ .revalidate = mmc_revalidate,
++#endif
++};
++
++static int detect_card(void)
++{
++ int result;
++
++ result = mmc_spi_card_init();
++ if (result != 0) {
++ // Give it an extra shot
++ result = mmc_spi_card_init();
++ if (result != 0) {
++ printk(KERN_ERR "mmc_spi_block: error in mmc_card_init (%d)\n", result);
++ return -ENODEV;
++ }
++ }
++
++ result = mmc_spi_card_config();
++ // result = mmc_spi_speed_test();
++ if (result != 0) {
++ printk(KERN_ERR "mmc_spi_block: error in mmc_card_config (%d)\n", result);
++ return -ENODEV;
++ }
++
++ return 0;
++}
++
++/* Fills in the gendisk structure from the received card
++ data. */
++static int gendisk_init(struct device *dev, struct gendisk *gd)
++{
++ if (!gd)
++ return -EINVAL;
++
++ gd->major = major;
++ gd->first_minor = 0; /* only one device supported */
++ gd->fops = &mmc_spi_bdops;
++ gd->driverfs_dev = dev;
++
++ gd->queue = blk_init_queue(mmc_spi_request,NULL);
++
++ if (!gd->queue)
++ return -ENOMEM;
++
++ sprintf(gd->disk_name, "mmcblk");
++
++ blk_queue_hardsect_size(gd->queue, hd_hardsectsizes[0]);
++
++ set_capacity(gd, hd_sizes[0]<<1);
++
++ return 0;
++}
++
++static int gendisk_fini(struct gendisk *gd)
++{
++ BUG_ON(!gd);
++
++ if (gd->queue)
++ blk_cleanup_queue(gd->queue);
++
++ del_gendisk(gd);
++}
++
++/* platform driver device instance routines */
++static int mmc_spi_probe(struct platform_device *pdev)
++{
++ int result;
++ printk("$Id: mmc_spi_block.c,v 1.04 2007/05/25 23:27:16 mrdata Exp $\n");
++
++ result = mmc_spi_hardware_init();
++ if (result != 0) {
++ printk(KERN_ERR "mmc_spi_block: error in mmc_spi_hardware_init (%d)\n", result);
++ result = -ENODEV;
++ return result;
++ }
++
++ result = detect_card();
++ if (result < 0)
++ return result;
++
++ mmc_media_detect = 1;
++
++ result = register_blkdev(major, DEVICE_NAME);
++ if (result < 0)
++ return result;
++
++ if (!major)
++ major = result;
++
++ /* allow 8 partitions per device */
++ BUG_ON(mmc_disk!=NULL);
++ mmc_disk = alloc_disk(1 << 3);
++ if (!mmc_disk) {
++ result = -ENOMEM;
++ goto out;
++ }
++
++ result = gendisk_init(&pdev->dev, mmc_disk);
++ if (result < 0)
++ goto out;
++
++ add_disk(mmc_disk);
++
++ /*init_timer(&mmc_timer);
++ mmc_timer.expires = jiffies + HZ;
++ mmc_timer.function = (void *)mmc_check_media;
++ add_timer(&mmc_timer); */
++ return 0;
++
++out:
++ if (mmc_disk)
++ put_disk(mmc_disk);
++
++ unregister_blkdev(major, DEVICE_NAME);
++ return result;
++}
++
++static int mmc_spi_remove(struct platform_device *dev)
++{
++ int ret;
++
++ if (mmc_disk) {
++ gendisk_fini(mmc_disk);
++ put_disk(mmc_disk);
++ }
++
++ ret = unregister_blkdev(major, DEVICE_NAME);
++ return ret;
++}
++
++struct platform_driver mmc_spi_driver = {
++ .probe = mmc_spi_probe,
++ .remove = mmc_spi_remove,
++ .driver = {
++ .name = "mmc_spi",
++ .owner = THIS_MODULE,
++ },
++};
++
++
++/* module init/exit */
++static int __init mmc_block_spi_init(void)
++{
++ int ret;
++ spin_lock_init(&mmc_spi_lock);
++
++ ret = platform_driver_register(&mmc_spi_driver);
++ if (ret < 0)
++ return ret;
++
++ /* we just support one device */
++ mmc_dev = platform_device_register_simple("mmc_spi", -1, NULL, 0);
++ if (IS_ERR(mmc_dev))
++ return PTR_ERR(mmc_dev);
++
++ return 0;
++}
++
++
++static void __exit mmc_block_spi_exit(void)
++{
++ platform_driver_unregister(&mmc_spi_driver);
++ if (mmc_dev)
++ platform_device_unregister(mmc_dev);
++}
++
++
++module_init(mmc_block_spi_init);
++module_exit(mmc_block_spi_exit);
++
++MODULE_AUTHOR("Madsuk,Rohde,TaGana,Carsten Juttner <carjay@gmx.net>,Guylhem Aznar <mmc-driver@externe.net>,mrdata");
++MODULE_DESCRIPTION("Driver for MMC/SD-Cards in SPI mode by GPIO");
++MODULE_SUPPORTED_DEVICE("SIMpad");
++MODULE_LICENSE("GPL");
++
++module_param(major, int, 0444);
++MODULE_PARM_DESC(major, "specify the major device number for the MMC/SD SPI driver");
diff --git a/recipes/linux/linux/simpad/linux-2.6.21-SIMpad-battery-old-way-but-also-with-sysfs.patch b/recipes/linux/linux/simpad/linux-2.6.21-SIMpad-battery-old-way-but-also-with-sysfs.patch
new file mode 100644
index 0000000000..ee18ff2bb0
--- /dev/null
+++ b/recipes/linux/linux/simpad/linux-2.6.21-SIMpad-battery-old-way-but-also-with-sysfs.patch
@@ -0,0 +1,571 @@
+diff -uNr linux-2.6.21.vanilla/drivers/mfd/Makefile linux-2.6.21/drivers/mfd/Makefile
+--- linux-2.6.21.vanilla/drivers/mfd/Makefile 2007-05-30 18:00:30.000000000 +0200
++++ linux-2.6.21/drivers/mfd/Makefile 2007-05-30 18:43:10.000000000 +0200
+@@ -12,3 +12,7 @@
+ ifeq ($(CONFIG_SA1100_ASSABET),y)
+ obj-$(CONFIG_MCP_UCB1200) += ucb1x00-assabet.o
+ endif
++
++ifeq ($(CONFIG_SA1100_SIMPAD),y)
++obj-$(CONFIG_MCP_UCB1200) += ucb1x00-simpad.o
++endif
+diff -uNr linux-2.6.21.vanilla/drivers/mfd/ucb1x00-simpad.c linux-2.6.21/drivers/mfd/ucb1x00-simpad.c
+--- linux-2.6.21.vanilla/drivers/mfd/ucb1x00-simpad.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.21/drivers/mfd/ucb1x00-simpad.c 2007-05-30 18:35:48.000000000 +0200
+@@ -0,0 +1,226 @@
++/*
++ * linux/drivers/mfd/ucb1x00-simpad.c
++ *
++ * Copyright (C) 2001-2003 Russell King, All Rights Reserved.
++ * 2007/03/18 mrdata:
++ * - adapted ucb1x00-assabet.c
++ * - transfer ucb1x00-simpad.c from kernel24
++ * to new structur of kernel26
++ *
++ * 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.
++ *
++ * We handle the machine-specific bits of the UCB1x00 driver here.
++ */
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/fs.h>
++#include <linux/proc_fs.h>
++#include <linux/device.h>
++
++#include <linux/apm-emulation.h>
++
++#include <asm/dma.h>
++
++#include <asm/arch/simpad.h>
++#include <asm/arch-sa1100/simpad_pm.h>
++
++#include "ucb1x00.h"
++#include "ucb1x00-simpad.h"
++
++#define UCB1X00_ATTR(name,input,designation) \
++static ssize_t name##_show(struct class_device *dev, char *buf) \
++{ \
++ struct ucb1x00 *ucb = classdev_to_ucb1x00(dev); \
++ int val; \
++ ucb1x00_adc_enable(ucb); \
++ val = ucb1x00_adc_read(ucb, input, UCB_NOSYNC); \
++ ucb1x00_adc_disable(ucb); \
++ return sprintf(buf, "%d\n", CALIBRATE_##designation(val)); \
++} \
++static CLASS_DEVICE_ATTR(name,0444,name##_show,NULL)
++
++UCB1X00_ATTR(vbatt, UCB_ADC_INP_AD1, BATTERY);
++UCB1X00_ATTR(vcharger, UCB_ADC_INP_AD2, SUPPLY);
++UCB1X00_ATTR(icharger, UCB_ADC_INP_AD3, CHARGING);
++
++static struct ucb1x00 *ucb_alt;
++
++#define UCB1X00_WERT(name,input,designation) \
++static int ucb1x00_simpad_read_##name(struct ucb1x00 *ucb_alt) \
++{ \
++ int val; \
++ ucb1x00_adc_enable(ucb_alt); \
++ val = ucb1x00_adc_read(ucb_alt, input, UCB_NOSYNC); \
++ ucb1x00_adc_disable(ucb_alt); \
++ return CALIBRATE_##designation(val); \
++}
++
++UCB1X00_WERT(vbatt, UCB_ADC_INP_AD1, BATTERY);
++UCB1X00_WERT(vcharger, UCB_ADC_INP_AD2, SUPPLY);
++UCB1X00_WERT(icharger, UCB_ADC_INP_AD3, CHARGING);
++
++static int ucb1x00_simpad_add(struct ucb1x00_dev *dev)
++{
++ class_device_create_file(&dev->ucb->cdev, &class_device_attr_vbatt);
++ class_device_create_file(&dev->ucb->cdev, &class_device_attr_vcharger);
++ class_device_create_file(&dev->ucb->cdev, &class_device_attr_icharger);
++ ucb_alt = dev->ucb;
++ return 0;
++}
++
++static void ucb1x00_simpad_remove(struct ucb1x00_dev *dev)
++{
++ class_device_remove_file(&dev->ucb->cdev, &class_device_attr_icharger);
++ class_device_remove_file(&dev->ucb->cdev, &class_device_attr_vcharger);
++ class_device_remove_file(&dev->ucb->cdev, &class_device_attr_vbatt);
++}
++
++static struct ucb1x00_driver ucb1x00_simpad_driver = {
++ .add = ucb1x00_simpad_add,
++ .remove = ucb1x00_simpad_remove,
++};
++
++static int __init ucb1x00_simpad_init(void)
++{
++ apm_get_power_status = simpad_apm_get_power_status;
++ return ucb1x00_register_driver(&ucb1x00_simpad_driver);
++}
++
++static void __exit ucb1x00_simpad_exit(void)
++{
++ apm_get_power_status = NULL;
++ ucb1x00_unregister_driver(&ucb1x00_simpad_driver);
++}
++
++/****************************************************************************/
++/* Functions exported for use by the kernel and kernel modules */
++/****************************************************************************/
++
++int simpad_get_battery(struct simpad_battery_apm *bstat)
++{
++ int icharger, vcharger, vbatt;
++
++ if ( ucb_alt ) {
++ icharger = ucb1x00_simpad_read_icharger( ucb_alt );
++ vcharger = ucb1x00_simpad_read_vcharger( ucb_alt );
++ vbatt = ucb1x00_simpad_read_vbatt( ucb_alt );
++ } else {
++ bstat->ac_status = SIMPAD_AC_STATUS_AC_UNKNOWN;
++ bstat->status = SIMPAD_BATT_STATUS_UNKNOWN;
++ bstat->percentage = 0x64; // lets say 100%
++ bstat->life = 330; // lets say a long time
++ return 0;
++ }
++
++ /* AC status */
++ bstat->ac_status = SIMPAD_AC_STATUS_AC_OFFLINE;
++ if ( vcharger>MIN_SUPPLY ) {
++ bstat->ac_status = SIMPAD_AC_STATUS_AC_ONLINE;
++ }
++
++ /* charging */
++ bstat->status = 0x0;
++ if ( icharger >= CHARGING_LED_LEVEL )
++ bstat->status = SIMPAD_BATT_STATUS_CHARGING;
++
++ if ( vbatt > BATT_LOW )
++ bstat->status |= SIMPAD_BATT_STATUS_HIGH;
++ else if ( vbatt < BATT_CRITICAL )
++ bstat->status |= SIMPAD_BATT_STATUS_CRITICAL;
++ else
++ bstat->status |= SIMPAD_BATT_STATUS_LOW;
++
++ if (bstat->status & SIMPAD_BATT_STATUS_CHARGING) {
++ if (icharger > CHARGING_MAX_LEVEL)
++ icharger = CHARGING_MAX_LEVEL;
++ if (icharger < CHARGING_LED_LEVEL)
++ icharger = CHARGING_LED_LEVEL;
++
++ bstat->percentage = 100 - 100 * (icharger - CHARGING_LED_LEVEL) /
++ (CHARGING_MAX_LEVEL - CHARGING_LED_LEVEL);
++ } else {
++ if (vbatt > BATT_FULL)
++ vbatt = BATT_FULL;
++ if (vbatt < BATT_EMPTY)
++ vbatt = BATT_EMPTY;
++
++ bstat->percentage = 100 * (vbatt - BATT_EMPTY) / (BATT_FULL - BATT_EMPTY);
++ }
++
++ /* let's assume: full load is 7h */
++ /* bstat->life = 420*bstat->percentage/100; */
++ /* mrdata: think, 4h is more realistic */
++ bstat->life = 240*(bstat->percentage)/100;
++
++#if 0
++ printk("get_battery: ac: %02x / ch: %02x / perc: %02x / life: %d \n",
++ bstat->ac_status, bstat->status,
++ bstat->percentage, bstat->life );
++#endif
++
++ return 0;
++}
++
++void simpad_apm_get_power_status(struct apm_power_info *info)
++{
++ struct simpad_battery_apm bstat;
++ unsigned char ac = APM_AC_UNKNOWN;
++ unsigned char level = APM_BATTERY_STATUS_UNKNOWN;
++ int status, result;
++
++ result = simpad_get_battery(&bstat);
++ if (result) {
++ printk("%s: unable to access battery information: result=%d\n", __FUNCTION__, result);
++ return;
++ }
++
++ switch (bstat.ac_status) {
++ case SIMPAD_AC_STATUS_AC_OFFLINE:
++ ac = APM_AC_OFFLINE;
++ break;
++ case SIMPAD_AC_STATUS_AC_ONLINE:
++ ac = APM_AC_ONLINE;
++ break;
++ case SIMPAD_AC_STATUS_AC_BACKUP:
++ ac = APM_AC_BACKUP;
++ break;
++ }
++
++ info->ac_line_status = ac;
++
++ status = bstat.status;
++ if (status & (SIMPAD_BATT_STATUS_CHARGING | SIMPAD_BATT_STATUS_CHARGE_MAIN))
++ level = APM_BATTERY_STATUS_CHARGING;
++ else if (status & (SIMPAD_BATT_STATUS_HIGH | SIMPAD_BATT_STATUS_FULL))
++ level = APM_BATTERY_STATUS_HIGH;
++ else if (status & SIMPAD_BATT_STATUS_LOW)
++ level = APM_BATTERY_STATUS_LOW;
++ else if (status & SIMPAD_BATT_STATUS_CRITICAL)
++ level = APM_BATTERY_STATUS_CRITICAL;
++
++ info->battery_status = level;
++ info->battery_flag = info->battery_status;
++
++ info->battery_life = bstat.percentage;
++
++ /* we have a dumb battery - so we know nothing */
++ info->time = bstat.life;
++ info->units = APM_UNITS_MINS;
++
++#if 0
++ printk("apm_get_power: ac: %02x / bs: %02x / bf: %02x / perc: %02x / life: %d\n",
++ info->ac_line_status, info->battery_status, info->battery_flag,
++ info->battery_life, info->time );
++#endif
++ return;
++}
++
++module_init(ucb1x00_simpad_init);
++module_exit(ucb1x00_simpad_exit);
++
++
++MODULE_AUTHOR("Juergen Messerer <juergen.messerer@freesurf.ch>");
++MODULE_DESCRIPTION("SIMpad noddy testing only example ADC driver");
++MODULE_LICENSE("GPL");
+diff -uNr linux-2.6.21.vanilla/drivers/mfd/ucb1x00-simpad.h linux-2.6.21/drivers/mfd/ucb1x00-simpad.h
+--- linux-2.6.21.vanilla/drivers/mfd/ucb1x00-simpad.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.21/drivers/mfd/ucb1x00-simpad.h 2007-05-30 18:35:48.000000000 +0200
+@@ -0,0 +1,86 @@
++/*
++ * linux/drivers/mfd/ucb1x00-simpad.h
++ *
++ * Copyright (C) 2001 Russell King, All Rights Reserved.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License.
++ */
++#ifndef UCB1300_SIMPAD_H
++#define UCB1300_SIMPAD_H
++
++/*
++ * Conversion from AD -> mV
++ * 7.5V = 1023 7.33137mV/Digit
++ *
++ * 400 Units == 9.7V
++ * a = ADC value
++ * 2007/03/24 mrdata:
++ * according UCB1300 datasheet ADC error max. 3 LSB
++ * 5-95% of full scale -> 3*7.33137mV = 21.99mV
++ * // old
++ * 21 = ADC error
++ * 12600 = Divident to get 2*7.3242
++ * 860 = Divider to get 2*7.3242
++ * 170 = Voltagedrop over
++ *
++ * // new
++ * 3 = ADC error
++ * 12610 = Divident to get 2*7.33139
++ * 860 = Divider to get 2*7.33139
++ * 170 = Voltagedrop over
++ */
++// #define CALIBRATE_BATTERY(a) ((((a + 21)*12600)/860) + 170)
++#define CALIBRATE_BATTERY(a) ((((a + 3)*12610)/860) + 170)
++
++/*
++ * We have two types of batteries a small and a large one
++ * To get the right value we to distinguish between those two
++ * 450 Units == 15 V
++ */
++#ifdef SMALL_BATTERY
++#define CALIBRATE_SUPPLY(a) (((a) * 1500) / 51)
++#define MIN_SUPPLY 8500 /* Less then 8.5V means no powersupply */
++#else
++#define CALIBRATE_SUPPLY(a) (((a) * 1500) / 45)
++//#define MIN_SUPPLY 14000 /* Less then 14V means no powersupply */
++#define MIN_SUPPLY 12000 /* Less then 12V means no powersupply */
++#endif
++
++/*
++ * Charging Current
++ * if value is >= 50 then charging is on
++ */
++// #define CALIBRATE_CHARGING(a) (((a) * 1000) / (152/4))
++#define CALIBRATE_CHARGING(a) (a)
++//#define CHARGING_LED_LEVEL 50
++
++#ifdef CONFIG_SA1100_SIMPAD_SINUSPAD
++
++// type small battery
++#define CHARGING_LED_LEVEL 12
++#define CHARGING_MAX_LEVEL 120
++#define BATT_FULL 8100
++#define BATT_LOW 7300
++#define BATT_CRITICAL 6700
++#define BATT_EMPTY 6400
++
++#else // CONFIG_SA1100_SIMPAD_SINUSPAD
++
++// type large battery
++// because of ADC error CHARGING_LED_LEVEL can changed
++// from 27 to 28
++#define CHARGING_LED_LEVEL 27
++#define CHARGING_MAX_LEVEL 265
++// BATT_FULL with SIMPAD_AC_STATUS_AC_OFFLINE
++#define BATT_FULL 8100
++#define BATT_LOW 7400
++#define BATT_CRITICAL 6800
++#define BATT_EMPTY 6500
++
++#endif // CONFIG_SA1100_SIMPAD_SINUSPAD
++
++// int simpad_get_battery(struct simpad_battery_apm *bstat);
++
++#endif
+diff -uNr linux-2.6.21.vanilla/include/asm-arm/arch-sa1100/simpad_pm.h linux-2.6.21/include/asm-arm/arch-sa1100/simpad_pm.h
+--- linux-2.6.21.vanilla/include/asm-arm/arch-sa1100/simpad_pm.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.21/include/asm-arm/arch-sa1100/simpad_pm.h 2007-05-30 18:36:07.000000000 +0200
+@@ -0,0 +1,236 @@
++/*
++* Abstraction interface for microcontroller connection to rest of system
++*
++* Copyright 2003 Peter Pregler
++* Copyright 2000,1 Compaq Computer Corporation.
++*
++* Use consistent with the GNU GPL is permitted,
++* provided that this copyright notice is
++* preserved in its entirety in all copies and derived works.
++*
++* COMPAQ COMPUTER CORPORATION MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,
++* AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS
++* FITNESS FOR ANY PARTICULAR PURPOSE.
++*
++* Author: Peter Pregler (based on work for ipaq by Andrew Christian)
++*
++*/
++
++#ifndef __SIMPAD_HAL_H
++#define __SIMPAD_HAL_H
++
++#include <linux/apm-emulation.h>
++
++struct simpad_battery_apm {
++ unsigned char ac_status; /* line connected yes/no */
++ unsigned char status; /* battery loading yes/no */
++ unsigned char percentage; /* percentage loaded */
++ unsigned short life; /* life till empty */
++};
++
++extern void simpad_apm_get_power_status(struct apm_power_info *);
++
++// extern int simpad_get_battery(struct simpad_battery_apm *bstat);
++
++/* These should match the apm_bios.h definitions */
++#define SIMPAD_AC_STATUS_AC_OFFLINE 0x00
++#define SIMPAD_AC_STATUS_AC_ONLINE 0x01
++#define SIMPAD_AC_STATUS_AC_BACKUP 0x02 /* What does this mean? */
++#define SIMPAD_AC_STATUS_AC_UNKNOWN 0xff
++
++
++/* These bitfields are rarely "or'd" together */
++#define SIMPAD_BATT_STATUS_HIGH 0x01
++#define SIMPAD_BATT_STATUS_LOW 0x02
++#define SIMPAD_BATT_STATUS_CRITICAL 0x04
++#define SIMPAD_BATT_STATUS_CHARGING 0x08
++#define SIMPAD_BATT_STATUS_CHARGE_MAIN 0x10
++#define SIMPAD_BATT_STATUS_DEAD 0x20 /* Battery will not charge */
++#define SIMPAD_BATT_NOT_INSTALLED 0x20 /* For expansion pack batteries */
++#define SIMPAD_BATT_STATUS_FULL 0x40 /* Battery fully charged (and connected to AC) */
++#define SIMPAD_BATT_STATUS_NOBATT 0x80
++#define SIMPAD_BATT_STATUS_UNKNOWN 0xff
++
++#if 0 // FIXME
++#include <linux/simpad_ts.h>
++
++enum simpad_asset_type {
++ ASSET_TCHAR = 0,
++ ASSET_SHORT,
++ ASSET_LONG
++};
++
++#define TTYPE(_type) (((unsigned int)_type) << 8)
++#define TCHAR(_len) (TTYPE(ASSET_TCHAR) | (_len))
++#define TSHORT TTYPE(ASSET_SHORT)
++#define TLONG TTYPE(ASSET_LONG)
++#define ASSET(_type,_num) ((((unsigned int)_type)<<16) | (_num))
++
++#define ASSET_HM_VERSION ASSET( TCHAR(10), 0 ) /* 1.1, 1.2 */
++#define ASSET_SERIAL_NUMBER ASSET( TCHAR(40), 1 ) /* Unique iPAQ serial number */
++#define ASSET_MODULE_ID ASSET( TCHAR(20), 2 ) /* E.g., "iPAQ 3700" */
++#define ASSET_PRODUCT_REVISION ASSET( TCHAR(10), 3 ) /* 1.0, 2.0 */
++#define ASSET_PRODUCT_ID ASSET( TSHORT, 4 ) /* 2 = Palm-sized computer */
++#define ASSET_FRAME_RATE ASSET( TSHORT, 5 )
++#define ASSET_PAGE_MODE ASSET( TSHORT, 6 ) /* 0 = Flash memory */
++#define ASSET_COUNTRY_ID ASSET( TSHORT, 7 ) /* 0 = USA */
++#define ASSET_IS_COLOR_DISPLAY ASSET( TSHORT, 8 ) /* Boolean, 1 = yes */
++#define ASSET_ROM_SIZE ASSET( TSHORT, 9 ) /* 16, 32 */
++#define ASSET_RAM_SIZE ASSET( TSHORT, 10 ) /* 32768 */
++#define ASSET_HORIZONTAL_PIXELS ASSET( TSHORT, 11 ) /* 240 */
++#define ASSET_VERTICAL_PIXELS ASSET( TSHORT, 12 ) /* 320 */
++
++#define ASSET_TYPE(_asset) (((_asset)&0xff000000)>>24)
++#define ASSET_TCHAR_LEN(_asset) (((_asset)&0x00ff0000)>>16)
++#define ASSET_NUMBER(_asset) ((_asset)&0x0000ffff)
++
++#define MAX_TCHAR_LEN 40
++
++struct simpad_asset {
++ unsigned int type;
++ union {
++ unsigned char tchar[ MAX_TCHAR_LEN ];
++ unsigned short vshort;
++ unsigned long vlong;
++ } a;
++};
++
++/********************************************************************
++ * Interface to the hardware-type specific functions
++ *
++ * get_version Read the version number of the microcontroller on the option pack SPI bus
++ * spi_read Reads from the serial EEPROM memory on the option pack SPI bus
++ * spi_write Write to the serial EEPROM memory on the option pack SPI bus
++ * get_option_detect Returns whether or not an option pack is present
++ *
++ * get_thermal_sensor Return measured temperature of the unit, in units of 0.125 deg C
++ * set_notify_led Turns on, off, or blinks the Green LED
++ * read_light_sensor Returns the value of the front light sensor
++ * get_battery Returns the current voltage and charging state of all batteries
++ * audio_clock Sets the audio CODEC to run at a particular rate
++ * audio_power Turns on/off audio CODEC (internally calls audio_clock)
++ * audio_mute Mutes the audio CODEC
++ * asset_read Extracts PocketPC-style asset information from persistent memory
++ * backlight_control Adjusts the backlight level (only on/off for 3100)
++ *
++ *
++ * iPAQ 3100 only
++ * ==============
++ * codec_control Reset/mute/control level of 3100 audio codec
++ * contrast_control Adjusts the contrast level (only for 3100)
++ *
++ * iPAQ 3600, 3700 only
++ * ====================
++ * eeprom_read Reads from the asset information on the eeprom of a 3600 (deprecated)
++ * eeprom_write Writes to the asset information on the eeprom (deprecated)
++ *
++ * The interfaces to the EEPROM functions are maintained only because the simpad_ts driver has
++ * a deprecated ioctl call for them. They are used internally by the "asset_read" function.
++ *
++ * iPAQ 3800, 3900 only
++ * ====================
++ * set_ebat Tells enhanced PCMCIA sleeves that this iPAQ can handle
++ * a wider voltage range (applies to 3800, 3900)
++ *
++ *********************************************************************/
++
++struct simpad_hal_ops {
++ /* Functions provided by the underlying hardware */
++ int (*get_version)( struct simpad_ts_version * );
++ int (*eeprom_read)( unsigned short address, unsigned char *data, unsigned short len );
++ int (*eeprom_write)( unsigned short address, unsigned char *data, unsigned short len );
++ int (*get_thermal_sensor)( unsigned short * );
++ int (*set_notify_led)( unsigned char mode, unsigned char duration,
++ unsigned char ontime, unsigned char offtime );
++ int (*read_light_sensor)( unsigned char *result );
++ int (*get_battery)( struct simpad_battery * );
++ int (*spi_read)( unsigned short address, unsigned char *data, unsigned short len );
++ int (*spi_write)( unsigned short address, unsigned char *data, unsigned short len );
++ int (*codec_control)( unsigned char, unsigned char );
++ int (*get_option_detect)( int *result );
++ int (*audio_clock)( long samplerate );
++ int (*audio_power)( long samplerate );
++ int (*audio_mute)( int mute );
++ int (*asset_read)( struct simpad_asset *asset );
++ int (*set_ebat)( void );
++
++ /* Functions indirectly provided by the underlying hardware */
++ int (*backlight_control)( enum flite_pwr power, unsigned char level );
++ int (*contrast_control)( unsigned char level );
++
++ /* for module use counting */
++ struct module *owner;
++};
++
++/* Used by the device-specific hardware module to register itself */
++extern int simpad_hal_register_interface( struct simpad_hal_ops *ops );
++extern void simpad_hal_unregister_interface( struct simpad_hal_ops *ops );
++
++/*
++ * Calls into HAL from the device-specific hardware module
++ * These run at interrupt time
++ */
++extern void simpad_hal_keypress( unsigned char key );
++extern void simpad_hal_touchpanel( unsigned short x, unsigned short y, int down );
++extern void simpad_hal_option_detect( int present );
++
++/* Callbacks registered by device drivers */
++struct simpad_driver_ops {
++ void (*keypress)( unsigned char key );
++ void (*touchpanel)( unsigned short x, unsigned short y, int down );
++ void (*option_detect)( int present );
++};
++
++extern int simpad_hal_register_driver( struct simpad_driver_ops * );
++extern void simpad_hal_unregister_driver( struct simpad_driver_ops * );
++
++
++/* Calls into HAL from device drivers and other kernel modules */
++extern void simpad_get_flite( struct simpad_ts_backlight *bl );
++extern void simpad_get_contrast( unsigned char *contrast );
++extern int simpad_set_flite( enum flite_pwr pwr, unsigned char brightness );
++extern int simpad_set_contrast( unsigned char contrast );
++extern int simpad_toggle_frontlight( void );
++
++extern int simpad_apm_get_power_status(unsigned char *ac_line_status, unsigned char *battery_status,
++ unsigned char *battery_flag, unsigned char *battery_percentage,
++ unsigned short *battery_life);
++
++extern struct simpad_hal_ops *simpad_hal_ops;
++
++/* Do not use this macro in driver files - instead, use the inline functions defined below */
++#define CALL_HAL( f, args... ) \
++ { int __result = -EIO; \
++ if ( simpad_hal_ops && simpad_hal_ops->f ) { \
++ __MOD_INC_USE_COUNT(simpad_hal_ops->owner); \
++ __result = simpad_hal_ops->f(args); \
++ __MOD_DEC_USE_COUNT(simpad_hal_ops->owner); \
++ } \
++ return __result; }
++
++#define HFUNC static __inline__ int
++
++/* The eeprom_read/write address + len has a maximum value of 512. Both must be even numbers */
++HFUNC simpad_eeprom_read( u16 addr, u8 *data, u16 len ) CALL_HAL(eeprom_read,addr,data,len)
++HFUNC simpad_eeprom_write( u16 addr, u8 *data, u16 len) CALL_HAL(eeprom_write,addr,data,len)
++HFUNC simpad_spi_read( u8 addr, u8 *data, u16 len) CALL_HAL(spi_read,addr,data,len)
++HFUNC simpad_spi_write( u8 addr, u8 *data, u16 len) CALL_HAL(spi_write,addr,data,len)
++HFUNC simpad_get_version( struct simpad_ts_version *v ) CALL_HAL(get_version,v)
++HFUNC simpad_get_thermal_sensor( u16 *thermal ) CALL_HAL(get_thermal_sensor,thermal)
++HFUNC simpad_set_led( u8 mode, u8 dur, u8 ont, u8 offt ) CALL_HAL(set_notify_led, mode, dur, ont, offt)
++HFUNC simpad_get_light_sensor( u8 *result ) CALL_HAL(read_light_sensor,result)
++HFUNC simpad_get_battery( struct simpad_battery *bat ) CALL_HAL(get_battery,bat)
++HFUNC simpad_get_option_detect( int *result) CALL_HAL(get_option_detect,result)
++HFUNC simpad_audio_clock( long samplerate ) CALL_HAL(audio_clock,samplerate)
++HFUNC simpad_audio_power( long samplerate ) CALL_HAL(audio_power,samplerate)
++HFUNC simpad_audio_mute( int mute ) CALL_HAL(audio_mute,mute)
++HFUNC simpad_asset_read( struct simpad_asset *asset ) CALL_HAL(asset_read,asset)
++HFUNC simpad_set_ebat( void ) CALL_HAL(set_ebat)
++
++/* Don't use these functions directly - rather, call {get,set}_{flite,contrast} */
++ /* Functions indirectly provided by the underlying hardware */
++HFUNC simpad_backlight_control( enum flite_pwr p, u8 v ) CALL_HAL(backlight_control,p,v)
++HFUNC simpad_contrast_control( u8 level ) CALL_HAL(contrast_control,level)
++
++#endif
++#endif
diff --git a/recipes/linux/linux/simpad/linux-2.6.21-SIMpad-cs3-simpad.patch b/recipes/linux/linux/simpad/linux-2.6.21-SIMpad-cs3-simpad.patch
new file mode 100644
index 0000000000..cfb9aad906
--- /dev/null
+++ b/recipes/linux/linux/simpad/linux-2.6.21-SIMpad-cs3-simpad.patch
@@ -0,0 +1,184 @@
+diff -uNr linux-2.6.21.vanilla/arch/arm/mach-sa1100/Makefile linux-2.6.21/arch/arm/mach-sa1100/Makefile
+--- linux-2.6.21.vanilla/arch/arm/mach-sa1100/Makefile 2007-05-29 21:34:59.000000000 +0200
++++ linux-2.6.21/arch/arm/mach-sa1100/Makefile 2007-05-30 17:44:04.000000000 +0200
+@@ -40,6 +40,7 @@
+ obj-$(CONFIG_SA1100_SHANNON) += shannon.o
+
+ obj-$(CONFIG_SA1100_SIMPAD) += simpad.o
++obj-$(CONFIG_SA1100_SIMPAD) += cs3-simpad.o
+ led-$(CONFIG_SA1100_SIMPAD) += leds-simpad.o
+
+ # LEDs support
+diff -uNr linux-2.6.21.vanilla/arch/arm/mach-sa1100/cs3-simpad.c linux-2.6.21/arch/arm/mach-sa1100/cs3-simpad.c
+--- linux-2.6.21.vanilla/arch/arm/mach-sa1100/cs3-simpad.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.21/arch/arm/mach-sa1100/cs3-simpad.c 2007-05-30 17:45:51.000000000 +0200
+@@ -0,0 +1,169 @@
++/*
++ * simpad-cs3.c
++ *
++ * This driver shows the GPIO states of the cs3 latch. You can also
++ * switch some GPIOS.
++ *
++ * (c) 2007 Bernhard Guillon <Bernhard.Guillon@OpenSIMpad.org>
++ *
++ * You may use this code as per GPL version 2
++ *
++ * Some parts are based on battery.c
++ *
++ * mrdata: -added cs3_ro support
++ * -added preprocessor stuff
++ *
++ */
++
++#include <linux/module.h>
++#include <linux/types.h>
++#include <linux/init.h>
++#include <linux/device.h>
++
++#include <asm/arch/simpad.h>
++
++extern long get_cs3_ro(void);
++extern long get_cs3_shadow(void);
++extern void set_cs3_bit(int value);
++extern void clear_cs3_bit(int value);
++
++struct cs3 {
++ struct class_device class_dev;
++ const char *name;
++ char *id;
++ int type;
++};
++
++struct cs3 cs3 ={
++ .name = "latch_cs3",
++};
++
++
++#define CS3_STORE_ATTR(namek,nameg) \
++static ssize_t namek##_store (struct class_device *cdev, const char * buf, size_t count) \
++{ \
++ char val; \
++ if (sscanf(buf, "%c",&val) != 1) \
++ return -EINVAL; \
++ if (val == '1') \
++ set_cs3_bit(nameg); \
++ else if (val == '0') \
++ clear_cs3_bit(nameg); \
++ return strlen(buf); \
++}
++
++CS3_STORE_ATTR(display_on, DISPLAY_ON);
++CS3_STORE_ATTR(dect_power_on, DECT_POWER_ON);
++CS3_STORE_ATTR(irda_sd, IRDA_SD);
++CS3_STORE_ATTR(sd_mediaq, SD_MEDIAQ);
++CS3_STORE_ATTR(led2_on, LED2_ON);
++CS3_STORE_ATTR(irda_mode, IRDA_MODE);
++CS3_STORE_ATTR(reset_simcard, RESET_SIMCARD);
++
++
++#define CS3_ATTR(shadro,namek,nameg,mode,store) \
++static ssize_t namek##_show(struct class_device *class_dev, char *buf) \
++{ \
++ if (get_cs3_##shadro() & nameg ) \
++ return sprintf(buf, "1\n"); \
++ else \
++ return sprintf(buf, "0\n"); \
++} \
++static CLASS_DEVICE_ATTR(namek, mode, namek##_show, store)
++
++CS3_ATTR(shadow, vcc_5v_en, VCC_5V_EN, 0444, NULL);
++CS3_ATTR(shadow, vcc_3v_en, VCC_3V_EN, 0444, NULL);
++CS3_ATTR(shadow, en1, EN1, 0444, NULL);
++CS3_ATTR(shadow, en0, EN0, 0444, NULL);
++CS3_ATTR(shadow, display_on, DISPLAY_ON, 0664, display_on_store);
++CS3_ATTR(shadow, pcmcia_buff_dis, PCMCIA_BUFF_DIS, 0444, NULL);
++CS3_ATTR(shadow, mq_reset, MQ_RESET, 0444, NULL);
++CS3_ATTR(shadow, pcmcia_reset, PCMCIA_RESET, 0444, NULL);
++CS3_ATTR(shadow, dect_power_on, DECT_POWER_ON, 0664, dect_power_on_store);
++CS3_ATTR(shadow, irda_sd, IRDA_SD, 0664, irda_sd_store);
++CS3_ATTR(shadow, rs232_on, RS232_ON, 0444, NULL);
++CS3_ATTR(shadow, sd_mediaq, SD_MEDIAQ, 0664, sd_mediaq_store);
++CS3_ATTR(shadow, led2_on, LED2_ON, 0664, led2_on_store);
++CS3_ATTR(shadow, irda_mode, IRDA_MODE, 0664, irda_mode_store);
++CS3_ATTR(shadow, enable_5v, ENABLE_5V, 0444, NULL);
++CS3_ATTR(shadow, reset_simcard, RESET_SIMCARD, 0664, reset_simcard_store);
++CS3_ATTR(ro, pcmcia_bvd1, PCMCIA_BVD1, 0444, NULL);
++CS3_ATTR(ro, pcmcia_bvd2, PCMCIA_BVD2, 0444, NULL);
++CS3_ATTR(ro, pcmcia_vs1, PCMCIA_VS1, 0444, NULL);
++CS3_ATTR(ro, pcmcia_vs2, PCMCIA_VS2, 0444, NULL);
++CS3_ATTR(ro, lock_ind, LOCK_IND, 0444, NULL);
++CS3_ATTR(ro, charging_state, CHARGING_STATE, 0444, NULL);
++CS3_ATTR(ro, pcmcia_short, PCMCIA_SHORT, 0444, NULL);
++
++static struct class simpad_gpios_class = {
++ .name = "simpad",
++};
++
++#define create_entry_conditional(namek) \
++ rc = class_device_create_file(&cs3->class_dev, &class_device_attr_##namek); \
++ if (rc) goto out; \
++
++static int register_cs3_latch(struct cs3 *cs3)
++{
++ int rc = 0;
++ cs3->class_dev.class = &simpad_gpios_class;
++ strcpy(cs3->class_dev.class_id, cs3->name);
++ rc = class_device_register(&cs3->class_dev);
++ if(rc)
++ goto out;
++
++ create_entry_conditional(vcc_5v_en);
++ create_entry_conditional(vcc_3v_en);
++ create_entry_conditional(en1);
++ create_entry_conditional(en0);
++ create_entry_conditional(display_on);
++ create_entry_conditional(pcmcia_buff_dis);
++ create_entry_conditional(mq_reset);
++ create_entry_conditional(pcmcia_reset);
++ create_entry_conditional(dect_power_on);
++ create_entry_conditional(irda_sd);
++ create_entry_conditional(rs232_on);
++ create_entry_conditional(sd_mediaq);
++ create_entry_conditional(led2_on);
++ create_entry_conditional(irda_mode);
++ create_entry_conditional(enable_5v);
++ create_entry_conditional(reset_simcard);
++ create_entry_conditional(pcmcia_bvd1);
++ create_entry_conditional(pcmcia_bvd2);
++ create_entry_conditional(pcmcia_vs1);
++ create_entry_conditional(pcmcia_vs2);
++ create_entry_conditional(lock_ind);
++ create_entry_conditional(charging_state);
++ create_entry_conditional(pcmcia_short);
++
++out:
++ return rc;
++}
++
++static int __init simpad_gpios_class_init(void)
++{
++ int rc = 0;
++
++ rc = class_register(&simpad_gpios_class);
++
++ if(rc != 0)
++ {
++ printk(KERN_ERR "cs3 latch class failed to register properly\n");
++ return rc;
++ }
++
++ rc = register_cs3_latch(&cs3);
++ return rc;
++}
++
++static void __exit simpad_gpios_class_exit(void)
++{
++ class_unregister(&simpad_gpios_class);
++}
++
++module_init(simpad_gpios_class_init);
++module_exit(simpad_gpios_class_exit);
++
++MODULE_AUTHOR("Bernhard Guillon");
++MODULE_DESCRIPTION("CS3_latch driver");
++MODULE_LICENSE("GPL");
diff --git a/recipes/linux/linux/simpad/linux-2.6.21-SIMpad-mq200.patch b/recipes/linux/linux/simpad/linux-2.6.21-SIMpad-mq200.patch
new file mode 100644
index 0000000000..5726779ad6
--- /dev/null
+++ b/recipes/linux/linux/simpad/linux-2.6.21-SIMpad-mq200.patch
@@ -0,0 +1,2511 @@
+diff -uNr linux-2.6.21.vanilla/drivers/video/Kconfig linux-2.6.21/drivers/video/Kconfig
+--- linux-2.6.21.vanilla/drivers/video/Kconfig 2007-05-01 16:40:48.000000000 +0200
++++ linux-2.6.21/drivers/video/Kconfig 2007-05-01 17:02:17.000000000 +0200
+@@ -139,7 +139,7 @@
+ This is particularly important to one driver, matroxfb. If
+ unsure, say N.
+
+-comment "Frame buffer hardware drivers"
++comment "Frambuffer hardware drivers"
+ depends on FB
+
+ config FB_CIRRUS
+@@ -1120,6 +1120,15 @@
+ ---help---
+ Driver for graphics boards with S3 Trio / S3 Virge chip.
+
++config FB_MQ200
++ bool "MQ200 Driver"
++ depends on (FB = y) && ARM && ARCH_SA1100
++ select FB_CFB_FILLRECT
++ select FB_CFB_COPYAREA
++ select FB_CFB_IMAGEBLIT
++ help
++ This is a MQ200 driver tested only on Siemens SIMpads.
++
+ config FB_SAVAGE
+ tristate "S3 Savage support"
+ depends on FB && PCI && EXPERIMENTAL
+diff -uNr linux-2.6.21.vanilla/drivers/video/Makefile linux-2.6.21/drivers/video/Makefile
+--- linux-2.6.21.vanilla/drivers/video/Makefile 2007-05-01 16:40:48.000000000 +0200
++++ linux-2.6.21/drivers/video/Makefile 2007-05-01 17:02:17.000000000 +0200
+@@ -29,6 +29,7 @@
+ obj-$(CONFIG_FB_PM2) += pm2fb.o
+ obj-$(CONFIG_FB_PM3) += pm3fb.o
+
++obj-$(CONFIG_FB_MQ200) += mq200/
+ obj-$(CONFIG_FB_MATROX) += matrox/
+ obj-$(CONFIG_FB_RIVA) += riva/ vgastate.o
+ obj-$(CONFIG_FB_NVIDIA) += nvidia/
+diff -uNr linux-2.6.21.vanilla/drivers/video/backlight/Kconfig linux-2.6.21/drivers/video/backlight/Kconfig
+--- linux-2.6.21.vanilla/drivers/video/backlight/Kconfig 2007-05-01 16:40:48.000000000 +0200
++++ linux-2.6.21/drivers/video/backlight/Kconfig 2007-05-01 17:02:17.000000000 +0200
+@@ -63,3 +63,20 @@
+ help
+ If you have a Frontpath ProGear say Y to enable the
+ backlight driver.
++
++config BACKLIGHT_SIMPAD
++ tristate "SIMpad MQ200 Backlight driver"
++ depends on SA1100_SIMPAD && BACKLIGHT_CLASS_DEVICE
++ default y
++ help
++ If you have a Siemens SIMpad say Y to enable the
++ backlight driver.
++
++config LCD_SIMPAD
++ tristate "SIMpad MQ200 LCD driver"
++ depends on SA1100_SIMPAD && LCD_CLASS_DEVICE
++ default y
++ help
++ If you have a Siemens SIMpad say Y to enable the
++ LCD driver.
++
+diff -uNr linux-2.6.21.vanilla/drivers/video/backlight/Makefile linux-2.6.21/drivers/video/backlight/Makefile
+--- linux-2.6.21.vanilla/drivers/video/backlight/Makefile 2007-05-01 16:40:48.000000000 +0200
++++ linux-2.6.21/drivers/video/backlight/Makefile 2007-05-01 17:02:17.000000000 +0200
+@@ -6,3 +6,5 @@
+ obj-$(CONFIG_BACKLIGHT_HP680) += hp680_bl.o
+ obj-$(CONFIG_BACKLIGHT_LOCOMO) += locomolcd.o
+ obj-$(CONFIG_BACKLIGHT_PROGEAR) += progear_bl.o
++obj-$(CONFIG_BACKLIGHT_SIMPAD) += simpad_bl.o
++obj-$(CONFIG_LCD_SIMPAD) += simpad_lcd.o
+diff -uNr linux-2.6.21.vanilla/drivers/video/backlight/simpad_bl.c linux-2.6.21/drivers/video/backlight/simpad_bl.c
+--- linux-2.6.21.vanilla/drivers/video/backlight/simpad_bl.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.21/drivers/video/backlight/simpad_bl.c 2007-05-01 17:02:17.000000000 +0200
+@@ -0,0 +1,208 @@
++/*
++ * GPLv2 <zecke@handhelds.org
++ *
++ * Implementation of the backlight_driver for
++ * the mq200 framebuffer
++ *
++ * 2007/03/17 mrdata:
++ * - small changes simpad_bl_get_brightness()
++ * simpad_bl_set_brightness()
++ * - new function simpad_bl_update_status()
++ * - changed struct backlight_properties simpad_bl_props()
++ * to new one
++ * - changed __init simpad_bl_init() -> backlight_device_register
++ *
++ * 2007/03/24 mrdata
++ * - added .brightness=127 in
++ * struct backlight_properties simpad_bl_props()
++ */
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/platform_device.h>
++#include <linux/spinlock.h>
++#include <linux/fb.h>
++#include <linux/backlight.h>
++
++#include <asm/types.h>
++#include <asm/hardware.h>
++#include <asm/io.h>
++
++#include "../mq200/mq200_data.h"
++
++#define SIMPAD_BACKLIGHT_MASK 0x00a10044
++#define SIMPAD_DEFAULT_INTENSITY 127
++#define SIMPAD_MAX_INTENSITY 254
++#define REGISTER_BASE 0xf2e00000
++
++static int simpad_bl_suspended;
++static int current_intensity = 0;
++
++static void simpad_bl_send_intensity(struct backlight_device *bd)
++{
++ int intensity = bd->props.brightness;
++
++ union fp0fr fp0fr;
++ unsigned long dutyCycle, pwmcontrol;
++
++ if (intensity > SIMPAD_MAX_INTENSITY)
++ intensity = SIMPAD_MAX_INTENSITY;
++
++ if (bd->props.power != FB_BLANK_UNBLANK)
++ intensity = 0;
++
++ if (bd->props.fb_blank != FB_BLANK_UNBLANK)
++ intensity = 0;
++
++ if (simpad_bl_suspended)
++ intensity = 0;
++
++ if (intensity != current_intensity)
++ {
++ /*
++ * Determine dutyCycle.
++ * Note: the lower the value, the brighter the display!
++ */
++
++ dutyCycle = SIMPAD_MAX_INTENSITY - intensity;
++
++ /*
++ * Configure PWM0 (source clock = oscillator clock, pwm always enabled,
++ * zero, clock pre-divider = 4) pwm frequency = 12.0kHz
++ */
++
++ fp0fr.whole = readl(FP0FR(REGISTER_BASE));
++ pwmcontrol = fp0fr.whole & 0xffff00ff;
++ fp0fr.whole &= 0xffffff00;
++ fp0fr.whole |= 0x00000044;
++ writel(fp0fr.whole, FP0FR(REGISTER_BASE));
++
++ /* Write to pwm duty cycle register. */
++ fp0fr.whole = dutyCycle << 8;
++ fp0fr.whole &= 0x0000ff00;
++ fp0fr.whole |= pwmcontrol;
++ writel(fp0fr.whole, FP0FR(REGISTER_BASE));
++
++ current_intensity = intensity;
++ }
++}
++
++
++#ifdef CONFIG_PM
++static int simpad_bl_suspend(struct platform_device *pdev, pm_message_t state)
++{
++ struct backlight_device *bd = platform_get_drvdata(pdev);
++
++ simpad_bl_suspended = 1;
++ simpad_bl_send_intensity(bd);
++ return 0;
++}
++
++static int simpad_bl_resume(struct platform_device *pdev)
++{
++ struct backlight_device *bd = platform_get_drvdata(pdev);
++
++ simpad_bl_suspended = 0;
++ simpad_bl_send_intensity(bd);
++ return 0;
++}
++#else
++#define simpad_bl_suspend NULL
++#define simpad_bl_resume NULL
++#endif
++
++
++static int simpad_bl_set_intensity(struct backlight_device *bd)
++{
++ simpad_bl_send_intensity(bd);
++ return 0;
++}
++
++
++static int simpad_bl_get_intensity(struct backlight_device *bd)
++{
++ return current_intensity;
++}
++
++
++static struct backlight_ops simpad_bl_ops = {
++ .get_brightness = simpad_bl_get_intensity,
++ .update_status = simpad_bl_set_intensity,
++};
++
++
++static int __init simpad_bl_probe(struct platform_device *pdev)
++{
++ struct backlight_device *bd;
++
++ bd = backlight_device_register("simpad-mq200-bl", &pdev->dev, NULL, &simpad_bl_ops);
++
++ if (IS_ERR (bd))
++ return PTR_ERR (bd);
++
++ platform_set_drvdata(pdev, bd);
++
++ bd->props.max_brightness = SIMPAD_MAX_INTENSITY;
++ bd->props.brightness = SIMPAD_DEFAULT_INTENSITY;
++ simpad_bl_send_intensity(bd);
++
++ return 0;
++}
++
++
++static int simpad_bl_remove(struct platform_device *pdev)
++{
++ struct backlight_device *bd = platform_get_drvdata(pdev);
++
++ bd->props.brightness = 0;
++ bd->props.power = 0;
++ simpad_bl_send_intensity(bd);
++
++ backlight_device_unregister(bd);
++
++ return 0;
++}
++
++static struct platform_driver simpad_bl_driver = {
++ .probe = simpad_bl_probe,
++ .remove = simpad_bl_remove,
++ .suspend = simpad_bl_suspend,
++ .resume = simpad_bl_resume,
++ .driver = {
++ .name = "simpad-mq200-bl",
++ },
++};
++
++static struct platform_device *simpad_bl_device = NULL;
++
++static int __init simpad_bl_init(void)
++{
++ int ret;
++
++ ret = platform_driver_register(&simpad_bl_driver);
++ if (!ret) {
++ simpad_bl_device = platform_device_alloc("simpad-mq200-bl", -1);
++ if (!simpad_bl_device)
++ return -ENOMEM;
++
++ ret = platform_device_add(simpad_bl_device);
++
++ if (ret) {
++ platform_device_put(simpad_bl_device);
++ platform_driver_unregister(&simpad_bl_driver);
++ }
++ }
++ return ret;
++}
++
++static void __exit simpad_bl_exit(void)
++{
++ platform_device_unregister(simpad_bl_device);
++ platform_driver_unregister(&simpad_bl_driver);
++}
++
++
++module_init(simpad_bl_init);
++module_exit(simpad_bl_exit);
++MODULE_AUTHOR("Holger Hans Peter Freyther");
++MODULE_LICENSE("GPL");
+diff -uNr linux-2.6.21.vanilla/drivers/video/backlight/simpad_lcd.c linux-2.6.21/drivers/video/backlight/simpad_lcd.c
+--- linux-2.6.21.vanilla/drivers/video/backlight/simpad_lcd.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.21/drivers/video/backlight/simpad_lcd.c 2007-05-01 17:02:17.000000000 +0200
+@@ -0,0 +1,170 @@
++/*
++ * GPLv2 <zecke@handhelds.org
++ *
++ * Implementation of the lcd_driver for the mq200 framebuffer
++ *
++ * 2007/03/24 mrdata:
++ * - added simpad_lcd_get_contrast()
++ * - added simpad_lcd_set_contrast()
++ * - modify struct lcd_properties simpad_lcd_props
++ */
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/platform_device.h>
++#include <linux/fb.h>
++#include <linux/lcd.h>
++
++#include <asm/arch/simpad.h>
++#include <asm/hardware.h>
++
++extern long get_cs3_shadow(void);
++extern void set_cs3_bit(int);
++extern void clear_cs3_bit(int);
++
++#define UNUSED(x) x=x
++
++static int simpad_lcd_get_power(struct lcd_device* dev)
++{
++ UNUSED(dev);
++
++ return (get_cs3_shadow() & DISPLAY_ON) ? 0 : 4;
++}
++
++static int simpad_lcd_set_power(struct lcd_device* dev, int power)
++{
++ UNUSED(dev);
++
++ if( power == 4 )
++ clear_cs3_bit(DISPLAY_ON);
++ else
++ set_cs3_bit(DISPLAY_ON);
++
++ return 0;
++}
++
++static int simpad_lcd_get_contrast(struct lcd_device* dev)
++{
++ UNUSED(dev);
++
++ return 0;
++}
++
++static int simpad_lcd_set_contrast(struct lcd_device* dev, int contrast)
++{
++ UNUSED(dev);
++
++ UNUSED(contrast);
++
++ return 0;
++}
++
++#ifdef CONFIG_PM
++static int simpad_lcd_suspend(struct platform_device *pdev, pm_message_t state)
++{
++ UNUSED(state);
++ static int ret;
++
++ struct lcd_device* ld;
++
++ ld = platform_get_drvdata(pdev);
++
++ ret = simpad_lcd_set_power(ld, 4);
++
++ return ret;
++}
++
++static int simpad_lcd_resume(struct platform_device *pdev)
++{
++ struct lcd_device *ld;
++ static int ret;
++
++ ld = platform_get_drvdata(pdev);
++
++ ret = simpad_lcd_set_power(ld, 0);
++
++ return ret;
++}
++#else
++#define simpad_lcd_suspend NULL
++#define simpad_lcd_resume NULL
++#endif
++
++static struct lcd_properties simpad_lcd_props = {
++ .max_contrast = 0,
++};
++
++
++static struct lcd_ops simpad_lcd_ops = {
++ .get_power = simpad_lcd_get_power,
++ .set_power = simpad_lcd_set_power,
++ .get_contrast = simpad_lcd_get_contrast,
++ .set_contrast = simpad_lcd_set_contrast,
++};
++
++static int __init simpad_lcd_probe(struct platform_device *pdev)
++{
++ struct lcd_device *ld;
++
++ ld = lcd_device_register ("simpad-mq200-lcd", &pdev->dev, &simpad_lcd_ops);
++
++ if (IS_ERR(ld))
++ return PTR_ERR(ld);
++
++ platform_set_drvdata(pdev, ld);
++
++ ld->props.max_contrast = 0;
++
++ return 0;
++}
++
++static int simpad_lcd_remove(struct platform_device *pdev)
++{
++ struct lcd_device *ld = platform_get_drvdata(pdev);
++
++ lcd_device_unregister(ld);
++
++ return 0;
++}
++
++static struct platform_driver simpad_lcd_driver = {
++ .probe = simpad_lcd_probe,
++ .remove = simpad_lcd_remove,
++ .suspend = simpad_lcd_suspend,
++ .resume = simpad_lcd_resume,
++ .driver = {
++ .name = "simpad-mq200-lcd",
++ },
++};
++
++static struct platform_device *simpad_lcd_device = NULL;
++
++static int __init simpad_lcd_init(void)
++{
++ int ret;
++
++ ret = platform_driver_register(&simpad_lcd_driver);
++ if (!ret) {
++ simpad_lcd_device = platform_device_alloc("simpad-mq200-lcd", -1);
++ if (!simpad_lcd_device)
++ return -ENOMEM;
++
++ ret = platform_device_add(simpad_lcd_device);
++
++ if (ret) {
++ platform_device_put(simpad_lcd_device);
++ platform_driver_unregister(&simpad_lcd_driver);
++ }
++ }
++ return ret;
++}
++
++static void __exit simpad_lcd_exit(void) {
++ platform_driver_unregister(&simpad_lcd_driver);
++ platform_device_unregister(simpad_lcd_device);
++}
++
++module_init(simpad_lcd_init);
++module_exit(simpad_lcd_exit);
++MODULE_AUTHOR("Holger Hans Peter Freyther");
++MODULE_LICENSE("GPL");
+diff -uNr linux-2.6.21.vanilla/drivers/video/mq200/Makefile linux-2.6.21/drivers/video/mq200/Makefile
+--- linux-2.6.21.vanilla/drivers/video/mq200/Makefile 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.21/drivers/video/mq200/Makefile 2007-05-01 17:02:17.000000000 +0200
+@@ -0,0 +1,6 @@
++# Makefile for mq200 video driver
++# 4 Aug 2003, Holger Hans Peter Freyther
++#
++
++obj-$(CONFIG_FB_MQ200) += mq_skeleton.o mq_external.o
++
+diff -uNr linux-2.6.21.vanilla/drivers/video/mq200/mq200_data.h linux-2.6.21/drivers/video/mq200/mq200_data.h
+--- linux-2.6.21.vanilla/drivers/video/mq200/mq200_data.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.21/drivers/video/mq200/mq200_data.h 2007-05-01 17:02:17.000000000 +0200
+@@ -0,0 +1,1120 @@
++/*
++ * From ucLinux mq200fb.c and mq200fb.h
++ *
++ * 2007/03/11 mrdata:
++ * insert registers for graphics controller 2 module
++ */
++
++#ifndef __MQ200_FB_H__
++#define __MQ200_FB_H__
++
++struct mq200_io_regions {
++ u32 fb_size; /* framebuffer size */
++ unsigned long phys_mmio_base; /* physical register memory base */
++ unsigned long virt_mmio_base; /* virtual start of registers */
++ unsigned long phys_fb_base; /* physical address of frame buffer */
++ unsigned long virt_fb_base; /* virtual start of the framebuffer */
++};
++
++#define MQ200_MONITOR_HORI_RES(info) info->monitor_info.horizontal_res
++#define MQ200_MONITOR_VERT_RES(info) info->monitor_info.vertical_res
++#define MQ200_MONITOR_DEPTH(info) info->monitor_info.depth
++#define MQ200_MONITOR_LINE_LENGTH(info) info->monitor_info.line_length
++
++struct mq200_monitor_info {
++ unsigned int horizontal_res;
++ unsigned int vertical_res;
++ unsigned int depth;
++ unsigned int refresh;
++ unsigned int line_length;
++ unsigned long flags;
++};
++
++
++/**
++ * Addresses of Module
++ */
++#define MQ200_FB_BASE (x) (x + 0x1800000) /* framebuffer */
++#define MQ200_FB_SIZE 0x200000 /* framebuffer size in bytes */
++#define MQ200_REGS_BASE(x) (x + 0x1e00000) /* start of registers area */
++#define MQ200_REGS_SIZE 0x200000 /* registers area size */
++
++#define PMU_OFFSET 0x00000 /* power management */
++#define CPU_OFFSET 0x02000 /* CPU interface */
++#define MIU_OFFSET 0x04000 /* memory controller */
++#define IN_OFFSET 0x08000 /* interrupt controller */
++#define GC_OFFSET 0x0a000 /* graphics controller 1&2 */
++#define GE_OFFSET 0x0c000 /* graphics engine */
++#define FPI_OFFSET 0x0e000 /* flat panel controller */
++#define CP1_OFFSET 0x10000 /* color palette 1 */
++#define DC_OFFSET 0x14000 /* device configuration */
++#define PCI_OFFSET 0x16000 /* PCI configuration */
++#define PSF_OFFSET 0x18000 /* ??? */
++
++
++/****
++ * Registers
++ */
++
++/* power management unit */
++#define PMR(addr) (addr + PCI_OFFSET + 0x40)/* power management
++ register */
++#define PMR_VALUE 0x06210001 /* expected read value of PMR register */
++#define PM00R(addr) (addr + PMU_OFFSET + 0x00) /* power management unit
++ configuration
++ register */
++#define PM01R(addr) (addr + PMU_OFFSET + 0x04) /* D1 state control */
++#define PM02R(addr) (addr + PMU_OFFSET + 0x08) /* d2 state control */
++#define PM06R(addr) (addr + PMU_OFFSET + 0x18) /* PLL 2 programming */
++#define PM07R(addr) (addr + PMU_OFFSET + 0x1c) /* PLL 3 programming */
++
++#define PMCSR(addr) (addr + PCI_OFFSET + 0x44) /* power management
++ control/status
++ register */
++
++/* memory interface unit */
++#define MM00R(addr) (addr + MIU_OFFSET + 0x00)/* MIU interface control
++ 0 */
++#define MM01R(addr) (addr + MIU_OFFSET + 0x04) /* MIU interface control
++ 1 */
++#define MM02R(addr) (addr + MIU_OFFSET + 0x08) /* memory interface
++ control 2 */
++#define MM03R(addr) (addr + MIU_OFFSET + 0x0c) /* memory interface
++ control 3 */
++#define MM04R(addr) (addr + MIU_OFFSET + 0x10) /* memory interface
++ control 4 */
++/* graphics controller 1 module */
++#define GC00R(addr) (addr + GC_OFFSET + 0x00) /* graphics controller 1
++ control */
++#define GC01R(addr) (addr + GC_OFFSET + 0x04) /* graphics controller
++ CRT control */
++#define GC02R(addr) (addr + GC_OFFSET + 0x08) /* horizontal display 1
++ control */
++#define GC03R(addr) (addr + GC_OFFSET + 0x0c) /* vertical display 1
++ control */
++#define GC04R(addr) (addr + GC_OFFSET + 0x10) /* horizontal sync 1
++ control */
++#define GC05R(addr) (addr + GC_OFFSET + 0x14) /* vertical sync 1
++ control */
++#define GC07R(addr) (addr + GC_OFFSET + 0x1c) /* vertical display 1
++ count */
++#define GC08R(addr) (addr + GC_OFFSET + 0x20) /* horizontal window 1
++ control */
++#define GC09R(addr) (addr + GC_OFFSET + 0x24) /* vertical window 1
++ control */
++#define GC0AR(addr) (addr + GC_OFFSET + 0x28) /* alternate horizontal
++ window 1 control */
++#define GC0BR(addr) (addr + GC_OFFSET + 0x2c) /* alternate vertical
++ window 1 control */
++#define GC0CR(addr) (addr + GC_OFFSET + 0x30) /* window 1
++ start address */
++#define GC0DR(addr) (addr + GC_OFFSET + 0x34) /* alternate window 1
++ start address */
++#define GC0ER(addr) (addr + GC_OFFSET + 0x38) /* alternate window 1
++ stride */
++#define GC0FR(addr) (addr + GC_OFFSET + 0x3c) /* alternate window 1
++ line size */
++#define GC10R(addr) (addr + GC_OFFSET + 0x40) /* hardware cursor 1
++ position */
++#define GC11R(addr) (addr + GC_OFFSET + 0x44) /* hardware cursor 1
++ start address and
++ offset */
++#define GC12R(addr) (addr + GC_OFFSET + 0x48) /* hardware cursor 1
++ foreground color */
++#define GC13R(addr) (addr + GC_OFFSET + 0x4c) /* hardware cursor 1
++ background color */
++
++/* graphics controller 2 module */
++#define GC20R(addr) (addr + GC_OFFSET + 0x80) /* graphics controller 2
++ control */
++#define GC21R(addr) (addr + GC_OFFSET + 0x84) /* graphics controller
++ CRC control */
++#define GC22R(addr) (addr + GC_OFFSET + 0x88) /* horizontal display 2
++ control */
++#define GC23R(addr) (addr + GC_OFFSET + 0x8c) /* vertical display 2
++ control */
++#define GC24R(addr) (addr + GC_OFFSET + 0x90) /* horizontal sync 2
++ control */
++#define GC25R(addr) (addr + GC_OFFSET + 0x94) /* vertical sync 2
++ control */
++#define GC27R(addr) (addr + GC_OFFSET + 0x9c) /* vertical display 2
++ count */
++#define GC28R(addr) (addr + GC_OFFSET + 0xa0) /* horizontal window 2
++ control */
++#define GC29R(addr) (addr + GC_OFFSET + 0xa4) /* vertical window 2
++ control */
++#define GC2AR(addr) (addr + GC_OFFSET + 0xa8) /* alternate horizontal
++ window 2 control */
++#define GC2BR(addr) (addr + GC_OFFSET + 0xac) /* alternate vertical
++ window 2 control */
++#define GC2CR(addr) (addr + GC_OFFSET + 0xb0) /* window 2
++ start address */
++#define GC2DR(addr) (addr + GC_OFFSET + 0xb4) /* alternate window 2
++ start address */
++#define GC2ER(addr) (addr + GC_OFFSET + 0xb8) /* alternate window 2
++ stride */
++#define GC2FR(addr) (addr + GC_OFFSET + 0xbc) /* alternate window 2
++ line size */
++#define GC30R(addr) (addr + GC_OFFSET + 0xc0) /* hardware cursor 2
++ position */
++#define GC31R(addr) (addr + GC_OFFSET + 0xc4) /* hardware cursor 2
++ start address and
++ offset */
++#define GC32R(addr) (addr + GC_OFFSET + 0xc8) /* hardware cursor 2
++ foreground color */
++#define GC33R(addr) (addr + GC_OFFSET + 0xcc) /* hardware cursor 2
++ background color */
++
++/* graphics engine */
++#define ROP_SRCCOPY 0xCC /* dest = source */
++#define ROP_SRCPAINT 0xEE /* dest = source OR dest */
++#define ROP_SRCAND 0x88 /* dest = source AND dest */
++#define ROP_SRCINVERT 0x66 /* dest = source XOR dest */
++#define ROP_SRCERASE 0x44 /* dest = source AND (NOT dest) */
++#define ROP_NOTSRCCOPY 0x33 /* dest = NOT source */
++#define ROP_NOTSRCERASE 0x11 /* dest = (NOT source) AND (NOT dest) */
++#define ROP_MERGECOPY 0xC0 /* dest = source AND pattern */
++#define ROP_MERGEPAINT 0xBB /* dest = (NOT source) OR dest */
++#define ROP_PATCOPY 0xF0 /* dest = pattern */
++#define ROP_PATPAINT 0xFB /* dest = DPSnoo */
++#define ROP_PATINVERT 0x5A /* dest = pattern XOR dest */
++#define ROP_DSTINVERT 0x55 /* dest = NOT dest */
++#define ROP_BLACKNESS 0x00 /* dest = BLACK */
++#define ROP_WHITENESS 0xFF /* dest = WHITE */
++
++#define GE00R(addr) (addr + GE_OFFSET + 0x00) /* primary drawing command
++ register */
++#define GE01R(addr) (addr + GE_OFFSET + 0x04) /* primary width and
++ height register */
++#define GE02R(addr) (addr + GE_OFFSET + 0x08) /* primary destination
++ address register */
++#define GE03R(addr) (addr + GE_OFFSET + 0x0c) /* primary source XY
++ register */
++#define GE04R(addr) (addr + GE_OFFSET + 0x10) /* primary color compare
++ register */
++#define GE05R(addr) (addr + GE_OFFSET + 0x14) /* primary clip left/top
++ register */
++#define GE06R(addr) (addr + GE_OFFSET + 0x18) /* primary clip
++ right/bottom register
++ */
++#define GE07R(addr) (addr + GE_OFFSET + 0x1c) /* primary source and
++ pattern offset
++ register */
++#define GE08R(addr) (addr + GE_OFFSET + 0x20) /* primary foreground
++ color
++ register/rectangle
++ fill register */
++#define GE09R(addr) (addr + GE_OFFSET + 0x24) /* source stride/offset
++ register */
++#define GE0AR(addr) (addr + GE_OFFSET + 0x28) /* destination stride
++ register and color
++ depth */
++#define GE0BR(addr) (addr + GE_OFFSET + 0x2c) /* image base address
++ register */
++#define GE40R(addr) (addr + GE_OFFSET + 0x100) /* mono pattern register
++ 0 */
++#define GE41R(addr) (addr + GE_OFFSET + 0x104) /* mono pattern register
++ 1 */
++#define GE42R(addr) (addr + GE_OFFSET + 0x108) /* foreground color
++ register */
++#define GE43R(addr) (addr + GE_OFFSET + 0x10c) /* background color
++ register */
++/* color palette */
++#define C1xxR(addr, regno) \
++ (addr + CP1_OFFSET + (regno) * 4) /* graphics controller color
++ palette 1 */
++/* device configuration */
++#define DC00R(addr) (addr + DC_OFFSET + 0x00) /* device configuration
++ register 0 */
++#define DC_RESET 0x4000
++/* PCI configuration space */
++#define PC00R(addr) (addr + PCI_OFFSET + 0x00)/* device ID/vendor ID
++ register */
++/* Flatpanel Control */
++#define FP00R(addr) (addr + FPI_OFFSET + 0x00) /* Flat Panel Control 0 */
++#define FP01R(addr) (addr + FPI_OFFSET + 0x04) /* Flat Panel Output Pin */
++#define FP02R(addr) (addr + FPI_OFFSET + 0x08) /* Flat Panel Gener Purpose
++ Outout Control Register */
++#define FP03R(addr) (addr + FPI_OFFSET + 0x0c) /* General Purpose I/O Port
++ Control Register */
++#define FP04R(addr) (addr + FPI_OFFSET + 0x10) /* STN Panel Control Register */
++#define FP05R(addr) (addr + FPI_OFFSET + 0x14) /* D-STN Half Frame Buffer
++ Control Register -By Guess */
++#define FP0FR(addr) (addr + FPI_OFFSET + 0x3c) /* Pulse Width Modulation
++ Control Register */
++#define FRCTL_PATTERN_COUNT 32
++#define FP10R(addr) (addr + FPI_OFFSET + 0x40) /* Frame-Rate Control Pattern
++ Register */
++#define FP11R(addr) (addr + FPI_OFFSET + 0x44)
++#define FP2FR(addr) (addr + FPI_OFFSET + 0xc0) /* Frame-Rate Control Weight
++ Registers */
++
++
++
++
++/* power management miscellaneous control */
++union pm00r {
++ struct {
++ u32 pll1_n_b5 :1; /* PLL 1 N parameter bit 5 is 0 */
++ u32 reserved_1 :1;
++ u32 pll2_enbl :1; /* PLL 2 enable */
++ u32 pll3_enbl :1; /* PLL 3 enable */
++ u32 reserved_2 :1;
++ u32 pwr_st_ctrl :1; /* power state status control */
++ u32 reserved_3 :2;
++
++ u32 ge_enbl :1; /* graphics engine enable */
++ u32 ge_bsy_gl :1; /* graphics engine force busy (global) */
++ u32 ge_bsy_lcl :1; /* graphics engine force busy (local) */
++ u32 ge_clock :2; /* graphics engine clock select */
++ u32 ge_cmd_fifo :1; /* graphics engine command FIFO reset */
++ u32 ge_src_fifo :1; /* graphics engine CPU source FIFO reset */
++ u32 miu_pwr_seq :1; /* memory interface unit power sequencing
++ enable */
++
++ u32 d3_mem_rfsh :1; /* D3 memory refresh */
++ u32 d4_mem_rfsh :1; /* D4 memory refresh */
++ u32 gpwr_intrvl :2; /* general power sequencing interval */
++ u32 fppwr_intrvl:2; /* flat panel power sequencing interval */
++ u32 gpwr_seq_ctr:1; /* general power sequencing interval control */
++ u32 pmu_tm :1; /* PMU test mode */
++
++ u32 pwr_state :2; /* power state (read only) */
++ u32 pwr_seq_st :1; /* power sequencing active status (read
++ only) */
++ u32 reserved_4 :5;
++ } part;
++ u32 whole;
++};
++
++/* D1 state control */
++union pm01r {
++ struct {
++ u32 osc_enbl :1; /* D1 oscillator enable */
++ u32 pll1_enbl :1; /* D1 PLL 1 enable */
++ u32 pll2_enbl :1; /* D1 PLL 2 enable */
++ u32 pll3_enbl :1; /* D1 PLL 3 enable */
++ u32 miu_enbl :1; /* D1 Memory Interface Unit (MIU) enable */
++ u32 mem_rfsh :1; /* D1 memory refresh enable */
++ u32 ge_enbl :1; /* D1 Graphics Engine (GE) enable */
++ u32 reserved_1 :1;
++
++ u32 crt_enbl :1; /* D1 CRT enable */
++ u32 fpd_enbl :1; /* D1 Flat Panel enable */
++ u32 reserved_2 :6;
++
++ u32 ctl1_enbl :1; /* D1 controller 1 enable */
++ u32 win1_enbl :1; /* D1 window 1 enable */
++ u32 awin1_enbl :1; /* D1 alternate window 1 enable */
++ u32 cur1_enbl :1; /* D1 cursor 1 enable */
++ u32 reserved_3 :4;
++
++ u32 ctl2_enbl :1; /* D1 controller 2 enable */
++ u32 win2_enbl :1; /* D1 window 2 enable */
++ u32 awin2_enbl :1; /* D1 alternate window 2 enable */
++ u32 cur2_enbl :1; /* D1 cursor 2 enable */
++ u32 reserved_4 :4;
++ } part;
++ u32 whole;
++};
++
++/* D2 state control */
++union pm02r {
++ struct {
++ u32 osc_enbl :1; /* D2 oscillator enable */
++ u32 pll1_enbl :1; /* D2 PLL 1 enable */
++ u32 pll2_enbl :1; /* D2 PLL 2 enable */
++ u32 pll3_enbl :1; /* D2 PLL 3 enable */
++ u32 miu_enbl :1; /* D2 Memory Interface Unit (MIU) enable */
++ u32 mem_rfsh :1; /* D2 memory refresh enable */
++ u32 ge_enbl :1; /* D2 Graphics Engine (GE) enable */
++ u32 reserved_1 :1;
++
++ u32 crt_enbl :1; /* D2 CRT enable */
++ u32 fpd_enbl :1; /* D2 Flat Panel enable */
++ u32 reserved_2 :6;
++
++ u32 ctl1_enbl :1; /* D2 controller 1 enable */
++ u32 win1_enbl :1; /* D2 window 1 enable */
++ u32 awin1_enbl :1; /* D2 alternate window 1 enable */
++ u32 cur1_enbl :1; /* D2 cursor 1 enable */
++ u32 reserved_3 :4;
++
++ u32 ctl2_enbl :1; /* D2 controller 2 enable */
++ u32 win2_enbl :1; /* D2 window 2 enable */
++ u32 awin2_enbl :1; /* D2 alternate window 2 enable */
++ u32 cur2_enbl :1; /* D2 cursor 2 enable */
++ u32 reserved_4 :4;
++ } part;
++ u32 whole;
++};
++
++/* PLL 2 programming */
++union pm06r {
++ struct {
++ u32 clk_src :1; /* PLL 2 reference clock source */
++ u32 bypass :1; /* PLL 2 bypass */
++ u32 reserved_1 :2;
++ u32 p_par :3; /* PLL 2 P parameter */
++ u32 reserved_2 :1;
++
++ u32 n_par :5; /* PLL 2 N parameter */
++ u32 reserved_3 :3;
++
++ u32 m_par :8; /* PLL 2 M parameter */
++
++ u32 reserved_4 :4;
++ u32 trim :4; /* PLL 2 trim value */
++ } part;
++ u32 whole;
++};
++
++/* PLL 3 programming */
++union pm07r {
++ struct {
++ u32 clk_src :1; /* PLL 3 reference clock source */
++ u32 bypass :1; /* PLL 3 bypass */
++ u32 reserved_1 :2;
++ u32 p_par :3; /* PLL 3 P parameter */
++ u32 reserved_2 :1;
++
++ u32 n_par :5; /* PLL 3 N parameter */
++ u32 reserved_3 :3;
++
++ u32 m_par :8; /* PLL 3 M parameter */
++
++ u32 reserved_4 :4;
++ u32 trim :4; /* PLL 3 trim value */
++ } part;
++ u32 whole;
++};
++
++
++
++/* MIU interface control 1 */
++union mm00r {
++ struct {
++ u32 miu_enbl :1; /* MIU enable bit */
++ u32 mr_dsbl :1; /* MIU reset disable bit */
++ u32 edr_dsbl :1; /* embedded DRAM reset disable bit */
++ u32 reserved_1 :29;
++ } part;
++ u32 whole;
++};
++
++/* MIU interface control 2 */
++union mm01r {
++ struct {
++ u32 mc_src :1; /* memory clock source */
++ u32 msr_enbl :1; /* memory slow refresh enable bit */
++ u32 pb_cpu :1; /* page break enable for CPU */
++ u32 pb_gc1 :1; /* page break enable for GC1 */
++ u32 pb_gc2 :1; /* page break enable for GC2 */
++ u32 pb_stn_r :1; /* page break enable for STN read */
++ u32 pb_stn_w :1; /* page break enable for STN write */
++ u32 pb_ge :1; /* page break enable for GE */
++ u32 reserved_1 :4;
++ u32 mr_interval :14; /* normal memory refresh time interval */
++ u32 reserved_2 :4;
++ u32 edarm_enbl :1; /* embedded DRAM auto-refresh mode enable */
++ u32 eds_enbl :1; /* EDRAM standby enable for EDRAM normal
++ mode operation */
++ } part;
++ u32 whole;
++};
++
++/* memory interface control 3 */
++union mm02r {
++ struct {
++ u32 bs_ :2;
++ u32 bs_stnr :2; /* burst count for STN read memory cycles */
++ u32 bs_stnw :2; /* burst count for STN write memroy cycles */
++ u32 bs_ge :2; /* burst count for graphics engine
++ read/write memroy cycles */
++ u32 bs_cpuw :2; /* burst count for CPU write memory cycles */
++ u32 fifo_gc1 :4; /* GC1 display refresh FIFO threshold */
++ u32 fifo_gc2 :4; /* GC2 display refresh FIFO threshold */
++ u32 fifo_stnr :4; /* STN read FIFO threshold */
++ u32 fifo_stnw :4; /* STN write FIFO threshold */
++ u32 fifo_ge_src :3; /* GE source read FIFO threshold */
++ u32 fifo_ge_dst :3; /* GE destination read FIFO threshold */
++ } part;
++ u32 whole;
++};
++
++/* memory interface control 4 */
++union mm03r {
++ struct {
++ u32 rd_late_req :1; /* read latency request */
++ u32 reserved_1 :31;
++ } part;
++ u32 whole;
++};
++
++/* memory interface control 5 */
++union mm04r {
++ struct {
++ u32 latency :3; /* EDRAM latency */
++ u32 dmm_cyc :1; /* enable for the dummy cycle insertion
++ between read and write cycles */
++ u32 pre_dmm_cyc :1; /* enable for the dummy cycle insertion
++ between read/write and precharge cycles
++ for the same bank */
++ u32 reserved_1 :3;
++ u32 bnk_act_cls :2; /* bank activate command to bank close
++ command timing interval control */
++ u32 bnk_act_rw :1; /* bank activate command to read/wirte
++ command timing interval control */
++ u32 bnk_cls_act :1; /* bank close command to bank activate
++ command timing interval control */
++ u32 trc :1; /* row cycle time */
++ u32 reserved_2 :3;
++ u32 delay_r :2; /* programmable delay for read clock */
++ u32 delay_m :2; /* programmable delay for internal memory
++ clock */
++ } part;
++ u32 whole;
++};
++
++/* graphics controller 1 register */
++union gc00r {
++ struct {
++ u32 ctl_enbl :1; /* Controller 1 Enable */
++ u32 hc_reset :1; /* Horizontal Counter 1 Reset */
++ u32 vc_reset :1; /* Vertical Counter 1 Reset */
++ u32 iwin_enbl :1; /* Image Window 1 Enable */
++ u32 gcd :4; /* Graphics Color Depth (GCD) */
++
++ u32 hc_enbl :1; /* Hardware Cursor 1 Enable */
++ u32 reserved_1 :2;
++ u32 aiwin_enbl :1; /* Alternate Image Window Enable */
++ u32 agcd :4; /* Alternate Graphics Color Depth (AGCD) */
++
++ u32 g1rclk_src :2; /* G1RCLK Source */
++ u32 tm0 :1; /* Test Mode 0 */
++ u32 tm1 :1; /* Test Mode 1 */
++ u32 fd :3; /* G1MCLK First Clock Divisor (FD1) */
++ u32 reserved_2 :1;
++
++ u32 sd :8; /* G1MCLK Second Clock Divisor (SD1) */
++ } part;
++ u32 whole;
++};
++
++/* graphics controller CRT control */
++union gc01r {
++ struct {
++ u32 dac_enbl :2; /* CRT DAC enable */
++ u32 hsync_out :1; /* CRT HSYNC output during power down mode */
++ u32 vsync_out :1; /* CRT VSYNC output during power down mode */
++ u32 hsync_ctl :2; /* CRT HSYNC control */
++ u32 vsync_ctl :2; /* CRT VSYNC control */
++ /**/
++ u32 hsync_pol :1; /* CRT HSYNC polarity */
++ u32 vsync_pol :1; /* CRT VSYNC polarity */
++ u32 sync_p_enbl :1; /* sync pedestal enable */
++ u32 blnk_p_enbl :1; /* blank pedestal enable */
++ u32 c_sync_enbl :1; /* composite sync enable */
++ u32 vref_sel :1; /* VREF select */
++ u32 mn_sns_enbl :1; /* monitor sense enable */
++ u32 ct_out_enbl :1; /* constant output enable */
++ /**/
++ u32 dac_out_lvl :8; /* monitor sense DAC output level */
++ /**/
++ u32 blue_dac_r :1; /* blue DAC sense result */
++ u32 green_dac_r :1; /* green DAC sense result */
++ u32 red_dac_r :1; /* red DAC sense result */
++ u32 reserved_1 :1;
++ u32 mon_col_sel :1; /* mono/color monitor select */
++ u32 reserved_2 :3;
++ } part;
++ u32 whole;
++};
++
++/* horizontal display 1 control */
++union gc02r {
++ struct {
++ u32 hd1t :12; /* horizontal display 1 total */
++ u32 reserved_1 :4;
++
++ u32 hd1e :12; /* horizontal display 1 end */
++ u32 reserved_2 :4;
++ } part;
++ u32 whole;
++};
++
++/* vertical display 1 control */
++union gc03r {
++ struct {
++ u32 vd1t :12; /* vertical display 1 total */
++ u32 reserved_1 :4;
++
++ u32 vd1e :12; /* vertical display 1 end */
++ u32 reserved_2 :4;
++ } part;
++ u32 whole;
++};
++
++/* horizontal sync 1 control */
++union gc04r {
++ struct {
++ u32 hs1s :12; /* horizontal sync 1 start */
++ u32 reserved_1 :4;
++
++ u32 hs1e :12; /* horizontal sync 1 end */
++ u32 reserved_2 :4;
++ } part;
++ u32 whole;
++};
++
++/* vertical sync 1 control */
++union gc05r {
++ struct {
++ u32 vs1s :12; /* vertical sync 1 start */
++ u32 reserved_1 :4;
++
++ u32 vs1e :12; /* vertical sync 1 end */
++ u32 reserved_2 :4;
++ } part;
++ u32 whole;
++};
++
++/* vertical display 1 count */
++union gc07r {
++ struct {
++ u32 vd_cnt :12; /* vertical display 1 count */
++ u32 reverved_1 :20;
++ } part;
++ u32 whole;
++};
++
++/* horizontal window 1 control */
++union gc08r {
++ struct {
++ u32 hw1s :12; /* horizontal window 1 start (HW1S) */
++ u32 reserved_1 :4;
++
++ u32 hw1w :12; /* horizontal window 1 width (HW1W) */
++ u32 w1ald :4; /* window 1 additional line data */
++ } part;
++ u32 whole;
++};
++
++/* vertical window 1 control */
++union gc09r {
++ struct {
++ u32 vw1s :12; /* vertical window 1 start */
++ u32 reserved_1 :4;
++ u32 vw1h :12; /* vertical window 1 height */
++ u32 reserved_2 :4;
++ } part;
++ u32 whole;
++};
++
++/* window 1 start address */
++union gc0cr {
++ struct {
++ u32 w1sa :21; /* window 1 start address */
++ u32 reserved_1 :11;
++ } part;
++ u32 whole;
++};
++
++/* window 1 stride */
++union gc0er {
++ struct {
++ s16 w1st; /* window 1 stride */
++ s16 aw1st; /* alternate window 1 stride */
++ } part;
++ u32 whole;
++};
++
++/* hardware cursor 1 position */
++union gc10r {
++ struct {
++ u32 hc1s :12; /* horizontal cursor 1 start */
++ u32 reserved_1 :4;
++ u32 vc1s :12; /* vertical cursor 1 start */
++ u32 reserved_2 :4;
++ } part;
++ u32 whole;
++};
++
++/* hardware cursor 1 start address and offset */
++union gc11r {
++ struct {
++ u32 hc1sa :11; /* hardware cursor 1 start address */
++ u32 reserved_1 :5;
++ u32 hc1o :6; /* horizontal cursor 1 offset */
++ u32 reserved_2 :2;
++ u32 vc1o :6; /* vertical cursor 1 offset */
++ u32 reserved_3 :2;
++ } part;
++ u32 whole;
++};
++
++/* hardware cursor 1 foreground color */
++union gc12r {
++ struct {
++ u32 hc1fc :24; /* hardware cursor 1 foreground color */
++ u32 reserved_1 :8;
++ } part;
++ u32 whole;
++};
++
++/* hardware cursor 1 background color */
++union gc13r {
++ struct {
++ u32 hc1bc :24; /* hardware cursor 1 background color */
++ u32 reserved_1 :8;
++ } part;
++ u32 whole;
++};
++
++
++/* graphics controller 2 register */
++union gc20r {
++ struct {
++ u32 ctl_enbl :1; /* Controller 2 Enable */
++ u32 hc_reset :1; /* Horizontal Counter 2 Reset */
++ u32 vc_reset :1; /* Vertical Counter 2 Reset */
++ u32 iwin_enbl :1; /* Image Window 2 Enable */
++ u32 gcd :4; /* Graphics Color Depth (GCD) */
++
++ u32 hc_enbl :1; /* Hardware Cursor 2 Enable */
++ u32 reserved_1 :2;
++ u32 aiwin_enbl :1; /* Alternate Image Window Enable */
++ u32 agcd :4; /* Alternate Graphics Color Depth (AGCD) */
++
++ u32 g2rclk_src :2; /* G2RCLK Source */
++ u32 tm0 :1; /* Test Mode 0 */
++ u32 tm1 :1; /* Test Mode 1 */
++ u32 fd :3; /* G2MCLK First Clock Divisor (FD1) */
++ u32 reserved_2 :1;
++
++ u32 sd :8; /* G2MCLK Second Clock Divisor (SD1) */
++ } part;
++ u32 whole;
++};
++
++/* graphics controller CRC control */
++union gc21r {
++ struct {
++ u32 crc_enbl :1; /* CRC enable */
++ u32 vsync_wait :1; /* CRC input data control waitime of VSYNC */
++ u32 crc_o_sel :2; /* CRC output select */
++ u32 reserved_1 :4;
++ u32 crc_result :22; /* CRC result (read only) */
++ u32 reserved_2 :2;
++ } part;
++ u32 whole;
++};
++
++/* horizontal display 2 control */
++union gc22r {
++ struct {
++ u32 hd2t :12; /* horizontal display 2 total */
++ u32 reserved_1 :4;
++
++ u32 hd2e :12; /* horizontal display 2 end */
++ u32 reserved_2 :4;
++ } part;
++ u32 whole;
++};
++
++/* vertical display 2 control */
++union gc23r {
++ struct {
++ u32 vd2t :12; /* vertical display 2 total */
++ u32 reserved_1 :4;
++
++ u32 vd2e :12; /* vertical display 2 end */
++ u32 reserved_2 :4;
++ } part;
++ u32 whole;
++};
++
++/* horizontal sync 2 control */
++union gc24r {
++ struct {
++ u32 hs2s :12; /* horizontal sync 2 start */
++ u32 reserved_1 :4;
++
++ u32 hs2e :12; /* horizontal sync 2 end */
++ u32 reserved_2 :4;
++ } part;
++ u32 whole;
++};
++
++/* vertical sync 2 control */
++union gc25r {
++ struct {
++ u32 vs2s :12; /* vertical sync 2 start */
++ u32 reserved_1 :4;
++
++ u32 vs2e :12; /* vertical sync 2 end */
++ u32 reserved_2 :4;
++ } part;
++ u32 whole;
++};
++
++/* vertical display 2 count */
++union gc27r {
++ struct {
++ u32 vd_cnt :12; /* vertical display 2 count */
++ u32 reverved_1 :20;
++ } part;
++ u32 whole;
++};
++
++/* horizontal window 2 control */
++union gc28r {
++ struct {
++ u32 hw2s :12; /* horizontal window 2 start (HW2S) */
++ u32 reserved_1 :4;
++
++ u32 hw2w :12; /* horizontal window 2 width (HW2W) */
++ u32 w2ald :4; /* window 2 additional line data */
++ } part;
++ u32 whole;
++};
++
++/* vertical window 2 control */
++union gc29r {
++ struct {
++ u32 vw2s :12; /* vertical window 2 start */
++ u32 reserved_1 :4;
++ u32 vw2h :12; /* vertical window 2 height */
++ u32 reserved_2 :4;
++ } part;
++ u32 whole;
++};
++
++/* window 2 start address */
++union gc2cr {
++ struct {
++ u32 w2sa :21; /* window 2 start address */
++ u32 reserved_1 :11;
++ } part;
++ u32 whole;
++};
++
++/* window 2 stride */
++union gc2er {
++ struct {
++ s16 w2st; /* window 2 stride */
++ s16 aw2st; /* alternate window 2 stride */
++ } part;
++ u32 whole;
++};
++
++/* hardware cursor 2 position */
++union gc30r {
++ struct {
++ u32 hc2s :12; /* horizontal cursor 2 start */
++ u32 reserved_1 :4;
++ u32 vc2s :12; /* vertical cursor 2 start */
++ u32 reserved_2 :4;
++ } part;
++ u32 whole;
++};
++
++/* hardware cursor 2 start address and offset */
++union gc31r {
++ struct {
++ u32 hc2sa :11; /* hardware cursor 2 start address */
++ u32 reserved_1 :5;
++ u32 hc2o :6; /* horizontal cursor 2 offset */
++ u32 reserved_2 :2;
++ u32 vc2o :6; /* vertical cursor 2 offset */
++ u32 reserved_3 :2;
++ } part;
++ u32 whole;
++};
++
++/* hardware cursor 2 foreground color */
++union gc32r {
++ struct {
++ u32 hc2fc :24; /* hardware cursor 2 foreground color */
++ u32 reserved_1 :8;
++ } part;
++ u32 whole;
++};
++
++/* hardware cursor 2 background color */
++union gc33r {
++ struct {
++ u32 hc2bc :24; /* hardware cursor 2 background color */
++ u32 reserved_1 :8;
++ } part;
++ u32 whole;
++};
++
++
++/* primary drawing command register */
++union ge00r {
++ struct {
++ u32 rop :8; /* raster operation */
++ /**/
++ u32 cmd_typ :3; /* command type */
++ u32 x_dir :1; /* x direction */
++ u32 y_dir :1; /* y direction */
++ u32 src_mem :1; /* source memory */
++ u32 mon_src :1; /* mono source */
++ u32 mon_ptn :1; /* mono pattern */
++ /**/
++ u32 dst_trns_e :1; /* destination transparency enable */
++ u32 dst_trns_p :1; /* destination transparency polarity */
++ u32 mon_trns_e :1; /* mono source or mono pattern transparency
++ enable */
++ u32 mon_trns_p :1; /* mono transparency polarity */
++ u32 mod_sel :1; /* memory to screen or off screen to screen
++ mode select */
++ u32 alpha_sel :2; /* Alpha byte mask selection */
++ u32 sol_col :1; /* solid color */
++ /**/
++ u32 stride_eq :1; /* source stride is equal to destination
++ stride */
++ u32 rop2_sel :1; /* ROP2 code selection */
++ u32 clipping :1; /* enable clipping */
++ u32 auto_exec :1; /* auto execute */
++ u32 reserved_1 :4;
++ } part;
++ u32 whole;
++};
++
++/* primary width and height register */
++union ge01r {
++ struct {
++ u32 width :12; /* source/destination window width */
++ u32 reserved_1 :4;
++
++ u32 height :12; /* source/destination window height */
++ u32 reserved_2 :1;
++ u32 reserved_3 :3;
++ } bitblt;
++ struct {
++ u32 dm :17;
++ u32 axis_major :12;
++ u32 x_y :1; /* x-major or y-major */
++ u32 last_pix :1; /* decision to draw or not to draw the last
++ pixel of the line */
++ u32 reserved_1 :1;
++ } bresenham;
++ u32 whole;
++};
++
++/* primary destination address register */
++union ge02r {
++ struct {
++ u32 dst_x :12; /* destination x position */
++ u32 reserved_1 :1;
++ u32 h_offset :3; /* mono/color pattern horizontal offset */
++
++ u32 dst_y :12; /* destination y position */
++ u32 reserved_2 :1;
++ u32 v_offset :3; /* mono/color pattern vertical offset */
++ } window;
++ struct {
++ u32 x :12; /* starting x coordinate */
++ u32 dm :17; /* 17 bits major-axis delta */
++ u32 reserved_1 :3;
++ } line;
++ u32 whole;
++};
++
++/* source XY register/line draw starting Y coordinate and mintor axis delta */
++union ge03r {
++ struct {
++ u32 src_x :12; /* source X position */
++ u32 reserved_1 :4;
++
++ u32 src_y :12; /* source Y position */
++ u32 reserved_2 :4;
++ } window;
++ struct {
++ u32 start_y :12; /* starting Y coordinate */
++ u32 dn :17; /* 17 bits minor-axis delta */
++ u32 reserved_1 :3;
++ } line;
++ u32 whole;
++};
++
++/* clip left/top register */
++union ge05r {
++ struct {
++ u32 left :12; /* left edge of clipping rectangle */
++ u32 reserved_1 :4;
++
++ u32 top :12; /* top edge of clipping rectangle */
++ u32 reserved_2 :4;
++ } part;
++ u32 whole;
++};
++
++/* source stride/offset register */
++union ge09r {
++ struct {
++ u32 src_strid :12; /* source line stride */
++ u32 reserved_1 :13;
++ u32 strt_bit :3; /* initial mono source bit offset */
++ u32 strt_byte :3; /* initial mono/color source byte offset */
++ u32 reserved_2 :1;
++ } line;
++ struct {
++ u32 strt_bit :5; /* initial mono source bit offset */
++ u32 reserved_1 :1;
++ u32 amount :10; /* number of 16 bytes amount that MIU need
++ to fetch from frame buffer */
++
++ u32 reserved_2 :9;
++ u32 bit_spc :7; /* bit space between lines */
++ } pack_mono;
++ struct {
++ u32 strt_bit :3; /* initial mono source bit offset */
++ u32 strt_byte :3; /* initial mono/color source byte offset */
++ u32 amount :10; /* number of 16 bytes amount that MIU need
++ to fetch from frame buffer */
++
++ u32 reserved_1 :9;
++ u32 bit_spc :3; /* bit space between lines */
++ u32 byt_spc :4; /* byte space between lines */
++ } pack_color;
++ u32 whole;
++};
++
++/* destination stride register and color depth */
++union ge0ar {
++ struct {
++ u32 dst_strid :12; /* destination line stride and color depth */
++ u32 reserved_1 :18;
++ u32 col_dpth :2; /* color depth */
++ } part;
++ u32 whole;
++};
++
++/* graphics controller color pallete */
++union c1xxr {
++ struct {
++ u8 red; /* red color pallete */
++ u8 green; /* green/gray color pallete */
++ u8 blue; /* blue color palette */
++ u8 reserved_1;
++ } part;
++ u32 whole;
++};
++
++/* devicee configuration register 0 */
++union dc00r {
++ struct {
++ u32 osc_bypass :1; /* oscillator bypass */
++ u32 osc_enbl :1; /* oscillator enable */
++ u32 pll1_bypass :1; /* PLL1 bypass */
++ u32 pll1_enbl :1; /* PLL1 enable */
++ u32 pll1_p_par :3; /* PLL1 P parameter */
++ u32 cpu_div :1; /* CPU interface clock divisor */
++ u32 pll1_n_par :5; /* PLL1 N parameter */
++ u32 saisc :1; /* StrongARM interface synchronizer control */
++ u32 s_chp_reset :1; /* software chip reset */
++ u32 mem_enbl :1; /* memory standby enable */
++ u32 pll1_m_par :8; /* PLL 1 M parameter */
++ u32 osc_shaper :1; /* oscillator shaper disable */
++ u32 fast_pwr :1; /* fast power sequencing */
++ u32 osc_frq :2; /* oscillator frequency select */
++ u32 pll1_trim :4; /* PLL 1 trim value */
++ } part;
++ u32 whole;
++};
++
++/* device ID/vendor ID register */
++union pc00r {
++ struct {
++ u16 device; /* device ID */
++ u16 vendor; /* vendor ID */
++ } part;
++ u32 whole;
++};
++
++/* Flat Panel Control Register */
++union fp00r {
++ struct {
++ u32 flatp_enbl : 2; /* Flat Panel Interface Enable */
++ u32 flatp_type : 2; /* Flat Panel Type */
++ u32 mono : 1; /* Mono/Color Panel Select */
++ u32 flatp_intf : 3; /* Flat Panel Interface */
++ u32 dither_pat : 2; /* Dither Pattern */
++ u32 reserved : 2; /* Reserved Must Be 0*/
++ u32 dither_col : 3; /* Dither Base Color */
++ u32 alt_win_ctl: 1; /* Alternate Window Control */
++ u32 frc_ctl : 2; /* FRC Control */
++ u32 dither_adj1: 6; /* Dither Pattern Adjust 1 */
++ u32 dither_adj2: 3; /* Dither Pattern Adjust 2 */
++ u32 dither_adj3: 1; /* Dither Pattern Adjust 3 */
++ u32 test_mode0 : 1; /* Test Mode 0 */
++ u32 test_mode1 : 1; /* Test Mode 1 */
++ u32 test_mode2 : 1; /* Test Mode 2 */
++ u32 test_mode3 : 1; /* Test Mode 3 */
++ } part;
++ u32 whole;
++};
++
++union fp01r {
++ struct {
++ u32 dummy;
++ } part;
++ u32 whole;
++};
++
++union fp02r {
++ struct {
++ u32 dummy;
++ } part;
++ u32 whole;
++};
++
++union fp03r {
++ struct {
++ u32 dummy;
++ } part;
++ u32 whole;
++};
++
++union fp04r {
++ struct {
++ u32 dummy;
++ } part;
++ u32 whole;
++};
++
++union fp05r {
++ struct {
++ u32 dummy;
++ } part;
++ u32 whole;
++};
++
++union fp0fr {
++ struct {
++ u32 dummy;
++ } part;
++ u32 whole;
++};
++
++
++
++
++/****
++ * Others
++ */
++
++#define CHIPNAME "MQ-200"
++
++extern void mq200_external_setpal(unsigned regno, unsigned long color, unsigned long addr);
++extern void mq200_external_setqmode(struct mq200_monitor_info*, unsigned long, spinlock_t *);
++extern void mq200_external_offdisplay(unsigned long);
++extern void mq200_external_ondisplay (unsigned long);
++extern int mq200_external_probe(unsigned long);
++
++
++
++#endif
+diff -uNr linux-2.6.21.vanilla/drivers/video/mq200/mq_external.c linux-2.6.21/drivers/video/mq200/mq_external.c
+--- linux-2.6.21.vanilla/drivers/video/mq200/mq_external.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.21/drivers/video/mq200/mq_external.c 2007-05-01 17:02:17.000000000 +0200
+@@ -0,0 +1,513 @@
++/*
++ * Copyright (C) 2005 Holger Hans Peter Freyther
++ *
++ * Based ON:
++ *
++ * linux/drivers/video/mq200fb.c -- MQ-200 for a frame buffer device
++ * based on linux/driver/video/pm2fb.c
++ *
++ * 2007/03/11 mrdata:
++ * bug found in gc1_reset(), renaming to gc1_gc2_reset()
++ * extend mq200_external_ondisplay() -> LCD for GC2 and CRT for GC1
++ *
++ * Copyright (C) 2000 Lineo, Japan
++ *
++ * 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 <asm/types.h>
++#include <asm/io.h>
++#include <linux/delay.h>
++#include <linux/spinlock.h>
++
++#include <asm/hardware.h>
++
++#include "mq200_data.h"
++
++
++#if 1
++#define PRINTK(args...) printk(args)
++#else
++#define PRINTK(args...)
++#endif
++
++
++/****
++ * power state transition to "state".
++ */
++static void
++power_state_transition(unsigned long register_base, int state)
++{
++ int i;
++ writel(state, PMCSR(register_base));
++ mdelay(300);
++ for (i = 1; ; i++) {
++ udelay(100);
++ if ((readl(PMCSR(register_base)) & 0x3) == state) {
++ break;
++ }
++ }
++}
++
++
++/****
++ * device configuration initialization.
++ */
++static void
++dc_reset(unsigned long register_base)
++{
++ union dc00r dc00r;
++
++ /* Reset First */
++ dc00r.whole = DC_RESET;
++ writel(dc00r.whole, DC00R(register_base));
++ mdelay(100);
++
++ dc00r.whole = 0xEF2082A;
++ writel(dc00r.whole, DC00R(register_base));
++ mdelay(300);
++ PRINTK(CHIPNAME ": DC00R = 0x%08X\n", readl(DC00R(register_base)));
++}
++
++
++/****
++ * initialize memory interface unit.
++ */
++static void
++miu_reset(unsigned long register_base)
++{
++ union mm00r mm00r;
++ union mm01r mm01r;
++ union mm02r mm02r;
++ union mm03r mm03r;
++ union mm04r mm04r;
++
++ /* MIU interface control 1 */
++ mm00r.whole = 0x4;
++ writel(mm00r.whole, MM00R(register_base));
++ mdelay(50);
++ writel(0, MM00R(register_base));
++ mdelay(50);
++
++ /* MIU interface control 2
++ * o PLL 1 output is used as memory clock source.
++ */
++ mm01r.whole = 0x4143e086;
++ writel(mm01r.whole, MM01R(register_base));
++
++ /* memory interface control 3 */
++ mm02r.whole = 0x6d6aabff;
++ writel(mm02r.whole, MM02R(register_base));
++
++ /* memory interface control 5 */
++ mm04r.whole = 0x10d;
++ writel(mm04r.whole, MM04R(register_base));
++
++ /* memory interface control 4 */
++ mm03r.whole = 0x1;
++ writel(mm03r.whole, MM03R(register_base));
++ mdelay(50);
++
++ /* MIU interface control 1 */
++ mm00r.whole = 0x3;
++ writel(mm00r.whole, MM00R(register_base));
++ mdelay(50);
++}
++
++/****
++ *
++ */
++static
++void fpctrl_reset(unsigned long addr)
++{
++ /*
++ * We're in D0 State, let us set the FPCTRL
++ */
++ union fp00r fp00r;
++ union fp01r fp01r;
++ union fp02r fp02r;
++ union fp03r fp03r;
++ union fp04r fp04r;
++ union fp0fr fp0fr;
++
++ fp00r.whole = 0x6320;
++ writel(fp00r.whole, FP00R(addr));
++
++ fp01r.whole = 0x20;
++ writel(fp01r.whole, FP01R(addr));
++
++ fp04r.whole = 0xBD0001;
++ writel(fp04r.whole, FP04R(addr));
++
++ /* Set Flat Panel General Purpose register first */
++ fp02r.whole = 0x0;
++ writel(fp02r.whole, FP02R(addr));
++
++ fp03r.whole = 0x0;
++ writel(fp03r.whole, FP03R(addr));
++
++ fp0fr.whole = 0xA16c44;
++ writel(fp0fr.whole, FP0FR(addr));
++
++ /* Set them again */
++ fp02r.whole = 0x0;
++ writel(fp02r.whole, FP02R(addr));
++
++ fp03r.whole = 0x0;
++ writel(fp03r.whole, FP03R(addr));
++}
++
++
++/****
++ * initialize power management unit.
++ */
++static void
++pmu_reset(unsigned long register_base)
++{
++ union pm00r pm00r;
++ union pm01r pm01r;
++ union pm02r pm02r;
++
++ /* power management miscellaneous control
++ * o GE is driven by PLL 1 clock.
++ */
++ pm00r.whole = 0xc0900;
++ writel(pm00r.whole, PM00R(register_base));
++
++ /* D1 state control */
++ pm01r.whole = 0x5000271;
++ writel(pm01r.whole, PM01R(register_base));
++
++ /* D2 state control */
++ pm02r.whole = 0x271;
++ writel(pm02r.whole, PM02R(register_base));
++}
++
++/****
++ * initialize graphics controller 1
++ * and graphics controller 2
++ */
++static void
++gc1_gc2_reset(unsigned long register_base, spinlock_t *lock )
++{
++ unsigned long flags;
++ union gc00r gc00r;
++ union gc01r gc01r;
++ union gc02r gc02r;
++ union gc03r gc03r;
++ union gc04r gc04r;
++ union gc05r gc05r;
++ union gc08r gc08r;
++ union gc09r gc09r;
++ union gc0cr gc0cr;
++ union gc0er gc0er;
++ union gc20r gc20r;
++ union gc22r gc22r;
++ union gc23r gc23r;
++ union gc24r gc24r;
++ union gc25r gc25r;
++ union gc28r gc28r;
++ union gc29r gc29r;
++ union gc2cr gc2cr;
++ union gc2er gc2er;
++
++ union pm00r pm00r;
++ union pm06r pm06r;
++ union pm06r pm07r;
++
++ spin_lock_irqsave(lock, flags);
++
++ /* alternate window 1 stride */
++ gc0er.whole = 0x640;
++ writel(gc0er.whole, GC0ER(register_base));
++
++ /* image window 1 start address */
++ gc0cr.whole = 0x0;
++ writel(gc0cr.whole, GC0CR(register_base));
++
++ /* alternate window 2 stride */
++ gc2er.whole = 0x640;
++ writel(gc0er.whole, GC2ER(register_base));
++
++ /* image window 2 start address */
++ gc2cr.whole = 0x0;
++ writel(gc2cr.whole, GC2CR(register_base));
++
++ /* read PM Register */
++ pm00r.whole = readl(PM00R(register_base));
++
++ /* horizontal window 1 control */
++ gc08r.whole = 0x131f0000;
++ writel(gc08r.whole, GC08R(register_base));
++
++ /* vertical window 1 control */
++ gc09r.whole = 0x12570000;
++ writel(gc09r.whole, GC09R(register_base));
++
++ /* horizontal display 1 control */
++ gc02r.whole = 0x320041e;
++ writel(gc02r.whole, GC02R(register_base));
++
++ /* vertical display 1 control */
++ gc03r.whole = 0x2570273;
++ writel(gc03r.whole, GC03R(register_base));
++
++ /* horizontal sync 1 control */
++ gc04r.whole = 0x3c70347;
++ writel(gc04r.whole, GC04R(register_base));
++
++ /* vertical sync 1 control */
++ gc05r.whole = 0x25d0259;
++ writel(gc05r.whole, GC05R(register_base));
++
++ /* graphics controller CRT control */
++ gc01r.whole = 0x800;
++ writel(gc01r.whole, GC01R(register_base));
++
++ /* PLL 2 programming */
++ pm06r.whole = 0xE90830;
++ writel(pm06r.whole, PM06R(register_base));
++
++ /* graphics controller 1 register
++ * o GC1 clock source is PLL 2.
++ * o hardware cursor is disabled.
++ */
++ gc00r.whole = 0x10000C8 | 0x20000;
++ writel(gc00r.whole, GC00R(register_base));
++
++#if 0
++ /* alternate horizontal window 1 control */
++ writel(0, GC0AR(register_base));
++
++ /* alternate vertical window 1 control */
++ writel(0, GC0BR(register_base));
++
++ /* window 1 start address */
++ writel(0x2004100, GC0CR(register_base));
++
++ /* alternate window 1 start address */
++ writel(0, GC0DR(register_base));
++
++ /* window 1 stride */
++ gc0er.whole = 0x5100048;
++ writel(gc0er.whole, GC0ER(register_base));
++
++ /* reserved register - ??? - */
++ writel(0x31f, GC0FR(register_base));
++#endif
++
++#if 0
++ /* hardware cursor 1 position */
++ writel(0, GC10R(register_base));
++
++ /* hardware cursor 1 start address and offset */
++ gc11r.whole = 0x5100048;
++ writel(gc11r.whole, GC11R(register_base));
++
++ /* hardware cursor 1 foreground color */
++ writel(0x00ffffff, GC12R(register_base));
++
++ /* hardware cursor 1 background color */
++ writel(0x00000000, GC13R(register_base));
++#endif
++
++ /* horizontal window 2 control */
++ gc28r.whole = 0x31f0000;
++ writel(gc28r.whole, GC28R(register_base));
++
++ /* vertical window 2 control */
++ gc29r.whole = 0x2570000;
++ writel(gc29r.whole, GC29R(register_base));
++
++ /* horizontal display 2 control */
++ gc22r.whole = 0x320041e;
++ writel(gc22r.whole, GC22R(register_base));
++
++ /* vertical display 2 control */
++ gc23r.whole = 0x2570273;
++ writel(gc23r.whole, GC23R(register_base));
++
++ /* horizontal sync 2 control */
++ gc24r.whole = 0x3c70347;
++ writel(gc24r.whole, GC24R(register_base));
++
++ /* vertical sync 2 control */
++ gc25r.whole = 0x25d0259;
++ writel(gc25r.whole, GC25R(register_base));
++
++ /* graphics controller CRT control */
++ gc01r.whole = 0x800;
++ writel(gc01r.whole, GC01R(register_base));
++
++ /* PLL 3 programming */
++ pm07r.whole = 0xE90830;
++ writel(pm07r.whole, PM07R(register_base));
++
++ /* graphics controller 2 register
++ * o GC2 clock source is PLL 3.
++ * o hardware cursor is disabled.
++ */
++ gc20r.whole = 0x10000C8 | 0x30000;
++ writel(gc20r.whole, GC20R(register_base));
++
++ /*
++ * Enable PLL2 and PLL3 in the PM Register
++ */
++ pm00r.part.pll2_enbl = 0x1;
++ pm00r.part.pll3_enbl = 0x1;
++ writel(pm00r.whole, PM00R(register_base));
++
++ spin_unlock_irqrestore(lock, flags);
++}
++
++
++/****
++ * initialize graphics engine.
++ */
++static void
++ge_reset(unsigned long register_base)
++{
++ /* drawing command register */
++ writel(0, GE00R(register_base));
++
++ /* promary width and height register */
++ writel(0, GE01R(register_base));
++
++ /* primary destination address register */
++ writel(0, GE02R(register_base));
++
++ /* primary source XY register */
++ writel(0, GE03R(register_base));
++
++ /* primary color compare register */
++ writel(0, GE04R(register_base));
++
++ /* primary clip left/top register */
++ writel(0, GE05R(register_base));
++
++ /* primary clip right/bottom register */
++ writel(0, GE06R(register_base));
++
++ /* primary source and pattern offset register */
++ writel(0, GE07R(register_base));
++
++ /* primary foreground color register/rectangle fill color depth */
++ writel(0, GE08R(register_base));
++
++ /* source stride/offset register */
++ writel(0, GE09R(register_base));
++
++ /* destination stride register and color depth */
++ writel(0, GE0AR(register_base));
++
++ /* image base address register */
++ writel(0, GE0BR(register_base));
++}
++
++/****
++ * initialize Color Palette 1.
++ */
++static void
++cp1_reset(unsigned long addr_info)
++{
++ int i;
++
++ for (i = 0; i < 256; i++)
++ writel(0, C1xxR(addr_info, i));
++}
++
++
++/*
++ * Below functions are called from the skeleton
++ */
++void mq200_external_setpal(unsigned regno, unsigned long color, unsigned long addr)
++{
++ writel(color,C1xxR(addr,regno));
++}
++
++void mq200_external_setqmode(struct mq200_monitor_info* info,
++ unsigned long addr, spinlock_t *lock)
++{
++ dc_reset(addr); /* device configuration */
++
++ power_state_transition(addr, 0); /* transition to D0 state */
++
++ pmu_reset(addr); /* power management unit */
++
++ miu_reset(addr); /* memory interface unit */
++
++ ge_reset(addr); /* graphics engine */
++
++ fpctrl_reset(addr); /* reset the panel settings */
++
++ gc1_gc2_reset(addr, lock); /* graphics controller 1 and 2 */
++
++ cp1_reset(addr); /* color palette 1 */
++
++ mq200_external_ondisplay(addr); /* LCD and CRT */
++}
++
++void mq200_external_offdisplay(unsigned long addr)
++{
++ /*
++ * Move the MQ200 to D3 mode
++ */
++ power_state_transition(addr, 3);
++}
++
++/**
++ * to be called after mq200_external_setqmode
++ */
++void mq200_external_ondisplay (unsigned long addr)
++{
++ /*
++ * Set the framebuffer details
++ */
++ union gc00r gc00r;
++ union gc01r gc01r;
++ union gc20r gc20r;
++ union fp00r fp00r;
++
++ /* enable LCD for GC2 */
++ fp00r.whole = readl(FP00R(addr));
++ fp00r.whole &= 0xfffffffc;
++
++ gc20r.whole = readl(GC20R(addr));
++
++ if(!(gc20r.whole & 0x1)) {
++ gc20r.whole |= 0x1;
++ writel(gc20r.whole, GC20R(addr));
++ }
++
++ fp00r.whole |= 0x3;
++ writel(fp00r.whole, FP00R(addr));
++
++ /* enable CRT for GC1 */
++ gc00r.whole = readl(GC00R(addr));
++
++ if(!(gc00r.whole & 0x1)) {
++ gc00r.whole |= 0x1;
++ writel(gc00r.whole, GC00R(addr));
++ }
++
++ gc01r.whole = readl(GC01R(addr));
++ gc01r.whole &= 0xfffffffc;
++
++ gc01r.whole |= 0x1;
++ writel(gc01r.whole, GC01R(addr));
++
++}
++
++int mq200_external_probe(unsigned long addr)
++{
++ union pc00r pc00r;
++ if(readl(PMR(addr)) != PMR_VALUE)
++ return 0;
++
++ pc00r.whole = readl(PC00R(addr));
++ printk(KERN_INFO "mq200 video driver found Vendor: 0x%X Device: 0x%X\n",
++ pc00r.part.device, pc00r.part.vendor);
++ return 1;
++}
+diff -uNr linux-2.6.21.vanilla/drivers/video/mq200/mq_skeleton.c linux-2.6.21/drivers/video/mq200/mq_skeleton.c
+--- linux-2.6.21.vanilla/drivers/video/mq200/mq_skeleton.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.21/drivers/video/mq200/mq_skeleton.c 2007-05-01 17:02:17.000000000 +0200
+@@ -0,0 +1,398 @@
++/*
++ * Author: Holger Hans Peter Freyther
++ *
++ *
++ * This implements the frame buffer driver interface to communicate
++ * with the kernel.
++ * It uses the mq200 routines from the ucLinux driver from Lineo
++ *
++ * 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/autoconf.h>
++#include <linux/platform_device.h>
++#include <linux/module.h>
++#include <linux/fb.h>
++#include <linux/types.h>
++#include <linux/spinlock.h>
++
++#include "mq200_data.h"
++
++#if CONFIG_SA1100_SIMPAD
++/*
++ * Siemens SIMpad specefic data
++ */
++#include <asm/arch/simpad.h>
++#include <asm/arch/hardware.h>
++
++#define MQ200_REGIONS simpad_mq200_regions
++#define MQ200_MONITOR simpad_mq200_panel
++
++static struct mq200_io_regions simpad_mq200_regions = {
++ .fb_size = MQ200_FB_SIZE,
++ .phys_mmio_base = 0x4be00000,
++ .virt_mmio_base = 0xf2e00000,
++ .phys_fb_base = 0x4b800000,
++ .virt_fb_base = 0xf2800000,
++};
++
++static struct mq200_monitor_info simpad_mq200_panel = {
++ .horizontal_res = 800,
++ .vertical_res = 600,
++ .depth = 16,
++ .refresh = 60,
++ .line_length = 1600,
++ .flags = 0x00130004,
++};
++
++extern long get_cs3_shadow(void);
++extern void set_cs3_bit(int value);
++extern void clear_cs3_bit(int value);
++#endif
++
++
++
++struct mq200_info {
++ struct fb_info fb_info;
++ struct mq200_io_regions io_regions;
++ struct mq200_monitor_info monitor_info;
++
++ /* palette */
++ u32 pseudo_palette[17]; /* 16 colors + 1 in reserve not that well documented... */
++ spinlock_t lock;
++};
++
++
++
++static int mq200_blank( int blank_mode, struct fb_info *info )
++{
++#ifdef CONFIG_SA1100_SIMPAD
++ if(blank_mode ){
++ clear_cs3_bit(DISPLAY_ON);
++ }else {
++ set_cs3_bit(DISPLAY_ON);
++ }
++#endif
++ return 0;
++}
++
++
++static int mq200_check_var(struct fb_var_screeninfo *var,
++ struct fb_info *info )
++{ /* TODO do we need sanity checks here */
++ return 0;
++}
++
++
++static int mq200_set_par( struct fb_info *info )
++{
++ /* TODO set paraemeter */
++ return 0;
++}
++
++static int mq200_setcolreg(unsigned regno, unsigned red, unsigned green,
++ unsigned blue, unsigned transp,
++ struct fb_info *info )
++{
++ struct mq200_info *p;
++ unsigned long color;
++ u32* pal = info->pseudo_palette;
++
++ p = info->par;
++
++ if(regno > 255 )
++ return 1;
++
++ switch( info->var.bits_per_pixel ){
++ case 16:
++ pal[regno] =
++ ((red & 0xf800) >> 0) |
++ ((green & 0xf800) >> 5) | ((blue & 0xf800) >> 11);
++ break;
++ case 24:
++ pal[regno] =
++ ((red & 0xff00) << 8) |
++ ((green & 0xff00)) | ((blue & 0xff00) >> 8);
++ break;
++ case 32:
++ pal[regno] =
++ ((red & 0xff00) >> 8) |
++ ((green & 0xff00)) | ((blue & 0xff00) << 8);
++ break;
++ default:
++ break;
++ }
++
++ red &= 0xFF;
++ green &= 0xFF;
++ blue &= 0xFF;
++
++ color = red | (green << 8) | (blue << 16);
++ mq200_external_setpal(regno, color, p->io_regions.virt_mmio_base);
++
++ return 0;
++}
++
++
++static struct fb_ops mq200_ops = {
++ .owner = THIS_MODULE,
++ .fb_check_var = mq200_check_var,
++ .fb_set_par = mq200_set_par,
++ .fb_setcolreg = mq200_setcolreg,
++#ifdef FB_SOFT_CURSOR
++ .fb_cursor = soft_cursor, /* FIXME use hardware cursor */
++#endif
++ .fb_fillrect = cfb_fillrect,
++ .fb_copyarea = cfb_copyarea,
++ .fb_imageblit = cfb_imageblit,
++ .fb_blank = mq200_blank,
++};
++
++
++/*********************************************************************
++ *
++ * Device driver and module init code
++ * this will register to the fb layer later
++ *
++ *********************************************************************/
++static void mq200_internal_init_color( struct fb_bitfield* red,
++ struct fb_bitfield* green,
++ struct fb_bitfield* blue,
++ int bpp )
++{
++ switch ( bpp )
++ {
++ case 16:
++ red->offset = 11;
++ green->offset = 5;
++ blue->offset = 0;
++
++ red->length = 5;
++ green->length = 6;
++ blue->length = 5;
++ break;
++ case 24:
++ red->offset = 16;
++ green->offset = 8;
++ blue->offset = 0;
++
++ red->length = 8;
++ green->length = 8;
++ blue->length = 8;
++ break;
++ case 32:
++ red->offset = 0;
++ green->offset = 8;
++ blue->offset = 16;
++
++ red->length = 8;
++ green->length = 8;
++ blue->length = 8;
++ case 8: /* fall through */
++ default:
++ red->offset = green->offset = blue->offset = 0;
++ red->length = green->length = blue->length = bpp;
++ break;
++ }
++
++}
++
++
++static struct mq200_info* __init mq200_internal_init_fbinfo(void)
++{
++ struct mq200_info *info = NULL;
++
++ info = (struct mq200_info*)kmalloc(sizeof(*info), GFP_KERNEL);
++ if(!info)
++ return NULL;
++
++ /*
++ * Initialize memory
++ */
++ memset(info, 0, sizeof(struct mq200_info) );
++ spin_lock_init(&info->lock);
++
++ /* set the base IO addresses */
++ info->io_regions = MQ200_REGIONS;
++ info->monitor_info = MQ200_MONITOR;
++
++ info->fb_info.screen_base = (char *)info->io_regions.virt_fb_base;
++
++ /* fb_fix_screeninfo filling */
++ strcpy(info->fb_info.fix.id, "MQ200_FB" );
++ info->fb_info.fix.smem_start = info->io_regions.phys_fb_base;
++ info->fb_info.fix.smem_len = info->io_regions.fb_size; /* - CURSOR_IMAGE */
++ info->fb_info.fix.mmio_start = info->io_regions.phys_mmio_base;
++ info->fb_info.fix.mmio_len = MQ200_REGS_SIZE;
++ info->fb_info.fix.type = FB_TYPE_PACKED_PIXELS;
++ info->fb_info.fix.accel = FB_ACCEL_NONE;
++ info->fb_info.fix.line_length = MQ200_MONITOR_LINE_LENGTH(info);
++
++ if(MQ200_MONITOR_DEPTH(info) <= 8 )
++ info->fb_info.fix.visual = FB_VISUAL_PSEUDOCOLOR;
++ else if( MQ200_MONITOR_DEPTH(info) >= 16 )
++ info->fb_info.fix.visual = FB_VISUAL_DIRECTCOLOR;
++ else
++ panic("Calling mq200 with wrong display data\n");
++
++ /* set the variable screen info */
++ info->fb_info.var.xres = MQ200_MONITOR_HORI_RES(info);
++ info->fb_info.var.yres = MQ200_MONITOR_VERT_RES(info);
++ info->fb_info.var.xres_virtual = MQ200_MONITOR_HORI_RES(info);
++ info->fb_info.var.yres_virtual = MQ200_MONITOR_VERT_RES(info);
++ info->fb_info.var.bits_per_pixel = MQ200_MONITOR_DEPTH(info);
++
++ mq200_internal_init_color(&info->fb_info.var.red,
++ &info->fb_info.var.green,
++ &info->fb_info.var.blue,
++ MQ200_MONITOR_DEPTH(info) );
++
++ info->fb_info.var.transp.length = info->fb_info.var.transp.offset = 0;
++ info->fb_info.var.height = info->fb_info.var.width = -1;
++
++ info->fb_info.var.vmode = FB_VMODE_NONINTERLACED;
++ info->fb_info.var.pixclock = 10000;
++ info->fb_info.var.left_margin = info->fb_info.var.right_margin = 16;
++ info->fb_info.var.upper_margin = info->fb_info.var.lower_margin = 16;
++ info->fb_info.var.hsync_len = info->fb_info.var.vsync_len = 8;
++
++ info->fb_info.var.nonstd = 0;
++ info->fb_info.var.activate = FB_ACTIVATE_NOW;
++ info->fb_info.var.accel_flags = 0;
++
++ return info;
++}
++
++
++extern void mq200_register_attributes(struct device* );
++/*
++ * gets called from the bus
++ * we will register our framebuffer from here
++ */
++static int __init mq200_probe(struct device *dev)
++{
++ struct mq200_info *info = NULL;
++ int retv= 0;
++
++ info = mq200_internal_init_fbinfo();
++ if(!mq200_external_probe(info->io_regions.virt_mmio_base))
++ goto error_out;
++
++ GPDR |= (1<<3);
++ GAFR &= ~(1<<3);
++ GPSR |= (1<<3);
++
++ mq200_external_setqmode(&info->monitor_info,
++ info->io_regions.virt_mmio_base,
++ &info->lock);
++
++ info->fb_info.fbops = &mq200_ops;
++ info->fb_info.flags = FBINFO_FLAG_DEFAULT;
++
++ mq200_check_var(&info->fb_info.var, &info->fb_info );
++
++ fb_alloc_cmap(&info->fb_info.cmap, 1 << MQ200_MONITOR_DEPTH(info), 0 );
++
++ info->fb_info.pseudo_palette = (void*)info->pseudo_palette;
++
++ /* save the pointer to the mq200 struct in var */
++ info->fb_info.par = info;
++
++ retv = register_framebuffer(&info->fb_info );
++ if(retv < 0)
++ goto error_out;
++
++
++ /* will get unset if retv != 0 */
++ dev_set_drvdata(dev, info );
++ return retv;
++
++/*
++ * Free the info and exit
++ */
++error_out:
++ kfree(info);
++ return -EINVAL;
++}
++
++#ifdef CONFIG_PM
++static struct mq200_info* get_mq200_info( struct device *dev)
++{
++ return dev_get_drvdata(dev);
++}
++
++static unsigned long get_mmio_base( struct device *dev )
++{
++ struct mq200_info *info = get_mq200_info(dev);
++ return info->io_regions.virt_mmio_base;
++}
++
++static struct mq200_monitor_info* get_monitor_info( struct device *dev)
++{
++ struct mq200_info *info = get_mq200_info(dev);
++ return &info->monitor_info;
++}
++
++static spinlock_t* get_spinlock( struct device *dev)
++{
++ return &get_mq200_info(dev)->lock;
++}
++
++/*
++ * FIXME: make sure we only call mq200_external_offdisplay only once
++ * a 2nd time will hang the kernel -zecke
++ *
++ * FIXME: save the content of the framebuffer inside dev->saved_state
++ * so on resume we can memcpy it back into the buffer and userspace
++ * does not need to redraw
++ *
++ * functions for suspending and resuming
++ */
++static int mq200_suspend(struct device *dev, pm_message_t state)
++{
++
++ mq200_external_offdisplay( get_mmio_base(dev) );
++ clear_cs3_bit(DISPLAY_ON);
++
++
++ return 0;
++}
++
++static int mq200_resume(struct device *dev)
++{
++ unsigned long mem = get_mmio_base(dev);
++ struct mq200_monitor_info *monitor = get_monitor_info(dev);
++ mq200_external_setqmode(monitor, mem, get_spinlock(dev) );
++
++
++ /*
++ * Set display on if it was on
++ */
++ set_cs3_bit(DISPLAY_ON);
++
++ return 0;
++}
++
++
++#endif
++
++
++static struct device_driver mq200fb_driver = {
++ .name = "simpad-mq200",
++ .bus = &platform_bus_type,
++ .probe = mq200_probe, /* will be called after we've registered the driver */
++ .suspend = mq200_suspend,
++ .resume = mq200_resume
++};
++
++int __devinit mq200_init(void)
++{
++ return driver_register(&mq200fb_driver);
++}
++
++module_init(mq200_init);
++MODULE_DESCRIPTION("MQ200 framebuffer driver");
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Holger Hans Peter Freyther");
diff --git a/recipes/linux/linux/simpad/linux-2.6.21-SIMpad-net-shared-irq.patch b/recipes/linux/linux/simpad/linux-2.6.21-SIMpad-net-shared-irq.patch
new file mode 100644
index 0000000000..e925781ccd
--- /dev/null
+++ b/recipes/linux/linux/simpad/linux-2.6.21-SIMpad-net-shared-irq.patch
@@ -0,0 +1,63 @@
+diff -uNr linux-2.6.21.vanilla/drivers/net/pcmcia/pcnet_cs.c linux-2.6.21/drivers/net/pcmcia/pcnet_cs.c
+--- linux-2.6.21.vanilla/drivers/net/pcmcia/pcnet_cs.c 2007-05-29 21:35:00.000000000 +0200
++++ linux-2.6.21/drivers/net/pcmcia/pcnet_cs.c 2007-05-30 17:51:21.000000000 +0200
+@@ -26,6 +26,8 @@
+ CCAE support. Drivers merged back together, and shared-memory
+ Socket EA support added, by Ken Raeburn, September 1995.
+
++ mrdata: -added shared irq
++
+ ======================================================================*/
+
+ #include <linux/kernel.h>
+@@ -254,7 +256,7 @@
+ info->p_dev = link;
+ link->priv = dev;
+
+- link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
++ link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
+ link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+ link->conf.Attributes = CONF_ENABLE_IRQ;
+ link->conf.IntType = INT_MEMORY_AND_IO;
+diff -uNr linux-2.6.21.vanilla/drivers/net/wireless/hostap/hostap_cs.c linux-2.6.21/drivers/net/wireless/hostap/hostap_cs.c
+--- linux-2.6.21.vanilla/drivers/net/wireless/hostap/hostap_cs.c 2007-05-29 21:35:00.000000000 +0200
++++ linux-2.6.21/drivers/net/wireless/hostap/hostap_cs.c 2007-05-30 17:53:20.000000000 +0200
+@@ -1,3 +1,8 @@
++/*
++ *
++ * mrdata: -added shared irq
++ */
++
+ #define PRISM2_PCCARD
+
+ #include <linux/module.h>
+@@ -695,7 +700,7 @@
+ * irq structure is initialized.
+ */
+ if (link->conf.Attributes & CONF_ENABLE_IRQ) {
+- link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
++ link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_FIRST_SHARED | IRQ_HANDLE_PRESENT;
+ link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+ link->irq.Handler = prism2_interrupt;
+ link->irq.Instance = dev;
+diff -uNr linux-2.6.21.vanilla/drivers/net/wireless/orinoco_cs.c linux-2.6.21/drivers/net/wireless/orinoco_cs.c
+--- linux-2.6.21.vanilla/drivers/net/wireless/orinoco_cs.c 2007-05-29 21:35:00.000000000 +0200
++++ linux-2.6.21/drivers/net/wireless/orinoco_cs.c 2007-05-30 17:52:19.000000000 +0200
+@@ -8,6 +8,8 @@
+ * cards such as the 3Com AirConnect and Ericsson WLAN.
+ *
+ * Copyright notice & release notes in file orinoco.c
++ *
++ * mrdata: added shared irq
+ */
+
+ #define DRIVER_NAME "orinoco_cs"
+@@ -120,7 +122,7 @@
+ link->priv = dev;
+
+ /* Interrupt setup */
+- link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
++ link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_FIRST_SHARED | IRQ_HANDLE_PRESENT;
+ link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+ link->irq.Handler = orinoco_interrupt;
+ link->irq.Instance = dev;
diff --git a/recipes/linux/linux/simpad/linux-2.6.21-SIMpad-pcmcia.patch b/recipes/linux/linux/simpad/linux-2.6.21-SIMpad-pcmcia.patch
new file mode 100644
index 0000000000..6ff5e37dcf
--- /dev/null
+++ b/recipes/linux/linux/simpad/linux-2.6.21-SIMpad-pcmcia.patch
@@ -0,0 +1,162 @@
+diff -uNr linux-2.6.21.vanilla/drivers/pcmcia/cs.c linux-2.6.21/drivers/pcmcia/cs.c
+--- linux-2.6.21.vanilla/drivers/pcmcia/cs.c 2007-05-30 18:00:30.000000000 +0200
++++ linux-2.6.21/drivers/pcmcia/cs.c 2007-05-30 18:10:20.000000000 +0200
+@@ -10,6 +10,8 @@
+ * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
+ *
+ * (C) 1999 David A. Hinds
++ *
++ * mrdata: -added suspend fix
+ */
+
+ #include <linux/module.h>
+@@ -60,6 +62,10 @@
+ INT_MODULE_PARM(unreset_delay, 10); /* centiseconds */
+ INT_MODULE_PARM(unreset_check, 10); /* centiseconds */
+ INT_MODULE_PARM(unreset_limit, 30); /* unreset_check's */
++// INT_MODULE_PARM(unreset_delay, 20); /* centiseconds */
++// INT_MODULE_PARM(unreset_check, 100); /* centiseconds */
++// INT_MODULE_PARM(unreset_limit, 300); /* unreset_check's */
++
+
+ /* Access speed for attribute memory windows */
+ INT_MODULE_PARM(cis_speed, 300); /* ns */
+@@ -365,6 +371,7 @@
+ skt->ops->set_socket(skt, &skt->socket);
+
+ msleep(unreset_delay * 10);
++
+ for (i = 0; i < unreset_limit; i++) {
+ skt->ops->get_status(skt, &status);
+
+@@ -430,7 +437,7 @@
+
+ msleep(initial_delay * 10);
+
+- for (i = 0; i < 100; i++) {
++ for (i = 0; i < 100; i++) {
+ skt->ops->get_status(skt, &status);
+ if (!(status & SS_DETECT))
+ return CS_NO_CARD;
+diff -uNr linux-2.6.21.vanilla/drivers/pcmcia/sa1100_generic.c linux-2.6.21/drivers/pcmcia/sa1100_generic.c
+--- linux-2.6.21.vanilla/drivers/pcmcia/sa1100_generic.c 2007-05-30 18:00:30.000000000 +0200
++++ linux-2.6.21/drivers/pcmcia/sa1100_generic.c 2007-05-30 18:00:40.000000000 +0200
+@@ -28,6 +28,9 @@
+ the provisions above, a recipient may use your version of this
+ file under either the MPL or the GPL.
+
++ 2007 mrnice: added thesings changes from device_driver
++ to platform_driver - many thx to thesing
++
+ ======================================================================*/
+
+ #include <linux/module.h>
+@@ -81,13 +84,15 @@
+ return ret;
+ }
+
+-static struct device_driver sa11x0_pcmcia_driver = {
+- .probe = sa11x0_drv_pcmcia_probe,
+- .remove = soc_common_drv_pcmcia_remove,
+- .name = "sa11x0-pcmcia",
+- .bus = &platform_bus_type,
+- .suspend = pcmcia_socket_dev_suspend,
+- .resume = pcmcia_socket_dev_resume,
++static struct platform_driver sa11x0_pcmcia_driver = {
++ .driver = {
++ .name = "sa11x0-pcmcia",
++ .probe = sa11x0_drv_pcmcia_probe,
++ .remove = soc_common_drv_pcmcia_remove,
++ .suspend= pcmcia_socket_dev_suspend,
++ .resume = pcmcia_socket_dev_resume,
++ //.bus = &platform_bus_type,
++ },
+ };
+
+ /* sa11x0_pcmcia_init()
+@@ -100,7 +105,7 @@
+ */
+ static int __init sa11x0_pcmcia_init(void)
+ {
+- return driver_register(&sa11x0_pcmcia_driver);
++ return platform_driver_register(&sa11x0_pcmcia_driver);
+ }
+
+ /* sa11x0_pcmcia_exit()
+@@ -110,7 +115,7 @@
+ */
+ static void __exit sa11x0_pcmcia_exit(void)
+ {
+- driver_unregister(&sa11x0_pcmcia_driver);
++ platform_driver_unregister(&sa11x0_pcmcia_driver);
+ }
+
+ MODULE_AUTHOR("John Dorsey <john+@cs.cmu.edu>");
+diff -uNr linux-2.6.21.vanilla/drivers/pcmcia/sa1100_simpad.c linux-2.6.21/drivers/pcmcia/sa1100_simpad.c
+--- linux-2.6.21.vanilla/drivers/pcmcia/sa1100_simpad.c 2007-05-30 18:00:30.000000000 +0200
++++ linux-2.6.21/drivers/pcmcia/sa1100_simpad.c 2007-05-30 18:08:53.000000000 +0200
+@@ -3,6 +3,8 @@
+ *
+ * PCMCIA implementation routines for simpad
+ *
++ * mrdata: -added cs3_ro stuff to get fix voltage issue
++ *
+ */
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+@@ -14,7 +16,8 @@
+ #include <asm/irq.h>
+ #include <asm/arch/simpad.h>
+ #include "sa1100_generic.h"
+-
++
++extern long get_cs3_ro(void);
+ extern long get_cs3_shadow(void);
+ extern void set_cs3_bit(int value);
+ extern void clear_cs3_bit(int value);
+@@ -25,7 +28,6 @@
+
+ static int simpad_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
+ {
+-
+ clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1);
+
+ skt->irq = IRQ_GPIO_CF_IRQ;
+@@ -47,21 +49,15 @@
+ struct pcmcia_state *state)
+ {
+ unsigned long levels = GPLR;
+- long cs3reg = get_cs3_shadow();
++ long cs3_ro_reg = get_cs3_ro();
+
+- state->detect=((levels & GPIO_CF_CD)==0)?1:0;
+- state->ready=(levels & GPIO_CF_IRQ)?1:0;
+- state->bvd1=1; /* Not available on Simpad. */
+- state->bvd2=1; /* Not available on Simpad. */
+- state->wrprot=0; /* Not available on Simpad. */
+-
+- if((cs3reg & 0x0c) == 0x0c) {
+- state->vs_3v=0;
+- state->vs_Xv=0;
+- } else {
+- state->vs_3v=1;
+- state->vs_Xv=0;
+- }
++ state->detect = ((levels & GPIO_CF_CD) == 0) ? 1 : 0 ;
++ state->ready = (levels & GPIO_CF_IRQ) ? 1 : 0 ;
++ state->bvd1 = (cs3_ro_reg & PCMCIA_BVD1) ? 1 : 0 ; /* alt: =1 Not available on Simpad. */
++ state->bvd2 = (cs3_ro_reg & PCMCIA_BVD2) ? 1 : 0 ; /* alt: =1 Not available on Simpad. */
++ state->wrprot = 0 ; /* Not available on Simpad. */
++ state->vs_3v = (cs3_ro_reg & PCMCIA_VS1) ? 0 : 1 ;
++ state->vs_Xv = (cs3_ro_reg & PCMCIA_VS2) ? 0 : 1 ;
+ }
+
+ static int
+@@ -104,6 +100,7 @@
+
+ static void simpad_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
+ {
++ clear_cs3_bit(PCMCIA_RESET);
+ soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
+ }
+
diff --git a/recipes/linux/linux/simpad/linux-2.6.21-SIMpad-serial-gpio_keys-and-cs3-ro.patch b/recipes/linux/linux/simpad/linux-2.6.21-SIMpad-serial-gpio_keys-and-cs3-ro.patch
new file mode 100644
index 0000000000..081afc8936
--- /dev/null
+++ b/recipes/linux/linux/simpad/linux-2.6.21-SIMpad-serial-gpio_keys-and-cs3-ro.patch
@@ -0,0 +1,332 @@
+diff -uNr linux-2.6.21.vanilla/arch/arm/mach-sa1100/simpad.c linux-2.6.21/arch/arm/mach-sa1100/simpad.c
+--- linux-2.6.21.vanilla/arch/arm/mach-sa1100/simpad.c 2007-05-30 18:00:29.000000000 +0200
++++ linux-2.6.21/arch/arm/mach-sa1100/simpad.c 2007-05-30 18:02:15.000000000 +0200
+@@ -1,5 +1,15 @@
+ /*
+ * linux/arch/arm/mach-sa1100/simpad.c
++ *
++ * 2007/04/11 mrdata:
++ * - insert simpad_uart_set_mctrl()
++ * simpad_uart_get_mctrl()
++ * - internal RS232/DECT/Bluetooth
++ * works again (based on 2.4 simpad-serial.patch)
++ * - added cs3_ro
++ *
++ * 2007/04/12 Bernhard Guillon:
++ * -added gpio_keys (based on h3000.c from hh.org)
+ */
+
+ #include <linux/module.h>
+@@ -9,6 +19,9 @@
+ #include <linux/proc_fs.h>
+ #include <linux/string.h>
+ #include <linux/pm.h>
++
++#include <linux/apm-emulation.h>
++
+ #include <linux/platform_device.h>
+ #include <linux/mtd/mtd.h>
+ #include <linux/mtd/partitions.h>
+@@ -27,12 +40,21 @@
+
+ #include <linux/serial_core.h>
+ #include <linux/ioport.h>
++#include <linux/input.h>
++#include <linux/gpio_keys.h>
+ #include <asm/io.h>
+
+ #include "generic.h"
+
++long cs3_ro;
+ long cs3_shadow;
+
++long get_cs3_ro(void)
++{
++ cs3_ro = *(CS3BUSTYPE *)(CS3_BASE);
++ return cs3_ro;
++}
++
+ long get_cs3_shadow(void)
+ {
+ return cs3_shadow;
+@@ -55,9 +77,12 @@
+ *(CS3BUSTYPE *)(CS3_BASE) = cs3_shadow;
+ }
+
++EXPORT_SYMBOL(get_cs3_ro);
++EXPORT_SYMBOL(get_cs3_shadow);
+ EXPORT_SYMBOL(set_cs3_bit);
+ EXPORT_SYMBOL(clear_cs3_bit);
+
++
+ static struct map_desc simpad_io_desc[] __initdata = {
+ { /* MQ200 */
+ .virtual = 0xf2800000,
+@@ -73,23 +98,71 @@
+ };
+
+
++static void simpad_uart_set_mctrl(struct uart_port *port, u_int mctrl)
++{
++ if (port->mapbase == _Ser1UTCR0) {
++ /* internal serial port (ttySA1, DECT/Bluetooth) */
++ if (mctrl & TIOCM_RTS) GPCR = GPIO_UART1_RTS;
++ else GPSR = GPIO_UART1_RTS;
++
++ if (mctrl & TIOCM_DTR) GPCR = GPIO_UART1_DTR;
++ else GPSR = GPIO_UART1_DTR;
++ }
++
++ else if (port->mapbase == _Ser3UTCR0) {
++ /* external serial port (ttySA0, RS232) */
++ if (mctrl & TIOCM_RTS) GPCR = GPIO_UART3_RTS;
++ else GPSR = GPIO_UART3_RTS;
++
++ if (mctrl & TIOCM_DTR) GPCR = GPIO_UART3_DTR;
++ else GPSR = GPIO_UART3_DTR;
++ }
++}
++
++
++static u_int simpad_uart_get_mctrl(struct uart_port *port)
++{
++ u_int ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR;
++
++ if (port->mapbase == _Ser1UTCR0) {
++ /* internal serial port (ttySA1, DECT/Bluetooth) */
++ int gplr = GPLR;
++ if (gplr & GPIO_UART1_DCD) ret &= ~TIOCM_CD;
++ if (gplr & GPIO_UART1_CTS) ret &= ~TIOCM_CTS;
++ if (gplr & GPIO_UART1_DSR) ret &= ~TIOCM_DSR;
++ }
++
++ else if (port->mapbase == _Ser3UTCR0) {
++ /* external serial port (ttySA0, RS232) */
++ int gplr = GPLR;
++ if (gplr & GPIO_UART3_DCD) ret &= ~TIOCM_CD;
++ if (gplr & GPIO_UART3_CTS) ret &= ~TIOCM_CTS;
++ if (gplr & GPIO_UART3_DSR) ret &= ~TIOCM_DSR;
++ }
++ return ret;
++}
++
++
+ static void simpad_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
+ {
+- if (port->mapbase == (u_int)&Ser1UTCR0) {
+- if (state)
+- {
+- clear_cs3_bit(RS232_ON);
+- clear_cs3_bit(DECT_POWER_ON);
+- }else
+- {
+- set_cs3_bit(RS232_ON);
+- set_cs3_bit(DECT_POWER_ON);
+- }
+- }
++ if (port->mapbase == (u_int)&Ser3UTCR0) {
++ if (state)
++ {
++ clear_cs3_bit(RS232_ON);
++ /* clear_cs3_bit(DECT_POWER_ON); */
++ }else
++ {
++ set_cs3_bit(RS232_ON);
++ /* set_cs3_bit(DECT_POWER_ON); */
++ }
++ }
+ }
+
++
+ static struct sa1100_port_fns simpad_port_fns __initdata = {
+- .pm = simpad_uart_pm,
++ .set_mctrl = simpad_uart_set_mctrl,
++ .get_mctrl = simpad_uart_get_mctrl,
++ .pm = simpad_uart_pm,
+ };
+
+
+@@ -135,7 +208,6 @@
+ };
+
+
+-
+ static void __init simpad_map_io(void)
+ {
+ sa1100_map_io();
+@@ -144,13 +216,12 @@
+
+ set_cs3_bit (EN1 | EN0 | LED2_ON | DISPLAY_ON | RS232_ON |
+ ENABLE_5V | RESET_SIMCARD | DECT_POWER_ON);
+-
+-
++
+ sa1100_register_uart_fns(&simpad_port_fns);
+ sa1100_register_uart(0, 3); /* serial interface */
+ sa1100_register_uart(1, 1); /* DECT */
+
+- // Reassign UART 1 pins
++ /* Reassign UART 1 pins */
+ GAFR |= GPIO_UART_TXD | GPIO_UART_RXD;
+ GPDR |= GPIO_UART_TXD | GPIO_LDD13 | GPIO_LDD15;
+ GPDR &= ~GPIO_UART_RXD;
+@@ -160,7 +231,6 @@
+ * Set up registers for sleep mode.
+ */
+
+-
+ PWER = PWER_GPIO0| PWER_RTC;
+ PGSR = 0x818;
+ PCFR = 0;
+@@ -171,9 +241,10 @@
+ sa11x0_set_mcp_data(&simpad_mcp_data);
+ }
+
++
+ static void simpad_power_off(void)
+ {
+- local_irq_disable(); // was cli
++ local_irq_disable(); /* was cli */
+ set_cs3(0x800); /* only SD_MEDIAQ */
+
+ /* disable internal oscillator, float CS lines */
+@@ -191,31 +262,52 @@
+ while(1);
+
+ local_irq_enable(); /* we won't ever call it */
++}
+
+
+-}
++/*
++ * gpio_keys
++*/
++
++static struct gpio_keys_button simpad_button_table[] = {
++ { KEY_POWER, IRQ_GPIO_POWER_BUTTON, 1, "power button" },
++};
++
++static struct gpio_keys_platform_data simpad_keys_data = {
++ .buttons = simpad_button_table,
++ .nbuttons = ARRAY_SIZE(simpad_button_table),
++};
++
++static struct platform_device simpad_keys = {
++ .name = "gpio-keys",
++ .dev = {
++ .platform_data = &simpad_keys_data,
++ },
++};
+
+
+ /*
+ * MediaQ Video Device
+ */
++
+ static struct platform_device simpad_mq200fb = {
+ .name = "simpad-mq200",
+ .id = 0,
+ };
+
++
+ static struct platform_device *devices[] __initdata = {
+- &simpad_mq200fb
++ &simpad_keys,
++ &simpad_mq200fb,
+ };
+
+
+-
+ static int __init simpad_init(void)
+ {
+ int ret;
+
+ pm_power_off = simpad_power_off;
+-
++
+ ret = platform_add_devices(devices, ARRAY_SIZE(devices));
+ if(ret)
+ printk(KERN_WARNING "simpad: Unable to register mq200 framebuffer device");
+diff -uNr linux-2.6.21.vanilla/include/asm-arm/arch-sa1100/simpad.h linux-2.6.21/include/asm-arm/arch-sa1100/simpad.h
+--- linux-2.6.21.vanilla/include/asm-arm/arch-sa1100/simpad.h 2007-05-30 18:00:30.000000000 +0200
++++ linux-2.6.21/include/asm-arm/arch-sa1100/simpad.h 2007-05-30 18:02:56.000000000 +0200
+@@ -12,11 +12,12 @@
+ #define __ASM_ARCH_SIMPAD_H
+
+
+-#define GPIO_UART1_RTS GPIO_GPIO14
++#define GPIO_UART1_RTS GPIO_GPIO9
+ #define GPIO_UART1_DTR GPIO_GPIO7
+ #define GPIO_UART1_CTS GPIO_GPIO8
+ #define GPIO_UART1_DCD GPIO_GPIO23
+ #define GPIO_UART1_DSR GPIO_GPIO6
++#define GPIO_UART1_RI GPIO_GPIO19
+
+ #define GPIO_UART3_RTS GPIO_GPIO12
+ #define GPIO_UART3_DTR GPIO_GPIO16
+@@ -48,9 +49,9 @@
+ #define GPIO_SMART_CARD GPIO_GPIO10
+ #define IRQ_GPIO_SMARD_CARD IRQ_GPIO10
+
+-// CS3 Latch is write only, a shadow is necessary
++// CS3 Latch is write only 16-bit , a shadow is necessary
+
+-#define CS3BUSTYPE unsigned volatile long
++#define CS3BUSTYPE unsigned volatile long
+ #define CS3_BASE 0xf1000000
+
+ #define VCC_5V_EN 0x0001 // For 5V PCMCIA
+@@ -70,43 +71,17 @@
+ #define ENABLE_5V 0x4000 // Enable 5V circuit
+ #define RESET_SIMCARD 0x8000
+
+-#define RS232_ENABLE 0x0440
+-#define PCMCIAMASK 0x402f
++// CS3 Latch is readable only 8-bit interest
+
++#define PCMCIA_BVD1 0x0001
++#define PCMCIA_BVD2 0x0002
++#define PCMCIA_VS1 0x0004 // PCMCIA card voltage select
++#define PCMCIA_VS2 0x0008 // PCMCIA card voltage select, if both are in high state -> 5V PCMCIA card
++#define LOCK_IND 0x0010
++#define CHARGING_STATE 0x0020 // Ladestatus
++#define PCMCIA_SHORT 0x0040 // low active
+
+-struct simpad_battery {
+- unsigned char ac_status; /* line connected yes/no */
+- unsigned char status; /* battery loading yes/no */
+- unsigned char percentage; /* percentage loaded */
+- unsigned short life; /* life till empty */
+-};
+-
+-/* These should match the apm_bios.h definitions */
+-#define SIMPAD_AC_STATUS_AC_OFFLINE 0x00
+-#define SIMPAD_AC_STATUS_AC_ONLINE 0x01
+-#define SIMPAD_AC_STATUS_AC_BACKUP 0x02 /* What does this mean? */
+-#define SIMPAD_AC_STATUS_AC_UNKNOWN 0xff
+-
+-/* These bitfields are rarely "or'd" together */
+-#define SIMPAD_BATT_STATUS_HIGH 0x01
+-#define SIMPAD_BATT_STATUS_LOW 0x02
+-#define SIMPAD_BATT_STATUS_CRITICAL 0x04
+-#define SIMPAD_BATT_STATUS_CHARGING 0x08
+-#define SIMPAD_BATT_STATUS_CHARGE_MAIN 0x10
+-#define SIMPAD_BATT_STATUS_DEAD 0x20 /* Battery will not charge */
+-#define SIMPAD_BATT_NOT_INSTALLED 0x20 /* For expansion pack batteries */
+-#define SIMPAD_BATT_STATUS_FULL 0x40 /* Battery fully charged (and connected to AC) */
+-#define SIMPAD_BATT_STATUS_NOBATT 0x80
+-#define SIMPAD_BATT_STATUS_UNKNOWN 0xff
+-
+-extern int simpad_get_battery(struct simpad_battery* );
++#define RS232_ENABLE 0x0440
++#define PCMCIAMASK 0x402f
+
+ #endif // __ASM_ARCH_SIMPAD_H
+-
+-
+-
+-
+-
+-
+-
+-
diff --git a/recipes/linux/linux/simpad/linux-2.6.21-SIMpad-ucb1x00-switches.patch b/recipes/linux/linux/simpad/linux-2.6.21-SIMpad-ucb1x00-switches.patch
new file mode 100644
index 0000000000..552bb8b223
--- /dev/null
+++ b/recipes/linux/linux/simpad/linux-2.6.21-SIMpad-ucb1x00-switches.patch
@@ -0,0 +1,359 @@
+diff -uNr linux-2.6.21.vanilla/drivers/mfd/Kconfig linux-2.6.21/drivers/mfd/Kconfig
+--- linux-2.6.21.vanilla/drivers/mfd/Kconfig 2007-04-26 05:08:32.000000000 +0200
++++ linux-2.6.21/drivers/mfd/Kconfig 2007-05-29 12:56:32.000000000 +0200
+@@ -37,4 +37,7 @@
+ tristate "Touchscreen interface support"
+ depends on MCP_UCB1200 && INPUT
+
++config MCP_UCB1200_SWITCHES
++ tristate "SIMpad Switches support"
++ depends on MCP_UCB1200 && INPUT
+ endmenu
+diff -uNr linux-2.6.21.vanilla/drivers/mfd/Makefile linux-2.6.21/drivers/mfd/Makefile
+--- linux-2.6.21.vanilla/drivers/mfd/Makefile 2007-04-26 05:08:32.000000000 +0200
++++ linux-2.6.21/drivers/mfd/Makefile 2007-05-29 12:56:32.000000000 +0200
+@@ -8,7 +8,7 @@
+ obj-$(CONFIG_MCP_SA11X0) += mcp-sa11x0.o
+ obj-$(CONFIG_MCP_UCB1200) += ucb1x00-core.o
+ obj-$(CONFIG_MCP_UCB1200_TS) += ucb1x00-ts.o
+-
++obj-$(CONFIG_MCP_UCB1200_SWITCHES) += ucb1x00-switches.o
+ ifeq ($(CONFIG_SA1100_ASSABET),y)
+ obj-$(CONFIG_MCP_UCB1200) += ucb1x00-assabet.o
+ endif
+diff -Naur linux-2.6.21/drivers/mfd.old/ucb1x00-switches.c linux-2.6.21/drivers/mfd/ucb1x00-switches.c
+--- linux-2.6.21/drivers/mfd/ucb1x00-switches.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.21/drivers/mfd/ucb1x00-switches.c 2007-07-04 23:59:39.000000000 +0200
+@@ -0,0 +1,332 @@
++/*
++ * linux/drivers/mfd/ucb1x00-switches.c
++ *
++ * Copyright (C) 2007 Bernhard Guillon.
++ *
++ * 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.
++ *
++ * This driver is for the Switches of Siemens SIMpad (CL4,SL4,SLC), T-Sinus-Pad and
++ * Swisscom WP50 devices.
++ *
++ * Six switches are routed to GPIO pins on the UCB1300: S3 -- S8.
++ *
++ * This driver is based on the 2.4 ucb1x00-switches, the 2.6 ucb1x00-assabet
++ * and the ucb1x00-ts driver.
++ *
++ * 2007/06/21 mrdata:
++ * - create new thread kswd() to handle irq_events for ucb1300-gpio's
++ * - found out, that not every key-press or key-release
++ * generate a irq_event
++ * -> establish key_state handling
++ * key_state, key_state_last <-> KEY_PRESS, KEY_RELEASE
++ * -> after irq_event polling the ucb1300-gpio's till all keys
++ * in key_state = KEY_RELEASE
++ *
++ */
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/input.h>
++#include <linux/device.h>
++#include <linux/sched.h>
++#include <linux/freezer.h>
++#include <linux/kthread.h>
++
++#include <asm/dma.h>
++
++#include "ucb1x00.h"
++
++#define KEY_PRESS 1
++#define KEY_RELEASE 0
++
++static int key [6] = { KEY_PROG1,KEY_PROG2,KEY_UP,KEY_DOWN,KEY_LEFT,KEY_RIGHT };
++
++static unsigned short int key_state [6] = { 0, 0, 0, 0, 0, 0};
++static unsigned short int key_state_last [6] = { 1, 1, 1, 1, 1, 1};
++
++struct ucb1x00_switches {
++ struct input_dev *idev;
++ struct ucb1x00 *ucb;
++
++ wait_queue_head_t irq_wait;
++ struct task_struct *rtask;
++
++ int idx;
++
++ unsigned int valid:1;
++};
++
++static int ucb1x00_thread(void *_switches_id)
++{
++ unsigned short int this;
++ int idx_tmp;
++ int i;
++ struct ucb1x00_switches *switches = _switches_id;
++ struct input_dev *idev = switches->idev;
++ struct task_struct *tsk = current;
++ DECLARE_WAITQUEUE(wait, tsk);
++
++ add_wait_queue(&switches->irq_wait, &wait);
++
++ while (!kthread_should_stop())
++ {
++ signed long timeout;
++
++ if ((switches->idx >= 0) && (switches->idx <= 5) && (switches->valid == 1))
++ {
++ switches->valid = 0;
++
++ idx_tmp = switches->idx;
++
++ ucb1x00_enable(switches->ucb);
++
++ this = ~ucb1x00_io_read(switches->ucb);
++
++ ucb1x00_disable(switches->ucb);
++
++ if (key_state[idx_tmp] == KEY_RELEASE)
++ {
++ key_state_last[idx_tmp] = KEY_RELEASE;
++ key_state[idx_tmp] = KEY_PRESS;
++
++ input_report_key(idev, key[idx_tmp], KEY_PRESS);
++ input_sync(idev);
++ }
++
++ for (i = 0; i < 6; i++)
++ {
++ if ((key_state[i] == KEY_RELEASE) && (((this & (1 << i)) ? 1 : 0) == KEY_PRESS))
++ {
++ key_state_last[i] = KEY_RELEASE;
++ key_state[i] = KEY_PRESS;
++
++ input_report_key(idev, key[i], KEY_PRESS);
++ input_sync(idev);
++ }
++ }
++
++ for(;;)
++ {
++ ucb1x00_enable(switches->ucb);
++ this = ~ucb1x00_io_read(switches->ucb);
++ ucb1x00_disable(switches->ucb);
++
++ for (i = 0; i < 6; i++)
++ {
++ if ((key_state[i] == KEY_PRESS) && (((this & (1 << i)) ? 1 : 0) == KEY_RELEASE))
++ {
++ key_state_last[i] = KEY_PRESS;
++ key_state[i] = KEY_RELEASE;
++
++ input_report_key(idev, key[i], KEY_RELEASE);
++ input_sync(idev);
++ }
++
++ if ((key_state[i] == KEY_RELEASE) && (((this & (1 << i)) ? 1 : 0) == KEY_PRESS))
++ {
++ key_state_last[i] = KEY_RELEASE;
++ key_state[i] = KEY_PRESS;
++
++ input_report_key(idev, key[i], KEY_PRESS);
++ input_sync(idev);
++ }
++
++ }
++
++ // left loop, if no key press detect
++ if ((this | 0xff80) == 0xff80)
++ {
++ break;
++ }
++
++ set_task_state(tsk, TASK_INTERRUPTIBLE);
++
++ try_to_freeze();
++
++ timeout = HZ / 100;
++
++ schedule_timeout(timeout);
++ }
++ }
++
++ set_task_state(tsk, TASK_INTERRUPTIBLE);
++
++ try_to_freeze();
++
++ timeout = MAX_SCHEDULE_TIMEOUT;
++
++ schedule_timeout(timeout);
++ }
++
++ remove_wait_queue(&switches->irq_wait, &wait);
++
++ switches->rtask = NULL;
++
++ return 0;
++}
++
++
++static void ucb1x00_dev_irq(int idx, void *id)
++{
++ struct ucb1x00_switches *switches = id;
++
++ switches->idx = idx;
++ switches->valid = 1;
++
++ wake_up(&switches->irq_wait);
++}
++
++static int ucb1x00_switches_add(struct ucb1x00_dev *dev)
++{
++ struct ucb1x00_switches *switches;
++ struct input_dev *idev;
++ int err,i;
++
++ switches = kzalloc(sizeof(struct ucb1x00_switches), GFP_KERNEL);
++ idev = input_allocate_device();
++
++ if (!switches || !idev) {
++ err = -ENOMEM;
++ goto fail;
++ }
++
++ switches->ucb = dev->ucb;
++
++ idev->private = switches;
++ idev->name = "SIMpad Switches";
++ idev->id.product = switches->ucb->id;
++
++ __set_bit(EV_KEY, idev->evbit);
++ __set_bit(EV_REP, idev->evbit);
++ __set_bit(KEY_PROG1, idev->keybit);
++ __set_bit(KEY_PROG2, idev->keybit);
++ __set_bit(KEY_UP, idev->keybit);
++ __set_bit(KEY_DOWN, idev->keybit);
++ __set_bit(KEY_LEFT, idev->keybit);
++ __set_bit(KEY_RIGHT, idev->keybit);
++
++ err = input_register_device(idev);
++ if (err)
++ goto fail;
++ switches->idev = idev;
++ dev->priv = switches;
++
++ BUG_ON(switches->rtask);
++
++ init_waitqueue_head(&switches->irq_wait);
++
++ ucb1x00_enable(switches->ucb);
++
++ ucb1x00_io_set_dir(switches->ucb,
++ UCB_IO_0 | UCB_IO_1 | UCB_IO_2 |
++ UCB_IO_3 | UCB_IO_4 | UCB_IO_5,
++ UCB_IO_8 | UCB_IO_9);
++
++ ucb1x00_disable(switches->ucb);
++
++ for (i = 0; i < 6; ++i) {
++ ucb1x00_enable_irq(switches->ucb, i, UCB_RISING | UCB_FALLING);
++
++ if (ucb1x00_hook_irq(switches->ucb, i, ucb1x00_dev_irq, switches) < 0) {
++ printk(KERN_ERR "unable to hook IRQ for "
++ "UCB1300 SWITCH_%d\n", i);
++ return -EBUSY;
++ }
++ }
++
++ switches->rtask = kthread_run(ucb1x00_thread, switches, "kswd");
++ if (!IS_ERR(switches->rtask))
++ {
++ return 0;
++ }
++ else
++ {
++ input_unregister_device(switches->idev);
++
++ for (i = 5; i >= 0; --i) {
++ ucb1x00_disable_irq(switches->ucb, i, UCB_RISING | UCB_FALLING);
++
++ /* Only error conditions are ENOENT and EINVAL; silently
++ * ignore:
++ */
++ ucb1x00_free_irq(switches->ucb, i, NULL);
++ }
++ switches->rtask = NULL;
++ ucb1x00_disable(switches->ucb);
++ kfree(switches);
++
++ return -EFAULT;
++ }
++
++fail:
++ input_free_device(idev);
++ kfree(switches);
++ return err;
++
++}
++
++static void ucb1x00_switches_remove(struct ucb1x00_dev *dev)
++{
++ int i;
++ struct ucb1x00_switches *switches = dev->priv;
++
++ if (switches->rtask)
++ kthread_stop(switches->rtask);
++
++ switches->rtask = NULL;
++
++ input_unregister_device(switches->idev);
++
++ for (i = 5; i >= 0; --i) {
++ ucb1x00_disable_irq(switches->ucb, i, UCB_RISING | UCB_FALLING);
++
++ /* Only error conditions are ENOENT and EINVAL; silently
++ * ignore:
++ */
++ ucb1x00_free_irq(switches->ucb, i, NULL);
++ }
++ ucb1x00_disable(switches->ucb);
++ kfree(switches);
++}
++
++#ifdef CONFIG_PM
++static int ucb1x00_switches_resume(struct ucb1x00_dev *dev)
++{
++ struct ucb1x00_switches *switches = dev->priv;
++
++ if (switches->rtask != NULL)
++ {
++ switches->valid = 0;
++ wake_up(&switches->irq_wait);
++
++ printk(KERN_DEBUG "ucb1x00-switches.c -> _switches_resume() kswd - restart *DONE*\n");
++ }
++ return 0;
++}
++#else
++#define ucb1x00_switches_resume NULL
++#endif
++
++static struct ucb1x00_driver ucb1x00_switches_driver = {
++ .add = ucb1x00_switches_add,
++ .remove = ucb1x00_switches_remove,
++ .resume = ucb1x00_switches_resume,
++};
++
++static int __init ucb1x00_switches_init(void)
++{
++ return ucb1x00_register_driver(&ucb1x00_switches_driver);
++}
++
++static void __exit ucb1x00_switches_exit(void)
++{
++ ucb1x00_unregister_driver(&ucb1x00_switches_driver);
++}
++
++module_init(ucb1x00_switches_init);
++module_exit(ucb1x00_switches_exit);
++
++MODULE_AUTHOR("Bernhard Guillon <Bernhard.Guillon@opensimpad.org>");
++MODULE_DESCRIPTION("UCB1x00 Switches driver for Siemens SIMpad");
++MODULE_LICENSE("GPL");
diff --git a/recipes/linux/linux/simpad/linux-2.6.21-SIMpad-ucb1x00-ts-supend-and-accuracy.patch b/recipes/linux/linux/simpad/linux-2.6.21-SIMpad-ucb1x00-ts-supend-and-accuracy.patch
new file mode 100644
index 0000000000..8c2c89235f
--- /dev/null
+++ b/recipes/linux/linux/simpad/linux-2.6.21-SIMpad-ucb1x00-ts-supend-and-accuracy.patch
@@ -0,0 +1,121 @@
+diff -uNr linux-2.6.21.vanilla/drivers/mfd/ucb1x00-ts.c linux-2.6.21/drivers/mfd/ucb1x00-ts.c
+--- linux-2.6.21.vanilla/drivers/mfd/ucb1x00-ts.c 2007-05-30 18:00:30.000000000 +0200
++++ linux-2.6.21/drivers/mfd/ucb1x00-ts.c 2007-05-30 18:14:42.000000000 +0200
+@@ -16,6 +16,10 @@
+ * It is important to note that the signal connected to the ADCSYNC
+ * pin should provide pulses even when the LCD is blanked, otherwise
+ * a pen touch needed to unblank the LCD will never be read.
++ *
++ * mrdata: -added some accuracy improvement based on thesings collie patch
++ * -added suspend fix
++ *
+ */
+ #include <linux/module.h>
+ #include <linux/moduleparam.h>
+@@ -105,6 +109,8 @@
+ UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_GND |
+ UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
+
++ udelay(55);
++
+ return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPY, ts->adcsync);
+ }
+ }
+@@ -131,7 +137,7 @@
+ UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
+ UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA);
+
+- udelay(55);
++ udelay(165);
+
+ return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPY, ts->adcsync);
+ }
+@@ -159,7 +165,7 @@
+ UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
+ UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA);
+
+- udelay(55);
++ udelay(165);
+
+ return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPX, ts->adcsync);
+ }
+@@ -225,13 +231,17 @@
+ signed long timeout;
+
+ ts->restart = 0;
+-
++
+ ucb1x00_adc_enable(ts->ucb);
+
+ x = ucb1x00_ts_read_xpos(ts);
++ ucb1x00_adc_disable(ts->ucb);
++ ucb1x00_adc_enable(ts->ucb);
+ y = ucb1x00_ts_read_ypos(ts);
++ ucb1x00_adc_disable(ts->ucb);
++ ucb1x00_adc_enable(ts->ucb);
+ p = ucb1x00_ts_read_pressure(ts);
+-
++
+ /*
+ * Switch back to interrupt mode.
+ */
+@@ -240,15 +250,19 @@
+
+ msleep(10);
+
++ if ((x < 60) || (y < 60)) {
++ p = 0;
++ }
++
+ ucb1x00_enable(ts->ucb);
+
+-
+ if (ucb1x00_ts_pen_down(ts)) {
++
+ set_task_state(tsk, TASK_INTERRUPTIBLE);
+
+ ucb1x00_enable_irq(ts->ucb, UCB_IRQ_TSPX, machine_is_collie() ? UCB_RISING : UCB_FALLING);
+ ucb1x00_disable(ts->ucb);
+-
++
+ /*
+ * If we spat out a valid sample set last time,
+ * spit out a "pen off" sample here.
+@@ -259,7 +273,9 @@
+ }
+
+ timeout = MAX_SCHEDULE_TIMEOUT;
++
+ } else {
++
+ ucb1x00_disable(ts->ucb);
+
+ /*
+@@ -278,6 +294,14 @@
+
+ try_to_freeze();
+
++ /*
++ * While suspend the ktsd-thread goes sleep -> try_to_freeze()
++ * While resume the ktsd-thread do wakup and must rune one time
++ * again to do a clean re-setup -> enable_irq: UCB_IRQ_TSPX
++ */
++ if(ts->restart)
++ timeout = HZ / 100;
++
+ schedule_timeout(timeout);
+ }
+
+@@ -360,8 +384,12 @@
+ * TS interrupt mode is set up again
+ * after sleep.
+ */
++
+ ts->restart = 1;
+ wake_up(&ts->irq_wait);
++
++ printk(KERN_INFO "ucb1x00-ts.c -> ucb1x00_ts_resume() ktsd - restart *DONE*\n");
++
+ }
+ return 0;
+ }
diff --git a/recipes/linux/linux/simpad/linux-2.6.21-SIMpad-usb-gadget.patch b/recipes/linux/linux/simpad/linux-2.6.21-SIMpad-usb-gadget.patch
new file mode 100644
index 0000000000..00d062bd7d
--- /dev/null
+++ b/recipes/linux/linux/simpad/linux-2.6.21-SIMpad-usb-gadget.patch
@@ -0,0 +1,3329 @@
+diff -uNr linux-2.6.21.vanilla/drivers/usb/gadget/Kconfig linux-2.6.21/drivers/usb/gadget/Kconfig
+--- linux-2.6.21.vanilla/drivers/usb/gadget/Kconfig 2007-04-26 05:08:32.000000000 +0200
++++ linux-2.6.21/drivers/usb/gadget/Kconfig 2007-06-05 11:58:28.000000000 +0200
+@@ -205,6 +205,21 @@
+ depends on USB_GADGET_AT91
+ default USB_GADGET
+
++config USB_GADGET_SA1100
++ boolean "SA1100 USB Device Port"
++ depends on ARCH_SA1100
++ select USB_GADGET_SELECTED
++ help
++
++ Say "y" to link the driver statically, or "m" to build a
++ dynamically linked module called "sa1100_udc" and force all
++ gadget drivers to also be dynamically linked.
++
++config USB_SA1100
++ tristate
++ depends on USB_GADGET_SA1100
++ default USB_GADGET
++
+ config USB_GADGET_DUMMY_HCD
+ boolean "Dummy HCD (DEVELOPMENT)"
+ depends on (USB=y || (USB=m && USB_GADGET=m)) && EXPERIMENTAL
+diff -uNr linux-2.6.21.vanilla/drivers/usb/gadget/Makefile linux-2.6.21/drivers/usb/gadget/Makefile
+--- linux-2.6.21.vanilla/drivers/usb/gadget/Makefile 2007-04-26 05:08:32.000000000 +0200
++++ linux-2.6.21/drivers/usb/gadget/Makefile 2007-06-05 11:58:28.000000000 +0200
+@@ -8,6 +8,7 @@
+ obj-$(CONFIG_USB_OMAP) += omap_udc.o
+ obj-$(CONFIG_USB_LH7A40X) += lh7a40x_udc.o
+ obj-$(CONFIG_USB_AT91) += at91_udc.o
++obj-$(CONFIG_USB_SA1100) += sa1100_udc.o
+
+ #
+ # USB gadget drivers
+diff -uNr linux-2.6.21.vanilla/drivers/usb/gadget/ether.c linux-2.6.21/drivers/usb/gadget/ether.c
+--- linux-2.6.21.vanilla/drivers/usb/gadget/ether.c 2007-04-26 05:08:32.000000000 +0200
++++ linux-2.6.21/drivers/usb/gadget/ether.c 2007-06-05 11:59:24.000000000 +0200
+@@ -1456,7 +1456,7 @@
+ goto done_set_intf;
+ }
+
+-#ifdef DEV_CONFIG_CDC
++//#ifdef DEV_CONFIG_CDC
+ switch (wIndex) {
+ case 0: /* control/master intf */
+ if (wValue != 0)
+@@ -1498,12 +1498,12 @@
+ value = 0;
+ break;
+ }
+-#else
++//#else
+ /* FIXME this is wrong, as is the assumption that
+ * all non-PXA hardware talks real CDC ...
+ */
+- dev_warn (&gadget->dev, "set_interface ignored!\n");
+-#endif /* DEV_CONFIG_CDC */
++// dev_warn (&gadget->dev, "set_interface ignored!\n");
++//#endif /* DEV_CONFIG_CDC */
+
+ done_set_intf:
+ spin_unlock (&dev->lock);
+diff -uNr linux-2.6.21.vanilla/drivers/usb/gadget/sa1100_udc.c linux-2.6.21/drivers/usb/gadget/sa1100_udc.c
+--- linux-2.6.21.vanilla/drivers/usb/gadget/sa1100_udc.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.21/drivers/usb/gadget/sa1100_udc.c 2007-06-05 11:58:29.000000000 +0200
+@@ -0,0 +1,2591 @@
++/*
++ * SA1100 USB Device Controller (UDC) driver.
++ *
++ * Copyright (C) Compaq Computer Corporation, 1998, 1999
++ * Copyright (C) Extenex Corporation, 2001
++ * Copyright (C) David Brownell, 2003
++ * Copyright (C) Nick Bane, 2005, 2006
++ * Many fragments from pxa2xx_udc.c and mach-sa1100 driver with various
++ * GPL Copyright authors incl Russel king and Nicolas Pitre
++ * Port to 2.6.12 by N C Bane
++ *
++ * This file provides interrupt routing and overall coordination for the
++ * sa1100 USB endpoints: ep0, ep1out-bulk, ep2out-bulk, as well as device
++ * initialization and some parts of USB "Chapter 9" device behavior.
++ *
++ * It implements the "USB gadget controller" API, abstracting most hardware
++ * details so that drivers running on top of this API are mostly independent
++ * of hardware. A key exception is that ep0 logic needs to understand which
++ * endpoints a given controller has, and their capabilities. Also, hardware
++ * that doesn't fully support USB (like sa1100) may need workarounds in the
++ * protocols implemented by device functions.
++ *
++ * See linux/Documentation/arm/SA1100/SA1100_USB for more info, or the
++ * kerneldoc for the API exposed to gadget drivers.
++ *
++ */
++#define DEBUG 1
++#define VERBOSE 1
++
++//#define SA1100_USB_DEBUG
++#ifdef SA1100_USB_DEBUG
++static int sa1100_usb_debug=0;
++#endif
++
++#define NCB_DMA_FIX
++#ifdef NCB_DMA_FIX
++#include <linux/slab.h>
++#define SEND_BUFFER_SIZE 4096 /* this is probably a bit big */
++#define RECEIVE_BUFFER_SIZE 256 /* 64 may be all that is necessary */
++static char *send_buffer=NULL;
++static char *receive_buffer=NULL;
++#endif
++
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/delay.h>
++#include <linux/ioport.h>
++#include <linux/sched.h>
++#include <linux/slab.h>
++#include <linux/smp_lock.h>
++#include <linux/errno.h>
++#include <linux/init.h>
++#include <linux/timer.h>
++#include <linux/list.h>
++#include <linux/interrupt.h>
++#include <linux/version.h>
++#include <linux/device.h>
++#include <linux/platform_device.h>
++
++#include <asm/byteorder.h>
++#include <asm/io.h>
++#include <asm/irq.h>
++#include <asm/dma.h>
++#include <asm/system.h>
++#include <asm/mach-types.h>
++#include <asm/unaligned.h>
++
++#include <linux/usb.h>
++#include <linux/usb_ch9.h>
++#include <linux/usb_gadget.h>
++
++#if CONFIG_PROC_FS
++#include <linux/proc_fs.h>
++#endif
++
++#if defined(CONFIG_SA1100_BALLOON)
++#include <asm/arch/balloon.h>
++#endif
++
++#define DRIVER_VERSION __DATE__
++
++#define DMA_ADDR_INVALID (~(dma_addr_t)0)
++
++
++static const char driver_name [] = "sa1100_udc";
++static const char driver_desc [] = "SA-1110 USB Device Controller";
++
++static const char ep0name [] = "ep0";
++
++#ifdef DEBUG
++static char *type_string (u8 bmAttributes)
++{
++ switch ( (bmAttributes) & USB_ENDPOINT_XFERTYPE_MASK) {
++ case USB_ENDPOINT_XFER_BULK: return "bulk";
++ //case USB_ENDPOINT_XFER_ISOC: return "iso";
++ case USB_ENDPOINT_XFER_INT: return "intr";
++ };
++ return "control";
++}
++#endif
++
++#include <linux/dma-mapping.h>
++struct usb_stats_t {
++ unsigned long ep0_fifo_write_failures;
++ unsigned long ep0_bytes_written;
++ unsigned long ep0_fifo_read_failures;
++ unsigned long ep0_bytes_read;
++};
++
++struct usb_info_t
++{
++ dma_regs_t *dmaregs_tx, *dmaregs_rx;
++ int state;
++ unsigned char address;
++ struct usb_stats_t stats;
++};
++
++enum { kError=-1, kEvSuspend=0, kEvReset=1,
++ kEvResume=2, kEvAddress=3, kEvConfig=4, kEvDeConfig=5 };
++int usbctl_next_state_on_event( int event ) {
++ return 0;
++}
++static struct usb_info_t usbd_info;
++
++/* receiver */
++void ep1_reset(void);
++void ep1_stall(void);
++int sa1100_usb_recv (struct usb_request *req, void (*callback) (int,int));
++
++/* xmitter */
++void ep2_reset(void);
++void ep2_stall(void);
++int sa1100_usb_send (struct usb_request *req, void (*callback) (int,int));
++
++/* UDC register utility functions */
++#define UDC_write(reg, val) { \
++ int i = 10000; \
++ do { \
++ (reg) = (val); \
++ if (i-- <= 0) { \
++ printk( "%s [%d]: write %#x to %p (%#x) failed\n", \
++ __FUNCTION__, __LINE__, (val), &(reg), (reg)); \
++ break; \
++ } \
++ } while((reg) != (val)); \
++}
++
++#define UDC_set(reg, val) { \
++ int i = 10000; \
++ do { \
++ (reg) |= (val); \
++ if (i-- <= 0) { \
++ printk( "%s [%d]: set %#x of %p (%#x) failed\n", \
++ __FUNCTION__, __LINE__, (val), &(reg), (reg)); \
++ break; \
++ } \
++ } while(!((reg) & (val))); \
++}
++
++#define UDC_clear(reg, val) { \
++ int i = 10000; \
++ do { \
++ (reg) &= ~(val); \
++ if (i-- <= 0) { \
++ printk( "%s [%d]: clear %#x of %p (%#x) failed\n", \
++ __FUNCTION__, __LINE__, (val), &(reg), (reg)); \
++ break; \
++ } \
++ } while((reg) & (val)); \
++}
++
++#define UDC_flip(reg, val) { \
++ int i = 10000; \
++ (reg) = (val); \
++ do { \
++ (reg) = (val); \
++ if (i-- <= 0) { \
++ printk( "%s [%d]: flip %#x of %p (%#x) failed\n", \
++ __FUNCTION__, __LINE__, (val), &(reg), (reg)); \
++ break; \
++ } \
++ } while(((reg) & (val))); \
++}
++
++#include "sa1100_udc.h"
++
++static struct sa1100_udc *the_controller;
++static void nuke (struct sa1100_ep *, int status);
++static void done (struct sa1100_ep *ep, struct sa1100_request *req, int status);
++static inline void ep0_idle (struct sa1100_udc *dev)
++{
++ dev->ep0state = EP0_IDLE;
++}
++
++// ep0 handlers
++
++// 1 == lots of trace noise, 0 = only "important' stuff
++//#define VERBOSITY 1
++
++#ifndef MIN
++#define MIN( a, b ) ((a)<(b)?(a):(b))
++#endif
++
++#if 1 && !defined( ASSERT )
++# define ASSERT(expr) \
++ if(!(expr)) { \
++ printk( "Assertion failed! %s,%s,%s,line=%d\n",\
++ #expr,__FILE__,__FUNCTION__,__LINE__); \
++ }
++#else
++# define ASSERT(expr)
++#endif
++
++#if VERBOSITY
++#define PRINTKD(fmt, args...) printk( fmt , ## args)
++#else
++#define PRINTKD(fmt, args...)
++#endif
++
++/* USB Device Requests */
++typedef struct
++{
++ __u8 bmRequestType;
++ __u8 bRequest;
++ __u16 wValue;
++ __u16 wIndex;
++ __u16 wLength;
++} usb_dev_request_t __attribute__ ((packed));
++
++/* other subroutines */
++unsigned int (*wrint)(void);
++void ep0_int_hndlr( void );
++static void ep0_queue(void *buf, unsigned int req, unsigned int act);
++static void write_fifo( void );
++static int read_fifo( struct usb_ctrlrequest * p );
++
++/* some voodo helpers 01Mar01ww */
++static void set_cs_bits( __u32 set_bits );
++static void set_de( void );
++static void set_ipr( void );
++static void set_ipr_and_de( void );
++static bool clear_opr( void );
++
++/***************************************************************************
++Inline Helpers
++***************************************************************************/
++
++/* Data extraction from usb_request_t fields */
++enum { kTargetDevice=0, kTargetInterface=1, kTargetEndpoint=2 };
++static inline int request_target( __u8 b ) { return (int) ( b & 0x0F); }
++
++static inline int windex_to_ep_num( __u16 w ) { return (int) ( w & 0x000F); }
++inline int type_code_from_request( __u8 by ) { return (( by >> 4 ) & 3); }
++
++/* following is hook for self-powered flag in GET_STATUS. Some devices
++ .. might like to override and return real info */
++static inline bool self_powered_hook( void ) { return true; }
++
++#if VERBOSITY
++/* "pcs" == "print control status" */
++static inline void pcs( void )
++{
++ __u32 foo = Ser0UDCCS0;
++ printk( "%8.8X: %s %s %s %s\n",
++ foo,
++ foo & UDCCS0_SE ? "SE" : "",
++ foo & UDCCS0_OPR ? "OPR" : "",
++ foo & UDCCS0_IPR ? "IPR" : "",
++ foo & UDCCS0_SST ? "SST" : ""
++ );
++}
++static inline void preq( struct usb_ctrlrequest * pReq )
++{
++ static char * tnames[] = { "dev", "intf", "ep", "oth" };
++ static char * rnames[] = { "std", "class", "vendor", "???" };
++ char * psz;
++ switch( pReq->bRequest ) {
++ case USB_REQ_GET_STATUS: psz = "get stat"; break;
++ case USB_REQ_CLEAR_FEATURE: psz = "clr feat"; break;
++ case USB_REQ_SET_FEATURE: psz = "set feat"; break;
++ case USB_REQ_SET_ADDRESS: psz = "set addr"; break;
++ case USB_REQ_GET_DESCRIPTOR: psz = "get desc"; break;
++ case USB_REQ_SET_DESCRIPTOR: psz = "set desc"; break;
++ case USB_REQ_GET_CONFIGURATION: psz = "get cfg"; break;
++ case USB_REQ_SET_CONFIGURATION: psz = "set cfg"; break;
++ case USB_REQ_GET_INTERFACE: psz = "get intf"; break;
++ case USB_REQ_SET_INTERFACE: psz = "set intf"; break;
++ default: psz = "unknown"; break;
++ }
++ printk( "- [%s: %s req to %s. dir=%s]\n", psz,
++ rnames[ (pReq->bRequestType >> 5) & 3 ],
++ tnames[ pReq->bRequestType & 3 ],
++ ( pReq->bRequestType & 0x80 ) ? "in" : "out" );
++}
++
++static inline void usbctl_dump_request(const char *prefix, const struct usb_ctrlrequest *req)
++{
++ printk("%s: bRequestType=0x%02x bRequest=0x%02x "
++ "wValue=0x%04x wIndex=0x%04x wLength=0x%04x\n",
++ prefix, req->bRequestType, req->bRequest,
++ le16_to_cpu(req->wValue), le16_to_cpu(req->wIndex),
++ le16_to_cpu(req->wLength));
++}
++#else
++static inline void pcs( void ){}
++//static inline void preq( void ){}
++static inline void preq( void *x ){}
++static inline void usbctl_dump_request(const char *prefix, const struct usb_ctrlrequest *req) {}
++#endif
++
++/***************************************************************************
++Globals
++***************************************************************************/
++static const char pszMe[] = "usbep0: ";
++
++
++/* global write struct to keep write
++ ..state around across interrupts */
++static struct {
++ unsigned char *p;
++ int bytes_left;
++} wr;
++
++/***************************************************************************
++Public Interface
++***************************************************************************/
++
++/* reset received from HUB (or controller just went nuts and reset by itself!)
++ so udc core has been reset, track this state here */
++void
++ep0_reset(void)
++{
++ /* reset state machine */
++ wr.p = NULL;
++ wr.bytes_left = 0;
++ usbd_info.address=0;
++// needed? Ser0UDCAR = 0;
++}
++
++
++/* handle interrupt for endpoint zero */
++
++inline void ep0_clear_write(void) {
++ wr.p=NULL;
++ wr.bytes_left=0;
++}
++
++/* this is a config packet parser based on that from the updated HH 2.6 udc */
++static void
++ep0_read_packet( void )
++{
++ unsigned char status_buf[2]; /* returned in GET_STATUS */
++ struct usb_ctrlrequest req;
++ int request_type;
++ int n;
++ __u32 address;
++
++ /* reset previous count */
++ the_controller->ep0_req_len=-1;
++
++ /* read the setup request */
++ n = read_fifo( &req );
++ usbctl_dump_request("ep0_read_packet",&req);
++
++ if ( n != sizeof( req ) ) {
++ printk( "%ssetup begin: fifo READ ERROR wanted %d bytes got %d. "
++ " Stalling out...\n",
++ pszMe, sizeof( req ), n );
++ /* force stall, serviced out */
++ set_cs_bits( UDCCS0_FST | UDCCS0_SO );
++ goto sh_sb_end;
++ }
++
++ /* Is it a standard request? (not vendor or class request) */
++ request_type = type_code_from_request( req.bRequestType );
++ if ( request_type != 0 ) {
++ printk( "%ssetup begin: unsupported bRequestType: %d ignored\n",
++ pszMe, request_type );
++ set_cs_bits( UDCCS0_DE | UDCCS0_SO );
++ goto sh_sb_end;
++ }
++
++ /* save requested reply size */
++ the_controller->ep0_req_len=le16_to_cpu(req.wLength);
++ PRINTKD("%s: request length is %d\n",__FUNCTION__,the_controller->ep0_req_len);
++
++#if VERBOSITY
++ {
++ unsigned char * pdb = (unsigned char *) &req;
++ PRINTKD( "%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X ",
++ pdb[0], pdb[1], pdb[2], pdb[3], pdb[4], pdb[5], pdb[6], pdb[7]
++ );
++ preq( &req );
++ }
++#endif
++
++ /* Handle it */
++ switch( req.bRequest ) {
++
++ /* This first bunch have no data phase */
++
++ case USB_REQ_SET_ADDRESS:
++ address = (__u32) (req.wValue & 0x7F);
++ /* when SO and DE sent, UDC will enter status phase and ack,
++ ..propagating new address to udc core. Next control transfer
++ ..will be on the new address. You can't see the change in a
++ ..read back of CAR until then. (about 250us later, on my box).
++ ..The original Intel driver sets S0 and DE and code to check
++ ..that address has propagated here. I tried this, but it
++ ..would only work sometimes! The rest of the time it would
++ ..never propagate and we'd spin forever. So now I just set
++ ..it and pray...
++ */
++ Ser0UDCAR = address;
++ usbd_info.address = address;
++ usbctl_next_state_on_event( kEvAddress );
++ set_cs_bits( UDCCS0_SO | UDCCS0_DE ); /* no data phase */
++ printk( "%sI have been assigned address: %d\n", pszMe, address );
++ break;
++
++
++ case USB_REQ_SET_CONFIGURATION:
++ if ( req.wValue == 1 ) {
++ /* configured */
++ if (usbctl_next_state_on_event( kEvConfig ) != kError) {
++ /* (re)set the out and in max packet sizes */
++ PRINTKD( "%s: calling the_controller.driver->setup with SET_CONFIGURATION\n", __FUNCTION__ );
++ the_controller->driver->setup(&the_controller->gadget, &req);
++ __u32 in = __le16_to_cpu( the_controller->ep[1].ep.maxpacket );
++ __u32 out = __le16_to_cpu( the_controller->ep[2].ep.maxpacket );
++ Ser0UDCOMP = ( out - 1 );
++ Ser0UDCIMP = ( in - 1 );
++ // we are configured
++ usbd_info.state = USB_STATE_CONFIGURED;
++ // enable rx and tx interrupts
++ Ser0UDCCR &= ~(UDCCR_RIM | UDCCR_TIM);
++
++ printk( "%sConfigured (OMP=%8.8X IMP=%8.8X)\n", pszMe, out, in );
++ break;
++ }
++ } else if ( req.wValue == 0 ) {
++ /* de-configured */
++ if (usbctl_next_state_on_event( kEvDeConfig ) != kError )
++ printk( "%sDe-Configured\n", pszMe );
++ usbd_info.state = 0;
++ Ser0UDCCR |= UDCCR_RIM | UDCCR_TIM;
++ ep1_reset ();
++ ep2_reset ();
++ printk("%s: de-configured. Tx and Rx interrupts disabled. ep1 and ep2 reset\n",__FUNCTION__);
++ } else {
++ printk( "%ssetup phase: Unknown "
++ "\"set configuration\" data %d\n",
++ pszMe, req.wValue );
++ }
++ set_cs_bits( UDCCS0_SO | UDCCS0_DE ); /* no data phase */
++ break;
++
++ case USB_REQ_CLEAR_FEATURE:
++ /* could check data length, direction...26Jan01ww */
++ if ( req.wValue == 0 ) { /* clearing ENDPOINT_HALT/STALL */
++ int ep = windex_to_ep_num( req.wIndex );
++ if ( ep == 1 ) {
++ printk( "%sclear feature \"endpoint halt\" "
++ " on receiver\n", pszMe );
++ ep1_reset();
++ }
++ else if ( ep == 2 ) {
++ printk( "%sclear feature \"endpoint halt\" "
++ "on xmitter\n", pszMe );
++ ep2_reset();
++ } else {
++ printk( "%sclear feature \"endpoint halt\" "
++ "on unsupported ep # %d\n",
++ pszMe, ep );
++ }
++ } else {
++ printk( "%sUnsupported feature selector (%d) "
++ "in clear feature. Ignored.\n" ,
++ pszMe, req.wValue );
++ }
++ set_cs_bits( UDCCS0_SO | UDCCS0_DE ); /* no data phase */
++ break;
++
++ case USB_REQ_SET_FEATURE:
++ if ( req.wValue == 0 ) { /* setting ENDPOINT_HALT/STALL */
++ int ep = windex_to_ep_num( req.wValue );
++ if ( ep == 1 ) {
++ printk( "%set feature \"endpoint halt\" "
++ "on receiver\n", pszMe );
++ ep1_stall();
++ }
++ else if ( ep == 2 ) {
++ printk( "%sset feature \"endpoint halt\" "
++ " on xmitter\n", pszMe );
++ ep2_stall();
++ } else {
++ printk( "%sset feature \"endpoint halt\" "
++ "on unsupported ep # %d\n",
++ pszMe, ep );
++ }
++ }
++ else {
++ printk( "%sUnsupported feature selector "
++ "(%d) in set feature\n",
++ pszMe, req.wValue );
++ }
++ set_cs_bits( UDCCS0_SO | UDCCS0_DE ); /* no data phase */
++ break;
++
++ /* The rest have a data phase that writes back to the host */
++ case USB_REQ_GET_STATUS:
++ /* return status bit flags */
++ status_buf[0] = status_buf[1] = 0;
++ n = request_target(req.bRequestType);
++ switch( n ) {
++ case kTargetDevice:
++ if ( self_powered_hook() )
++ status_buf[0] |= 1;
++ break;
++ case kTargetInterface:
++ break;
++ case kTargetEndpoint:
++ /* return stalled bit */
++ n = windex_to_ep_num( req.wIndex );
++ if ( n == 1 )
++ status_buf[0] |= (Ser0UDCCS1 & UDCCS1_FST) >> 4;
++ else if ( n == 2 )
++ status_buf[0] |= (Ser0UDCCS2 & UDCCS2_FST) >> 5;
++ else {
++ printk( "%sUnknown endpoint (%d) "
++ "in GET_STATUS\n", pszMe, n );
++ }
++ break;
++ default:
++ printk( "%sUnknown target (%d) in GET_STATUS\n",
++ pszMe, n );
++ /* fall thru */
++ break;
++ }
++ PRINTKD("%s: GET_STATUS writing %d\n",__FUNCTION__,req.wLength);
++ ep0_queue( status_buf, req.wLength, sizeof( status_buf ));
++ break;
++ case USB_REQ_GET_DESCRIPTOR:
++ PRINTKD( "%s: calling the_controller.driver->setup with GET_DESCRIPTOR\n", __FUNCTION__ );
++ the_controller->driver->setup(&the_controller->gadget, &req);
++ break;
++ case USB_REQ_GET_CONFIGURATION:
++ PRINTKD( "%s: calling the_controller.driver->setup with GET_CONFIGURATION\n", __FUNCTION__ );
++ the_controller->driver->setup(&the_controller->gadget, &req);
++ break;
++ case USB_REQ_GET_INTERFACE:
++ PRINTKD( "%s: calling the_controller->driver->setup with GET_INTERFACE\n", __FUNCTION__ );
++ the_controller->driver->setup(&the_controller->gadget, &req);
++ break;
++ case USB_REQ_SET_INTERFACE:
++ PRINTKD( "%s: calling the_controller->driver->setup with SET_INTERFACE\n", __FUNCTION__ );
++ the_controller->driver->setup(&the_controller->gadget, &req);
++ break;
++ default :
++ printk("%sunknown request 0x%x\n", pszMe, req.bRequest);
++ break;
++ } /* switch( bRequest ) */
++
++sh_sb_end:
++ return;
++
++}
++
++void
++ep0_int_hndlr( void )
++{
++ u32 cs_reg_in;
++
++ pcs();
++
++ cs_reg_in = Ser0UDCCS0;
++
++
++ /*
++ * If "setup end" has been set, the usb controller has terminated
++ * a setup transaction before we set DE. This happens during
++ * enumeration with some hosts. For example, the host will ask for
++ * our device descriptor and specify a return of 64 bytes. When we
++ * hand back the first 8, the host will know our max packet size
++ * and turn around and issue a new setup immediately. This causes
++ * the UDC to auto-ack the new setup and set SE. We must then
++ * "unload" (process) the new setup, which is what will happen
++ * after this preamble is finished executing.
++ */
++ if (cs_reg_in & UDCCS0_SE) {
++ PRINTKD("UDC: early termination of setup\n");
++
++ /*
++ * Clear setup end
++ */
++ set_cs_bits(UDCCS0_SSE);
++
++ /*
++ * Clear any pending write.
++ */
++ ep0_clear_write();
++ }
++
++ /*
++ * UDC sent a stall due to a protocol violation.
++ */
++ if (cs_reg_in & UDCCS0_SST) {
++// usb->ep0_stall_sent++;
++
++ PRINTKD("UDC: write_preamble: UDC sent stall\n");
++
++ /*
++ * Clear sent stall
++ */
++ set_cs_bits(UDCCS0_SST);
++
++ /*
++ * Clear any pending write.
++ */
++ ep0_clear_write();
++ }
++
++ switch (cs_reg_in & (UDCCS0_OPR | UDCCS0_IPR)) {
++ case UDCCS0_OPR | UDCCS0_IPR:
++ PRINTKD("UDC: write_preamble: see OPR. Stopping write to "
++ "handle new SETUP\n");
++
++ /*
++ * very rarely, you can get OPR and
++ * leftover IPR. Try to clear
++ */
++ UDC_clear(Ser0UDCCS0, UDCCS0_IPR);
++
++ /*
++ * Clear any pending write.
++ */
++ ep0_clear_write();
++
++ /*FALLTHROUGH*/
++ case UDCCS0_OPR:
++ /*
++ * A new setup request is pending. Handle
++ * it. Note that we don't try to read a
++ * packet if SE was set and OPR is clear.
++ */
++ ep0_read_packet();
++ break;
++
++ case 0:
++ // if data pending ...
++ if (wr.p) {
++ unsigned int cs_bits = 0;
++ if (wr.bytes_left != 0) {
++ /*
++ * More data to go
++ */
++ write_fifo();
++ // packet ready
++ cs_bits |= UDCCS0_IPR;
++ }
++
++ if (wr.bytes_left == 0) {
++ /*
++ * All data sent.
++ */
++ cs_bits |= wrint();
++ // a null packet may be following
++ if (!wrint)
++ ep0_clear_write();
++ }
++ set_cs_bits(cs_bits);
++ }
++ else
++ PRINTKD("%s: No data - probably an ACK\n",__FUNCTION__);
++ break;
++
++ case UDCCS0_IPR:
++ PRINTKD("UDC: IPR set, not writing\n");
++// usb->ep0_early_irqs++;
++ break;
++ }
++
++ pcs();
++ PRINTKD( "-end-\n" );
++}
++
++static unsigned int ep0_sh_write_data(void)
++{
++ /*
++ * If bytes left is zero, we are coming in on the
++ * interrupt after the last packet went out. And
++ * we know we don't have to empty packet this
++ * transfer so just set DE and we are done
++ */
++ PRINTKD("UDC: normal packet ended\n");
++ wrint=NULL;
++ return UDCCS0_DE;
++}
++
++static unsigned int ep0_sh_write_with_empty_packet(void)
++{
++ /*
++ * If bytes left is zero, we are coming in on the
++ * interrupt after the last packet went out.
++ * We must do short packet suff, so set DE and IPR
++ */
++ PRINTKD("UDC: short packet sent\n");
++ wrint=NULL;
++ return UDCCS0_IPR | UDCCS0_DE;
++}
++
++static unsigned int ep0_sh_write_data_then_empty_packet(void)
++{
++ PRINTKD("UDC: last packet full. Send empty packet next\n");
++ wrint=ep0_sh_write_with_empty_packet;
++ return 0;
++}
++
++static void ep0_queue(void *buf, unsigned int len, unsigned int req_len)
++{
++ __u32 cs_reg_bits = UDCCS0_IPR;
++
++ PRINTKD("a=%d r=%d\n", len, req_len);
++
++ if (len == 0) {
++ // no output packet to wait for
++ printk("%s: zero byte packet being queued. Setting DE and OPR end exiting\n",__FUNCTION__);
++ set_cs_bits(UDCCS0_DE | UDCCS0_SO);
++ return;
++ }
++
++ /*
++ * thou shalt not enter data phase until
++ * Out Packet Ready is clear
++ */
++ if (!clear_opr()) {
++ printk("UDC: SO did not clear OPR\n");
++ set_cs_bits(UDCCS0_DE | UDCCS0_SO);
++ return;
++ }
++
++ // note data to xmit stored
++ wr.p=buf;
++ wr.bytes_left=min(len, req_len);
++
++ // write the first block
++ write_fifo();
++
++ // done already?
++ if (wr.bytes_left == 0) {
++ /*
++ * out in one, so data end
++ */
++ cs_reg_bits |= UDCCS0_DE;
++ ep0_clear_write();
++ // rest is a shorter than expected reply?
++ } else if (len < req_len) {
++ /*
++ * we are going to short-change host
++ * so need nul to not stall
++ */
++ if (len % 8) {
++ PRINTKD("%s: %d more to go ending in a short packet.\n",__FUNCTION__,wr.bytes_left);
++ wrint=ep0_sh_write_with_empty_packet;
++ }
++ // unless we are on a packet boundary. Then send full packet plus null packet.
++ else {
++ PRINTKD("%s: %d more to go then add empty packet.\n",__FUNCTION__,wr.bytes_left);
++ wrint=ep0_sh_write_data_then_empty_packet;
++ }
++ } else {
++ /*
++ * we have as much or more than requested
++ */
++ PRINTKD("%s: %d more to go.\n",__FUNCTION__,wr.bytes_left);
++ wrint=ep0_sh_write_data;
++ }
++
++ /*
++ * note: IPR was set uncondtionally at start of routine
++ */
++ set_cs_bits(cs_reg_bits);
++}
++
++/*
++ * write_fifo()
++ * Stick bytes in the 8 bytes endpoint zero FIFO.
++ * This version uses a variety of tricks to make sure the bytes
++ * are written correctly. 1. The count register is checked to
++ * see if the byte went in, and the write is attempted again
++ * if not. 2. An overall counter is used to break out so we
++ * don't hang in those (rare) cases where the UDC reverses
++ * direction of the FIFO underneath us without notification
++ * (in response to host aborting a setup transaction early).
++ *
++ */
++static void write_fifo( void )
++{
++ int bytes_this_time = MIN( wr.bytes_left, 8 );
++ int bytes_written = 0;
++
++ PRINTKD( "WF=%d: ", bytes_this_time );
++
++ while( bytes_this_time-- ) {
++ unsigned int cwc;
++ int i;
++ PRINTKD( "%2.2X ", *wr.p );
++ cwc = Ser0UDCWC & 15;
++ i = 10;
++ do {
++ Ser0UDCD0 = *wr.p;
++ udelay( 20 ); /* voodo 28Feb01ww */
++ } while( (Ser0UDCWC &15) == cwc && --i );
++
++ if ( i == 0 ) {
++ printk( "%swrite_fifo: write failure\n", pszMe );
++ usbd_info.stats.ep0_fifo_write_failures++;
++ }
++
++ wr.p++;
++ bytes_written++;
++ }
++ wr.bytes_left -= bytes_written;
++
++ /* following propagation voodo so maybe caller writing IPR in
++ ..a moment might actually get it to stick 28Feb01ww */
++ udelay( 300 );
++
++ usbd_info.stats.ep0_bytes_written += bytes_written;
++ PRINTKD( "L=%d WCR=%8.8X\n", wr.bytes_left, Ser0UDCWC );
++}
++/*
++ * read_fifo()
++ * Read 1-8 bytes out of FIFO and put in request.
++ * Called to do the initial read of setup requests
++ * from the host. Return number of bytes read.
++ *
++ * Like write fifo above, this driver uses multiple
++ * reads checked agains the count register with an
++ * overall timeout.
++ *
++ */
++static int
++read_fifo( struct usb_ctrlrequest * request )
++{
++ int bytes_read = 0;
++ int fifo_count;
++
++ unsigned char * pOut = (unsigned char*) request;
++
++ fifo_count = ( Ser0UDCWC & 0xFF );
++
++ ASSERT( fifo_count <= 8 );
++ PRINTKD( "RF=%d ", fifo_count );
++
++ while( fifo_count-- ) {
++ unsigned int cwc;
++ int i;
++
++ cwc = Ser0UDCWC & 15;
++
++ i = 10;
++ do {
++ *pOut = (unsigned char) Ser0UDCD0;
++ udelay( 20 );
++ } while( ( Ser0UDCWC & 15 ) == cwc && --i );
++
++ if ( i == 0 ) {
++ printk( "%sread_fifo(): read failure\n", pszMe );
++ usbd_info.stats.ep0_fifo_read_failures++;
++ }
++ pOut++;
++ bytes_read++;
++ }
++
++ PRINTKD( "fc=%d\n", bytes_read );
++ usbd_info.stats.ep0_bytes_read++;
++ return bytes_read;
++}
++
++/* some voodo I am adding, since the vanilla macros just aren't doing it 1Mar01ww */
++
++#define ABORT_BITS ( UDCCS0_SST | UDCCS0_SE )
++#define OK_TO_WRITE (!( Ser0UDCCS0 & ABORT_BITS ))
++#define BOTH_BITS (UDCCS0_IPR | UDCCS0_DE)
++
++static void set_cs_bits( __u32 bits )
++{
++ if ( bits & ( UDCCS0_SO | UDCCS0_SSE | UDCCS0_FST | UDCCS0_SST) )
++ Ser0UDCCS0 = bits;
++ else if ( (bits & BOTH_BITS) == BOTH_BITS )
++ set_ipr_and_de();
++ else if ( bits & UDCCS0_IPR )
++ set_ipr();
++ else if ( bits & UDCCS0_DE )
++ set_de();
++}
++
++static void set_de( void )
++{
++ int i = 1;
++ while( 1 ) {
++ if ( OK_TO_WRITE ) {
++ Ser0UDCCS0 |= UDCCS0_DE;
++ } else {
++ PRINTKD( "%sQuitting set DE because SST or SE set\n", pszMe );
++ break;
++ }
++ if ( Ser0UDCCS0 & UDCCS0_DE )
++ break;
++ udelay( i );
++ if ( ++i == 50 ) {
++ printk( "%sDangnabbbit! Cannot set DE! (DE=%8.8X CCS0=%8.8X)\n",
++ pszMe, UDCCS0_DE, Ser0UDCCS0 );
++ break;
++ }
++ }
++}
++
++static void set_ipr( void )
++{
++ int i = 1;
++ while( 1 ) {
++ if ( OK_TO_WRITE ) {
++ Ser0UDCCS0 |= UDCCS0_IPR;
++ } else {
++ PRINTKD( "%sQuitting set IPR because SST or SE set\n", pszMe );
++ break;
++ }
++ if ( Ser0UDCCS0 & UDCCS0_IPR )
++ break;
++ udelay( i );
++ if ( ++i == 50 ) {
++ printk( "%sDangnabbbit! Cannot set IPR! (IPR=%8.8X CCS0=%8.8X)\n",
++ pszMe, UDCCS0_IPR, Ser0UDCCS0 );
++ break;
++ }
++ }
++}
++
++static void set_ipr_and_de( void )
++{
++ int i = 1;
++ while( 1 ) {
++ if ( OK_TO_WRITE ) {
++ Ser0UDCCS0 |= BOTH_BITS;
++ } else {
++ PRINTKD( "%sQuitting set IPR/DE because SST or SE set\n", pszMe );
++ break;
++ }
++ if ( (Ser0UDCCS0 & BOTH_BITS) == BOTH_BITS)
++ break;
++ udelay( i );
++ if ( ++i == 50 ) {
++ printk( "%sDangnabbbit! Cannot set DE/IPR! (DE=%8.8X IPR=%8.8X CCS0=%8.8X)\n",
++ pszMe, UDCCS0_DE, UDCCS0_IPR, Ser0UDCCS0 );
++ break;
++ }
++ }
++}
++
++static bool clear_opr( void )
++{
++ int i = 10000;
++ bool is_clear;
++ do {
++ Ser0UDCCS0 = UDCCS0_SO;
++ is_clear = ! ( Ser0UDCCS0 & UDCCS0_OPR );
++ if ( i-- <= 0 ) {
++ printk( "%sclear_opr(): failed\n", pszMe );
++ break;
++ }
++ } while( ! is_clear );
++ return is_clear;
++}
++
++
++
++// ep1 handlers
++
++static char *ep1_buf;
++static int ep1_len;
++static void (*ep1_callback)(int flag, int size);
++static char *ep1_curdmabuf;
++static dma_addr_t ep1_curdmapos;
++static int ep1_curdmalen;
++static int ep1_remain;
++static int ep1_used;
++
++static dma_regs_t *dmaregs_rx = NULL;
++static int rx_pktsize;
++
++static int naking;
++
++static void
++ep1_start(void)
++{
++ sa1100_reset_dma(dmaregs_rx);
++ if (!ep1_curdmalen) {
++ ep1_curdmalen = rx_pktsize;
++ if (ep1_curdmalen > ep1_remain)
++ ep1_curdmalen = ep1_remain;
++ ep1_curdmapos = dma_map_single(NULL, ep1_curdmabuf, ep1_curdmalen,
++ DMA_FROM_DEVICE);
++ }
++
++ UDC_write( Ser0UDCOMP, ep1_curdmalen-1 );
++
++ sa1100_start_dma(dmaregs_rx, ep1_curdmapos, ep1_curdmalen);
++
++ if ( naking ) {
++ /* turn off NAK of OUT packets, if set */
++ UDC_flip( Ser0UDCCS1, UDCCS1_RPC );
++ naking = 0;
++ }
++}
++
++static void
++ep1_done(int flag)
++{
++ int size = ep1_len - ep1_remain;
++
++ if (!ep1_len)
++ return;
++ if (ep1_curdmalen)
++ dma_unmap_single(NULL, ep1_curdmapos, ep1_curdmalen,
++ DMA_FROM_DEVICE);
++ ep1_len = ep1_curdmalen = 0;
++ if (ep1_callback)
++ ep1_callback(flag, size);
++}
++
++void
++ep1_state_change_notify( int new_state )
++{
++
++}
++
++void
++ep1_stall( void )
++{
++ /* SET_FEATURE force stall at UDC */
++ UDC_set( Ser0UDCCS1, UDCCS1_FST );
++}
++
++int
++ep1_init(dma_regs_t *dmaregs)
++{
++ dmaregs_rx = dmaregs;
++ sa1100_reset_dma(dmaregs_rx);
++ ep1_done(-EAGAIN);
++ return 0;
++}
++
++void
++ep1_reset(void)
++{
++ if (dmaregs_rx)
++ sa1100_reset_dma(dmaregs_rx);
++ UDC_clear(Ser0UDCCS1, UDCCS1_FST);
++ ep1_done(-EINTR);
++}
++
++void
++ep1_int_hndlr(int udcsr)
++{
++ dma_addr_t dma_addr;
++ unsigned int len;
++ int status = Ser0UDCCS1;
++
++ if ( naking ) printk( "%sEh? in ISR but naking = %d\n", "usbrx: ", naking );
++
++ if (status & UDCCS1_RPC) {
++
++ if (!ep1_curdmalen) {
++ printk("usb_recv: RPC for non-existent buffer\n");
++ naking=1;
++ return;
++ }
++
++ sa1100_stop_dma(dmaregs_rx);
++
++ if (status & UDCCS1_SST) {
++ printk("usb_recv: stall sent OMP=%d\n",Ser0UDCOMP);
++ UDC_flip(Ser0UDCCS1, UDCCS1_SST);
++ ep1_done(-EIO); // UDC aborted current transfer, so we do
++ return;
++ }
++
++ if (status & UDCCS1_RPE) {
++ printk("usb_recv: RPError %x\n", status);
++ UDC_flip(Ser0UDCCS1, UDCCS1_RPC);
++ ep1_done(-EIO);
++ return;
++ }
++
++ dma_addr=sa1100_get_dma_pos(dmaregs_rx);
++ dma_unmap_single(NULL, ep1_curdmapos, ep1_curdmalen,
++ DMA_FROM_DEVICE);
++ len = dma_addr - ep1_curdmapos;
++#ifdef SA1100_USB_DEBUG
++ if (sa1100_usb_debug) {
++ int i;
++ printk("usb rx %d :\n ",len);
++ if (sa1100_usb_debug>1) {
++ for (i=0; i<len; i++) {
++ if ((i % 32)==31)
++ printk("\n ");
++// printk("%2.2x ",((char *)ep1_buf)[ep1_used+i]);
++ printk("%2.2x ",((char *)ep1_curdmapos)[i]);
++ }
++ }
++ printk("\n");
++ }
++#endif
++ if (len < ep1_curdmalen) {
++ char *buf = ep1_curdmabuf + len;
++ while (Ser0UDCCS1 & UDCCS1_RNE) {
++ if (len >= ep1_curdmalen) {
++ printk("usb_recv: too much data in fifo\n");
++ break;
++ }
++ *buf++ = Ser0UDCDR;
++ len++;
++ }
++ } else if (Ser0UDCCS1 & UDCCS1_RNE) {
++ printk("usb_recv: fifo screwed, shouldn't contain data\n");
++ len = 0;
++ }
++
++#if defined(NCB_DMA_FIX)
++// if (len && (ep1_buf != ep1_curdmabuf))
++// memcpy(ep1_buf,ep1_curdmabuf,len);
++ if (len)
++ memcpy(&(((unsigned char *)ep1_buf)[ep1_used]),ep1_curdmabuf,len);
++#endif
++
++ ep1_curdmalen = 0; /* dma unmap already done */
++ ep1_remain -= len;
++ ep1_used += len;
++// ep1_curdmabuf += len; // use same buffer again
++ naking = 1;
++//printk("%s: received %d, %d remaining\n",__FUNCTION__,len,ep1_remain);
++ if (len && (len == rx_pktsize))
++ ep1_start();
++ else
++ ep1_done((len) ? 0 : -EPIPE);
++ }
++ /* else, you can get here if we are holding NAK */
++}
++
++int
++sa1100_usb_recv(struct usb_request *req, void (*callback)(int flag, int size))
++{
++ unsigned long flags;
++ char *buf=req->buf;
++ int len=req->length;
++
++ if (ep1_len)
++ return -EBUSY;
++
++ local_irq_save(flags);
++ ep1_buf = buf;
++ ep1_len = len;
++ ep1_callback = callback;
++ ep1_remain = len;
++ ep1_used = 0;
++#ifdef NCB_DMA_FIX
++// if (((size_t)buf)&3)
++ if (1)
++ ep1_curdmabuf = receive_buffer;
++ else
++#else
++ ep1_curdmabuf = buf;
++#endif
++ ep1_curdmalen = 0;
++ ep1_start();
++ local_irq_restore(flags);
++
++ return 0;
++}
++
++// ep2 handlers
++
++static char *ep2_buf;
++static int ep2_len;
++static void (*ep2_callback)(int status, int size);
++static dma_addr_t ep2_dma;
++static dma_addr_t ep2_curdmapos;
++static int ep2_curdmalen;
++static int ep2_remain;
++static dma_regs_t *dmaregs_tx = NULL;
++static int tx_pktsize;
++
++/* device state is changing, async */
++void
++ep2_state_change_notify( int new_state )
++{
++}
++
++/* set feature stall executing, async */
++void
++ep2_stall( void )
++{
++ UDC_set( Ser0UDCCS2, UDCCS2_FST ); /* force stall at UDC */
++}
++
++static void
++ep2_start(void)
++{
++ if (!ep2_len)
++ return;
++
++ ep2_curdmalen = tx_pktsize;
++ if (ep2_curdmalen > ep2_remain)
++ ep2_curdmalen = ep2_remain;
++
++ /* must do this _before_ queue buffer.. */
++ UDC_flip( Ser0UDCCS2,UDCCS2_TPC ); /* stop NAKing IN tokens */
++ UDC_write( Ser0UDCIMP, ep2_curdmalen-1 );
++
++#if 0
++ /* Remove if never seen...8Mar01ww */
++ {
++ int massive_attack = 20;
++ while ( Ser0UDCIMP != ep2_curdmalen-1 && massive_attack-- ) {
++ printk( "usbsnd: Oh no you don't! Let me spin..." );
++ udelay( 500 );
++ printk( "and try again...\n" );
++ UDC_write( Ser0UDCIMP, ep2_curdmalen-1 );
++ }
++ if ( massive_attack != 20 ) {
++ if ( Ser0UDCIMP != ep2_curdmalen-1 )
++ printk( "usbsnd: Massive attack FAILED :-( %d\n",
++ 20 - massive_attack );
++ else
++ printk( "usbsnd: Massive attack WORKED :-) %d\n",
++ 20 - massive_attack );
++ }
++ }
++ /* End remove if never seen... 8Mar01ww */
++#endif
++
++ Ser0UDCAR = usbd_info.address; // fighting stupid silicon bug
++ sa1100_start_dma(dmaregs_tx, ep2_curdmapos, ep2_curdmalen);
++}
++
++static void
++ep2_done(int flag)
++{
++ int size = ep2_len - ep2_remain;
++ if (ep2_len) {
++ dma_unmap_single(NULL, ep2_dma, ep2_len, DMA_TO_DEVICE);
++ ep2_len = 0;
++ if (ep2_callback)
++ ep2_callback(flag, size);
++ }
++}
++
++int
++ep2_init(dma_regs_t *dmaregs)
++{
++ dmaregs_tx = dmaregs;
++ sa1100_reset_dma(dmaregs_tx);
++ ep2_done(-EAGAIN);
++ return 0;
++}
++
++void
++ep2_reset(void)
++{
++ UDC_clear(Ser0UDCCS2, UDCCS2_FST);
++ if (dmaregs_tx)
++ sa1100_reset_dma(dmaregs_tx);
++ ep2_done(-EINTR);
++}
++
++void
++ep2_int_hndlr(int udcsr)
++{
++ int status = Ser0UDCCS2;
++
++ if (Ser0UDCAR != usbd_info.address) // check for stupid silicon bug.
++ Ser0UDCAR = usbd_info.address;
++
++ if (status & UDCCS2_TPC) {
++
++ UDC_flip(Ser0UDCCS2, UDCCS2_SST);
++
++ sa1100_reset_dma(dmaregs_tx);
++
++ if (status & (UDCCS2_TPE | UDCCS2_TUR)) {
++ printk("usb_send: transmit error %x\n", status);
++ ep2_done(-EIO);
++ } else {
++#if 1 // 22Feb01ww/Oleg
++ ep2_curdmapos += ep2_curdmalen;
++ ep2_remain -= ep2_curdmalen;
++#else
++ ep2_curdmapos += Ser0UDCIMP + 1; // this is workaround
++ ep2_remain -= Ser0UDCIMP + 1; // for case when setting of Ser0UDCIMP was failed
++#endif
++
++ if (ep2_remain != 0)
++ ep2_start();
++ else
++ ep2_done(0);
++ }
++ } else {
++ printk("usb_send: Not TPC: UDCCS2 = %x\n", status);
++ }
++}
++
++int
++sa1100_usb_send(struct usb_request *req, void (*callback)(int status, int size))
++{
++ char *buf=req->buf;
++ int len=req->length;
++ unsigned long flags;
++
++ if (usbd_info.state != USB_STATE_CONFIGURED) {
++ PRINTKD("%s: return -ENODEV\n",__FUNCTION__);
++ return -ENODEV;
++ }
++
++ if (ep2_len) {
++ PRINTKD("%s: return -EBUSY\n",__FUNCTION__);
++ return -EBUSY;
++ }
++
++ local_irq_save(flags);
++#ifdef NCB_DMA_FIX
++ // if misaligned, copy to aligned buffer
++// if (((size_t)buf)&3) {
++ if (1) {
++ PRINTKD("%s: copying %d bytes to send_buffer\n",__FUNCTION__,len);
++ memcpy(send_buffer,buf,len);
++ ep2_buf = send_buffer;
++ }
++ else
++#endif
++ ep2_buf = buf;
++
++ ep2_len = len;
++ ep2_dma = dma_map_single(NULL, ep2_buf, len,DMA_TO_DEVICE);
++ PRINTKD("%s: mapped dma to buffer(%p0\n",__FUNCTION__,buf);
++
++ ep2_callback = callback;
++ ep2_remain = len;
++ ep2_curdmapos = ep2_dma;
++
++ PRINTKD("%s: calling ep2_start\n",__FUNCTION__);
++ ep2_start();
++ local_irq_restore(flags);
++
++ return 0;
++}
++/*-------------------------------------------------------------------------*/
++
++static int
++sa1100_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc)
++{
++ struct sa1100_udc *dev;
++ struct sa1100_ep *ep;
++ u32 max;
++ int type;
++
++ ep = container_of (_ep, struct sa1100_ep, ep);
++ if (!_ep || !desc || ep->desc || _ep->name == ep0name
++ || desc->bDescriptorType != USB_DT_ENDPOINT) {
++ PRINTKD("%s: _ep = %p, desc = %p\n",__FUNCTION__,_ep,desc);
++ if (_ep && desc)
++ PRINTKD("%s: ep->desc = %p, _ep->name = %s desc->bDescriptorType = %s\n",__FUNCTION__,ep->desc,_ep->name,
++ (desc->bDescriptorType == USB_DT_ENDPOINT) ? "USB_DT_ENDPOINT":"bad!!");
++ return -EINVAL;
++ }
++
++ dev = ep->dev;
++ if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN)
++ return -ESHUTDOWN;
++
++ type = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
++ max = le16_to_cpu (desc->wMaxPacketSize);
++ switch (max) {
++ case 64: case 32:
++ /* note: maxpacket > 16 means DMA might overrun/underrun */
++ case 16: case 8:
++ break;
++ default:
++ if (type == USB_ENDPOINT_XFER_INT && max < 64)
++ break;
++ return -EDOM;
++ }
++
++ switch (type) {
++ case USB_ENDPOINT_XFER_BULK:
++ case USB_ENDPOINT_XFER_INT:
++ if (ep == &dev->ep[2]) {
++ if (desc->bEndpointAddress != (USB_DIR_IN|2) ) {
++ PRINTKD("%s: ep[2] has invalid endpoint\n",__FUNCTION__);
++ return -EINVAL;
++ }
++ tx_pktsize = max;
++ Ser0UDCOMP = max - 1;
++ PRINTKD("%s: ep2 max packet size is %d\n",__FUNCTION__,max);
++ break;
++ } else if (ep == &dev->ep[1]) {
++ if (desc->bEndpointAddress != (USB_DIR_OUT|1)) {
++ PRINTKD("%s: ep[1] has invalid endpoint\n",__FUNCTION__);
++ return -EINVAL;
++ }
++ rx_pktsize = max;
++ Ser0UDCIMP = max - 1;
++ PRINTKD("%s: ep1 max packet size is %d\n",__FUNCTION__,max);
++ break;
++ }
++ // FALLTHROUGH
++ default:
++ PRINTKD("%s: Invalid endpoint\n",__FUNCTION__);
++ return -EINVAL;
++ }
++
++ _ep->maxpacket = max;
++ ep->desc = desc;
++
++ DEBUG (dev, "enabled %s %s max %04x\n", _ep->name,
++ type_string (desc->bmAttributes), max);
++
++ return 0;
++}
++
++static int sa1100_disable (struct usb_ep *_ep)
++{
++ struct sa1100_ep *ep;
++
++ ep = container_of (_ep, struct sa1100_ep, ep);
++ if (!_ep || !ep->desc || _ep->name == ep0name)
++ return -EINVAL;
++
++ nuke (ep, -ESHUTDOWN);
++
++ DEBUG (ep->dev, "disabled %s\n", _ep->name);
++
++ ep->desc = NULL;
++ ep->stopped = 1;
++ return 0;
++}
++
++/*-------------------------------------------------------------------------*/
++
++static struct usb_request *
++sa1100_alloc_request (struct usb_ep *_ep, int gfp_flags)
++{
++ struct sa1100_request *req;
++
++ if (!_ep)
++ return 0;
++
++ req = kmalloc (sizeof *req, gfp_flags);
++ if (!req)
++ return 0;
++
++ memset (req, 0, sizeof *req);
++ req->req.dma = DMA_ADDR_INVALID;
++ INIT_LIST_HEAD (&req->queue);
++ return &req->req;
++}
++
++static void
++sa1100_free_request (struct usb_ep *_ep, struct usb_request *_req)
++{
++ struct sa1100_request *req;
++
++#if 0 // NCB
++ struct sa1100_ep *ep;
++ ep = container_of (_ep, struct sa1100_ep, ep);
++ if (!ep || !_req || (!ep->desc && _ep->name != ep0name))
++ return;
++ #endif
++
++ req = container_of (_req, struct sa1100_request, req);
++ WARN_ON (!list_empty (&req->queue));
++ kfree(req); //NCB - see pxa2xx_udc
++}
++
++/*-------------------------------------------------------------------------*/
++
++/* allocate buffers this way to eliminate per-io buffer copies */
++
++static void *
++sa1100_alloc_buffer (
++ struct usb_ep *_ep,
++ unsigned bytes,
++ dma_addr_t *dma,
++ int gfp_flags
++)
++{
++ void *retval;
++#if 1 // NCB see pxa2xx_udc
++ retval = kmalloc (bytes, gfp_flags & ~(__GFP_DMA|__GFP_HIGHMEM));
++ if (retval)
++// used in pxa .. *dma = virt_to_bus (retval);
++ *dma = virt_to_phys (retval);
++#else
++ struct sa1100_ep *ep;
++
++ ep = container_of (_ep, struct sa1100_ep, ep);
++ if (!ep || (!ep->desc && _ep->name != ep0name))
++ return 0;
++
++ *dma = DMA_ADDR_INVALID;
++ retval = kmalloc (bytes, GFP_DMA | gfp_flags);
++ if (retval)
++ *dma = virt_to_phys (retval);
++ #endif
++ return retval;
++}
++
++static void
++sa1100_free_buffer (
++ struct usb_ep *_ep,
++ void *buf,
++ dma_addr_t dma,
++ unsigned bytes
++) {
++ kfree (buf);
++}
++
++/*-------------------------------------------------------------------------*/
++
++static void
++done (struct sa1100_ep *ep, struct sa1100_request *req, int status)
++{
++ unsigned stopped = ep->stopped;
++
++
++ list_del_init (&req->queue);
++
++ if (req->req.status == -EINPROGRESS)
++ req->req.status = status;
++ else
++ status = req->req.status;
++
++ if (status && status != -ESHUTDOWN)
++ VDEBUG (ep->dev, "complete %s req %p stat %d len %u/%u\n",
++ ep->ep.name, &req->req, status,
++ req->req.actual, req->req.length);
++
++ /* don't modify queue heads during completion callback */
++ ep->stopped = 1;
++ PRINTKD("%s: calling complete on req\n",__FUNCTION__);
++ req->req.complete (&ep->ep, &req->req);
++ ep->stopped = stopped;
++}
++
++#if 0 // NCB
++void control_done (int value)
++{
++ struct list_head *entry, *tmp;
++ struct sa1100_request *req;
++
++ list_for_each_safe (entry, tmp, &the_controller.ep[0].queue) {
++ req = list_entry (entry, struct sa1100_request, queue);
++
++ /* HACK -- assume no control errors */
++ if (value == 0)
++ req->req.actual = req->req.length;
++#if 1
++ PRINTKD("%s: calling done with ep=%p, req=%p\n",__FUNCTION__,&the_udc.ep[0],req);
++ done (&the_udc.ep[0], req, value);
++#else
++ done (&the_udc.ep0, req, value);
++#endif
++ value = -EPROTO;
++ }
++}
++#endif
++
++/*-------------------------------------------------------------------------*/
++
++/* FIXME move away from the old non-queued api.
++ * - forces extra work on us
++ * - stores request state twice
++ * - doesn't let gadget driver handle dma mapping
++ * - status codes need mapping
++ */
++
++static int map_status (int status)
++{
++ switch (status) {
++ case 0:
++ case -EIO: /* ep[12]_int_handler */
++ return status;
++ case -EPIPE: /* ep1_int_handler */
++ return 0;
++ // case -EAGAIN: /* ep[12]_init */
++ // case -EINTR: /* ep[12]_reset */
++ default:
++ return -ESHUTDOWN;
++ }
++}
++
++static void tx_callback (int status, int size)
++{
++ struct sa1100_ep *ep = &the_controller->ep[2];
++ struct sa1100_request *req;
++
++// PRINTKD("%s: doing ...\n",__FUNCTION__);
++PRINTKD("%s: doing ... status=%d size=%d\n",__FUNCTION__,status,size);
++//PRINTKD("%s: doing ... status=%d\n",__FUNCTION__,status);
++ if (list_empty (&ep->queue)) {
++ if (status != -EAGAIN)
++ DEBUG (ep->dev, "%s, bogus tx callback %d/%d\n",
++ ep->ep.name, status, size);
++// DEBUG (ep->dev, "%s, bogus tx callback %d\n",
++// ep->ep.name, status);
++else
++PRINTKD("%s: list empty.\n",__FUNCTION__);
++ return;
++ }
++ req = list_entry (ep->queue.next, struct sa1100_request, queue);
++ req->req.actual = size;
++ done (ep, req, map_status (status));
++
++PRINTKD("%s: ep->stopped=%s\n",__FUNCTION__,ep->stopped ? "true":"false");
++ if (ep->stopped || list_empty (&ep->queue))
++ return;
++ req = list_entry (ep->queue.next, struct sa1100_request, queue);
++PRINTKD("%s: calling sa1100_usb_send\n",__FUNCTION__);
++ sa1100_usb_send (&req->req, tx_callback);
++}
++
++static void rx_callback (int status, int size)
++{
++ struct sa1100_ep *ep = &the_controller->ep[1];
++ struct sa1100_request *req;
++
++// PRINTKD("%s: doing ...\n",__FUNCTION__);
++PRINTKD("%s: doing ... status=%d\n",__FUNCTION__,status);
++ if (list_empty (&ep->queue)) {
++ if (status != -EAGAIN)
++ DEBUG (ep->dev, "%s, bogus tx callback %d/%d\n",
++ ep->ep.name, status, size);
++ return;
++ }
++ req = list_entry (ep->queue.next, struct sa1100_request, queue);
++ req->req.actual = size;
++ done (ep, req, map_status (status));
++
++ if (ep->stopped || list_empty (&ep->queue))
++ return;
++ req = list_entry (ep->queue.next, struct sa1100_request, queue);
++ sa1100_usb_recv (&req->req, rx_callback);
++}
++
++
++static int
++sa1100_queue (struct usb_ep *_ep, struct usb_request *_req, int gfp_flags)
++{
++ struct sa1100_request *req;
++ struct sa1100_ep *ep;
++ struct sa1100_udc *dev;
++ unsigned long flags;
++
++ req = container_of (_req, struct sa1100_request, req);
++ if (!_req || !_req->complete || !_req->buf
++ || !list_empty (&req->queue))
++ return -EINVAL;
++
++ ep = container_of (_ep, struct sa1100_ep, ep);
++ if (!_ep || (!ep->desc && _ep->name != ep0name))
++ return -EINVAL;
++ dev = ep->dev;
++
++ // handle ep0
++ if (_ep->name == ep0name) {
++ ep0_queue( _req->buf, _req->length, dev->ep0_req_len >=0 ? dev->ep0_req_len: _req->length );
++ return 0;
++ }
++
++ if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN)
++ return -ESHUTDOWN;
++
++ /* sa1100 udc can't write zlps */
++ if (ep == &dev->ep[2] && _req->length == 0)
++ return -ERANGE;
++
++ /* the old sa1100 api doesn't use 'unsigned' for lengths */
++ if (_req->length > INT_MAX)
++ return -ERANGE;
++
++#if 0
++ VDEBUG (dev, "%s queue req %p, len %d buf %p\n",
++ _ep->name, _req, _req->length, _req->buf);
++#endif
++
++ local_irq_save (flags);
++
++ _req->status = -EINPROGRESS;
++ _req->actual = 0;
++
++// NCB if (list_empty) {
++ if (list_empty (&ep->queue) && !ep->stopped) {
++ /* FIXME this does DMA mapping wrong. caller is allowed
++ * to provide buffers that don't need mapping, but this
++ * doesn't use them.
++ */
++ if (ep == &ep->dev->ep[2]) {
++ PRINTKD("%s: sa1100_usb_send buf %p length %d\n",__FUNCTION__,_req->buf,_req->length);
++ sa1100_usb_send (_req, tx_callback);
++ }
++ else if (ep == &ep->dev->ep[1]) {
++ PRINTKD("%s: sa1100_usb_recv buf %p length %d\n",__FUNCTION__,_req->buf,_req->length);
++ sa1100_usb_recv (_req, rx_callback);
++ }
++ /* ep0 rx/tx is handled separately */
++ }
++ list_add_tail (&req->queue, &ep->queue);
++
++ local_irq_restore (flags);
++
++ return 0;
++}
++
++/* dequeue ALL requests */
++static void nuke (struct sa1100_ep *ep, int status)
++{
++ struct sa1100_request *req;
++
++ /* called with irqs blocked */
++ ep->stopped = 1;
++ if (ep == &ep->dev->ep[1])
++ ep1_reset ();
++ else if (ep == &ep->dev->ep[2])
++ ep2_reset ();
++ while (!list_empty (&ep->queue)) {
++ req = list_entry (ep->queue.next,
++ struct sa1100_request,
++ queue);
++ done (ep, req, status);
++ }
++}
++
++/* dequeue JUST ONE request */
++static int sa1100_dequeue (struct usb_ep *_ep, struct usb_request *_req)
++{
++ struct sa1100_ep *ep;
++ struct sa1100_request *req;
++ unsigned long flags;
++
++ ep = container_of (_ep, struct sa1100_ep, ep);
++ req = container_of (_req, struct sa1100_request, req);
++ if (!_ep || (!ep->desc && _ep->name != ep0name) || !_req)
++ 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;
++ }
++
++#if 0
++//#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 pxa2xx_request, queue);
++ kick_dma(ep, req);
++ }
++ } else
++//#endif
++#endif
++ done(ep, req, -ECONNRESET);
++
++ local_irq_restore(flags);
++
++ return 0;
++}
++
++/*-------------------------------------------------------------------------*/
++
++static int
++sa1100_set_halt (struct usb_ep *_ep, int value)
++{
++ struct sa1100_ep *ep;
++
++ ep = container_of (_ep, struct sa1100_ep, ep);
++ if (!_ep || (!ep->desc && _ep->name != ep0name))
++ return -EINVAL;
++ if (!ep->dev->driver || ep->dev->gadget.speed == USB_SPEED_UNKNOWN)
++ return -ESHUTDOWN;
++ if ( (ep->desc->bmAttributes & 0x03) == USB_ENDPOINT_XFER_ISOC)
++ return -EINVAL;
++
++ VDEBUG (ep->dev, "%s %s halt\n", _ep->name, value ? "set" : "clear");
++
++ /* set/clear, then synch memory views with the device */
++ if (value) {
++ if (ep == &ep->dev->ep[1])
++ ep1_stall ();
++ else
++ ep2_stall ();
++ } else {
++ if (ep == &ep->dev->ep[1])
++ ep1_reset ();
++ else
++ ep2_reset ();
++ }
++
++ return 0;
++}
++
++static struct usb_ep_ops sa1100_ep_ops = {
++ .enable = sa1100_enable,
++ .disable = sa1100_disable,
++
++ .alloc_request = sa1100_alloc_request,
++ .free_request = sa1100_free_request,
++
++ .alloc_buffer = sa1100_alloc_buffer,
++ .free_buffer = sa1100_free_buffer,
++
++ .queue = sa1100_queue,
++ .dequeue = sa1100_dequeue,
++
++ .set_halt = sa1100_set_halt,
++ // .fifo_status = sa1100_fifo_status,
++ // .fifo_flush = sa1100_fifo_flush,
++};
++
++/*-------------------------------------------------------------------------*/
++
++static int sa1100_get_frame (struct usb_gadget *_gadget)
++{
++ return -EOPNOTSUPP;
++}
++
++static int sa1100_wakeup (struct usb_gadget *_gadget)
++{
++ struct sa1100_udc *dev;
++
++ if (!_gadget)
++ return 0;
++ dev = container_of (_gadget, struct sa1100_udc, gadget);
++
++ // FIXME
++
++ return 0;
++}
++
++static const struct usb_gadget_ops sa1100_ops = {
++ .get_frame = sa1100_get_frame,
++ .wakeup = sa1100_wakeup,
++
++ // .set_selfpowered = sa1100_set_selfpowered,
++};
++
++/*-------------------------------------------------------------------------*/
++
++static inline void enable_resume_mask_suspend (void)
++{
++ int i = 0;
++
++ while (1) {
++ Ser0UDCCR |= UDCCR_SUSIM; // mask future suspend events
++ udelay (i);
++ if ( (Ser0UDCCR & UDCCR_SUSIM) || (Ser0UDCSR & UDCSR_RSTIR))
++ break;
++ if (++i == 50) {
++ WARN (&the_controller, "%s Could not set SUSIM %8.8X\n",
++ __FUNCTION__, Ser0UDCCR);
++ break;
++ }
++ }
++
++ i = 0;
++ while (1) {
++ Ser0UDCCR &= ~UDCCR_RESIM;
++ udelay (i);
++ if ( (Ser0UDCCR & UDCCR_RESIM) == 0
++ || (Ser0UDCSR & UDCSR_RSTIR))
++ break;
++ if (++i == 50) {
++ WARN (&the_controller, "%s Could not clear RESIM %8.8X\n",
++ __FUNCTION__, Ser0UDCCR);
++ break;
++ }
++ }
++}
++
++static inline void enable_suspend_mask_resume (void)
++{
++ int i = 0;
++ while (1) {
++ Ser0UDCCR |= UDCCR_RESIM; // mask future resume events
++ udelay (i);
++ if (Ser0UDCCR & UDCCR_RESIM || (Ser0UDCSR & UDCSR_RSTIR))
++ break;
++ if (++i == 50) {
++ WARN (&the_controller, "%s could not set RESIM %8.8X\n",
++ __FUNCTION__, Ser0UDCCR);
++ break;
++ }
++ }
++ i = 0;
++ while (1) {
++ Ser0UDCCR &= ~UDCCR_SUSIM;
++ udelay (i);
++ if ( (Ser0UDCCR & UDCCR_SUSIM) == 0
++ || (Ser0UDCSR & UDCSR_RSTIR))
++ break;
++ if (++i == 50) {
++ WARN (&the_controller, "%s Could not clear SUSIM %8.8X\n",
++ __FUNCTION__, Ser0UDCCR);
++ break;
++ }
++ }
++}
++
++// HACK DEBUG 3Mar01ww
++// Well, maybe not, it really seems to help! 08Mar01ww
++static void core_kicker (void)
++{
++ u32 car = Ser0UDCAR;
++ u32 imp = Ser0UDCIMP;
++ u32 omp = Ser0UDCOMP;
++
++ UDC_set (Ser0UDCCR, UDCCR_UDD);
++ udelay (300);
++ UDC_clear (Ser0UDCCR, UDCCR_UDD);
++
++ Ser0UDCAR = car;
++ Ser0UDCIMP = imp;
++ Ser0UDCOMP = omp;
++}
++
++// NCB static void
++static irqreturn_t
++udc_int_hndlr (int irq, void *_dev, struct pt_regs *regs)
++{
++ struct sa1100_udc *dev = _dev;
++ u32 status = Ser0UDCSR;
++
++ u32 control = Ser0UDCCR;
++ PRINTKD("%s: status = 0x%x and control = 0x%x\n",__FUNCTION__,status,control);
++ /* ReSeT Interrupt Request - UDC has been reset */
++ if (status & UDCSR_RSTIR) {
++ PRINTKD("%s: processing UDCSR_RSTIR\n",__FUNCTION__);
++ if (usbctl_next_state_on_event (kEvReset) != kError) {
++ /* starting 20ms or so reset sequence now... */
++ INFO (dev, "Resetting\n");
++ ep0_reset (); // just set state to idle
++ ep1_reset (); // flush dma, clear false stall
++ ep2_reset (); // flush dma, clear false stall
++ }
++ // mask reset ints, they flood during sequence, enable
++ // suspend and resume
++ Ser0UDCCR |= UDCCR_REM; // mask reset
++ Ser0UDCCR &= ~ (UDCCR_SUSIM | UDCCR_RESIM); // enable suspend and resume
++ UDC_flip ( Ser0UDCSR, status); // clear all pending sources
++ PRINTKD("%s: setting USB_FULL_SPEED\n",__FUNCTION__);
++ dev->gadget.speed = USB_SPEED_FULL;
++ return IRQ_HANDLED; // NCB
++ }
++
++ /* else we have done something other than reset,
++ * so be sure reset enabled
++ */
++ UDC_clear (Ser0UDCCR, UDCCR_REM);
++
++ /* RESume Interrupt Request */
++ if (status & UDCSR_RESIR) {
++ struct usb_gadget_driver *driver = dev->driver;
++
++ PRINTKD("%s: processing UDCSR_RESIR\n",__FUNCTION__);
++ if (driver->resume)
++ driver->resume (&dev->gadget);
++ core_kicker ();
++ enable_suspend_mask_resume ();
++ }
++
++ /* SUSpend Interrupt Request */
++ if (status & UDCSR_SUSIR) {
++ struct usb_gadget_driver *driver = dev->driver;
++
++ PRINTKD("%s: processing UDCSR_SUSIR\n",__FUNCTION__);
++ if (driver->suspend)
++ driver->suspend (&dev->gadget);
++ enable_resume_mask_suspend ();
++ }
++
++ UDC_flip (Ser0UDCSR, status); // clear all pending sources
++
++ if (status & UDCSR_EIR)
++ ep0_int_hndlr ();
++
++
++ if (status & UDCSR_RIR) {
++ PRINTKD("%s: processing ep1_int_hndlr\n",__FUNCTION__);
++ ep1_int_hndlr (status);
++ }
++ if (status & UDCSR_TIR) {
++ PRINTKD("%s: processing ep2_int_hndlr\n",__FUNCTION__);
++ ep2_int_hndlr (status);
++ }
++
++ return IRQ_HANDLED; // NCB
++
++}
++
++/* soft_connect_hook ()
++ * Some devices have platform-specific circuitry to make USB
++ * not seem to be plugged in, even when it is. This allows
++ * software to control when a device 'appears' on the USB bus
++ * (after Linux has booted and this driver has loaded, for
++ * example). If you have such a circuit, control it here.
++ */
++#ifdef CONFIG_SA1100_EXTENEX1
++static void soft_connect_hook (int enable)
++{
++ if (machine_is_extenex1 ()) {
++ if (enable) {
++ PPDR |= PPC_USB_SOFT_CON;
++ PPSR |= PPC_USB_SOFT_CON;
++ } else {
++ PPSR &= ~PPC_USB_SOFT_CON;
++ PPDR &= ~PPC_USB_SOFT_CON;
++ }
++ }
++}
++#elif defined(CONFIG_SA1100_BALLOON)
++static void soft_connect_hook (int enable)
++{
++ if (machine_is_balloon()) {
++ if (enable)
++ balloon_udc_connect();
++ else
++ balloon_udc_disconnect();
++ }
++}
++#else
++#define soft_connect_hook(x) do { } while (0);
++#endif
++
++/* "function" sysfs attribute */
++static ssize_t
++show_function (struct device *_dev, char *buf)
++{
++ struct sa1100_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);
++
++/* disable the UDC at the source */
++static void udc_disable (struct sa1100_udc *dev)
++{
++ soft_connect_hook (0);
++ UDC_set (Ser0UDCCR, UDCCR_UDD);
++ dev->gadget.speed = USB_SPEED_UNKNOWN;
++ ep0_idle(dev);
++}
++
++static void udc_reinit(struct sa1100_udc *dev) {
++
++ u32 i;
++
++ /* Initialize the gadget controller data structure */
++ INIT_LIST_HEAD (&dev->gadget.ep_list);
++ INIT_LIST_HEAD (&dev->gadget.ep0->ep_list);
++ ep0_idle(dev);
++ for ( i = 0 ; i < 3 ; i++) {
++ struct sa1100_ep *ep = &dev->ep[i];
++ if (i != 0)
++ list_add_tail(&ep->ep.ep_list, &dev->gadget.ep_list);
++ ep->desc = NULL;
++ ep->stopped = 0;
++ INIT_LIST_HEAD(&ep->queue);
++ }
++}
++
++/* enable the udc at the source */
++static void udc_enable (struct sa1100_udc *dev)
++{
++ UDC_clear (Ser0UDCCR, UDCCR_UDD);
++ ep0_idle(dev);
++}
++
++static void ep0_start (struct sa1100_udc *dev)
++{
++ udc_enable (dev);
++ udelay (100);
++
++ /* clear stall - receiver seems to start stalled? 19Jan01ww */
++ /* also clear other stuff just to be thurough 22Feb01ww */
++ UDC_clear(Ser0UDCCS1, UDCCS1_FST | UDCCS1_RPE | UDCCS1_RPC );
++ UDC_clear(Ser0UDCCS2, UDCCS2_FST | UDCCS2_TPE | UDCCS2_TPC );
++
++ /* mask everything */
++ Ser0UDCCR = 0xFC;
++
++ /* flush DMA and fire through some -EAGAINs */
++ ep1_init (dev->ep[1].dmaregs);
++ ep2_init (dev->ep[2].dmaregs);
++
++ /* enable any platform specific hardware */
++ soft_connect_hook (1);
++
++ /* clear all top-level sources */
++ Ser0UDCSR = UDCSR_RSTIR | UDCSR_RESIR | UDCSR_EIR |
++ UDCSR_RIR | UDCSR_TIR | UDCSR_SUSIR ;
++
++ /* EXERIMENT - a short line in the spec says toggling this
++ * bit diddles the internal state machine in the udc to
++ * expect a suspend
++ */
++ Ser0UDCCR |= UDCCR_RESIM;
++ /* END EXPERIMENT 10Feb01ww */
++
++ /* enable any platform specific hardware */
++ soft_connect_hook (1);
++
++ /* Enable interrupts. If you are unplugged you will immediately
++ * get a suspend interrupt. If you are plugged and have a soft
++ * connect-circuit, you will get a reset. If you are plugged
++ * without a soft-connect, I think you also get suspend. In short,
++ * start with suspend masked and everything else enabled
++ */
++ UDC_write( Ser0UDCCR, UDCCR_SUSIM );
++}
++
++
++/* 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 sa1100_udc *dev = the_controller;
++ int retval;
++
++ if (!driver
++ || !driver->bind
++ || !driver->unbind
++ || !driver->setup)
++ return -EINVAL;
++ if (!dev)
++ return -ENODEV;
++ if (dev->driver)
++ return -EBUSY;
++
++ /* hook up the driver ... */
++ dev->driver = driver;
++ dev->gadget.dev.driver = &driver->driver;
++
++// device_add (&dev->gadget.dev);
++ retval = driver->bind (&dev->gadget);
++ if (retval) {
++ DEBUG (dev, "bind to driver %s --> %d\n",
++ driver->driver.name, retval);
++ device_del(&dev->gadget.dev);
++ dev->driver = NULL;
++ dev->gadget.dev.driver = NULL;
++ return retval;
++ }
++ device_create_file(dev->dev, &dev_attr_function);
++
++ /* ... then enable host detection and ep0; and we're ready
++ * for set_configuration as well as eventual disconnect.
++ */
++ ep0_start (dev);
++
++ DEBUG (dev, "%s ready\n", driver->driver.name);
++
++ return 0;
++}
++EXPORT_SYMBOL (usb_gadget_register_driver);
++
++static void
++stop_activity (struct sa1100_udc *dev, struct usb_gadget_driver *driver)
++{
++ int i;
++
++ /* don't disconnect if it's not connected */
++ if (dev->gadget.speed == USB_SPEED_UNKNOWN)
++ driver = NULL;
++ dev->gadget.speed = USB_SPEED_UNKNOWN;
++
++ /* mask everything */
++ Ser0UDCCR = 0xFC;
++
++ /* stop hardware; prevent new request submissions;
++ * and kill any outstanding requests.
++ */
++ for (i = 0; i < 3; i++) {
++ struct sa1100_ep *ep = &dev->ep[i];
++
++ ep->stopped = 1;
++ nuke(ep, -ESHUTDOWN);
++ }
++ udc_disable (dev);
++
++ /* report disconnect; the driver is already quiesced */
++ if (driver) {
++// spin_unlock (&dev->lock);
++ driver->disconnect (&dev->gadget);
++// spin_lock (&dev->lock);
++ }
++ /* re-init driver-visible data structures */
++ udc_reinit(dev);
++}
++
++int usb_gadget_unregister_driver (struct usb_gadget_driver *driver)
++{
++ struct sa1100_udc *dev = the_controller;
++
++ if (!dev)
++ return -ENODEV;
++ if (!driver || driver != dev->driver)
++ return -EINVAL;
++
++ local_irq_disable();
++ stop_activity (dev, driver);
++ local_irq_enable();
++ driver->unbind (&dev->gadget);
++ dev->driver = 0;
++
++//printk("%s: deleting device\n",__FUNCTION__);
++// device_del (&dev->gadget.dev);
++ device_remove_file(dev->dev, &dev_attr_function);
++
++ DEBUG (dev, "unregistered driver '%s'\n", driver->driver.name);
++ return 0;
++}
++EXPORT_SYMBOL (usb_gadget_unregister_driver);
++
++
++/*-------------------------------------------------------------------------*/
++
++/*-------------------------------------------------------------------------*/
++
++//////////////////////////////////////////////////////////////////////////////
++// Proc Filesystem Support
++//////////////////////////////////////////////////////////////////////////////
++
++#if CONFIG_PROC_FS
++
++#define SAY(fmt,args...) p += sprintf (p, fmt, ## args)
++#define SAYV(num) p += sprintf (p, num_fmt, "Value", num)
++#define SAYC(label,yn) p += sprintf (p, yn_fmt, label, yn)
++#define SAYS(label,v) p += sprintf (p, cnt_fmt, label, v)
++
++static int usbctl_read_proc (char *page, char **start, off_t off,
++ int count, int *eof, void *data)
++{
++ const char * num_fmt = "%25.25s: %8.8lX\n";
++ const char * cnt_fmt = "%25.25s: %lu\n";
++ const char * yn_fmt = "%25.25s: %s\n";
++ const char * yes = "YES";
++ const char * no = "NO";
++ unsigned long v;
++ char * p = page;
++ int len;
++
++ SAY ("SA1100 USB Controller Core\n");
++
++ SAYS ("ep0 bytes read", usbd_info.stats.ep0_bytes_read);
++ SAYS ("ep0 bytes written", usbd_info.stats.ep0_bytes_written);
++ SAYS ("ep0 FIFO read failures", usbd_info.stats.ep0_fifo_read_failures);
++ SAYS ("ep0 FIFO write failures", usbd_info.stats.ep0_fifo_write_failures);
++
++ SAY ("\n");
++
++ v = Ser0UDCAR;
++ SAY ("%25.25s: 0x%8.8lX - %ld\n", "Address Register", v, v);
++ v = Ser0UDCIMP;
++ SAY ("%25.25s: %ld (%8.8lX)\n", "IN max packet size", v+1, v);
++ v = Ser0UDCOMP;
++ SAY ("%25.25s: %ld (%8.8lX)\n", "OUT max packet size", v+1, v);
++
++ v = Ser0UDCCR;
++ SAY ("\nUDC Mask Register\n");
++ SAYV (v);
++ SAYC ("UDC Active", (v & UDCCR_UDA) ? yes : no);
++ SAYC ("Suspend interrupts masked", (v & UDCCR_SUSIM) ? yes : no);
++ SAYC ("Resume interrupts masked", (v & UDCCR_RESIM) ? yes : no);
++ SAYC ("Reset interrupts masked", (v & UDCCR_REM) ? yes : no);
++
++ v = Ser0UDCSR;
++ SAY ("\nUDC Interrupt Request Register\n");
++ SAYV (v);
++ SAYC ("Reset pending", (v & UDCSR_RSTIR) ? yes : no);
++ SAYC ("Suspend pending", (v & UDCSR_SUSIR) ? yes : no);
++ SAYC ("Resume pending", (v & UDCSR_RESIR) ? yes : no);
++ SAYC ("ep0 pending", (v & UDCSR_EIR) ? yes : no);
++ SAYC ("receiver pending", (v & UDCSR_RIR) ? yes : no);
++ SAYC ("tramsitter pending", (v & UDCSR_TIR) ? yes : no);
++
++#ifdef CONFIG_SA1100_EXTENEX1
++ SAYC ("\nSoft connect", (PPSR & PPC_USB_SOFT_CON) ? "Visible" : "Hidden");
++#endif
++
++#if 1
++ SAY ("\nDMA Tx registers\n");
++ {
++ dma_regs_t *r=the_controller->ep[2].dmaregs;
++ SAY (" DDAR");
++ SAYV(r->DDAR);
++ SAY (" DCSR");
++ SAYV(r->RdDCSR);
++ SAY (" DBSA (address buf A) ");
++ SAYV(r->DBSA);
++ SAY (" DBTA (transfer count A) ");
++ SAYV(r->DBTA);
++ SAY (" DBSB (address buf B) ");
++ SAYV(r->DBSB);
++ SAY (" DBTB (transfer count B) ");
++ SAYV(r->DBTB);
++
++ }
++ SAY ("\nDMA Rx registers\n");
++ {
++ dma_regs_t *r=the_controller->ep[1].dmaregs;
++ SAY (" DDAR");
++ SAYV(r->DDAR);
++ SAY (" DCSR");
++ SAYV(r->RdDCSR);
++ SAY (" DBSA (address buf A) ");
++ SAYV(r->DBSA);
++ SAY (" DBTA (transfer count A) ");
++ SAYV(r->DBTA);
++ SAY (" DBSB (address buf B) ");
++ SAYV(r->DBSB);
++ SAY (" DBTB (transfer count B) ");
++ SAYV(r->DBTB);
++
++ }
++#endif
++#if 1
++ v = Ser0UDCCS0;
++ SAY ("\nUDC Endpoint Zero Status Register\n");
++ SAYV (v);
++ SAYC ("Out Packet Ready", (v & UDCCS0_OPR) ? yes : no);
++ SAYC ("In Packet Ready", (v & UDCCS0_IPR) ? yes : no);
++ SAYC ("Sent Stall", (v & UDCCS0_SST) ? yes : no);
++ SAYC ("Force Stall", (v & UDCCS0_FST) ? yes : no);
++ SAYC ("Data End", (v & UDCCS0_DE) ? yes : no);
++ SAYC ("Data Setup End", (v & UDCCS0_SE) ? yes : no);
++ SAYC ("Serviced (SO)", (v & UDCCS0_SO) ? yes : no);
++
++ v = Ser0UDCCS1;
++ SAY ("\nUDC Receiver Status Register\n");
++ SAYV (v);
++ SAYC ("Receive Packet Complete", (v & UDCCS1_RPC) ? yes : no);
++ SAYC ("Sent Stall", (v & UDCCS1_SST) ? yes : no);
++ SAYC ("Force Stall", (v & UDCCS1_FST) ? yes : no);
++ SAYC ("Receive Packet Error", (v & UDCCS1_RPE) ? yes : no);
++ SAYC ("Receive FIFO not empty", (v & UDCCS1_RNE) ? yes : no);
++
++ v = Ser0UDCCS2;
++ SAY ("\nUDC Transmitter Status Register\n");
++ SAYV (v);
++ SAYC ("FIFO has < 8 of 16 chars", (v & UDCCS2_TFS) ? yes : no);
++ SAYC ("Transmit Packet Complete", (v & UDCCS2_TPC) ? yes : no);
++ SAYC ("Transmit FIFO underrun", (v & UDCCS2_TUR) ? yes : no);
++ SAYC ("Transmit Packet Error", (v & UDCCS2_TPE) ? yes : no);
++ SAYC ("Sent Stall", (v & UDCCS2_SST) ? yes : no);
++ SAYC ("Force Stall", (v & UDCCS2_FST) ? yes : no);
++#endif
++
++ len = (p - page) - off;
++ if (len < 0)
++ len = 0;
++ *eof = (len <=count) ? 1 : 0;
++ *start = page + off;
++ return len;
++}
++
++static inline void register_proc_entry (void)
++{
++ create_proc_read_entry (driver_name, 0, NULL,
++ usbctl_read_proc, NULL);
++}
++
++static inline void unregister_proc_entry (void)
++{
++ remove_proc_entry (driver_name, NULL);
++}
++
++#else
++
++#define register_proc_entry() do {} while (0)
++#define unregister_proc_entry() do {} while (0)
++
++#endif /* CONFIG_PROC_FS */
++
++/*-------------------------------------------------------------------------*/
++
++MODULE_DESCRIPTION ("sa1100_udc");
++MODULE_AUTHOR ("Various");
++MODULE_LICENSE ("GPL");
++
++static struct sa1100_udc memory = {
++ .gadget = {
++ .ops = &sa1100_ops,
++ .ep0 = &memory.ep[0].ep,
++ .name = driver_name,
++/*
++ .dev = {
++ .bus_id = "gadget",
++ .release = nop_release,
++ },
++*/
++ },
++
++ /* control endpoint */
++ .ep[0] = {
++ .ep = {
++ .name = ep0name,
++ .ops = &sa1100_ep_ops,
++ .maxpacket = EP0_FIFO_SIZE,
++// .maxpacket = 8,
++ },
++ .dev = &memory,
++/*
++ .reg_udccs = &UDCCS0,
++ .reg_uddr = &UDDR0,
++*/
++ },
++
++ /* first group of endpoints */
++ .ep[1] = {
++ .ep = {
++ .name = "ep1out-bulk",
++ .ops = &sa1100_ep_ops,
++ .maxpacket = BULK_FIFO_SIZE,
++// .maxpacket = 64,
++ },
++ .dev = &memory,
++/*
++ .fifo_size = BULK_FIFO_SIZE,
++ .bEndpointAddress = USB_DIR_IN | 1,
++ .bmAttributes = USB_ENDPOINT_XFER_BULK,
++ .reg_udccs = &UDCCS1,
++ .reg_uddr = &UDDR1,
++ drcmr (25)
++*/
++ },
++ .ep[2] = {
++ .ep = {
++ .name = "ep2in-bulk",
++ .ops = &sa1100_ep_ops,
++ .maxpacket = BULK_FIFO_SIZE,
++// .maxpacket = 64,
++ },
++ .dev = &memory,
++/*
++ .fifo_size = BULK_FIFO_SIZE,
++ .bEndpointAddress = 2,
++ .bmAttributes = USB_ENDPOINT_XFER_BULK,
++ .reg_udccs = &UDCCS2,
++ .reg_ubcr = &UBCR2,
++ .reg_uddr = &UDDR2,
++ drcmr (26)
++*/
++ }
++};
++
++static int __init sa1100_udc_probe ( struct device *_dev)
++{
++ struct sa1100_udc *dev=&memory;
++ int retval = 0;
++
++ /* setup dev */
++ dev->dev = _dev;
++// dev->mach = _dev->platform_data;
++
++ device_initialize(&dev->gadget.dev);
++ dev->gadget.dev.parent = _dev;
++ dev->gadget.dev.dma_mask = _dev->dma_mask;
++
++ the_controller = dev;
++ dev_set_drvdata(_dev, dev);
++
++ /* controller stays disabled until gadget driver is bound */
++ udc_disable (dev);
++ udc_reinit(dev);
++
++// spin_lock_init(&the_udc.lock);
++ register_proc_entry ();
++
++ /* setup dma channels and IRQ */
++ retval = sa1100_request_dma(DMA_Ser0UDCRd, "USB receive",
++ NULL, NULL, &dev->ep[1].dmaregs);
++ if (retval) {
++ ERROR (dev, "couldn't get rx dma, err %d\n", retval);
++ goto err_rx_dma;
++ }
++ retval = sa1100_request_dma(DMA_Ser0UDCWr, "USB transmit",
++ NULL, NULL, &dev->ep[2].dmaregs);
++ if (retval) {
++ ERROR (dev, "couldn't get tx dma, err %d\n", retval);
++ goto err_tx_dma;
++ }
++ retval = request_irq (IRQ_Ser0UDC, udc_int_hndlr, SA_INTERRUPT,
++ driver_name, dev);
++ if (retval) {
++ ERROR (dev, "couldn't get irq, err %d\n", retval);
++ goto err_irq;
++ }
++
++ INFO (dev, "initialized, rx %p tx %p irq %d\n",
++ dev->ep[1].dmaregs, dev->ep[2].dmaregs, IRQ_Ser0UDC);
++ return 0;
++
++err_irq:
++ sa1100_free_dma (dev->ep[2].dmaregs);
++ usbd_info.dmaregs_rx = 0;
++err_tx_dma:
++ sa1100_free_dma (dev->ep[1].dmaregs);
++ usbd_info.dmaregs_tx = 0;
++err_rx_dma:
++ return retval;
++}
++
++static int __exit sa1100_udc_remove (struct device *_dev)
++{
++ struct sa1100_udc *dev = dev_get_drvdata(_dev);
++
++ udc_disable (dev);
++ unregister_proc_entry ();
++ usb_gadget_unregister_driver (dev->driver);
++ sa1100_free_dma (dev->ep[1].dmaregs);
++ sa1100_free_dma (dev->ep[2].dmaregs);
++ free_irq (IRQ_Ser0UDC, dev);
++ dev_set_drvdata(_dev,NULL);
++ the_controller = NULL;
++ return 0;
++}
++
++static struct device_driver udc_driver = {
++ .name = "sa11x0-udc",
++ .bus = &platform_bus_type,
++ .probe = sa1100_udc_probe,
++ .remove = __exit_p(sa1100_udc_remove),
++// .suspend = sa1100_udc_suspend,
++// .resume = sa1100_udc_resume,
++};
++
++static int __init udc_init(void)
++{
++ printk(KERN_INFO "%s: version %s\n", driver_name, DRIVER_VERSION);
++#ifdef NCB_DMA_FIX
++ send_buffer = (char*) kmalloc( SEND_BUFFER_SIZE, GFP_KERNEL | GFP_DMA );
++ receive_buffer = (char*) kmalloc( RECEIVE_BUFFER_SIZE, GFP_KERNEL | GFP_DMA );
++#endif
++ return driver_register(&udc_driver);
++}
++module_init(udc_init);
++
++static void __exit udc_exit(void)
++{
++#ifdef NCB_DMA_FIX
++ if (send_buffer) {
++ kfree(send_buffer);
++ send_buffer=NULL;
++ }
++ if (receive_buffer) {
++ kfree(receive_buffer);
++ receive_buffer=NULL;
++ }
++#endif
++ driver_unregister(&udc_driver);
++}
++module_exit(udc_exit);
++
+diff -uNr linux-2.6.21.vanilla/drivers/usb/gadget/sa1100_udc.h linux-2.6.21/drivers/usb/gadget/sa1100_udc.h
+--- linux-2.6.21.vanilla/drivers/usb/gadget/sa1100_udc.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.21/drivers/usb/gadget/sa1100_udc.h 2007-06-05 11:58:29.000000000 +0200
+@@ -0,0 +1,107 @@
++/*
++ * internals of "new style" UDC controller
++ * <linux/usb_gadget.h> replaces ARM-specific "sa1100_usb.h".
++ */
++
++struct sa1100_ep {
++ struct usb_ep ep;
++ struct sa1100_udc *dev;
++ //unsigned long irqs;
++
++ const struct usb_endpoint_descriptor *desc;
++ struct list_head queue;
++ dma_regs_t *dmaregs;
++ unsigned stopped : 1;
++};
++
++struct sa1100_request {
++ struct usb_request req;
++ struct list_head queue;
++// NCB unsigned mapped : 1;
++};
++
++enum ep0_state {
++ EP0_IDLE,
++ EP0_IN_DATA_PHASE,
++ EP0_OUT_DATA_PHASE,
++ EP0_END_XFER,
++ EP0_STALL,
++};
++
++//#define EP0_FIFO_SIZE ((unsigned)16)
++#define EP0_FIFO_SIZE ((unsigned)8)
++#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;
++};
++
++struct sa1100_udc {
++ struct usb_gadget gadget;
++ struct usb_gadget_driver *driver;
++ struct device *dev;
++ enum ep0_state ep0state;
++ struct udc_stats stats;
++// NCB spinlock_t lock;
++// NCB dma_regs_t *dmaregs_tx, *dmaregs_rx;
++ unsigned got_irq : 1,
++ vbus : 1,
++ pullup : 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;
++ u64 dma_mask;
++ unsigned char address;
++ struct sa1100_ep ep[3];
++ int ep0_req_len;
++};
++
++/*-------------------------------------------------------------------------*/
++
++#define xprintk(dev,level,fmt,args...) \
++ printk(level "%s: " fmt , driver_name , ## args)
++
++#ifdef DEBUG
++#undef DEBUG
++#define DEBUG(dev,fmt,args...) \
++ xprintk(dev , KERN_DEBUG , fmt , ## args)
++#else
++#define DEBUG(dev,fmt,args...) \
++ do { } while (0)
++#endif /* DEBUG */
++
++#ifdef VERBOSE
++#define VDEBUG DEBUG
++#else
++#define VDEBUG(dev,fmt,args...) \
++ do { } while (0)
++#endif /* VERBOSE */
++
++#define ERROR(dev,fmt,args...) \
++ xprintk(dev , KERN_ERR , fmt , ## args)
++#define WARN(dev,fmt,args...) \
++ xprintk(dev , KERN_WARNING , fmt , ## args)
++#define INFO(dev,fmt,args...) \
++ xprintk(dev , KERN_INFO , fmt , ## args)
++
++/*-------------------------------------------------------------------------*/
++
++#ifndef container_of
++#define container_of list_entry
++#endif
++
++#ifndef WARN_ON
++#define WARN_ON(x) do { } while (0)
++#endif
++
++
+diff -uNr linux-2.6.21.vanilla/include/linux/usb_ch9.h linux-2.6.21/include/linux/usb_ch9.h
+--- linux-2.6.21.vanilla/include/linux/usb_ch9.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.21/include/linux/usb_ch9.h 2007-06-05 11:58:29.000000000 +0200
+@@ -0,0 +1,555 @@
++/*
++ * This file holds USB constants and structures that are needed for USB
++ * device APIs. These are used by the USB device model, which is defined
++ * in chapter 9 of the USB 2.0 specification. Linux has several APIs in C
++ * that need these:
++ *
++ * - the master/host side Linux-USB kernel driver API;
++ * - the "usbfs" user space API; and
++ * - the Linux "gadget" slave/device/peripheral side driver API.
++ *
++ * USB 2.0 adds an additional "On The Go" (OTG) mode, which lets systems
++ * act either as a USB master/host or as a USB slave/device. That means
++ * the master and slave side APIs benefit from working well together.
++ *
++ * There's also "Wireless USB", using low power short range radios for
++ * peripheral interconnection but otherwise building on the USB framework.
++ */
++
++#ifndef __LINUX_USB_CH9_H
++#define __LINUX_USB_CH9_H
++
++#include <linux/types.h> /* __u8 etc */
++
++/*-------------------------------------------------------------------------*/
++
++/* CONTROL REQUEST SUPPORT */
++
++/*
++ * USB directions
++ *
++ * This bit flag is used in endpoint descriptors' bEndpointAddress field.
++ * It's also one of three fields in control requests bRequestType.
++ */
++#define USB_DIR_OUT 0 /* to device */
++#define USB_DIR_IN 0x80 /* to host */
++
++/*
++ * USB types, the second of three bRequestType fields
++ */
++#define USB_TYPE_MASK (0x03 << 5)
++#define USB_TYPE_STANDARD (0x00 << 5)
++#define USB_TYPE_CLASS (0x01 << 5)
++#define USB_TYPE_VENDOR (0x02 << 5)
++#define USB_TYPE_RESERVED (0x03 << 5)
++
++/*
++ * USB recipients, the third of three bRequestType fields
++ */
++#define USB_RECIP_MASK 0x1f
++#define USB_RECIP_DEVICE 0x00
++#define USB_RECIP_INTERFACE 0x01
++#define USB_RECIP_ENDPOINT 0x02
++#define USB_RECIP_OTHER 0x03
++
++/*
++ * Standard requests, for the bRequest field of a SETUP packet.
++ *
++ * These are qualified by the bRequestType field, so that for example
++ * TYPE_CLASS or TYPE_VENDOR specific feature flags could be retrieved
++ * by a GET_STATUS request.
++ */
++#define USB_REQ_GET_STATUS 0x00
++#define USB_REQ_CLEAR_FEATURE 0x01
++#define USB_REQ_SET_FEATURE 0x03
++#define USB_REQ_SET_ADDRESS 0x05
++#define USB_REQ_GET_DESCRIPTOR 0x06
++#define USB_REQ_SET_DESCRIPTOR 0x07
++#define USB_REQ_GET_CONFIGURATION 0x08
++#define USB_REQ_SET_CONFIGURATION 0x09
++#define USB_REQ_GET_INTERFACE 0x0A
++#define USB_REQ_SET_INTERFACE 0x0B
++#define USB_REQ_SYNCH_FRAME 0x0C
++
++#define USB_REQ_SET_ENCRYPTION 0x0D /* Wireless USB */
++#define USB_REQ_GET_ENCRYPTION 0x0E
++#define USB_REQ_SET_HANDSHAKE 0x0F
++#define USB_REQ_GET_HANDSHAKE 0x10
++#define USB_REQ_SET_CONNECTION 0x11
++#define USB_REQ_SET_SECURITY_DATA 0x12
++#define USB_REQ_GET_SECURITY_DATA 0x13
++#define USB_REQ_SET_WUSB_DATA 0x14
++#define USB_REQ_LOOPBACK_DATA_WRITE 0x15
++#define USB_REQ_LOOPBACK_DATA_READ 0x16
++#define USB_REQ_SET_INTERFACE_DS 0x17
++
++/*
++ * USB feature flags are written using USB_REQ_{CLEAR,SET}_FEATURE, and
++ * are read as a bit array returned by USB_REQ_GET_STATUS. (So there
++ * are at most sixteen features of each type.)
++ */
++#define USB_DEVICE_SELF_POWERED 0 /* (read only) */
++#define USB_DEVICE_REMOTE_WAKEUP 1 /* dev may initiate wakeup */
++#define USB_DEVICE_TEST_MODE 2 /* (wired high speed only) */
++#define USB_DEVICE_BATTERY 2 /* (wireless) */
++#define USB_DEVICE_B_HNP_ENABLE 3 /* (otg) dev may initiate HNP */
++#define USB_DEVICE_WUSB_DEVICE 3 /* (wireless)*/
++#define USB_DEVICE_A_HNP_SUPPORT 4 /* (otg) RH port supports HNP */
++#define USB_DEVICE_A_ALT_HNP_SUPPORT 5 /* (otg) other RH port does */
++#define USB_DEVICE_DEBUG_MODE 6 /* (special devices only) */
++
++#define USB_ENDPOINT_HALT 0 /* IN/OUT will STALL */
++
++
++/**
++ * struct usb_ctrlrequest - SETUP data for a USB device control request
++ * @bRequestType: matches the USB bmRequestType field
++ * @bRequest: matches the USB bRequest field
++ * @wValue: matches the USB wValue field (le16 byte order)
++ * @wIndex: matches the USB wIndex field (le16 byte order)
++ * @wLength: matches the USB wLength field (le16 byte order)
++ *
++ * This structure is used to send control requests to a USB device. It matches
++ * the different fields of the USB 2.0 Spec section 9.3, table 9-2. See the
++ * USB spec for a fuller description of the different fields, and what they are
++ * used for.
++ *
++ * Note that the driver for any interface can issue control requests.
++ * For most devices, interfaces don't coordinate with each other, so
++ * such requests may be made at any time.
++ */
++struct usb_ctrlrequest {
++ __u8 bRequestType;
++ __u8 bRequest;
++ __le16 wValue;
++ __le16 wIndex;
++ __le16 wLength;
++} __attribute__ ((packed));
++
++/*-------------------------------------------------------------------------*/
++
++/*
++ * STANDARD DESCRIPTORS ... as returned by GET_DESCRIPTOR, or
++ * (rarely) accepted by SET_DESCRIPTOR.
++ *
++ * Note that all multi-byte values here are encoded in little endian
++ * byte order "on the wire". But when exposed through Linux-USB APIs,
++ * they've been converted to cpu byte order.
++ */
++
++/*
++ * Descriptor types ... USB 2.0 spec table 9.5
++ */
++#define USB_DT_DEVICE 0x01
++#define USB_DT_CONFIG 0x02
++#define USB_DT_STRING 0x03
++#define USB_DT_INTERFACE 0x04
++#define USB_DT_ENDPOINT 0x05
++#define USB_DT_DEVICE_QUALIFIER 0x06
++#define USB_DT_OTHER_SPEED_CONFIG 0x07
++#define USB_DT_INTERFACE_POWER 0x08
++/* these are from a minor usb 2.0 revision (ECN) */
++#define USB_DT_OTG 0x09
++#define USB_DT_DEBUG 0x0a
++#define USB_DT_INTERFACE_ASSOCIATION 0x0b
++/* these are from the Wireless USB spec */
++#define USB_DT_SECURITY 0x0c
++#define USB_DT_KEY 0x0d
++#define USB_DT_ENCRYPTION_TYPE 0x0e
++#define USB_DT_BOS 0x0f
++#define USB_DT_DEVICE_CAPABILITY 0x10
++#define USB_DT_WIRELESS_ENDPOINT_COMP 0x11
++
++/* conventional codes for class-specific descriptors */
++#define USB_DT_CS_DEVICE 0x21
++#define USB_DT_CS_CONFIG 0x22
++#define USB_DT_CS_STRING 0x23
++#define USB_DT_CS_INTERFACE 0x24
++#define USB_DT_CS_ENDPOINT 0x25
++
++/* All standard descriptors have these 2 fields at the beginning */
++struct usb_descriptor_header {
++ __u8 bLength;
++ __u8 bDescriptorType;
++} __attribute__ ((packed));
++
++
++/*-------------------------------------------------------------------------*/
++
++/* USB_DT_DEVICE: Device descriptor */
++struct usb_device_descriptor {
++ __u8 bLength;
++ __u8 bDescriptorType;
++
++ __le16 bcdUSB;
++ __u8 bDeviceClass;
++ __u8 bDeviceSubClass;
++ __u8 bDeviceProtocol;
++ __u8 bMaxPacketSize0;
++ __le16 idVendor;
++ __le16 idProduct;
++ __le16 bcdDevice;
++ __u8 iManufacturer;
++ __u8 iProduct;
++ __u8 iSerialNumber;
++ __u8 bNumConfigurations;
++} __attribute__ ((packed));
++
++#define USB_DT_DEVICE_SIZE 18
++
++
++/*
++ * Device and/or Interface Class codes
++ * as found in bDeviceClass or bInterfaceClass
++ * and defined by www.usb.org documents
++ */
++#define USB_CLASS_PER_INTERFACE 0 /* for DeviceClass */
++#define USB_CLASS_AUDIO 1
++#define USB_CLASS_COMM 2
++#define USB_CLASS_HID 3
++#define USB_CLASS_PHYSICAL 5
++#define USB_CLASS_STILL_IMAGE 6
++#define USB_CLASS_PRINTER 7
++#define USB_CLASS_MASS_STORAGE 8
++#define USB_CLASS_HUB 9
++#define USB_CLASS_CDC_DATA 0x0a
++#define USB_CLASS_CSCID 0x0b /* chip+ smart card */
++#define USB_CLASS_CONTENT_SEC 0x0d /* content security */
++#define USB_CLASS_VIDEO 0x0e
++#define USB_CLASS_WIRELESS_CONTROLLER 0xe0
++#define USB_CLASS_APP_SPEC 0xfe
++#define USB_CLASS_VENDOR_SPEC 0xff
++
++/*-------------------------------------------------------------------------*/
++
++/* USB_DT_CONFIG: Configuration descriptor information.
++ *
++ * USB_DT_OTHER_SPEED_CONFIG is the same descriptor, except that the
++ * descriptor type is different. Highspeed-capable devices can look
++ * different depending on what speed they're currently running. Only
++ * devices with a USB_DT_DEVICE_QUALIFIER have any OTHER_SPEED_CONFIG
++ * descriptors.
++ */
++struct usb_config_descriptor {
++ __u8 bLength;
++ __u8 bDescriptorType;
++
++ __le16 wTotalLength;
++ __u8 bNumInterfaces;
++ __u8 bConfigurationValue;
++ __u8 iConfiguration;
++ __u8 bmAttributes;
++ __u8 bMaxPower;
++} __attribute__ ((packed));
++
++#define USB_DT_CONFIG_SIZE 9
++
++/* from config descriptor bmAttributes */
++#define USB_CONFIG_ATT_ONE (1 << 7) /* must be set */
++#define USB_CONFIG_ATT_SELFPOWER (1 << 6) /* self powered */
++#define USB_CONFIG_ATT_WAKEUP (1 << 5) /* can wakeup */
++#define USB_CONFIG_ATT_BATTERY (1 << 4) /* battery powered */
++
++/*-------------------------------------------------------------------------*/
++
++/* USB_DT_STRING: String descriptor */
++struct usb_string_descriptor {
++ __u8 bLength;
++ __u8 bDescriptorType;
++
++ __le16 wData[1]; /* UTF-16LE encoded */
++} __attribute__ ((packed));
++
++/* note that "string" zero is special, it holds language codes that
++ * the device supports, not Unicode characters.
++ */
++
++/*-------------------------------------------------------------------------*/
++
++/* USB_DT_INTERFACE: Interface descriptor */
++struct usb_interface_descriptor {
++ __u8 bLength;
++ __u8 bDescriptorType;
++
++ __u8 bInterfaceNumber;
++ __u8 bAlternateSetting;
++ __u8 bNumEndpoints;
++ __u8 bInterfaceClass;
++ __u8 bInterfaceSubClass;
++ __u8 bInterfaceProtocol;
++ __u8 iInterface;
++} __attribute__ ((packed));
++
++#define USB_DT_INTERFACE_SIZE 9
++
++/*-------------------------------------------------------------------------*/
++
++/* USB_DT_ENDPOINT: Endpoint descriptor */
++struct usb_endpoint_descriptor {
++ __u8 bLength;
++ __u8 bDescriptorType;
++
++ __u8 bEndpointAddress;
++ __u8 bmAttributes;
++ __le16 wMaxPacketSize;
++ __u8 bInterval;
++
++ /* NOTE: these two are _only_ in audio endpoints. */
++ /* use USB_DT_ENDPOINT*_SIZE in bLength, not sizeof. */
++ __u8 bRefresh;
++ __u8 bSynchAddress;
++} __attribute__ ((packed));
++
++#define USB_DT_ENDPOINT_SIZE 7
++#define USB_DT_ENDPOINT_AUDIO_SIZE 9 /* Audio extension */
++
++
++/*
++ * Endpoints
++ */
++#define USB_ENDPOINT_NUMBER_MASK 0x0f /* in bEndpointAddress */
++#define USB_ENDPOINT_DIR_MASK 0x80
++
++#define USB_ENDPOINT_XFERTYPE_MASK 0x03 /* in bmAttributes */
++#define USB_ENDPOINT_XFER_CONTROL 0
++#define USB_ENDPOINT_XFER_ISOC 1
++#define USB_ENDPOINT_XFER_BULK 2
++#define USB_ENDPOINT_XFER_INT 3
++#define USB_ENDPOINT_MAX_ADJUSTABLE 0x80
++
++
++/*-------------------------------------------------------------------------*/
++
++/* USB_DT_DEVICE_QUALIFIER: Device Qualifier descriptor */
++struct usb_qualifier_descriptor {
++ __u8 bLength;
++ __u8 bDescriptorType;
++
++ __le16 bcdUSB;
++ __u8 bDeviceClass;
++ __u8 bDeviceSubClass;
++ __u8 bDeviceProtocol;
++ __u8 bMaxPacketSize0;
++ __u8 bNumConfigurations;
++ __u8 bRESERVED;
++} __attribute__ ((packed));
++
++
++/*-------------------------------------------------------------------------*/
++
++/* USB_DT_OTG (from OTG 1.0a supplement) */
++struct usb_otg_descriptor {
++ __u8 bLength;
++ __u8 bDescriptorType;
++
++ __u8 bmAttributes; /* support for HNP, SRP, etc */
++} __attribute__ ((packed));
++
++/* from usb_otg_descriptor.bmAttributes */
++#define USB_OTG_SRP (1 << 0)
++#define USB_OTG_HNP (1 << 1) /* swap host/device roles */
++
++/*-------------------------------------------------------------------------*/
++
++/* USB_DT_DEBUG: for special highspeed devices, replacing serial console */
++struct usb_debug_descriptor {
++ __u8 bLength;
++ __u8 bDescriptorType;
++
++ /* bulk endpoints with 8 byte maxpacket */
++ __u8 bDebugInEndpoint;
++ __u8 bDebugOutEndpoint;
++};
++
++/*-------------------------------------------------------------------------*/
++
++/* USB_DT_INTERFACE_ASSOCIATION: groups interfaces */
++struct usb_interface_assoc_descriptor {
++ __u8 bLength;
++ __u8 bDescriptorType;
++
++ __u8 bFirstInterface;
++ __u8 bInterfaceCount;
++ __u8 bFunctionClass;
++ __u8 bFunctionSubClass;
++ __u8 bFunctionProtocol;
++ __u8 iFunction;
++} __attribute__ ((packed));
++
++
++/*-------------------------------------------------------------------------*/
++
++/* USB_DT_SECURITY: group of wireless security descriptors, including
++ * encryption types available for setting up a CC/association.
++ */
++struct usb_security_descriptor {
++ __u8 bLength;
++ __u8 bDescriptorType;
++
++ __le16 wTotalLength;
++ __u8 bNumEncryptionTypes;
++};
++
++/*-------------------------------------------------------------------------*/
++
++/* USB_DT_KEY: used with {GET,SET}_SECURITY_DATA; only public keys
++ * may be retrieved.
++ */
++struct usb_key_descriptor {
++ __u8 bLength;
++ __u8 bDescriptorType;
++
++ __u8 tTKID[3];
++ __u8 bReserved;
++ __u8 bKeyData[0];
++};
++
++/*-------------------------------------------------------------------------*/
++
++/* USB_DT_ENCRYPTION_TYPE: bundled in DT_SECURITY groups */
++struct usb_encryption_descriptor {
++ __u8 bLength;
++ __u8 bDescriptorType;
++
++ __u8 bEncryptionType;
++#define USB_ENC_TYPE_UNSECURE 0
++#define USB_ENC_TYPE_WIRED 1 /* non-wireless mode */
++#define USB_ENC_TYPE_CCM_1 2 /* aes128/cbc session */
++#define USB_ENC_TYPE_RSA_1 3 /* rsa3072/sha1 auth */
++ __u8 bEncryptionValue; /* use in SET_ENCRYPTION */
++ __u8 bAuthKeyIndex;
++};
++
++
++/*-------------------------------------------------------------------------*/
++
++/* USB_DT_BOS: group of wireless capabilities */
++struct usb_bos_descriptor {
++ __u8 bLength;
++ __u8 bDescriptorType;
++
++ __le16 wTotalLength;
++ __u8 bNumDeviceCaps;
++};
++
++/*-------------------------------------------------------------------------*/
++
++/* USB_DT_DEVICE_CAPABILITY: grouped with BOS */
++struct usb_dev_cap_header {
++ __u8 bLength;
++ __u8 bDescriptorType;
++ __u8 bDevCapabilityType;
++};
++
++#define USB_CAP_TYPE_WIRELESS_USB 1
++
++struct usb_wireless_cap_descriptor { /* Ultra Wide Band */
++ __u8 bLength;
++ __u8 bDescriptorType;
++ __u8 bDevCapabilityType;
++
++ __u8 bmAttributes;
++#define USB_WIRELESS_P2P_DRD (1 << 1)
++#define USB_WIRELESS_BEACON_MASK (3 << 2)
++#define USB_WIRELESS_BEACON_SELF (1 << 2)
++#define USB_WIRELESS_BEACON_DIRECTED (2 << 2)
++#define USB_WIRELESS_BEACON_NONE (3 << 2)
++ __le16 wPHYRates; /* bit rates, Mbps */
++#define USB_WIRELESS_PHY_53 (1 << 0) /* always set */
++#define USB_WIRELESS_PHY_80 (1 << 1)
++#define USB_WIRELESS_PHY_107 (1 << 2) /* always set */
++#define USB_WIRELESS_PHY_160 (1 << 3)
++#define USB_WIRELESS_PHY_200 (1 << 4) /* always set */
++#define USB_WIRELESS_PHY_320 (1 << 5)
++#define USB_WIRELESS_PHY_400 (1 << 6)
++#define USB_WIRELESS_PHY_480 (1 << 7)
++ __u8 bmTFITXPowerInfo; /* TFI power levels */
++ __u8 bmFFITXPowerInfo; /* FFI power levels */
++ __le16 bmBandGroup;
++ __u8 bReserved;
++};
++
++/*-------------------------------------------------------------------------*/
++
++/* USB_DT_WIRELESS_ENDPOINT_COMP: companion descriptor associated with
++ * each endpoint descriptor for a wireless device
++ */
++struct usb_wireless_ep_comp_descriptor {
++ __u8 bLength;
++ __u8 bDescriptorType;
++
++ __u8 bMaxBurst;
++ __u8 bMaxSequence;
++ __le16 wMaxStreamDelay;
++ __le16 wOverTheAirPacketSize;
++ __u8 bOverTheAirInterval;
++ __u8 bmCompAttributes;
++#define USB_ENDPOINT_SWITCH_MASK 0x03 /* in bmCompAttributes */
++#define USB_ENDPOINT_SWITCH_NO 0
++#define USB_ENDPOINT_SWITCH_SWITCH 1
++#define USB_ENDPOINT_SWITCH_SCALE 2
++};
++
++/*-------------------------------------------------------------------------*/
++
++/* USB_REQ_SET_HANDSHAKE is a four-way handshake used between a wireless
++ * host and a device for connection set up, mutual authentication, and
++ * exchanging short lived session keys. The handshake depends on a CC.
++ */
++struct usb_handshake {
++ __u8 bMessageNumber;
++ __u8 bStatus;
++ __u8 tTKID[3];
++ __u8 bReserved;
++ __u8 CDID[16];
++ __u8 nonce[16];
++ __u8 MIC[8];
++};
++
++/*-------------------------------------------------------------------------*/
++
++/* USB_REQ_SET_CONNECTION modifies or revokes a connection context (CC).
++ * A CC may also be set up using non-wireless secure channels (including
++ * wired USB!), and some devices may support CCs with multiple hosts.
++ */
++struct usb_connection_context {
++ __u8 CHID[16]; /* persistent host id */
++ __u8 CDID[16]; /* device id (unique w/in host context) */
++ __u8 CK[16]; /* connection key */
++};
++
++/*-------------------------------------------------------------------------*/
++
++/* USB 2.0 defines three speeds, here's how Linux identifies them */
++
++enum usb_device_speed {
++ USB_SPEED_UNKNOWN = 0, /* enumerating */
++ USB_SPEED_LOW, USB_SPEED_FULL, /* usb 1.1 */
++ USB_SPEED_HIGH, /* usb 2.0 */
++ USB_SPEED_VARIABLE, /* wireless (usb 2.5) */
++};
++
++enum usb_device_state {
++ /* NOTATTACHED isn't in the USB spec, and this state acts
++ * the same as ATTACHED ... but it's clearer this way.
++ */
++ USB_STATE_NOTATTACHED = 0,
++
++ /* chapter 9 and authentication (wireless) device states */
++ USB_STATE_ATTACHED,
++ USB_STATE_POWERED, /* wired */
++ USB_STATE_UNAUTHENTICATED, /* auth */
++ USB_STATE_RECONNECTING, /* auth */
++ USB_STATE_DEFAULT, /* limited function */
++ USB_STATE_ADDRESS,
++ USB_STATE_CONFIGURED, /* most functions */
++
++ USB_STATE_SUSPENDED
++
++ /* NOTE: there are actually four different SUSPENDED
++ * states, returning to POWERED, DEFAULT, ADDRESS, or
++ * CONFIGURED respectively when SOF tokens flow again.
++ */
++};
++
++#endif /* __LINUX_USB_CH9_H */
diff --git a/recipes/linux/linux/simpad/linux-2.6.24-SIMpad-GPIO-MMC-mod.patch b/recipes/linux/linux/simpad/linux-2.6.24-SIMpad-GPIO-MMC-mod.patch
new file mode 100644
index 0000000000..70a1555158
--- /dev/null
+++ b/recipes/linux/linux/simpad/linux-2.6.24-SIMpad-GPIO-MMC-mod.patch
@@ -0,0 +1,1699 @@
+diff -Nur linux-2.6.24.vanilla/drivers/mmc/card/Makefile linux-2.6.24/drivers/mmc/card/Makefile
+--- linux-2.6.24.vanilla/drivers/mmc/card/Makefile 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24/drivers/mmc/card/Makefile 2008-02-23 03:10:45.000000000 +0100
+@@ -6,8 +6,11 @@
+ EXTRA_CFLAGS += -DDEBUG
+ endif
+
++ifeq ($(CONFIG_SA1100_SIMPAD),y)
++# nothing to do
++else
+ obj-$(CONFIG_MMC_BLOCK) += mmc_block.o
+ mmc_block-objs := block.o queue.o
+
+ obj-$(CONFIG_SDIO_UART) += sdio_uart.o
+-
++endif
+diff -Nur linux-2.6.24.vanilla/drivers/mmc/core/Makefile linux-2.6.24/drivers/mmc/core/Makefile
+--- linux-2.6.24.vanilla/drivers/mmc/core/Makefile 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24/drivers/mmc/core/Makefile 2008-02-23 03:10:45.000000000 +0100
+@@ -6,9 +6,13 @@
+ EXTRA_CFLAGS += -DDEBUG
+ endif
+
++ifeq ($(CONFIG_SA1100_SIMPAD),y)
++# nothing to do
++else
+ obj-$(CONFIG_MMC) += mmc_core.o
+ mmc_core-y := core.o sysfs.o bus.o host.o \
+ mmc.o mmc_ops.o sd.o sd_ops.o \
+ sdio.o sdio_ops.o sdio_bus.o \
+ sdio_cis.o sdio_io.o sdio_irq.o
++endif
+
+diff -Nur linux-2.6.24.vanilla/drivers/mmc/host/Kconfig linux-2.6.24/drivers/mmc/host/Kconfig
+--- linux-2.6.24.vanilla/drivers/mmc/host/Kconfig 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24/drivers/mmc/host/Kconfig 2008-02-23 03:10:45.000000000 +0100
+@@ -4,6 +4,7 @@
+
+ comment "MMC/SD Host Controller Drivers"
+
++
+ config MMC_ARMMMCI
+ tristate "ARM AMBA Multimedia Card Interface support"
+ depends on ARM_AMBA
+@@ -130,3 +131,9 @@
+
+ If unsure, or if your system has no SPI master driver, say N.
+
++config MMC_SPI_BLOCK
++ tristate "MMC/SD over GPIO (Software SPI) for SIMpad (EXPERIMENTAL)"
++ depends on SA1100_SIMPAD && EXPERIMENTAL
++ help
++ Say Y here to enable MMC block device over GPIO
++ if you have done the MMC-Mod. For Module say M.
+diff -Nur linux-2.6.24.vanilla/drivers/mmc/host/Makefile linux-2.6.24/drivers/mmc/host/Makefile
+--- linux-2.6.24.vanilla/drivers/mmc/host/Makefile 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24/drivers/mmc/host/Makefile 2008-02-23 03:10:45.000000000 +0100
+@@ -6,6 +6,9 @@
+ EXTRA_CFLAGS += -DDEBUG
+ endif
+
++ifeq ($(CONFIG_SA1100_SIMPAD),y)
++obj-$(CONFIG_MMC_SPI_BLOCK) += mmc_spi_block.o
++else
+ obj-$(CONFIG_MMC_ARMMMCI) += mmci.o
+ obj-$(CONFIG_MMC_PXA) += pxamci.o
+ obj-$(CONFIG_MMC_IMX) += imxmmc.o
+@@ -17,4 +20,4 @@
+ obj-$(CONFIG_MMC_AT91) += at91_mci.o
+ obj-$(CONFIG_MMC_TIFM_SD) += tifm_sd.o
+ obj-$(CONFIG_MMC_SPI) += mmc_spi.o
+-
++endif
+diff -Nur linux-2.6.24.vanilla/drivers/mmc/host/mmc_spi_block.c linux-2.6.24/drivers/mmc/host/mmc_spi_block.c
+--- linux-2.6.24.vanilla/drivers/mmc/host/mmc_spi_block.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24/drivers/mmc/host/mmc_spi_block.c 2008-02-23 03:10:45.000000000 +0100
+@@ -0,0 +1,1622 @@
++/*
++ * Copyright (c) Cl�ent Ballabriga, 2005 - GPL
++ * Copyright (c) Guylhem Aznar, 2005 - GPL
++ *
++ * Please check http://externe.net/zaurus/simpad-bluetooth reference design first.
++ *
++ * Based on Madsuk/Rohde work on a MMC driver for the WRT54G.
++ *
++ * This is an ugly hack of a driver. I am surprised if it ever works!
++ * So please use a real driver or contribute one to the 2.4/2.6 mmc framework
++ *
++ * mrdata: ported to 2.6
++ */
++
++#include <linux/module.h>
++#include <linux/init.h>
++
++#include <linux/sched.h>
++#include <linux/kernel.h>
++#include <linux/fs.h>
++#include <linux/errno.h>
++#include <linux/hdreg.h>
++#include <linux/kdev_t.h>
++#include <linux/blkdev.h>
++#include <linux/spinlock.h>
++#include <linux/time.h>
++#include <linux/delay.h>
++#include <linux/timer.h>
++
++#include <linux/platform_device.h>
++
++#include <asm/hardware.h>
++#include <asm/arch/simpad.h>
++#include <asm/arch/gpio.h>
++
++static int major = 121;
++
++#define DEVICE_NAME "mmc_spi"
++
++static int hd_sizes[1<<6];
++static int hd_blocksizes[1<<6];
++static int hd_hardsectsizes[1<<6];
++static int hd_maxsect[1<<6];
++static struct hd_struct hd[1<<6];
++
++static struct gendisk *mmc_disk;
++
++static struct platform_device *mmc_dev; /* the one and only instance */
++
++static spinlock_t mmc_spi_lock;
++
++/*
++ * *******************************************************************
++ *
++ * This is the only configurable part.
++ *
++ * *******************************************************************
++ *
++ */
++
++// #define DEBUG 1
++// #define DEBUG_HD 1
++// #define CHECK_MEDIA_CHANGE // for developement ONLY, not working yet
++
++/* Let that include where it is or compilation fails on INIT_REQUEST/CURRENT */
++
++
++/*
++ * If you are using different GPIOs in your hardware hack, you must
++ * first make sure they are unused for other functions and then
++ * configure them here.
++ *
++ * On the simpad I use spare pins from the UART1 (internal serial port -> DECT 20-polig):
++ *
++ * Funktion PIN ## Original direction GPIO ## SPI function New direction SD/MMC
++ * - DCD PIN 08 (in) GPIO 23 DO - new name: DI -> MISO (in) PIN 7 Data Out
++ * - DTR PIN 11 (out) GPIO 07 CS (out) PIN 1 Chip Select
++ * - RI PIN 14 (in) GPIO 19 CLK (out) PIN 5 Clock
++ * - DSR PIN 16 (in) GPIO 06 DI - new name: DO -> MOSI (out) PIN 2 Data In
++ *
++ *
++ * SPI: MISO = Master In / Slave OUT MOSI = Master Out / Slave In
++ *
++ * Don't worry about in/out original function - the GPIOs will be
++ * reprogrammed.
++ */
++
++#define GPIO_SD_DI 23
++#define GPIO_SD_CS 7
++#define GPIO_SD_CLK 19
++#define GPIO_SD_DO 6
++
++// #define FAST_GPIO_SD_DI GPIO_GPIO23
++// #define FAST_GPIO_SD_CS GPIO_GPIO7
++// #define FAST_GPIO_SD_CLK GPIO_GPIO19
++// #define FAST_GPIO_SD_DO GPIO_GPIO6
++
++#define FAST_GPIO_SD_DI GPIO_UART1_DCD
++#define FAST_GPIO_SD_CS GPIO_UART1_DTR
++#define FAST_GPIO_SD_CLK GPIO_UART1_RI
++#define FAST_GPIO_SD_DO GPIO_UART1_DSR
++
++/*
++ * *******************************************************************
++ *
++ * Do not change anything below !
++ *
++ * *******************************************************************
++ *
++ */
++
++/* GPIO states */
++#define LOW 0
++#define HIGH 1
++
++#define INPUT 0
++#define OUTPUT 1
++
++#define PRESENT 1
++#define ABSENT 0
++
++typedef unsigned int uint32;
++typedef unsigned long u32_t;
++typedef unsigned short u16_t;
++typedef unsigned char u8_t;
++
++// static struct timer_list mmc_timer;
++
++// static struct timeval s_zeit, e_zeit;
++
++/* start with no card */
++static int mmc_media_detect = 0;
++// static int mmc_media_changed = 1;
++
++
++/////////////////////
++// prototypes
++static int mmc_open(struct inode *inode, struct file *filp);
++static int mmc_release(struct inode *inode, struct file *filp);
++static int mmc_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg);
++static void mmc_spi_request(struct request_queue *q);
++
++
++/*
++ * *******************************************************************
++ *
++ * Begin GPIO hardware access functions.
++ *
++ * *******************************************************************
++ *
++ */
++
++#define gpio_read(a) ((GPLR & a) ? 1 : 0)
++#define gpio_write_high(a) GPSR = a
++#define gpio_write_low(a) GPCR = a
++
++/* set MMC_Chip_Select to HIGH (MMC/SD-Card inactiv) */
++#define MMC_Disable() gpio_write_high( FAST_GPIO_SD_CS)
++
++/* set MMC_Chip_Select to LOW (MMC/SD-Card activ) */
++#define MMC_Enable() gpio_write_low( FAST_GPIO_SD_CS)
++
++/*
++ * *******************************************************************
++ *
++ * Begin SPI hardware access functions.
++ *
++ * *******************************************************************
++ *
++ */
++static int mmc_spi_media_detect(void)
++{
++// FIXME: add card detection/test by SPI
++
++ return 1;
++}
++
++static int mmc_spi_hardware_init(void)
++{
++ printk("\nmmc: GPIO init\n");
++
++ /* cut existing functions */
++ gpio_set_alternative_function(GPIO_SD_CLK, 0);
++ gpio_set_alternative_function(GPIO_SD_DI, 0);
++ gpio_set_alternative_function(GPIO_SD_DO, 0);
++ gpio_set_alternative_function(GPIO_SD_CS, 0);
++
++ /* remap directions and set state of spi pins */
++ gpio_direction_output(GPIO_SD_CLK, 0);
++ gpio_direction_input(GPIO_SD_DI);
++ gpio_direction_output(GPIO_SD_DO, 0);
++ gpio_direction_output(GPIO_SD_CS, 0);
++
++ printk("mmc: initialising MMC\n");
++
++ /* Start */
++ MMC_Disable();
++ gpio_write_low( FAST_GPIO_SD_CLK);
++ gpio_write_high( FAST_GPIO_SD_DO);
++ return 0;
++}
++
++/* return what has been read, write the parameter */
++/* Clockrate round about 1,2 MHz */
++
++static unsigned char mmc_spi_readwrite(unsigned char data_out)
++{
++ unsigned char i;
++ unsigned char result = 0;
++
++ for(i = 0x80 ; i != 0 ; i >>= 1)
++ {
++ if (data_out & i)
++ {
++ gpio_write_high( FAST_GPIO_SD_DO);
++ }
++ else
++ {
++ gpio_write_low( FAST_GPIO_SD_DO);
++ }
++
++ gpio_write_high( FAST_GPIO_SD_CLK);
++
++ if (gpio_read( FAST_GPIO_SD_DI) == 1)
++ {
++ result |= i;
++ }
++
++ gpio_write_low( FAST_GPIO_SD_CLK);
++
++ }
++
++ gpio_write_high( FAST_GPIO_SD_DO);
++
++ return (result);
++}
++
++/* return what has been read, write the parameter */
++/* Clockrate round 200 kHz */
++
++static unsigned char mmc_spi_readwrite_slow(unsigned char data_out)
++{
++ unsigned char i;
++ unsigned char result = 0;
++
++ for(i = 0x80 ; i != 0 ; i >>= 1)
++ {
++ if (data_out & i)
++ {
++ gpio_write_high( FAST_GPIO_SD_DO);
++ }
++ else
++ {
++ gpio_write_low( FAST_GPIO_SD_DO);
++ }
++
++ udelay(10);
++
++ gpio_write_high( FAST_GPIO_SD_CLK);
++
++ udelay(10);
++
++ if (gpio_read( FAST_GPIO_SD_DI) == 1)
++ {
++ result |= i;
++ }
++
++ udelay(10);
++
++ gpio_write_low( FAST_GPIO_SD_CLK);
++
++ udelay(10);
++
++ }
++
++ gpio_write_high( FAST_GPIO_SD_DO);
++
++ udelay(10);
++
++ // printk("Send Byte = 0x%2X Receive Byte = 0x%2X \n", data_out, result);
++
++ return (result);
++}
++
++/* return what has been read */
++
++static unsigned char mmc_spi_read_only(void)
++{
++ unsigned char i;
++ unsigned char result = 0;
++
++ for(i = 0x80 ; i != 0 ; i >>= 1)
++ {
++
++ gpio_write_high( FAST_GPIO_SD_CLK);
++
++ if (gpio_read( FAST_GPIO_SD_DI) == 1)
++ {
++ result |= i;
++ }
++
++ gpio_write_low( FAST_GPIO_SD_CLK);
++
++ }
++
++ return (result);
++}
++
++/* write the parameter */
++/* Clockrate round about 3,6 MHz */
++
++static unsigned char mmc_spi_write_only(unsigned char data_out)
++{
++ unsigned char i;
++ unsigned char result = 0;
++
++ for(i = 0x80 ; i != 0 ; i >>= 1)
++ {
++
++ if (data_out & i)
++ {
++ gpio_write_high( FAST_GPIO_SD_DO);
++ }
++ else
++ {
++ gpio_write_low( FAST_GPIO_SD_DO);
++ }
++
++ gpio_write_high( FAST_GPIO_SD_CLK);
++
++ gpio_write_low( FAST_GPIO_SD_CLK);
++
++ }
++
++ gpio_write_high( FAST_GPIO_SD_DO);
++
++ return (result);
++}
++
++
++/**
++ * this function was contributed by: rcichielo from openwrt forums
++ *
++ * Comments added by Marc DENTY on 2007-03-20
++ *
++ * Sequence to read a card's "CID" bytes (name, serial number etc)
++ *
++ * Send: 4ah,00h,00h,00h,00h,00h - CMD10, no args, null CRC
++ * Read: xx - NCR Time
++ * Read: xx - Command Response (Should be 00h)
++ * Read: until FEh is received - Wait for Data token
++ * Read: yy * 16 - Get 16 bytes from CID
++ * Read: zz - Read CRC lo byte
++ * Read: zz - Read CRC hi byte
++ *
++ * Useful locations in the returned data packet:
++ *
++ * 03h-08h Manufacturers's name in ascii
++ * 0ah-0dh Card's 32 bit serial number
++ */
++/**
++ * Comments added by Cyril CATTIAUX on 2007-03-21
++ *
++ * CID format specification (from Sandisk SD Product Manual v1.9)
++ *
++ * cid[00 ] Manufacturer ID (unsigned byte)
++ * cid[01-02] OEM/Application ID (ASCII)
++ * cid[03-07] Product Name (ASCII)
++ * cid[08 ] Product Revistion (BCD coded number)
++ * cid[09-12] Serial Number (32-bit unsigned int)
++ * cid[13-14] Reserved(bit 12->15) - Manufacture Date(bit 0->11)
++ * cid[15 ] CRC7(bit 1->7) - Not used, allways 1 (bit 0)
++*/
++static int mmc_read_cid(unsigned char *cid)
++{
++ unsigned char result = 0;
++ int i;
++
++ MMC_Enable();
++
++ /* wait */
++ for (i = 0; i < 4; i++)
++ {
++ result=mmc_spi_readwrite(0xff);
++ }
++
++ /* issue CID (card identification data) read request */
++ mmc_spi_readwrite(0xff);
++ mmc_spi_readwrite(0x40 | 10);
++ mmc_spi_readwrite(0x00);
++ mmc_spi_readwrite(0x00);
++ mmc_spi_readwrite(0x00);
++ mmc_spi_readwrite(0x00);
++ mmc_spi_readwrite(0x95);
++
++ for (i = 0; i < 8; i++)
++ {
++ result=mmc_spi_readwrite(0xff);
++
++ if(result == 0x00)
++ break;
++ }
++
++ if (result != 0x00) {
++ MMC_Disable();
++ mmc_spi_readwrite(0xff);
++ return(1);
++ }
++
++ for (i = 0; i < 8; i++) {
++ result = mmc_spi_readwrite(0xff);
++ if (result == 0xfe) break;
++ }
++
++ if (result != 0xfe) {
++ MMC_Disable();
++ mmc_spi_readwrite(0xff);
++ return(2);
++ }
++
++ for (i = 0; i < 16; i++) {
++ result = mmc_spi_readwrite(0xff);
++ cid[i] = result;
++ }
++
++ mmc_spi_readwrite(0xff);
++ mmc_spi_readwrite(0xff);
++
++ MMC_Disable();
++ mmc_spi_readwrite(0xff);
++
++ return 0;
++}
++
++
++/**
++ * Comments added by Cyril CATTIAUX on 2007-03-21
++ *
++ * CID format specification (from Sandisk SD Product Manual v1.9)
++ *
++ * cid[00 ] Manufacturer ID (unsigned byte)
++ * cid[01-02] OEM/Application ID (ASCII)
++ * cid[03-07] Product Name (ASCII)
++ * cid[08 ] Product Revision (BCD coded 2 digit number)
++ * cid[09-12] Serial Number (32-bit unsigned int)
++ * cid[13-14] Manufacture Date(bit 0->11) (BCD coded 3 digit number YYM offset from 2000) - Reserved(bit 12->15)
++ * cid[15 ] Not used, allways 1 (bit 0) - CRC7(bit 1->7)
++*/
++static void mmc_show_cid_info(void)
++{
++ int i, result;
++ unsigned short tmps;
++ unsigned char cid[16];
++
++ char manufacturer_id;
++ char oem_id[3];
++ char product_name[6];
++ unsigned char product_revision_h, product_revision_l;
++ unsigned int product_sn;
++ unsigned short product_date_y;
++ unsigned char product_date_m;
++
++ result = mmc_read_cid(cid);
++
++ if (result == 0)
++ {
++ printk("mmc_init: MMC/SD Card ID: ");
++ for (i=0; i<16; i++) {
++ printk("%02X ", cid[i]);
++ }
++ manufacturer_id=cid[0];
++ strncpy(oem_id, &cid[1], 2);
++ oem_id[2]='\0';
++ strncpy(product_name, &cid[3], 5);
++ product_name[5]='\0';
++ product_revision_h=(cid[8] >> 4) & 0xf;
++ product_revision_l=cid[8] & 0xf;
++ product_sn=(cid[9]<<24) + (cid[10]<<16) + (cid[11]<<8) + cid[12];
++ tmps=((cid[13]<<8) + cid[14]) & 0x0fff;
++ product_date_y=2000 + (((tmps >> 8) & 0xf) * 10) + ((tmps >> 4) & 0xf);
++ product_date_m=tmps & 0xf;
++
++ printk("\nManufacturer ID : %02X\n", manufacturer_id);
++ printk("OEM/Application ID: %s\n", oem_id);
++ printk("Product name : %s\n", product_name);
++ printk("Product revision : %d.%d\n", product_revision_h, product_revision_l);
++ printk("Product SN : %08X\n", product_sn);
++ printk("Product Date : %d-%d\n", product_date_y, product_date_m);
++
++ } else {
++ printk("mmc_init: impossible to get card indentification info for reason code: %02x", result);
++ }
++}
++
++
++/*
++static int mmc_spi_hw_test(void)
++{
++ unsigned char result, k;
++
++ unsigned int i, j, t;
++
++ printk("mmc_spi_hw_test -> \n\n");
++ k = 0x55;
++ for ( i = 0 ; i < 5; i++) {
++
++ printk("\n0x%2X - ", k);
++ for ( j = 0 ; j < 8; j++ ) {
++ do_gettimeofday( &s_zeit );
++ result = mmc_spi_readwrite_slow(k);
++ do_gettimeofday( &e_zeit );
++
++ if ( result != k ) {
++ printk("!>ERROR<! Transfer = 0x%2X Receive = 0x%2X Trail = %d \n", k, result, j);
++ // i = 255; j = 1000;
++ }
++
++ t = (e_zeit.tv_sec-s_zeit.tv_sec)*1000000+(e_zeit.tv_usec-s_zeit.tv_usec);
++ printk("Durchlauf: %i Versuch: %i von 8 -> Laufzeit: 0x%X s\n", i , j, t);
++ udelay(200);
++ }
++ printk("ready ");
++
++ // k++;
++ }
++ printk("ready ");
++ printk("\n\n");
++ return (0);
++}
++*/
++
++/*
++static int mmc_spi_speed_test(void)
++{
++ unsigned int i, j, k, l, t;
++
++ MMC_Disable();
++
++ for (k = 1; k < 6; k++)
++ {
++ l = 10000 * k;
++ for (j = 0; j < 5; j++)
++ {
++ do_gettimeofday( &s_zeit );
++ for (i = 0; i < l; i++)
++ mmc_spi_readwrite(0xff);
++ do_gettimeofday( &e_zeit );
++ t = (e_zeit.tv_sec-s_zeit.tv_sec)*1000000+(e_zeit.tv_usec-s_zeit.tv_usec);
++ printk("mmc_spi_readwrite: Laufzeit %u x : 0x%X \n", l, t);
++ }
++ }
++
++ for (k = 1; k < 1; k++)
++ {
++ l = 10000 * k;
++ for (j = 0; j < 1; j++)
++ {
++ do_gettimeofday( &s_zeit );
++ for (i = 0; i < l; i++)
++ mmc_spi_readwrite_slow(0xff);
++ do_gettimeofday( &e_zeit );
++ t = (e_zeit.tv_sec-s_zeit.tv_sec)*1000000+(e_zeit.tv_usec-s_zeit.tv_usec);
++ printk("mmc_spi_readwrite_slow: Laufzeit %u x : 0x%X \n", l, t);
++ }
++ }
++
++ for (k = 1; k < 6; k++)
++ {
++ l = 10000 * k;
++ for (j = 0; j < 5; j++)
++ {
++ do_gettimeofday( &s_zeit );
++ for (i = 0; i < l; i++)
++ mmc_spi_read_only();
++ do_gettimeofday( &e_zeit );
++ t = (e_zeit.tv_sec-s_zeit.tv_sec)*1000000+(e_zeit.tv_usec-s_zeit.tv_usec);
++ printk("mmc_spi_read_only: Laufzeit %u x : 0x%X \n", l, t);
++ }
++ }
++
++ for (k = 1; k < 6; k++)
++ {
++ l = 10000 * k;
++ for (j = 0; j < 5; j++)
++ {
++ do_gettimeofday( &s_zeit );
++ for (i = 0; i < l; i++)
++ mmc_spi_write_only(0xff);
++ do_gettimeofday( &e_zeit );
++ t = (e_zeit.tv_sec-s_zeit.tv_sec)*1000000+(e_zeit.tv_usec-s_zeit.tv_usec);
++ printk("mmc_spi_write_only: Laufzeit %u x : 0x%X \n", l, t);
++ }
++ }
++
++ return (1);
++
++}
++*/
++
++
++static int mmc_spi_card_init(void)
++{
++ unsigned char result = 0;
++ short i, j;
++
++// unsigned long flags;
++
++ // save_flags(flags);
++ // cli();
++
++/*
++ printk("GPIO_SD_CS dir: %u alt: %u\n", gpio_getdir(&gp, GPIO_SD_CS), gpio_getalt(&gp, GPIO_SD_CS));
++ printk("GPIO_SD_DI dir: %u alt: %u\n", gpio_getdir(&gp, GPIO_SD_DI), gpio_getalt(&gp, GPIO_SD_DI));
++ printk("GPIO_SD_DO dir: %u alt: %u\n", gpio_getdir(&gp, GPIO_SD_DO), gpio_getalt(&gp, GPIO_SD_DO));
++ printk("GPIO_SD_CS dir: %u alt: %u\n", gpio_getdir(&gp, GPIO_SD_CLK), gpio_getalt(&gp, GPIO_SD_CLK));
++*/
++
++ // printk("\nmmc: mmc_spi_hw_test() *START*\n");
++
++ // mmc_spi_hw_test();
++
++ printk("\nmmc: card init 1/2 (CMD0)\n");
++
++ for (j = 0; j < 10; j++)
++ {
++ MMC_Disable();
++
++ for (i = 0; i < 10; i++)
++ mmc_spi_readwrite_slow(0xff);
++
++ MMC_Enable();
++
++ mmc_spi_readwrite_slow(0xff);
++
++ mmc_spi_readwrite_slow(0x40);
++
++ for (i = 0; i < 4; i++) {
++
++ mmc_spi_readwrite_slow(0x00);
++
++ }
++
++ mmc_spi_readwrite_slow(0x95);
++
++ for (i = 0; i < 8; i++) {
++
++ result = mmc_spi_readwrite_slow(0xff);
++
++#ifdef DEBUG_HD
++ if (result != 0xff) {
++ if (result > 0x1F && result < 0x80)
++ printk("mmc: resp. (CMD0) Versuch(%d) BYTE: %d result = 0x%X Zeichen = %c\n", j, i, result, result);
++ else
++ printk("mmc: resp. (CMD0) Versuch(%d) BYTE: %d result = 0x%X\n", j, i, result);
++ }
++#endif
++ if (result == 0x01)
++ break;
++ }
++
++ if (result == 0x01)
++ break;
++
++ MMC_Disable();
++ mmc_spi_readwrite_slow(0xff);
++
++ mdelay(60);
++ }
++
++ if (result != 0x01) {
++
++ printk("mmc: card init 1/2 error: %d (CMD0) failed\n", result);
++ printk(" -> Hint: MMC/SD-Card realy (fully) inserted ?\n");
++
++ return (1);
++ }
++
++ printk("mmc: card init 1/2 (CMD0) success\n\n");
++
++ mdelay(1);
++
++ printk("mmc: card init 2/2 (CMD1)\n");
++ for (j = 0; j < 10; j++) {
++
++ mmc_spi_readwrite_slow(0xff);
++ mmc_spi_readwrite_slow(0x41);
++ for (i = 0; i < 4; i++)
++ mmc_spi_readwrite_slow(0x00);
++ mmc_spi_readwrite_slow(0x95);
++ for (i = 0; i < 8; i++) {
++ result = mmc_spi_readwrite_slow(0xff);
++#ifdef DEBUG_HD
++ // if (result >= 32 && result <= 127)
++ // printk("mmc: response (CMD1) Versuch(%d) start token BYTE: %d result = 0x%X Zeichen = %c\n", j, i, result, result);
++ // else
++ // printk("mmc: response (CMD1) Versuch(%d) start token BYTE: %d result = 0x%X\n", j, i, result);
++#endif
++ if (result == 0x00)
++ break;
++ }
++
++ mmc_spi_readwrite_slow(0xff);
++
++ if (result == 0x00) {
++ printk("mmc: card init 2/2 (CMD1) success\n\n");
++
++ mmc_spi_readwrite_slow(0xff);
++ mmc_spi_readwrite_slow(0x4d);
++ mmc_spi_readwrite_slow(0x00);
++ mmc_spi_readwrite_slow(0x00);
++ mmc_spi_readwrite_slow(0x00);
++ mmc_spi_readwrite_slow(0x00);
++ mmc_spi_readwrite_slow(0x95);
++ for (i = 0; i < 6; i++) {
++ result = mmc_spi_readwrite_slow(0xff);
++#ifdef DEBUG_HD
++ // if (result > 31 && result < 128)
++ // printk("mmc: response (CMD13) Versuch(%d) start token BYTE: %d result = 0x%X Zeichen = %c\n", j, i, result, result);
++ // else
++ // printk("mmc: response (CMD13) Versuch(%d) start token BYTE: %d result = 0x%X\n", j, i, result);
++#endif
++ // if (result == 0x00)
++ // break;
++ }
++ // mdelay(60);
++ MMC_Disable();
++ mmc_spi_readwrite_slow(0xff);
++ // mmc_spi_readwrite_slow(0xff);
++ // mdelay(10);
++
++ // restore_flags(flags);
++
++ return (0);
++ }
++ mdelay(60);
++ }
++ return (2);
++}
++
++
++static int mmc_spi_card_config(void)
++{
++ unsigned char result = 0;
++ short i, j;
++ unsigned char csd[32];
++ unsigned int c_size;
++ unsigned int c_size_mult;
++ unsigned int mult;
++ unsigned int read_bl_len;
++ unsigned int blocknr = 0;
++ unsigned int block_len = 0;
++ unsigned int size = 0;
++ unsigned char rd_buffer[528];
++// unsigned long flags;
++
++ MMC_Enable();
++
++ mmc_spi_readwrite_slow(0xff);
++ result = mmc_spi_readwrite_slow(0x51);
++ // mmc_spi_readwrite_slow(0x4A);
++ // mmc_spi_readwrite_slow(0x40+0x0D);
++ // mmc_spi_readwrite_slow(0x42);
++ for (i = 0; i < 4; i++)
++ mmc_spi_readwrite_slow(0x00);
++ mmc_spi_readwrite_slow(0x95);
++
++ // printk("mmc: (CMD17) response von 0x51 result = 0x%X\n", result);
++
++ for (i = 0; i < 8; i++) {
++ result = mmc_spi_readwrite_slow(0xff);
++#ifdef DEBUG_HD
++ // printk("mmc: (CMD17) response (start token) result = 0x%X\n", result);
++#endif
++ if (result == 0x00)
++ break;
++ }
++ if (result != 0x00) {
++ MMC_Disable();
++ mmc_spi_readwrite_slow(0xff);
++ // restore_flags(flags);
++ // mmc_spi_readwrite_slow(0xff);
++ return (1);
++ }
++ // restore_flags(flags);
++ for (i = 0; i < 8; i++) {
++ result = mmc_spi_readwrite_slow(0xff);
++ rd_buffer[i] = result;
++#ifdef DEBUG_HD
++ /*
++ if (result >= 32 && result <= 127)
++ printk("mmc: CMD17 response (start token) result = 0x%X Zeichen = %c\n", result, result);
++ else
++ printk("mmc: CMD17 response (start token) result = 0x%X\n", result);
++ */
++#endif
++ // if (result == 0xfe)
++ // break;
++ }
++ /*
++ if (result != 0xfe) {
++ MMC_Disable();
++ mmc_spi_readwrite_slow(0xff);
++ mmc_spi_readwrite_slow(0xff);
++ return(1);
++ }
++ */
++
++ for (i = 8; i < 520; i++) {
++ result = mmc_spi_readwrite_slow(0xff);
++ rd_buffer[i] = result;
++ }
++ for (i = 0; i < 2; i++) {
++ result = mmc_spi_readwrite_slow(0xff);
++ }
++ MMC_Disable();
++ mmc_spi_readwrite_slow(0xff);
++ // mmc_spi_readwrite_slow(0xff);
++
++ printk("Buffer - Start\n");
++
++ for ( i = 0 ; i < 33 ; i++) {
++ printk("\r\n%4X - ", i*16);
++ for ( j = 0 ; j < 16 ; j++) {
++ if ( rd_buffer[i*16+j] < 16)
++ printk("0%X ", rd_buffer[i*16+j]);
++ else
++ printk("%2X ", rd_buffer[i*16+j]);
++ }
++ for ( j = 0 ; j < 16 ; j++) {
++ if ( rd_buffer[i*16+j] < ' ')
++ printk(".");
++ else
++ printk("%c", rd_buffer[i*16+j]);
++ }
++ }
++
++ printk("\nBuffer - Ende\n");
++
++ mmc_show_cid_info();
++
++ for(j = 0 ; j < 1; j++) {
++ MMC_Enable();
++
++ // mdelay(1);
++
++ // save_flags(flags);
++ // cli();
++ mmc_spi_readwrite_slow(0xff);
++ mmc_spi_readwrite_slow(0x49);
++ // mmc_spi_readwrite_slow(0x4A);
++ // mmc_spi_readwrite_slow(0x40+0x0D);
++ // mmc_spi_readwrite_slow(0x42);
++ for (i = 0; i < 4; i++)
++ mmc_spi_readwrite_slow(0x00);
++ mmc_spi_readwrite_slow(0x95);
++ for (i = 0; i < 8; i++) {
++ result = mmc_spi_readwrite_slow(0xff);
++#ifdef DEBUG_HD
++ // printk("mmc: (CMD9) response (start token) result = 0x%X\n", result);
++#endif
++ if (result == 0x00)
++ break;
++ }
++ // restore_flags(flags);
++ if (result != 0x00) {
++ MMC_Disable();
++ mmc_spi_readwrite_slow(0xff);
++ // mmc_spi_readwrite_slow(0xff);
++ return (1);
++ }
++ for (i = 0; i < 22; i++) {
++ result = mmc_spi_readwrite_slow(0xff);
++#ifdef DEBUG_HD
++ if (result >= 32 && result <= 127)
++ printk("mmc: response (start token) result = 0x%X Zeichen = %c\n", result, result);
++ else
++ printk("mmc: response (start token) result = 0x%X\n", result);
++#endif
++ if (result == 0xfe)
++ break;
++ }
++ if (result == 0xfe)
++ break;
++
++ if (result != 0xfe) {
++ MMC_Disable();
++ mmc_spi_readwrite_slow(0xff);
++ // mmc_spi_readwrite_slow(0xff);
++ }
++ mdelay(60);
++ }
++
++ if (result != 0xfe) {
++ MMC_Disable();
++ mmc_spi_readwrite_slow(0xff);
++ printk("mmc: mmc card config (CMD9) failed result = 0x%X\n\n", result);
++ return (2);
++ }
++ for (i = 0; i < 16; i++) {
++ result = mmc_spi_readwrite_slow(0xff);
++ csd[i] = result;
++ }
++ for (i = 0; i < 2; i++) {
++ result = mmc_spi_readwrite_slow(0xff);
++ }
++ MMC_Disable();
++ mmc_spi_readwrite_slow(0xff);
++ // mmc_spi_readwrite_slow(0xff);
++
++ if (result == 0x00)
++ return (3);
++
++ c_size = (csd[8] & 0xC0) + (csd[7] << 8) + ((csd[6] & 0x03) << 16);
++ c_size >>= 6;
++ c_size_mult = (csd[10] & 0x80) + ((csd[9] & 0x03) << 8);
++ c_size_mult >>= 7;
++ read_bl_len = csd[5] & 0x0f;
++ mult = 1;
++ mult <<= c_size_mult + 2;
++ blocknr = (c_size + 1) * mult;
++ block_len = 1;
++ block_len <<= read_bl_len;
++ size = block_len * blocknr;
++ size >>= 10;
++
++ for (i = 0; i < (1 << 6); i++) {
++ hd_blocksizes[i] = 1024;
++ hd_hardsectsizes[i] = block_len;
++ hd_maxsect[i] = 256;
++ }
++ hd_sizes[0] = size;
++ hd[0].nr_sects = blocknr;
++
++ printk("Size = %d, hardsectsize = %d, sectors = %d\n",
++ size, block_len, blocknr);
++
++ return 0;
++}
++
++
++/*
++ * *******************************************************************
++ *
++ * End of SPI hardware access functions.
++ *
++ * *******************************************************************
++ */
++
++
++static int mmc_spi_write_block(unsigned int dest_addr, unsigned char *data)
++{
++ unsigned int address;
++ unsigned char result = 0;
++ unsigned char ab0, ab1, ab2, ab3;
++ int i;
++
++ address = dest_addr;
++
++ ab3 = 0xff & (address >> 24);
++ ab2 = 0xff & (address >> 16);
++ ab1 = 0xff & (address >> 8);
++ ab0 = 0xff & address;
++
++ MMC_Enable();
++
++ mmc_spi_readwrite(0xff);
++
++ mmc_spi_readwrite(0x58);
++ mmc_spi_readwrite(ab3); /* msb */
++ mmc_spi_readwrite(ab2);
++ mmc_spi_readwrite(ab1);
++ mmc_spi_readwrite(ab0); /* lsb */
++ mmc_spi_readwrite(0xff);
++
++ for (i = 0; i < 8; i++)
++ {
++ result = mmc_spi_readwrite(0xff);
++ if (result == 0x00)
++ {
++ break;
++ }
++ }
++
++ if (result != 0x00)
++ {
++ MMC_Disable();
++ mmc_spi_readwrite(0xff);
++ return (1);
++ }
++
++ mmc_spi_readwrite(0xfe);
++
++ for (i = 0; i < 512; i += 32)
++ {
++ mmc_spi_write_only(data[i]);
++ mmc_spi_write_only(data[i+1]);
++ mmc_spi_write_only(data[i+2]);
++ mmc_spi_write_only(data[i+3]);
++ mmc_spi_write_only(data[i+4]);
++ mmc_spi_write_only(data[i+5]);
++ mmc_spi_write_only(data[i+6]);
++ mmc_spi_write_only(data[i+7]);
++ mmc_spi_write_only(data[i+8]);
++ mmc_spi_write_only(data[i+9]);
++ mmc_spi_write_only(data[i+10]);
++ mmc_spi_write_only(data[i+11]);
++ mmc_spi_write_only(data[i+12]);
++ mmc_spi_write_only(data[i+13]);
++ mmc_spi_write_only(data[i+14]);
++ mmc_spi_write_only(data[i+15]);
++ mmc_spi_write_only(data[i+16]);
++ mmc_spi_write_only(data[i+17]);
++ mmc_spi_write_only(data[i+18]);
++ mmc_spi_write_only(data[i+19]);
++ mmc_spi_write_only(data[i+20]);
++ mmc_spi_write_only(data[i+21]);
++ mmc_spi_write_only(data[i+22]);
++ mmc_spi_write_only(data[i+23]);
++ mmc_spi_write_only(data[i+24]);
++ mmc_spi_write_only(data[i+25]);
++ mmc_spi_write_only(data[i+26]);
++ mmc_spi_write_only(data[i+27]);
++ mmc_spi_write_only(data[i+28]);
++ mmc_spi_write_only(data[i+29]);
++ mmc_spi_write_only(data[i+30]);
++ mmc_spi_write_only(data[i+31]);
++ }
++
++ mmc_spi_readwrite(0xff);
++ mmc_spi_readwrite(0xff);
++
++ for (i = 0; i < 1000000; i++)
++ {
++ result = mmc_spi_readwrite(0xff);
++ if (result == 0xff)
++ {
++ break;
++ }
++ }
++
++ if (result != 0xff)
++ {
++ MMC_Disable();
++ mmc_spi_readwrite(0xff);
++ return (3);
++ }
++
++ MMC_Disable();
++ mmc_spi_readwrite(0xff);
++ return (0);
++}
++
++static int mmc_spi_read_block(unsigned char *data, unsigned int src_addr)
++{
++ unsigned int address;
++ unsigned char result = 0;
++ unsigned char ab0, ab1, ab2, ab3;
++ // unsigned long flags;
++ // int i, j;
++ int i;
++
++ address = src_addr;
++
++ ab3 = 0xff & (address >> 24);
++ ab2 = 0xff & (address >> 16);
++ ab1 = 0xff & (address >> 8);
++ ab0 = 0xff & address;
++
++ MMC_Enable();
++
++ mmc_spi_readwrite(0xff);
++
++ mmc_spi_readwrite(0x51);
++ mmc_spi_readwrite(ab3); /* msb */
++ mmc_spi_readwrite(ab2);
++ mmc_spi_readwrite(ab1);
++ mmc_spi_readwrite(ab0); /* lsb */
++ mmc_spi_readwrite(0xff);
++
++ for (i = 0; i < 8; i++)
++ {
++ result = mmc_spi_readwrite(0xff);
++ if (result == 0x00)
++ {
++ break;
++ }
++ }
++
++ if (result != 0x00)
++ {
++ MMC_Disable();
++ mmc_spi_readwrite(0xff);
++ return (1);
++ }
++
++ for (i = 0; i < 100000; i++)
++ {
++ result = mmc_spi_readwrite(0xff);
++ if (result == 0xfe)
++ {
++ break;
++ }
++ }
++
++ if (result != 0xfe)
++ {
++ MMC_Disable();
++ mmc_spi_readwrite(0xff);
++ return (2);
++ }
++
++ for (i = 0; i < 512; i += 32 )
++ {
++ data[i] = mmc_spi_read_only();
++ data[i+1] = mmc_spi_read_only();
++ data[i+2] = mmc_spi_read_only();
++ data[i+3] = mmc_spi_read_only();
++ data[i+4] = mmc_spi_read_only();
++ data[i+5] = mmc_spi_read_only();
++ data[i+6] = mmc_spi_read_only();
++ data[i+7] = mmc_spi_read_only();
++ data[i+8] = mmc_spi_read_only();
++ data[i+9] = mmc_spi_read_only();
++ data[i+10] = mmc_spi_read_only();
++ data[i+11] = mmc_spi_read_only();
++ data[i+12] = mmc_spi_read_only();
++ data[i+13] = mmc_spi_read_only();
++ data[i+14] = mmc_spi_read_only();
++ data[i+15] = mmc_spi_read_only();
++ data[i+16] = mmc_spi_read_only();
++ data[i+17] = mmc_spi_read_only();
++ data[i+18] = mmc_spi_read_only();
++ data[i+19] = mmc_spi_read_only();
++ data[i+20] = mmc_spi_read_only();
++ data[i+21] = mmc_spi_read_only();
++ data[i+22] = mmc_spi_read_only();
++ data[i+23] = mmc_spi_read_only();
++ data[i+24] = mmc_spi_read_only();
++ data[i+25] = mmc_spi_read_only();
++ data[i+26] = mmc_spi_read_only();
++ data[i+27] = mmc_spi_read_only();
++ data[i+28] = mmc_spi_read_only();
++ data[i+29] = mmc_spi_read_only();
++ data[i+30] = mmc_spi_read_only();
++ data[i+31] = mmc_spi_read_only();
++ }
++
++ result = mmc_spi_readwrite(0xff);
++ result = mmc_spi_readwrite(0xff);
++
++ MMC_Disable();
++ mmc_spi_readwrite(0xff);
++
++ return (0);
++}
++
++/*
++static int mmc_revalidate(kdev_t dev)
++{
++ int target, max_p, start, i;
++
++ mmc_media_detect = mmc_spi_media_detect();
++
++ if (mmc_media_detect == 0)
++ {
++ return -ENODEV;
++ }
++
++ target = DEVICE_NR(dev);
++
++ max_p = hd_gendisk.max_p;
++ start = target << 6;
++ for (i = max_p - 1; i >= 0; i--)
++ {
++ int minor = start + i;
++ invalidate_device(MKDEV(MAJOR_NR, minor), 1);
++ hd_gendisk.part[minor].start_sect = 0;
++ hd_gendisk.part[minor].nr_sects = 0;
++ }
++
++ grok_partitions(&hd_gendisk, target, 1 << 6, hd_sizes[0] * 2);
++
++ return 0;
++}
++*/
++
++
++static int mmc_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
++ unsigned long arg)
++{
++ if (!inode || !inode->i_rdev)
++ return -EINVAL;
++
++ switch (cmd) {
++#if 0
++ case BLKGETSIZE:
++ return put_user(hd[MINOR(inode->i_rdev)].nr_sects,
++ (unsigned long *)arg);
++ case BLKGETSIZE64:
++ return put_user((u64) hd[MINOR(inode->i_rdev)].
++ nr_sects, (u64 *) arg);
++ case BLKRRPART:
++ if (!capable(CAP_SYS_ADMIN))
++ return -EACCES;
++
++ return mmc_revalidate(inode->i_rdev);
++#endif
++ case HDIO_GETGEO:
++ {
++ struct block_device *bdev = inode->i_bdev;
++ struct hd_geometry *loc, g;
++ loc = (struct hd_geometry *)arg;
++ if (!loc)
++ return -EINVAL;
++ memset(loc, 0, sizeof(struct hd_geometry));
++ g.heads = 4;
++ g.sectors = 16;
++ g.cylinders = get_capacity(bdev->bd_disk) / (4*16);
++ g.start = get_start_sect(bdev);
++ return copy_to_user(loc, &g, sizeof(g)) ? -EFAULT : 0;
++ }
++ default:
++ return -ENOTTY;
++ }
++}
++
++
++/*
++static int mmc_check_media_change(kdev_t dev)
++{
++ (void) dev;
++ if (mmc_media_changed == 1)
++ {
++ mmc_media_changed = 0;
++ return 1;
++ }
++ else
++ {
++ return 0;
++ }
++}
++*/
++
++
++/*
++static int mmc_init(void)
++{
++ int result;
++
++ result = mmc_spi_hardware_init();
++
++ if (result != 0)
++ {
++ printk("mmc: error %d in mmc_spi_hardware_init\n", result);
++ return -1;
++ }
++
++
++ result = mmc_spi_hw_test();
++
++ if (result != 0)
++ {
++ printk("\n mmc: mmc_spi_hw_test i.O. \n\n");
++ return -1;
++ }
++
++
++ result = mmc_spi_speed_test();
++
++ if (result != 0)
++ {
++ printk("\n mmc: mmc_spi_speed_test i.O. \n\n");
++ return -1;
++ }
++
++
++ result = mmc_spi_card_init();
++ mdelay(50);
++ if (result != 0)
++ {
++ // Give it an extra shot
++ // result = mmc_spi_card_init();
++ if (result != 0)
++ {
++ printk("mmc: error %d in mmc_card_init\n", result);
++ return -1;
++ }
++ }
++
++ result = mmc_spi_card_config();
++ if (result != 0)
++ {
++ printk("mmc: error %d in mmc_card_config\n", result);
++ return -1;
++ }
++
++
++ return 0;
++}
++*/
++
++/*
++static void mmc_exit(void)
++{
++}
++*/
++
++
++/*
++static void mmc_check_media(void)
++{
++ int old_state, new_state;
++ int result;
++
++ old_state = mmc_media_detect;
++ new_state = mmc_spi_media_detect();
++
++ if (old_state != new_state)
++ {
++ mmc_media_changed = 1;
++ if (new_state == PRESENT)
++ {
++ result = mmc_init();
++ if (result != 0)
++ {
++ printk("mmc: error %d in mmc_init\n", result);
++ }
++ else
++ {
++ mmc_exit();
++ }
++ }
++ }
++
++#ifdef CHECK_MEDIA_CHANGE
++ del_timer(&mmc_timer);
++ mmc_timer.expires = jiffies + 10*HZ;
++ add_timer(&mmc_timer);
++#endif
++
++}
++*/
++
++
++/* NB: There might be several requests in the queue, simply dequeuing only one
++ and not checking for more will cause a stall because the block subsystem
++ will not call this function again unless the queue is "plugged" which can
++ only happen if it runs empty... */
++static void mmc_spi_request(struct request_queue *q)
++{
++ struct request *req;
++ int ret;
++
++ unsigned int mmc_address;
++ unsigned char *buffer_address;
++ int nr_sectors;
++ int i;
++ int result, success;
++
++ if (blk_queue_plugged(q)) {
++ return;
++ }
++
++ spin_lock(&mmc_spi_lock);
++ for(;;) {
++ req = elv_next_request(q);
++ if (!req)
++ break;
++
++ if (!blk_fs_request(req)) {
++ printk("not a blk_fs_request\n");
++ spin_unlock(&mmc_spi_lock);
++ continue;
++ }
++
++ mmc_address = req->sector * hd_hardsectsizes[0];
++ buffer_address = req->buffer;
++ nr_sectors = req->current_nr_sectors;
++ success = 1;
++ if (rq_data_dir(req) == READ) {
++ spin_unlock_irq(q->queue_lock);
++ for (i = 0; i < nr_sectors; i++) {
++ result = mmc_spi_read_block(buffer_address, mmc_address);
++ if (unlikely(result < 0)) {
++ printk(KERN_ERR "mmi_spi_block: error reading block (%d)\n", result);
++ success = 0;
++ break;
++ }
++ mmc_address += hd_hardsectsizes[0];
++ buffer_address += hd_hardsectsizes[0];
++ }
++ spin_lock_irq(q->queue_lock);
++ } else {
++ spin_unlock_irq(q->queue_lock);
++ for (i = 0; i < nr_sectors; i++) {
++ result = mmc_spi_write_block(mmc_address, buffer_address);
++ if (unlikely(result < 0)) {
++ printk(KERN_ERR "mmi_spi_block: error writing block (%d)\n", result);
++ success = 0;
++ break;
++ }
++ mmc_address += hd_hardsectsizes[0];
++ buffer_address += hd_hardsectsizes[0];
++ }
++ spin_lock_irq(q->queue_lock);
++ }
++ ret = end_that_request_chunk(req, success, nr_sectors * hd_hardsectsizes[0]);
++ if (!ret) {
++ blkdev_dequeue_request(req);
++ end_that_request_last(req, 0);
++ }
++ }
++ spin_unlock(&mmc_spi_lock);
++}
++
++
++static int mmc_open(struct inode *inode, struct file *filp)
++{
++ // int device;
++ (void) filp;
++ mmc_media_detect = mmc_spi_media_detect();
++
++ if (mmc_media_detect == 0)
++ return -ENODEV;
++
++ return 0;
++}
++
++static int mmc_release(struct inode *inode, struct file *filp)
++{
++ return 0;
++}
++
++
++static struct block_device_operations mmc_spi_bdops = {
++ .open = mmc_open,
++ .release = mmc_release,
++ .ioctl = mmc_ioctl,
++ .owner = THIS_MODULE,
++#if 0
++ .check_media_change = mmc_check_media_change,
++ .revalidate = mmc_revalidate,
++#endif
++};
++
++static int detect_card(void)
++{
++ int result;
++
++ result = mmc_spi_card_init();
++ if (result != 0) {
++ // Give it an extra shot
++ result = mmc_spi_card_init();
++ if (result != 0) {
++ printk(KERN_ERR "mmc_spi_block: error in mmc_card_init (%d)\n", result);
++ return -ENODEV;
++ }
++ }
++
++ result = mmc_spi_card_config();
++ // result = mmc_spi_speed_test();
++ if (result != 0) {
++ printk(KERN_ERR "mmc_spi_block: error in mmc_card_config (%d)\n", result);
++ return -ENODEV;
++ }
++
++ return 0;
++}
++
++/* Fills in the gendisk structure from the received card
++ data. */
++static int gendisk_init(struct device *dev, struct gendisk *gd)
++{
++ if (!gd)
++ return -EINVAL;
++
++ gd->major = major;
++ gd->first_minor = 0; /* only one device supported */
++ gd->fops = &mmc_spi_bdops;
++ gd->driverfs_dev = dev;
++
++ gd->queue = blk_init_queue(mmc_spi_request,NULL);
++
++ if (!gd->queue)
++ return -ENOMEM;
++
++ sprintf(gd->disk_name, "mmcblk");
++
++ blk_queue_hardsect_size(gd->queue, hd_hardsectsizes[0]);
++
++ set_capacity(gd, hd_sizes[0]<<1);
++
++ return 0;
++}
++
++static int gendisk_fini(struct gendisk *gd)
++{
++ BUG_ON(!gd);
++
++ if (gd->queue)
++ blk_cleanup_queue(gd->queue);
++
++ del_gendisk(gd);
++
++ return 0;
++}
++
++/* platform driver device instance routines */
++static int mmc_spi_probe(struct platform_device *pdev)
++{
++ int result;
++ printk("$Id: mmc_spi_block.c,v 1.05 2008/01/04 01:02:10 mrdata Exp $\n");
++
++ result = mmc_spi_hardware_init();
++ if (result != 0) {
++ printk(KERN_ERR "mmc_spi_block: error in mmc_spi_hardware_init (%d)\n", result);
++ result = -ENODEV;
++ return result;
++ }
++
++ result = detect_card();
++ if (result < 0)
++ return result;
++
++ mmc_media_detect = 1;
++
++ result = register_blkdev(major, DEVICE_NAME);
++ if (result < 0)
++ return result;
++
++ if (!major)
++ major = result;
++
++ /* allow 8 partitions per device */
++ BUG_ON(mmc_disk!=NULL);
++ mmc_disk = alloc_disk(1 << 3);
++ if (!mmc_disk) {
++ result = -ENOMEM;
++ goto out;
++ }
++
++ result = gendisk_init(&pdev->dev, mmc_disk);
++ if (result < 0)
++ goto out;
++
++ add_disk(mmc_disk);
++
++ /*init_timer(&mmc_timer);
++ mmc_timer.expires = jiffies + HZ;
++ mmc_timer.function = (void *)mmc_check_media;
++ add_timer(&mmc_timer); */
++ return 0;
++
++out:
++ if (mmc_disk)
++ put_disk(mmc_disk);
++
++ unregister_blkdev(major, DEVICE_NAME);
++ return result;
++}
++
++static int mmc_spi_remove(struct platform_device *dev)
++{
++ // int ret;
++
++ if (mmc_disk) {
++ gendisk_fini(mmc_disk);
++ put_disk(mmc_disk);
++ }
++
++ // ret = unregister_blkdev(major, DEVICE_NAME);
++ unregister_blkdev(major, DEVICE_NAME);
++ return 0;
++}
++
++struct platform_driver mmc_spi_driver = {
++ .probe = mmc_spi_probe,
++ .remove = mmc_spi_remove,
++ .driver = {
++ .name = "mmc_spi_block",
++ .owner = THIS_MODULE,
++ },
++};
++
++
++/* module init/exit */
++static int __init mmc_spi_block_init(void)
++{
++ int ret;
++ spin_lock_init(&mmc_spi_lock);
++
++ ret = platform_driver_register(&mmc_spi_driver);
++ if (ret < 0)
++ return ret;
++
++ /* we just support one device */
++ mmc_dev = platform_device_register_simple("mmc_spi_block", -1, NULL, 0);
++ if (IS_ERR(mmc_dev))
++ return PTR_ERR(mmc_dev);
++
++ return 0;
++}
++
++
++static void __exit mmc_spi_block_exit(void)
++{
++ platform_driver_unregister(&mmc_spi_driver);
++ if (mmc_dev)
++ platform_device_unregister(mmc_dev);
++}
++
++
++module_init(mmc_spi_block_init);
++module_exit(mmc_spi_block_exit);
++
++MODULE_AUTHOR("Madsuk,Rohde,TaGana,Carsten Juttner <carjay@gmx.net>,Guylhem Aznar <mmc-driver@externe.net>,mrdata");
++MODULE_DESCRIPTION("Driver for MMC/SD-Cards in SPI mode over GPIO (Software SPI)");
++MODULE_SUPPORTED_DEVICE("SIMpad");
++MODULE_LICENSE("GPL");
++
++module_param(major, int, 0444);
++MODULE_PARM_DESC(major, "specify the major device number for the MMC/SD SPI driver");
diff --git a/recipes/linux/linux/simpad/linux-2.6.24-SIMpad-battery-old-way-but-also-with-sysfs.patch b/recipes/linux/linux/simpad/linux-2.6.24-SIMpad-battery-old-way-but-also-with-sysfs.patch
new file mode 100644
index 0000000000..35f192ada2
--- /dev/null
+++ b/recipes/linux/linux/simpad/linux-2.6.24-SIMpad-battery-old-way-but-also-with-sysfs.patch
@@ -0,0 +1,571 @@
+diff -Nur linux-2.6.24.vanilla/drivers/mfd/Makefile linux-2.6.24/drivers/mfd/Makefile
+--- linux-2.6.24.vanilla/drivers/mfd/Makefile 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24/drivers/mfd/Makefile 2008-02-20 21:27:39.000000000 +0100
+@@ -12,3 +12,7 @@
+ ifeq ($(CONFIG_SA1100_ASSABET),y)
+ obj-$(CONFIG_MCP_UCB1200) += ucb1x00-assabet.o
+ endif
++
++ifeq ($(CONFIG_SA1100_SIMPAD),y)
++obj-$(CONFIG_MCP_UCB1200) += ucb1x00-simpad.o
++endif
+diff -Nur linux-2.6.24.vanilla/drivers/mfd/ucb1x00-simpad.c linux-2.6.24/drivers/mfd/ucb1x00-simpad.c
+--- linux-2.6.24.vanilla/drivers/mfd/ucb1x00-simpad.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24/drivers/mfd/ucb1x00-simpad.c 2008-02-20 21:27:39.000000000 +0100
+@@ -0,0 +1,226 @@
++/*
++ * linux/drivers/mfd/ucb1x00-simpad.c
++ *
++ * Copyright (C) 2001-2003 Russell King, All Rights Reserved.
++ * 2007/03/18 mrdata:
++ * - adapted ucb1x00-assabet.c
++ * - transfer ucb1x00-simpad.c from kernel24
++ * to new structur of kernel26
++ *
++ * 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.
++ *
++ * We handle the machine-specific bits of the UCB1x00 driver here.
++ */
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/fs.h>
++#include <linux/proc_fs.h>
++#include <linux/device.h>
++
++#include <linux/apm-emulation.h>
++
++#include <asm/dma.h>
++
++#include <asm/arch/simpad.h>
++#include <asm/arch-sa1100/simpad_pm.h>
++
++#include "ucb1x00.h"
++#include "ucb1x00-simpad.h"
++
++#define UCB1X00_ATTR(name,input,designation) \
++static ssize_t name##_show(struct class_device *dev, char *buf) \
++{ \
++ struct ucb1x00 *ucb = classdev_to_ucb1x00(dev); \
++ int val; \
++ ucb1x00_adc_enable(ucb); \
++ val = ucb1x00_adc_read(ucb, input, UCB_NOSYNC); \
++ ucb1x00_adc_disable(ucb); \
++ return sprintf(buf, "%d\n", CALIBRATE_##designation(val)); \
++} \
++static CLASS_DEVICE_ATTR(name,0444,name##_show,NULL)
++
++UCB1X00_ATTR(vbatt, UCB_ADC_INP_AD1, BATTERY);
++UCB1X00_ATTR(vcharger, UCB_ADC_INP_AD2, SUPPLY);
++UCB1X00_ATTR(icharger, UCB_ADC_INP_AD3, CHARGING);
++
++static struct ucb1x00 *ucb_alt;
++
++#define UCB1X00_WERT(name,input,designation) \
++static int ucb1x00_simpad_read_##name(struct ucb1x00 *ucb_alt) \
++{ \
++ int val; \
++ ucb1x00_adc_enable(ucb_alt); \
++ val = ucb1x00_adc_read(ucb_alt, input, UCB_NOSYNC); \
++ ucb1x00_adc_disable(ucb_alt); \
++ return CALIBRATE_##designation(val); \
++}
++
++UCB1X00_WERT(vbatt, UCB_ADC_INP_AD1, BATTERY);
++UCB1X00_WERT(vcharger, UCB_ADC_INP_AD2, SUPPLY);
++UCB1X00_WERT(icharger, UCB_ADC_INP_AD3, CHARGING);
++
++static int ucb1x00_simpad_add(struct ucb1x00_dev *dev)
++{
++ class_device_create_file(&dev->ucb->cdev, &class_device_attr_vbatt);
++ class_device_create_file(&dev->ucb->cdev, &class_device_attr_vcharger);
++ class_device_create_file(&dev->ucb->cdev, &class_device_attr_icharger);
++ ucb_alt = dev->ucb;
++ return 0;
++}
++
++static void ucb1x00_simpad_remove(struct ucb1x00_dev *dev)
++{
++ class_device_remove_file(&dev->ucb->cdev, &class_device_attr_icharger);
++ class_device_remove_file(&dev->ucb->cdev, &class_device_attr_vcharger);
++ class_device_remove_file(&dev->ucb->cdev, &class_device_attr_vbatt);
++}
++
++static struct ucb1x00_driver ucb1x00_simpad_driver = {
++ .add = ucb1x00_simpad_add,
++ .remove = ucb1x00_simpad_remove,
++};
++
++static int __init ucb1x00_simpad_init(void)
++{
++ apm_get_power_status = simpad_apm_get_power_status;
++ return ucb1x00_register_driver(&ucb1x00_simpad_driver);
++}
++
++static void __exit ucb1x00_simpad_exit(void)
++{
++ apm_get_power_status = NULL;
++ ucb1x00_unregister_driver(&ucb1x00_simpad_driver);
++}
++
++/****************************************************************************/
++/* Functions exported for use by the kernel and kernel modules */
++/****************************************************************************/
++
++int simpad_get_battery(struct simpad_battery_apm *bstat)
++{
++ int icharger, vcharger, vbatt;
++
++ if ( ucb_alt ) {
++ icharger = ucb1x00_simpad_read_icharger( ucb_alt );
++ vcharger = ucb1x00_simpad_read_vcharger( ucb_alt );
++ vbatt = ucb1x00_simpad_read_vbatt( ucb_alt );
++ } else {
++ bstat->ac_status = SIMPAD_AC_STATUS_AC_UNKNOWN;
++ bstat->status = SIMPAD_BATT_STATUS_UNKNOWN;
++ bstat->percentage = 0x64; // lets say 100%
++ bstat->life = 330; // lets say a long time
++ return 0;
++ }
++
++ /* AC status */
++ bstat->ac_status = SIMPAD_AC_STATUS_AC_OFFLINE;
++ if ( vcharger>MIN_SUPPLY ) {
++ bstat->ac_status = SIMPAD_AC_STATUS_AC_ONLINE;
++ }
++
++ /* charging */
++ bstat->status = 0x0;
++ if ( icharger >= CHARGING_LED_LEVEL )
++ bstat->status = SIMPAD_BATT_STATUS_CHARGING;
++
++ if ( vbatt > BATT_LOW )
++ bstat->status |= SIMPAD_BATT_STATUS_HIGH;
++ else if ( vbatt < BATT_CRITICAL )
++ bstat->status |= SIMPAD_BATT_STATUS_CRITICAL;
++ else
++ bstat->status |= SIMPAD_BATT_STATUS_LOW;
++
++ if (bstat->status & SIMPAD_BATT_STATUS_CHARGING) {
++ if (icharger > CHARGING_MAX_LEVEL)
++ icharger = CHARGING_MAX_LEVEL;
++ if (icharger < CHARGING_LED_LEVEL)
++ icharger = CHARGING_LED_LEVEL;
++
++ bstat->percentage = 100 - 100 * (icharger - CHARGING_LED_LEVEL) /
++ (CHARGING_MAX_LEVEL - CHARGING_LED_LEVEL);
++ } else {
++ if (vbatt > BATT_FULL)
++ vbatt = BATT_FULL;
++ if (vbatt < BATT_EMPTY)
++ vbatt = BATT_EMPTY;
++
++ bstat->percentage = 100 * (vbatt - BATT_EMPTY) / (BATT_FULL - BATT_EMPTY);
++ }
++
++ /* let's assume: full load is 7h */
++ /* bstat->life = 420*bstat->percentage/100; */
++ /* mrdata: think, 4h is more realistic */
++ bstat->life = 240*(bstat->percentage)/100;
++
++#if 0
++ printk("get_battery: ac: %02x / ch: %02x / perc: %02x / life: %d \n",
++ bstat->ac_status, bstat->status,
++ bstat->percentage, bstat->life );
++#endif
++
++ return 0;
++}
++
++void simpad_apm_get_power_status(struct apm_power_info *info)
++{
++ struct simpad_battery_apm bstat;
++ unsigned char ac = APM_AC_UNKNOWN;
++ unsigned char level = APM_BATTERY_STATUS_UNKNOWN;
++ int status, result;
++
++ result = simpad_get_battery(&bstat);
++ if (result) {
++ printk("%s: unable to access battery information: result=%d\n", __FUNCTION__, result);
++ return;
++ }
++
++ switch (bstat.ac_status) {
++ case SIMPAD_AC_STATUS_AC_OFFLINE:
++ ac = APM_AC_OFFLINE;
++ break;
++ case SIMPAD_AC_STATUS_AC_ONLINE:
++ ac = APM_AC_ONLINE;
++ break;
++ case SIMPAD_AC_STATUS_AC_BACKUP:
++ ac = APM_AC_BACKUP;
++ break;
++ }
++
++ info->ac_line_status = ac;
++
++ status = bstat.status;
++ if (status & (SIMPAD_BATT_STATUS_CHARGING | SIMPAD_BATT_STATUS_CHARGE_MAIN))
++ level = APM_BATTERY_STATUS_CHARGING;
++ else if (status & (SIMPAD_BATT_STATUS_HIGH | SIMPAD_BATT_STATUS_FULL))
++ level = APM_BATTERY_STATUS_HIGH;
++ else if (status & SIMPAD_BATT_STATUS_LOW)
++ level = APM_BATTERY_STATUS_LOW;
++ else if (status & SIMPAD_BATT_STATUS_CRITICAL)
++ level = APM_BATTERY_STATUS_CRITICAL;
++
++ info->battery_status = level;
++ info->battery_flag = info->battery_status;
++
++ info->battery_life = bstat.percentage;
++
++ /* we have a dumb battery - so we know nothing */
++ info->time = bstat.life;
++ info->units = APM_UNITS_MINS;
++
++#if 0
++ printk("apm_get_power: ac: %02x / bs: %02x / bf: %02x / perc: %02x / life: %d\n",
++ info->ac_line_status, info->battery_status, info->battery_flag,
++ info->battery_life, info->time );
++#endif
++ return;
++}
++
++module_init(ucb1x00_simpad_init);
++module_exit(ucb1x00_simpad_exit);
++
++
++MODULE_AUTHOR("Juergen Messerer <juergen.messerer@freesurf.ch>");
++MODULE_DESCRIPTION("SIMpad noddy testing only example ADC driver");
++MODULE_LICENSE("GPL");
+diff -Nur linux-2.6.24.vanilla/drivers/mfd/ucb1x00-simpad.h linux-2.6.24/drivers/mfd/ucb1x00-simpad.h
+--- linux-2.6.24.vanilla/drivers/mfd/ucb1x00-simpad.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24/drivers/mfd/ucb1x00-simpad.h 2008-02-20 21:27:39.000000000 +0100
+@@ -0,0 +1,86 @@
++/*
++ * linux/drivers/mfd/ucb1x00-simpad.h
++ *
++ * Copyright (C) 2001 Russell King, All Rights Reserved.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License.
++ */
++#ifndef UCB1300_SIMPAD_H
++#define UCB1300_SIMPAD_H
++
++/*
++ * Conversion from AD -> mV
++ * 7.5V = 1023 7.33137mV/Digit
++ *
++ * 400 Units == 9.7V
++ * a = ADC value
++ * 2007/03/24 mrdata:
++ * according UCB1300 datasheet ADC error max. 3 LSB
++ * 5-95% of full scale -> 3*7.33137mV = 21.99mV
++ * // old
++ * 21 = ADC error
++ * 12600 = Divident to get 2*7.3242
++ * 860 = Divider to get 2*7.3242
++ * 170 = Voltagedrop over
++ *
++ * // new
++ * 3 = ADC error
++ * 12610 = Divident to get 2*7.33139
++ * 860 = Divider to get 2*7.33139
++ * 170 = Voltagedrop over
++ */
++// #define CALIBRATE_BATTERY(a) ((((a + 21)*12600)/860) + 170)
++#define CALIBRATE_BATTERY(a) ((((a + 3)*12610)/860) + 170)
++
++/*
++ * We have two types of batteries a small and a large one
++ * To get the right value we to distinguish between those two
++ * 450 Units == 15 V
++ */
++#ifdef SMALL_BATTERY
++#define CALIBRATE_SUPPLY(a) (((a) * 1500) / 51)
++#define MIN_SUPPLY 8500 /* Less then 8.5V means no powersupply */
++#else
++#define CALIBRATE_SUPPLY(a) (((a) * 1500) / 45)
++//#define MIN_SUPPLY 14000 /* Less then 14V means no powersupply */
++#define MIN_SUPPLY 12000 /* Less then 12V means no powersupply */
++#endif
++
++/*
++ * Charging Current
++ * if value is >= 50 then charging is on
++ */
++// #define CALIBRATE_CHARGING(a) (((a) * 1000) / (152/4))
++#define CALIBRATE_CHARGING(a) (a)
++//#define CHARGING_LED_LEVEL 50
++
++#ifdef CONFIG_SA1100_SIMPAD_SINUSPAD
++
++// type small battery
++#define CHARGING_LED_LEVEL 12
++#define CHARGING_MAX_LEVEL 120
++#define BATT_FULL 8100
++#define BATT_LOW 7300
++#define BATT_CRITICAL 6700
++#define BATT_EMPTY 6400
++
++#else // CONFIG_SA1100_SIMPAD_SINUSPAD
++
++// type large battery
++// because of ADC error CHARGING_LED_LEVEL can changed
++// from 27 to 28
++#define CHARGING_LED_LEVEL 27
++#define CHARGING_MAX_LEVEL 265
++// BATT_FULL with SIMPAD_AC_STATUS_AC_OFFLINE
++#define BATT_FULL 8100
++#define BATT_LOW 7400
++#define BATT_CRITICAL 6800
++#define BATT_EMPTY 6500
++
++#endif // CONFIG_SA1100_SIMPAD_SINUSPAD
++
++// int simpad_get_battery(struct simpad_battery_apm *bstat);
++
++#endif
+diff -Nur linux-2.6.24.vanilla/include/asm-arm/arch-sa1100/simpad_pm.h linux-2.6.24/include/asm-arm/arch-sa1100/simpad_pm.h
+--- linux-2.6.24.vanilla/include/asm-arm/arch-sa1100/simpad_pm.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24/include/asm-arm/arch-sa1100/simpad_pm.h 2008-02-20 21:27:39.000000000 +0100
+@@ -0,0 +1,236 @@
++/*
++* Abstraction interface for microcontroller connection to rest of system
++*
++* Copyright 2003 Peter Pregler
++* Copyright 2000,1 Compaq Computer Corporation.
++*
++* Use consistent with the GNU GPL is permitted,
++* provided that this copyright notice is
++* preserved in its entirety in all copies and derived works.
++*
++* COMPAQ COMPUTER CORPORATION MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,
++* AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS
++* FITNESS FOR ANY PARTICULAR PURPOSE.
++*
++* Author: Peter Pregler (based on work for ipaq by Andrew Christian)
++*
++*/
++
++#ifndef __SIMPAD_HAL_H
++#define __SIMPAD_HAL_H
++
++#include <linux/apm-emulation.h>
++
++struct simpad_battery_apm {
++ unsigned char ac_status; /* line connected yes/no */
++ unsigned char status; /* battery loading yes/no */
++ unsigned char percentage; /* percentage loaded */
++ unsigned short life; /* life till empty */
++};
++
++extern void simpad_apm_get_power_status(struct apm_power_info *);
++
++// extern int simpad_get_battery(struct simpad_battery_apm *bstat);
++
++/* These should match the apm_bios.h definitions */
++#define SIMPAD_AC_STATUS_AC_OFFLINE 0x00
++#define SIMPAD_AC_STATUS_AC_ONLINE 0x01
++#define SIMPAD_AC_STATUS_AC_BACKUP 0x02 /* What does this mean? */
++#define SIMPAD_AC_STATUS_AC_UNKNOWN 0xff
++
++
++/* These bitfields are rarely "or'd" together */
++#define SIMPAD_BATT_STATUS_HIGH 0x01
++#define SIMPAD_BATT_STATUS_LOW 0x02
++#define SIMPAD_BATT_STATUS_CRITICAL 0x04
++#define SIMPAD_BATT_STATUS_CHARGING 0x08
++#define SIMPAD_BATT_STATUS_CHARGE_MAIN 0x10
++#define SIMPAD_BATT_STATUS_DEAD 0x20 /* Battery will not charge */
++#define SIMPAD_BATT_NOT_INSTALLED 0x20 /* For expansion pack batteries */
++#define SIMPAD_BATT_STATUS_FULL 0x40 /* Battery fully charged (and connected to AC) */
++#define SIMPAD_BATT_STATUS_NOBATT 0x80
++#define SIMPAD_BATT_STATUS_UNKNOWN 0xff
++
++#if 0 // FIXME
++#include <linux/simpad_ts.h>
++
++enum simpad_asset_type {
++ ASSET_TCHAR = 0,
++ ASSET_SHORT,
++ ASSET_LONG
++};
++
++#define TTYPE(_type) (((unsigned int)_type) << 8)
++#define TCHAR(_len) (TTYPE(ASSET_TCHAR) | (_len))
++#define TSHORT TTYPE(ASSET_SHORT)
++#define TLONG TTYPE(ASSET_LONG)
++#define ASSET(_type,_num) ((((unsigned int)_type)<<16) | (_num))
++
++#define ASSET_HM_VERSION ASSET( TCHAR(10), 0 ) /* 1.1, 1.2 */
++#define ASSET_SERIAL_NUMBER ASSET( TCHAR(40), 1 ) /* Unique iPAQ serial number */
++#define ASSET_MODULE_ID ASSET( TCHAR(20), 2 ) /* E.g., "iPAQ 3700" */
++#define ASSET_PRODUCT_REVISION ASSET( TCHAR(10), 3 ) /* 1.0, 2.0 */
++#define ASSET_PRODUCT_ID ASSET( TSHORT, 4 ) /* 2 = Palm-sized computer */
++#define ASSET_FRAME_RATE ASSET( TSHORT, 5 )
++#define ASSET_PAGE_MODE ASSET( TSHORT, 6 ) /* 0 = Flash memory */
++#define ASSET_COUNTRY_ID ASSET( TSHORT, 7 ) /* 0 = USA */
++#define ASSET_IS_COLOR_DISPLAY ASSET( TSHORT, 8 ) /* Boolean, 1 = yes */
++#define ASSET_ROM_SIZE ASSET( TSHORT, 9 ) /* 16, 32 */
++#define ASSET_RAM_SIZE ASSET( TSHORT, 10 ) /* 32768 */
++#define ASSET_HORIZONTAL_PIXELS ASSET( TSHORT, 11 ) /* 240 */
++#define ASSET_VERTICAL_PIXELS ASSET( TSHORT, 12 ) /* 320 */
++
++#define ASSET_TYPE(_asset) (((_asset)&0xff000000)>>24)
++#define ASSET_TCHAR_LEN(_asset) (((_asset)&0x00ff0000)>>16)
++#define ASSET_NUMBER(_asset) ((_asset)&0x0000ffff)
++
++#define MAX_TCHAR_LEN 40
++
++struct simpad_asset {
++ unsigned int type;
++ union {
++ unsigned char tchar[ MAX_TCHAR_LEN ];
++ unsigned short vshort;
++ unsigned long vlong;
++ } a;
++};
++
++/********************************************************************
++ * Interface to the hardware-type specific functions
++ *
++ * get_version Read the version number of the microcontroller on the option pack SPI bus
++ * spi_read Reads from the serial EEPROM memory on the option pack SPI bus
++ * spi_write Write to the serial EEPROM memory on the option pack SPI bus
++ * get_option_detect Returns whether or not an option pack is present
++ *
++ * get_thermal_sensor Return measured temperature of the unit, in units of 0.125 deg C
++ * set_notify_led Turns on, off, or blinks the Green LED
++ * read_light_sensor Returns the value of the front light sensor
++ * get_battery Returns the current voltage and charging state of all batteries
++ * audio_clock Sets the audio CODEC to run at a particular rate
++ * audio_power Turns on/off audio CODEC (internally calls audio_clock)
++ * audio_mute Mutes the audio CODEC
++ * asset_read Extracts PocketPC-style asset information from persistent memory
++ * backlight_control Adjusts the backlight level (only on/off for 3100)
++ *
++ *
++ * iPAQ 3100 only
++ * ==============
++ * codec_control Reset/mute/control level of 3100 audio codec
++ * contrast_control Adjusts the contrast level (only for 3100)
++ *
++ * iPAQ 3600, 3700 only
++ * ====================
++ * eeprom_read Reads from the asset information on the eeprom of a 3600 (deprecated)
++ * eeprom_write Writes to the asset information on the eeprom (deprecated)
++ *
++ * The interfaces to the EEPROM functions are maintained only because the simpad_ts driver has
++ * a deprecated ioctl call for them. They are used internally by the "asset_read" function.
++ *
++ * iPAQ 3800, 3900 only
++ * ====================
++ * set_ebat Tells enhanced PCMCIA sleeves that this iPAQ can handle
++ * a wider voltage range (applies to 3800, 3900)
++ *
++ *********************************************************************/
++
++struct simpad_hal_ops {
++ /* Functions provided by the underlying hardware */
++ int (*get_version)( struct simpad_ts_version * );
++ int (*eeprom_read)( unsigned short address, unsigned char *data, unsigned short len );
++ int (*eeprom_write)( unsigned short address, unsigned char *data, unsigned short len );
++ int (*get_thermal_sensor)( unsigned short * );
++ int (*set_notify_led)( unsigned char mode, unsigned char duration,
++ unsigned char ontime, unsigned char offtime );
++ int (*read_light_sensor)( unsigned char *result );
++ int (*get_battery)( struct simpad_battery * );
++ int (*spi_read)( unsigned short address, unsigned char *data, unsigned short len );
++ int (*spi_write)( unsigned short address, unsigned char *data, unsigned short len );
++ int (*codec_control)( unsigned char, unsigned char );
++ int (*get_option_detect)( int *result );
++ int (*audio_clock)( long samplerate );
++ int (*audio_power)( long samplerate );
++ int (*audio_mute)( int mute );
++ int (*asset_read)( struct simpad_asset *asset );
++ int (*set_ebat)( void );
++
++ /* Functions indirectly provided by the underlying hardware */
++ int (*backlight_control)( enum flite_pwr power, unsigned char level );
++ int (*contrast_control)( unsigned char level );
++
++ /* for module use counting */
++ struct module *owner;
++};
++
++/* Used by the device-specific hardware module to register itself */
++extern int simpad_hal_register_interface( struct simpad_hal_ops *ops );
++extern void simpad_hal_unregister_interface( struct simpad_hal_ops *ops );
++
++/*
++ * Calls into HAL from the device-specific hardware module
++ * These run at interrupt time
++ */
++extern void simpad_hal_keypress( unsigned char key );
++extern void simpad_hal_touchpanel( unsigned short x, unsigned short y, int down );
++extern void simpad_hal_option_detect( int present );
++
++/* Callbacks registered by device drivers */
++struct simpad_driver_ops {
++ void (*keypress)( unsigned char key );
++ void (*touchpanel)( unsigned short x, unsigned short y, int down );
++ void (*option_detect)( int present );
++};
++
++extern int simpad_hal_register_driver( struct simpad_driver_ops * );
++extern void simpad_hal_unregister_driver( struct simpad_driver_ops * );
++
++
++/* Calls into HAL from device drivers and other kernel modules */
++extern void simpad_get_flite( struct simpad_ts_backlight *bl );
++extern void simpad_get_contrast( unsigned char *contrast );
++extern int simpad_set_flite( enum flite_pwr pwr, unsigned char brightness );
++extern int simpad_set_contrast( unsigned char contrast );
++extern int simpad_toggle_frontlight( void );
++
++extern int simpad_apm_get_power_status(unsigned char *ac_line_status, unsigned char *battery_status,
++ unsigned char *battery_flag, unsigned char *battery_percentage,
++ unsigned short *battery_life);
++
++extern struct simpad_hal_ops *simpad_hal_ops;
++
++/* Do not use this macro in driver files - instead, use the inline functions defined below */
++#define CALL_HAL( f, args... ) \
++ { int __result = -EIO; \
++ if ( simpad_hal_ops && simpad_hal_ops->f ) { \
++ __MOD_INC_USE_COUNT(simpad_hal_ops->owner); \
++ __result = simpad_hal_ops->f(args); \
++ __MOD_DEC_USE_COUNT(simpad_hal_ops->owner); \
++ } \
++ return __result; }
++
++#define HFUNC static __inline__ int
++
++/* The eeprom_read/write address + len has a maximum value of 512. Both must be even numbers */
++HFUNC simpad_eeprom_read( u16 addr, u8 *data, u16 len ) CALL_HAL(eeprom_read,addr,data,len)
++HFUNC simpad_eeprom_write( u16 addr, u8 *data, u16 len) CALL_HAL(eeprom_write,addr,data,len)
++HFUNC simpad_spi_read( u8 addr, u8 *data, u16 len) CALL_HAL(spi_read,addr,data,len)
++HFUNC simpad_spi_write( u8 addr, u8 *data, u16 len) CALL_HAL(spi_write,addr,data,len)
++HFUNC simpad_get_version( struct simpad_ts_version *v ) CALL_HAL(get_version,v)
++HFUNC simpad_get_thermal_sensor( u16 *thermal ) CALL_HAL(get_thermal_sensor,thermal)
++HFUNC simpad_set_led( u8 mode, u8 dur, u8 ont, u8 offt ) CALL_HAL(set_notify_led, mode, dur, ont, offt)
++HFUNC simpad_get_light_sensor( u8 *result ) CALL_HAL(read_light_sensor,result)
++HFUNC simpad_get_battery( struct simpad_battery *bat ) CALL_HAL(get_battery,bat)
++HFUNC simpad_get_option_detect( int *result) CALL_HAL(get_option_detect,result)
++HFUNC simpad_audio_clock( long samplerate ) CALL_HAL(audio_clock,samplerate)
++HFUNC simpad_audio_power( long samplerate ) CALL_HAL(audio_power,samplerate)
++HFUNC simpad_audio_mute( int mute ) CALL_HAL(audio_mute,mute)
++HFUNC simpad_asset_read( struct simpad_asset *asset ) CALL_HAL(asset_read,asset)
++HFUNC simpad_set_ebat( void ) CALL_HAL(set_ebat)
++
++/* Don't use these functions directly - rather, call {get,set}_{flite,contrast} */
++ /* Functions indirectly provided by the underlying hardware */
++HFUNC simpad_backlight_control( enum flite_pwr p, u8 v ) CALL_HAL(backlight_control,p,v)
++HFUNC simpad_contrast_control( u8 level ) CALL_HAL(contrast_control,level)
++
++#endif
++#endif
diff --git a/recipes/linux/linux/simpad/linux-2.6.24-SIMpad-cs3-simpad.patch b/recipes/linux/linux/simpad/linux-2.6.24-SIMpad-cs3-simpad.patch
new file mode 100644
index 0000000000..51232d55cd
--- /dev/null
+++ b/recipes/linux/linux/simpad/linux-2.6.24-SIMpad-cs3-simpad.patch
@@ -0,0 +1,184 @@
+diff -uNr linux-2.6.24.vanilla/arch/arm/mach-sa1100/Makefile linux-2.6.24/arch/arm/mach-sa1100/Makefile
+--- linux-2.6.24.vanilla/arch/arm/mach-sa1100/Makefile 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24/arch/arm/mach-sa1100/Makefile 2008-02-20 20:49:57.000000000 +0100
+@@ -41,6 +41,7 @@
+ obj-$(CONFIG_SA1100_SHANNON) += shannon.o
+
+ obj-$(CONFIG_SA1100_SIMPAD) += simpad.o
++obj-$(CONFIG_SA1100_SIMPAD) += cs3-simpad.o
+ led-$(CONFIG_SA1100_SIMPAD) += leds-simpad.o
+
+ # LEDs support
+diff -uNr linux-2.6.24.vanilla/arch/arm/mach-sa1100/cs3-simpad.c linux-2.6.24/arch/arm/mach-sa1100/cs3-simpad.c
+--- linux-2.6.24.vanilla/arch/arm/mach-sa1100/cs3-simpad.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24/arch/arm/mach-sa1100/cs3-simpad.c 2008-02-20 20:49:57.000000000 +0100
+@@ -0,0 +1,169 @@
++/*
++ * simpad-cs3.c
++ *
++ * This driver shows the GPIO states of the cs3 latch. You can also
++ * switch some GPIOS.
++ *
++ * (c) 2007 Bernhard Guillon <Bernhard.Guillon@OpenSIMpad.org>
++ *
++ * You may use this code as per GPL version 2
++ *
++ * Some parts are based on battery.c
++ *
++ * mrdata: -added cs3_ro support
++ * -added preprocessor stuff
++ *
++ */
++
++#include <linux/module.h>
++#include <linux/types.h>
++#include <linux/init.h>
++#include <linux/device.h>
++
++#include <asm/arch/simpad.h>
++
++extern long get_cs3_ro(void);
++extern long get_cs3_shadow(void);
++extern void set_cs3_bit(int value);
++extern void clear_cs3_bit(int value);
++
++struct cs3 {
++ struct class_device class_dev;
++ const char *name;
++ char *id;
++ int type;
++};
++
++struct cs3 cs3 ={
++ .name = "latch_cs3",
++};
++
++
++#define CS3_STORE_ATTR(namek,nameg) \
++static ssize_t namek##_store (struct class_device *cdev, const char * buf, size_t count) \
++{ \
++ char val; \
++ if (sscanf(buf, "%c",&val) != 1) \
++ return -EINVAL; \
++ if (val == '1') \
++ set_cs3_bit(nameg); \
++ else if (val == '0') \
++ clear_cs3_bit(nameg); \
++ return strlen(buf); \
++}
++
++CS3_STORE_ATTR(display_on, DISPLAY_ON);
++CS3_STORE_ATTR(dect_power_on, DECT_POWER_ON);
++CS3_STORE_ATTR(irda_sd, IRDA_SD);
++CS3_STORE_ATTR(sd_mediaq, SD_MEDIAQ);
++CS3_STORE_ATTR(led2_on, LED2_ON);
++CS3_STORE_ATTR(irda_mode, IRDA_MODE);
++CS3_STORE_ATTR(reset_simcard, RESET_SIMCARD);
++
++
++#define CS3_ATTR(shadro,namek,nameg,mode,store) \
++static ssize_t namek##_show(struct class_device *class_dev, char *buf) \
++{ \
++ if (get_cs3_##shadro() & nameg ) \
++ return sprintf(buf, "1\n"); \
++ else \
++ return sprintf(buf, "0\n"); \
++} \
++static CLASS_DEVICE_ATTR(namek, mode, namek##_show, store)
++
++CS3_ATTR(shadow, vcc_5v_en, VCC_5V_EN, 0444, NULL);
++CS3_ATTR(shadow, vcc_3v_en, VCC_3V_EN, 0444, NULL);
++CS3_ATTR(shadow, en1, EN1, 0444, NULL);
++CS3_ATTR(shadow, en0, EN0, 0444, NULL);
++CS3_ATTR(shadow, display_on, DISPLAY_ON, 0664, display_on_store);
++CS3_ATTR(shadow, pcmcia_buff_dis, PCMCIA_BUFF_DIS, 0444, NULL);
++CS3_ATTR(shadow, mq_reset, MQ_RESET, 0444, NULL);
++CS3_ATTR(shadow, pcmcia_reset, PCMCIA_RESET, 0444, NULL);
++CS3_ATTR(shadow, dect_power_on, DECT_POWER_ON, 0664, dect_power_on_store);
++CS3_ATTR(shadow, irda_sd, IRDA_SD, 0664, irda_sd_store);
++CS3_ATTR(shadow, rs232_on, RS232_ON, 0444, NULL);
++CS3_ATTR(shadow, sd_mediaq, SD_MEDIAQ, 0664, sd_mediaq_store);
++CS3_ATTR(shadow, led2_on, LED2_ON, 0664, led2_on_store);
++CS3_ATTR(shadow, irda_mode, IRDA_MODE, 0664, irda_mode_store);
++CS3_ATTR(shadow, enable_5v, ENABLE_5V, 0444, NULL);
++CS3_ATTR(shadow, reset_simcard, RESET_SIMCARD, 0664, reset_simcard_store);
++CS3_ATTR(ro, pcmcia_bvd1, PCMCIA_BVD1, 0444, NULL);
++CS3_ATTR(ro, pcmcia_bvd2, PCMCIA_BVD2, 0444, NULL);
++CS3_ATTR(ro, pcmcia_vs1, PCMCIA_VS1, 0444, NULL);
++CS3_ATTR(ro, pcmcia_vs2, PCMCIA_VS2, 0444, NULL);
++CS3_ATTR(ro, lock_ind, LOCK_IND, 0444, NULL);
++CS3_ATTR(ro, charging_state, CHARGING_STATE, 0444, NULL);
++CS3_ATTR(ro, pcmcia_short, PCMCIA_SHORT, 0444, NULL);
++
++static struct class simpad_gpios_class = {
++ .name = "simpad",
++};
++
++#define create_entry_conditional(namek) \
++ rc = class_device_create_file(&cs3->class_dev, &class_device_attr_##namek); \
++ if (rc) goto out; \
++
++static int register_cs3_latch(struct cs3 *cs3)
++{
++ int rc = 0;
++ cs3->class_dev.class = &simpad_gpios_class;
++ strcpy(cs3->class_dev.class_id, cs3->name);
++ rc = class_device_register(&cs3->class_dev);
++ if(rc)
++ goto out;
++
++ create_entry_conditional(vcc_5v_en);
++ create_entry_conditional(vcc_3v_en);
++ create_entry_conditional(en1);
++ create_entry_conditional(en0);
++ create_entry_conditional(display_on);
++ create_entry_conditional(pcmcia_buff_dis);
++ create_entry_conditional(mq_reset);
++ create_entry_conditional(pcmcia_reset);
++ create_entry_conditional(dect_power_on);
++ create_entry_conditional(irda_sd);
++ create_entry_conditional(rs232_on);
++ create_entry_conditional(sd_mediaq);
++ create_entry_conditional(led2_on);
++ create_entry_conditional(irda_mode);
++ create_entry_conditional(enable_5v);
++ create_entry_conditional(reset_simcard);
++ create_entry_conditional(pcmcia_bvd1);
++ create_entry_conditional(pcmcia_bvd2);
++ create_entry_conditional(pcmcia_vs1);
++ create_entry_conditional(pcmcia_vs2);
++ create_entry_conditional(lock_ind);
++ create_entry_conditional(charging_state);
++ create_entry_conditional(pcmcia_short);
++
++out:
++ return rc;
++}
++
++static int __init simpad_gpios_class_init(void)
++{
++ int rc = 0;
++
++ rc = class_register(&simpad_gpios_class);
++
++ if(rc != 0)
++ {
++ printk(KERN_ERR "cs3 latch class failed to register properly\n");
++ return rc;
++ }
++
++ rc = register_cs3_latch(&cs3);
++ return rc;
++}
++
++static void __exit simpad_gpios_class_exit(void)
++{
++ class_unregister(&simpad_gpios_class);
++}
++
++module_init(simpad_gpios_class_init);
++module_exit(simpad_gpios_class_exit);
++
++MODULE_AUTHOR("Bernhard Guillon");
++MODULE_DESCRIPTION("CS3_latch driver");
++MODULE_LICENSE("GPL");
diff --git a/recipes/linux/linux/simpad/linux-2.6.24-SIMpad-hostap_cs-shared-irq.patch b/recipes/linux/linux/simpad/linux-2.6.24-SIMpad-hostap_cs-shared-irq.patch
new file mode 100644
index 0000000000..758ddae7f7
--- /dev/null
+++ b/recipes/linux/linux/simpad/linux-2.6.24-SIMpad-hostap_cs-shared-irq.patch
@@ -0,0 +1,106 @@
+diff -Nur linux-2.6.24.vanilla/drivers/net/wireless/hostap/hostap_cs.c linux-2.6.24/drivers/net/wireless/hostap/hostap_cs.c
+--- linux-2.6.24.vanilla/drivers/net/wireless/hostap/hostap_cs.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24/drivers/net/wireless/hostap/hostap_cs.c 2008-02-28 12:00:27.000000000 +0100
+@@ -1,3 +1,8 @@
++/*
++ *
++ * mrdata: -added shared irq
++ */
++
+ #define PRISM2_PCCARD
+
+ #include <linux/module.h>
+@@ -35,7 +40,7 @@
+ module_param(ignore_cis_vcc, int, 0444);
+ MODULE_PARM_DESC(ignore_cis_vcc, "Ignore broken CIS VCC entry");
+
+-
++int activar=0;
+ /* struct local_info::hw_priv */
+ struct hostap_cs_priv {
+ dev_node_t node;
+@@ -499,11 +504,13 @@
+
+ PDEBUG(DEBUG_HW, "%s: setting Vcc=33 (constant)\n", dev_info);
+ p_dev->conf.IntType = INT_MEMORY_AND_IO;
+-
++
++ activar=0;
+ ret = prism2_config(p_dev);
+ if (ret) {
+ PDEBUG(DEBUG_EXTRA, "prism2_config() failed\n");
+ }
++ activar=1;
+
+ return ret;
+ }
+@@ -693,7 +700,7 @@
+ * irq structure is initialized.
+ */
+ if (link->conf.Attributes & CONF_ENABLE_IRQ) {
+- link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
++ link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_FIRST_SHARED | IRQ_HANDLE_PRESENT;
+ link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+ link->irq.Handler = prism2_interrupt;
+ link->irq.Instance = dev;
+diff -Nur linux-2.6.24.vanilla/drivers/net/wireless/hostap/hostap_hw.c linux-2.6.24/drivers/net/wireless/hostap/hostap_hw.c
+--- linux-2.6.24.vanilla/drivers/net/wireless/hostap/hostap_hw.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24/drivers/net/wireless/hostap/hostap_hw.c 2008-02-28 12:00:27.000000000 +0100
+@@ -54,6 +54,7 @@
+ #include "hostap.h"
+ #include "hostap_ap.h"
+
++extern int activar;
+
+ /* #define final_version */
+
+@@ -1497,6 +1498,8 @@
+ if (local->hw_downloading)
+ return 1;
+
++ activar=1;
++
+ if (prism2_hw_init(dev, initial)) {
+ return local->no_pri ? 0 : 1;
+ }
+@@ -2630,8 +2633,15 @@
+ int events = 0;
+ u16 ev;
+
+- iface = netdev_priv(dev);
+- local = iface->local;
++
++ // Todos los parametros de entrada son correctos (no son nulos). De momento esta es la unica forma que conozco de detectar el problema.
++ if (!activar) {
++ printk("hostap_hw.c: INTERRUPT BEFORE DEVICE INIT!\n");
++ return IRQ_HANDLED;
++ }
++
++ iface = netdev_priv(dev);
++ local = iface->local;
+
+ prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_INTERRUPT, 0, 0);
+
+diff -Nur linux-2.6.24.vanilla/drivers/net/wireless/hostap/hostap_pci.c linux-2.6.24/drivers/net/wireless/hostap/hostap_pci.c
+--- linux-2.6.24.vanilla/drivers/net/wireless/hostap/hostap_pci.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24/drivers/net/wireless/hostap/hostap_pci.c 2008-02-28 12:00:27.000000000 +0100
+@@ -19,6 +19,7 @@
+
+ #include "hostap_wlan.h"
+
++int activar=1;
+
+ static char *dev_info = "hostap_pci";
+
+diff -Nur linux-2.6.24.vanilla/drivers/net/wireless/hostap/hostap_plx.c linux-2.6.24/drivers/net/wireless/hostap/hostap_plx.c
+--- linux-2.6.24.vanilla/drivers/net/wireless/hostap/hostap_plx.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24/drivers/net/wireless/hostap/hostap_plx.c 2008-02-28 12:00:27.000000000 +0100
+@@ -21,7 +21,7 @@
+ #include <asm/io.h>
+
+ #include "hostap_wlan.h"
+-
++int activar=1;
+
+ static char *dev_info = "hostap_plx";
+
diff --git a/recipes/linux/linux/simpad/linux-2.6.24-SIMpad-mq200.patch b/recipes/linux/linux/simpad/linux-2.6.24-SIMpad-mq200.patch
new file mode 100644
index 0000000000..ac9fdfbfcf
--- /dev/null
+++ b/recipes/linux/linux/simpad/linux-2.6.24-SIMpad-mq200.patch
@@ -0,0 +1,2513 @@
+diff -Nur linux-2.6.24.vanilla/drivers/video/Kconfig linux-2.6.24/drivers/video/Kconfig
+--- linux-2.6.24.vanilla/drivers/video/Kconfig 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24/drivers/video/Kconfig 2008-02-20 21:51:22.000000000 +0100
+@@ -198,7 +198,7 @@
+ This is particularly important to one driver, matroxfb. If
+ unsure, say N.
+
+-comment "Frame buffer hardware drivers"
++comment "Frambuffer hardware drivers"
+ depends on FB
+
+ config FB_CIRRUS
+@@ -1389,6 +1389,15 @@
+ ---help---
+ Driver for graphics boards with S3 Trio / S3 Virge chip.
+
++config FB_MQ200
++ bool "MQ200 Driver"
++ depends on (FB = y) && ARM && ARCH_SA1100
++ select FB_CFB_FILLRECT
++ select FB_CFB_COPYAREA
++ select FB_CFB_IMAGEBLIT
++ help
++ This is a MQ200 driver tested only on Siemens SIMpads.
++
+ config FB_SAVAGE
+ tristate "S3 Savage support"
+ depends on FB && PCI && EXPERIMENTAL
+diff -Nur linux-2.6.24.vanilla/drivers/video/Makefile linux-2.6.24/drivers/video/Makefile
+--- linux-2.6.24.vanilla/drivers/video/Makefile 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24/drivers/video/Makefile 2008-02-20 21:51:22.000000000 +0100
+@@ -35,6 +35,7 @@
+ obj-$(CONFIG_FB_PM2) += pm2fb.o
+ obj-$(CONFIG_FB_PM3) += pm3fb.o
+
++obj-$(CONFIG_FB_MQ200) += mq200/
+ obj-$(CONFIG_FB_MATROX) += matrox/
+ obj-$(CONFIG_FB_RIVA) += riva/
+ obj-$(CONFIG_FB_NVIDIA) += nvidia/
+diff -Nur linux-2.6.24.vanilla/drivers/video/backlight/Kconfig linux-2.6.24/drivers/video/backlight/Kconfig
+--- linux-2.6.24.vanilla/drivers/video/backlight/Kconfig 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24/drivers/video/backlight/Kconfig 2008-02-20 21:51:22.000000000 +0100
+@@ -90,3 +90,20 @@
+ help
+ If you have a Intel LE80578 (Carillo Ranch) say Y to enable the
+ backlight driver.
++
++config BACKLIGHT_SIMPAD
++ tristate "SIMpad MQ200 Backlight driver"
++ depends on SA1100_SIMPAD && BACKLIGHT_CLASS_DEVICE
++ default y
++ help
++ If you have a Siemens SIMpad say Y to enable the
++ backlight driver.
++
++config LCD_SIMPAD
++ tristate "SIMpad MQ200 LCD driver"
++ depends on SA1100_SIMPAD && LCD_CLASS_DEVICE
++ default y
++ help
++ If you have a Siemens SIMpad say Y to enable the
++ LCD driver.
++
+diff -Nur linux-2.6.24.vanilla/drivers/video/backlight/Makefile linux-2.6.24/drivers/video/backlight/Makefile
+--- linux-2.6.24.vanilla/drivers/video/backlight/Makefile 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24/drivers/video/backlight/Makefile 2008-02-20 21:51:22.000000000 +0100
+@@ -9,3 +9,5 @@
+ obj-$(CONFIG_BACKLIGHT_LOCOMO) += locomolcd.o
+ obj-$(CONFIG_BACKLIGHT_PROGEAR) += progear_bl.o
+ obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH) += cr_bllcd.o
++obj-$(CONFIG_BACKLIGHT_SIMPAD) += simpad_bl.o
++obj-$(CONFIG_LCD_SIMPAD) += simpad_lcd.o
+diff -Nur linux-2.6.24.vanilla/drivers/video/backlight/simpad_bl.c linux-2.6.24/drivers/video/backlight/simpad_bl.c
+--- linux-2.6.24.vanilla/drivers/video/backlight/simpad_bl.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24/drivers/video/backlight/simpad_bl.c 2008-02-20 21:51:22.000000000 +0100
+@@ -0,0 +1,208 @@
++/*
++ * GPLv2 <zecke@handhelds.org
++ *
++ * Implementation of the backlight_driver for
++ * the mq200 framebuffer
++ *
++ * 2007/03/17 mrdata:
++ * - small changes simpad_bl_get_brightness()
++ * simpad_bl_set_brightness()
++ * - new function simpad_bl_update_status()
++ * - changed struct backlight_properties simpad_bl_props()
++ * to new one
++ * - changed __init simpad_bl_init() -> backlight_device_register
++ *
++ * 2007/03/24 mrdata
++ * - added .brightness=127 in
++ * struct backlight_properties simpad_bl_props()
++ */
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/platform_device.h>
++#include <linux/spinlock.h>
++#include <linux/fb.h>
++#include <linux/backlight.h>
++
++#include <asm/types.h>
++#include <asm/hardware.h>
++#include <asm/io.h>
++
++#include "../mq200/mq200_data.h"
++
++#define SIMPAD_BACKLIGHT_MASK 0x00a10044
++#define SIMPAD_DEFAULT_INTENSITY 127
++#define SIMPAD_MAX_INTENSITY 254
++#define REGISTER_BASE 0xf2e00000
++
++static int simpad_bl_suspended;
++static int current_intensity = 0;
++
++static void simpad_bl_send_intensity(struct backlight_device *bd)
++{
++ int intensity = bd->props.brightness;
++
++ union fp0fr fp0fr;
++ unsigned long dutyCycle, pwmcontrol;
++
++ if (intensity > SIMPAD_MAX_INTENSITY)
++ intensity = SIMPAD_MAX_INTENSITY;
++
++ if (bd->props.power != FB_BLANK_UNBLANK)
++ intensity = 0;
++
++ if (bd->props.fb_blank != FB_BLANK_UNBLANK)
++ intensity = 0;
++
++ if (simpad_bl_suspended)
++ intensity = 0;
++
++ if (intensity != current_intensity)
++ {
++ /*
++ * Determine dutyCycle.
++ * Note: the lower the value, the brighter the display!
++ */
++
++ dutyCycle = SIMPAD_MAX_INTENSITY - intensity;
++
++ /*
++ * Configure PWM0 (source clock = oscillator clock, pwm always enabled,
++ * zero, clock pre-divider = 4) pwm frequency = 12.0kHz
++ */
++
++ fp0fr.whole = readl(FP0FR(REGISTER_BASE));
++ pwmcontrol = fp0fr.whole & 0xffff00ff;
++ fp0fr.whole &= 0xffffff00;
++ fp0fr.whole |= 0x00000044;
++ writel(fp0fr.whole, FP0FR(REGISTER_BASE));
++
++ /* Write to pwm duty cycle register. */
++ fp0fr.whole = dutyCycle << 8;
++ fp0fr.whole &= 0x0000ff00;
++ fp0fr.whole |= pwmcontrol;
++ writel(fp0fr.whole, FP0FR(REGISTER_BASE));
++
++ current_intensity = intensity;
++ }
++}
++
++
++#ifdef CONFIG_PM
++static int simpad_bl_suspend(struct platform_device *pdev, pm_message_t state)
++{
++ struct backlight_device *bd = platform_get_drvdata(pdev);
++
++ simpad_bl_suspended = 1;
++ simpad_bl_send_intensity(bd);
++ return 0;
++}
++
++static int simpad_bl_resume(struct platform_device *pdev)
++{
++ struct backlight_device *bd = platform_get_drvdata(pdev);
++
++ simpad_bl_suspended = 0;
++ simpad_bl_send_intensity(bd);
++ return 0;
++}
++#else
++#define simpad_bl_suspend NULL
++#define simpad_bl_resume NULL
++#endif
++
++
++static int simpad_bl_set_intensity(struct backlight_device *bd)
++{
++ simpad_bl_send_intensity(bd);
++ return 0;
++}
++
++
++static int simpad_bl_get_intensity(struct backlight_device *bd)
++{
++ return current_intensity;
++}
++
++
++static struct backlight_ops simpad_bl_ops = {
++ .get_brightness = simpad_bl_get_intensity,
++ .update_status = simpad_bl_set_intensity,
++};
++
++
++static int __init simpad_bl_probe(struct platform_device *pdev)
++{
++ struct backlight_device *bd;
++
++ bd = backlight_device_register("simpad-mq200-bl", &pdev->dev, NULL, &simpad_bl_ops);
++
++ if (IS_ERR (bd))
++ return PTR_ERR (bd);
++
++ platform_set_drvdata(pdev, bd);
++
++ bd->props.max_brightness = SIMPAD_MAX_INTENSITY;
++ bd->props.brightness = SIMPAD_DEFAULT_INTENSITY;
++ simpad_bl_send_intensity(bd);
++
++ return 0;
++}
++
++
++static int simpad_bl_remove(struct platform_device *pdev)
++{
++ struct backlight_device *bd = platform_get_drvdata(pdev);
++
++ bd->props.brightness = 0;
++ bd->props.power = 0;
++ simpad_bl_send_intensity(bd);
++
++ backlight_device_unregister(bd);
++
++ return 0;
++}
++
++static struct platform_driver simpad_bl_driver = {
++ .probe = simpad_bl_probe,
++ .remove = simpad_bl_remove,
++ .suspend = simpad_bl_suspend,
++ .resume = simpad_bl_resume,
++ .driver = {
++ .name = "simpad-mq200-bl",
++ },
++};
++
++static struct platform_device *simpad_bl_device = NULL;
++
++static int __init simpad_bl_init(void)
++{
++ int ret;
++
++ ret = platform_driver_register(&simpad_bl_driver);
++ if (!ret) {
++ simpad_bl_device = platform_device_alloc("simpad-mq200-bl", -1);
++ if (!simpad_bl_device)
++ return -ENOMEM;
++
++ ret = platform_device_add(simpad_bl_device);
++
++ if (ret) {
++ platform_device_put(simpad_bl_device);
++ platform_driver_unregister(&simpad_bl_driver);
++ }
++ }
++ return ret;
++}
++
++static void __exit simpad_bl_exit(void)
++{
++ platform_device_unregister(simpad_bl_device);
++ platform_driver_unregister(&simpad_bl_driver);
++}
++
++
++module_init(simpad_bl_init);
++module_exit(simpad_bl_exit);
++MODULE_AUTHOR("Holger Hans Peter Freyther");
++MODULE_LICENSE("GPL");
+diff -Nur linux-2.6.24.vanilla/drivers/video/backlight/simpad_lcd.c linux-2.6.24/drivers/video/backlight/simpad_lcd.c
+--- linux-2.6.24.vanilla/drivers/video/backlight/simpad_lcd.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24/drivers/video/backlight/simpad_lcd.c 2008-02-20 21:51:22.000000000 +0100
+@@ -0,0 +1,172 @@
++/*
++ * GPLv2 <zecke@handhelds.org
++ *
++ * Implementation of the lcd_driver for the mq200 framebuffer
++ *
++ * 2007/03/24 mrdata:
++ * - added simpad_lcd_get_contrast()
++ * - added simpad_lcd_set_contrast()
++ * - modify struct lcd_properties simpad_lcd_props
++ */
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/platform_device.h>
++#include <linux/fb.h>
++#include <linux/lcd.h>
++
++#include <asm/arch/simpad.h>
++#include <asm/hardware.h>
++
++extern long get_cs3_shadow(void);
++extern void set_cs3_bit(int);
++extern void clear_cs3_bit(int);
++
++#define UNUSED(x) x=x
++
++static int simpad_lcd_get_power(struct lcd_device* dev)
++{
++ UNUSED(dev);
++
++ return (get_cs3_shadow() & DISPLAY_ON) ? 0 : 4;
++}
++
++static int simpad_lcd_set_power(struct lcd_device* dev, int power)
++{
++ UNUSED(dev);
++
++ if( power == 4 )
++ clear_cs3_bit(DISPLAY_ON);
++ else
++ set_cs3_bit(DISPLAY_ON);
++
++ return 0;
++}
++
++static int simpad_lcd_get_contrast(struct lcd_device* dev)
++{
++ UNUSED(dev);
++
++ return 0;
++}
++
++static int simpad_lcd_set_contrast(struct lcd_device* dev, int contrast)
++{
++ UNUSED(dev);
++
++ UNUSED(contrast);
++
++ return 0;
++}
++
++#ifdef CONFIG_PM
++static int simpad_lcd_suspend(struct platform_device *pdev, pm_message_t state)
++{
++ static int ret;
++ struct lcd_device* ld;
++
++ UNUSED(state);
++
++ ld = platform_get_drvdata(pdev);
++
++ ret = simpad_lcd_set_power(ld, 4);
++
++ return ret;
++}
++
++static int simpad_lcd_resume(struct platform_device *pdev)
++{
++ struct lcd_device *ld;
++ static int ret;
++
++ ld = platform_get_drvdata(pdev);
++
++ ret = simpad_lcd_set_power(ld, 0);
++
++ return ret;
++}
++#else
++#define simpad_lcd_suspend NULL
++#define simpad_lcd_resume NULL
++#endif
++
++
++/*FIXME
++static struct lcd_properties simpad_lcd_props = {
++ .max_contrast = 0,
++};
++*/
++
++static struct lcd_ops simpad_lcd_ops = {
++ .get_power = simpad_lcd_get_power,
++ .set_power = simpad_lcd_set_power,
++ .get_contrast = simpad_lcd_get_contrast,
++ .set_contrast = simpad_lcd_set_contrast,
++};
++
++static int __init simpad_lcd_probe(struct platform_device *pdev)
++{
++ struct lcd_device *ld;
++
++ ld = lcd_device_register ("simpad-mq200-lcd", &pdev->dev, NULL, &simpad_lcd_ops);
++
++ if (IS_ERR(ld))
++ return PTR_ERR(ld);
++
++ platform_set_drvdata(pdev, ld);
++
++ ld->props.max_contrast = 0;
++
++ return 0;
++}
++
++static int simpad_lcd_remove(struct platform_device *pdev)
++{
++ struct lcd_device *ld = platform_get_drvdata(pdev);
++
++ lcd_device_unregister(ld);
++
++ return 0;
++}
++
++static struct platform_driver simpad_lcd_driver = {
++ .probe = simpad_lcd_probe,
++ .remove = simpad_lcd_remove,
++ .suspend = simpad_lcd_suspend,
++ .resume = simpad_lcd_resume,
++ .driver = {
++ .name = "simpad-mq200-lcd",
++ },
++};
++
++static struct platform_device *simpad_lcd_device = NULL;
++
++static int __init simpad_lcd_init(void)
++{
++ int ret;
++
++ ret = platform_driver_register(&simpad_lcd_driver);
++ if (!ret) {
++ simpad_lcd_device = platform_device_alloc("simpad-mq200-lcd", -1);
++ if (!simpad_lcd_device)
++ return -ENOMEM;
++
++ ret = platform_device_add(simpad_lcd_device);
++
++ if (ret) {
++ platform_device_put(simpad_lcd_device);
++ platform_driver_unregister(&simpad_lcd_driver);
++ }
++ }
++ return ret;
++}
++
++static void __exit simpad_lcd_exit(void) {
++ platform_driver_unregister(&simpad_lcd_driver);
++ platform_device_unregister(simpad_lcd_device);
++}
++
++module_init(simpad_lcd_init);
++module_exit(simpad_lcd_exit);
++MODULE_AUTHOR("Holger Hans Peter Freyther");
++MODULE_LICENSE("GPL");
+diff -Nur linux-2.6.24.vanilla/drivers/video/mq200/Makefile linux-2.6.24/drivers/video/mq200/Makefile
+--- linux-2.6.24.vanilla/drivers/video/mq200/Makefile 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24/drivers/video/mq200/Makefile 2008-02-20 21:51:22.000000000 +0100
+@@ -0,0 +1,6 @@
++# Makefile for mq200 video driver
++# 4 Aug 2003, Holger Hans Peter Freyther
++#
++
++obj-$(CONFIG_FB_MQ200) += mq_skeleton.o mq_external.o
++
+diff -Nur linux-2.6.24.vanilla/drivers/video/mq200/mq200_data.h linux-2.6.24/drivers/video/mq200/mq200_data.h
+--- linux-2.6.24.vanilla/drivers/video/mq200/mq200_data.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24/drivers/video/mq200/mq200_data.h 2008-02-20 21:51:22.000000000 +0100
+@@ -0,0 +1,1120 @@
++/*
++ * From ucLinux mq200fb.c and mq200fb.h
++ *
++ * 2007/03/11 mrdata:
++ * insert registers for graphics controller 2 module
++ */
++
++#ifndef __MQ200_FB_H__
++#define __MQ200_FB_H__
++
++struct mq200_io_regions {
++ u32 fb_size; /* framebuffer size */
++ unsigned long phys_mmio_base; /* physical register memory base */
++ unsigned long virt_mmio_base; /* virtual start of registers */
++ unsigned long phys_fb_base; /* physical address of frame buffer */
++ unsigned long virt_fb_base; /* virtual start of the framebuffer */
++};
++
++#define MQ200_MONITOR_HORI_RES(info) info->monitor_info.horizontal_res
++#define MQ200_MONITOR_VERT_RES(info) info->monitor_info.vertical_res
++#define MQ200_MONITOR_DEPTH(info) info->monitor_info.depth
++#define MQ200_MONITOR_LINE_LENGTH(info) info->monitor_info.line_length
++
++struct mq200_monitor_info {
++ unsigned int horizontal_res;
++ unsigned int vertical_res;
++ unsigned int depth;
++ unsigned int refresh;
++ unsigned int line_length;
++ unsigned long flags;
++};
++
++
++/**
++ * Addresses of Module
++ */
++#define MQ200_FB_BASE (x) (x + 0x1800000) /* framebuffer */
++#define MQ200_FB_SIZE 0x200000 /* framebuffer size in bytes */
++#define MQ200_REGS_BASE(x) (x + 0x1e00000) /* start of registers area */
++#define MQ200_REGS_SIZE 0x200000 /* registers area size */
++
++#define PMU_OFFSET 0x00000 /* power management */
++#define CPU_OFFSET 0x02000 /* CPU interface */
++#define MIU_OFFSET 0x04000 /* memory controller */
++#define IN_OFFSET 0x08000 /* interrupt controller */
++#define GC_OFFSET 0x0a000 /* graphics controller 1&2 */
++#define GE_OFFSET 0x0c000 /* graphics engine */
++#define FPI_OFFSET 0x0e000 /* flat panel controller */
++#define CP1_OFFSET 0x10000 /* color palette 1 */
++#define DC_OFFSET 0x14000 /* device configuration */
++#define PCI_OFFSET 0x16000 /* PCI configuration */
++#define PSF_OFFSET 0x18000 /* ??? */
++
++
++/****
++ * Registers
++ */
++
++/* power management unit */
++#define PMR(addr) (addr + PCI_OFFSET + 0x40)/* power management
++ register */
++#define PMR_VALUE 0x06210001 /* expected read value of PMR register */
++#define PM00R(addr) (addr + PMU_OFFSET + 0x00) /* power management unit
++ configuration
++ register */
++#define PM01R(addr) (addr + PMU_OFFSET + 0x04) /* D1 state control */
++#define PM02R(addr) (addr + PMU_OFFSET + 0x08) /* d2 state control */
++#define PM06R(addr) (addr + PMU_OFFSET + 0x18) /* PLL 2 programming */
++#define PM07R(addr) (addr + PMU_OFFSET + 0x1c) /* PLL 3 programming */
++
++#define PMCSR(addr) (addr + PCI_OFFSET + 0x44) /* power management
++ control/status
++ register */
++
++/* memory interface unit */
++#define MM00R(addr) (addr + MIU_OFFSET + 0x00)/* MIU interface control
++ 0 */
++#define MM01R(addr) (addr + MIU_OFFSET + 0x04) /* MIU interface control
++ 1 */
++#define MM02R(addr) (addr + MIU_OFFSET + 0x08) /* memory interface
++ control 2 */
++#define MM03R(addr) (addr + MIU_OFFSET + 0x0c) /* memory interface
++ control 3 */
++#define MM04R(addr) (addr + MIU_OFFSET + 0x10) /* memory interface
++ control 4 */
++/* graphics controller 1 module */
++#define GC00R(addr) (addr + GC_OFFSET + 0x00) /* graphics controller 1
++ control */
++#define GC01R(addr) (addr + GC_OFFSET + 0x04) /* graphics controller
++ CRT control */
++#define GC02R(addr) (addr + GC_OFFSET + 0x08) /* horizontal display 1
++ control */
++#define GC03R(addr) (addr + GC_OFFSET + 0x0c) /* vertical display 1
++ control */
++#define GC04R(addr) (addr + GC_OFFSET + 0x10) /* horizontal sync 1
++ control */
++#define GC05R(addr) (addr + GC_OFFSET + 0x14) /* vertical sync 1
++ control */
++#define GC07R(addr) (addr + GC_OFFSET + 0x1c) /* vertical display 1
++ count */
++#define GC08R(addr) (addr + GC_OFFSET + 0x20) /* horizontal window 1
++ control */
++#define GC09R(addr) (addr + GC_OFFSET + 0x24) /* vertical window 1
++ control */
++#define GC0AR(addr) (addr + GC_OFFSET + 0x28) /* alternate horizontal
++ window 1 control */
++#define GC0BR(addr) (addr + GC_OFFSET + 0x2c) /* alternate vertical
++ window 1 control */
++#define GC0CR(addr) (addr + GC_OFFSET + 0x30) /* window 1
++ start address */
++#define GC0DR(addr) (addr + GC_OFFSET + 0x34) /* alternate window 1
++ start address */
++#define GC0ER(addr) (addr + GC_OFFSET + 0x38) /* alternate window 1
++ stride */
++#define GC0FR(addr) (addr + GC_OFFSET + 0x3c) /* alternate window 1
++ line size */
++#define GC10R(addr) (addr + GC_OFFSET + 0x40) /* hardware cursor 1
++ position */
++#define GC11R(addr) (addr + GC_OFFSET + 0x44) /* hardware cursor 1
++ start address and
++ offset */
++#define GC12R(addr) (addr + GC_OFFSET + 0x48) /* hardware cursor 1
++ foreground color */
++#define GC13R(addr) (addr + GC_OFFSET + 0x4c) /* hardware cursor 1
++ background color */
++
++/* graphics controller 2 module */
++#define GC20R(addr) (addr + GC_OFFSET + 0x80) /* graphics controller 2
++ control */
++#define GC21R(addr) (addr + GC_OFFSET + 0x84) /* graphics controller
++ CRC control */
++#define GC22R(addr) (addr + GC_OFFSET + 0x88) /* horizontal display 2
++ control */
++#define GC23R(addr) (addr + GC_OFFSET + 0x8c) /* vertical display 2
++ control */
++#define GC24R(addr) (addr + GC_OFFSET + 0x90) /* horizontal sync 2
++ control */
++#define GC25R(addr) (addr + GC_OFFSET + 0x94) /* vertical sync 2
++ control */
++#define GC27R(addr) (addr + GC_OFFSET + 0x9c) /* vertical display 2
++ count */
++#define GC28R(addr) (addr + GC_OFFSET + 0xa0) /* horizontal window 2
++ control */
++#define GC29R(addr) (addr + GC_OFFSET + 0xa4) /* vertical window 2
++ control */
++#define GC2AR(addr) (addr + GC_OFFSET + 0xa8) /* alternate horizontal
++ window 2 control */
++#define GC2BR(addr) (addr + GC_OFFSET + 0xac) /* alternate vertical
++ window 2 control */
++#define GC2CR(addr) (addr + GC_OFFSET + 0xb0) /* window 2
++ start address */
++#define GC2DR(addr) (addr + GC_OFFSET + 0xb4) /* alternate window 2
++ start address */
++#define GC2ER(addr) (addr + GC_OFFSET + 0xb8) /* alternate window 2
++ stride */
++#define GC2FR(addr) (addr + GC_OFFSET + 0xbc) /* alternate window 2
++ line size */
++#define GC30R(addr) (addr + GC_OFFSET + 0xc0) /* hardware cursor 2
++ position */
++#define GC31R(addr) (addr + GC_OFFSET + 0xc4) /* hardware cursor 2
++ start address and
++ offset */
++#define GC32R(addr) (addr + GC_OFFSET + 0xc8) /* hardware cursor 2
++ foreground color */
++#define GC33R(addr) (addr + GC_OFFSET + 0xcc) /* hardware cursor 2
++ background color */
++
++/* graphics engine */
++#define ROP_SRCCOPY 0xCC /* dest = source */
++#define ROP_SRCPAINT 0xEE /* dest = source OR dest */
++#define ROP_SRCAND 0x88 /* dest = source AND dest */
++#define ROP_SRCINVERT 0x66 /* dest = source XOR dest */
++#define ROP_SRCERASE 0x44 /* dest = source AND (NOT dest) */
++#define ROP_NOTSRCCOPY 0x33 /* dest = NOT source */
++#define ROP_NOTSRCERASE 0x11 /* dest = (NOT source) AND (NOT dest) */
++#define ROP_MERGECOPY 0xC0 /* dest = source AND pattern */
++#define ROP_MERGEPAINT 0xBB /* dest = (NOT source) OR dest */
++#define ROP_PATCOPY 0xF0 /* dest = pattern */
++#define ROP_PATPAINT 0xFB /* dest = DPSnoo */
++#define ROP_PATINVERT 0x5A /* dest = pattern XOR dest */
++#define ROP_DSTINVERT 0x55 /* dest = NOT dest */
++#define ROP_BLACKNESS 0x00 /* dest = BLACK */
++#define ROP_WHITENESS 0xFF /* dest = WHITE */
++
++#define GE00R(addr) (addr + GE_OFFSET + 0x00) /* primary drawing command
++ register */
++#define GE01R(addr) (addr + GE_OFFSET + 0x04) /* primary width and
++ height register */
++#define GE02R(addr) (addr + GE_OFFSET + 0x08) /* primary destination
++ address register */
++#define GE03R(addr) (addr + GE_OFFSET + 0x0c) /* primary source XY
++ register */
++#define GE04R(addr) (addr + GE_OFFSET + 0x10) /* primary color compare
++ register */
++#define GE05R(addr) (addr + GE_OFFSET + 0x14) /* primary clip left/top
++ register */
++#define GE06R(addr) (addr + GE_OFFSET + 0x18) /* primary clip
++ right/bottom register
++ */
++#define GE07R(addr) (addr + GE_OFFSET + 0x1c) /* primary source and
++ pattern offset
++ register */
++#define GE08R(addr) (addr + GE_OFFSET + 0x20) /* primary foreground
++ color
++ register/rectangle
++ fill register */
++#define GE09R(addr) (addr + GE_OFFSET + 0x24) /* source stride/offset
++ register */
++#define GE0AR(addr) (addr + GE_OFFSET + 0x28) /* destination stride
++ register and color
++ depth */
++#define GE0BR(addr) (addr + GE_OFFSET + 0x2c) /* image base address
++ register */
++#define GE40R(addr) (addr + GE_OFFSET + 0x100) /* mono pattern register
++ 0 */
++#define GE41R(addr) (addr + GE_OFFSET + 0x104) /* mono pattern register
++ 1 */
++#define GE42R(addr) (addr + GE_OFFSET + 0x108) /* foreground color
++ register */
++#define GE43R(addr) (addr + GE_OFFSET + 0x10c) /* background color
++ register */
++/* color palette */
++#define C1xxR(addr, regno) \
++ (addr + CP1_OFFSET + (regno) * 4) /* graphics controller color
++ palette 1 */
++/* device configuration */
++#define DC00R(addr) (addr + DC_OFFSET + 0x00) /* device configuration
++ register 0 */
++#define DC_RESET 0x4000
++/* PCI configuration space */
++#define PC00R(addr) (addr + PCI_OFFSET + 0x00)/* device ID/vendor ID
++ register */
++/* Flatpanel Control */
++#define FP00R(addr) (addr + FPI_OFFSET + 0x00) /* Flat Panel Control 0 */
++#define FP01R(addr) (addr + FPI_OFFSET + 0x04) /* Flat Panel Output Pin */
++#define FP02R(addr) (addr + FPI_OFFSET + 0x08) /* Flat Panel Gener Purpose
++ Outout Control Register */
++#define FP03R(addr) (addr + FPI_OFFSET + 0x0c) /* General Purpose I/O Port
++ Control Register */
++#define FP04R(addr) (addr + FPI_OFFSET + 0x10) /* STN Panel Control Register */
++#define FP05R(addr) (addr + FPI_OFFSET + 0x14) /* D-STN Half Frame Buffer
++ Control Register -By Guess */
++#define FP0FR(addr) (addr + FPI_OFFSET + 0x3c) /* Pulse Width Modulation
++ Control Register */
++#define FRCTL_PATTERN_COUNT 32
++#define FP10R(addr) (addr + FPI_OFFSET + 0x40) /* Frame-Rate Control Pattern
++ Register */
++#define FP11R(addr) (addr + FPI_OFFSET + 0x44)
++#define FP2FR(addr) (addr + FPI_OFFSET + 0xc0) /* Frame-Rate Control Weight
++ Registers */
++
++
++
++
++/* power management miscellaneous control */
++union pm00r {
++ struct {
++ u32 pll1_n_b5 :1; /* PLL 1 N parameter bit 5 is 0 */
++ u32 reserved_1 :1;
++ u32 pll2_enbl :1; /* PLL 2 enable */
++ u32 pll3_enbl :1; /* PLL 3 enable */
++ u32 reserved_2 :1;
++ u32 pwr_st_ctrl :1; /* power state status control */
++ u32 reserved_3 :2;
++
++ u32 ge_enbl :1; /* graphics engine enable */
++ u32 ge_bsy_gl :1; /* graphics engine force busy (global) */
++ u32 ge_bsy_lcl :1; /* graphics engine force busy (local) */
++ u32 ge_clock :2; /* graphics engine clock select */
++ u32 ge_cmd_fifo :1; /* graphics engine command FIFO reset */
++ u32 ge_src_fifo :1; /* graphics engine CPU source FIFO reset */
++ u32 miu_pwr_seq :1; /* memory interface unit power sequencing
++ enable */
++
++ u32 d3_mem_rfsh :1; /* D3 memory refresh */
++ u32 d4_mem_rfsh :1; /* D4 memory refresh */
++ u32 gpwr_intrvl :2; /* general power sequencing interval */
++ u32 fppwr_intrvl:2; /* flat panel power sequencing interval */
++ u32 gpwr_seq_ctr:1; /* general power sequencing interval control */
++ u32 pmu_tm :1; /* PMU test mode */
++
++ u32 pwr_state :2; /* power state (read only) */
++ u32 pwr_seq_st :1; /* power sequencing active status (read
++ only) */
++ u32 reserved_4 :5;
++ } part;
++ u32 whole;
++};
++
++/* D1 state control */
++union pm01r {
++ struct {
++ u32 osc_enbl :1; /* D1 oscillator enable */
++ u32 pll1_enbl :1; /* D1 PLL 1 enable */
++ u32 pll2_enbl :1; /* D1 PLL 2 enable */
++ u32 pll3_enbl :1; /* D1 PLL 3 enable */
++ u32 miu_enbl :1; /* D1 Memory Interface Unit (MIU) enable */
++ u32 mem_rfsh :1; /* D1 memory refresh enable */
++ u32 ge_enbl :1; /* D1 Graphics Engine (GE) enable */
++ u32 reserved_1 :1;
++
++ u32 crt_enbl :1; /* D1 CRT enable */
++ u32 fpd_enbl :1; /* D1 Flat Panel enable */
++ u32 reserved_2 :6;
++
++ u32 ctl1_enbl :1; /* D1 controller 1 enable */
++ u32 win1_enbl :1; /* D1 window 1 enable */
++ u32 awin1_enbl :1; /* D1 alternate window 1 enable */
++ u32 cur1_enbl :1; /* D1 cursor 1 enable */
++ u32 reserved_3 :4;
++
++ u32 ctl2_enbl :1; /* D1 controller 2 enable */
++ u32 win2_enbl :1; /* D1 window 2 enable */
++ u32 awin2_enbl :1; /* D1 alternate window 2 enable */
++ u32 cur2_enbl :1; /* D1 cursor 2 enable */
++ u32 reserved_4 :4;
++ } part;
++ u32 whole;
++};
++
++/* D2 state control */
++union pm02r {
++ struct {
++ u32 osc_enbl :1; /* D2 oscillator enable */
++ u32 pll1_enbl :1; /* D2 PLL 1 enable */
++ u32 pll2_enbl :1; /* D2 PLL 2 enable */
++ u32 pll3_enbl :1; /* D2 PLL 3 enable */
++ u32 miu_enbl :1; /* D2 Memory Interface Unit (MIU) enable */
++ u32 mem_rfsh :1; /* D2 memory refresh enable */
++ u32 ge_enbl :1; /* D2 Graphics Engine (GE) enable */
++ u32 reserved_1 :1;
++
++ u32 crt_enbl :1; /* D2 CRT enable */
++ u32 fpd_enbl :1; /* D2 Flat Panel enable */
++ u32 reserved_2 :6;
++
++ u32 ctl1_enbl :1; /* D2 controller 1 enable */
++ u32 win1_enbl :1; /* D2 window 1 enable */
++ u32 awin1_enbl :1; /* D2 alternate window 1 enable */
++ u32 cur1_enbl :1; /* D2 cursor 1 enable */
++ u32 reserved_3 :4;
++
++ u32 ctl2_enbl :1; /* D2 controller 2 enable */
++ u32 win2_enbl :1; /* D2 window 2 enable */
++ u32 awin2_enbl :1; /* D2 alternate window 2 enable */
++ u32 cur2_enbl :1; /* D2 cursor 2 enable */
++ u32 reserved_4 :4;
++ } part;
++ u32 whole;
++};
++
++/* PLL 2 programming */
++union pm06r {
++ struct {
++ u32 clk_src :1; /* PLL 2 reference clock source */
++ u32 bypass :1; /* PLL 2 bypass */
++ u32 reserved_1 :2;
++ u32 p_par :3; /* PLL 2 P parameter */
++ u32 reserved_2 :1;
++
++ u32 n_par :5; /* PLL 2 N parameter */
++ u32 reserved_3 :3;
++
++ u32 m_par :8; /* PLL 2 M parameter */
++
++ u32 reserved_4 :4;
++ u32 trim :4; /* PLL 2 trim value */
++ } part;
++ u32 whole;
++};
++
++/* PLL 3 programming */
++union pm07r {
++ struct {
++ u32 clk_src :1; /* PLL 3 reference clock source */
++ u32 bypass :1; /* PLL 3 bypass */
++ u32 reserved_1 :2;
++ u32 p_par :3; /* PLL 3 P parameter */
++ u32 reserved_2 :1;
++
++ u32 n_par :5; /* PLL 3 N parameter */
++ u32 reserved_3 :3;
++
++ u32 m_par :8; /* PLL 3 M parameter */
++
++ u32 reserved_4 :4;
++ u32 trim :4; /* PLL 3 trim value */
++ } part;
++ u32 whole;
++};
++
++
++
++/* MIU interface control 1 */
++union mm00r {
++ struct {
++ u32 miu_enbl :1; /* MIU enable bit */
++ u32 mr_dsbl :1; /* MIU reset disable bit */
++ u32 edr_dsbl :1; /* embedded DRAM reset disable bit */
++ u32 reserved_1 :29;
++ } part;
++ u32 whole;
++};
++
++/* MIU interface control 2 */
++union mm01r {
++ struct {
++ u32 mc_src :1; /* memory clock source */
++ u32 msr_enbl :1; /* memory slow refresh enable bit */
++ u32 pb_cpu :1; /* page break enable for CPU */
++ u32 pb_gc1 :1; /* page break enable for GC1 */
++ u32 pb_gc2 :1; /* page break enable for GC2 */
++ u32 pb_stn_r :1; /* page break enable for STN read */
++ u32 pb_stn_w :1; /* page break enable for STN write */
++ u32 pb_ge :1; /* page break enable for GE */
++ u32 reserved_1 :4;
++ u32 mr_interval :14; /* normal memory refresh time interval */
++ u32 reserved_2 :4;
++ u32 edarm_enbl :1; /* embedded DRAM auto-refresh mode enable */
++ u32 eds_enbl :1; /* EDRAM standby enable for EDRAM normal
++ mode operation */
++ } part;
++ u32 whole;
++};
++
++/* memory interface control 3 */
++union mm02r {
++ struct {
++ u32 bs_ :2;
++ u32 bs_stnr :2; /* burst count for STN read memory cycles */
++ u32 bs_stnw :2; /* burst count for STN write memroy cycles */
++ u32 bs_ge :2; /* burst count for graphics engine
++ read/write memroy cycles */
++ u32 bs_cpuw :2; /* burst count for CPU write memory cycles */
++ u32 fifo_gc1 :4; /* GC1 display refresh FIFO threshold */
++ u32 fifo_gc2 :4; /* GC2 display refresh FIFO threshold */
++ u32 fifo_stnr :4; /* STN read FIFO threshold */
++ u32 fifo_stnw :4; /* STN write FIFO threshold */
++ u32 fifo_ge_src :3; /* GE source read FIFO threshold */
++ u32 fifo_ge_dst :3; /* GE destination read FIFO threshold */
++ } part;
++ u32 whole;
++};
++
++/* memory interface control 4 */
++union mm03r {
++ struct {
++ u32 rd_late_req :1; /* read latency request */
++ u32 reserved_1 :31;
++ } part;
++ u32 whole;
++};
++
++/* memory interface control 5 */
++union mm04r {
++ struct {
++ u32 latency :3; /* EDRAM latency */
++ u32 dmm_cyc :1; /* enable for the dummy cycle insertion
++ between read and write cycles */
++ u32 pre_dmm_cyc :1; /* enable for the dummy cycle insertion
++ between read/write and precharge cycles
++ for the same bank */
++ u32 reserved_1 :3;
++ u32 bnk_act_cls :2; /* bank activate command to bank close
++ command timing interval control */
++ u32 bnk_act_rw :1; /* bank activate command to read/wirte
++ command timing interval control */
++ u32 bnk_cls_act :1; /* bank close command to bank activate
++ command timing interval control */
++ u32 trc :1; /* row cycle time */
++ u32 reserved_2 :3;
++ u32 delay_r :2; /* programmable delay for read clock */
++ u32 delay_m :2; /* programmable delay for internal memory
++ clock */
++ } part;
++ u32 whole;
++};
++
++/* graphics controller 1 register */
++union gc00r {
++ struct {
++ u32 ctl_enbl :1; /* Controller 1 Enable */
++ u32 hc_reset :1; /* Horizontal Counter 1 Reset */
++ u32 vc_reset :1; /* Vertical Counter 1 Reset */
++ u32 iwin_enbl :1; /* Image Window 1 Enable */
++ u32 gcd :4; /* Graphics Color Depth (GCD) */
++
++ u32 hc_enbl :1; /* Hardware Cursor 1 Enable */
++ u32 reserved_1 :2;
++ u32 aiwin_enbl :1; /* Alternate Image Window Enable */
++ u32 agcd :4; /* Alternate Graphics Color Depth (AGCD) */
++
++ u32 g1rclk_src :2; /* G1RCLK Source */
++ u32 tm0 :1; /* Test Mode 0 */
++ u32 tm1 :1; /* Test Mode 1 */
++ u32 fd :3; /* G1MCLK First Clock Divisor (FD1) */
++ u32 reserved_2 :1;
++
++ u32 sd :8; /* G1MCLK Second Clock Divisor (SD1) */
++ } part;
++ u32 whole;
++};
++
++/* graphics controller CRT control */
++union gc01r {
++ struct {
++ u32 dac_enbl :2; /* CRT DAC enable */
++ u32 hsync_out :1; /* CRT HSYNC output during power down mode */
++ u32 vsync_out :1; /* CRT VSYNC output during power down mode */
++ u32 hsync_ctl :2; /* CRT HSYNC control */
++ u32 vsync_ctl :2; /* CRT VSYNC control */
++ /**/
++ u32 hsync_pol :1; /* CRT HSYNC polarity */
++ u32 vsync_pol :1; /* CRT VSYNC polarity */
++ u32 sync_p_enbl :1; /* sync pedestal enable */
++ u32 blnk_p_enbl :1; /* blank pedestal enable */
++ u32 c_sync_enbl :1; /* composite sync enable */
++ u32 vref_sel :1; /* VREF select */
++ u32 mn_sns_enbl :1; /* monitor sense enable */
++ u32 ct_out_enbl :1; /* constant output enable */
++ /**/
++ u32 dac_out_lvl :8; /* monitor sense DAC output level */
++ /**/
++ u32 blue_dac_r :1; /* blue DAC sense result */
++ u32 green_dac_r :1; /* green DAC sense result */
++ u32 red_dac_r :1; /* red DAC sense result */
++ u32 reserved_1 :1;
++ u32 mon_col_sel :1; /* mono/color monitor select */
++ u32 reserved_2 :3;
++ } part;
++ u32 whole;
++};
++
++/* horizontal display 1 control */
++union gc02r {
++ struct {
++ u32 hd1t :12; /* horizontal display 1 total */
++ u32 reserved_1 :4;
++
++ u32 hd1e :12; /* horizontal display 1 end */
++ u32 reserved_2 :4;
++ } part;
++ u32 whole;
++};
++
++/* vertical display 1 control */
++union gc03r {
++ struct {
++ u32 vd1t :12; /* vertical display 1 total */
++ u32 reserved_1 :4;
++
++ u32 vd1e :12; /* vertical display 1 end */
++ u32 reserved_2 :4;
++ } part;
++ u32 whole;
++};
++
++/* horizontal sync 1 control */
++union gc04r {
++ struct {
++ u32 hs1s :12; /* horizontal sync 1 start */
++ u32 reserved_1 :4;
++
++ u32 hs1e :12; /* horizontal sync 1 end */
++ u32 reserved_2 :4;
++ } part;
++ u32 whole;
++};
++
++/* vertical sync 1 control */
++union gc05r {
++ struct {
++ u32 vs1s :12; /* vertical sync 1 start */
++ u32 reserved_1 :4;
++
++ u32 vs1e :12; /* vertical sync 1 end */
++ u32 reserved_2 :4;
++ } part;
++ u32 whole;
++};
++
++/* vertical display 1 count */
++union gc07r {
++ struct {
++ u32 vd_cnt :12; /* vertical display 1 count */
++ u32 reverved_1 :20;
++ } part;
++ u32 whole;
++};
++
++/* horizontal window 1 control */
++union gc08r {
++ struct {
++ u32 hw1s :12; /* horizontal window 1 start (HW1S) */
++ u32 reserved_1 :4;
++
++ u32 hw1w :12; /* horizontal window 1 width (HW1W) */
++ u32 w1ald :4; /* window 1 additional line data */
++ } part;
++ u32 whole;
++};
++
++/* vertical window 1 control */
++union gc09r {
++ struct {
++ u32 vw1s :12; /* vertical window 1 start */
++ u32 reserved_1 :4;
++ u32 vw1h :12; /* vertical window 1 height */
++ u32 reserved_2 :4;
++ } part;
++ u32 whole;
++};
++
++/* window 1 start address */
++union gc0cr {
++ struct {
++ u32 w1sa :21; /* window 1 start address */
++ u32 reserved_1 :11;
++ } part;
++ u32 whole;
++};
++
++/* window 1 stride */
++union gc0er {
++ struct {
++ s16 w1st; /* window 1 stride */
++ s16 aw1st; /* alternate window 1 stride */
++ } part;
++ u32 whole;
++};
++
++/* hardware cursor 1 position */
++union gc10r {
++ struct {
++ u32 hc1s :12; /* horizontal cursor 1 start */
++ u32 reserved_1 :4;
++ u32 vc1s :12; /* vertical cursor 1 start */
++ u32 reserved_2 :4;
++ } part;
++ u32 whole;
++};
++
++/* hardware cursor 1 start address and offset */
++union gc11r {
++ struct {
++ u32 hc1sa :11; /* hardware cursor 1 start address */
++ u32 reserved_1 :5;
++ u32 hc1o :6; /* horizontal cursor 1 offset */
++ u32 reserved_2 :2;
++ u32 vc1o :6; /* vertical cursor 1 offset */
++ u32 reserved_3 :2;
++ } part;
++ u32 whole;
++};
++
++/* hardware cursor 1 foreground color */
++union gc12r {
++ struct {
++ u32 hc1fc :24; /* hardware cursor 1 foreground color */
++ u32 reserved_1 :8;
++ } part;
++ u32 whole;
++};
++
++/* hardware cursor 1 background color */
++union gc13r {
++ struct {
++ u32 hc1bc :24; /* hardware cursor 1 background color */
++ u32 reserved_1 :8;
++ } part;
++ u32 whole;
++};
++
++
++/* graphics controller 2 register */
++union gc20r {
++ struct {
++ u32 ctl_enbl :1; /* Controller 2 Enable */
++ u32 hc_reset :1; /* Horizontal Counter 2 Reset */
++ u32 vc_reset :1; /* Vertical Counter 2 Reset */
++ u32 iwin_enbl :1; /* Image Window 2 Enable */
++ u32 gcd :4; /* Graphics Color Depth (GCD) */
++
++ u32 hc_enbl :1; /* Hardware Cursor 2 Enable */
++ u32 reserved_1 :2;
++ u32 aiwin_enbl :1; /* Alternate Image Window Enable */
++ u32 agcd :4; /* Alternate Graphics Color Depth (AGCD) */
++
++ u32 g2rclk_src :2; /* G2RCLK Source */
++ u32 tm0 :1; /* Test Mode 0 */
++ u32 tm1 :1; /* Test Mode 1 */
++ u32 fd :3; /* G2MCLK First Clock Divisor (FD1) */
++ u32 reserved_2 :1;
++
++ u32 sd :8; /* G2MCLK Second Clock Divisor (SD1) */
++ } part;
++ u32 whole;
++};
++
++/* graphics controller CRC control */
++union gc21r {
++ struct {
++ u32 crc_enbl :1; /* CRC enable */
++ u32 vsync_wait :1; /* CRC input data control waitime of VSYNC */
++ u32 crc_o_sel :2; /* CRC output select */
++ u32 reserved_1 :4;
++ u32 crc_result :22; /* CRC result (read only) */
++ u32 reserved_2 :2;
++ } part;
++ u32 whole;
++};
++
++/* horizontal display 2 control */
++union gc22r {
++ struct {
++ u32 hd2t :12; /* horizontal display 2 total */
++ u32 reserved_1 :4;
++
++ u32 hd2e :12; /* horizontal display 2 end */
++ u32 reserved_2 :4;
++ } part;
++ u32 whole;
++};
++
++/* vertical display 2 control */
++union gc23r {
++ struct {
++ u32 vd2t :12; /* vertical display 2 total */
++ u32 reserved_1 :4;
++
++ u32 vd2e :12; /* vertical display 2 end */
++ u32 reserved_2 :4;
++ } part;
++ u32 whole;
++};
++
++/* horizontal sync 2 control */
++union gc24r {
++ struct {
++ u32 hs2s :12; /* horizontal sync 2 start */
++ u32 reserved_1 :4;
++
++ u32 hs2e :12; /* horizontal sync 2 end */
++ u32 reserved_2 :4;
++ } part;
++ u32 whole;
++};
++
++/* vertical sync 2 control */
++union gc25r {
++ struct {
++ u32 vs2s :12; /* vertical sync 2 start */
++ u32 reserved_1 :4;
++
++ u32 vs2e :12; /* vertical sync 2 end */
++ u32 reserved_2 :4;
++ } part;
++ u32 whole;
++};
++
++/* vertical display 2 count */
++union gc27r {
++ struct {
++ u32 vd_cnt :12; /* vertical display 2 count */
++ u32 reverved_1 :20;
++ } part;
++ u32 whole;
++};
++
++/* horizontal window 2 control */
++union gc28r {
++ struct {
++ u32 hw2s :12; /* horizontal window 2 start (HW2S) */
++ u32 reserved_1 :4;
++
++ u32 hw2w :12; /* horizontal window 2 width (HW2W) */
++ u32 w2ald :4; /* window 2 additional line data */
++ } part;
++ u32 whole;
++};
++
++/* vertical window 2 control */
++union gc29r {
++ struct {
++ u32 vw2s :12; /* vertical window 2 start */
++ u32 reserved_1 :4;
++ u32 vw2h :12; /* vertical window 2 height */
++ u32 reserved_2 :4;
++ } part;
++ u32 whole;
++};
++
++/* window 2 start address */
++union gc2cr {
++ struct {
++ u32 w2sa :21; /* window 2 start address */
++ u32 reserved_1 :11;
++ } part;
++ u32 whole;
++};
++
++/* window 2 stride */
++union gc2er {
++ struct {
++ s16 w2st; /* window 2 stride */
++ s16 aw2st; /* alternate window 2 stride */
++ } part;
++ u32 whole;
++};
++
++/* hardware cursor 2 position */
++union gc30r {
++ struct {
++ u32 hc2s :12; /* horizontal cursor 2 start */
++ u32 reserved_1 :4;
++ u32 vc2s :12; /* vertical cursor 2 start */
++ u32 reserved_2 :4;
++ } part;
++ u32 whole;
++};
++
++/* hardware cursor 2 start address and offset */
++union gc31r {
++ struct {
++ u32 hc2sa :11; /* hardware cursor 2 start address */
++ u32 reserved_1 :5;
++ u32 hc2o :6; /* horizontal cursor 2 offset */
++ u32 reserved_2 :2;
++ u32 vc2o :6; /* vertical cursor 2 offset */
++ u32 reserved_3 :2;
++ } part;
++ u32 whole;
++};
++
++/* hardware cursor 2 foreground color */
++union gc32r {
++ struct {
++ u32 hc2fc :24; /* hardware cursor 2 foreground color */
++ u32 reserved_1 :8;
++ } part;
++ u32 whole;
++};
++
++/* hardware cursor 2 background color */
++union gc33r {
++ struct {
++ u32 hc2bc :24; /* hardware cursor 2 background color */
++ u32 reserved_1 :8;
++ } part;
++ u32 whole;
++};
++
++
++/* primary drawing command register */
++union ge00r {
++ struct {
++ u32 rop :8; /* raster operation */
++ /**/
++ u32 cmd_typ :3; /* command type */
++ u32 x_dir :1; /* x direction */
++ u32 y_dir :1; /* y direction */
++ u32 src_mem :1; /* source memory */
++ u32 mon_src :1; /* mono source */
++ u32 mon_ptn :1; /* mono pattern */
++ /**/
++ u32 dst_trns_e :1; /* destination transparency enable */
++ u32 dst_trns_p :1; /* destination transparency polarity */
++ u32 mon_trns_e :1; /* mono source or mono pattern transparency
++ enable */
++ u32 mon_trns_p :1; /* mono transparency polarity */
++ u32 mod_sel :1; /* memory to screen or off screen to screen
++ mode select */
++ u32 alpha_sel :2; /* Alpha byte mask selection */
++ u32 sol_col :1; /* solid color */
++ /**/
++ u32 stride_eq :1; /* source stride is equal to destination
++ stride */
++ u32 rop2_sel :1; /* ROP2 code selection */
++ u32 clipping :1; /* enable clipping */
++ u32 auto_exec :1; /* auto execute */
++ u32 reserved_1 :4;
++ } part;
++ u32 whole;
++};
++
++/* primary width and height register */
++union ge01r {
++ struct {
++ u32 width :12; /* source/destination window width */
++ u32 reserved_1 :4;
++
++ u32 height :12; /* source/destination window height */
++ u32 reserved_2 :1;
++ u32 reserved_3 :3;
++ } bitblt;
++ struct {
++ u32 dm :17;
++ u32 axis_major :12;
++ u32 x_y :1; /* x-major or y-major */
++ u32 last_pix :1; /* decision to draw or not to draw the last
++ pixel of the line */
++ u32 reserved_1 :1;
++ } bresenham;
++ u32 whole;
++};
++
++/* primary destination address register */
++union ge02r {
++ struct {
++ u32 dst_x :12; /* destination x position */
++ u32 reserved_1 :1;
++ u32 h_offset :3; /* mono/color pattern horizontal offset */
++
++ u32 dst_y :12; /* destination y position */
++ u32 reserved_2 :1;
++ u32 v_offset :3; /* mono/color pattern vertical offset */
++ } window;
++ struct {
++ u32 x :12; /* starting x coordinate */
++ u32 dm :17; /* 17 bits major-axis delta */
++ u32 reserved_1 :3;
++ } line;
++ u32 whole;
++};
++
++/* source XY register/line draw starting Y coordinate and mintor axis delta */
++union ge03r {
++ struct {
++ u32 src_x :12; /* source X position */
++ u32 reserved_1 :4;
++
++ u32 src_y :12; /* source Y position */
++ u32 reserved_2 :4;
++ } window;
++ struct {
++ u32 start_y :12; /* starting Y coordinate */
++ u32 dn :17; /* 17 bits minor-axis delta */
++ u32 reserved_1 :3;
++ } line;
++ u32 whole;
++};
++
++/* clip left/top register */
++union ge05r {
++ struct {
++ u32 left :12; /* left edge of clipping rectangle */
++ u32 reserved_1 :4;
++
++ u32 top :12; /* top edge of clipping rectangle */
++ u32 reserved_2 :4;
++ } part;
++ u32 whole;
++};
++
++/* source stride/offset register */
++union ge09r {
++ struct {
++ u32 src_strid :12; /* source line stride */
++ u32 reserved_1 :13;
++ u32 strt_bit :3; /* initial mono source bit offset */
++ u32 strt_byte :3; /* initial mono/color source byte offset */
++ u32 reserved_2 :1;
++ } line;
++ struct {
++ u32 strt_bit :5; /* initial mono source bit offset */
++ u32 reserved_1 :1;
++ u32 amount :10; /* number of 16 bytes amount that MIU need
++ to fetch from frame buffer */
++
++ u32 reserved_2 :9;
++ u32 bit_spc :7; /* bit space between lines */
++ } pack_mono;
++ struct {
++ u32 strt_bit :3; /* initial mono source bit offset */
++ u32 strt_byte :3; /* initial mono/color source byte offset */
++ u32 amount :10; /* number of 16 bytes amount that MIU need
++ to fetch from frame buffer */
++
++ u32 reserved_1 :9;
++ u32 bit_spc :3; /* bit space between lines */
++ u32 byt_spc :4; /* byte space between lines */
++ } pack_color;
++ u32 whole;
++};
++
++/* destination stride register and color depth */
++union ge0ar {
++ struct {
++ u32 dst_strid :12; /* destination line stride and color depth */
++ u32 reserved_1 :18;
++ u32 col_dpth :2; /* color depth */
++ } part;
++ u32 whole;
++};
++
++/* graphics controller color pallete */
++union c1xxr {
++ struct {
++ u8 red; /* red color pallete */
++ u8 green; /* green/gray color pallete */
++ u8 blue; /* blue color palette */
++ u8 reserved_1;
++ } part;
++ u32 whole;
++};
++
++/* devicee configuration register 0 */
++union dc00r {
++ struct {
++ u32 osc_bypass :1; /* oscillator bypass */
++ u32 osc_enbl :1; /* oscillator enable */
++ u32 pll1_bypass :1; /* PLL1 bypass */
++ u32 pll1_enbl :1; /* PLL1 enable */
++ u32 pll1_p_par :3; /* PLL1 P parameter */
++ u32 cpu_div :1; /* CPU interface clock divisor */
++ u32 pll1_n_par :5; /* PLL1 N parameter */
++ u32 saisc :1; /* StrongARM interface synchronizer control */
++ u32 s_chp_reset :1; /* software chip reset */
++ u32 mem_enbl :1; /* memory standby enable */
++ u32 pll1_m_par :8; /* PLL 1 M parameter */
++ u32 osc_shaper :1; /* oscillator shaper disable */
++ u32 fast_pwr :1; /* fast power sequencing */
++ u32 osc_frq :2; /* oscillator frequency select */
++ u32 pll1_trim :4; /* PLL 1 trim value */
++ } part;
++ u32 whole;
++};
++
++/* device ID/vendor ID register */
++union pc00r {
++ struct {
++ u16 device; /* device ID */
++ u16 vendor; /* vendor ID */
++ } part;
++ u32 whole;
++};
++
++/* Flat Panel Control Register */
++union fp00r {
++ struct {
++ u32 flatp_enbl : 2; /* Flat Panel Interface Enable */
++ u32 flatp_type : 2; /* Flat Panel Type */
++ u32 mono : 1; /* Mono/Color Panel Select */
++ u32 flatp_intf : 3; /* Flat Panel Interface */
++ u32 dither_pat : 2; /* Dither Pattern */
++ u32 reserved : 2; /* Reserved Must Be 0*/
++ u32 dither_col : 3; /* Dither Base Color */
++ u32 alt_win_ctl: 1; /* Alternate Window Control */
++ u32 frc_ctl : 2; /* FRC Control */
++ u32 dither_adj1: 6; /* Dither Pattern Adjust 1 */
++ u32 dither_adj2: 3; /* Dither Pattern Adjust 2 */
++ u32 dither_adj3: 1; /* Dither Pattern Adjust 3 */
++ u32 test_mode0 : 1; /* Test Mode 0 */
++ u32 test_mode1 : 1; /* Test Mode 1 */
++ u32 test_mode2 : 1; /* Test Mode 2 */
++ u32 test_mode3 : 1; /* Test Mode 3 */
++ } part;
++ u32 whole;
++};
++
++union fp01r {
++ struct {
++ u32 dummy;
++ } part;
++ u32 whole;
++};
++
++union fp02r {
++ struct {
++ u32 dummy;
++ } part;
++ u32 whole;
++};
++
++union fp03r {
++ struct {
++ u32 dummy;
++ } part;
++ u32 whole;
++};
++
++union fp04r {
++ struct {
++ u32 dummy;
++ } part;
++ u32 whole;
++};
++
++union fp05r {
++ struct {
++ u32 dummy;
++ } part;
++ u32 whole;
++};
++
++union fp0fr {
++ struct {
++ u32 dummy;
++ } part;
++ u32 whole;
++};
++
++
++
++
++/****
++ * Others
++ */
++
++#define CHIPNAME "MQ-200"
++
++extern void mq200_external_setpal(unsigned regno, unsigned long color, unsigned long addr);
++extern void mq200_external_setqmode(struct mq200_monitor_info*, unsigned long, spinlock_t *);
++extern void mq200_external_offdisplay(unsigned long);
++extern void mq200_external_ondisplay (unsigned long);
++extern int mq200_external_probe(unsigned long);
++
++
++
++#endif
+diff -Nur linux-2.6.24.vanilla/drivers/video/mq200/mq_external.c linux-2.6.24/drivers/video/mq200/mq_external.c
+--- linux-2.6.24.vanilla/drivers/video/mq200/mq_external.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24/drivers/video/mq200/mq_external.c 2008-02-20 21:51:22.000000000 +0100
+@@ -0,0 +1,513 @@
++/*
++ * Copyright (C) 2005 Holger Hans Peter Freyther
++ *
++ * Based ON:
++ *
++ * linux/drivers/video/mq200fb.c -- MQ-200 for a frame buffer device
++ * based on linux/driver/video/pm2fb.c
++ *
++ * 2007/03/11 mrdata:
++ * bug found in gc1_reset(), renaming to gc1_gc2_reset()
++ * extend mq200_external_ondisplay() -> LCD for GC2 and CRT for GC1
++ *
++ * Copyright (C) 2000 Lineo, Japan
++ *
++ * 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 <asm/types.h>
++#include <asm/io.h>
++#include <linux/delay.h>
++#include <linux/spinlock.h>
++
++#include <asm/hardware.h>
++
++#include "mq200_data.h"
++
++
++#if 1
++#define PRINTK(args...) printk(args)
++#else
++#define PRINTK(args...)
++#endif
++
++
++/****
++ * power state transition to "state".
++ */
++static void
++power_state_transition(unsigned long register_base, int state)
++{
++ int i;
++ writel(state, PMCSR(register_base));
++ mdelay(300);
++ for (i = 1; ; i++) {
++ udelay(100);
++ if ((readl(PMCSR(register_base)) & 0x3) == state) {
++ break;
++ }
++ }
++}
++
++
++/****
++ * device configuration initialization.
++ */
++static void
++dc_reset(unsigned long register_base)
++{
++ union dc00r dc00r;
++
++ /* Reset First */
++ dc00r.whole = DC_RESET;
++ writel(dc00r.whole, DC00R(register_base));
++ mdelay(100);
++
++ dc00r.whole = 0xEF2082A;
++ writel(dc00r.whole, DC00R(register_base));
++ mdelay(300);
++ PRINTK(CHIPNAME ": DC00R = 0x%08X\n", readl(DC00R(register_base)));
++}
++
++
++/****
++ * initialize memory interface unit.
++ */
++static void
++miu_reset(unsigned long register_base)
++{
++ union mm00r mm00r;
++ union mm01r mm01r;
++ union mm02r mm02r;
++ union mm03r mm03r;
++ union mm04r mm04r;
++
++ /* MIU interface control 1 */
++ mm00r.whole = 0x4;
++ writel(mm00r.whole, MM00R(register_base));
++ mdelay(50);
++ writel(0, MM00R(register_base));
++ mdelay(50);
++
++ /* MIU interface control 2
++ * o PLL 1 output is used as memory clock source.
++ */
++ mm01r.whole = 0x4143e086;
++ writel(mm01r.whole, MM01R(register_base));
++
++ /* memory interface control 3 */
++ mm02r.whole = 0x6d6aabff;
++ writel(mm02r.whole, MM02R(register_base));
++
++ /* memory interface control 5 */
++ mm04r.whole = 0x10d;
++ writel(mm04r.whole, MM04R(register_base));
++
++ /* memory interface control 4 */
++ mm03r.whole = 0x1;
++ writel(mm03r.whole, MM03R(register_base));
++ mdelay(50);
++
++ /* MIU interface control 1 */
++ mm00r.whole = 0x3;
++ writel(mm00r.whole, MM00R(register_base));
++ mdelay(50);
++}
++
++/****
++ *
++ */
++static
++void fpctrl_reset(unsigned long addr)
++{
++ /*
++ * We're in D0 State, let us set the FPCTRL
++ */
++ union fp00r fp00r;
++ union fp01r fp01r;
++ union fp02r fp02r;
++ union fp03r fp03r;
++ union fp04r fp04r;
++ union fp0fr fp0fr;
++
++ fp00r.whole = 0x6320;
++ writel(fp00r.whole, FP00R(addr));
++
++ fp01r.whole = 0x20;
++ writel(fp01r.whole, FP01R(addr));
++
++ fp04r.whole = 0xBD0001;
++ writel(fp04r.whole, FP04R(addr));
++
++ /* Set Flat Panel General Purpose register first */
++ fp02r.whole = 0x0;
++ writel(fp02r.whole, FP02R(addr));
++
++ fp03r.whole = 0x0;
++ writel(fp03r.whole, FP03R(addr));
++
++ fp0fr.whole = 0xA16c44;
++ writel(fp0fr.whole, FP0FR(addr));
++
++ /* Set them again */
++ fp02r.whole = 0x0;
++ writel(fp02r.whole, FP02R(addr));
++
++ fp03r.whole = 0x0;
++ writel(fp03r.whole, FP03R(addr));
++}
++
++
++/****
++ * initialize power management unit.
++ */
++static void
++pmu_reset(unsigned long register_base)
++{
++ union pm00r pm00r;
++ union pm01r pm01r;
++ union pm02r pm02r;
++
++ /* power management miscellaneous control
++ * o GE is driven by PLL 1 clock.
++ */
++ pm00r.whole = 0xc0900;
++ writel(pm00r.whole, PM00R(register_base));
++
++ /* D1 state control */
++ pm01r.whole = 0x5000271;
++ writel(pm01r.whole, PM01R(register_base));
++
++ /* D2 state control */
++ pm02r.whole = 0x271;
++ writel(pm02r.whole, PM02R(register_base));
++}
++
++/****
++ * initialize graphics controller 1
++ * and graphics controller 2
++ */
++static void
++gc1_gc2_reset(unsigned long register_base, spinlock_t *lock )
++{
++ unsigned long flags;
++ union gc00r gc00r;
++ union gc01r gc01r;
++ union gc02r gc02r;
++ union gc03r gc03r;
++ union gc04r gc04r;
++ union gc05r gc05r;
++ union gc08r gc08r;
++ union gc09r gc09r;
++ union gc0cr gc0cr;
++ union gc0er gc0er;
++ union gc20r gc20r;
++ union gc22r gc22r;
++ union gc23r gc23r;
++ union gc24r gc24r;
++ union gc25r gc25r;
++ union gc28r gc28r;
++ union gc29r gc29r;
++ union gc2cr gc2cr;
++ union gc2er gc2er;
++
++ union pm00r pm00r;
++ union pm06r pm06r;
++ union pm06r pm07r;
++
++ spin_lock_irqsave(lock, flags);
++
++ /* alternate window 1 stride */
++ gc0er.whole = 0x640;
++ writel(gc0er.whole, GC0ER(register_base));
++
++ /* image window 1 start address */
++ gc0cr.whole = 0x0;
++ writel(gc0cr.whole, GC0CR(register_base));
++
++ /* alternate window 2 stride */
++ gc2er.whole = 0x640;
++ writel(gc0er.whole, GC2ER(register_base));
++
++ /* image window 2 start address */
++ gc2cr.whole = 0x0;
++ writel(gc2cr.whole, GC2CR(register_base));
++
++ /* read PM Register */
++ pm00r.whole = readl(PM00R(register_base));
++
++ /* horizontal window 1 control */
++ gc08r.whole = 0x131f0000;
++ writel(gc08r.whole, GC08R(register_base));
++
++ /* vertical window 1 control */
++ gc09r.whole = 0x12570000;
++ writel(gc09r.whole, GC09R(register_base));
++
++ /* horizontal display 1 control */
++ gc02r.whole = 0x320041e;
++ writel(gc02r.whole, GC02R(register_base));
++
++ /* vertical display 1 control */
++ gc03r.whole = 0x2570273;
++ writel(gc03r.whole, GC03R(register_base));
++
++ /* horizontal sync 1 control */
++ gc04r.whole = 0x3c70347;
++ writel(gc04r.whole, GC04R(register_base));
++
++ /* vertical sync 1 control */
++ gc05r.whole = 0x25d0259;
++ writel(gc05r.whole, GC05R(register_base));
++
++ /* graphics controller CRT control */
++ gc01r.whole = 0x800;
++ writel(gc01r.whole, GC01R(register_base));
++
++ /* PLL 2 programming */
++ pm06r.whole = 0xE90830;
++ writel(pm06r.whole, PM06R(register_base));
++
++ /* graphics controller 1 register
++ * o GC1 clock source is PLL 2.
++ * o hardware cursor is disabled.
++ */
++ gc00r.whole = 0x10000C8 | 0x20000;
++ writel(gc00r.whole, GC00R(register_base));
++
++#if 0
++ /* alternate horizontal window 1 control */
++ writel(0, GC0AR(register_base));
++
++ /* alternate vertical window 1 control */
++ writel(0, GC0BR(register_base));
++
++ /* window 1 start address */
++ writel(0x2004100, GC0CR(register_base));
++
++ /* alternate window 1 start address */
++ writel(0, GC0DR(register_base));
++
++ /* window 1 stride */
++ gc0er.whole = 0x5100048;
++ writel(gc0er.whole, GC0ER(register_base));
++
++ /* reserved register - ??? - */
++ writel(0x31f, GC0FR(register_base));
++#endif
++
++#if 0
++ /* hardware cursor 1 position */
++ writel(0, GC10R(register_base));
++
++ /* hardware cursor 1 start address and offset */
++ gc11r.whole = 0x5100048;
++ writel(gc11r.whole, GC11R(register_base));
++
++ /* hardware cursor 1 foreground color */
++ writel(0x00ffffff, GC12R(register_base));
++
++ /* hardware cursor 1 background color */
++ writel(0x00000000, GC13R(register_base));
++#endif
++
++ /* horizontal window 2 control */
++ gc28r.whole = 0x31f0000;
++ writel(gc28r.whole, GC28R(register_base));
++
++ /* vertical window 2 control */
++ gc29r.whole = 0x2570000;
++ writel(gc29r.whole, GC29R(register_base));
++
++ /* horizontal display 2 control */
++ gc22r.whole = 0x320041e;
++ writel(gc22r.whole, GC22R(register_base));
++
++ /* vertical display 2 control */
++ gc23r.whole = 0x2570273;
++ writel(gc23r.whole, GC23R(register_base));
++
++ /* horizontal sync 2 control */
++ gc24r.whole = 0x3c70347;
++ writel(gc24r.whole, GC24R(register_base));
++
++ /* vertical sync 2 control */
++ gc25r.whole = 0x25d0259;
++ writel(gc25r.whole, GC25R(register_base));
++
++ /* graphics controller CRT control */
++ gc01r.whole = 0x800;
++ writel(gc01r.whole, GC01R(register_base));
++
++ /* PLL 3 programming */
++ pm07r.whole = 0xE90830;
++ writel(pm07r.whole, PM07R(register_base));
++
++ /* graphics controller 2 register
++ * o GC2 clock source is PLL 3.
++ * o hardware cursor is disabled.
++ */
++ gc20r.whole = 0x10000C8 | 0x30000;
++ writel(gc20r.whole, GC20R(register_base));
++
++ /*
++ * Enable PLL2 and PLL3 in the PM Register
++ */
++ pm00r.part.pll2_enbl = 0x1;
++ pm00r.part.pll3_enbl = 0x1;
++ writel(pm00r.whole, PM00R(register_base));
++
++ spin_unlock_irqrestore(lock, flags);
++}
++
++
++/****
++ * initialize graphics engine.
++ */
++static void
++ge_reset(unsigned long register_base)
++{
++ /* drawing command register */
++ writel(0, GE00R(register_base));
++
++ /* promary width and height register */
++ writel(0, GE01R(register_base));
++
++ /* primary destination address register */
++ writel(0, GE02R(register_base));
++
++ /* primary source XY register */
++ writel(0, GE03R(register_base));
++
++ /* primary color compare register */
++ writel(0, GE04R(register_base));
++
++ /* primary clip left/top register */
++ writel(0, GE05R(register_base));
++
++ /* primary clip right/bottom register */
++ writel(0, GE06R(register_base));
++
++ /* primary source and pattern offset register */
++ writel(0, GE07R(register_base));
++
++ /* primary foreground color register/rectangle fill color depth */
++ writel(0, GE08R(register_base));
++
++ /* source stride/offset register */
++ writel(0, GE09R(register_base));
++
++ /* destination stride register and color depth */
++ writel(0, GE0AR(register_base));
++
++ /* image base address register */
++ writel(0, GE0BR(register_base));
++}
++
++/****
++ * initialize Color Palette 1.
++ */
++static void
++cp1_reset(unsigned long addr_info)
++{
++ int i;
++
++ for (i = 0; i < 256; i++)
++ writel(0, C1xxR(addr_info, i));
++}
++
++
++/*
++ * Below functions are called from the skeleton
++ */
++void mq200_external_setpal(unsigned regno, unsigned long color, unsigned long addr)
++{
++ writel(color,C1xxR(addr,regno));
++}
++
++void mq200_external_setqmode(struct mq200_monitor_info* info,
++ unsigned long addr, spinlock_t *lock)
++{
++ dc_reset(addr); /* device configuration */
++
++ power_state_transition(addr, 0); /* transition to D0 state */
++
++ pmu_reset(addr); /* power management unit */
++
++ miu_reset(addr); /* memory interface unit */
++
++ ge_reset(addr); /* graphics engine */
++
++ fpctrl_reset(addr); /* reset the panel settings */
++
++ gc1_gc2_reset(addr, lock); /* graphics controller 1 and 2 */
++
++ cp1_reset(addr); /* color palette 1 */
++
++ mq200_external_ondisplay(addr); /* LCD and CRT */
++}
++
++void mq200_external_offdisplay(unsigned long addr)
++{
++ /*
++ * Move the MQ200 to D3 mode
++ */
++ power_state_transition(addr, 3);
++}
++
++/**
++ * to be called after mq200_external_setqmode
++ */
++void mq200_external_ondisplay (unsigned long addr)
++{
++ /*
++ * Set the framebuffer details
++ */
++ union gc00r gc00r;
++ union gc01r gc01r;
++ union gc20r gc20r;
++ union fp00r fp00r;
++
++ /* enable LCD for GC2 */
++ fp00r.whole = readl(FP00R(addr));
++ fp00r.whole &= 0xfffffffc;
++
++ gc20r.whole = readl(GC20R(addr));
++
++ if(!(gc20r.whole & 0x1)) {
++ gc20r.whole |= 0x1;
++ writel(gc20r.whole, GC20R(addr));
++ }
++
++ fp00r.whole |= 0x3;
++ writel(fp00r.whole, FP00R(addr));
++
++ /* enable CRT for GC1 */
++ gc00r.whole = readl(GC00R(addr));
++
++ if(!(gc00r.whole & 0x1)) {
++ gc00r.whole |= 0x1;
++ writel(gc00r.whole, GC00R(addr));
++ }
++
++ gc01r.whole = readl(GC01R(addr));
++ gc01r.whole &= 0xfffffffc;
++
++ gc01r.whole |= 0x1;
++ writel(gc01r.whole, GC01R(addr));
++
++}
++
++int mq200_external_probe(unsigned long addr)
++{
++ union pc00r pc00r;
++ if(readl(PMR(addr)) != PMR_VALUE)
++ return 0;
++
++ pc00r.whole = readl(PC00R(addr));
++ printk(KERN_INFO "mq200 video driver found Vendor: 0x%X Device: 0x%X\n",
++ pc00r.part.device, pc00r.part.vendor);
++ return 1;
++}
+diff -Nur linux-2.6.24.vanilla/drivers/video/mq200/mq_skeleton.c linux-2.6.24/drivers/video/mq200/mq_skeleton.c
+--- linux-2.6.24.vanilla/drivers/video/mq200/mq_skeleton.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24/drivers/video/mq200/mq_skeleton.c 2008-02-20 21:51:22.000000000 +0100
+@@ -0,0 +1,398 @@
++/*
++ * Author: Holger Hans Peter Freyther
++ *
++ *
++ * This implements the frame buffer driver interface to communicate
++ * with the kernel.
++ * It uses the mq200 routines from the ucLinux driver from Lineo
++ *
++ * 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/autoconf.h>
++#include <linux/platform_device.h>
++#include <linux/module.h>
++#include <linux/fb.h>
++#include <linux/types.h>
++#include <linux/spinlock.h>
++
++#include "mq200_data.h"
++
++#if CONFIG_SA1100_SIMPAD
++/*
++ * Siemens SIMpad specefic data
++ */
++#include <asm/arch/simpad.h>
++#include <asm/arch/hardware.h>
++
++#define MQ200_REGIONS simpad_mq200_regions
++#define MQ200_MONITOR simpad_mq200_panel
++
++static struct mq200_io_regions simpad_mq200_regions = {
++ .fb_size = MQ200_FB_SIZE,
++ .phys_mmio_base = 0x4be00000,
++ .virt_mmio_base = 0xf2e00000,
++ .phys_fb_base = 0x4b800000,
++ .virt_fb_base = 0xf2800000,
++};
++
++static struct mq200_monitor_info simpad_mq200_panel = {
++ .horizontal_res = 800,
++ .vertical_res = 600,
++ .depth = 16,
++ .refresh = 60,
++ .line_length = 1600,
++ .flags = 0x00130004,
++};
++
++extern long get_cs3_shadow(void);
++extern void set_cs3_bit(int value);
++extern void clear_cs3_bit(int value);
++#endif
++
++
++
++struct mq200_info {
++ struct fb_info fb_info;
++ struct mq200_io_regions io_regions;
++ struct mq200_monitor_info monitor_info;
++
++ /* palette */
++ u32 pseudo_palette[17]; /* 16 colors + 1 in reserve not that well documented... */
++ spinlock_t lock;
++};
++
++
++
++static int mq200_blank( int blank_mode, struct fb_info *info )
++{
++#ifdef CONFIG_SA1100_SIMPAD
++ if(blank_mode ){
++ clear_cs3_bit(DISPLAY_ON);
++ }else {
++ set_cs3_bit(DISPLAY_ON);
++ }
++#endif
++ return 0;
++}
++
++
++static int mq200_check_var(struct fb_var_screeninfo *var,
++ struct fb_info *info )
++{ /* TODO do we need sanity checks here */
++ return 0;
++}
++
++
++static int mq200_set_par( struct fb_info *info )
++{
++ /* TODO set paraemeter */
++ return 0;
++}
++
++static int mq200_setcolreg(unsigned regno, unsigned red, unsigned green,
++ unsigned blue, unsigned transp,
++ struct fb_info *info )
++{
++ struct mq200_info *p;
++ unsigned long color;
++ u32* pal = info->pseudo_palette;
++
++ p = info->par;
++
++ if(regno > 255 )
++ return 1;
++
++ switch( info->var.bits_per_pixel ){
++ case 16:
++ pal[regno] =
++ ((red & 0xf800) >> 0) |
++ ((green & 0xf800) >> 5) | ((blue & 0xf800) >> 11);
++ break;
++ case 24:
++ pal[regno] =
++ ((red & 0xff00) << 8) |
++ ((green & 0xff00)) | ((blue & 0xff00) >> 8);
++ break;
++ case 32:
++ pal[regno] =
++ ((red & 0xff00) >> 8) |
++ ((green & 0xff00)) | ((blue & 0xff00) << 8);
++ break;
++ default:
++ break;
++ }
++
++ red &= 0xFF;
++ green &= 0xFF;
++ blue &= 0xFF;
++
++ color = red | (green << 8) | (blue << 16);
++ mq200_external_setpal(regno, color, p->io_regions.virt_mmio_base);
++
++ return 0;
++}
++
++
++static struct fb_ops mq200_ops = {
++ .owner = THIS_MODULE,
++ .fb_check_var = mq200_check_var,
++ .fb_set_par = mq200_set_par,
++ .fb_setcolreg = mq200_setcolreg,
++#ifdef FB_SOFT_CURSOR
++ .fb_cursor = soft_cursor, /* FIXME use hardware cursor */
++#endif
++ .fb_fillrect = cfb_fillrect,
++ .fb_copyarea = cfb_copyarea,
++ .fb_imageblit = cfb_imageblit,
++ .fb_blank = mq200_blank,
++};
++
++
++/*********************************************************************
++ *
++ * Device driver and module init code
++ * this will register to the fb layer later
++ *
++ *********************************************************************/
++static void mq200_internal_init_color( struct fb_bitfield* red,
++ struct fb_bitfield* green,
++ struct fb_bitfield* blue,
++ int bpp )
++{
++ switch ( bpp )
++ {
++ case 16:
++ red->offset = 11;
++ green->offset = 5;
++ blue->offset = 0;
++
++ red->length = 5;
++ green->length = 6;
++ blue->length = 5;
++ break;
++ case 24:
++ red->offset = 16;
++ green->offset = 8;
++ blue->offset = 0;
++
++ red->length = 8;
++ green->length = 8;
++ blue->length = 8;
++ break;
++ case 32:
++ red->offset = 0;
++ green->offset = 8;
++ blue->offset = 16;
++
++ red->length = 8;
++ green->length = 8;
++ blue->length = 8;
++ case 8: /* fall through */
++ default:
++ red->offset = green->offset = blue->offset = 0;
++ red->length = green->length = blue->length = bpp;
++ break;
++ }
++
++}
++
++
++static struct mq200_info* __init mq200_internal_init_fbinfo(void)
++{
++ struct mq200_info *info = NULL;
++
++ info = (struct mq200_info*)kmalloc(sizeof(*info), GFP_KERNEL);
++ if(!info)
++ return NULL;
++
++ /*
++ * Initialize memory
++ */
++ memset(info, 0, sizeof(struct mq200_info) );
++ spin_lock_init(&info->lock);
++
++ /* set the base IO addresses */
++ info->io_regions = MQ200_REGIONS;
++ info->monitor_info = MQ200_MONITOR;
++
++ info->fb_info.screen_base = (char *)info->io_regions.virt_fb_base;
++
++ /* fb_fix_screeninfo filling */
++ strcpy(info->fb_info.fix.id, "MQ200_FB" );
++ info->fb_info.fix.smem_start = info->io_regions.phys_fb_base;
++ info->fb_info.fix.smem_len = info->io_regions.fb_size; /* - CURSOR_IMAGE */
++ info->fb_info.fix.mmio_start = info->io_regions.phys_mmio_base;
++ info->fb_info.fix.mmio_len = MQ200_REGS_SIZE;
++ info->fb_info.fix.type = FB_TYPE_PACKED_PIXELS;
++ info->fb_info.fix.accel = FB_ACCEL_NONE;
++ info->fb_info.fix.line_length = MQ200_MONITOR_LINE_LENGTH(info);
++
++ if(MQ200_MONITOR_DEPTH(info) <= 8 )
++ info->fb_info.fix.visual = FB_VISUAL_PSEUDOCOLOR;
++ else if( MQ200_MONITOR_DEPTH(info) >= 16 )
++ info->fb_info.fix.visual = FB_VISUAL_DIRECTCOLOR;
++ else
++ panic("Calling mq200 with wrong display data\n");
++
++ /* set the variable screen info */
++ info->fb_info.var.xres = MQ200_MONITOR_HORI_RES(info);
++ info->fb_info.var.yres = MQ200_MONITOR_VERT_RES(info);
++ info->fb_info.var.xres_virtual = MQ200_MONITOR_HORI_RES(info);
++ info->fb_info.var.yres_virtual = MQ200_MONITOR_VERT_RES(info);
++ info->fb_info.var.bits_per_pixel = MQ200_MONITOR_DEPTH(info);
++
++ mq200_internal_init_color(&info->fb_info.var.red,
++ &info->fb_info.var.green,
++ &info->fb_info.var.blue,
++ MQ200_MONITOR_DEPTH(info) );
++
++ info->fb_info.var.transp.length = info->fb_info.var.transp.offset = 0;
++ info->fb_info.var.height = info->fb_info.var.width = -1;
++
++ info->fb_info.var.vmode = FB_VMODE_NONINTERLACED;
++ info->fb_info.var.pixclock = 10000;
++ info->fb_info.var.left_margin = info->fb_info.var.right_margin = 16;
++ info->fb_info.var.upper_margin = info->fb_info.var.lower_margin = 16;
++ info->fb_info.var.hsync_len = info->fb_info.var.vsync_len = 8;
++
++ info->fb_info.var.nonstd = 0;
++ info->fb_info.var.activate = FB_ACTIVATE_NOW;
++ info->fb_info.var.accel_flags = 0;
++
++ return info;
++}
++
++
++extern void mq200_register_attributes(struct device* );
++/*
++ * gets called from the bus
++ * we will register our framebuffer from here
++ */
++static int __init mq200_probe(struct device *dev)
++{
++ struct mq200_info *info = NULL;
++ int retv= 0;
++
++ info = mq200_internal_init_fbinfo();
++ if(!mq200_external_probe(info->io_regions.virt_mmio_base))
++ goto error_out;
++
++ GPDR |= (1<<3);
++ GAFR &= ~(1<<3);
++ GPSR |= (1<<3);
++
++ mq200_external_setqmode(&info->monitor_info,
++ info->io_regions.virt_mmio_base,
++ &info->lock);
++
++ info->fb_info.fbops = &mq200_ops;
++ info->fb_info.flags = FBINFO_FLAG_DEFAULT;
++
++ mq200_check_var(&info->fb_info.var, &info->fb_info );
++
++ fb_alloc_cmap(&info->fb_info.cmap, 1 << MQ200_MONITOR_DEPTH(info), 0 );
++
++ info->fb_info.pseudo_palette = (void*)info->pseudo_palette;
++
++ /* save the pointer to the mq200 struct in var */
++ info->fb_info.par = info;
++
++ retv = register_framebuffer(&info->fb_info );
++ if(retv < 0)
++ goto error_out;
++
++
++ /* will get unset if retv != 0 */
++ dev_set_drvdata(dev, info );
++ return retv;
++
++/*
++ * Free the info and exit
++ */
++error_out:
++ kfree(info);
++ return -EINVAL;
++}
++
++#ifdef CONFIG_PM
++static struct mq200_info* get_mq200_info( struct device *dev)
++{
++ return dev_get_drvdata(dev);
++}
++
++static unsigned long get_mmio_base( struct device *dev )
++{
++ struct mq200_info *info = get_mq200_info(dev);
++ return info->io_regions.virt_mmio_base;
++}
++
++static struct mq200_monitor_info* get_monitor_info( struct device *dev)
++{
++ struct mq200_info *info = get_mq200_info(dev);
++ return &info->monitor_info;
++}
++
++static spinlock_t* get_spinlock( struct device *dev)
++{
++ return &get_mq200_info(dev)->lock;
++}
++
++/*
++ * FIXME: make sure we only call mq200_external_offdisplay only once
++ * a 2nd time will hang the kernel -zecke
++ *
++ * FIXME: save the content of the framebuffer inside dev->saved_state
++ * so on resume we can memcpy it back into the buffer and userspace
++ * does not need to redraw
++ *
++ * functions for suspending and resuming
++ */
++static int mq200_suspend(struct device *dev, pm_message_t state)
++{
++
++ mq200_external_offdisplay( get_mmio_base(dev) );
++ clear_cs3_bit(DISPLAY_ON);
++
++
++ return 0;
++}
++
++static int mq200_resume(struct device *dev)
++{
++ unsigned long mem = get_mmio_base(dev);
++ struct mq200_monitor_info *monitor = get_monitor_info(dev);
++ mq200_external_setqmode(monitor, mem, get_spinlock(dev) );
++
++
++ /*
++ * Set display on if it was on
++ */
++ set_cs3_bit(DISPLAY_ON);
++
++ return 0;
++}
++
++
++#endif
++
++
++static struct device_driver mq200fb_driver = {
++ .name = "simpad-mq200",
++ .bus = &platform_bus_type,
++ .probe = mq200_probe, /* will be called after we've registered the driver */
++ .suspend = mq200_suspend,
++ .resume = mq200_resume
++};
++
++int __devinit mq200_init(void)
++{
++ return driver_register(&mq200fb_driver);
++}
++
++module_init(mq200_init);
++MODULE_DESCRIPTION("MQ200 framebuffer driver");
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Holger Hans Peter Freyther");
diff --git a/recipes/linux/linux/simpad/linux-2.6.24-SIMpad-orinoco_cs-shared-irq.patch b/recipes/linux/linux/simpad/linux-2.6.24-SIMpad-orinoco_cs-shared-irq.patch
new file mode 100644
index 0000000000..2568093020
--- /dev/null
+++ b/recipes/linux/linux/simpad/linux-2.6.24-SIMpad-orinoco_cs-shared-irq.patch
@@ -0,0 +1,21 @@
+diff -Nur linux-2.6.24.vanilla/drivers/net/wireless/orinoco_cs.c linux-2.6.24/drivers/net/wireless/orinoco_cs.c
+--- linux-2.6.24.vanilla/drivers/net/wireless/orinoco_cs.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24/drivers/net/wireless/orinoco_cs.c 2008-02-22 21:23:51.000000000 +0100
+@@ -8,6 +8,8 @@
+ * cards such as the 3Com AirConnect and Ericsson WLAN.
+ *
+ * Copyright notice & release notes in file orinoco.c
++ *
++ * mrdata: added shared irq
+ */
+
+ #define DRIVER_NAME "orinoco_cs"
+@@ -120,7 +122,7 @@
+ link->priv = dev;
+
+ /* Interrupt setup */
+- link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
++ link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_FIRST_SHARED | IRQ_HANDLE_PRESENT;
+ link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+ link->irq.Handler = orinoco_interrupt;
+ link->irq.Instance = dev;
diff --git a/recipes/linux/linux/simpad/linux-2.6.24-SIMpad-pcmcia.patch b/recipes/linux/linux/simpad/linux-2.6.24-SIMpad-pcmcia.patch
new file mode 100644
index 0000000000..5560d67494
--- /dev/null
+++ b/recipes/linux/linux/simpad/linux-2.6.24-SIMpad-pcmcia.patch
@@ -0,0 +1,209 @@
+diff -Nur linux-2.6.24.vanilla/drivers/pcmcia/cs.c linux-2.6.24/drivers/pcmcia/cs.c
+--- linux-2.6.24.vanilla/drivers/pcmcia/cs.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24/drivers/pcmcia/cs.c 2008-02-22 20:53:06.000000000 +0100
+@@ -10,6 +10,8 @@
+ * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
+ *
+ * (C) 1999 David A. Hinds
++ *
++ * mrdata: -added suspend fix
+ */
+
+ #include <linux/module.h>
+@@ -59,6 +61,10 @@
+ INT_MODULE_PARM(unreset_delay, 10); /* centiseconds */
+ INT_MODULE_PARM(unreset_check, 10); /* centiseconds */
+ INT_MODULE_PARM(unreset_limit, 30); /* unreset_check's */
++// INT_MODULE_PARM(unreset_delay, 20); /* centiseconds */
++// INT_MODULE_PARM(unreset_check, 100); /* centiseconds */
++// INT_MODULE_PARM(unreset_limit, 300); /* unreset_check's */
++
+
+ /* Access speed for attribute memory windows */
+ INT_MODULE_PARM(cis_speed, 300); /* ns */
+@@ -366,6 +372,7 @@
+ skt->ops->set_socket(skt, &skt->socket);
+
+ msleep(unreset_delay * 10);
++
+ for (i = 0; i < unreset_limit; i++) {
+ skt->ops->get_status(skt, &status);
+
+@@ -434,7 +441,7 @@
+
+ msleep(initial_delay * 10);
+
+- for (i = 0; i < 100; i++) {
++ for (i = 0; i < 100; i++) {
+ skt->ops->get_status(skt, &status);
+ if (!(status & SS_DETECT))
+ return CS_NO_CARD;
+diff -Nur linux-2.6.24.vanilla/drivers/pcmcia/sa1100_generic.c linux-2.6.24/drivers/pcmcia/sa1100_generic.c
+--- linux-2.6.24.vanilla/drivers/pcmcia/sa1100_generic.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24/drivers/pcmcia/sa1100_generic.c 2008-02-22 20:53:06.000000000 +0100
+@@ -28,6 +28,9 @@
+ the provisions above, a recipient may use your version of this
+ file under either the MPL or the GPL.
+
++ 2007 mrnice: added thesings changes from device_driver
++ to platform_driver - many thx to thesing
++
+ ======================================================================*/
+
+ #include <linux/module.h>
+@@ -81,13 +84,15 @@
+ return ret;
+ }
+
+-static struct device_driver sa11x0_pcmcia_driver = {
+- .probe = sa11x0_drv_pcmcia_probe,
+- .remove = soc_common_drv_pcmcia_remove,
+- .name = "sa11x0-pcmcia",
+- .bus = &platform_bus_type,
+- .suspend = pcmcia_socket_dev_suspend,
+- .resume = pcmcia_socket_dev_resume,
++static struct platform_driver sa11x0_pcmcia_driver = {
++ .driver = {
++ .name = "sa11x0-pcmcia",
++ .probe = sa11x0_drv_pcmcia_probe,
++ .remove = soc_common_drv_pcmcia_remove,
++ .suspend= pcmcia_socket_dev_suspend,
++ .resume = pcmcia_socket_dev_resume,
++ //.bus = &platform_bus_type,
++ },
+ };
+
+ /* sa11x0_pcmcia_init()
+@@ -100,7 +105,7 @@
+ */
+ static int __init sa11x0_pcmcia_init(void)
+ {
+- return driver_register(&sa11x0_pcmcia_driver);
++ return platform_driver_register(&sa11x0_pcmcia_driver);
+ }
+
+ /* sa11x0_pcmcia_exit()
+@@ -110,7 +115,7 @@
+ */
+ static void __exit sa11x0_pcmcia_exit(void)
+ {
+- driver_unregister(&sa11x0_pcmcia_driver);
++ platform_driver_unregister(&sa11x0_pcmcia_driver);
+ }
+
+ MODULE_AUTHOR("John Dorsey <john+@cs.cmu.edu>");
+diff -Nur linux-2.6.24.vanilla/drivers/pcmcia/sa1100_simpad.c linux-2.6.24/drivers/pcmcia/sa1100_simpad.c
+--- linux-2.6.24.vanilla/drivers/pcmcia/sa1100_simpad.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24/drivers/pcmcia/sa1100_simpad.c 2008-02-22 20:53:32.000000000 +0100
+@@ -8,13 +8,15 @@
+ #include <linux/kernel.h>
+ #include <linux/device.h>
+ #include <linux/init.h>
++#include <linux/delay.h>
+
+ #include <asm/hardware.h>
+ #include <asm/mach-types.h>
+ #include <asm/irq.h>
+ #include <asm/arch/simpad.h>
+ #include "sa1100_generic.h"
+-
++
++extern long get_cs3_ro(void);
+ extern long get_cs3_shadow(void);
+ extern void set_cs3_bit(int value);
+ extern void clear_cs3_bit(int value);
+@@ -25,8 +27,15 @@
+
+ static int simpad_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
+ {
+-
+- clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1);
++ clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1|PCMCIA_RESET);
++
++ set_cs3_bit(PCMCIA_BUFF_DIS);
++
++ msleep(10);
++
++ clear_cs3_bit(PCMCIA_BUFF_DIS);
++
++ msleep(5);
+
+ skt->irq = IRQ_GPIO_CF_IRQ;
+
+@@ -38,7 +47,7 @@
+ soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
+
+ /* Disable CF bus: */
+- //set_cs3_bit(PCMCIA_BUFF_DIS);
++ set_cs3_bit(PCMCIA_BUFF_DIS);
+ clear_cs3_bit(PCMCIA_RESET);
+ }
+
+@@ -47,21 +56,17 @@
+ struct pcmcia_state *state)
+ {
+ unsigned long levels = GPLR;
+- long cs3reg = get_cs3_shadow();
+-
+- state->detect=((levels & GPIO_CF_CD)==0)?1:0;
+- state->ready=(levels & GPIO_CF_IRQ)?1:0;
+- state->bvd1=1; /* Not available on Simpad. */
+- state->bvd2=1; /* Not available on Simpad. */
+- state->wrprot=0; /* Not available on Simpad. */
+-
+- if((cs3reg & 0x0c) == 0x0c) {
+- state->vs_3v=0;
+- state->vs_Xv=0;
+- } else {
+- state->vs_3v=1;
+- state->vs_Xv=0;
+- }
++
++ state->detect = ((levels & GPIO_CF_CD) == 0) ? 1 : 0 ;
++ state->ready = (levels & GPIO_CF_IRQ) ? 1 : 0 ;
++
++ long cs3_ro_reg = get_cs3_ro();
++
++ state->bvd1 = (cs3_ro_reg & PCMCIA_BVD1) ? 1 : 0 ; /* old: =1 Not available on Simpad. */
++ state->bvd2 = (cs3_ro_reg & PCMCIA_BVD2) ? 1 : 0 ; /* old: =1 Not available on Simpad. */
++ state->wrprot = 0 ; /* Not available on Simpad. */
++ state->vs_3v = (cs3_ro_reg & PCMCIA_VS1) ? 0 : 1 ;
++ state->vs_Xv = (cs3_ro_reg & PCMCIA_VS2) ? 0 : 1 ;
+ }
+
+ static int
+@@ -95,7 +100,11 @@
+ local_irq_restore(flags);
+ return -1;
+ }
+-
++
++ if (state->flags & SS_RESET)
++ set_cs3_bit(PCMCIA_RESET);
++ else
++ clear_cs3_bit(PCMCIA_RESET);
+
+ local_irq_restore(flags);
+
+@@ -104,6 +113,7 @@
+
+ static void simpad_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
+ {
++ clear_cs3_bit(PCMCIA_RESET);
+ soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
+ }
+
+diff -Nur linux-2.6.24.vanilla/drivers/pcmcia/soc_common.c linux-2.6.24/drivers/pcmcia/soc_common.c
+--- linux-2.6.24.vanilla/drivers/pcmcia/soc_common.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24/drivers/pcmcia/soc_common.c 2008-02-22 20:53:06.000000000 +0100
+@@ -747,7 +747,9 @@
+
+ add_timer(&skt->poll_timer);
+
+- device_create_file(&skt->socket.dev, &dev_attr_status);
++ ret = device_create_file(&skt->socket.dev, &dev_attr_status);
++ if (ret)
++ goto out_err_7;
+ }
+
+ dev_set_drvdata(dev, sinfo);
diff --git a/recipes/linux/linux/simpad/linux-2.6.24-SIMpad-rtc-sa1100.patch b/recipes/linux/linux/simpad/linux-2.6.24-SIMpad-rtc-sa1100.patch
new file mode 100644
index 0000000000..407fd89a26
--- /dev/null
+++ b/recipes/linux/linux/simpad/linux-2.6.24-SIMpad-rtc-sa1100.patch
@@ -0,0 +1,68 @@
+diff -Nur linux-2.6.24.vanilla/drivers/rtc/rtc-sa1100.c linux-2.6.24_rtc/drivers/rtc/rtc-sa1100.c
+--- linux-2.6.24.vanilla/drivers/rtc/rtc-sa1100.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24_rtc/drivers/rtc/rtc-sa1100.c 2008-03-24 13:49:40.000000000 +0100
+@@ -79,7 +79,10 @@
+
+ rtsr = RTSR;
+ /* clear interrupt sources */
+- RTSR = 0;
++ RTSR &= ~RTSR_HZE; //RTSR = 0; is not possible and does not work
++ RTSR &= ~RTSR_HZ;
++ RTSR &= ~RTSR_ALE;
++ RTSR &= ~RTSR_AL;
+ RTSR = (RTSR_AL | RTSR_HZ) & (rtsr >> 2);
+
+ /* clear alarm interrupt if it has occurred */
+@@ -155,6 +158,20 @@
+ {
+ int ret;
+
++ /*
++ * On some devices RTSR is set to some value but it must be set to 0.
++ * We have to set RTSR to 0 and OIER/OSSR to default. This should not be
++ * necessary here but it is.
++ */
++ spin_lock_irq(&sa1100_rtc_lock);
++ RTSR &= ~RTSR_HZE;
++ RTSR &= ~RTSR_HZ;
++ RTSR &= ~RTSR_ALE;
++ RTSR &= ~RTSR_AL;
++ OIER &= ~OIER_E1;
++ OSSR = OSSR_M1;
++ spin_unlock_irq(&sa1100_rtc_lock);
++
+ ret = request_irq(IRQ_RTC1Hz, sa1100_rtc_interrupt, IRQF_DISABLED,
+ "rtc 1Hz", dev);
+ if (ret) {
+@@ -186,7 +203,10 @@
+ static void sa1100_rtc_release(struct device *dev)
+ {
+ spin_lock_irq(&sa1100_rtc_lock);
+- RTSR = 0;
++ RTSR &= ~RTSR_HZE; //RTSR = 0; is not possible and does not work
++ RTSR &= ~RTSR_HZ;
++ RTSR &= ~RTSR_ALE;
++ RTSR &= ~RTSR_AL;
+ OIER &= ~OIER_E1;
+ OSSR = OSSR_M1;
+ spin_unlock_irq(&sa1100_rtc_lock);
+@@ -339,6 +359,19 @@
+
+ platform_set_drvdata(pdev, rtc);
+
++ /*
++ * On some devices RTSR is set to some value but it must be set to 0.
++ * We have to set RTSR to 0 and OIER/OSSR to default.
++ */
++ spin_lock_irq(&sa1100_rtc_lock);
++ RTSR &= ~RTSR_HZE;
++ RTSR &= ~RTSR_HZ;
++ RTSR &= ~RTSR_ALE;
++ RTSR &= ~RTSR_AL;
++ OIER &= ~OIER_E1;
++ OSSR = OSSR_M1;
++ spin_unlock_irq(&sa1100_rtc_lock);
++
+ return 0;
+ }
+
diff --git a/recipes/linux/linux/simpad/linux-2.6.24-SIMpad-serial-gpio_keys-and-cs3-ro.patch.v2 b/recipes/linux/linux/simpad/linux-2.6.24-SIMpad-serial-gpio_keys-and-cs3-ro.patch.v2
new file mode 100644
index 0000000000..e47d99288f
--- /dev/null
+++ b/recipes/linux/linux/simpad/linux-2.6.24-SIMpad-serial-gpio_keys-and-cs3-ro.patch.v2
@@ -0,0 +1,358 @@
+diff -Nur linux-2.6.24.vanilla/arch/arm/mach-sa1100/simpad.c linux-2.6.24/arch/arm/mach-sa1100/simpad.c
+--- linux-2.6.24.vanilla/arch/arm/mach-sa1100/simpad.c 2008-10-04 21:47:24.000000000 +0200
++++ linux-2.6.24/arch/arm/mach-sa1100/simpad.c 2008-10-04 22:01:20.000000000 +0200
+@@ -1,5 +1,15 @@
+ /*
+ * linux/arch/arm/mach-sa1100/simpad.c
++ *
++ * 2007/04/11 mrdata:
++ * - insert simpad_uart_set_mctrl()
++ * simpad_uart_get_mctrl()
++ * - internal RS232/DECT/Bluetooth
++ * works again (based on 2.4 simpad-serial.patch)
++ * - added cs3_ro
++ *
++ * 2007/04/12 Bernhard Guillon:
++ * -added gpio_keys (based on h3000.c from hh.org)
+ */
+
+ #include <linux/module.h>
+@@ -9,6 +19,9 @@
+ #include <linux/proc_fs.h>
+ #include <linux/string.h>
+ #include <linux/pm.h>
++
++#include <linux/apm-emulation.h>
++
+ #include <linux/platform_device.h>
+ #include <linux/mtd/mtd.h>
+ #include <linux/mtd/partitions.h>
+@@ -27,12 +40,21 @@
+
+ #include <linux/serial_core.h>
+ #include <linux/ioport.h>
++#include <linux/input.h>
++#include <linux/gpio_keys.h>
+ #include <asm/io.h>
+
+ #include "generic.h"
+
++long cs3_ro;
+ long cs3_shadow;
+
++long get_cs3_ro(void)
++{
++ cs3_ro = *(CS3BUSTYPE *)(CS3_BASE);
++ return cs3_ro;
++}
++
+ long get_cs3_shadow(void)
+ {
+ return cs3_shadow;
+@@ -55,9 +77,12 @@
+ *(CS3BUSTYPE *)(CS3_BASE) = cs3_shadow;
+ }
+
++EXPORT_SYMBOL(get_cs3_ro);
++EXPORT_SYMBOL(get_cs3_shadow);
+ EXPORT_SYMBOL(set_cs3_bit);
+ EXPORT_SYMBOL(clear_cs3_bit);
+
++
+ static struct map_desc simpad_io_desc[] __initdata = {
+ { /* MQ200 */
+ .virtual = 0xf2800000,
+@@ -73,23 +98,71 @@
+ };
+
+
++static void simpad_uart_set_mctrl(struct uart_port *port, u_int mctrl)
++{
++ if (port->mapbase == _Ser1UTCR0) {
++ /* internal serial port (ttySA1, DECT/Bluetooth) */
++ if (mctrl & TIOCM_RTS) GPCR = GPIO_UART1_RTS;
++ else GPSR = GPIO_UART1_RTS;
++
++ if (mctrl & TIOCM_DTR) GPCR = GPIO_UART1_DTR;
++ else GPSR = GPIO_UART1_DTR;
++ }
++
++ else if (port->mapbase == _Ser3UTCR0) {
++ /* external serial port (ttySA0, RS232) */
++ if (mctrl & TIOCM_RTS) GPCR = GPIO_UART3_RTS;
++ else GPSR = GPIO_UART3_RTS;
++
++ if (mctrl & TIOCM_DTR) GPCR = GPIO_UART3_DTR;
++ else GPSR = GPIO_UART3_DTR;
++ }
++}
++
++
++static u_int simpad_uart_get_mctrl(struct uart_port *port)
++{
++ u_int ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR;
++
++ if (port->mapbase == _Ser1UTCR0) {
++ /* internal serial port (ttySA1, DECT/Bluetooth) */
++ int gplr = GPLR;
++ if (gplr & GPIO_UART1_DCD) ret &= ~TIOCM_CD;
++ if (gplr & GPIO_UART1_CTS) ret &= ~TIOCM_CTS;
++ if (gplr & GPIO_UART1_DSR) ret &= ~TIOCM_DSR;
++ }
++
++ else if (port->mapbase == _Ser3UTCR0) {
++ /* external serial port (ttySA0, RS232) */
++ int gplr = GPLR;
++ if (gplr & GPIO_UART3_DCD) ret &= ~TIOCM_CD;
++ if (gplr & GPIO_UART3_CTS) ret &= ~TIOCM_CTS;
++ if (gplr & GPIO_UART3_DSR) ret &= ~TIOCM_DSR;
++ }
++ return ret;
++}
++
++
+ static void simpad_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
+ {
+- if (port->mapbase == (u_int)&Ser1UTCR0) {
+- if (state)
+- {
+- clear_cs3_bit(RS232_ON);
+- clear_cs3_bit(DECT_POWER_ON);
+- }else
+- {
+- set_cs3_bit(RS232_ON);
+- set_cs3_bit(DECT_POWER_ON);
+- }
+- }
++ if (port->mapbase == (u_int)&Ser3UTCR0) {
++ if (state)
++ {
++ clear_cs3_bit(RS232_ON);
++ /* clear_cs3_bit(DECT_POWER_ON); */
++ }else
++ {
++ set_cs3_bit(RS232_ON);
++ /* set_cs3_bit(DECT_POWER_ON); */
++ }
++ }
+ }
+
++
+ static struct sa1100_port_fns simpad_port_fns __initdata = {
+- .pm = simpad_uart_pm,
++ .set_mctrl = simpad_uart_set_mctrl,
++ .get_mctrl = simpad_uart_get_mctrl,
++ .pm = simpad_uart_pm,
+ };
+
+
+@@ -135,7 +208,6 @@
+ };
+
+
+-
+ static void __init simpad_map_io(void)
+ {
+ sa1100_map_io();
+@@ -144,23 +216,45 @@
+
+ set_cs3_bit (EN1 | EN0 | LED2_ON | DISPLAY_ON | RS232_ON |
+ ENABLE_5V | RESET_SIMCARD | DECT_POWER_ON);
+-
+-
++
+ sa1100_register_uart_fns(&simpad_port_fns);
+ sa1100_register_uart(0, 3); /* serial interface */
+ sa1100_register_uart(1, 1); /* DECT */
+
+- // Reassign UART 1 pins
++ /* Reassign UART 1 pins */
++ /* TEST SOME OLD KERNEL STUFF INSTEAD
+ GAFR |= GPIO_UART_TXD | GPIO_UART_RXD;
+ GPDR |= GPIO_UART_TXD | GPIO_LDD13 | GPIO_LDD15;
+ GPDR &= ~GPIO_UART_RXD;
+ PPAR |= PPAR_UPR;
++ */
++
++ // txd and rxd use their alternate function
++ GAFR |= (GPIO_UART_TXD | GPIO_UART_RXD);
++
++ // the control lines are gpio
++ GAFR &= ~(GPIO_UART1_RTS | GPIO_UART1_CTS | GPIO_UART1_DCD);
++ GAFR &= ~(GPIO_UART1_DSR | GPIO_UART1_DTR);
++ GAFR &= ~(GPIO_UART3_RTS | GPIO_UART3_CTS | GPIO_UART3_DCD);
++ GAFR &= ~(GPIO_UART3_DSR | GPIO_UART3_DTR);
++
++ // txd, rts and dtr are outputs
++ GPDR |= GPIO_UART_TXD;
++ GPDR |= GPIO_UART1_RTS | GPIO_UART3_RTS;
++ GPDR |= GPIO_UART1_DTR | GPIO_UART3_DTR;
++
++ // cts, dcd, dsr and rxd are inputs
++ GPDR &= ~(GPIO_UART1_CTS | GPIO_UART3_CTS);
++ GPDR &= ~(GPIO_UART1_DCD | GPIO_UART3_DCD);
++ GPDR &= ~(GPIO_UART1_DSR | GPIO_UART3_DSR);
++ GPDR &= ~GPIO_UART_RXD;
++
++ PPAR |= PPAR_UPR;
+
+ /*
+ * Set up registers for sleep mode.
+ */
+
+-
+ PWER = PWER_GPIO0| PWER_RTC;
+ PGSR = 0x818;
+ PCFR = 0;
+@@ -171,9 +265,10 @@
+ sa11x0_set_mcp_data(&simpad_mcp_data);
+ }
+
++
+ static void simpad_power_off(void)
+ {
+- local_irq_disable(); // was cli
++ local_irq_disable(); /* was cli */
+ set_cs3(0x800); /* only SD_MEDIAQ */
+
+ /* disable internal oscillator, float CS lines */
+@@ -191,31 +286,52 @@
+ while(1);
+
+ local_irq_enable(); /* we won't ever call it */
++}
+
+
+-}
++/*
++ * gpio_keys
++*/
++
++static struct gpio_keys_button simpad_button_table[] = {
++ { KEY_POWER, IRQ_GPIO_POWER_BUTTON, 1, "power button" },
++};
++
++static struct gpio_keys_platform_data simpad_keys_data = {
++ .buttons = simpad_button_table,
++ .nbuttons = ARRAY_SIZE(simpad_button_table),
++};
++
++static struct platform_device simpad_keys = {
++ .name = "gpio-keys",
++ .dev = {
++ .platform_data = &simpad_keys_data,
++ },
++};
+
+
+ /*
+ * MediaQ Video Device
+ */
++
+ static struct platform_device simpad_mq200fb = {
+ .name = "simpad-mq200",
+ .id = 0,
+ };
+
++
+ static struct platform_device *devices[] __initdata = {
+- &simpad_mq200fb
++ &simpad_keys,
++ &simpad_mq200fb,
+ };
+
+
+-
+ static int __init simpad_init(void)
+ {
+ int ret;
+
+ pm_power_off = simpad_power_off;
+-
++
+ ret = platform_add_devices(devices, ARRAY_SIZE(devices));
+ if(ret)
+ printk(KERN_WARNING "simpad: Unable to register mq200 framebuffer device");
+diff -Nur linux-2.6.24.vanilla/include/asm-arm/arch-sa1100/simpad.h linux-2.6.24/include/asm-arm/arch-sa1100/simpad.h
+--- linux-2.6.24.vanilla/include/asm-arm/arch-sa1100/simpad.h 2008-10-04 21:47:17.000000000 +0200
++++ linux-2.6.24/include/asm-arm/arch-sa1100/simpad.h 2008-10-04 22:00:57.000000000 +0200
+@@ -12,11 +12,12 @@
+ #define __ASM_ARCH_SIMPAD_H
+
+
+-#define GPIO_UART1_RTS GPIO_GPIO14
++#define GPIO_UART1_RTS GPIO_GPIO9
+ #define GPIO_UART1_DTR GPIO_GPIO7
+ #define GPIO_UART1_CTS GPIO_GPIO8
+ #define GPIO_UART1_DCD GPIO_GPIO23
+ #define GPIO_UART1_DSR GPIO_GPIO6
++#define GPIO_UART1_RI GPIO_GPIO19
+
+ #define GPIO_UART3_RTS GPIO_GPIO12
+ #define GPIO_UART3_DTR GPIO_GPIO16
+@@ -48,9 +49,9 @@
+ #define GPIO_SMART_CARD GPIO_GPIO10
+ #define IRQ_GPIO_SMARD_CARD IRQ_GPIO10
+
+-// CS3 Latch is write only, a shadow is necessary
++// CS3 Latch is write only 16-bit , a shadow is necessary
+
+-#define CS3BUSTYPE unsigned volatile long
++#define CS3BUSTYPE unsigned volatile long
+ #define CS3_BASE 0xf1000000
+
+ #define VCC_5V_EN 0x0001 // For 5V PCMCIA
+@@ -70,43 +71,17 @@
+ #define ENABLE_5V 0x4000 // Enable 5V circuit
+ #define RESET_SIMCARD 0x8000
+
+-#define RS232_ENABLE 0x0440
+-#define PCMCIAMASK 0x402f
++// CS3 Latch is readable only 8-bit interest
+
++#define PCMCIA_BVD1 0x0001
++#define PCMCIA_BVD2 0x0002
++#define PCMCIA_VS1 0x0004 // PCMCIA card voltage select
++#define PCMCIA_VS2 0x0008 // PCMCIA card voltage select, if both are in high state -> 5V PCMCIA card
++#define LOCK_IND 0x0010
++#define CHARGING_STATE 0x0020 // Ladestatus
++#define PCMCIA_SHORT 0x0040 // low active
+
+-struct simpad_battery {
+- unsigned char ac_status; /* line connected yes/no */
+- unsigned char status; /* battery loading yes/no */
+- unsigned char percentage; /* percentage loaded */
+- unsigned short life; /* life till empty */
+-};
+-
+-/* These should match the apm_bios.h definitions */
+-#define SIMPAD_AC_STATUS_AC_OFFLINE 0x00
+-#define SIMPAD_AC_STATUS_AC_ONLINE 0x01
+-#define SIMPAD_AC_STATUS_AC_BACKUP 0x02 /* What does this mean? */
+-#define SIMPAD_AC_STATUS_AC_UNKNOWN 0xff
+-
+-/* These bitfields are rarely "or'd" together */
+-#define SIMPAD_BATT_STATUS_HIGH 0x01
+-#define SIMPAD_BATT_STATUS_LOW 0x02
+-#define SIMPAD_BATT_STATUS_CRITICAL 0x04
+-#define SIMPAD_BATT_STATUS_CHARGING 0x08
+-#define SIMPAD_BATT_STATUS_CHARGE_MAIN 0x10
+-#define SIMPAD_BATT_STATUS_DEAD 0x20 /* Battery will not charge */
+-#define SIMPAD_BATT_NOT_INSTALLED 0x20 /* For expansion pack batteries */
+-#define SIMPAD_BATT_STATUS_FULL 0x40 /* Battery fully charged (and connected to AC) */
+-#define SIMPAD_BATT_STATUS_NOBATT 0x80
+-#define SIMPAD_BATT_STATUS_UNKNOWN 0xff
+-
+-extern int simpad_get_battery(struct simpad_battery* );
++#define RS232_ENABLE 0x0440
++#define PCMCIAMASK 0x402f
+
+ #endif // __ASM_ARCH_SIMPAD_H
+-
+-
+-
+-
+-
+-
+-
+-
diff --git a/recipes/linux/linux/simpad/linux-2.6.24-SIMpad-ucb1x00-audio.patch b/recipes/linux/linux/simpad/linux-2.6.24-SIMpad-ucb1x00-audio.patch
new file mode 100644
index 0000000000..4f471b5fb4
--- /dev/null
+++ b/recipes/linux/linux/simpad/linux-2.6.24-SIMpad-ucb1x00-audio.patch
@@ -0,0 +1,1622 @@
+Index: linux-2.6.24/sound/arm/sa11xx-ucb1x00.c
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.24/sound/arm/sa11xx-ucb1x00.c 2008-12-25 23:23:38.000000000 +0100
+@@ -0,0 +1,829 @@
++/*
++ * Driver for Philips UCB1300 on Siemens Simpad
++ * Copyright (C) 2008 Thomas Schätzlein <thomas@pnxs.de>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License.
++ *
++ */
++
++#include <sound/driver.h>
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/init.h>
++#include <linux/err.h>
++#include <linux/platform_device.h>
++#include <linux/errno.h>
++#include <linux/ioctl.h>
++#include <linux/delay.h>
++#include <linux/slab.h>
++
++#ifdef CONFIG_PM
++#include <linux/pm.h>
++#endif
++
++#include <asm/dma.h>
++
++#include <sound/core.h>
++#include <sound/control.h>
++#include <sound/pcm.h>
++#include <sound/initval.h>
++#include <sound/info.h>
++
++#include <linux/mfd/ucb1x00.h>
++
++#undef DEBUG_MODE
++#undef DEBUG_FUNCTION_NAMES
++
++#define AUDIO_RATE_DEFAULT 44100
++
++MODULE_AUTHOR("Thomas Schätzlein <thomas@pnxs.de>");
++MODULE_LICENSE("GPL");
++MODULE_DESCRIPTION("SA1100/SA1111 + UCB1300 driver for ALSA");
++MODULE_SUPPORTED_DEVICE("{{UCB1x00,Simpad}}");
++
++static char *id; /* ID for this card */
++
++module_param(id, charp, 0444);
++MODULE_PARM_DESC(id, "ID string for SA1100/SA1111 + UCB1x00 soundcard.");
++
++struct audio_stream {
++ char *id; /* identification string */
++ int stream_id; /* numeric identification */
++ dma_device_t dma_dev; /* device identifier for DMA */
++ dma_regs_t *dma_regs; /* points to our DMA registers */
++ unsigned int active:1; /* we are using this stream for transfer now */
++ int period; /* current transfer period */
++ int periods; /* current count of periods registerd in the DMA engine */
++ unsigned int old_offset;
++ spinlock_t dma_lock; /* for locking in DMA operations (see dma-sa1100.c in the kernel) */
++ struct snd_pcm_substream *stream;
++};
++
++struct sa11xx_ucb1x00 {
++ struct snd_card* card;
++ struct snd_pcm* pcm;
++ struct ucb1x00_dev* ucb1x00;
++ struct device* pdev;
++ long samplerate;
++ struct audio_stream s[2]; /* playback & capture */
++};
++
++#if 0
++static unsigned int rates[] = {
++ 8000, 10666, 10985, 14647,
++ 16000, 21970, 22050, 24000,
++ 29400, 32000, 44100, 48000,
++};
++
++static struct snd_pcm_hw_constraint_list hw_constraints_rates = {
++ .count = ARRAY_SIZE(rates),
++ .list = rates,
++ .mask = 0,
++};
++#endif
++
++#define UCB1x00_SINGLE(xname, where, reg, shift, mask, invert) \
++{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_ucb1x00_info_single, \
++ .get = snd_ucb1x00_get_single, .put = snd_ucb1x00_put_single, \
++ .private_value = where | (reg << 5) | (shift << 9) | (mask << 13) | (invert << 19) \
++}
++
++#define UCB1x00_SINGLE_WHERE(value) (value & 31)
++#define UCB1x00_SINGLE_REG(value) ((value >> 5) & 15)
++#define UCB1x00_SINGLE_SHIFT(value) ((value >> 9) & 15)
++#define UCB1x00_SINGLE_MASK(value) ((value >> 13) & 63)
++#define UCB1x00_SINGLE_INV(value) ((value >> 19) & 1)
++
++static int snd_ucb1x00_info_single(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_info *uinfo)
++{
++ int mask = UCB1x00_SINGLE_MASK(kcontrol->private_value);
++
++// printk(KERN_INFO "snd_ucb1x00_info_single called\n");
++
++ uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
++ uinfo->count = 1;
++ uinfo->value.integer.min = 0;
++ uinfo->value.integer.max = mask;
++ return 0;
++}
++
++static int snd_ucb1x00_get_single(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
++{
++ struct sa11xx_ucb1x00* chip = snd_kcontrol_chip(kcontrol);
++ struct ucb1x00 *ucb = chip->ucb1x00->ucb;
++ unsigned int retval;
++
++ int reg = UCB1x00_SINGLE_REG(kcontrol->private_value);
++ int shift = UCB1x00_SINGLE_SHIFT(kcontrol->private_value);
++ int mask = UCB1x00_SINGLE_MASK(kcontrol->private_value);
++ int invert= UCB1x00_SINGLE_INV(kcontrol->private_value);
++
++// printk(KERN_INFO "snd_ucb1x00_get_single called\n");
++
++ retval = (ucb1x00_reg_read(ucb, reg) >> shift) & mask;
++
++// printk(KERN_INFO "ucb1x00_reg_read reg=%02X value=%08X\n", reg, retval);
++
++ ucontrol->value.integer.value[0] = retval;
++ if (invert) {
++ ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
++ }
++
++ return 0;
++}
++
++static int snd_ucb1x00_put_single(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
++{
++ struct sa11xx_ucb1x00* chip = snd_kcontrol_chip(kcontrol);
++ struct ucb1x00 *ucb = chip->ucb1x00->ucb;
++ int reg = UCB1x00_SINGLE_REG(kcontrol->private_value);
++ int shift = UCB1x00_SINGLE_SHIFT(kcontrol->private_value);
++ int mask = UCB1x00_SINGLE_MASK(kcontrol->private_value);
++ int invert= UCB1x00_SINGLE_INV(kcontrol->private_value);
++ unsigned short val;
++ unsigned int regval;
++
++ val = (ucontrol->value.integer.value[0] & mask);
++ if (invert)
++ val = mask - val;
++
++// printk(KERN_INFO "snd_ucb1x00_put_single called val=%d\n", val);
++
++ regval = ucb1x00_reg_read(ucb, reg);
++ regval &= ~(mask << shift);
++ regval |= val << shift;
++// printk(KERN_INFO "snd_ucb1x00_put_single write regval=%08X to reg %d\n", regval, reg);
++ ucb1x00_reg_write(ucb, reg, regval);
++ return 0;
++}
++
++enum ucb1x00_config {
++ CMD_OMUTE = 0,
++ CMD_VOLUME,
++ CMD_IGAIN,
++ CMD_IMUTE,
++ CMD_LOOPBACK,
++ CMD_CLIP,
++ CMD_OENA,
++};
++
++static struct snd_kcontrol_new snd_ucb1x00_controls[] = {
++ UCB1x00_SINGLE("Master Playback Switch", CMD_OMUTE, UCB_AC_B, 13, 0x01, 1),
++ UCB1x00_SINGLE("Master Playback Volume", CMD_VOLUME, UCB_AC_B, 0, 0x1F, 1),
++
++ UCB1x00_SINGLE("Input Gain", CMD_IGAIN, UCB_AC_A, 7, 0x1F, 1),
++// UCB1x00_SINGLE("Input Mute", CMD_IMUTE, UCB_AC_B, 14, 1, 1),
++// UCB1x00_SINGLE("Output Enabled", CMD_OENA, UCB_AC_B, 15, 1, 1),
++
++ UCB1x00_SINGLE("Audio Loopback", CMD_LOOPBACK, UCB_AC_B, 8, 1, 0),
++};
++
++static void sa11xx_ucb1x00_set_samplerate(struct sa11xx_ucb1x00 *sa11xx_ucb1x00, long rate)
++{
++ struct ucb1x00 *ucb = sa11xx_ucb1x00->ucb1x00->ucb;
++ unsigned int div_rate = ucb1x00_clkrate(ucb) / 32;
++ unsigned int div;
++ unsigned int reg;
++
++// printk(KERN_INFO "sa11xx_ucb1x00_set_samplerate called rate=%d div_rate=%d\n", rate, div_rate);
++
++ div = (div_rate + (rate / 2)) / rate;
++ if (div < 6) {
++ div = 6;
++ }
++ if (div > 127) {
++ div = 127;
++ }
++/*
++ printk(KERN_INFO "ucb=%08X\n", ucb);
++ printk(KERN_INFO "ucb1x00_set_audio_divisor(%d)\n", div*32);
++ printk(KERN_INFO "ucb1x00_reg_write(reg=%d, div=%d)\n", UCB_AC_A, div);
++*/
++ reg = ucb1x00_reg_read(ucb, UCB_AC_B);
++ reg &= ~(UCB_AC_B_IN_ENA | UCB_AC_B_OUT_ENA);
++ ucb1x00_reg_write(ucb, UCB_AC_B, reg);
++
++ // ucb1x00_reg_write(ucb, UCB_AC_B, 0);
++ ucb1x00_set_audio_divisor(ucb, div*32); /* set divisor in MCP */
++
++ reg = ucb1x00_reg_read(ucb, UCB_AC_A);
++ reg &= ~(0x1F);
++ reg |= div;
++ ucb1x00_reg_write(ucb, UCB_AC_A, reg); /* set divisor in UCB1x00 */
++
++ reg = ucb1x00_reg_read(ucb, UCB_AC_B);
++ reg |= UCB_AC_B_IN_ENA | UCB_AC_B_OUT_ENA;
++ ucb1x00_reg_write(ucb, UCB_AC_B, reg);
++
++ sa11xx_ucb1x00->samplerate = div_rate / div;
++
++// printk(KERN_INFO "sa11xx_ucb1x00_set_samplerate done\n");
++}
++
++/* HW init and shutdown */
++static void sa11xx_ucb1x00_audio_init(struct sa11xx_ucb1x00 *sa11xx_ucb1x00)
++{
++ //unsigned long flags;
++
++ /* Setup DMA stuff */
++ sa11xx_ucb1x00->s[SNDRV_PCM_STREAM_PLAYBACK].id = "UCB1x00 out";
++ sa11xx_ucb1x00->s[SNDRV_PCM_STREAM_PLAYBACK].stream_id = SNDRV_PCM_STREAM_PLAYBACK;
++ sa11xx_ucb1x00->s[SNDRV_PCM_STREAM_PLAYBACK].dma_dev = sa11xx_ucb1x00->ucb1x00->ucb->mcp->dma_audio_wr;
++
++ sa11xx_ucb1x00->s[SNDRV_PCM_STREAM_CAPTURE].id = "UCB1x00 in";
++ sa11xx_ucb1x00->s[SNDRV_PCM_STREAM_CAPTURE].stream_id = SNDRV_PCM_STREAM_CAPTURE;
++ sa11xx_ucb1x00->s[SNDRV_PCM_STREAM_CAPTURE].dma_dev = sa11xx_ucb1x00->ucb1x00->ucb->mcp->dma_audio_rd;
++}
++
++#if 0
++static void sa11xx_ucb1x00_audio_shutdown(struct sa11xx_ucb1x00 *sa11xx_ucb1x00)
++{
++ /* mute on */
++// set_sa11xx_uda1341_egpio(IPAQ_EGPIO_QMUTE);
++
++ /* disable the audio power and all signals leading to the audio chip */
++// l3_close(sa11xx_uda1341->uda1341);
++// Ser4SSCR0 = 0;
++// clr_sa11xx_uda1341_egpio(IPAQ_EGPIO_CODEC_NRESET);
++
++ /* power off and mute off */
++ /* FIXME - is muting off necesary??? */
++
++// clr_sa11xx_uda1341_egpio(IPAQ_EGPIO_AUDIO_ON);
++// clr_sa11xx_uda1341_egpio(IPAQ_EGPIO_QMUTE);
++}
++#endif
++
++/* DMA stuff */
++
++/*
++ * these are the address and sizes used to fill the xmit buffer
++ * so we can get a clock in record only mode
++ */
++//#define FORCE_CLOCK_ADDR (dma_addr_t)FLUSH_BASE_PHYS
++//#define FORCE_CLOCK_SIZE 4096 // was 2048
++
++// FIXME Why this value exactly - wrote comment
++#define DMA_BUF_SIZE 8176 /* <= MAX_DMA_SIZE from asm/arch-sa1100/dma.h */
++
++static int audio_dma_request(struct audio_stream *s, void (*callback)(void *))
++{
++ int ret;
++
++// printk(KERN_INFO "audio_dma_request stream=%08X\n", s);
++
++ ret = sa1100_request_dma(s->dma_dev, s->id, callback, s, &s->dma_regs);
++ if (ret < 0)
++ printk(KERN_ERR "unable to grab audio dma 0x%x\n", s->dma_dev);
++ return ret;
++}
++
++static void audio_dma_free(struct audio_stream *s)
++{
++// printk(KERN_INFO "audio_dma_free stream=%08X\n", s);
++ sa1100_free_dma(s->dma_regs);
++ s->dma_regs = 0;
++}
++
++static u_int audio_get_dma_pos(struct audio_stream *s)
++{
++ struct snd_pcm_substream *substream = s->stream;
++ struct snd_pcm_runtime *runtime = substream->runtime;
++ unsigned int offset;
++ unsigned long flags;
++ dma_addr_t addr;
++
++ // this must be called w/ interrupts locked out see dma-sa1100.c in the kernel
++ spin_lock_irqsave(&s->dma_lock, flags);
++ addr = sa1100_get_dma_pos((s)->dma_regs);
++ offset = addr - runtime->dma_addr;
++ spin_unlock_irqrestore(&s->dma_lock, flags);
++
++// printk(KERN_INFO "audio_get_dma_pos real_offset=%d\n", offset);
++
++ offset = bytes_to_frames(runtime,offset);
++ if (offset >= runtime->buffer_size)
++ offset = 0;
++
++// printk(KERN_INFO "audio_get_dma_pos stream=%08X pos=%d\n", s, offset);
++
++ return offset;
++}
++
++/*
++ * this stops the dma and clears the dma ptrs
++ */
++static void audio_stop_dma(struct audio_stream *s)
++{
++ unsigned long flags;
++
++ spin_lock_irqsave(&s->dma_lock, flags);
++ s->active = 0;
++ s->period = 0;
++ /* this stops the dma channel and clears the buffer ptrs */
++ sa1100_clear_dma(s->dma_regs);
++ spin_unlock_irqrestore(&s->dma_lock, flags);
++}
++
++static void audio_process_dma(struct audio_stream *s)
++{
++ struct snd_pcm_substream *substream = s->stream;
++ struct snd_pcm_runtime *runtime;
++ unsigned int dma_size;
++ unsigned int offset;
++ int ret;
++
++// printk(KERN_ERR "audio_process_dma called periods=%d period=%d\n", s->periods, s->period);
++
++ /* must be set here - only valid for running streams, not for forced_clock dma fills */
++ runtime = substream->runtime;
++ while (s->active && s->periods < runtime->periods) {
++ dma_size = frames_to_bytes(runtime, runtime->period_size);
++ if (s->old_offset) {
++ /* a little trick, we need resume from old position */
++ offset = frames_to_bytes(runtime, s->old_offset - 1);
++ s->old_offset = 0;
++ s->periods = 0;
++ s->period = offset / dma_size;
++ offset %= dma_size;
++ dma_size = dma_size - offset;
++ if (!dma_size)
++ continue; /* special case */
++ } else {
++ offset = dma_size * s->period;
++ snd_assert(dma_size <= DMA_BUF_SIZE, );
++ }
++// printk(KERN_INFO "start addr=%08X size=%d\n", runtime->dma_addr + offset, dma_size);
++ ret = sa1100_start_dma((s)->dma_regs, runtime->dma_addr + offset, dma_size);
++ if (ret) {
++// printk(KERN_ERR "audio_process_dma: cannot queue DMA buffer (%i)\n", ret);
++ return;
++ }
++
++ s->period++;
++ s->period %= runtime->periods;
++ s->periods++;
++ }
++}
++
++static void audio_dma_callback(void *data)
++{
++ struct audio_stream *s = data;
++
++// printk(KERN_INFO "audio_dma_callback called stream=%08X\n", s);
++
++ /*
++ * If we are getting a callback for an active stream then we inform
++ * the PCM middle layer we've finished a period
++ */
++ if (s->active) {
++// printk(KERN_INFO "audio_dma_callback period elapsed\n");
++ snd_pcm_period_elapsed(s->stream);
++ }
++
++ spin_lock(&s->dma_lock);
++ if (s->periods > 0) {
++ s->periods--;
++ }
++ audio_process_dma(s);
++ spin_unlock(&s->dma_lock);
++}
++
++static void sa11xx_ucb1x00_enable_audio(struct ucb1x00* ucb)
++{
++ uint32_t reg;
++ reg = ucb1x00_reg_read(ucb, UCB_AC_B);
++ reg |= UCB_AC_B_OUT_ENA;
++ ucb1x00_reg_write(ucb, UCB_AC_B, reg);
++}
++
++static void sa11xx_ucb1x00_disable_audio(struct ucb1x00* ucb)
++{
++ uint32_t reg;
++ reg = ucb1x00_reg_read(ucb, UCB_AC_B);
++ reg &= ~(UCB_AC_B_OUT_ENA);
++ ucb1x00_reg_write(ucb, UCB_AC_B, reg);
++}
++
++/* PCM setting */
++
++/* trigger & timer */
++static int snd_sa11xx_ucb1x00_trigger(struct snd_pcm_substream *substream, int cmd)
++{
++ struct sa11xx_ucb1x00 *chip = snd_pcm_substream_chip(substream);
++ int stream_id = substream->pstr->stream;
++ struct audio_stream *s = &chip->s[stream_id];
++ int err = 0;
++
++// printk(KERN_INFO "snd_sa11xx_ucb1x00_trigger called\n");
++
++ /* note local interrupts are already disabled in the midlevel code */
++ spin_lock(&s->dma_lock);
++ switch (cmd) {
++ case SNDRV_PCM_TRIGGER_START:
++ /* requested stream startup */
++ s->active = 1;
++ sa11xx_ucb1x00_enable_audio(chip->ucb1x00->ucb);
++ audio_process_dma(s);
++ break;
++ case SNDRV_PCM_TRIGGER_STOP:
++ /* requested stream shutdown */
++ sa11xx_ucb1x00_disable_audio(chip->ucb1x00->ucb);
++ audio_stop_dma(s);
++ break;
++ case SNDRV_PCM_TRIGGER_SUSPEND:
++ s->active = 0;
++ sa1100_stop_dma(s->dma_regs);
++ s->old_offset = audio_get_dma_pos(s) + 1;
++#ifdef HH_VERSION
++ sa1100_dma_flush_all(s->dma_regs);
++#else
++ //FIXME - DMA API
++#endif
++ s->periods = 0;
++ break;
++ case SNDRV_PCM_TRIGGER_RESUME:
++ s->active = 1;
++ audio_process_dma(s);
++ break;
++ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
++ sa1100_stop_dma(s->dma_regs);
++ s->active = 0;
++ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
++ s->active = 1;
++ if (s->old_offset) {
++ audio_process_dma(s);
++ break;
++ }
++ sa1100_resume_dma(s->dma_regs);
++ break;
++ default:
++ err = -EINVAL;
++ break;
++ }
++ spin_unlock(&s->dma_lock);
++ return err;
++}
++
++static int snd_sa11xx_ucb1x00_prepare(struct snd_pcm_substream *substream)
++{
++ struct sa11xx_ucb1x00 *chip = snd_pcm_substream_chip(substream);
++ struct snd_pcm_runtime *runtime = substream->runtime;
++ struct audio_stream *s = &chip->s[substream->pstr->stream];
++
++// printk(KERN_INFO "snd_sa11xx_ucb1x00_prepare called\n");
++
++ /* set requested samplerate */
++ sa11xx_ucb1x00_set_samplerate(chip, runtime->rate);
++
++ s->period = 0;
++ s->periods = 0;
++
++ return 0;
++}
++
++static snd_pcm_uframes_t snd_sa11xx_ucb1x00_pointer(struct snd_pcm_substream *substream)
++{
++ struct sa11xx_ucb1x00 *chip = snd_pcm_substream_chip(substream);
++// printk(KERN_INFO "snd_sa11xx_ucb1x00_pointer called\n");
++ return audio_get_dma_pos(&chip->s[substream->pstr->stream]);
++}
++
++static struct snd_pcm_hardware snd_sa11xx_ucb1x00_hw =
++{
++ .info = (SNDRV_PCM_INFO_INTERLEAVED |
++ SNDRV_PCM_INFO_BLOCK_TRANSFER |
++ SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
++ SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
++ .formats = SNDRV_PCM_FMTBIT_S16_LE,
++/* .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
++ SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 |\
++ SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\
++ SNDRV_PCM_RATE_KNOT),*/
++ .rate_min = 5000,
++ .rate_max = 48000,
++ .channels_min = 1,
++ .channels_max = 1,
++ .buffer_bytes_max = 64*1024,
++ .period_bytes_min = 4096,
++ .period_bytes_max = DMA_BUF_SIZE,
++ .periods_min = 2,
++ .periods_max = 255,
++ .fifo_size = 0,
++};
++
++#if 0
++static struct snd_pcm_hardware snd_sa11xx_ucb1x00_playback =
++{
++ .info = (SNDRV_PCM_INFO_INTERLEAVED |
++ SNDRV_PCM_INFO_BLOCK_TRANSFER |
++ SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
++ SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
++ .formats = SNDRV_PCM_FMTBIT_S16_LE,
++ .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
++ SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 |\
++ SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\
++ SNDRV_PCM_RATE_KNOT),
++ .rate_min = 8000,
++ .rate_max = 48000,
++ .channels_min = 2,
++ .channels_max = 2,
++ .buffer_bytes_max = 64*1024,
++ .period_bytes_min = 128,
++ .period_bytes_max = DMA_BUF_SIZE,
++ .periods_min = 2,
++ .periods_max = 8,
++ .fifo_size = 0,
++};
++#endif
++
++static int snd_card_sa11xx_ucb1x00_open(struct snd_pcm_substream *substream)
++{
++ struct sa11xx_ucb1x00 *chip = snd_pcm_substream_chip(substream);
++ struct snd_pcm_runtime *runtime = substream->runtime;
++ int stream_id = substream->pstr->stream;
++ //int err;
++
++ chip->s[stream_id].stream = substream;
++
++// printk(KERN_INFO "snd_card_sa11xx_ucb1x00_open called substream=%08X\n", substream);
++
++ runtime->hw = snd_sa11xx_ucb1x00_hw;
++ if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) {
++ }
++ else {
++ }
++/*
++ if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0) {
++ return err;
++ }
++*/
++/* if ((err = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates)) < 0) {
++ return err;
++ }
++*/
++ return 0;
++}
++
++static int snd_card_sa11xx_ucb1x00_close(struct snd_pcm_substream *substream)
++{
++ struct sa11xx_ucb1x00 *chip = snd_pcm_substream_chip(substream);
++
++ chip->s[substream->pstr->stream].stream = NULL;
++// printk(KERN_INFO "snd_card_sa11xx_ucb1x00_close called substream=%08X\n", substream);
++ return 0;
++}
++
++/* HW params & free */
++
++static int snd_sa11xx_ucb1x00_hw_params(struct snd_pcm_substream *substream,
++ struct snd_pcm_hw_params *hw_params)
++{
++// struct sa11xx_ucb1x00 *chip = snd_pcm_substream_chip(substream);
++// struct ucb1x00* ucb = chip->ucb1x00->ucb;
++// printk(KERN_INFO "snd_sa11xx_ucb1x00_hw_params called substream=%08X\n", substream);
++
++
++ return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
++}
++
++static int snd_sa11xx_ucb1x00_hw_free(struct snd_pcm_substream *substream)
++{
++// struct sa11xx_ucb1x00 *chip = snd_pcm_substream_chip(substream);
++// struct ucb1x00* ucb = chip->ucb1x00->ucb;
++// printk(KERN_INFO "snd_sa11xx_ucb1x00_hw_free called substream=%08X\n", substream);
++
++ return snd_pcm_lib_free_pages(substream);
++}
++
++static struct snd_pcm_ops snd_card_sa11xx_ucb1x00_playback_ops = {
++ .open = snd_card_sa11xx_ucb1x00_open,
++ .close = snd_card_sa11xx_ucb1x00_close,
++ .ioctl = snd_pcm_lib_ioctl,
++ .hw_params = snd_sa11xx_ucb1x00_hw_params,
++ .hw_free = snd_sa11xx_ucb1x00_hw_free,
++ .prepare = snd_sa11xx_ucb1x00_prepare,
++ .trigger = snd_sa11xx_ucb1x00_trigger,
++ .pointer = snd_sa11xx_ucb1x00_pointer,
++};
++
++static struct snd_pcm_ops snd_card_sa11xx_ucb1x00_capture_ops = {
++ .open = snd_card_sa11xx_ucb1x00_open,
++ .close = snd_card_sa11xx_ucb1x00_close,
++ .ioctl = snd_pcm_lib_ioctl,
++ .hw_params = snd_sa11xx_ucb1x00_hw_params,
++ .hw_free = snd_sa11xx_ucb1x00_hw_free,
++ .prepare = snd_sa11xx_ucb1x00_prepare,
++ .trigger = snd_sa11xx_ucb1x00_trigger,
++ .pointer = snd_sa11xx_ucb1x00_pointer,
++};
++
++static int __init snd_card_sa11xx_ucb1x00_pcm(struct sa11xx_ucb1x00 *sa11xx_ucb1x00, int device)
++{
++ struct snd_pcm *pcm;
++ int err;
++
++ if ((err = snd_pcm_new(sa11xx_ucb1x00->card, "UCB1x00 PCM", device, 1, 1, &pcm)) < 0) {
++ return err;
++ }
++
++ sa11xx_ucb1x00_audio_init(sa11xx_ucb1x00);
++
++
++ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_card_sa11xx_ucb1x00_playback_ops);
++ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_card_sa11xx_ucb1x00_capture_ops);
++ pcm->private_data = sa11xx_ucb1x00;
++ pcm->info_flags = 0;
++ strcpy(pcm->name, "UCB1x00 PCM");
++
++ err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
++ NULL, 64*1024, 64*1024);
++// printk(KERN_INFO "snd_pcm_lib_preallocate_pages_for_all returns %d\n", err);
++
++
++ /* setup DMA controller */
++ audio_dma_request(&sa11xx_ucb1x00->s[SNDRV_PCM_STREAM_PLAYBACK], audio_dma_callback);
++ audio_dma_request(&sa11xx_ucb1x00->s[SNDRV_PCM_STREAM_CAPTURE], audio_dma_callback);
++
++ sa11xx_ucb1x00->pcm = pcm;
++
++ return 0;
++}
++
++#if 0
++#ifdef CONFIG_PM
++
++static int snd_sa11xx_ucb1x00_suspend(struct platform_device *devptr,
++ pm_message_t state)
++{
++ struct snd_card *card = platform_get_drvdata(devptr);
++ struct sa11xx_ucb1x00 *chip = card->private_data;
++
++ snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
++ snd_pcm_suspend_all(chip->pcm);
++#ifdef HH_VERSION
++ sa1100_dma_sleep(chip->s[SNDRV_PCM_STREAM_PLAYBACK].dmach);
++ sa1100_dma_sleep(chip->s[SNDRV_PCM_STREAM_CAPTURE].dmach);
++#else
++ //FIXME
++#endif
++ l3_command(chip->ucb1x00, CMD_SUSPEND, NULL);
++ sa11xx_uda1341_audio_shutdown(chip);
++
++ return 0;
++}
++
++static int snd_sa11xx_ucb1x00_resume(struct platform_device *devptr)
++{
++ struct snd_card *card = platform_get_drvdata(devptr);
++ struct sa11xx_ucb1x00 *chip = card->private_data;
++
++ sa11xx_ucb1x00_audio_init(chip);
++ l3_command(chip->ucb1x00, CMD_RESUME, NULL);
++#ifdef HH_VERSION
++ sa1100_dma_wakeup(chip->s[SNDRV_PCM_STREAM_PLAYBACK].dmach);
++ sa1100_dma_wakeup(chip->s[SNDRV_PCM_STREAM_CAPTURE].dmach);
++#else
++ //FIXME
++#endif
++ snd_power_change_state(card, SNDRV_CTL_POWER_D0);
++ return 0;
++}
++#endif /* COMFIG_PM */
++#endif
++
++void snd_sa11xx_ucb1x00_free(struct snd_card *card)
++{
++ struct sa11xx_ucb1x00 *chip = card->private_data;
++
++// printk(KERN_INFO "snd_sa11xx_ucb1x00_free called\n");
++
++ if (&chip->s[SNDRV_PCM_STREAM_PLAYBACK]) {
++ audio_dma_free(&chip->s[SNDRV_PCM_STREAM_PLAYBACK]);
++ }
++ if (&chip->s[SNDRV_PCM_STREAM_CAPTURE]) {
++ audio_dma_free(&chip->s[SNDRV_PCM_STREAM_CAPTURE]);
++ }
++}
++
++static int ucb1x00_dev_free(struct snd_device *device)
++{
++ return 0;
++}
++
++static int snd_chip_ucb1x00_mixer_new(struct snd_card *card)
++{
++ static struct snd_device_ops ops = {
++ .dev_free = ucb1x00_dev_free,
++ };
++
++ struct sa11xx_ucb1x00 *chip = card->private_data;
++ int idx;
++ int err;
++
++ snd_assert(card != NULL, return -EINVAL);
++
++ for (idx = 0; idx < ARRAY_SIZE(snd_ucb1x00_controls); idx++) {
++ if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_ucb1x00_controls[idx], chip))) < 0) {
++ return err;
++ }
++ }
++
++ if ((err = snd_device_new(card, SNDRV_DEV_CODEC, chip, &ops)) < 0) {
++ return err;
++ }
++
++ strcpy(card->mixername, "UCB1x00 Mixer");
++ // ((struct ucb1x00_dev *)clnt->driver_data)->card = card;
++
++ return 0;
++}
++
++static int __init sa11xx_ucb1x00_audio_add(struct ucb1x00_dev* dev)
++{
++ int err;
++ struct snd_card *card;
++ struct sa11xx_ucb1x00 *chip;
++
++ /* register the soundcard */
++ card = snd_card_new(-1, id, THIS_MODULE, sizeof(struct sa11xx_ucb1x00));
++ if (card == NULL) {
++ return -ENOMEM;
++ }
++
++ ucb1x00_enable(dev->ucb);
++
++ chip = card->private_data;
++ spin_lock_init(&chip->s[0].dma_lock);
++ spin_lock_init(&chip->s[1].dma_lock);
++
++ card->private_free = snd_sa11xx_ucb1x00_free;
++ chip->card = card;
++ chip->samplerate = AUDIO_RATE_DEFAULT;
++ chip->ucb1x00 = dev;
++ chip->pdev = &dev->ucb->mcp->attached_device;
++ dev->priv = chip;
++
++ // mixer
++ if ((err = snd_chip_ucb1x00_mixer_new(card)))
++ goto nodev;
++
++ // PCM
++ if ((err = snd_card_sa11xx_ucb1x00_pcm(chip, 0)) < 0)
++ goto nodev;
++
++ strcpy(card->driver, "UCB1x00");
++ strcpy(card->shortname, "Simpad UCB1x00");
++ sprintf(card->longname, "Siemens Simpad with Philips UCB1x00");
++
++ snd_card_set_dev(card, chip->pdev);
++
++ if ((err = snd_card_register(card)) == 0) {
++ printk( KERN_INFO "Simpad audio support initialized 2\n" );
++ return 0;
++ }
++
++ nodev:
++ snd_card_free(card);
++ return err;
++}
++
++static void sa11xx_ucb1x00_audio_remove(struct ucb1x00_dev* dev)
++{
++ struct sa11xx_ucb1x00* chip = dev->priv;
++ printk(KERN_INFO "sa11xx_ucb1x00_audio_remove called\n");
++ ucb1x00_disable(dev->ucb);
++ snd_card_free(chip->card);
++}
++
++static int sa11xx_ucb1x00_audio_resume(struct ucb1x00_dev* dev)
++{
++ printk(KERN_INFO "sa11xx_ucb1x00_audio_resume called\n");
++ return 0;
++}
++
++/* ---- GOOD ----------------------------------------------------- */
++
++static struct ucb1x00_driver sa11xx_ucb1x00_audio_driver = {
++ .add = sa11xx_ucb1x00_audio_add,
++ .remove = sa11xx_ucb1x00_audio_remove,
++ .resume = sa11xx_ucb1x00_audio_resume,
++};
++
++static int __init sa11xx_ucb1x00_init(void)
++{
++ return ucb1x00_register_driver(&sa11xx_ucb1x00_audio_driver);
++}
++
++static void __exit sa11xx_ucb1x00_exit(void)
++{
++ ucb1x00_unregister_driver(&sa11xx_ucb1x00_audio_driver);
++}
++
++module_init(sa11xx_ucb1x00_init);
++module_exit(sa11xx_ucb1x00_exit);
++
+Index: linux-2.6.24/drivers/mfd/ucb1x00.h
+===================================================================
+--- linux-2.6.24.orig/drivers/mfd/ucb1x00.h 2008-12-23 22:00:03.000000000 +0100
++++ /dev/null 1970-01-01 00:00:00.000000000 +0000
+@@ -1,255 +0,0 @@
+-/*
+- * linux/drivers/mfd/ucb1x00.h
+- *
+- * Copyright (C) 2001 Russell King, All Rights Reserved.
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License.
+- */
+-#ifndef UCB1200_H
+-#define UCB1200_H
+-
+-#define UCB_IO_DATA 0x00
+-#define UCB_IO_DIR 0x01
+-
+-#define UCB_IO_0 (1 << 0)
+-#define UCB_IO_1 (1 << 1)
+-#define UCB_IO_2 (1 << 2)
+-#define UCB_IO_3 (1 << 3)
+-#define UCB_IO_4 (1 << 4)
+-#define UCB_IO_5 (1 << 5)
+-#define UCB_IO_6 (1 << 6)
+-#define UCB_IO_7 (1 << 7)
+-#define UCB_IO_8 (1 << 8)
+-#define UCB_IO_9 (1 << 9)
+-
+-#define UCB_IE_RIS 0x02
+-#define UCB_IE_FAL 0x03
+-#define UCB_IE_STATUS 0x04
+-#define UCB_IE_CLEAR 0x04
+-#define UCB_IE_ADC (1 << 11)
+-#define UCB_IE_TSPX (1 << 12)
+-#define UCB_IE_TSMX (1 << 13)
+-#define UCB_IE_TCLIP (1 << 14)
+-#define UCB_IE_ACLIP (1 << 15)
+-
+-#define UCB_IRQ_TSPX 12
+-
+-#define UCB_TC_A 0x05
+-#define UCB_TC_A_LOOP (1 << 7) /* UCB1200 */
+-#define UCB_TC_A_AMPL (1 << 7) /* UCB1300 */
+-
+-#define UCB_TC_B 0x06
+-#define UCB_TC_B_VOICE_ENA (1 << 3)
+-#define UCB_TC_B_CLIP (1 << 4)
+-#define UCB_TC_B_ATT (1 << 6)
+-#define UCB_TC_B_SIDE_ENA (1 << 11)
+-#define UCB_TC_B_MUTE (1 << 13)
+-#define UCB_TC_B_IN_ENA (1 << 14)
+-#define UCB_TC_B_OUT_ENA (1 << 15)
+-
+-#define UCB_AC_A 0x07
+-#define UCB_AC_B 0x08
+-#define UCB_AC_B_LOOP (1 << 8)
+-#define UCB_AC_B_MUTE (1 << 13)
+-#define UCB_AC_B_IN_ENA (1 << 14)
+-#define UCB_AC_B_OUT_ENA (1 << 15)
+-
+-#define UCB_TS_CR 0x09
+-#define UCB_TS_CR_TSMX_POW (1 << 0)
+-#define UCB_TS_CR_TSPX_POW (1 << 1)
+-#define UCB_TS_CR_TSMY_POW (1 << 2)
+-#define UCB_TS_CR_TSPY_POW (1 << 3)
+-#define UCB_TS_CR_TSMX_GND (1 << 4)
+-#define UCB_TS_CR_TSPX_GND (1 << 5)
+-#define UCB_TS_CR_TSMY_GND (1 << 6)
+-#define UCB_TS_CR_TSPY_GND (1 << 7)
+-#define UCB_TS_CR_MODE_INT (0 << 8)
+-#define UCB_TS_CR_MODE_PRES (1 << 8)
+-#define UCB_TS_CR_MODE_POS (2 << 8)
+-#define UCB_TS_CR_BIAS_ENA (1 << 11)
+-#define UCB_TS_CR_TSPX_LOW (1 << 12)
+-#define UCB_TS_CR_TSMX_LOW (1 << 13)
+-
+-#define UCB_ADC_CR 0x0a
+-#define UCB_ADC_SYNC_ENA (1 << 0)
+-#define UCB_ADC_VREFBYP_CON (1 << 1)
+-#define UCB_ADC_INP_TSPX (0 << 2)
+-#define UCB_ADC_INP_TSMX (1 << 2)
+-#define UCB_ADC_INP_TSPY (2 << 2)
+-#define UCB_ADC_INP_TSMY (3 << 2)
+-#define UCB_ADC_INP_AD0 (4 << 2)
+-#define UCB_ADC_INP_AD1 (5 << 2)
+-#define UCB_ADC_INP_AD2 (6 << 2)
+-#define UCB_ADC_INP_AD3 (7 << 2)
+-#define UCB_ADC_EXT_REF (1 << 5)
+-#define UCB_ADC_START (1 << 7)
+-#define UCB_ADC_ENA (1 << 15)
+-
+-#define UCB_ADC_DATA 0x0b
+-#define UCB_ADC_DAT_VAL (1 << 15)
+-#define UCB_ADC_DAT(x) (((x) & 0x7fe0) >> 5)
+-
+-#define UCB_ID 0x0c
+-#define UCB_ID_1200 0x1004
+-#define UCB_ID_1300 0x1005
+-#define UCB_ID_TC35143 0x9712
+-
+-#define UCB_MODE 0x0d
+-#define UCB_MODE_DYN_VFLAG_ENA (1 << 12)
+-#define UCB_MODE_AUD_OFF_CAN (1 << 13)
+-
+-#include "mcp.h"
+-
+-struct ucb1x00_irq {
+- void *devid;
+- void (*fn)(int, void *);
+-};
+-
+-struct ucb1x00 {
+- spinlock_t lock;
+- struct mcp *mcp;
+- unsigned int irq;
+- struct semaphore adc_sem;
+- spinlock_t io_lock;
+- u16 id;
+- u16 io_dir;
+- u16 io_out;
+- u16 adc_cr;
+- u16 irq_fal_enbl;
+- u16 irq_ris_enbl;
+- struct ucb1x00_irq irq_handler[16];
+- struct class_device cdev;
+- struct list_head node;
+- struct list_head devs;
+-};
+-
+-struct ucb1x00_driver;
+-
+-struct ucb1x00_dev {
+- struct list_head dev_node;
+- struct list_head drv_node;
+- struct ucb1x00 *ucb;
+- struct ucb1x00_driver *drv;
+- void *priv;
+-};
+-
+-struct ucb1x00_driver {
+- struct list_head node;
+- struct list_head devs;
+- int (*add)(struct ucb1x00_dev *dev);
+- void (*remove)(struct ucb1x00_dev *dev);
+- int (*suspend)(struct ucb1x00_dev *dev, pm_message_t state);
+- int (*resume)(struct ucb1x00_dev *dev);
+-};
+-
+-#define classdev_to_ucb1x00(cd) container_of(cd, struct ucb1x00, cdev)
+-
+-int ucb1x00_register_driver(struct ucb1x00_driver *);
+-void ucb1x00_unregister_driver(struct ucb1x00_driver *);
+-
+-/**
+- * ucb1x00_clkrate - return the UCB1x00 SIB clock rate
+- * @ucb: UCB1x00 structure describing chip
+- *
+- * Return the SIB clock rate in Hz.
+- */
+-static inline unsigned int ucb1x00_clkrate(struct ucb1x00 *ucb)
+-{
+- return mcp_get_sclk_rate(ucb->mcp);
+-}
+-
+-/**
+- * ucb1x00_enable - enable the UCB1x00 SIB clock
+- * @ucb: UCB1x00 structure describing chip
+- *
+- * Enable the SIB clock. This can be called multiple times.
+- */
+-static inline void ucb1x00_enable(struct ucb1x00 *ucb)
+-{
+- mcp_enable(ucb->mcp);
+-}
+-
+-/**
+- * ucb1x00_disable - disable the UCB1x00 SIB clock
+- * @ucb: UCB1x00 structure describing chip
+- *
+- * Disable the SIB clock. The SIB clock will only be disabled
+- * when the number of ucb1x00_enable calls match the number of
+- * ucb1x00_disable calls.
+- */
+-static inline void ucb1x00_disable(struct ucb1x00 *ucb)
+-{
+- mcp_disable(ucb->mcp);
+-}
+-
+-/**
+- * ucb1x00_reg_write - write a UCB1x00 register
+- * @ucb: UCB1x00 structure describing chip
+- * @reg: UCB1x00 4-bit register index to write
+- * @val: UCB1x00 16-bit value to write
+- *
+- * Write the UCB1x00 register @reg with value @val. The SIB
+- * clock must be running for this function to return.
+- */
+-static inline void ucb1x00_reg_write(struct ucb1x00 *ucb, unsigned int reg, unsigned int val)
+-{
+- mcp_reg_write(ucb->mcp, reg, val);
+-}
+-
+-/**
+- * ucb1x00_reg_read - read a UCB1x00 register
+- * @ucb: UCB1x00 structure describing chip
+- * @reg: UCB1x00 4-bit register index to write
+- *
+- * Read the UCB1x00 register @reg and return its value. The SIB
+- * clock must be running for this function to return.
+- */
+-static inline unsigned int ucb1x00_reg_read(struct ucb1x00 *ucb, unsigned int reg)
+-{
+- return mcp_reg_read(ucb->mcp, reg);
+-}
+-/**
+- * ucb1x00_set_audio_divisor -
+- * @ucb: UCB1x00 structure describing chip
+- * @div: SIB clock divisor
+- */
+-static inline void ucb1x00_set_audio_divisor(struct ucb1x00 *ucb, unsigned int div)
+-{
+- mcp_set_audio_divisor(ucb->mcp, div);
+-}
+-
+-/**
+- * ucb1x00_set_telecom_divisor -
+- * @ucb: UCB1x00 structure describing chip
+- * @div: SIB clock divisor
+- */
+-static inline void ucb1x00_set_telecom_divisor(struct ucb1x00 *ucb, unsigned int div)
+-{
+- mcp_set_telecom_divisor(ucb->mcp, div);
+-}
+-
+-void ucb1x00_io_set_dir(struct ucb1x00 *ucb, unsigned int, unsigned int);
+-void ucb1x00_io_write(struct ucb1x00 *ucb, unsigned int, unsigned int);
+-unsigned int ucb1x00_io_read(struct ucb1x00 *ucb);
+-
+-#define UCB_NOSYNC (0)
+-#define UCB_SYNC (1)
+-
+-unsigned int ucb1x00_adc_read(struct ucb1x00 *ucb, int adc_channel, int sync);
+-void ucb1x00_adc_enable(struct ucb1x00 *ucb);
+-void ucb1x00_adc_disable(struct ucb1x00 *ucb);
+-
+-/*
+- * Which edges of the IRQ do you want to control today?
+- */
+-#define UCB_RISING (1 << 0)
+-#define UCB_FALLING (1 << 1)
+-
+-int ucb1x00_hook_irq(struct ucb1x00 *ucb, unsigned int idx, void (*fn)(int, void *), void *devid);
+-void ucb1x00_enable_irq(struct ucb1x00 *ucb, unsigned int idx, int edges);
+-void ucb1x00_disable_irq(struct ucb1x00 *ucb, unsigned int idx, int edges);
+-int ucb1x00_free_irq(struct ucb1x00 *ucb, unsigned int idx, void *devid);
+-
+-#endif
+Index: linux-2.6.24/sound/arm/Kconfig
+===================================================================
+--- linux-2.6.24.orig/sound/arm/Kconfig 2008-12-23 21:48:54.000000000 +0100
++++ linux-2.6.24/sound/arm/Kconfig 2008-12-23 21:50:13.000000000 +0100
+@@ -14,6 +14,16 @@
+ To compile this driver as a module, choose M here: the module
+ will be called snd-sa11xx-uda1341.
+
++config SND_SA11XX_UCB1X00
++ tristate "SA11xx UCB1x00 driver (Simpad)"
++ depends on ARCH_SA1100 && SND
++ select SND_PCM
++ help
++ Say Y here if you have a Simpad handheld computer
++
++ To compile this driver as a module, choose M here: the module
++ will be called snd-sa11xx-ucb1x00.
++
+ config SND_ARMAACI
+ tristate "ARM PrimeCell PL041 AC Link support"
+ depends on SND && ARM_AMBA
+Index: linux-2.6.24/sound/arm/Makefile
+===================================================================
+--- linux-2.6.24.orig/sound/arm/Makefile 2008-12-23 21:48:56.000000000 +0100
++++ linux-2.6.24/sound/arm/Makefile 2008-12-23 21:57:32.000000000 +0100
+@@ -5,6 +5,9 @@
+ obj-$(CONFIG_SND_SA11XX_UDA1341) += snd-sa11xx-uda1341.o
+ snd-sa11xx-uda1341-objs := sa11xx-uda1341.o
+
++obj-$(CONFIG_SND_SA11XX_UCB1X00) += snd-sa11xx-ucb1x00.o
++snd-sa11xx-ucb1x00-objs := sa11xx-ucb1x00.o
++
+ obj-$(CONFIG_SND_ARMAACI) += snd-aaci.o
+ snd-aaci-objs := aaci.o devdma.o
+
+Index: linux-2.6.24/drivers/mfd/ucb1x00-assabet.c
+===================================================================
+--- linux-2.6.24.orig/drivers/mfd/ucb1x00-assabet.c 2008-12-23 22:03:30.000000000 +0100
++++ linux-2.6.24/drivers/mfd/ucb1x00-assabet.c 2008-12-23 22:03:50.000000000 +0100
+@@ -17,7 +17,7 @@
+
+ #include <asm/dma.h>
+
+-#include "ucb1x00.h"
++#include <linux/ucb1x00.h>
+
+ #define UCB1X00_ATTR(name,input)\
+ static ssize_t name##_show(struct class_device *dev, char *buf) \
+Index: linux-2.6.24/drivers/mfd/ucb1x00-core.c
+===================================================================
+--- linux-2.6.24.orig/drivers/mfd/ucb1x00-core.c 2008-12-23 22:03:02.000000000 +0100
++++ linux-2.6.24/drivers/mfd/ucb1x00-core.c 2008-12-23 22:09:00.000000000 +0100
+@@ -28,7 +28,7 @@
+ #include <asm/dma.h>
+ #include <asm/hardware.h>
+
+-#include "ucb1x00.h"
++#include <linux/mfd/ucb1x00.h>
+
+ static DEFINE_MUTEX(ucb1x00_mutex);
+ static LIST_HEAD(ucb1x00_drivers);
+Index: linux-2.6.24/drivers/mfd/ucb1x00-switches.c
+===================================================================
+--- linux-2.6.24.orig/drivers/mfd/ucb1x00-switches.c 2008-12-23 22:03:36.000000000 +0100
++++ linux-2.6.24/drivers/mfd/ucb1x00-switches.c 2008-12-23 22:09:19.000000000 +0100
+@@ -35,7 +35,7 @@
+
+ #include <asm/dma.h>
+
+-#include "ucb1x00.h"
++#include <linux/mfd/ucb1x00.h>
+
+ #define KEY_PRESS 1
+ #define KEY_RELEASE 0
+Index: linux-2.6.24/drivers/mfd/ucb1x00-ts.c
+===================================================================
+--- linux-2.6.24.orig/drivers/mfd/ucb1x00-ts.c 2008-12-23 22:03:40.000000000 +0100
++++ linux-2.6.24/drivers/mfd/ucb1x00-ts.c 2008-12-23 22:09:11.000000000 +0100
+@@ -40,7 +40,7 @@
+ #include <asm/arch/collie.h>
+ #include <asm/mach-types.h>
+
+-#include "ucb1x00.h"
++#include <linux/mfd/ucb1x00.h>
+
+
+ struct ucb1x00_ts {
+Index: linux-2.6.24/include/linux/mfd/mcp.h
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.24/include/linux/mfd/mcp.h 2008-12-23 22:06:04.000000000 +0100
+@@ -0,0 +1,66 @@
++/*
++ * linux/drivers/mfd/mcp.h
++ *
++ * Copyright (C) 2001 Russell King, All Rights Reserved.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License.
++ */
++#ifndef MCP_H
++#define MCP_H
++
++struct mcp_ops;
++
++struct mcp {
++ struct module *owner;
++ struct mcp_ops *ops;
++ spinlock_t lock;
++ int use_count;
++ unsigned int sclk_rate;
++ unsigned int rw_timeout;
++ dma_device_t dma_audio_rd;
++ dma_device_t dma_audio_wr;
++ dma_device_t dma_telco_rd;
++ dma_device_t dma_telco_wr;
++ struct device attached_device;
++};
++
++struct mcp_ops {
++ void (*set_telecom_divisor)(struct mcp *, unsigned int);
++ void (*set_audio_divisor)(struct mcp *, unsigned int);
++ void (*reg_write)(struct mcp *, unsigned int, unsigned int);
++ unsigned int (*reg_read)(struct mcp *, unsigned int);
++ void (*enable)(struct mcp *);
++ void (*disable)(struct mcp *);
++};
++
++void mcp_set_telecom_divisor(struct mcp *, unsigned int);
++void mcp_set_audio_divisor(struct mcp *, unsigned int);
++void mcp_reg_write(struct mcp *, unsigned int, unsigned int);
++unsigned int mcp_reg_read(struct mcp *, unsigned int);
++void mcp_enable(struct mcp *);
++void mcp_disable(struct mcp *);
++#define mcp_get_sclk_rate(mcp) ((mcp)->sclk_rate)
++
++struct mcp *mcp_host_alloc(struct device *, size_t);
++int mcp_host_register(struct mcp *);
++void mcp_host_unregister(struct mcp *);
++
++struct mcp_driver {
++ struct device_driver drv;
++ int (*probe)(struct mcp *);
++ void (*remove)(struct mcp *);
++ int (*suspend)(struct mcp *, pm_message_t);
++ int (*resume)(struct mcp *);
++};
++
++int mcp_driver_register(struct mcp_driver *);
++void mcp_driver_unregister(struct mcp_driver *);
++
++#define mcp_get_drvdata(mcp) dev_get_drvdata(&(mcp)->attached_device)
++#define mcp_set_drvdata(mcp,d) dev_set_drvdata(&(mcp)->attached_device, d)
++
++#define mcp_priv(mcp) ((void *)((mcp)+1))
++
++#endif
+Index: linux-2.6.24/drivers/mfd/mcp.h
+===================================================================
+--- linux-2.6.24.orig/drivers/mfd/mcp.h 2008-12-23 22:06:30.000000000 +0100
++++ /dev/null 1970-01-01 00:00:00.000000000 +0000
+@@ -1,66 +0,0 @@
+-/*
+- * linux/drivers/mfd/mcp.h
+- *
+- * Copyright (C) 2001 Russell King, All Rights Reserved.
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License.
+- */
+-#ifndef MCP_H
+-#define MCP_H
+-
+-struct mcp_ops;
+-
+-struct mcp {
+- struct module *owner;
+- struct mcp_ops *ops;
+- spinlock_t lock;
+- int use_count;
+- unsigned int sclk_rate;
+- unsigned int rw_timeout;
+- dma_device_t dma_audio_rd;
+- dma_device_t dma_audio_wr;
+- dma_device_t dma_telco_rd;
+- dma_device_t dma_telco_wr;
+- struct device attached_device;
+-};
+-
+-struct mcp_ops {
+- void (*set_telecom_divisor)(struct mcp *, unsigned int);
+- void (*set_audio_divisor)(struct mcp *, unsigned int);
+- void (*reg_write)(struct mcp *, unsigned int, unsigned int);
+- unsigned int (*reg_read)(struct mcp *, unsigned int);
+- void (*enable)(struct mcp *);
+- void (*disable)(struct mcp *);
+-};
+-
+-void mcp_set_telecom_divisor(struct mcp *, unsigned int);
+-void mcp_set_audio_divisor(struct mcp *, unsigned int);
+-void mcp_reg_write(struct mcp *, unsigned int, unsigned int);
+-unsigned int mcp_reg_read(struct mcp *, unsigned int);
+-void mcp_enable(struct mcp *);
+-void mcp_disable(struct mcp *);
+-#define mcp_get_sclk_rate(mcp) ((mcp)->sclk_rate)
+-
+-struct mcp *mcp_host_alloc(struct device *, size_t);
+-int mcp_host_register(struct mcp *);
+-void mcp_host_unregister(struct mcp *);
+-
+-struct mcp_driver {
+- struct device_driver drv;
+- int (*probe)(struct mcp *);
+- void (*remove)(struct mcp *);
+- int (*suspend)(struct mcp *, pm_message_t);
+- int (*resume)(struct mcp *);
+-};
+-
+-int mcp_driver_register(struct mcp_driver *);
+-void mcp_driver_unregister(struct mcp_driver *);
+-
+-#define mcp_get_drvdata(mcp) dev_get_drvdata(&(mcp)->attached_device)
+-#define mcp_set_drvdata(mcp,d) dev_set_drvdata(&(mcp)->attached_device, d)
+-
+-#define mcp_priv(mcp) ((void *)((mcp)+1))
+-
+-#endif
+Index: linux-2.6.24/drivers/mfd/mcp-core.c
+===================================================================
+--- linux-2.6.24.orig/drivers/mfd/mcp-core.c 2008-12-23 22:07:01.000000000 +0100
++++ linux-2.6.24/drivers/mfd/mcp-core.c 2008-12-23 22:07:23.000000000 +0100
+@@ -21,7 +21,7 @@
+ #include <asm/dma.h>
+ #include <asm/system.h>
+
+-#include "mcp.h"
++#include <linux/mfd/mcp.h>
+
+ #define to_mcp(d) container_of(d, struct mcp, attached_device)
+ #define to_mcp_driver(d) container_of(d, struct mcp_driver, drv)
+Index: linux-2.6.24/drivers/mfd/mcp-sa11x0.c
+===================================================================
+--- linux-2.6.24.orig/drivers/mfd/mcp-sa11x0.c 2008-12-23 22:07:06.000000000 +0100
++++ linux-2.6.24/drivers/mfd/mcp-sa11x0.c 2008-12-23 22:07:33.000000000 +0100
+@@ -28,7 +28,7 @@
+
+ #include <asm/arch/assabet.h>
+
+-#include "mcp.h"
++#include <linux/mfd/mcp.h>
+
+ struct mcp_sa11x0 {
+ u32 mccr0;
+Index: linux-2.6.24/include/linux/mfd/ucb1x00.h
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.24/include/linux/mfd/ucb1x00.h 2008-12-23 22:08:46.000000000 +0100
+@@ -0,0 +1,255 @@
++/*
++ * linux/drivers/mfd/ucb1x00.h
++ *
++ * Copyright (C) 2001 Russell King, All Rights Reserved.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License.
++ */
++#ifndef UCB1200_H
++#define UCB1200_H
++
++#define UCB_IO_DATA 0x00
++#define UCB_IO_DIR 0x01
++
++#define UCB_IO_0 (1 << 0)
++#define UCB_IO_1 (1 << 1)
++#define UCB_IO_2 (1 << 2)
++#define UCB_IO_3 (1 << 3)
++#define UCB_IO_4 (1 << 4)
++#define UCB_IO_5 (1 << 5)
++#define UCB_IO_6 (1 << 6)
++#define UCB_IO_7 (1 << 7)
++#define UCB_IO_8 (1 << 8)
++#define UCB_IO_9 (1 << 9)
++
++#define UCB_IE_RIS 0x02
++#define UCB_IE_FAL 0x03
++#define UCB_IE_STATUS 0x04
++#define UCB_IE_CLEAR 0x04
++#define UCB_IE_ADC (1 << 11)
++#define UCB_IE_TSPX (1 << 12)
++#define UCB_IE_TSMX (1 << 13)
++#define UCB_IE_TCLIP (1 << 14)
++#define UCB_IE_ACLIP (1 << 15)
++
++#define UCB_IRQ_TSPX 12
++
++#define UCB_TC_A 0x05
++#define UCB_TC_A_LOOP (1 << 7) /* UCB1200 */
++#define UCB_TC_A_AMPL (1 << 7) /* UCB1300 */
++
++#define UCB_TC_B 0x06
++#define UCB_TC_B_VOICE_ENA (1 << 3)
++#define UCB_TC_B_CLIP (1 << 4)
++#define UCB_TC_B_ATT (1 << 6)
++#define UCB_TC_B_SIDE_ENA (1 << 11)
++#define UCB_TC_B_MUTE (1 << 13)
++#define UCB_TC_B_IN_ENA (1 << 14)
++#define UCB_TC_B_OUT_ENA (1 << 15)
++
++#define UCB_AC_A 0x07
++#define UCB_AC_B 0x08
++#define UCB_AC_B_LOOP (1 << 8)
++#define UCB_AC_B_MUTE (1 << 13)
++#define UCB_AC_B_IN_ENA (1 << 14)
++#define UCB_AC_B_OUT_ENA (1 << 15)
++
++#define UCB_TS_CR 0x09
++#define UCB_TS_CR_TSMX_POW (1 << 0)
++#define UCB_TS_CR_TSPX_POW (1 << 1)
++#define UCB_TS_CR_TSMY_POW (1 << 2)
++#define UCB_TS_CR_TSPY_POW (1 << 3)
++#define UCB_TS_CR_TSMX_GND (1 << 4)
++#define UCB_TS_CR_TSPX_GND (1 << 5)
++#define UCB_TS_CR_TSMY_GND (1 << 6)
++#define UCB_TS_CR_TSPY_GND (1 << 7)
++#define UCB_TS_CR_MODE_INT (0 << 8)
++#define UCB_TS_CR_MODE_PRES (1 << 8)
++#define UCB_TS_CR_MODE_POS (2 << 8)
++#define UCB_TS_CR_BIAS_ENA (1 << 11)
++#define UCB_TS_CR_TSPX_LOW (1 << 12)
++#define UCB_TS_CR_TSMX_LOW (1 << 13)
++
++#define UCB_ADC_CR 0x0a
++#define UCB_ADC_SYNC_ENA (1 << 0)
++#define UCB_ADC_VREFBYP_CON (1 << 1)
++#define UCB_ADC_INP_TSPX (0 << 2)
++#define UCB_ADC_INP_TSMX (1 << 2)
++#define UCB_ADC_INP_TSPY (2 << 2)
++#define UCB_ADC_INP_TSMY (3 << 2)
++#define UCB_ADC_INP_AD0 (4 << 2)
++#define UCB_ADC_INP_AD1 (5 << 2)
++#define UCB_ADC_INP_AD2 (6 << 2)
++#define UCB_ADC_INP_AD3 (7 << 2)
++#define UCB_ADC_EXT_REF (1 << 5)
++#define UCB_ADC_START (1 << 7)
++#define UCB_ADC_ENA (1 << 15)
++
++#define UCB_ADC_DATA 0x0b
++#define UCB_ADC_DAT_VAL (1 << 15)
++#define UCB_ADC_DAT(x) (((x) & 0x7fe0) >> 5)
++
++#define UCB_ID 0x0c
++#define UCB_ID_1200 0x1004
++#define UCB_ID_1300 0x1005
++#define UCB_ID_TC35143 0x9712
++
++#define UCB_MODE 0x0d
++#define UCB_MODE_DYN_VFLAG_ENA (1 << 12)
++#define UCB_MODE_AUD_OFF_CAN (1 << 13)
++
++#include "mcp.h"
++
++struct ucb1x00_irq {
++ void *devid;
++ void (*fn)(int, void *);
++};
++
++struct ucb1x00 {
++ spinlock_t lock;
++ struct mcp *mcp;
++ unsigned int irq;
++ struct semaphore adc_sem;
++ spinlock_t io_lock;
++ u16 id;
++ u16 io_dir;
++ u16 io_out;
++ u16 adc_cr;
++ u16 irq_fal_enbl;
++ u16 irq_ris_enbl;
++ struct ucb1x00_irq irq_handler[16];
++ struct class_device cdev;
++ struct list_head node;
++ struct list_head devs;
++};
++
++struct ucb1x00_driver;
++
++struct ucb1x00_dev {
++ struct list_head dev_node;
++ struct list_head drv_node;
++ struct ucb1x00 *ucb;
++ struct ucb1x00_driver *drv;
++ void *priv;
++};
++
++struct ucb1x00_driver {
++ struct list_head node;
++ struct list_head devs;
++ int (*add)(struct ucb1x00_dev *dev);
++ void (*remove)(struct ucb1x00_dev *dev);
++ int (*suspend)(struct ucb1x00_dev *dev, pm_message_t state);
++ int (*resume)(struct ucb1x00_dev *dev);
++};
++
++#define classdev_to_ucb1x00(cd) container_of(cd, struct ucb1x00, cdev)
++
++int ucb1x00_register_driver(struct ucb1x00_driver *);
++void ucb1x00_unregister_driver(struct ucb1x00_driver *);
++
++/**
++ * ucb1x00_clkrate - return the UCB1x00 SIB clock rate
++ * @ucb: UCB1x00 structure describing chip
++ *
++ * Return the SIB clock rate in Hz.
++ */
++static inline unsigned int ucb1x00_clkrate(struct ucb1x00 *ucb)
++{
++ return mcp_get_sclk_rate(ucb->mcp);
++}
++
++/**
++ * ucb1x00_enable - enable the UCB1x00 SIB clock
++ * @ucb: UCB1x00 structure describing chip
++ *
++ * Enable the SIB clock. This can be called multiple times.
++ */
++static inline void ucb1x00_enable(struct ucb1x00 *ucb)
++{
++ mcp_enable(ucb->mcp);
++}
++
++/**
++ * ucb1x00_disable - disable the UCB1x00 SIB clock
++ * @ucb: UCB1x00 structure describing chip
++ *
++ * Disable the SIB clock. The SIB clock will only be disabled
++ * when the number of ucb1x00_enable calls match the number of
++ * ucb1x00_disable calls.
++ */
++static inline void ucb1x00_disable(struct ucb1x00 *ucb)
++{
++ mcp_disable(ucb->mcp);
++}
++
++/**
++ * ucb1x00_reg_write - write a UCB1x00 register
++ * @ucb: UCB1x00 structure describing chip
++ * @reg: UCB1x00 4-bit register index to write
++ * @val: UCB1x00 16-bit value to write
++ *
++ * Write the UCB1x00 register @reg with value @val. The SIB
++ * clock must be running for this function to return.
++ */
++static inline void ucb1x00_reg_write(struct ucb1x00 *ucb, unsigned int reg, unsigned int val)
++{
++ mcp_reg_write(ucb->mcp, reg, val);
++}
++
++/**
++ * ucb1x00_reg_read - read a UCB1x00 register
++ * @ucb: UCB1x00 structure describing chip
++ * @reg: UCB1x00 4-bit register index to write
++ *
++ * Read the UCB1x00 register @reg and return its value. The SIB
++ * clock must be running for this function to return.
++ */
++static inline unsigned int ucb1x00_reg_read(struct ucb1x00 *ucb, unsigned int reg)
++{
++ return mcp_reg_read(ucb->mcp, reg);
++}
++/**
++ * ucb1x00_set_audio_divisor -
++ * @ucb: UCB1x00 structure describing chip
++ * @div: SIB clock divisor
++ */
++static inline void ucb1x00_set_audio_divisor(struct ucb1x00 *ucb, unsigned int div)
++{
++ mcp_set_audio_divisor(ucb->mcp, div);
++}
++
++/**
++ * ucb1x00_set_telecom_divisor -
++ * @ucb: UCB1x00 structure describing chip
++ * @div: SIB clock divisor
++ */
++static inline void ucb1x00_set_telecom_divisor(struct ucb1x00 *ucb, unsigned int div)
++{
++ mcp_set_telecom_divisor(ucb->mcp, div);
++}
++
++void ucb1x00_io_set_dir(struct ucb1x00 *ucb, unsigned int, unsigned int);
++void ucb1x00_io_write(struct ucb1x00 *ucb, unsigned int, unsigned int);
++unsigned int ucb1x00_io_read(struct ucb1x00 *ucb);
++
++#define UCB_NOSYNC (0)
++#define UCB_SYNC (1)
++
++unsigned int ucb1x00_adc_read(struct ucb1x00 *ucb, int adc_channel, int sync);
++void ucb1x00_adc_enable(struct ucb1x00 *ucb);
++void ucb1x00_adc_disable(struct ucb1x00 *ucb);
++
++/*
++ * Which edges of the IRQ do you want to control today?
++ */
++#define UCB_RISING (1 << 0)
++#define UCB_FALLING (1 << 1)
++
++int ucb1x00_hook_irq(struct ucb1x00 *ucb, unsigned int idx, void (*fn)(int, void *), void *devid);
++void ucb1x00_enable_irq(struct ucb1x00 *ucb, unsigned int idx, int edges);
++void ucb1x00_disable_irq(struct ucb1x00 *ucb, unsigned int idx, int edges);
++int ucb1x00_free_irq(struct ucb1x00 *ucb, unsigned int idx, void *devid);
++
++#endif
+Index: linux-2.6.24/drivers/mfd/ucb1x00-simpad.c
+===================================================================
+--- linux-2.6.24.orig/drivers/mfd/ucb1x00-simpad.c 2008-12-23 22:09:59.000000000 +0100
++++ linux-2.6.24/drivers/mfd/ucb1x00-simpad.c 2008-12-23 22:10:12.000000000 +0100
+@@ -26,7 +26,7 @@
+ #include <asm/arch/simpad.h>
+ #include <asm/arch-sa1100/simpad_pm.h>
+
+-#include "ucb1x00.h"
++#include <linux/mfd/ucb1x00.h>
+ #include "ucb1x00-simpad.h"
+
+ #define UCB1X00_ATTR(name,input,designation) \ \ No newline at end of file
diff --git a/recipes/linux/linux/simpad/linux-2.6.24-SIMpad-ucb1x00-switches.patch b/recipes/linux/linux/simpad/linux-2.6.24-SIMpad-ucb1x00-switches.patch
new file mode 100644
index 0000000000..20cb56d11b
--- /dev/null
+++ b/recipes/linux/linux/simpad/linux-2.6.24-SIMpad-ucb1x00-switches.patch
@@ -0,0 +1,359 @@
+diff -Nur linux-2.6.24.vanilla/drivers/mfd/Kconfig linux-2.6.24/drivers/mfd/Kconfig
+--- linux-2.6.24.vanilla/drivers/mfd/Kconfig 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24/drivers/mfd/Kconfig 2008-02-20 21:17:07.000000000 +0100
+@@ -38,4 +38,7 @@
+ tristate "Touchscreen interface support"
+ depends on MCP_UCB1200 && INPUT
+
++config MCP_UCB1200_SWITCHES
++ tristate "SIMpad Switches support"
++ depends on MCP_UCB1200 && INPUT
+ endmenu
+diff -Nur linux-2.6.24.vanilla/drivers/mfd/Makefile linux-2.6.24/drivers/mfd/Makefile
+--- linux-2.6.24.vanilla/drivers/mfd/Makefile 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24/drivers/mfd/Makefile 2008-02-20 21:17:07.000000000 +0100
+@@ -8,7 +8,7 @@
+ obj-$(CONFIG_MCP_SA11X0) += mcp-sa11x0.o
+ obj-$(CONFIG_MCP_UCB1200) += ucb1x00-core.o
+ obj-$(CONFIG_MCP_UCB1200_TS) += ucb1x00-ts.o
+-
++obj-$(CONFIG_MCP_UCB1200_SWITCHES) += ucb1x00-switches.o
+ ifeq ($(CONFIG_SA1100_ASSABET),y)
+ obj-$(CONFIG_MCP_UCB1200) += ucb1x00-assabet.o
+ endif
+diff -Nur linux-2.6.24.vanilla/drivers/mfd/ucb1x00-switches.c linux-2.6.24/drivers/mfd/ucb1x00-switches.c
+--- linux-2.6.24.vanilla/drivers/mfd/ucb1x00-switches.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24/drivers/mfd/ucb1x00-switches.c 2008-02-20 21:17:07.000000000 +0100
+@@ -0,0 +1,332 @@
++/*
++ * linux/drivers/mfd/ucb1x00-switches.c
++ *
++ * Copyright (C) 2007 Bernhard Guillon.
++ *
++ * 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.
++ *
++ * This driver is for the Switches of Siemens SIMpad (CL4,SL4,SLC), T-Sinus-Pad and
++ * Swisscom WP50 devices.
++ *
++ * Six switches are routed to GPIO pins on the UCB1300: S3 -- S8.
++ *
++ * This driver is based on the 2.4 ucb1x00-switches, the 2.6 ucb1x00-assabet
++ * and the ucb1x00-ts driver.
++ *
++ * 2007/06/21 mrdata:
++ * - create new thread kswd() to handle irq_events for ucb1300-gpio's
++ * - found out, that not every key-press or key-release
++ * generate a irq_event
++ * -> establish key_state handling
++ * key_state, key_state_last <-> KEY_PRESS, KEY_RELEASE
++ * -> after irq_event polling the ucb1300-gpio's till all keys
++ * in key_state = KEY_RELEASE
++ *
++ */
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/input.h>
++#include <linux/device.h>
++#include <linux/sched.h>
++#include <linux/freezer.h>
++#include <linux/kthread.h>
++
++#include <asm/dma.h>
++
++#include "ucb1x00.h"
++
++#define KEY_PRESS 1
++#define KEY_RELEASE 0
++
++static int key [6] = { KEY_PROG1,KEY_PROG2,KEY_UP,KEY_DOWN,KEY_LEFT,KEY_RIGHT };
++
++static unsigned short int key_state [6] = { 0, 0, 0, 0, 0, 0};
++static unsigned short int key_state_last [6] = { 1, 1, 1, 1, 1, 1};
++
++struct ucb1x00_switches {
++ struct input_dev *idev;
++ struct ucb1x00 *ucb;
++
++ wait_queue_head_t irq_wait;
++ struct task_struct *rtask;
++
++ int idx;
++
++ unsigned int valid:1;
++};
++
++static int ucb1x00_thread(void *_switches_id)
++{
++ unsigned short int this;
++ int idx_tmp;
++ int i;
++ struct ucb1x00_switches *switches = _switches_id;
++ struct input_dev *idev = switches->idev;
++ struct task_struct *tsk = current;
++ DECLARE_WAITQUEUE(wait, tsk);
++
++ add_wait_queue(&switches->irq_wait, &wait);
++
++ while (!kthread_should_stop())
++ {
++ signed long timeout;
++
++ if ((switches->idx >= 0) && (switches->idx <= 5) && (switches->valid == 1))
++ {
++ switches->valid = 0;
++
++ idx_tmp = switches->idx;
++
++ ucb1x00_enable(switches->ucb);
++
++ this = ~ucb1x00_io_read(switches->ucb);
++
++ ucb1x00_disable(switches->ucb);
++
++ if (key_state[idx_tmp] == KEY_RELEASE)
++ {
++ key_state_last[idx_tmp] = KEY_RELEASE;
++ key_state[idx_tmp] = KEY_PRESS;
++
++ input_report_key(idev, key[idx_tmp], KEY_PRESS);
++ input_sync(idev);
++ }
++
++ for (i = 0; i < 6; i++)
++ {
++ if ((key_state[i] == KEY_RELEASE) && (((this & (1 << i)) ? 1 : 0) == KEY_PRESS))
++ {
++ key_state_last[i] = KEY_RELEASE;
++ key_state[i] = KEY_PRESS;
++
++ input_report_key(idev, key[i], KEY_PRESS);
++ input_sync(idev);
++ }
++ }
++
++ for(;;)
++ {
++ ucb1x00_enable(switches->ucb);
++ this = ~ucb1x00_io_read(switches->ucb);
++ ucb1x00_disable(switches->ucb);
++
++ for (i = 0; i < 6; i++)
++ {
++ if ((key_state[i] == KEY_PRESS) && (((this & (1 << i)) ? 1 : 0) == KEY_RELEASE))
++ {
++ key_state_last[i] = KEY_PRESS;
++ key_state[i] = KEY_RELEASE;
++
++ input_report_key(idev, key[i], KEY_RELEASE);
++ input_sync(idev);
++ }
++
++ if ((key_state[i] == KEY_RELEASE) && (((this & (1 << i)) ? 1 : 0) == KEY_PRESS))
++ {
++ key_state_last[i] = KEY_RELEASE;
++ key_state[i] = KEY_PRESS;
++
++ input_report_key(idev, key[i], KEY_PRESS);
++ input_sync(idev);
++ }
++
++ }
++
++ // left loop, if no key press detect
++ if ((this | 0xff80) == 0xff80)
++ {
++ break;
++ }
++
++ set_task_state(tsk, TASK_INTERRUPTIBLE);
++
++ try_to_freeze();
++
++ timeout = HZ / 100;
++
++ schedule_timeout(timeout);
++ }
++ }
++
++ set_task_state(tsk, TASK_INTERRUPTIBLE);
++
++ try_to_freeze();
++
++ timeout = MAX_SCHEDULE_TIMEOUT;
++
++ schedule_timeout(timeout);
++ }
++
++ remove_wait_queue(&switches->irq_wait, &wait);
++
++ switches->rtask = NULL;
++
++ return 0;
++}
++
++
++static void ucb1x00_dev_irq(int idx, void *id)
++{
++ struct ucb1x00_switches *switches = id;
++
++ switches->idx = idx;
++ switches->valid = 1;
++
++ wake_up(&switches->irq_wait);
++}
++
++static int ucb1x00_switches_add(struct ucb1x00_dev *dev)
++{
++ struct ucb1x00_switches *switches;
++ struct input_dev *idev;
++ int err,i;
++
++ switches = kzalloc(sizeof(struct ucb1x00_switches), GFP_KERNEL);
++ idev = input_allocate_device();
++
++ if (!switches || !idev) {
++ err = -ENOMEM;
++ goto fail;
++ }
++
++ switches->ucb = dev->ucb;
++
++ idev->private = switches;
++ idev->name = "SIMpad Switches";
++ idev->id.product = switches->ucb->id;
++
++ __set_bit(EV_KEY, idev->evbit);
++ __set_bit(EV_REP, idev->evbit);
++ __set_bit(KEY_PROG1, idev->keybit);
++ __set_bit(KEY_PROG2, idev->keybit);
++ __set_bit(KEY_UP, idev->keybit);
++ __set_bit(KEY_DOWN, idev->keybit);
++ __set_bit(KEY_LEFT, idev->keybit);
++ __set_bit(KEY_RIGHT, idev->keybit);
++
++ err = input_register_device(idev);
++ if (err)
++ goto fail;
++ switches->idev = idev;
++ dev->priv = switches;
++
++ BUG_ON(switches->rtask);
++
++ init_waitqueue_head(&switches->irq_wait);
++
++ ucb1x00_enable(switches->ucb);
++
++ ucb1x00_io_set_dir(switches->ucb,
++ UCB_IO_0 | UCB_IO_1 | UCB_IO_2 |
++ UCB_IO_3 | UCB_IO_4 | UCB_IO_5,
++ UCB_IO_8 | UCB_IO_9);
++
++ ucb1x00_disable(switches->ucb);
++
++ for (i = 0; i < 6; ++i) {
++ ucb1x00_enable_irq(switches->ucb, i, UCB_RISING | UCB_FALLING);
++
++ if (ucb1x00_hook_irq(switches->ucb, i, ucb1x00_dev_irq, switches) < 0) {
++ printk(KERN_ERR "unable to hook IRQ for "
++ "UCB1300 SWITCH_%d\n", i);
++ return -EBUSY;
++ }
++ }
++
++ switches->rtask = kthread_run(ucb1x00_thread, switches, "kswd");
++ if (!IS_ERR(switches->rtask))
++ {
++ return 0;
++ }
++ else
++ {
++ input_unregister_device(switches->idev);
++
++ for (i = 5; i >= 0; --i) {
++ ucb1x00_disable_irq(switches->ucb, i, UCB_RISING | UCB_FALLING);
++
++ /* Only error conditions are ENOENT and EINVAL; silently
++ * ignore:
++ */
++ ucb1x00_free_irq(switches->ucb, i, NULL);
++ }
++ switches->rtask = NULL;
++ ucb1x00_disable(switches->ucb);
++ kfree(switches);
++
++ return -EFAULT;
++ }
++
++fail:
++ input_free_device(idev);
++ kfree(switches);
++ return err;
++
++}
++
++static void ucb1x00_switches_remove(struct ucb1x00_dev *dev)
++{
++ int i;
++ struct ucb1x00_switches *switches = dev->priv;
++
++ if (switches->rtask)
++ kthread_stop(switches->rtask);
++
++ switches->rtask = NULL;
++
++ input_unregister_device(switches->idev);
++
++ for (i = 5; i >= 0; --i) {
++ ucb1x00_disable_irq(switches->ucb, i, UCB_RISING | UCB_FALLING);
++
++ /* Only error conditions are ENOENT and EINVAL; silently
++ * ignore:
++ */
++ ucb1x00_free_irq(switches->ucb, i, NULL);
++ }
++ ucb1x00_disable(switches->ucb);
++ kfree(switches);
++}
++
++#ifdef CONFIG_PM
++static int ucb1x00_switches_resume(struct ucb1x00_dev *dev)
++{
++ struct ucb1x00_switches *switches = dev->priv;
++
++ if (switches->rtask != NULL)
++ {
++ switches->valid = 0;
++ wake_up(&switches->irq_wait);
++
++ printk(KERN_DEBUG "ucb1x00-switches.c -> _switches_resume() kswd - restart *DONE*\n");
++ }
++ return 0;
++}
++#else
++#define ucb1x00_switches_resume NULL
++#endif
++
++static struct ucb1x00_driver ucb1x00_switches_driver = {
++ .add = ucb1x00_switches_add,
++ .remove = ucb1x00_switches_remove,
++ .resume = ucb1x00_switches_resume,
++};
++
++static int __init ucb1x00_switches_init(void)
++{
++ return ucb1x00_register_driver(&ucb1x00_switches_driver);
++}
++
++static void __exit ucb1x00_switches_exit(void)
++{
++ ucb1x00_unregister_driver(&ucb1x00_switches_driver);
++}
++
++module_init(ucb1x00_switches_init);
++module_exit(ucb1x00_switches_exit);
++
++MODULE_AUTHOR("Bernhard Guillon <Bernhard.Guillon@opensimpad.org>");
++MODULE_DESCRIPTION("UCB1x00 Switches driver for Siemens SIMpad");
++MODULE_LICENSE("GPL");
diff --git a/recipes/linux/linux/simpad/linux-2.6.24-SIMpad-ucb1x00-ts-supend-and-accuracy.patch b/recipes/linux/linux/simpad/linux-2.6.24-SIMpad-ucb1x00-ts-supend-and-accuracy.patch
new file mode 100644
index 0000000000..702bbfbfba
--- /dev/null
+++ b/recipes/linux/linux/simpad/linux-2.6.24-SIMpad-ucb1x00-ts-supend-and-accuracy.patch
@@ -0,0 +1,121 @@
+diff -Nur linux-2.6.24.vanilla/drivers/mfd/ucb1x00-ts.c linux-2.6.24/drivers/mfd/ucb1x00-ts.c
+--- linux-2.6.24.vanilla/drivers/mfd/ucb1x00-ts.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24/drivers/mfd/ucb1x00-ts.c 2008-02-20 21:21:51.000000000 +0100
+@@ -16,6 +16,10 @@
+ * It is important to note that the signal connected to the ADCSYNC
+ * pin should provide pulses even when the LCD is blanked, otherwise
+ * a pen touch needed to unblank the LCD will never be read.
++ *
++ * mrdata: -added some accuracy improvement based on thesings collie patch
++ * -added suspend fix
++ *
+ */
+ #include <linux/module.h>
+ #include <linux/moduleparam.h>
+@@ -104,6 +108,8 @@
+ UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_GND |
+ UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
+
++ udelay(55);
++
+ return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPY, ts->adcsync);
+ }
+ }
+@@ -130,7 +136,7 @@
+ UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
+ UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA);
+
+- udelay(55);
++ udelay(165);
+
+ return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPY, ts->adcsync);
+ }
+@@ -158,7 +164,7 @@
+ UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
+ UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA);
+
+- udelay(55);
++ udelay(165);
+
+ return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPX, ts->adcsync);
+ }
+@@ -216,13 +222,17 @@
+ signed long timeout;
+
+ ts->restart = 0;
+-
++
+ ucb1x00_adc_enable(ts->ucb);
+
+ x = ucb1x00_ts_read_xpos(ts);
++ ucb1x00_adc_disable(ts->ucb);
++ ucb1x00_adc_enable(ts->ucb);
+ y = ucb1x00_ts_read_ypos(ts);
++ ucb1x00_adc_disable(ts->ucb);
++ ucb1x00_adc_enable(ts->ucb);
+ p = ucb1x00_ts_read_pressure(ts);
+-
++
+ /*
+ * Switch back to interrupt mode.
+ */
+@@ -231,15 +241,19 @@
+
+ msleep(10);
+
++ if ((x < 60) || (y < 60)) {
++ p = 0;
++ }
++
+ ucb1x00_enable(ts->ucb);
+
+-
+ if (ucb1x00_ts_pen_down(ts)) {
++
+ set_task_state(tsk, TASK_INTERRUPTIBLE);
+
+ ucb1x00_enable_irq(ts->ucb, UCB_IRQ_TSPX, machine_is_collie() ? UCB_RISING : UCB_FALLING);
+ ucb1x00_disable(ts->ucb);
+-
++
+ /*
+ * If we spat out a valid sample set last time,
+ * spit out a "pen off" sample here.
+@@ -250,7 +264,9 @@
+ }
+
+ timeout = MAX_SCHEDULE_TIMEOUT;
++
+ } else {
++
+ ucb1x00_disable(ts->ucb);
+
+ /*
+@@ -269,6 +285,14 @@
+
+ try_to_freeze();
+
++ /*
++ * While suspend the ktsd-thread goes sleep -> try_to_freeze()
++ * While resume the ktsd-thread do wakup and must rune one time
++ * again to do a clean re-setup -> enable_irq: UCB_IRQ_TSPX
++ */
++ if(ts->restart)
++ timeout = HZ / 100;
++
+ schedule_timeout(timeout);
+ }
+
+@@ -351,8 +375,12 @@
+ * TS interrupt mode is set up again
+ * after sleep.
+ */
++
+ ts->restart = 1;
+ wake_up(&ts->irq_wait);
++
++ printk(KERN_INFO "ucb1x00-ts.c -> ucb1x00_ts_resume() ktsd - restart *DONE*\n");
++
+ }
+ return 0;
+ }
diff --git a/recipes/linux/linux/simpad/linux-2.6.27-SIMpad-GPIO-MMC-mod.patch b/recipes/linux/linux/simpad/linux-2.6.27-SIMpad-GPIO-MMC-mod.patch
new file mode 100644
index 0000000000..deacad37b0
--- /dev/null
+++ b/recipes/linux/linux/simpad/linux-2.6.27-SIMpad-GPIO-MMC-mod.patch
@@ -0,0 +1,1701 @@
+Index: linux-2.6.27/drivers/mmc/card/Makefile
+===================================================================
+--- linux-2.6.27.orig/drivers/mmc/card/Makefile 2008-10-10 00:13:53.000000000 +0200
++++ linux-2.6.27/drivers/mmc/card/Makefile 2008-12-04 00:49:46.888896871 +0100
+@@ -6,6 +6,9 @@
+ EXTRA_CFLAGS += -DDEBUG
+ endif
+
++ifeq ($(CONFIG_SA1100_SIMPAD),y)
++# nothing to do
++else
+ obj-$(CONFIG_MMC_BLOCK) += mmc_block.o
+ mmc_block-objs := block.o queue.o
+ obj-$(CONFIG_MMC_TEST) += mmc_test.o
+Index: linux-2.6.27/drivers/mmc/core/Makefile
+===================================================================
+--- linux-2.6.27.orig/drivers/mmc/core/Makefile 2008-10-10 00:13:53.000000000 +0200
++++ linux-2.6.27/drivers/mmc/core/Makefile 2008-12-04 00:50:42.755561658 +0100
+@@ -6,6 +6,9 @@
+ EXTRA_CFLAGS += -DDEBUG
+ endif
+
++ifeq ($(CONFIG_SA1100_SIMPAD),y)
++# nothing to do
++else
+ obj-$(CONFIG_MMC) += mmc_core.o
+ mmc_core-y := core.o bus.o host.o \
+ mmc.o mmc_ops.o sd.o sd_ops.o \
+Index: linux-2.6.27/drivers/mmc/host/Kconfig
+===================================================================
+--- linux-2.6.27.orig/drivers/mmc/host/Kconfig 2008-10-10 00:13:53.000000000 +0200
++++ linux-2.6.27/drivers/mmc/host/Kconfig 2008-12-04 00:53:18.968875446 +0100
+@@ -4,6 +4,7 @@
+
+ comment "MMC/SD Host Controller Drivers"
+
++
+ config MMC_ARMMMCI
+ tristate "ARM AMBA Multimedia Card Interface support"
+ depends on ARM_AMBA
+@@ -153,6 +154,13 @@
+
+ If unsure, or if your system has no SPI master driver, say N.
+
++config MMC_SPI_BLOCK
++ tristate "MMC/SD over GPIO (Software SPI) for SIMpad (EXPERIMENTAL)"
++ depends on SA1100_SIMPAD && EXPERIMENTAL
++ help
++ Say Y here to enable MMC block device over GPIO
++ if you have done the MMC-Mod. For Module say M.
++
+ config MMC_S3C
+ tristate "Samsung S3C SD/MMC Card Interface support"
+ depends on ARCH_S3C2410 && MMC
+Index: linux-2.6.27/drivers/mmc/host/Makefile
+===================================================================
+--- linux-2.6.27.orig/drivers/mmc/host/Makefile 2008-10-10 00:13:53.000000000 +0200
++++ linux-2.6.27/drivers/mmc/host/Makefile 2008-12-04 00:54:44.972204850 +0100
+@@ -6,6 +6,9 @@
+ EXTRA_CFLAGS += -DDEBUG
+ endif
+
++ifeq ($(CONFIG_SA1100_SIMPAD),y)
++obj-$(CONFIG_MMC_SPI_BLOCK) += mmc_spi_block.o
++else
+ obj-$(CONFIG_MMC_ARMMMCI) += mmci.o
+ obj-$(CONFIG_MMC_PXA) += pxamci.o
+ obj-$(CONFIG_MMC_IMX) += imxmmc.o
+@@ -22,4 +25,5 @@
+ obj-$(CONFIG_MMC_S3C) += s3cmci.o
+ obj-$(CONFIG_MMC_SDRICOH_CS) += sdricoh_cs.o
+ obj-$(CONFIG_MMC_TMIO) += tmio_mmc.o
++endif
+
+Index: linux-2.6.27/drivers/mmc/host/mmc_spi_block.c
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.27/drivers/mmc/host/mmc_spi_block.c 2008-12-04 00:55:17.229964087 +0100
+@@ -0,0 +1,1622 @@
++/*
++ * Copyright (c) Cl�ent Ballabriga, 2005 - GPL
++ * Copyright (c) Guylhem Aznar, 2005 - GPL
++ *
++ * Please check http://externe.net/zaurus/simpad-bluetooth reference design first.
++ *
++ * Based on Madsuk/Rohde work on a MMC driver for the WRT54G.
++ *
++ * This is an ugly hack of a driver. I am surprised if it ever works!
++ * So please use a real driver or contribute one to the 2.4/2.6 mmc framework
++ *
++ * mrdata: ported to 2.6
++ */
++
++#include <linux/module.h>
++#include <linux/init.h>
++
++#include <linux/sched.h>
++#include <linux/kernel.h>
++#include <linux/fs.h>
++#include <linux/errno.h>
++#include <linux/hdreg.h>
++#include <linux/kdev_t.h>
++#include <linux/blkdev.h>
++#include <linux/spinlock.h>
++#include <linux/time.h>
++#include <linux/delay.h>
++#include <linux/timer.h>
++
++#include <linux/platform_device.h>
++
++#include <asm/hardware.h>
++#include <asm/arch/simpad.h>
++#include <asm/arch/gpio.h>
++
++static int major = 121;
++
++#define DEVICE_NAME "mmc_spi"
++
++static int hd_sizes[1<<6];
++static int hd_blocksizes[1<<6];
++static int hd_hardsectsizes[1<<6];
++static int hd_maxsect[1<<6];
++static struct hd_struct hd[1<<6];
++
++static struct gendisk *mmc_disk;
++
++static struct platform_device *mmc_dev; /* the one and only instance */
++
++static spinlock_t mmc_spi_lock;
++
++/*
++ * *******************************************************************
++ *
++ * This is the only configurable part.
++ *
++ * *******************************************************************
++ *
++ */
++
++// #define DEBUG 1
++// #define DEBUG_HD 1
++// #define CHECK_MEDIA_CHANGE // for developement ONLY, not working yet
++
++/* Let that include where it is or compilation fails on INIT_REQUEST/CURRENT */
++
++
++/*
++ * If you are using different GPIOs in your hardware hack, you must
++ * first make sure they are unused for other functions and then
++ * configure them here.
++ *
++ * On the simpad I use spare pins from the UART1 (internal serial port -> DECT 20-polig):
++ *
++ * Funktion PIN ## Original direction GPIO ## SPI function New direction SD/MMC
++ * - DCD PIN 08 (in) GPIO 23 DO - new name: DI -> MISO (in) PIN 7 Data Out
++ * - DTR PIN 11 (out) GPIO 07 CS (out) PIN 1 Chip Select
++ * - RI PIN 14 (in) GPIO 19 CLK (out) PIN 5 Clock
++ * - DSR PIN 16 (in) GPIO 06 DI - new name: DO -> MOSI (out) PIN 2 Data In
++ *
++ *
++ * SPI: MISO = Master In / Slave OUT MOSI = Master Out / Slave In
++ *
++ * Don't worry about in/out original function - the GPIOs will be
++ * reprogrammed.
++ */
++
++#define GPIO_SD_DI 23
++#define GPIO_SD_CS 7
++#define GPIO_SD_CLK 19
++#define GPIO_SD_DO 6
++
++// #define FAST_GPIO_SD_DI GPIO_GPIO23
++// #define FAST_GPIO_SD_CS GPIO_GPIO7
++// #define FAST_GPIO_SD_CLK GPIO_GPIO19
++// #define FAST_GPIO_SD_DO GPIO_GPIO6
++
++#define FAST_GPIO_SD_DI GPIO_UART1_DCD
++#define FAST_GPIO_SD_CS GPIO_UART1_DTR
++#define FAST_GPIO_SD_CLK GPIO_UART1_RI
++#define FAST_GPIO_SD_DO GPIO_UART1_DSR
++
++/*
++ * *******************************************************************
++ *
++ * Do not change anything below !
++ *
++ * *******************************************************************
++ *
++ */
++
++/* GPIO states */
++#define LOW 0
++#define HIGH 1
++
++#define INPUT 0
++#define OUTPUT 1
++
++#define PRESENT 1
++#define ABSENT 0
++
++typedef unsigned int uint32;
++typedef unsigned long u32_t;
++typedef unsigned short u16_t;
++typedef unsigned char u8_t;
++
++// static struct timer_list mmc_timer;
++
++// static struct timeval s_zeit, e_zeit;
++
++/* start with no card */
++static int mmc_media_detect = 0;
++// static int mmc_media_changed = 1;
++
++
++/////////////////////
++// prototypes
++static int mmc_open(struct inode *inode, struct file *filp);
++static int mmc_release(struct inode *inode, struct file *filp);
++static int mmc_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg);
++static void mmc_spi_request(struct request_queue *q);
++
++
++/*
++ * *******************************************************************
++ *
++ * Begin GPIO hardware access functions.
++ *
++ * *******************************************************************
++ *
++ */
++
++#define gpio_read(a) ((GPLR & a) ? 1 : 0)
++#define gpio_write_high(a) GPSR = a
++#define gpio_write_low(a) GPCR = a
++
++/* set MMC_Chip_Select to HIGH (MMC/SD-Card inactiv) */
++#define MMC_Disable() gpio_write_high( FAST_GPIO_SD_CS)
++
++/* set MMC_Chip_Select to LOW (MMC/SD-Card activ) */
++#define MMC_Enable() gpio_write_low( FAST_GPIO_SD_CS)
++
++/*
++ * *******************************************************************
++ *
++ * Begin SPI hardware access functions.
++ *
++ * *******************************************************************
++ *
++ */
++static int mmc_spi_media_detect(void)
++{
++// FIXME: add card detection/test by SPI
++
++ return 1;
++}
++
++static int mmc_spi_hardware_init(void)
++{
++ printk("\nmmc: GPIO init\n");
++
++ /* cut existing functions */
++ gpio_set_alternative_function(GPIO_SD_CLK, 0);
++ gpio_set_alternative_function(GPIO_SD_DI, 0);
++ gpio_set_alternative_function(GPIO_SD_DO, 0);
++ gpio_set_alternative_function(GPIO_SD_CS, 0);
++
++ /* remap directions and set state of spi pins */
++ gpio_direction_output(GPIO_SD_CLK, 0);
++ gpio_direction_input(GPIO_SD_DI);
++ gpio_direction_output(GPIO_SD_DO, 0);
++ gpio_direction_output(GPIO_SD_CS, 0);
++
++ printk("mmc: initialising MMC\n");
++
++ /* Start */
++ MMC_Disable();
++ gpio_write_low( FAST_GPIO_SD_CLK);
++ gpio_write_high( FAST_GPIO_SD_DO);
++ return 0;
++}
++
++/* return what has been read, write the parameter */
++/* Clockrate round about 1,2 MHz */
++
++static unsigned char mmc_spi_readwrite(unsigned char data_out)
++{
++ unsigned char i;
++ unsigned char result = 0;
++
++ for(i = 0x80 ; i != 0 ; i >>= 1)
++ {
++ if (data_out & i)
++ {
++ gpio_write_high( FAST_GPIO_SD_DO);
++ }
++ else
++ {
++ gpio_write_low( FAST_GPIO_SD_DO);
++ }
++
++ gpio_write_high( FAST_GPIO_SD_CLK);
++
++ if (gpio_read( FAST_GPIO_SD_DI) == 1)
++ {
++ result |= i;
++ }
++
++ gpio_write_low( FAST_GPIO_SD_CLK);
++
++ }
++
++ gpio_write_high( FAST_GPIO_SD_DO);
++
++ return (result);
++}
++
++/* return what has been read, write the parameter */
++/* Clockrate round 200 kHz */
++
++static unsigned char mmc_spi_readwrite_slow(unsigned char data_out)
++{
++ unsigned char i;
++ unsigned char result = 0;
++
++ for(i = 0x80 ; i != 0 ; i >>= 1)
++ {
++ if (data_out & i)
++ {
++ gpio_write_high( FAST_GPIO_SD_DO);
++ }
++ else
++ {
++ gpio_write_low( FAST_GPIO_SD_DO);
++ }
++
++ udelay(10);
++
++ gpio_write_high( FAST_GPIO_SD_CLK);
++
++ udelay(10);
++
++ if (gpio_read( FAST_GPIO_SD_DI) == 1)
++ {
++ result |= i;
++ }
++
++ udelay(10);
++
++ gpio_write_low( FAST_GPIO_SD_CLK);
++
++ udelay(10);
++
++ }
++
++ gpio_write_high( FAST_GPIO_SD_DO);
++
++ udelay(10);
++
++ // printk("Send Byte = 0x%2X Receive Byte = 0x%2X \n", data_out, result);
++
++ return (result);
++}
++
++/* return what has been read */
++
++static unsigned char mmc_spi_read_only(void)
++{
++ unsigned char i;
++ unsigned char result = 0;
++
++ for(i = 0x80 ; i != 0 ; i >>= 1)
++ {
++
++ gpio_write_high( FAST_GPIO_SD_CLK);
++
++ if (gpio_read( FAST_GPIO_SD_DI) == 1)
++ {
++ result |= i;
++ }
++
++ gpio_write_low( FAST_GPIO_SD_CLK);
++
++ }
++
++ return (result);
++}
++
++/* write the parameter */
++/* Clockrate round about 3,6 MHz */
++
++static unsigned char mmc_spi_write_only(unsigned char data_out)
++{
++ unsigned char i;
++ unsigned char result = 0;
++
++ for(i = 0x80 ; i != 0 ; i >>= 1)
++ {
++
++ if (data_out & i)
++ {
++ gpio_write_high( FAST_GPIO_SD_DO);
++ }
++ else
++ {
++ gpio_write_low( FAST_GPIO_SD_DO);
++ }
++
++ gpio_write_high( FAST_GPIO_SD_CLK);
++
++ gpio_write_low( FAST_GPIO_SD_CLK);
++
++ }
++
++ gpio_write_high( FAST_GPIO_SD_DO);
++
++ return (result);
++}
++
++
++/**
++ * this function was contributed by: rcichielo from openwrt forums
++ *
++ * Comments added by Marc DENTY on 2007-03-20
++ *
++ * Sequence to read a card's "CID" bytes (name, serial number etc)
++ *
++ * Send: 4ah,00h,00h,00h,00h,00h - CMD10, no args, null CRC
++ * Read: xx - NCR Time
++ * Read: xx - Command Response (Should be 00h)
++ * Read: until FEh is received - Wait for Data token
++ * Read: yy * 16 - Get 16 bytes from CID
++ * Read: zz - Read CRC lo byte
++ * Read: zz - Read CRC hi byte
++ *
++ * Useful locations in the returned data packet:
++ *
++ * 03h-08h Manufacturers's name in ascii
++ * 0ah-0dh Card's 32 bit serial number
++ */
++/**
++ * Comments added by Cyril CATTIAUX on 2007-03-21
++ *
++ * CID format specification (from Sandisk SD Product Manual v1.9)
++ *
++ * cid[00 ] Manufacturer ID (unsigned byte)
++ * cid[01-02] OEM/Application ID (ASCII)
++ * cid[03-07] Product Name (ASCII)
++ * cid[08 ] Product Revistion (BCD coded number)
++ * cid[09-12] Serial Number (32-bit unsigned int)
++ * cid[13-14] Reserved(bit 12->15) - Manufacture Date(bit 0->11)
++ * cid[15 ] CRC7(bit 1->7) - Not used, allways 1 (bit 0)
++*/
++static int mmc_read_cid(unsigned char *cid)
++{
++ unsigned char result = 0;
++ int i;
++
++ MMC_Enable();
++
++ /* wait */
++ for (i = 0; i < 4; i++)
++ {
++ result=mmc_spi_readwrite(0xff);
++ }
++
++ /* issue CID (card identification data) read request */
++ mmc_spi_readwrite(0xff);
++ mmc_spi_readwrite(0x40 | 10);
++ mmc_spi_readwrite(0x00);
++ mmc_spi_readwrite(0x00);
++ mmc_spi_readwrite(0x00);
++ mmc_spi_readwrite(0x00);
++ mmc_spi_readwrite(0x95);
++
++ for (i = 0; i < 8; i++)
++ {
++ result=mmc_spi_readwrite(0xff);
++
++ if(result == 0x00)
++ break;
++ }
++
++ if (result != 0x00) {
++ MMC_Disable();
++ mmc_spi_readwrite(0xff);
++ return(1);
++ }
++
++ for (i = 0; i < 8; i++) {
++ result = mmc_spi_readwrite(0xff);
++ if (result == 0xfe) break;
++ }
++
++ if (result != 0xfe) {
++ MMC_Disable();
++ mmc_spi_readwrite(0xff);
++ return(2);
++ }
++
++ for (i = 0; i < 16; i++) {
++ result = mmc_spi_readwrite(0xff);
++ cid[i] = result;
++ }
++
++ mmc_spi_readwrite(0xff);
++ mmc_spi_readwrite(0xff);
++
++ MMC_Disable();
++ mmc_spi_readwrite(0xff);
++
++ return 0;
++}
++
++
++/**
++ * Comments added by Cyril CATTIAUX on 2007-03-21
++ *
++ * CID format specification (from Sandisk SD Product Manual v1.9)
++ *
++ * cid[00 ] Manufacturer ID (unsigned byte)
++ * cid[01-02] OEM/Application ID (ASCII)
++ * cid[03-07] Product Name (ASCII)
++ * cid[08 ] Product Revision (BCD coded 2 digit number)
++ * cid[09-12] Serial Number (32-bit unsigned int)
++ * cid[13-14] Manufacture Date(bit 0->11) (BCD coded 3 digit number YYM offset from 2000) - Reserved(bit 12->15)
++ * cid[15 ] Not used, allways 1 (bit 0) - CRC7(bit 1->7)
++*/
++static void mmc_show_cid_info(void)
++{
++ int i, result;
++ unsigned short tmps;
++ unsigned char cid[16];
++
++ char manufacturer_id;
++ char oem_id[3];
++ char product_name[6];
++ unsigned char product_revision_h, product_revision_l;
++ unsigned int product_sn;
++ unsigned short product_date_y;
++ unsigned char product_date_m;
++
++ result = mmc_read_cid(cid);
++
++ if (result == 0)
++ {
++ printk("mmc_init: MMC/SD Card ID: ");
++ for (i=0; i<16; i++) {
++ printk("%02X ", cid[i]);
++ }
++ manufacturer_id=cid[0];
++ strncpy(oem_id, &cid[1], 2);
++ oem_id[2]='\0';
++ strncpy(product_name, &cid[3], 5);
++ product_name[5]='\0';
++ product_revision_h=(cid[8] >> 4) & 0xf;
++ product_revision_l=cid[8] & 0xf;
++ product_sn=(cid[9]<<24) + (cid[10]<<16) + (cid[11]<<8) + cid[12];
++ tmps=((cid[13]<<8) + cid[14]) & 0x0fff;
++ product_date_y=2000 + (((tmps >> 8) & 0xf) * 10) + ((tmps >> 4) & 0xf);
++ product_date_m=tmps & 0xf;
++
++ printk("\nManufacturer ID : %02X\n", manufacturer_id);
++ printk("OEM/Application ID: %s\n", oem_id);
++ printk("Product name : %s\n", product_name);
++ printk("Product revision : %d.%d\n", product_revision_h, product_revision_l);
++ printk("Product SN : %08X\n", product_sn);
++ printk("Product Date : %d-%d\n", product_date_y, product_date_m);
++
++ } else {
++ printk("mmc_init: impossible to get card indentification info for reason code: %02x", result);
++ }
++}
++
++
++/*
++static int mmc_spi_hw_test(void)
++{
++ unsigned char result, k;
++
++ unsigned int i, j, t;
++
++ printk("mmc_spi_hw_test -> \n\n");
++ k = 0x55;
++ for ( i = 0 ; i < 5; i++) {
++
++ printk("\n0x%2X - ", k);
++ for ( j = 0 ; j < 8; j++ ) {
++ do_gettimeofday( &s_zeit );
++ result = mmc_spi_readwrite_slow(k);
++ do_gettimeofday( &e_zeit );
++
++ if ( result != k ) {
++ printk("!>ERROR<! Transfer = 0x%2X Receive = 0x%2X Trail = %d \n", k, result, j);
++ // i = 255; j = 1000;
++ }
++
++ t = (e_zeit.tv_sec-s_zeit.tv_sec)*1000000+(e_zeit.tv_usec-s_zeit.tv_usec);
++ printk("Durchlauf: %i Versuch: %i von 8 -> Laufzeit: 0x%X s\n", i , j, t);
++ udelay(200);
++ }
++ printk("ready ");
++
++ // k++;
++ }
++ printk("ready ");
++ printk("\n\n");
++ return (0);
++}
++*/
++
++/*
++static int mmc_spi_speed_test(void)
++{
++ unsigned int i, j, k, l, t;
++
++ MMC_Disable();
++
++ for (k = 1; k < 6; k++)
++ {
++ l = 10000 * k;
++ for (j = 0; j < 5; j++)
++ {
++ do_gettimeofday( &s_zeit );
++ for (i = 0; i < l; i++)
++ mmc_spi_readwrite(0xff);
++ do_gettimeofday( &e_zeit );
++ t = (e_zeit.tv_sec-s_zeit.tv_sec)*1000000+(e_zeit.tv_usec-s_zeit.tv_usec);
++ printk("mmc_spi_readwrite: Laufzeit %u x : 0x%X \n", l, t);
++ }
++ }
++
++ for (k = 1; k < 1; k++)
++ {
++ l = 10000 * k;
++ for (j = 0; j < 1; j++)
++ {
++ do_gettimeofday( &s_zeit );
++ for (i = 0; i < l; i++)
++ mmc_spi_readwrite_slow(0xff);
++ do_gettimeofday( &e_zeit );
++ t = (e_zeit.tv_sec-s_zeit.tv_sec)*1000000+(e_zeit.tv_usec-s_zeit.tv_usec);
++ printk("mmc_spi_readwrite_slow: Laufzeit %u x : 0x%X \n", l, t);
++ }
++ }
++
++ for (k = 1; k < 6; k++)
++ {
++ l = 10000 * k;
++ for (j = 0; j < 5; j++)
++ {
++ do_gettimeofday( &s_zeit );
++ for (i = 0; i < l; i++)
++ mmc_spi_read_only();
++ do_gettimeofday( &e_zeit );
++ t = (e_zeit.tv_sec-s_zeit.tv_sec)*1000000+(e_zeit.tv_usec-s_zeit.tv_usec);
++ printk("mmc_spi_read_only: Laufzeit %u x : 0x%X \n", l, t);
++ }
++ }
++
++ for (k = 1; k < 6; k++)
++ {
++ l = 10000 * k;
++ for (j = 0; j < 5; j++)
++ {
++ do_gettimeofday( &s_zeit );
++ for (i = 0; i < l; i++)
++ mmc_spi_write_only(0xff);
++ do_gettimeofday( &e_zeit );
++ t = (e_zeit.tv_sec-s_zeit.tv_sec)*1000000+(e_zeit.tv_usec-s_zeit.tv_usec);
++ printk("mmc_spi_write_only: Laufzeit %u x : 0x%X \n", l, t);
++ }
++ }
++
++ return (1);
++
++}
++*/
++
++
++static int mmc_spi_card_init(void)
++{
++ unsigned char result = 0;
++ short i, j;
++
++// unsigned long flags;
++
++ // save_flags(flags);
++ // cli();
++
++/*
++ printk("GPIO_SD_CS dir: %u alt: %u\n", gpio_getdir(&gp, GPIO_SD_CS), gpio_getalt(&gp, GPIO_SD_CS));
++ printk("GPIO_SD_DI dir: %u alt: %u\n", gpio_getdir(&gp, GPIO_SD_DI), gpio_getalt(&gp, GPIO_SD_DI));
++ printk("GPIO_SD_DO dir: %u alt: %u\n", gpio_getdir(&gp, GPIO_SD_DO), gpio_getalt(&gp, GPIO_SD_DO));
++ printk("GPIO_SD_CS dir: %u alt: %u\n", gpio_getdir(&gp, GPIO_SD_CLK), gpio_getalt(&gp, GPIO_SD_CLK));
++*/
++
++ // printk("\nmmc: mmc_spi_hw_test() *START*\n");
++
++ // mmc_spi_hw_test();
++
++ printk("\nmmc: card init 1/2 (CMD0)\n");
++
++ for (j = 0; j < 10; j++)
++ {
++ MMC_Disable();
++
++ for (i = 0; i < 10; i++)
++ mmc_spi_readwrite_slow(0xff);
++
++ MMC_Enable();
++
++ mmc_spi_readwrite_slow(0xff);
++
++ mmc_spi_readwrite_slow(0x40);
++
++ for (i = 0; i < 4; i++) {
++
++ mmc_spi_readwrite_slow(0x00);
++
++ }
++
++ mmc_spi_readwrite_slow(0x95);
++
++ for (i = 0; i < 8; i++) {
++
++ result = mmc_spi_readwrite_slow(0xff);
++
++#ifdef DEBUG_HD
++ if (result != 0xff) {
++ if (result > 0x1F && result < 0x80)
++ printk("mmc: resp. (CMD0) Versuch(%d) BYTE: %d result = 0x%X Zeichen = %c\n", j, i, result, result);
++ else
++ printk("mmc: resp. (CMD0) Versuch(%d) BYTE: %d result = 0x%X\n", j, i, result);
++ }
++#endif
++ if (result == 0x01)
++ break;
++ }
++
++ if (result == 0x01)
++ break;
++
++ MMC_Disable();
++ mmc_spi_readwrite_slow(0xff);
++
++ mdelay(60);
++ }
++
++ if (result != 0x01) {
++
++ printk("mmc: card init 1/2 error: %d (CMD0) failed\n", result);
++ printk(" -> Hint: MMC/SD-Card realy (fully) inserted ?\n");
++
++ return (1);
++ }
++
++ printk("mmc: card init 1/2 (CMD0) success\n\n");
++
++ mdelay(1);
++
++ printk("mmc: card init 2/2 (CMD1)\n");
++ for (j = 0; j < 10; j++) {
++
++ mmc_spi_readwrite_slow(0xff);
++ mmc_spi_readwrite_slow(0x41);
++ for (i = 0; i < 4; i++)
++ mmc_spi_readwrite_slow(0x00);
++ mmc_spi_readwrite_slow(0x95);
++ for (i = 0; i < 8; i++) {
++ result = mmc_spi_readwrite_slow(0xff);
++#ifdef DEBUG_HD
++ // if (result >= 32 && result <= 127)
++ // printk("mmc: response (CMD1) Versuch(%d) start token BYTE: %d result = 0x%X Zeichen = %c\n", j, i, result, result);
++ // else
++ // printk("mmc: response (CMD1) Versuch(%d) start token BYTE: %d result = 0x%X\n", j, i, result);
++#endif
++ if (result == 0x00)
++ break;
++ }
++
++ mmc_spi_readwrite_slow(0xff);
++
++ if (result == 0x00) {
++ printk("mmc: card init 2/2 (CMD1) success\n\n");
++
++ mmc_spi_readwrite_slow(0xff);
++ mmc_spi_readwrite_slow(0x4d);
++ mmc_spi_readwrite_slow(0x00);
++ mmc_spi_readwrite_slow(0x00);
++ mmc_spi_readwrite_slow(0x00);
++ mmc_spi_readwrite_slow(0x00);
++ mmc_spi_readwrite_slow(0x95);
++ for (i = 0; i < 6; i++) {
++ result = mmc_spi_readwrite_slow(0xff);
++#ifdef DEBUG_HD
++ // if (result > 31 && result < 128)
++ // printk("mmc: response (CMD13) Versuch(%d) start token BYTE: %d result = 0x%X Zeichen = %c\n", j, i, result, result);
++ // else
++ // printk("mmc: response (CMD13) Versuch(%d) start token BYTE: %d result = 0x%X\n", j, i, result);
++#endif
++ // if (result == 0x00)
++ // break;
++ }
++ // mdelay(60);
++ MMC_Disable();
++ mmc_spi_readwrite_slow(0xff);
++ // mmc_spi_readwrite_slow(0xff);
++ // mdelay(10);
++
++ // restore_flags(flags);
++
++ return (0);
++ }
++ mdelay(60);
++ }
++ return (2);
++}
++
++
++static int mmc_spi_card_config(void)
++{
++ unsigned char result = 0;
++ short i, j;
++ unsigned char csd[32];
++ unsigned int c_size;
++ unsigned int c_size_mult;
++ unsigned int mult;
++ unsigned int read_bl_len;
++ unsigned int blocknr = 0;
++ unsigned int block_len = 0;
++ unsigned int size = 0;
++ unsigned char rd_buffer[528];
++// unsigned long flags;
++
++ MMC_Enable();
++
++ mmc_spi_readwrite_slow(0xff);
++ result = mmc_spi_readwrite_slow(0x51);
++ // mmc_spi_readwrite_slow(0x4A);
++ // mmc_spi_readwrite_slow(0x40+0x0D);
++ // mmc_spi_readwrite_slow(0x42);
++ for (i = 0; i < 4; i++)
++ mmc_spi_readwrite_slow(0x00);
++ mmc_spi_readwrite_slow(0x95);
++
++ // printk("mmc: (CMD17) response von 0x51 result = 0x%X\n", result);
++
++ for (i = 0; i < 8; i++) {
++ result = mmc_spi_readwrite_slow(0xff);
++#ifdef DEBUG_HD
++ // printk("mmc: (CMD17) response (start token) result = 0x%X\n", result);
++#endif
++ if (result == 0x00)
++ break;
++ }
++ if (result != 0x00) {
++ MMC_Disable();
++ mmc_spi_readwrite_slow(0xff);
++ // restore_flags(flags);
++ // mmc_spi_readwrite_slow(0xff);
++ return (1);
++ }
++ // restore_flags(flags);
++ for (i = 0; i < 8; i++) {
++ result = mmc_spi_readwrite_slow(0xff);
++ rd_buffer[i] = result;
++#ifdef DEBUG_HD
++ /*
++ if (result >= 32 && result <= 127)
++ printk("mmc: CMD17 response (start token) result = 0x%X Zeichen = %c\n", result, result);
++ else
++ printk("mmc: CMD17 response (start token) result = 0x%X\n", result);
++ */
++#endif
++ // if (result == 0xfe)
++ // break;
++ }
++ /*
++ if (result != 0xfe) {
++ MMC_Disable();
++ mmc_spi_readwrite_slow(0xff);
++ mmc_spi_readwrite_slow(0xff);
++ return(1);
++ }
++ */
++
++ for (i = 8; i < 520; i++) {
++ result = mmc_spi_readwrite_slow(0xff);
++ rd_buffer[i] = result;
++ }
++ for (i = 0; i < 2; i++) {
++ result = mmc_spi_readwrite_slow(0xff);
++ }
++ MMC_Disable();
++ mmc_spi_readwrite_slow(0xff);
++ // mmc_spi_readwrite_slow(0xff);
++
++ printk("Buffer - Start\n");
++
++ for ( i = 0 ; i < 33 ; i++) {
++ printk("\r\n%4X - ", i*16);
++ for ( j = 0 ; j < 16 ; j++) {
++ if ( rd_buffer[i*16+j] < 16)
++ printk("0%X ", rd_buffer[i*16+j]);
++ else
++ printk("%2X ", rd_buffer[i*16+j]);
++ }
++ for ( j = 0 ; j < 16 ; j++) {
++ if ( rd_buffer[i*16+j] < ' ')
++ printk(".");
++ else
++ printk("%c", rd_buffer[i*16+j]);
++ }
++ }
++
++ printk("\nBuffer - Ende\n");
++
++ mmc_show_cid_info();
++
++ for(j = 0 ; j < 1; j++) {
++ MMC_Enable();
++
++ // mdelay(1);
++
++ // save_flags(flags);
++ // cli();
++ mmc_spi_readwrite_slow(0xff);
++ mmc_spi_readwrite_slow(0x49);
++ // mmc_spi_readwrite_slow(0x4A);
++ // mmc_spi_readwrite_slow(0x40+0x0D);
++ // mmc_spi_readwrite_slow(0x42);
++ for (i = 0; i < 4; i++)
++ mmc_spi_readwrite_slow(0x00);
++ mmc_spi_readwrite_slow(0x95);
++ for (i = 0; i < 8; i++) {
++ result = mmc_spi_readwrite_slow(0xff);
++#ifdef DEBUG_HD
++ // printk("mmc: (CMD9) response (start token) result = 0x%X\n", result);
++#endif
++ if (result == 0x00)
++ break;
++ }
++ // restore_flags(flags);
++ if (result != 0x00) {
++ MMC_Disable();
++ mmc_spi_readwrite_slow(0xff);
++ // mmc_spi_readwrite_slow(0xff);
++ return (1);
++ }
++ for (i = 0; i < 22; i++) {
++ result = mmc_spi_readwrite_slow(0xff);
++#ifdef DEBUG_HD
++ if (result >= 32 && result <= 127)
++ printk("mmc: response (start token) result = 0x%X Zeichen = %c\n", result, result);
++ else
++ printk("mmc: response (start token) result = 0x%X\n", result);
++#endif
++ if (result == 0xfe)
++ break;
++ }
++ if (result == 0xfe)
++ break;
++
++ if (result != 0xfe) {
++ MMC_Disable();
++ mmc_spi_readwrite_slow(0xff);
++ // mmc_spi_readwrite_slow(0xff);
++ }
++ mdelay(60);
++ }
++
++ if (result != 0xfe) {
++ MMC_Disable();
++ mmc_spi_readwrite_slow(0xff);
++ printk("mmc: mmc card config (CMD9) failed result = 0x%X\n\n", result);
++ return (2);
++ }
++ for (i = 0; i < 16; i++) {
++ result = mmc_spi_readwrite_slow(0xff);
++ csd[i] = result;
++ }
++ for (i = 0; i < 2; i++) {
++ result = mmc_spi_readwrite_slow(0xff);
++ }
++ MMC_Disable();
++ mmc_spi_readwrite_slow(0xff);
++ // mmc_spi_readwrite_slow(0xff);
++
++ if (result == 0x00)
++ return (3);
++
++ c_size = (csd[8] & 0xC0) + (csd[7] << 8) + ((csd[6] & 0x03) << 16);
++ c_size >>= 6;
++ c_size_mult = (csd[10] & 0x80) + ((csd[9] & 0x03) << 8);
++ c_size_mult >>= 7;
++ read_bl_len = csd[5] & 0x0f;
++ mult = 1;
++ mult <<= c_size_mult + 2;
++ blocknr = (c_size + 1) * mult;
++ block_len = 1;
++ block_len <<= read_bl_len;
++ size = block_len * blocknr;
++ size >>= 10;
++
++ for (i = 0; i < (1 << 6); i++) {
++ hd_blocksizes[i] = 1024;
++ hd_hardsectsizes[i] = block_len;
++ hd_maxsect[i] = 256;
++ }
++ hd_sizes[0] = size;
++ hd[0].nr_sects = blocknr;
++
++ printk("Size = %d, hardsectsize = %d, sectors = %d\n",
++ size, block_len, blocknr);
++
++ return 0;
++}
++
++
++/*
++ * *******************************************************************
++ *
++ * End of SPI hardware access functions.
++ *
++ * *******************************************************************
++ */
++
++
++static int mmc_spi_write_block(unsigned int dest_addr, unsigned char *data)
++{
++ unsigned int address;
++ unsigned char result = 0;
++ unsigned char ab0, ab1, ab2, ab3;
++ int i;
++
++ address = dest_addr;
++
++ ab3 = 0xff & (address >> 24);
++ ab2 = 0xff & (address >> 16);
++ ab1 = 0xff & (address >> 8);
++ ab0 = 0xff & address;
++
++ MMC_Enable();
++
++ mmc_spi_readwrite(0xff);
++
++ mmc_spi_readwrite(0x58);
++ mmc_spi_readwrite(ab3); /* msb */
++ mmc_spi_readwrite(ab2);
++ mmc_spi_readwrite(ab1);
++ mmc_spi_readwrite(ab0); /* lsb */
++ mmc_spi_readwrite(0xff);
++
++ for (i = 0; i < 8; i++)
++ {
++ result = mmc_spi_readwrite(0xff);
++ if (result == 0x00)
++ {
++ break;
++ }
++ }
++
++ if (result != 0x00)
++ {
++ MMC_Disable();
++ mmc_spi_readwrite(0xff);
++ return (1);
++ }
++
++ mmc_spi_readwrite(0xfe);
++
++ for (i = 0; i < 512; i += 32)
++ {
++ mmc_spi_write_only(data[i]);
++ mmc_spi_write_only(data[i+1]);
++ mmc_spi_write_only(data[i+2]);
++ mmc_spi_write_only(data[i+3]);
++ mmc_spi_write_only(data[i+4]);
++ mmc_spi_write_only(data[i+5]);
++ mmc_spi_write_only(data[i+6]);
++ mmc_spi_write_only(data[i+7]);
++ mmc_spi_write_only(data[i+8]);
++ mmc_spi_write_only(data[i+9]);
++ mmc_spi_write_only(data[i+10]);
++ mmc_spi_write_only(data[i+11]);
++ mmc_spi_write_only(data[i+12]);
++ mmc_spi_write_only(data[i+13]);
++ mmc_spi_write_only(data[i+14]);
++ mmc_spi_write_only(data[i+15]);
++ mmc_spi_write_only(data[i+16]);
++ mmc_spi_write_only(data[i+17]);
++ mmc_spi_write_only(data[i+18]);
++ mmc_spi_write_only(data[i+19]);
++ mmc_spi_write_only(data[i+20]);
++ mmc_spi_write_only(data[i+21]);
++ mmc_spi_write_only(data[i+22]);
++ mmc_spi_write_only(data[i+23]);
++ mmc_spi_write_only(data[i+24]);
++ mmc_spi_write_only(data[i+25]);
++ mmc_spi_write_only(data[i+26]);
++ mmc_spi_write_only(data[i+27]);
++ mmc_spi_write_only(data[i+28]);
++ mmc_spi_write_only(data[i+29]);
++ mmc_spi_write_only(data[i+30]);
++ mmc_spi_write_only(data[i+31]);
++ }
++
++ mmc_spi_readwrite(0xff);
++ mmc_spi_readwrite(0xff);
++
++ for (i = 0; i < 1000000; i++)
++ {
++ result = mmc_spi_readwrite(0xff);
++ if (result == 0xff)
++ {
++ break;
++ }
++ }
++
++ if (result != 0xff)
++ {
++ MMC_Disable();
++ mmc_spi_readwrite(0xff);
++ return (3);
++ }
++
++ MMC_Disable();
++ mmc_spi_readwrite(0xff);
++ return (0);
++}
++
++static int mmc_spi_read_block(unsigned char *data, unsigned int src_addr)
++{
++ unsigned int address;
++ unsigned char result = 0;
++ unsigned char ab0, ab1, ab2, ab3;
++ // unsigned long flags;
++ // int i, j;
++ int i;
++
++ address = src_addr;
++
++ ab3 = 0xff & (address >> 24);
++ ab2 = 0xff & (address >> 16);
++ ab1 = 0xff & (address >> 8);
++ ab0 = 0xff & address;
++
++ MMC_Enable();
++
++ mmc_spi_readwrite(0xff);
++
++ mmc_spi_readwrite(0x51);
++ mmc_spi_readwrite(ab3); /* msb */
++ mmc_spi_readwrite(ab2);
++ mmc_spi_readwrite(ab1);
++ mmc_spi_readwrite(ab0); /* lsb */
++ mmc_spi_readwrite(0xff);
++
++ for (i = 0; i < 8; i++)
++ {
++ result = mmc_spi_readwrite(0xff);
++ if (result == 0x00)
++ {
++ break;
++ }
++ }
++
++ if (result != 0x00)
++ {
++ MMC_Disable();
++ mmc_spi_readwrite(0xff);
++ return (1);
++ }
++
++ for (i = 0; i < 100000; i++)
++ {
++ result = mmc_spi_readwrite(0xff);
++ if (result == 0xfe)
++ {
++ break;
++ }
++ }
++
++ if (result != 0xfe)
++ {
++ MMC_Disable();
++ mmc_spi_readwrite(0xff);
++ return (2);
++ }
++
++ for (i = 0; i < 512; i += 32 )
++ {
++ data[i] = mmc_spi_read_only();
++ data[i+1] = mmc_spi_read_only();
++ data[i+2] = mmc_spi_read_only();
++ data[i+3] = mmc_spi_read_only();
++ data[i+4] = mmc_spi_read_only();
++ data[i+5] = mmc_spi_read_only();
++ data[i+6] = mmc_spi_read_only();
++ data[i+7] = mmc_spi_read_only();
++ data[i+8] = mmc_spi_read_only();
++ data[i+9] = mmc_spi_read_only();
++ data[i+10] = mmc_spi_read_only();
++ data[i+11] = mmc_spi_read_only();
++ data[i+12] = mmc_spi_read_only();
++ data[i+13] = mmc_spi_read_only();
++ data[i+14] = mmc_spi_read_only();
++ data[i+15] = mmc_spi_read_only();
++ data[i+16] = mmc_spi_read_only();
++ data[i+17] = mmc_spi_read_only();
++ data[i+18] = mmc_spi_read_only();
++ data[i+19] = mmc_spi_read_only();
++ data[i+20] = mmc_spi_read_only();
++ data[i+21] = mmc_spi_read_only();
++ data[i+22] = mmc_spi_read_only();
++ data[i+23] = mmc_spi_read_only();
++ data[i+24] = mmc_spi_read_only();
++ data[i+25] = mmc_spi_read_only();
++ data[i+26] = mmc_spi_read_only();
++ data[i+27] = mmc_spi_read_only();
++ data[i+28] = mmc_spi_read_only();
++ data[i+29] = mmc_spi_read_only();
++ data[i+30] = mmc_spi_read_only();
++ data[i+31] = mmc_spi_read_only();
++ }
++
++ result = mmc_spi_readwrite(0xff);
++ result = mmc_spi_readwrite(0xff);
++
++ MMC_Disable();
++ mmc_spi_readwrite(0xff);
++
++ return (0);
++}
++
++/*
++static int mmc_revalidate(kdev_t dev)
++{
++ int target, max_p, start, i;
++
++ mmc_media_detect = mmc_spi_media_detect();
++
++ if (mmc_media_detect == 0)
++ {
++ return -ENODEV;
++ }
++
++ target = DEVICE_NR(dev);
++
++ max_p = hd_gendisk.max_p;
++ start = target << 6;
++ for (i = max_p - 1; i >= 0; i--)
++ {
++ int minor = start + i;
++ invalidate_device(MKDEV(MAJOR_NR, minor), 1);
++ hd_gendisk.part[minor].start_sect = 0;
++ hd_gendisk.part[minor].nr_sects = 0;
++ }
++
++ grok_partitions(&hd_gendisk, target, 1 << 6, hd_sizes[0] * 2);
++
++ return 0;
++}
++*/
++
++
++static int mmc_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
++ unsigned long arg)
++{
++ if (!inode || !inode->i_rdev)
++ return -EINVAL;
++
++ switch (cmd) {
++#if 0
++ case BLKGETSIZE:
++ return put_user(hd[MINOR(inode->i_rdev)].nr_sects,
++ (unsigned long *)arg);
++ case BLKGETSIZE64:
++ return put_user((u64) hd[MINOR(inode->i_rdev)].
++ nr_sects, (u64 *) arg);
++ case BLKRRPART:
++ if (!capable(CAP_SYS_ADMIN))
++ return -EACCES;
++
++ return mmc_revalidate(inode->i_rdev);
++#endif
++ case HDIO_GETGEO:
++ {
++ struct block_device *bdev = inode->i_bdev;
++ struct hd_geometry *loc, g;
++ loc = (struct hd_geometry *)arg;
++ if (!loc)
++ return -EINVAL;
++ memset(loc, 0, sizeof(struct hd_geometry));
++ g.heads = 4;
++ g.sectors = 16;
++ g.cylinders = get_capacity(bdev->bd_disk) / (4*16);
++ g.start = get_start_sect(bdev);
++ return copy_to_user(loc, &g, sizeof(g)) ? -EFAULT : 0;
++ }
++ default:
++ return -ENOTTY;
++ }
++}
++
++
++/*
++static int mmc_check_media_change(kdev_t dev)
++{
++ (void) dev;
++ if (mmc_media_changed == 1)
++ {
++ mmc_media_changed = 0;
++ return 1;
++ }
++ else
++ {
++ return 0;
++ }
++}
++*/
++
++
++/*
++static int mmc_init(void)
++{
++ int result;
++
++ result = mmc_spi_hardware_init();
++
++ if (result != 0)
++ {
++ printk("mmc: error %d in mmc_spi_hardware_init\n", result);
++ return -1;
++ }
++
++
++ result = mmc_spi_hw_test();
++
++ if (result != 0)
++ {
++ printk("\n mmc: mmc_spi_hw_test i.O. \n\n");
++ return -1;
++ }
++
++
++ result = mmc_spi_speed_test();
++
++ if (result != 0)
++ {
++ printk("\n mmc: mmc_spi_speed_test i.O. \n\n");
++ return -1;
++ }
++
++
++ result = mmc_spi_card_init();
++ mdelay(50);
++ if (result != 0)
++ {
++ // Give it an extra shot
++ // result = mmc_spi_card_init();
++ if (result != 0)
++ {
++ printk("mmc: error %d in mmc_card_init\n", result);
++ return -1;
++ }
++ }
++
++ result = mmc_spi_card_config();
++ if (result != 0)
++ {
++ printk("mmc: error %d in mmc_card_config\n", result);
++ return -1;
++ }
++
++
++ return 0;
++}
++*/
++
++/*
++static void mmc_exit(void)
++{
++}
++*/
++
++
++/*
++static void mmc_check_media(void)
++{
++ int old_state, new_state;
++ int result;
++
++ old_state = mmc_media_detect;
++ new_state = mmc_spi_media_detect();
++
++ if (old_state != new_state)
++ {
++ mmc_media_changed = 1;
++ if (new_state == PRESENT)
++ {
++ result = mmc_init();
++ if (result != 0)
++ {
++ printk("mmc: error %d in mmc_init\n", result);
++ }
++ else
++ {
++ mmc_exit();
++ }
++ }
++ }
++
++#ifdef CHECK_MEDIA_CHANGE
++ del_timer(&mmc_timer);
++ mmc_timer.expires = jiffies + 10*HZ;
++ add_timer(&mmc_timer);
++#endif
++
++}
++*/
++
++
++/* NB: There might be several requests in the queue, simply dequeuing only one
++ and not checking for more will cause a stall because the block subsystem
++ will not call this function again unless the queue is "plugged" which can
++ only happen if it runs empty... */
++static void mmc_spi_request(struct request_queue *q)
++{
++ struct request *req;
++ int ret;
++
++ unsigned int mmc_address;
++ unsigned char *buffer_address;
++ int nr_sectors;
++ int i;
++ int result, success;
++
++ if (blk_queue_plugged(q)) {
++ return;
++ }
++
++ spin_lock(&mmc_spi_lock);
++ for(;;) {
++ req = elv_next_request(q);
++ if (!req)
++ break;
++
++ if (!blk_fs_request(req)) {
++ printk("not a blk_fs_request\n");
++ spin_unlock(&mmc_spi_lock);
++ continue;
++ }
++
++ mmc_address = req->sector * hd_hardsectsizes[0];
++ buffer_address = req->buffer;
++ nr_sectors = req->current_nr_sectors;
++ success = 1;
++ if (rq_data_dir(req) == READ) {
++ spin_unlock_irq(q->queue_lock);
++ for (i = 0; i < nr_sectors; i++) {
++ result = mmc_spi_read_block(buffer_address, mmc_address);
++ if (unlikely(result < 0)) {
++ printk(KERN_ERR "mmi_spi_block: error reading block (%d)\n", result);
++ success = 0;
++ break;
++ }
++ mmc_address += hd_hardsectsizes[0];
++ buffer_address += hd_hardsectsizes[0];
++ }
++ spin_lock_irq(q->queue_lock);
++ } else {
++ spin_unlock_irq(q->queue_lock);
++ for (i = 0; i < nr_sectors; i++) {
++ result = mmc_spi_write_block(mmc_address, buffer_address);
++ if (unlikely(result < 0)) {
++ printk(KERN_ERR "mmi_spi_block: error writing block (%d)\n", result);
++ success = 0;
++ break;
++ }
++ mmc_address += hd_hardsectsizes[0];
++ buffer_address += hd_hardsectsizes[0];
++ }
++ spin_lock_irq(q->queue_lock);
++ }
++ ret = end_that_request_chunk(req, success, nr_sectors * hd_hardsectsizes[0]);
++ if (!ret) {
++ blkdev_dequeue_request(req);
++ end_that_request_last(req, 0);
++ }
++ }
++ spin_unlock(&mmc_spi_lock);
++}
++
++
++static int mmc_open(struct inode *inode, struct file *filp)
++{
++ // int device;
++ (void) filp;
++ mmc_media_detect = mmc_spi_media_detect();
++
++ if (mmc_media_detect == 0)
++ return -ENODEV;
++
++ return 0;
++}
++
++static int mmc_release(struct inode *inode, struct file *filp)
++{
++ return 0;
++}
++
++
++static struct block_device_operations mmc_spi_bdops = {
++ .open = mmc_open,
++ .release = mmc_release,
++ .ioctl = mmc_ioctl,
++ .owner = THIS_MODULE,
++#if 0
++ .check_media_change = mmc_check_media_change,
++ .revalidate = mmc_revalidate,
++#endif
++};
++
++static int detect_card(void)
++{
++ int result;
++
++ result = mmc_spi_card_init();
++ if (result != 0) {
++ // Give it an extra shot
++ result = mmc_spi_card_init();
++ if (result != 0) {
++ printk(KERN_ERR "mmc_spi_block: error in mmc_card_init (%d)\n", result);
++ return -ENODEV;
++ }
++ }
++
++ result = mmc_spi_card_config();
++ // result = mmc_spi_speed_test();
++ if (result != 0) {
++ printk(KERN_ERR "mmc_spi_block: error in mmc_card_config (%d)\n", result);
++ return -ENODEV;
++ }
++
++ return 0;
++}
++
++/* Fills in the gendisk structure from the received card
++ data. */
++static int gendisk_init(struct device *dev, struct gendisk *gd)
++{
++ if (!gd)
++ return -EINVAL;
++
++ gd->major = major;
++ gd->first_minor = 0; /* only one device supported */
++ gd->fops = &mmc_spi_bdops;
++ gd->driverfs_dev = dev;
++
++ gd->queue = blk_init_queue(mmc_spi_request,NULL);
++
++ if (!gd->queue)
++ return -ENOMEM;
++
++ sprintf(gd->disk_name, "mmcblk");
++
++ blk_queue_hardsect_size(gd->queue, hd_hardsectsizes[0]);
++
++ set_capacity(gd, hd_sizes[0]<<1);
++
++ return 0;
++}
++
++static int gendisk_fini(struct gendisk *gd)
++{
++ BUG_ON(!gd);
++
++ if (gd->queue)
++ blk_cleanup_queue(gd->queue);
++
++ del_gendisk(gd);
++
++ return 0;
++}
++
++/* platform driver device instance routines */
++static int mmc_spi_probe(struct platform_device *pdev)
++{
++ int result;
++ printk("$Id: mmc_spi_block.c,v 1.05 2008/01/04 01:02:10 mrdata Exp $\n");
++
++ result = mmc_spi_hardware_init();
++ if (result != 0) {
++ printk(KERN_ERR "mmc_spi_block: error in mmc_spi_hardware_init (%d)\n", result);
++ result = -ENODEV;
++ return result;
++ }
++
++ result = detect_card();
++ if (result < 0)
++ return result;
++
++ mmc_media_detect = 1;
++
++ result = register_blkdev(major, DEVICE_NAME);
++ if (result < 0)
++ return result;
++
++ if (!major)
++ major = result;
++
++ /* allow 8 partitions per device */
++ BUG_ON(mmc_disk!=NULL);
++ mmc_disk = alloc_disk(1 << 3);
++ if (!mmc_disk) {
++ result = -ENOMEM;
++ goto out;
++ }
++
++ result = gendisk_init(&pdev->dev, mmc_disk);
++ if (result < 0)
++ goto out;
++
++ add_disk(mmc_disk);
++
++ /*init_timer(&mmc_timer);
++ mmc_timer.expires = jiffies + HZ;
++ mmc_timer.function = (void *)mmc_check_media;
++ add_timer(&mmc_timer); */
++ return 0;
++
++out:
++ if (mmc_disk)
++ put_disk(mmc_disk);
++
++ unregister_blkdev(major, DEVICE_NAME);
++ return result;
++}
++
++static int mmc_spi_remove(struct platform_device *dev)
++{
++ // int ret;
++
++ if (mmc_disk) {
++ gendisk_fini(mmc_disk);
++ put_disk(mmc_disk);
++ }
++
++ // ret = unregister_blkdev(major, DEVICE_NAME);
++ unregister_blkdev(major, DEVICE_NAME);
++ return 0;
++}
++
++struct platform_driver mmc_spi_driver = {
++ .probe = mmc_spi_probe,
++ .remove = mmc_spi_remove,
++ .driver = {
++ .name = "mmc_spi_block",
++ .owner = THIS_MODULE,
++ },
++};
++
++
++/* module init/exit */
++static int __init mmc_spi_block_init(void)
++{
++ int ret;
++ spin_lock_init(&mmc_spi_lock);
++
++ ret = platform_driver_register(&mmc_spi_driver);
++ if (ret < 0)
++ return ret;
++
++ /* we just support one device */
++ mmc_dev = platform_device_register_simple("mmc_spi_block", -1, NULL, 0);
++ if (IS_ERR(mmc_dev))
++ return PTR_ERR(mmc_dev);
++
++ return 0;
++}
++
++
++static void __exit mmc_spi_block_exit(void)
++{
++ platform_driver_unregister(&mmc_spi_driver);
++ if (mmc_dev)
++ platform_device_unregister(mmc_dev);
++}
++
++
++module_init(mmc_spi_block_init);
++module_exit(mmc_spi_block_exit);
++
++MODULE_AUTHOR("Madsuk,Rohde,TaGana,Carsten Juttner <carjay@gmx.net>,Guylhem Aznar <mmc-driver@externe.net>,mrdata");
++MODULE_DESCRIPTION("Driver for MMC/SD-Cards in SPI mode over GPIO (Software SPI)");
++MODULE_SUPPORTED_DEVICE("SIMpad");
++MODULE_LICENSE("GPL");
++
++module_param(major, int, 0444);
++MODULE_PARM_DESC(major, "specify the major device number for the MMC/SD SPI driver");
diff --git a/recipes/linux/linux/simpad/linux-2.6.27-SIMpad-battery-old-way-but-also-with-sysfs.patch b/recipes/linux/linux/simpad/linux-2.6.27-SIMpad-battery-old-way-but-also-with-sysfs.patch
new file mode 100644
index 0000000000..ce23e42806
--- /dev/null
+++ b/recipes/linux/linux/simpad/linux-2.6.27-SIMpad-battery-old-way-but-also-with-sysfs.patch
@@ -0,0 +1,577 @@
+Index: linux-2.6.27/drivers/mfd/Makefile
+===================================================================
+--- linux-2.6.27.orig/drivers/mfd/Makefile 2008-12-07 01:02:17.739605256 +0100
++++ linux-2.6.27/drivers/mfd/Makefile 2008-12-07 01:18:53.732838088 +0100
+@@ -22,3 +22,7 @@
+ ifeq ($(CONFIG_SA1100_ASSABET),y)
+ obj-$(CONFIG_MCP_UCB1200) += ucb1x00-assabet.o
+ endif
++
++ifeq ($(CONFIG_SA1100_SIMPAD),y)
++obj-$(CONFIG_MCP_UCB1200) += ucb1x00-simpad.o
++endif
+Index: linux-2.6.27/drivers/mfd/ucb1x00-simpad.c
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.27/drivers/mfd/ucb1x00-simpad.c 2008-12-07 01:17:54.760583677 +0100
+@@ -0,0 +1,228 @@
++/*
++ * linux/drivers/mfd/ucb1x00-simpad.c
++ *
++ * Copyright (C) 2001-2003 Russell King, All Rights Reserved.
++ * 2007/03/18 mrdata:
++ * - adapted ucb1x00-assabet.c
++ * - transfer ucb1x00-simpad.c from kernel24
++ * to new structur of kernel26
++ *
++ * 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.
++ *
++ * We handle the machine-specific bits of the UCB1x00 driver here.
++ */
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/fs.h>
++#include <linux/proc_fs.h>
++#include <linux/device.h>
++
++#include <linux/apm-emulation.h>
++
++#include <asm/dma.h>
++
++#include <mach/simpad.h>
++#include <mach/simpad_pm.h>
++
++#include "ucb1x00.h"
++#include "ucb1x00-simpad.h"
++
++#define UCB1X00_ATTR(name,input,designation) \
++static ssize_t name##_show(struct device *dev, \
++ struct device_attribute *attr, \
++ char *buf) \
++{ \
++ struct ucb1x00 *ucb = classdev_to_ucb1x00(dev); \
++ int val; \
++ ucb1x00_adc_enable(ucb); \
++ val = ucb1x00_adc_read(ucb, input, UCB_NOSYNC); \
++ ucb1x00_adc_disable(ucb); \
++ return sprintf(buf, "%d\n", CALIBRATE_##designation(val)); \
++} \
++static DEVICE_ATTR(name,0444,name##_show,NULL)
++
++UCB1X00_ATTR(vbatt, UCB_ADC_INP_AD1, BATTERY);
++UCB1X00_ATTR(vcharger, UCB_ADC_INP_AD2, SUPPLY);
++UCB1X00_ATTR(icharger, UCB_ADC_INP_AD3, CHARGING);
++
++static struct ucb1x00 *ucb_alt;
++
++#define UCB1X00_WERT(name,input,designation) \
++static int ucb1x00_simpad_read_##name(struct ucb1x00 *ucb_alt) \
++{ \
++ int val; \
++ ucb1x00_adc_enable(ucb_alt); \
++ val = ucb1x00_adc_read(ucb_alt, input, UCB_NOSYNC); \
++ ucb1x00_adc_disable(ucb_alt); \
++ return CALIBRATE_##designation(val); \
++}
++
++UCB1X00_WERT(vbatt, UCB_ADC_INP_AD1, BATTERY);
++UCB1X00_WERT(vcharger, UCB_ADC_INP_AD2, SUPPLY);
++UCB1X00_WERT(icharger, UCB_ADC_INP_AD3, CHARGING);
++
++static int ucb1x00_simpad_add(struct ucb1x00_dev *dev)
++{
++ device_create_file(&dev->ucb->dev, &dev_attr_vbatt);
++ device_create_file(&dev->ucb->dev, &dev_attr_vcharger);
++ device_create_file(&dev->ucb->dev, &dev_attr_icharger);
++ ucb_alt = dev->ucb;
++ return 0;
++}
++
++static void ucb1x00_simpad_remove(struct ucb1x00_dev *dev)
++{
++ device_remove_file(&dev->ucb->dev, &dev_attr_icharger);
++ device_remove_file(&dev->ucb->dev, &dev_attr_vcharger);
++ device_remove_file(&dev->ucb->dev, &dev_attr_vbatt);
++}
++
++static struct ucb1x00_driver ucb1x00_simpad_driver = {
++ .add = ucb1x00_simpad_add,
++ .remove = ucb1x00_simpad_remove,
++};
++
++static int __init ucb1x00_simpad_init(void)
++{
++ apm_get_power_status = simpad_apm_get_power_status;
++ return ucb1x00_register_driver(&ucb1x00_simpad_driver);
++}
++
++static void __exit ucb1x00_simpad_exit(void)
++{
++ apm_get_power_status = NULL;
++ ucb1x00_unregister_driver(&ucb1x00_simpad_driver);
++}
++
++/****************************************************************************/
++/* Functions exported for use by the kernel and kernel modules */
++/****************************************************************************/
++
++int simpad_get_battery(struct simpad_battery_apm *bstat)
++{
++ int icharger, vcharger, vbatt;
++
++ if ( ucb_alt ) {
++ icharger = ucb1x00_simpad_read_icharger( ucb_alt );
++ vcharger = ucb1x00_simpad_read_vcharger( ucb_alt );
++ vbatt = ucb1x00_simpad_read_vbatt( ucb_alt );
++ } else {
++ bstat->ac_status = SIMPAD_AC_STATUS_AC_UNKNOWN;
++ bstat->status = SIMPAD_BATT_STATUS_UNKNOWN;
++ bstat->percentage = 0x64; // lets say 100%
++ bstat->life = 330; // lets say a long time
++ return 0;
++ }
++
++ /* AC status */
++ bstat->ac_status = SIMPAD_AC_STATUS_AC_OFFLINE;
++ if ( vcharger>MIN_SUPPLY ) {
++ bstat->ac_status = SIMPAD_AC_STATUS_AC_ONLINE;
++ }
++
++ /* charging */
++ bstat->status = 0x0;
++ if ( icharger >= CHARGING_LED_LEVEL )
++ bstat->status = SIMPAD_BATT_STATUS_CHARGING;
++
++ if ( vbatt > BATT_LOW )
++ bstat->status |= SIMPAD_BATT_STATUS_HIGH;
++ else if ( vbatt < BATT_CRITICAL )
++ bstat->status |= SIMPAD_BATT_STATUS_CRITICAL;
++ else
++ bstat->status |= SIMPAD_BATT_STATUS_LOW;
++
++ if (bstat->status & SIMPAD_BATT_STATUS_CHARGING) {
++ if (icharger > CHARGING_MAX_LEVEL)
++ icharger = CHARGING_MAX_LEVEL;
++ if (icharger < CHARGING_LED_LEVEL)
++ icharger = CHARGING_LED_LEVEL;
++
++ bstat->percentage = 100 - 100 * (icharger - CHARGING_LED_LEVEL) /
++ (CHARGING_MAX_LEVEL - CHARGING_LED_LEVEL);
++ } else {
++ if (vbatt > BATT_FULL)
++ vbatt = BATT_FULL;
++ if (vbatt < BATT_EMPTY)
++ vbatt = BATT_EMPTY;
++
++ bstat->percentage = 100 * (vbatt - BATT_EMPTY) / (BATT_FULL - BATT_EMPTY);
++ }
++
++ /* let's assume: full load is 7h */
++ /* bstat->life = 420*bstat->percentage/100; */
++ /* mrdata: think, 4h is more realistic */
++ bstat->life = 240*(bstat->percentage)/100;
++
++#if 0
++ printk("get_battery: ac: %02x / ch: %02x / perc: %02x / life: %d \n",
++ bstat->ac_status, bstat->status,
++ bstat->percentage, bstat->life );
++#endif
++
++ return 0;
++}
++
++void simpad_apm_get_power_status(struct apm_power_info *info)
++{
++ struct simpad_battery_apm bstat;
++ unsigned char ac = APM_AC_UNKNOWN;
++ unsigned char level = APM_BATTERY_STATUS_UNKNOWN;
++ int status, result;
++
++ result = simpad_get_battery(&bstat);
++ if (result) {
++ printk("%s: unable to access battery information: result=%d\n", __FUNCTION__, result);
++ return;
++ }
++
++ switch (bstat.ac_status) {
++ case SIMPAD_AC_STATUS_AC_OFFLINE:
++ ac = APM_AC_OFFLINE;
++ break;
++ case SIMPAD_AC_STATUS_AC_ONLINE:
++ ac = APM_AC_ONLINE;
++ break;
++ case SIMPAD_AC_STATUS_AC_BACKUP:
++ ac = APM_AC_BACKUP;
++ break;
++ }
++
++ info->ac_line_status = ac;
++
++ status = bstat.status;
++ if (status & (SIMPAD_BATT_STATUS_CHARGING | SIMPAD_BATT_STATUS_CHARGE_MAIN))
++ level = APM_BATTERY_STATUS_CHARGING;
++ else if (status & (SIMPAD_BATT_STATUS_HIGH | SIMPAD_BATT_STATUS_FULL))
++ level = APM_BATTERY_STATUS_HIGH;
++ else if (status & SIMPAD_BATT_STATUS_LOW)
++ level = APM_BATTERY_STATUS_LOW;
++ else if (status & SIMPAD_BATT_STATUS_CRITICAL)
++ level = APM_BATTERY_STATUS_CRITICAL;
++
++ info->battery_status = level;
++ info->battery_flag = info->battery_status;
++
++ info->battery_life = bstat.percentage;
++
++ /* we have a dumb battery - so we know nothing */
++ info->time = bstat.life;
++ info->units = APM_UNITS_MINS;
++
++#if 0
++ printk("apm_get_power: ac: %02x / bs: %02x / bf: %02x / perc: %02x / life: %d\n",
++ info->ac_line_status, info->battery_status, info->battery_flag,
++ info->battery_life, info->time );
++#endif
++ return;
++}
++
++module_init(ucb1x00_simpad_init);
++module_exit(ucb1x00_simpad_exit);
++
++
++MODULE_AUTHOR("Juergen Messerer <juergen.messerer@freesurf.ch>");
++MODULE_DESCRIPTION("SIMpad noddy testing only example ADC driver");
++MODULE_LICENSE("GPL");
+Index: linux-2.6.27/drivers/mfd/ucb1x00-simpad.h
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.27/drivers/mfd/ucb1x00-simpad.h 2008-12-07 01:02:19.936271486 +0100
+@@ -0,0 +1,86 @@
++/*
++ * linux/drivers/mfd/ucb1x00-simpad.h
++ *
++ * Copyright (C) 2001 Russell King, All Rights Reserved.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License.
++ */
++#ifndef UCB1300_SIMPAD_H
++#define UCB1300_SIMPAD_H
++
++/*
++ * Conversion from AD -> mV
++ * 7.5V = 1023 7.33137mV/Digit
++ *
++ * 400 Units == 9.7V
++ * a = ADC value
++ * 2007/03/24 mrdata:
++ * according UCB1300 datasheet ADC error max. 3 LSB
++ * 5-95% of full scale -> 3*7.33137mV = 21.99mV
++ * // old
++ * 21 = ADC error
++ * 12600 = Divident to get 2*7.3242
++ * 860 = Divider to get 2*7.3242
++ * 170 = Voltagedrop over
++ *
++ * // new
++ * 3 = ADC error
++ * 12610 = Divident to get 2*7.33139
++ * 860 = Divider to get 2*7.33139
++ * 170 = Voltagedrop over
++ */
++// #define CALIBRATE_BATTERY(a) ((((a + 21)*12600)/860) + 170)
++#define CALIBRATE_BATTERY(a) ((((a + 3)*12610)/860) + 170)
++
++/*
++ * We have two types of batteries a small and a large one
++ * To get the right value we to distinguish between those two
++ * 450 Units == 15 V
++ */
++#ifdef SMALL_BATTERY
++#define CALIBRATE_SUPPLY(a) (((a) * 1500) / 51)
++#define MIN_SUPPLY 8500 /* Less then 8.5V means no powersupply */
++#else
++#define CALIBRATE_SUPPLY(a) (((a) * 1500) / 45)
++//#define MIN_SUPPLY 14000 /* Less then 14V means no powersupply */
++#define MIN_SUPPLY 12000 /* Less then 12V means no powersupply */
++#endif
++
++/*
++ * Charging Current
++ * if value is >= 50 then charging is on
++ */
++// #define CALIBRATE_CHARGING(a) (((a) * 1000) / (152/4))
++#define CALIBRATE_CHARGING(a) (a)
++//#define CHARGING_LED_LEVEL 50
++
++#ifdef CONFIG_SA1100_SIMPAD_SINUSPAD
++
++// type small battery
++#define CHARGING_LED_LEVEL 12
++#define CHARGING_MAX_LEVEL 120
++#define BATT_FULL 8100
++#define BATT_LOW 7300
++#define BATT_CRITICAL 6700
++#define BATT_EMPTY 6400
++
++#else // CONFIG_SA1100_SIMPAD_SINUSPAD
++
++// type large battery
++// because of ADC error CHARGING_LED_LEVEL can changed
++// from 27 to 28
++#define CHARGING_LED_LEVEL 27
++#define CHARGING_MAX_LEVEL 265
++// BATT_FULL with SIMPAD_AC_STATUS_AC_OFFLINE
++#define BATT_FULL 8100
++#define BATT_LOW 7400
++#define BATT_CRITICAL 6800
++#define BATT_EMPTY 6500
++
++#endif // CONFIG_SA1100_SIMPAD_SINUSPAD
++
++// int simpad_get_battery(struct simpad_battery_apm *bstat);
++
++#endif
+Index: linux-2.6.27/arch/arm/mach-sa1100/include/mach/simpad_pm.h
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.27/arch/arm/mach-sa1100/include/mach/simpad_pm.h 2008-12-07 01:02:19.936271486 +0100
+@@ -0,0 +1,236 @@
++/*
++* Abstraction interface for microcontroller connection to rest of system
++*
++* Copyright 2003 Peter Pregler
++* Copyright 2000,1 Compaq Computer Corporation.
++*
++* Use consistent with the GNU GPL is permitted,
++* provided that this copyright notice is
++* preserved in its entirety in all copies and derived works.
++*
++* COMPAQ COMPUTER CORPORATION MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,
++* AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS
++* FITNESS FOR ANY PARTICULAR PURPOSE.
++*
++* Author: Peter Pregler (based on work for ipaq by Andrew Christian)
++*
++*/
++
++#ifndef __SIMPAD_HAL_H
++#define __SIMPAD_HAL_H
++
++#include <linux/apm-emulation.h>
++
++struct simpad_battery_apm {
++ unsigned char ac_status; /* line connected yes/no */
++ unsigned char status; /* battery loading yes/no */
++ unsigned char percentage; /* percentage loaded */
++ unsigned short life; /* life till empty */
++};
++
++extern void simpad_apm_get_power_status(struct apm_power_info *);
++
++// extern int simpad_get_battery(struct simpad_battery_apm *bstat);
++
++/* These should match the apm_bios.h definitions */
++#define SIMPAD_AC_STATUS_AC_OFFLINE 0x00
++#define SIMPAD_AC_STATUS_AC_ONLINE 0x01
++#define SIMPAD_AC_STATUS_AC_BACKUP 0x02 /* What does this mean? */
++#define SIMPAD_AC_STATUS_AC_UNKNOWN 0xff
++
++
++/* These bitfields are rarely "or'd" together */
++#define SIMPAD_BATT_STATUS_HIGH 0x01
++#define SIMPAD_BATT_STATUS_LOW 0x02
++#define SIMPAD_BATT_STATUS_CRITICAL 0x04
++#define SIMPAD_BATT_STATUS_CHARGING 0x08
++#define SIMPAD_BATT_STATUS_CHARGE_MAIN 0x10
++#define SIMPAD_BATT_STATUS_DEAD 0x20 /* Battery will not charge */
++#define SIMPAD_BATT_NOT_INSTALLED 0x20 /* For expansion pack batteries */
++#define SIMPAD_BATT_STATUS_FULL 0x40 /* Battery fully charged (and connected to AC) */
++#define SIMPAD_BATT_STATUS_NOBATT 0x80
++#define SIMPAD_BATT_STATUS_UNKNOWN 0xff
++
++#if 0 // FIXME
++#include <linux/simpad_ts.h>
++
++enum simpad_asset_type {
++ ASSET_TCHAR = 0,
++ ASSET_SHORT,
++ ASSET_LONG
++};
++
++#define TTYPE(_type) (((unsigned int)_type) << 8)
++#define TCHAR(_len) (TTYPE(ASSET_TCHAR) | (_len))
++#define TSHORT TTYPE(ASSET_SHORT)
++#define TLONG TTYPE(ASSET_LONG)
++#define ASSET(_type,_num) ((((unsigned int)_type)<<16) | (_num))
++
++#define ASSET_HM_VERSION ASSET( TCHAR(10), 0 ) /* 1.1, 1.2 */
++#define ASSET_SERIAL_NUMBER ASSET( TCHAR(40), 1 ) /* Unique iPAQ serial number */
++#define ASSET_MODULE_ID ASSET( TCHAR(20), 2 ) /* E.g., "iPAQ 3700" */
++#define ASSET_PRODUCT_REVISION ASSET( TCHAR(10), 3 ) /* 1.0, 2.0 */
++#define ASSET_PRODUCT_ID ASSET( TSHORT, 4 ) /* 2 = Palm-sized computer */
++#define ASSET_FRAME_RATE ASSET( TSHORT, 5 )
++#define ASSET_PAGE_MODE ASSET( TSHORT, 6 ) /* 0 = Flash memory */
++#define ASSET_COUNTRY_ID ASSET( TSHORT, 7 ) /* 0 = USA */
++#define ASSET_IS_COLOR_DISPLAY ASSET( TSHORT, 8 ) /* Boolean, 1 = yes */
++#define ASSET_ROM_SIZE ASSET( TSHORT, 9 ) /* 16, 32 */
++#define ASSET_RAM_SIZE ASSET( TSHORT, 10 ) /* 32768 */
++#define ASSET_HORIZONTAL_PIXELS ASSET( TSHORT, 11 ) /* 240 */
++#define ASSET_VERTICAL_PIXELS ASSET( TSHORT, 12 ) /* 320 */
++
++#define ASSET_TYPE(_asset) (((_asset)&0xff000000)>>24)
++#define ASSET_TCHAR_LEN(_asset) (((_asset)&0x00ff0000)>>16)
++#define ASSET_NUMBER(_asset) ((_asset)&0x0000ffff)
++
++#define MAX_TCHAR_LEN 40
++
++struct simpad_asset {
++ unsigned int type;
++ union {
++ unsigned char tchar[ MAX_TCHAR_LEN ];
++ unsigned short vshort;
++ unsigned long vlong;
++ } a;
++};
++
++/********************************************************************
++ * Interface to the hardware-type specific functions
++ *
++ * get_version Read the version number of the microcontroller on the option pack SPI bus
++ * spi_read Reads from the serial EEPROM memory on the option pack SPI bus
++ * spi_write Write to the serial EEPROM memory on the option pack SPI bus
++ * get_option_detect Returns whether or not an option pack is present
++ *
++ * get_thermal_sensor Return measured temperature of the unit, in units of 0.125 deg C
++ * set_notify_led Turns on, off, or blinks the Green LED
++ * read_light_sensor Returns the value of the front light sensor
++ * get_battery Returns the current voltage and charging state of all batteries
++ * audio_clock Sets the audio CODEC to run at a particular rate
++ * audio_power Turns on/off audio CODEC (internally calls audio_clock)
++ * audio_mute Mutes the audio CODEC
++ * asset_read Extracts PocketPC-style asset information from persistent memory
++ * backlight_control Adjusts the backlight level (only on/off for 3100)
++ *
++ *
++ * iPAQ 3100 only
++ * ==============
++ * codec_control Reset/mute/control level of 3100 audio codec
++ * contrast_control Adjusts the contrast level (only for 3100)
++ *
++ * iPAQ 3600, 3700 only
++ * ====================
++ * eeprom_read Reads from the asset information on the eeprom of a 3600 (deprecated)
++ * eeprom_write Writes to the asset information on the eeprom (deprecated)
++ *
++ * The interfaces to the EEPROM functions are maintained only because the simpad_ts driver has
++ * a deprecated ioctl call for them. They are used internally by the "asset_read" function.
++ *
++ * iPAQ 3800, 3900 only
++ * ====================
++ * set_ebat Tells enhanced PCMCIA sleeves that this iPAQ can handle
++ * a wider voltage range (applies to 3800, 3900)
++ *
++ *********************************************************************/
++
++struct simpad_hal_ops {
++ /* Functions provided by the underlying hardware */
++ int (*get_version)( struct simpad_ts_version * );
++ int (*eeprom_read)( unsigned short address, unsigned char *data, unsigned short len );
++ int (*eeprom_write)( unsigned short address, unsigned char *data, unsigned short len );
++ int (*get_thermal_sensor)( unsigned short * );
++ int (*set_notify_led)( unsigned char mode, unsigned char duration,
++ unsigned char ontime, unsigned char offtime );
++ int (*read_light_sensor)( unsigned char *result );
++ int (*get_battery)( struct simpad_battery * );
++ int (*spi_read)( unsigned short address, unsigned char *data, unsigned short len );
++ int (*spi_write)( unsigned short address, unsigned char *data, unsigned short len );
++ int (*codec_control)( unsigned char, unsigned char );
++ int (*get_option_detect)( int *result );
++ int (*audio_clock)( long samplerate );
++ int (*audio_power)( long samplerate );
++ int (*audio_mute)( int mute );
++ int (*asset_read)( struct simpad_asset *asset );
++ int (*set_ebat)( void );
++
++ /* Functions indirectly provided by the underlying hardware */
++ int (*backlight_control)( enum flite_pwr power, unsigned char level );
++ int (*contrast_control)( unsigned char level );
++
++ /* for module use counting */
++ struct module *owner;
++};
++
++/* Used by the device-specific hardware module to register itself */
++extern int simpad_hal_register_interface( struct simpad_hal_ops *ops );
++extern void simpad_hal_unregister_interface( struct simpad_hal_ops *ops );
++
++/*
++ * Calls into HAL from the device-specific hardware module
++ * These run at interrupt time
++ */
++extern void simpad_hal_keypress( unsigned char key );
++extern void simpad_hal_touchpanel( unsigned short x, unsigned short y, int down );
++extern void simpad_hal_option_detect( int present );
++
++/* Callbacks registered by device drivers */
++struct simpad_driver_ops {
++ void (*keypress)( unsigned char key );
++ void (*touchpanel)( unsigned short x, unsigned short y, int down );
++ void (*option_detect)( int present );
++};
++
++extern int simpad_hal_register_driver( struct simpad_driver_ops * );
++extern void simpad_hal_unregister_driver( struct simpad_driver_ops * );
++
++
++/* Calls into HAL from device drivers and other kernel modules */
++extern void simpad_get_flite( struct simpad_ts_backlight *bl );
++extern void simpad_get_contrast( unsigned char *contrast );
++extern int simpad_set_flite( enum flite_pwr pwr, unsigned char brightness );
++extern int simpad_set_contrast( unsigned char contrast );
++extern int simpad_toggle_frontlight( void );
++
++extern int simpad_apm_get_power_status(unsigned char *ac_line_status, unsigned char *battery_status,
++ unsigned char *battery_flag, unsigned char *battery_percentage,
++ unsigned short *battery_life);
++
++extern struct simpad_hal_ops *simpad_hal_ops;
++
++/* Do not use this macro in driver files - instead, use the inline functions defined below */
++#define CALL_HAL( f, args... ) \
++ { int __result = -EIO; \
++ if ( simpad_hal_ops && simpad_hal_ops->f ) { \
++ __MOD_INC_USE_COUNT(simpad_hal_ops->owner); \
++ __result = simpad_hal_ops->f(args); \
++ __MOD_DEC_USE_COUNT(simpad_hal_ops->owner); \
++ } \
++ return __result; }
++
++#define HFUNC static __inline__ int
++
++/* The eeprom_read/write address + len has a maximum value of 512. Both must be even numbers */
++HFUNC simpad_eeprom_read( u16 addr, u8 *data, u16 len ) CALL_HAL(eeprom_read,addr,data,len)
++HFUNC simpad_eeprom_write( u16 addr, u8 *data, u16 len) CALL_HAL(eeprom_write,addr,data,len)
++HFUNC simpad_spi_read( u8 addr, u8 *data, u16 len) CALL_HAL(spi_read,addr,data,len)
++HFUNC simpad_spi_write( u8 addr, u8 *data, u16 len) CALL_HAL(spi_write,addr,data,len)
++HFUNC simpad_get_version( struct simpad_ts_version *v ) CALL_HAL(get_version,v)
++HFUNC simpad_get_thermal_sensor( u16 *thermal ) CALL_HAL(get_thermal_sensor,thermal)
++HFUNC simpad_set_led( u8 mode, u8 dur, u8 ont, u8 offt ) CALL_HAL(set_notify_led, mode, dur, ont, offt)
++HFUNC simpad_get_light_sensor( u8 *result ) CALL_HAL(read_light_sensor,result)
++HFUNC simpad_get_battery( struct simpad_battery *bat ) CALL_HAL(get_battery,bat)
++HFUNC simpad_get_option_detect( int *result) CALL_HAL(get_option_detect,result)
++HFUNC simpad_audio_clock( long samplerate ) CALL_HAL(audio_clock,samplerate)
++HFUNC simpad_audio_power( long samplerate ) CALL_HAL(audio_power,samplerate)
++HFUNC simpad_audio_mute( int mute ) CALL_HAL(audio_mute,mute)
++HFUNC simpad_asset_read( struct simpad_asset *asset ) CALL_HAL(asset_read,asset)
++HFUNC simpad_set_ebat( void ) CALL_HAL(set_ebat)
++
++/* Don't use these functions directly - rather, call {get,set}_{flite,contrast} */
++ /* Functions indirectly provided by the underlying hardware */
++HFUNC simpad_backlight_control( enum flite_pwr p, u8 v ) CALL_HAL(backlight_control,p,v)
++HFUNC simpad_contrast_control( u8 level ) CALL_HAL(contrast_control,level)
++
++#endif
++#endif
diff --git a/recipes/linux/linux/simpad/linux-2.6.27-SIMpad-cs3-simpad.patch b/recipes/linux/linux/simpad/linux-2.6.27-SIMpad-cs3-simpad.patch
new file mode 100644
index 0000000000..400e171208
--- /dev/null
+++ b/recipes/linux/linux/simpad/linux-2.6.27-SIMpad-cs3-simpad.patch
@@ -0,0 +1,192 @@
+Index: linux-2.6.27/arch/arm/mach-sa1100/Makefile
+===================================================================
+--- linux-2.6.27.orig/arch/arm/mach-sa1100/Makefile 2008-10-10 00:13:53.000000000 +0200
++++ linux-2.6.27/arch/arm/mach-sa1100/Makefile 2008-12-04 03:12:57.098042257 +0100
+@@ -41,6 +41,7 @@
+ obj-$(CONFIG_SA1100_SHANNON) += shannon.o
+
+ obj-$(CONFIG_SA1100_SIMPAD) += simpad.o
++obj-$(CONFIG_SA1100_SIMPAD) += cs3-simpad.o
+ led-$(CONFIG_SA1100_SIMPAD) += leds-simpad.o
+
+ # LEDs support
+Index: linux-2.6.27/arch/arm/mach-sa1100/cs3-simpad.c
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.27/arch/arm/mach-sa1100/cs3-simpad.c 2008-12-07 00:36:17.353090743 +0100
+@@ -0,0 +1,175 @@
++/*
++ * simpad-cs3.c
++ *
++ * This driver shows the GPIO states of the cs3 latch. You can also
++ * switch some GPIOS.
++ *
++ * (c) 2007 Bernhard Guillon <Bernhard.Guillon@OpenSIMpad.org>
++ *
++ * You may use this code as per GPL version 2
++ *
++ * Some parts are based on battery.c
++ *
++ * mrdata: -added cs3_ro support
++ * -added preprocessor stuff
++ *
++ */
++
++#include <linux/module.h>
++#include <linux/types.h>
++#include <linux/init.h>
++#include <linux/device.h>
++
++#include <mach/simpad.h>
++
++extern long get_cs3_ro(void);
++extern long get_cs3_shadow(void);
++extern void set_cs3_bit(int value);
++extern void clear_cs3_bit(int value);
++
++struct cs3 {
++ struct device dev;
++ const char *name;
++ char *id;
++ int type;
++};
++
++struct cs3 cs3 ={
++ .name = "latch_cs3",
++};
++
++
++#define CS3_STORE_ATTR(namek,nameg) \
++static ssize_t namek##_store (struct device *dev, \
++ struct device_attribute *attr, \
++ const char *buf, size_t count) \
++{ \
++ char val; \
++ if (sscanf(buf, "%c",&val) != 1) \
++ return -EINVAL; \
++ if (val == '1') \
++ set_cs3_bit(nameg); \
++ else if (val == '0') \
++ clear_cs3_bit(nameg); \
++ return strlen(buf); \
++}
++
++CS3_STORE_ATTR(display_on, DISPLAY_ON);
++CS3_STORE_ATTR(dect_power_on, DECT_POWER_ON);
++CS3_STORE_ATTR(irda_sd, IRDA_SD);
++CS3_STORE_ATTR(sd_mediaq, SD_MEDIAQ);
++CS3_STORE_ATTR(led2_on, LED2_ON);
++CS3_STORE_ATTR(irda_mode, IRDA_MODE);
++CS3_STORE_ATTR(reset_simcard, RESET_SIMCARD);
++
++
++#define CS3_ATTR(shadro,namek,nameg,mode,store) \
++static ssize_t namek##_show(struct device *dev, \
++ struct device_attribute *attr, \
++ char *buf) \
++{ \
++ if (get_cs3_##shadro() & nameg ) { \
++ return sprintf(buf, "1\n"); \
++ } \
++ else { \
++ return sprintf(buf, "0\n"); \
++ } \
++} \
++static DEVICE_ATTR(namek, mode, namek##_show, store)
++
++CS3_ATTR(shadow, vcc_5v_en, VCC_5V_EN, 0444, NULL);
++CS3_ATTR(shadow, vcc_3v_en, VCC_3V_EN, 0444, NULL);
++CS3_ATTR(shadow, en1, EN1, 0444, NULL);
++CS3_ATTR(shadow, en0, EN0, 0444, NULL);
++CS3_ATTR(shadow, display_on, DISPLAY_ON, 0664, display_on_store);
++CS3_ATTR(shadow, pcmcia_buff_dis, PCMCIA_BUFF_DIS, 0444, NULL);
++CS3_ATTR(shadow, mq_reset, MQ_RESET, 0444, NULL);
++CS3_ATTR(shadow, pcmcia_reset, PCMCIA_RESET, 0444, NULL);
++CS3_ATTR(shadow, dect_power_on, DECT_POWER_ON, 0664, dect_power_on_store);
++CS3_ATTR(shadow, irda_sd, IRDA_SD, 0664, irda_sd_store);
++CS3_ATTR(shadow, rs232_on, RS232_ON, 0444, NULL);
++CS3_ATTR(shadow, sd_mediaq, SD_MEDIAQ, 0664, sd_mediaq_store);
++CS3_ATTR(shadow, led2_on, LED2_ON, 0664, led2_on_store);
++CS3_ATTR(shadow, irda_mode, IRDA_MODE, 0664, irda_mode_store);
++CS3_ATTR(shadow, enable_5v, ENABLE_5V, 0444, NULL);
++CS3_ATTR(shadow, reset_simcard, RESET_SIMCARD, 0664, reset_simcard_store);
++CS3_ATTR(ro, pcmcia_bvd1, PCMCIA_BVD1, 0444, NULL);
++CS3_ATTR(ro, pcmcia_bvd2, PCMCIA_BVD2, 0444, NULL);
++CS3_ATTR(ro, pcmcia_vs1, PCMCIA_VS1, 0444, NULL);
++CS3_ATTR(ro, pcmcia_vs2, PCMCIA_VS2, 0444, NULL);
++CS3_ATTR(ro, lock_ind, LOCK_IND, 0444, NULL);
++CS3_ATTR(ro, charging_state, CHARGING_STATE, 0444, NULL);
++CS3_ATTR(ro, pcmcia_short, PCMCIA_SHORT, 0444, NULL);
++
++static struct device simpad_gpios_device = {
++ .init_name = "simpad",
++};
++
++#define create_entry_conditional(namek) \
++ rc = device_create_file(&cs3->dev, &dev_attr_##namek); \
++ if (rc) goto out; \
++
++static int register_cs3_latch(struct cs3 *cs3)
++{
++ int rc = 0;
++ cs3->dev.parent = &simpad_gpios_device;
++ strcpy(cs3->dev.bus_id, cs3->name);
++ rc = device_register(&cs3->dev);
++ if(rc)
++ goto out;
++
++ create_entry_conditional(vcc_5v_en);
++ create_entry_conditional(vcc_3v_en);
++ create_entry_conditional(en1);
++ create_entry_conditional(en0);
++ create_entry_conditional(display_on);
++ create_entry_conditional(pcmcia_buff_dis);
++ create_entry_conditional(mq_reset);
++ create_entry_conditional(pcmcia_reset);
++ create_entry_conditional(dect_power_on);
++ create_entry_conditional(irda_sd);
++ create_entry_conditional(rs232_on);
++ create_entry_conditional(sd_mediaq);
++ create_entry_conditional(led2_on);
++ create_entry_conditional(irda_mode);
++ create_entry_conditional(enable_5v);
++ create_entry_conditional(reset_simcard);
++ create_entry_conditional(pcmcia_bvd1);
++ create_entry_conditional(pcmcia_bvd2);
++ create_entry_conditional(pcmcia_vs1);
++ create_entry_conditional(pcmcia_vs2);
++ create_entry_conditional(lock_ind);
++ create_entry_conditional(charging_state);
++ create_entry_conditional(pcmcia_short);
++
++out:
++ return rc;
++}
++
++static int __init simpad_gpios_device_init(void)
++{
++ int rc = 0;
++
++ rc = device_register(&simpad_gpios_device);
++
++ if(rc != 0)
++ {
++ printk(KERN_ERR "cs3 latch device failed to register properly\n");
++ return rc;
++ }
++
++ rc = register_cs3_latch(&cs3);
++ return rc;
++}
++
++static void __exit simpad_gpios_device_exit(void)
++{
++ device_unregister(&simpad_gpios_device);
++}
++
++module_init(simpad_gpios_device_init);
++module_exit(simpad_gpios_device_exit);
++
++MODULE_AUTHOR("Bernhard Guillon");
++MODULE_DESCRIPTION("CS3_latch driver");
++MODULE_LICENSE("GPL");
diff --git a/recipes/linux/linux/simpad/linux-2.6.27-SIMpad-mq200.patch b/recipes/linux/linux/simpad/linux-2.6.27-SIMpad-mq200.patch
new file mode 100644
index 0000000000..b64715116c
--- /dev/null
+++ b/recipes/linux/linux/simpad/linux-2.6.27-SIMpad-mq200.patch
@@ -0,0 +1,2640 @@
+Index: linux-2.6.27/drivers/video/Kconfig
+===================================================================
+--- linux-2.6.27.orig/drivers/video/Kconfig 2008-12-07 01:18:57.236171217 +0100
++++ linux-2.6.27/drivers/video/Kconfig 2008-12-07 01:19:16.649503720 +0100
+@@ -16,7 +16,7 @@
+ config VIDEO_OUTPUT_CONTROL
+ tristate "Lowlevel video output switch controls"
+ help
+- This framework adds support for low-level control of the video
++ This framework adds support for low-level control of the video
+ output switch.
+
+ menuconfig FB
+@@ -231,7 +231,7 @@
+ This is particularly important to one driver, matroxfb. If
+ unsure, say N.
+
+-comment "Frame buffer hardware drivers"
++comment "Frambuffer hardware drivers"
+ depends on FB
+
+ config FB_CIRRUS
+@@ -611,7 +611,7 @@
+ BIOS routines contained in a ROM chip in HP PA-RISC based machines.
+ Enabling this option will implement the linux framebuffer device
+ using calls to the STI BIOS routines for initialisation.
+-
++
+ If you enable this option, you will get a planar framebuffer device
+ /dev/fb which will work on the most common HP graphic cards of the
+ NGLE family, including the artist chips (in the 7xx and Bxxx series),
+@@ -1061,36 +1061,36 @@
+ select FB_CFB_IMAGEBLIT
+ select VGASTATE
+ help
+- This driver supports the on-board graphics built in to the Intel 810
++ This driver supports the on-board graphics built in to the Intel 810
+ and 815 chipsets. Say Y if you have and plan to use such a board.
+
+ To compile this driver as a module, choose M here: the
+ module will be called i810fb.
+
+- For more information, please read
++ For more information, please read
+ <file:Documentation/fb/intel810.txt>
+
+ config FB_I810_GTF
+ bool "use VESA Generalized Timing Formula"
+ depends on FB_I810
+ help
+- If you say Y, then the VESA standard, Generalized Timing Formula
++ If you say Y, then the VESA standard, Generalized Timing Formula
+ or GTF, will be used to calculate the required video timing values
+- per video mode. Since the GTF allows nondiscrete timings
++ per video mode. Since the GTF allows nondiscrete timings
+ (nondiscrete being a range of values as opposed to discrete being a
+- set of values), you'll be able to use any combination of horizontal
++ set of values), you'll be able to use any combination of horizontal
+ and vertical resolutions, and vertical refresh rates without having
+ to specify your own timing parameters. This is especially useful
+- to maximize the performance of an aging display, or if you just
+- have a display with nonstandard dimensions. A VESA compliant
++ to maximize the performance of an aging display, or if you just
++ have a display with nonstandard dimensions. A VESA compliant
+ monitor is recommended, but can still work with non-compliant ones.
+- If you need or want this, then select this option. The timings may
+- not be compliant with Intel's recommended values. Use at your own
++ If you need or want this, then select this option. The timings may
++ not be compliant with Intel's recommended values. Use at your own
+ risk.
+
+- If you say N, the driver will revert to discrete video timings
++ If you say N, the driver will revert to discrete video timings
+ using a set recommended by Intel in their documentation.
+-
++
+ If unsure, say N.
+
+ config FB_I810_I2C
+@@ -1214,10 +1214,10 @@
+ framebuffer section. G450/G550 secondary head and digital output
+ are supported without additional modules.
+
+- The driver starts in monitor mode. You must use the matroxset tool
+- (available at <ftp://platan.vc.cvut.cz/pub/linux/matrox-latest/>) to
+- swap primary and secondary head outputs, or to change output mode.
+- Secondary head driver always start in 640x480 resolution and you
++ The driver starts in monitor mode. You must use the matroxset tool
++ (available at <ftp://platan.vc.cvut.cz/pub/linux/matrox-latest/>) to
++ swap primary and secondary head outputs, or to change output mode.
++ Secondary head driver always start in 640x480 resolution and you
+ must use fbset to change it.
+
+ Do not forget that second head supports only 16 and 32 bpp
+@@ -1315,7 +1315,7 @@
+ "I2C support" and "I2C bit-banging support" in the character devices
+ section.
+
+- If you say M here then "I2C support" and "I2C bit-banging support"
++ If you say M here then "I2C support" and "I2C bit-banging support"
+ can be build either as modules or built-in.
+
+ There is a product page at
+@@ -1327,7 +1327,7 @@
+ select FB_DDC
+ default y
+ help
+- Say Y here if you want DDC/I2C support for your Radeon board.
++ Say Y here if you want DDC/I2C support for your Radeon board.
+
+ config FB_RADEON_BACKLIGHT
+ bool "Support for backlight control"
+@@ -1431,6 +1431,15 @@
+ ---help---
+ Driver for graphics boards with S3 Trio / S3 Virge chip.
+
++config FB_MQ200
++ bool "MQ200 Driver"
++ depends on (FB = y) && ARM && ARCH_SA1100
++ select FB_CFB_FILLRECT
++ select FB_CFB_COPYAREA
++ select FB_CFB_IMAGEBLIT
++ help
++ This is a MQ200 driver tested only on Siemens SIMpads.
++
+ config FB_SAVAGE
+ tristate "S3 Savage support"
+ depends on FB && PCI && EXPERIMENTAL
+@@ -1508,7 +1517,7 @@
+ select VGASTATE
+ help
+ This driver supports notebooks with NeoMagic PCI chips.
+- Say Y if you have such a graphics card.
++ Say Y if you have such a graphics card.
+
+ To compile this driver as a module, choose M here: the
+ module will be called neofb.
+@@ -1554,7 +1563,7 @@
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ ---help---
+- Say Y here if you have a 3Dfx Voodoo Graphics (Voodoo1/sst1) or
++ Say Y here if you have a 3Dfx Voodoo Graphics (Voodoo1/sst1) or
+ Voodoo2 (cvg) based graphics card.
+
+ To compile this driver as a module, choose M here: the
+Index: linux-2.6.27/drivers/video/Makefile
+===================================================================
+--- linux-2.6.27.orig/drivers/video/Makefile 2008-12-07 01:18:57.252839170 +0100
++++ linux-2.6.27/drivers/video/Makefile 2008-12-07 01:19:16.649503720 +0100
+@@ -36,6 +36,7 @@
+ obj-$(CONFIG_FB_PM2) += pm2fb.o
+ obj-$(CONFIG_FB_PM3) += pm3fb.o
+
++obj-$(CONFIG_FB_MQ200) += mq200/
+ obj-$(CONFIG_FB_MATROX) += matrox/
+ obj-$(CONFIG_FB_RIVA) += riva/
+ obj-$(CONFIG_FB_NVIDIA) += nvidia/
+Index: linux-2.6.27/drivers/video/backlight/Kconfig
+===================================================================
+--- linux-2.6.27.orig/drivers/video/backlight/Kconfig 2008-12-07 01:18:57.262838759 +0100
++++ linux-2.6.27/drivers/video/backlight/Kconfig 2008-12-07 01:19:16.649503720 +0100
+@@ -164,3 +164,19 @@
+ If you have an Apple Macbook Pro with Nvidia graphics hardware say Y
+ to enable a driver for its backlight
+
++config BACKLIGHT_SIMPAD
++ tristate "SIMpad MQ200 Backlight driver"
++ depends on SA1100_SIMPAD && BACKLIGHT_CLASS_DEVICE
++ default y
++ help
++ If you have a Siemens SIMpad say Y to enable the
++ backlight driver.
++
++config LCD_SIMPAD
++ tristate "SIMpad MQ200 LCD driver"
++ depends on SA1100_SIMPAD && LCD_CLASS_DEVICE
++ default y
++ help
++ If you have a Siemens SIMpad say Y to enable the
++ LCD driver.
++
+Index: linux-2.6.27/drivers/video/backlight/Makefile
+===================================================================
+--- linux-2.6.27.orig/drivers/video/backlight/Makefile 2008-12-07 01:18:57.279504370 +0100
++++ linux-2.6.27/drivers/video/backlight/Makefile 2008-12-07 01:19:16.652836923 +0100
+@@ -16,4 +16,5 @@
+ obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH) += cr_bllcd.o
+ obj-$(CONFIG_BACKLIGHT_PWM) += pwm_bl.o
+ obj-$(CONFIG_BACKLIGHT_MBP_NVIDIA) += mbp_nvidia_bl.o
+-
++obj-$(CONFIG_BACKLIGHT_SIMPAD) += simpad_bl.o
++obj-$(CONFIG_LCD_SIMPAD) += simpad_lcd.o
+Index: linux-2.6.27/drivers/video/backlight/simpad_bl.c
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.27/drivers/video/backlight/simpad_bl.c 2008-12-07 01:32:34.467302764 +0100
+@@ -0,0 +1,208 @@
++/*
++ * GPLv2 <zecke@handhelds.org
++ *
++ * Implementation of the backlight_driver for
++ * the mq200 framebuffer
++ *
++ * 2007/03/17 mrdata:
++ * - small changes simpad_bl_get_brightness()
++ * simpad_bl_set_brightness()
++ * - new function simpad_bl_update_status()
++ * - changed struct backlight_properties simpad_bl_props()
++ * to new one
++ * - changed __init simpad_bl_init() -> backlight_device_register
++ *
++ * 2007/03/24 mrdata
++ * - added .brightness=127 in
++ * struct backlight_properties simpad_bl_props()
++ */
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/platform_device.h>
++#include <linux/spinlock.h>
++#include <linux/fb.h>
++#include <linux/backlight.h>
++
++#include <asm/types.h>
++#include <mach/hardware.h>
++#include <asm/io.h>
++
++#include "../mq200/mq200_data.h"
++
++#define SIMPAD_BACKLIGHT_MASK 0x00a10044
++#define SIMPAD_DEFAULT_INTENSITY 127
++#define SIMPAD_MAX_INTENSITY 254
++#define REGISTER_BASE 0xf2e00000
++
++static int simpad_bl_suspended;
++static int current_intensity = 0;
++
++static void simpad_bl_send_intensity(struct backlight_device *bd)
++{
++ int intensity = bd->props.brightness;
++
++ union fp0fr fp0fr;
++ unsigned long dutyCycle, pwmcontrol;
++
++ if (intensity > SIMPAD_MAX_INTENSITY)
++ intensity = SIMPAD_MAX_INTENSITY;
++
++ if (bd->props.power != FB_BLANK_UNBLANK)
++ intensity = 0;
++
++ if (bd->props.fb_blank != FB_BLANK_UNBLANK)
++ intensity = 0;
++
++ if (simpad_bl_suspended)
++ intensity = 0;
++
++ if (intensity != current_intensity)
++ {
++ /*
++ * Determine dutyCycle.
++ * Note: the lower the value, the brighter the display!
++ */
++
++ dutyCycle = SIMPAD_MAX_INTENSITY - intensity;
++
++ /*
++ * Configure PWM0 (source clock = oscillator clock, pwm always enabled,
++ * zero, clock pre-divider = 4) pwm frequency = 12.0kHz
++ */
++
++ fp0fr.whole = readl(FP0FR(REGISTER_BASE));
++ pwmcontrol = fp0fr.whole & 0xffff00ff;
++ fp0fr.whole &= 0xffffff00;
++ fp0fr.whole |= 0x00000044;
++ writel(fp0fr.whole, FP0FR(REGISTER_BASE));
++
++ /* Write to pwm duty cycle register. */
++ fp0fr.whole = dutyCycle << 8;
++ fp0fr.whole &= 0x0000ff00;
++ fp0fr.whole |= pwmcontrol;
++ writel(fp0fr.whole, FP0FR(REGISTER_BASE));
++
++ current_intensity = intensity;
++ }
++}
++
++
++#ifdef CONFIG_PM
++static int simpad_bl_suspend(struct platform_device *pdev, pm_message_t state)
++{
++ struct backlight_device *bd = platform_get_drvdata(pdev);
++
++ simpad_bl_suspended = 1;
++ simpad_bl_send_intensity(bd);
++ return 0;
++}
++
++static int simpad_bl_resume(struct platform_device *pdev)
++{
++ struct backlight_device *bd = platform_get_drvdata(pdev);
++
++ simpad_bl_suspended = 0;
++ simpad_bl_send_intensity(bd);
++ return 0;
++}
++#else
++#define simpad_bl_suspend NULL
++#define simpad_bl_resume NULL
++#endif
++
++
++static int simpad_bl_set_intensity(struct backlight_device *bd)
++{
++ simpad_bl_send_intensity(bd);
++ return 0;
++}
++
++
++static int simpad_bl_get_intensity(struct backlight_device *bd)
++{
++ return current_intensity;
++}
++
++
++static struct backlight_ops simpad_bl_ops = {
++ .get_brightness = simpad_bl_get_intensity,
++ .update_status = simpad_bl_set_intensity,
++};
++
++
++static int __init simpad_bl_probe(struct platform_device *pdev)
++{
++ struct backlight_device *bd;
++
++ bd = backlight_device_register("simpad-mq200-bl", &pdev->dev, NULL, &simpad_bl_ops);
++
++ if (IS_ERR (bd))
++ return PTR_ERR (bd);
++
++ platform_set_drvdata(pdev, bd);
++
++ bd->props.max_brightness = SIMPAD_MAX_INTENSITY;
++ bd->props.brightness = SIMPAD_DEFAULT_INTENSITY;
++ simpad_bl_send_intensity(bd);
++
++ return 0;
++}
++
++
++static int simpad_bl_remove(struct platform_device *pdev)
++{
++ struct backlight_device *bd = platform_get_drvdata(pdev);
++
++ bd->props.brightness = 0;
++ bd->props.power = 0;
++ simpad_bl_send_intensity(bd);
++
++ backlight_device_unregister(bd);
++
++ return 0;
++}
++
++static struct platform_driver simpad_bl_driver = {
++ .probe = simpad_bl_probe,
++ .remove = simpad_bl_remove,
++ .suspend = simpad_bl_suspend,
++ .resume = simpad_bl_resume,
++ .driver = {
++ .name = "simpad-mq200-bl",
++ },
++};
++
++static struct platform_device *simpad_bl_device = NULL;
++
++static int __init simpad_bl_init(void)
++{
++ int ret;
++
++ ret = platform_driver_register(&simpad_bl_driver);
++ if (!ret) {
++ simpad_bl_device = platform_device_alloc("simpad-mq200-bl", -1);
++ if (!simpad_bl_device)
++ return -ENOMEM;
++
++ ret = platform_device_add(simpad_bl_device);
++
++ if (ret) {
++ platform_device_put(simpad_bl_device);
++ platform_driver_unregister(&simpad_bl_driver);
++ }
++ }
++ return ret;
++}
++
++static void __exit simpad_bl_exit(void)
++{
++ platform_device_unregister(simpad_bl_device);
++ platform_driver_unregister(&simpad_bl_driver);
++}
++
++
++module_init(simpad_bl_init);
++module_exit(simpad_bl_exit);
++MODULE_AUTHOR("Holger Hans Peter Freyther");
++MODULE_LICENSE("GPL");
+Index: linux-2.6.27/drivers/video/backlight/simpad_lcd.c
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.27/drivers/video/backlight/simpad_lcd.c 2008-12-07 01:33:39.386863247 +0100
+@@ -0,0 +1,172 @@
++/*
++ * GPLv2 <zecke@handhelds.org
++ *
++ * Implementation of the lcd_driver for the mq200 framebuffer
++ *
++ * 2007/03/24 mrdata:
++ * - added simpad_lcd_get_contrast()
++ * - added simpad_lcd_set_contrast()
++ * - modify struct lcd_properties simpad_lcd_props
++ */
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/platform_device.h>
++#include <linux/fb.h>
++#include <linux/lcd.h>
++
++#include <mach/simpad.h>
++#include <mach/hardware.h>
++
++extern long get_cs3_shadow(void);
++extern void set_cs3_bit(int);
++extern void clear_cs3_bit(int);
++
++#define UNUSED(x) x=x
++
++static int simpad_lcd_get_power(struct lcd_device* dev)
++{
++ UNUSED(dev);
++
++ return (get_cs3_shadow() & DISPLAY_ON) ? 0 : 4;
++}
++
++static int simpad_lcd_set_power(struct lcd_device* dev, int power)
++{
++ UNUSED(dev);
++
++ if( power == 4 )
++ clear_cs3_bit(DISPLAY_ON);
++ else
++ set_cs3_bit(DISPLAY_ON);
++
++ return 0;
++}
++
++static int simpad_lcd_get_contrast(struct lcd_device* dev)
++{
++ UNUSED(dev);
++
++ return 0;
++}
++
++static int simpad_lcd_set_contrast(struct lcd_device* dev, int contrast)
++{
++ UNUSED(dev);
++
++ UNUSED(contrast);
++
++ return 0;
++}
++
++#ifdef CONFIG_PM
++static int simpad_lcd_suspend(struct platform_device *pdev, pm_message_t state)
++{
++ static int ret;
++ struct lcd_device* ld;
++
++ UNUSED(state);
++
++ ld = platform_get_drvdata(pdev);
++
++ ret = simpad_lcd_set_power(ld, 4);
++
++ return ret;
++}
++
++static int simpad_lcd_resume(struct platform_device *pdev)
++{
++ struct lcd_device *ld;
++ static int ret;
++
++ ld = platform_get_drvdata(pdev);
++
++ ret = simpad_lcd_set_power(ld, 0);
++
++ return ret;
++}
++#else
++#define simpad_lcd_suspend NULL
++#define simpad_lcd_resume NULL
++#endif
++
++
++/*FIXME
++static struct lcd_properties simpad_lcd_props = {
++ .max_contrast = 0,
++};
++*/
++
++static struct lcd_ops simpad_lcd_ops = {
++ .get_power = simpad_lcd_get_power,
++ .set_power = simpad_lcd_set_power,
++ .get_contrast = simpad_lcd_get_contrast,
++ .set_contrast = simpad_lcd_set_contrast,
++};
++
++static int __init simpad_lcd_probe(struct platform_device *pdev)
++{
++ struct lcd_device *ld;
++
++ ld = lcd_device_register ("simpad-mq200-lcd", &pdev->dev, NULL, &simpad_lcd_ops);
++
++ if (IS_ERR(ld))
++ return PTR_ERR(ld);
++
++ platform_set_drvdata(pdev, ld);
++
++ ld->props.max_contrast = 0;
++
++ return 0;
++}
++
++static int simpad_lcd_remove(struct platform_device *pdev)
++{
++ struct lcd_device *ld = platform_get_drvdata(pdev);
++
++ lcd_device_unregister(ld);
++
++ return 0;
++}
++
++static struct platform_driver simpad_lcd_driver = {
++ .probe = simpad_lcd_probe,
++ .remove = simpad_lcd_remove,
++ .suspend = simpad_lcd_suspend,
++ .resume = simpad_lcd_resume,
++ .driver = {
++ .name = "simpad-mq200-lcd",
++ },
++};
++
++static struct platform_device *simpad_lcd_device = NULL;
++
++static int __init simpad_lcd_init(void)
++{
++ int ret;
++
++ ret = platform_driver_register(&simpad_lcd_driver);
++ if (!ret) {
++ simpad_lcd_device = platform_device_alloc("simpad-mq200-lcd", -1);
++ if (!simpad_lcd_device)
++ return -ENOMEM;
++
++ ret = platform_device_add(simpad_lcd_device);
++
++ if (ret) {
++ platform_device_put(simpad_lcd_device);
++ platform_driver_unregister(&simpad_lcd_driver);
++ }
++ }
++ return ret;
++}
++
++static void __exit simpad_lcd_exit(void) {
++ platform_driver_unregister(&simpad_lcd_driver);
++ platform_device_unregister(simpad_lcd_device);
++}
++
++module_init(simpad_lcd_init);
++module_exit(simpad_lcd_exit);
++MODULE_AUTHOR("Holger Hans Peter Freyther");
++MODULE_LICENSE("GPL");
+Index: linux-2.6.27/drivers/video/mq200/Makefile
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.27/drivers/video/mq200/Makefile 2008-12-07 01:19:16.652836923 +0100
+@@ -0,0 +1,6 @@
++# Makefile for mq200 video driver
++# 4 Aug 2003, Holger Hans Peter Freyther
++#
++
++obj-$(CONFIG_FB_MQ200) += mq_skeleton.o mq_external.o
++
+Index: linux-2.6.27/drivers/video/mq200/mq200_data.h
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.27/drivers/video/mq200/mq200_data.h 2008-12-07 01:19:16.656170018 +0100
+@@ -0,0 +1,1120 @@
++/*
++ * From ucLinux mq200fb.c and mq200fb.h
++ *
++ * 2007/03/11 mrdata:
++ * insert registers for graphics controller 2 module
++ */
++
++#ifndef __MQ200_FB_H__
++#define __MQ200_FB_H__
++
++struct mq200_io_regions {
++ u32 fb_size; /* framebuffer size */
++ unsigned long phys_mmio_base; /* physical register memory base */
++ unsigned long virt_mmio_base; /* virtual start of registers */
++ unsigned long phys_fb_base; /* physical address of frame buffer */
++ unsigned long virt_fb_base; /* virtual start of the framebuffer */
++};
++
++#define MQ200_MONITOR_HORI_RES(info) info->monitor_info.horizontal_res
++#define MQ200_MONITOR_VERT_RES(info) info->monitor_info.vertical_res
++#define MQ200_MONITOR_DEPTH(info) info->monitor_info.depth
++#define MQ200_MONITOR_LINE_LENGTH(info) info->monitor_info.line_length
++
++struct mq200_monitor_info {
++ unsigned int horizontal_res;
++ unsigned int vertical_res;
++ unsigned int depth;
++ unsigned int refresh;
++ unsigned int line_length;
++ unsigned long flags;
++};
++
++
++/**
++ * Addresses of Module
++ */
++#define MQ200_FB_BASE (x) (x + 0x1800000) /* framebuffer */
++#define MQ200_FB_SIZE 0x200000 /* framebuffer size in bytes */
++#define MQ200_REGS_BASE(x) (x + 0x1e00000) /* start of registers area */
++#define MQ200_REGS_SIZE 0x200000 /* registers area size */
++
++#define PMU_OFFSET 0x00000 /* power management */
++#define CPU_OFFSET 0x02000 /* CPU interface */
++#define MIU_OFFSET 0x04000 /* memory controller */
++#define IN_OFFSET 0x08000 /* interrupt controller */
++#define GC_OFFSET 0x0a000 /* graphics controller 1&2 */
++#define GE_OFFSET 0x0c000 /* graphics engine */
++#define FPI_OFFSET 0x0e000 /* flat panel controller */
++#define CP1_OFFSET 0x10000 /* color palette 1 */
++#define DC_OFFSET 0x14000 /* device configuration */
++#define PCI_OFFSET 0x16000 /* PCI configuration */
++#define PSF_OFFSET 0x18000 /* ??? */
++
++
++/****
++ * Registers
++ */
++
++/* power management unit */
++#define PMR(addr) (addr + PCI_OFFSET + 0x40)/* power management
++ register */
++#define PMR_VALUE 0x06210001 /* expected read value of PMR register */
++#define PM00R(addr) (addr + PMU_OFFSET + 0x00) /* power management unit
++ configuration
++ register */
++#define PM01R(addr) (addr + PMU_OFFSET + 0x04) /* D1 state control */
++#define PM02R(addr) (addr + PMU_OFFSET + 0x08) /* d2 state control */
++#define PM06R(addr) (addr + PMU_OFFSET + 0x18) /* PLL 2 programming */
++#define PM07R(addr) (addr + PMU_OFFSET + 0x1c) /* PLL 3 programming */
++
++#define PMCSR(addr) (addr + PCI_OFFSET + 0x44) /* power management
++ control/status
++ register */
++
++/* memory interface unit */
++#define MM00R(addr) (addr + MIU_OFFSET + 0x00)/* MIU interface control
++ 0 */
++#define MM01R(addr) (addr + MIU_OFFSET + 0x04) /* MIU interface control
++ 1 */
++#define MM02R(addr) (addr + MIU_OFFSET + 0x08) /* memory interface
++ control 2 */
++#define MM03R(addr) (addr + MIU_OFFSET + 0x0c) /* memory interface
++ control 3 */
++#define MM04R(addr) (addr + MIU_OFFSET + 0x10) /* memory interface
++ control 4 */
++/* graphics controller 1 module */
++#define GC00R(addr) (addr + GC_OFFSET + 0x00) /* graphics controller 1
++ control */
++#define GC01R(addr) (addr + GC_OFFSET + 0x04) /* graphics controller
++ CRT control */
++#define GC02R(addr) (addr + GC_OFFSET + 0x08) /* horizontal display 1
++ control */
++#define GC03R(addr) (addr + GC_OFFSET + 0x0c) /* vertical display 1
++ control */
++#define GC04R(addr) (addr + GC_OFFSET + 0x10) /* horizontal sync 1
++ control */
++#define GC05R(addr) (addr + GC_OFFSET + 0x14) /* vertical sync 1
++ control */
++#define GC07R(addr) (addr + GC_OFFSET + 0x1c) /* vertical display 1
++ count */
++#define GC08R(addr) (addr + GC_OFFSET + 0x20) /* horizontal window 1
++ control */
++#define GC09R(addr) (addr + GC_OFFSET + 0x24) /* vertical window 1
++ control */
++#define GC0AR(addr) (addr + GC_OFFSET + 0x28) /* alternate horizontal
++ window 1 control */
++#define GC0BR(addr) (addr + GC_OFFSET + 0x2c) /* alternate vertical
++ window 1 control */
++#define GC0CR(addr) (addr + GC_OFFSET + 0x30) /* window 1
++ start address */
++#define GC0DR(addr) (addr + GC_OFFSET + 0x34) /* alternate window 1
++ start address */
++#define GC0ER(addr) (addr + GC_OFFSET + 0x38) /* alternate window 1
++ stride */
++#define GC0FR(addr) (addr + GC_OFFSET + 0x3c) /* alternate window 1
++ line size */
++#define GC10R(addr) (addr + GC_OFFSET + 0x40) /* hardware cursor 1
++ position */
++#define GC11R(addr) (addr + GC_OFFSET + 0x44) /* hardware cursor 1
++ start address and
++ offset */
++#define GC12R(addr) (addr + GC_OFFSET + 0x48) /* hardware cursor 1
++ foreground color */
++#define GC13R(addr) (addr + GC_OFFSET + 0x4c) /* hardware cursor 1
++ background color */
++
++/* graphics controller 2 module */
++#define GC20R(addr) (addr + GC_OFFSET + 0x80) /* graphics controller 2
++ control */
++#define GC21R(addr) (addr + GC_OFFSET + 0x84) /* graphics controller
++ CRC control */
++#define GC22R(addr) (addr + GC_OFFSET + 0x88) /* horizontal display 2
++ control */
++#define GC23R(addr) (addr + GC_OFFSET + 0x8c) /* vertical display 2
++ control */
++#define GC24R(addr) (addr + GC_OFFSET + 0x90) /* horizontal sync 2
++ control */
++#define GC25R(addr) (addr + GC_OFFSET + 0x94) /* vertical sync 2
++ control */
++#define GC27R(addr) (addr + GC_OFFSET + 0x9c) /* vertical display 2
++ count */
++#define GC28R(addr) (addr + GC_OFFSET + 0xa0) /* horizontal window 2
++ control */
++#define GC29R(addr) (addr + GC_OFFSET + 0xa4) /* vertical window 2
++ control */
++#define GC2AR(addr) (addr + GC_OFFSET + 0xa8) /* alternate horizontal
++ window 2 control */
++#define GC2BR(addr) (addr + GC_OFFSET + 0xac) /* alternate vertical
++ window 2 control */
++#define GC2CR(addr) (addr + GC_OFFSET + 0xb0) /* window 2
++ start address */
++#define GC2DR(addr) (addr + GC_OFFSET + 0xb4) /* alternate window 2
++ start address */
++#define GC2ER(addr) (addr + GC_OFFSET + 0xb8) /* alternate window 2
++ stride */
++#define GC2FR(addr) (addr + GC_OFFSET + 0xbc) /* alternate window 2
++ line size */
++#define GC30R(addr) (addr + GC_OFFSET + 0xc0) /* hardware cursor 2
++ position */
++#define GC31R(addr) (addr + GC_OFFSET + 0xc4) /* hardware cursor 2
++ start address and
++ offset */
++#define GC32R(addr) (addr + GC_OFFSET + 0xc8) /* hardware cursor 2
++ foreground color */
++#define GC33R(addr) (addr + GC_OFFSET + 0xcc) /* hardware cursor 2
++ background color */
++
++/* graphics engine */
++#define ROP_SRCCOPY 0xCC /* dest = source */
++#define ROP_SRCPAINT 0xEE /* dest = source OR dest */
++#define ROP_SRCAND 0x88 /* dest = source AND dest */
++#define ROP_SRCINVERT 0x66 /* dest = source XOR dest */
++#define ROP_SRCERASE 0x44 /* dest = source AND (NOT dest) */
++#define ROP_NOTSRCCOPY 0x33 /* dest = NOT source */
++#define ROP_NOTSRCERASE 0x11 /* dest = (NOT source) AND (NOT dest) */
++#define ROP_MERGECOPY 0xC0 /* dest = source AND pattern */
++#define ROP_MERGEPAINT 0xBB /* dest = (NOT source) OR dest */
++#define ROP_PATCOPY 0xF0 /* dest = pattern */
++#define ROP_PATPAINT 0xFB /* dest = DPSnoo */
++#define ROP_PATINVERT 0x5A /* dest = pattern XOR dest */
++#define ROP_DSTINVERT 0x55 /* dest = NOT dest */
++#define ROP_BLACKNESS 0x00 /* dest = BLACK */
++#define ROP_WHITENESS 0xFF /* dest = WHITE */
++
++#define GE00R(addr) (addr + GE_OFFSET + 0x00) /* primary drawing command
++ register */
++#define GE01R(addr) (addr + GE_OFFSET + 0x04) /* primary width and
++ height register */
++#define GE02R(addr) (addr + GE_OFFSET + 0x08) /* primary destination
++ address register */
++#define GE03R(addr) (addr + GE_OFFSET + 0x0c) /* primary source XY
++ register */
++#define GE04R(addr) (addr + GE_OFFSET + 0x10) /* primary color compare
++ register */
++#define GE05R(addr) (addr + GE_OFFSET + 0x14) /* primary clip left/top
++ register */
++#define GE06R(addr) (addr + GE_OFFSET + 0x18) /* primary clip
++ right/bottom register
++ */
++#define GE07R(addr) (addr + GE_OFFSET + 0x1c) /* primary source and
++ pattern offset
++ register */
++#define GE08R(addr) (addr + GE_OFFSET + 0x20) /* primary foreground
++ color
++ register/rectangle
++ fill register */
++#define GE09R(addr) (addr + GE_OFFSET + 0x24) /* source stride/offset
++ register */
++#define GE0AR(addr) (addr + GE_OFFSET + 0x28) /* destination stride
++ register and color
++ depth */
++#define GE0BR(addr) (addr + GE_OFFSET + 0x2c) /* image base address
++ register */
++#define GE40R(addr) (addr + GE_OFFSET + 0x100) /* mono pattern register
++ 0 */
++#define GE41R(addr) (addr + GE_OFFSET + 0x104) /* mono pattern register
++ 1 */
++#define GE42R(addr) (addr + GE_OFFSET + 0x108) /* foreground color
++ register */
++#define GE43R(addr) (addr + GE_OFFSET + 0x10c) /* background color
++ register */
++/* color palette */
++#define C1xxR(addr, regno) \
++ (addr + CP1_OFFSET + (regno) * 4) /* graphics controller color
++ palette 1 */
++/* device configuration */
++#define DC00R(addr) (addr + DC_OFFSET + 0x00) /* device configuration
++ register 0 */
++#define DC_RESET 0x4000
++/* PCI configuration space */
++#define PC00R(addr) (addr + PCI_OFFSET + 0x00)/* device ID/vendor ID
++ register */
++/* Flatpanel Control */
++#define FP00R(addr) (addr + FPI_OFFSET + 0x00) /* Flat Panel Control 0 */
++#define FP01R(addr) (addr + FPI_OFFSET + 0x04) /* Flat Panel Output Pin */
++#define FP02R(addr) (addr + FPI_OFFSET + 0x08) /* Flat Panel Gener Purpose
++ Outout Control Register */
++#define FP03R(addr) (addr + FPI_OFFSET + 0x0c) /* General Purpose I/O Port
++ Control Register */
++#define FP04R(addr) (addr + FPI_OFFSET + 0x10) /* STN Panel Control Register */
++#define FP05R(addr) (addr + FPI_OFFSET + 0x14) /* D-STN Half Frame Buffer
++ Control Register -By Guess */
++#define FP0FR(addr) (addr + FPI_OFFSET + 0x3c) /* Pulse Width Modulation
++ Control Register */
++#define FRCTL_PATTERN_COUNT 32
++#define FP10R(addr) (addr + FPI_OFFSET + 0x40) /* Frame-Rate Control Pattern
++ Register */
++#define FP11R(addr) (addr + FPI_OFFSET + 0x44)
++#define FP2FR(addr) (addr + FPI_OFFSET + 0xc0) /* Frame-Rate Control Weight
++ Registers */
++
++
++
++
++/* power management miscellaneous control */
++union pm00r {
++ struct {
++ u32 pll1_n_b5 :1; /* PLL 1 N parameter bit 5 is 0 */
++ u32 reserved_1 :1;
++ u32 pll2_enbl :1; /* PLL 2 enable */
++ u32 pll3_enbl :1; /* PLL 3 enable */
++ u32 reserved_2 :1;
++ u32 pwr_st_ctrl :1; /* power state status control */
++ u32 reserved_3 :2;
++
++ u32 ge_enbl :1; /* graphics engine enable */
++ u32 ge_bsy_gl :1; /* graphics engine force busy (global) */
++ u32 ge_bsy_lcl :1; /* graphics engine force busy (local) */
++ u32 ge_clock :2; /* graphics engine clock select */
++ u32 ge_cmd_fifo :1; /* graphics engine command FIFO reset */
++ u32 ge_src_fifo :1; /* graphics engine CPU source FIFO reset */
++ u32 miu_pwr_seq :1; /* memory interface unit power sequencing
++ enable */
++
++ u32 d3_mem_rfsh :1; /* D3 memory refresh */
++ u32 d4_mem_rfsh :1; /* D4 memory refresh */
++ u32 gpwr_intrvl :2; /* general power sequencing interval */
++ u32 fppwr_intrvl:2; /* flat panel power sequencing interval */
++ u32 gpwr_seq_ctr:1; /* general power sequencing interval control */
++ u32 pmu_tm :1; /* PMU test mode */
++
++ u32 pwr_state :2; /* power state (read only) */
++ u32 pwr_seq_st :1; /* power sequencing active status (read
++ only) */
++ u32 reserved_4 :5;
++ } part;
++ u32 whole;
++};
++
++/* D1 state control */
++union pm01r {
++ struct {
++ u32 osc_enbl :1; /* D1 oscillator enable */
++ u32 pll1_enbl :1; /* D1 PLL 1 enable */
++ u32 pll2_enbl :1; /* D1 PLL 2 enable */
++ u32 pll3_enbl :1; /* D1 PLL 3 enable */
++ u32 miu_enbl :1; /* D1 Memory Interface Unit (MIU) enable */
++ u32 mem_rfsh :1; /* D1 memory refresh enable */
++ u32 ge_enbl :1; /* D1 Graphics Engine (GE) enable */
++ u32 reserved_1 :1;
++
++ u32 crt_enbl :1; /* D1 CRT enable */
++ u32 fpd_enbl :1; /* D1 Flat Panel enable */
++ u32 reserved_2 :6;
++
++ u32 ctl1_enbl :1; /* D1 controller 1 enable */
++ u32 win1_enbl :1; /* D1 window 1 enable */
++ u32 awin1_enbl :1; /* D1 alternate window 1 enable */
++ u32 cur1_enbl :1; /* D1 cursor 1 enable */
++ u32 reserved_3 :4;
++
++ u32 ctl2_enbl :1; /* D1 controller 2 enable */
++ u32 win2_enbl :1; /* D1 window 2 enable */
++ u32 awin2_enbl :1; /* D1 alternate window 2 enable */
++ u32 cur2_enbl :1; /* D1 cursor 2 enable */
++ u32 reserved_4 :4;
++ } part;
++ u32 whole;
++};
++
++/* D2 state control */
++union pm02r {
++ struct {
++ u32 osc_enbl :1; /* D2 oscillator enable */
++ u32 pll1_enbl :1; /* D2 PLL 1 enable */
++ u32 pll2_enbl :1; /* D2 PLL 2 enable */
++ u32 pll3_enbl :1; /* D2 PLL 3 enable */
++ u32 miu_enbl :1; /* D2 Memory Interface Unit (MIU) enable */
++ u32 mem_rfsh :1; /* D2 memory refresh enable */
++ u32 ge_enbl :1; /* D2 Graphics Engine (GE) enable */
++ u32 reserved_1 :1;
++
++ u32 crt_enbl :1; /* D2 CRT enable */
++ u32 fpd_enbl :1; /* D2 Flat Panel enable */
++ u32 reserved_2 :6;
++
++ u32 ctl1_enbl :1; /* D2 controller 1 enable */
++ u32 win1_enbl :1; /* D2 window 1 enable */
++ u32 awin1_enbl :1; /* D2 alternate window 1 enable */
++ u32 cur1_enbl :1; /* D2 cursor 1 enable */
++ u32 reserved_3 :4;
++
++ u32 ctl2_enbl :1; /* D2 controller 2 enable */
++ u32 win2_enbl :1; /* D2 window 2 enable */
++ u32 awin2_enbl :1; /* D2 alternate window 2 enable */
++ u32 cur2_enbl :1; /* D2 cursor 2 enable */
++ u32 reserved_4 :4;
++ } part;
++ u32 whole;
++};
++
++/* PLL 2 programming */
++union pm06r {
++ struct {
++ u32 clk_src :1; /* PLL 2 reference clock source */
++ u32 bypass :1; /* PLL 2 bypass */
++ u32 reserved_1 :2;
++ u32 p_par :3; /* PLL 2 P parameter */
++ u32 reserved_2 :1;
++
++ u32 n_par :5; /* PLL 2 N parameter */
++ u32 reserved_3 :3;
++
++ u32 m_par :8; /* PLL 2 M parameter */
++
++ u32 reserved_4 :4;
++ u32 trim :4; /* PLL 2 trim value */
++ } part;
++ u32 whole;
++};
++
++/* PLL 3 programming */
++union pm07r {
++ struct {
++ u32 clk_src :1; /* PLL 3 reference clock source */
++ u32 bypass :1; /* PLL 3 bypass */
++ u32 reserved_1 :2;
++ u32 p_par :3; /* PLL 3 P parameter */
++ u32 reserved_2 :1;
++
++ u32 n_par :5; /* PLL 3 N parameter */
++ u32 reserved_3 :3;
++
++ u32 m_par :8; /* PLL 3 M parameter */
++
++ u32 reserved_4 :4;
++ u32 trim :4; /* PLL 3 trim value */
++ } part;
++ u32 whole;
++};
++
++
++
++/* MIU interface control 1 */
++union mm00r {
++ struct {
++ u32 miu_enbl :1; /* MIU enable bit */
++ u32 mr_dsbl :1; /* MIU reset disable bit */
++ u32 edr_dsbl :1; /* embedded DRAM reset disable bit */
++ u32 reserved_1 :29;
++ } part;
++ u32 whole;
++};
++
++/* MIU interface control 2 */
++union mm01r {
++ struct {
++ u32 mc_src :1; /* memory clock source */
++ u32 msr_enbl :1; /* memory slow refresh enable bit */
++ u32 pb_cpu :1; /* page break enable for CPU */
++ u32 pb_gc1 :1; /* page break enable for GC1 */
++ u32 pb_gc2 :1; /* page break enable for GC2 */
++ u32 pb_stn_r :1; /* page break enable for STN read */
++ u32 pb_stn_w :1; /* page break enable for STN write */
++ u32 pb_ge :1; /* page break enable for GE */
++ u32 reserved_1 :4;
++ u32 mr_interval :14; /* normal memory refresh time interval */
++ u32 reserved_2 :4;
++ u32 edarm_enbl :1; /* embedded DRAM auto-refresh mode enable */
++ u32 eds_enbl :1; /* EDRAM standby enable for EDRAM normal
++ mode operation */
++ } part;
++ u32 whole;
++};
++
++/* memory interface control 3 */
++union mm02r {
++ struct {
++ u32 bs_ :2;
++ u32 bs_stnr :2; /* burst count for STN read memory cycles */
++ u32 bs_stnw :2; /* burst count for STN write memroy cycles */
++ u32 bs_ge :2; /* burst count for graphics engine
++ read/write memroy cycles */
++ u32 bs_cpuw :2; /* burst count for CPU write memory cycles */
++ u32 fifo_gc1 :4; /* GC1 display refresh FIFO threshold */
++ u32 fifo_gc2 :4; /* GC2 display refresh FIFO threshold */
++ u32 fifo_stnr :4; /* STN read FIFO threshold */
++ u32 fifo_stnw :4; /* STN write FIFO threshold */
++ u32 fifo_ge_src :3; /* GE source read FIFO threshold */
++ u32 fifo_ge_dst :3; /* GE destination read FIFO threshold */
++ } part;
++ u32 whole;
++};
++
++/* memory interface control 4 */
++union mm03r {
++ struct {
++ u32 rd_late_req :1; /* read latency request */
++ u32 reserved_1 :31;
++ } part;
++ u32 whole;
++};
++
++/* memory interface control 5 */
++union mm04r {
++ struct {
++ u32 latency :3; /* EDRAM latency */
++ u32 dmm_cyc :1; /* enable for the dummy cycle insertion
++ between read and write cycles */
++ u32 pre_dmm_cyc :1; /* enable for the dummy cycle insertion
++ between read/write and precharge cycles
++ for the same bank */
++ u32 reserved_1 :3;
++ u32 bnk_act_cls :2; /* bank activate command to bank close
++ command timing interval control */
++ u32 bnk_act_rw :1; /* bank activate command to read/wirte
++ command timing interval control */
++ u32 bnk_cls_act :1; /* bank close command to bank activate
++ command timing interval control */
++ u32 trc :1; /* row cycle time */
++ u32 reserved_2 :3;
++ u32 delay_r :2; /* programmable delay for read clock */
++ u32 delay_m :2; /* programmable delay for internal memory
++ clock */
++ } part;
++ u32 whole;
++};
++
++/* graphics controller 1 register */
++union gc00r {
++ struct {
++ u32 ctl_enbl :1; /* Controller 1 Enable */
++ u32 hc_reset :1; /* Horizontal Counter 1 Reset */
++ u32 vc_reset :1; /* Vertical Counter 1 Reset */
++ u32 iwin_enbl :1; /* Image Window 1 Enable */
++ u32 gcd :4; /* Graphics Color Depth (GCD) */
++
++ u32 hc_enbl :1; /* Hardware Cursor 1 Enable */
++ u32 reserved_1 :2;
++ u32 aiwin_enbl :1; /* Alternate Image Window Enable */
++ u32 agcd :4; /* Alternate Graphics Color Depth (AGCD) */
++
++ u32 g1rclk_src :2; /* G1RCLK Source */
++ u32 tm0 :1; /* Test Mode 0 */
++ u32 tm1 :1; /* Test Mode 1 */
++ u32 fd :3; /* G1MCLK First Clock Divisor (FD1) */
++ u32 reserved_2 :1;
++
++ u32 sd :8; /* G1MCLK Second Clock Divisor (SD1) */
++ } part;
++ u32 whole;
++};
++
++/* graphics controller CRT control */
++union gc01r {
++ struct {
++ u32 dac_enbl :2; /* CRT DAC enable */
++ u32 hsync_out :1; /* CRT HSYNC output during power down mode */
++ u32 vsync_out :1; /* CRT VSYNC output during power down mode */
++ u32 hsync_ctl :2; /* CRT HSYNC control */
++ u32 vsync_ctl :2; /* CRT VSYNC control */
++ /**/
++ u32 hsync_pol :1; /* CRT HSYNC polarity */
++ u32 vsync_pol :1; /* CRT VSYNC polarity */
++ u32 sync_p_enbl :1; /* sync pedestal enable */
++ u32 blnk_p_enbl :1; /* blank pedestal enable */
++ u32 c_sync_enbl :1; /* composite sync enable */
++ u32 vref_sel :1; /* VREF select */
++ u32 mn_sns_enbl :1; /* monitor sense enable */
++ u32 ct_out_enbl :1; /* constant output enable */
++ /**/
++ u32 dac_out_lvl :8; /* monitor sense DAC output level */
++ /**/
++ u32 blue_dac_r :1; /* blue DAC sense result */
++ u32 green_dac_r :1; /* green DAC sense result */
++ u32 red_dac_r :1; /* red DAC sense result */
++ u32 reserved_1 :1;
++ u32 mon_col_sel :1; /* mono/color monitor select */
++ u32 reserved_2 :3;
++ } part;
++ u32 whole;
++};
++
++/* horizontal display 1 control */
++union gc02r {
++ struct {
++ u32 hd1t :12; /* horizontal display 1 total */
++ u32 reserved_1 :4;
++
++ u32 hd1e :12; /* horizontal display 1 end */
++ u32 reserved_2 :4;
++ } part;
++ u32 whole;
++};
++
++/* vertical display 1 control */
++union gc03r {
++ struct {
++ u32 vd1t :12; /* vertical display 1 total */
++ u32 reserved_1 :4;
++
++ u32 vd1e :12; /* vertical display 1 end */
++ u32 reserved_2 :4;
++ } part;
++ u32 whole;
++};
++
++/* horizontal sync 1 control */
++union gc04r {
++ struct {
++ u32 hs1s :12; /* horizontal sync 1 start */
++ u32 reserved_1 :4;
++
++ u32 hs1e :12; /* horizontal sync 1 end */
++ u32 reserved_2 :4;
++ } part;
++ u32 whole;
++};
++
++/* vertical sync 1 control */
++union gc05r {
++ struct {
++ u32 vs1s :12; /* vertical sync 1 start */
++ u32 reserved_1 :4;
++
++ u32 vs1e :12; /* vertical sync 1 end */
++ u32 reserved_2 :4;
++ } part;
++ u32 whole;
++};
++
++/* vertical display 1 count */
++union gc07r {
++ struct {
++ u32 vd_cnt :12; /* vertical display 1 count */
++ u32 reverved_1 :20;
++ } part;
++ u32 whole;
++};
++
++/* horizontal window 1 control */
++union gc08r {
++ struct {
++ u32 hw1s :12; /* horizontal window 1 start (HW1S) */
++ u32 reserved_1 :4;
++
++ u32 hw1w :12; /* horizontal window 1 width (HW1W) */
++ u32 w1ald :4; /* window 1 additional line data */
++ } part;
++ u32 whole;
++};
++
++/* vertical window 1 control */
++union gc09r {
++ struct {
++ u32 vw1s :12; /* vertical window 1 start */
++ u32 reserved_1 :4;
++ u32 vw1h :12; /* vertical window 1 height */
++ u32 reserved_2 :4;
++ } part;
++ u32 whole;
++};
++
++/* window 1 start address */
++union gc0cr {
++ struct {
++ u32 w1sa :21; /* window 1 start address */
++ u32 reserved_1 :11;
++ } part;
++ u32 whole;
++};
++
++/* window 1 stride */
++union gc0er {
++ struct {
++ s16 w1st; /* window 1 stride */
++ s16 aw1st; /* alternate window 1 stride */
++ } part;
++ u32 whole;
++};
++
++/* hardware cursor 1 position */
++union gc10r {
++ struct {
++ u32 hc1s :12; /* horizontal cursor 1 start */
++ u32 reserved_1 :4;
++ u32 vc1s :12; /* vertical cursor 1 start */
++ u32 reserved_2 :4;
++ } part;
++ u32 whole;
++};
++
++/* hardware cursor 1 start address and offset */
++union gc11r {
++ struct {
++ u32 hc1sa :11; /* hardware cursor 1 start address */
++ u32 reserved_1 :5;
++ u32 hc1o :6; /* horizontal cursor 1 offset */
++ u32 reserved_2 :2;
++ u32 vc1o :6; /* vertical cursor 1 offset */
++ u32 reserved_3 :2;
++ } part;
++ u32 whole;
++};
++
++/* hardware cursor 1 foreground color */
++union gc12r {
++ struct {
++ u32 hc1fc :24; /* hardware cursor 1 foreground color */
++ u32 reserved_1 :8;
++ } part;
++ u32 whole;
++};
++
++/* hardware cursor 1 background color */
++union gc13r {
++ struct {
++ u32 hc1bc :24; /* hardware cursor 1 background color */
++ u32 reserved_1 :8;
++ } part;
++ u32 whole;
++};
++
++
++/* graphics controller 2 register */
++union gc20r {
++ struct {
++ u32 ctl_enbl :1; /* Controller 2 Enable */
++ u32 hc_reset :1; /* Horizontal Counter 2 Reset */
++ u32 vc_reset :1; /* Vertical Counter 2 Reset */
++ u32 iwin_enbl :1; /* Image Window 2 Enable */
++ u32 gcd :4; /* Graphics Color Depth (GCD) */
++
++ u32 hc_enbl :1; /* Hardware Cursor 2 Enable */
++ u32 reserved_1 :2;
++ u32 aiwin_enbl :1; /* Alternate Image Window Enable */
++ u32 agcd :4; /* Alternate Graphics Color Depth (AGCD) */
++
++ u32 g2rclk_src :2; /* G2RCLK Source */
++ u32 tm0 :1; /* Test Mode 0 */
++ u32 tm1 :1; /* Test Mode 1 */
++ u32 fd :3; /* G2MCLK First Clock Divisor (FD1) */
++ u32 reserved_2 :1;
++
++ u32 sd :8; /* G2MCLK Second Clock Divisor (SD1) */
++ } part;
++ u32 whole;
++};
++
++/* graphics controller CRC control */
++union gc21r {
++ struct {
++ u32 crc_enbl :1; /* CRC enable */
++ u32 vsync_wait :1; /* CRC input data control waitime of VSYNC */
++ u32 crc_o_sel :2; /* CRC output select */
++ u32 reserved_1 :4;
++ u32 crc_result :22; /* CRC result (read only) */
++ u32 reserved_2 :2;
++ } part;
++ u32 whole;
++};
++
++/* horizontal display 2 control */
++union gc22r {
++ struct {
++ u32 hd2t :12; /* horizontal display 2 total */
++ u32 reserved_1 :4;
++
++ u32 hd2e :12; /* horizontal display 2 end */
++ u32 reserved_2 :4;
++ } part;
++ u32 whole;
++};
++
++/* vertical display 2 control */
++union gc23r {
++ struct {
++ u32 vd2t :12; /* vertical display 2 total */
++ u32 reserved_1 :4;
++
++ u32 vd2e :12; /* vertical display 2 end */
++ u32 reserved_2 :4;
++ } part;
++ u32 whole;
++};
++
++/* horizontal sync 2 control */
++union gc24r {
++ struct {
++ u32 hs2s :12; /* horizontal sync 2 start */
++ u32 reserved_1 :4;
++
++ u32 hs2e :12; /* horizontal sync 2 end */
++ u32 reserved_2 :4;
++ } part;
++ u32 whole;
++};
++
++/* vertical sync 2 control */
++union gc25r {
++ struct {
++ u32 vs2s :12; /* vertical sync 2 start */
++ u32 reserved_1 :4;
++
++ u32 vs2e :12; /* vertical sync 2 end */
++ u32 reserved_2 :4;
++ } part;
++ u32 whole;
++};
++
++/* vertical display 2 count */
++union gc27r {
++ struct {
++ u32 vd_cnt :12; /* vertical display 2 count */
++ u32 reverved_1 :20;
++ } part;
++ u32 whole;
++};
++
++/* horizontal window 2 control */
++union gc28r {
++ struct {
++ u32 hw2s :12; /* horizontal window 2 start (HW2S) */
++ u32 reserved_1 :4;
++
++ u32 hw2w :12; /* horizontal window 2 width (HW2W) */
++ u32 w2ald :4; /* window 2 additional line data */
++ } part;
++ u32 whole;
++};
++
++/* vertical window 2 control */
++union gc29r {
++ struct {
++ u32 vw2s :12; /* vertical window 2 start */
++ u32 reserved_1 :4;
++ u32 vw2h :12; /* vertical window 2 height */
++ u32 reserved_2 :4;
++ } part;
++ u32 whole;
++};
++
++/* window 2 start address */
++union gc2cr {
++ struct {
++ u32 w2sa :21; /* window 2 start address */
++ u32 reserved_1 :11;
++ } part;
++ u32 whole;
++};
++
++/* window 2 stride */
++union gc2er {
++ struct {
++ s16 w2st; /* window 2 stride */
++ s16 aw2st; /* alternate window 2 stride */
++ } part;
++ u32 whole;
++};
++
++/* hardware cursor 2 position */
++union gc30r {
++ struct {
++ u32 hc2s :12; /* horizontal cursor 2 start */
++ u32 reserved_1 :4;
++ u32 vc2s :12; /* vertical cursor 2 start */
++ u32 reserved_2 :4;
++ } part;
++ u32 whole;
++};
++
++/* hardware cursor 2 start address and offset */
++union gc31r {
++ struct {
++ u32 hc2sa :11; /* hardware cursor 2 start address */
++ u32 reserved_1 :5;
++ u32 hc2o :6; /* horizontal cursor 2 offset */
++ u32 reserved_2 :2;
++ u32 vc2o :6; /* vertical cursor 2 offset */
++ u32 reserved_3 :2;
++ } part;
++ u32 whole;
++};
++
++/* hardware cursor 2 foreground color */
++union gc32r {
++ struct {
++ u32 hc2fc :24; /* hardware cursor 2 foreground color */
++ u32 reserved_1 :8;
++ } part;
++ u32 whole;
++};
++
++/* hardware cursor 2 background color */
++union gc33r {
++ struct {
++ u32 hc2bc :24; /* hardware cursor 2 background color */
++ u32 reserved_1 :8;
++ } part;
++ u32 whole;
++};
++
++
++/* primary drawing command register */
++union ge00r {
++ struct {
++ u32 rop :8; /* raster operation */
++ /**/
++ u32 cmd_typ :3; /* command type */
++ u32 x_dir :1; /* x direction */
++ u32 y_dir :1; /* y direction */
++ u32 src_mem :1; /* source memory */
++ u32 mon_src :1; /* mono source */
++ u32 mon_ptn :1; /* mono pattern */
++ /**/
++ u32 dst_trns_e :1; /* destination transparency enable */
++ u32 dst_trns_p :1; /* destination transparency polarity */
++ u32 mon_trns_e :1; /* mono source or mono pattern transparency
++ enable */
++ u32 mon_trns_p :1; /* mono transparency polarity */
++ u32 mod_sel :1; /* memory to screen or off screen to screen
++ mode select */
++ u32 alpha_sel :2; /* Alpha byte mask selection */
++ u32 sol_col :1; /* solid color */
++ /**/
++ u32 stride_eq :1; /* source stride is equal to destination
++ stride */
++ u32 rop2_sel :1; /* ROP2 code selection */
++ u32 clipping :1; /* enable clipping */
++ u32 auto_exec :1; /* auto execute */
++ u32 reserved_1 :4;
++ } part;
++ u32 whole;
++};
++
++/* primary width and height register */
++union ge01r {
++ struct {
++ u32 width :12; /* source/destination window width */
++ u32 reserved_1 :4;
++
++ u32 height :12; /* source/destination window height */
++ u32 reserved_2 :1;
++ u32 reserved_3 :3;
++ } bitblt;
++ struct {
++ u32 dm :17;
++ u32 axis_major :12;
++ u32 x_y :1; /* x-major or y-major */
++ u32 last_pix :1; /* decision to draw or not to draw the last
++ pixel of the line */
++ u32 reserved_1 :1;
++ } bresenham;
++ u32 whole;
++};
++
++/* primary destination address register */
++union ge02r {
++ struct {
++ u32 dst_x :12; /* destination x position */
++ u32 reserved_1 :1;
++ u32 h_offset :3; /* mono/color pattern horizontal offset */
++
++ u32 dst_y :12; /* destination y position */
++ u32 reserved_2 :1;
++ u32 v_offset :3; /* mono/color pattern vertical offset */
++ } window;
++ struct {
++ u32 x :12; /* starting x coordinate */
++ u32 dm :17; /* 17 bits major-axis delta */
++ u32 reserved_1 :3;
++ } line;
++ u32 whole;
++};
++
++/* source XY register/line draw starting Y coordinate and mintor axis delta */
++union ge03r {
++ struct {
++ u32 src_x :12; /* source X position */
++ u32 reserved_1 :4;
++
++ u32 src_y :12; /* source Y position */
++ u32 reserved_2 :4;
++ } window;
++ struct {
++ u32 start_y :12; /* starting Y coordinate */
++ u32 dn :17; /* 17 bits minor-axis delta */
++ u32 reserved_1 :3;
++ } line;
++ u32 whole;
++};
++
++/* clip left/top register */
++union ge05r {
++ struct {
++ u32 left :12; /* left edge of clipping rectangle */
++ u32 reserved_1 :4;
++
++ u32 top :12; /* top edge of clipping rectangle */
++ u32 reserved_2 :4;
++ } part;
++ u32 whole;
++};
++
++/* source stride/offset register */
++union ge09r {
++ struct {
++ u32 src_strid :12; /* source line stride */
++ u32 reserved_1 :13;
++ u32 strt_bit :3; /* initial mono source bit offset */
++ u32 strt_byte :3; /* initial mono/color source byte offset */
++ u32 reserved_2 :1;
++ } line;
++ struct {
++ u32 strt_bit :5; /* initial mono source bit offset */
++ u32 reserved_1 :1;
++ u32 amount :10; /* number of 16 bytes amount that MIU need
++ to fetch from frame buffer */
++
++ u32 reserved_2 :9;
++ u32 bit_spc :7; /* bit space between lines */
++ } pack_mono;
++ struct {
++ u32 strt_bit :3; /* initial mono source bit offset */
++ u32 strt_byte :3; /* initial mono/color source byte offset */
++ u32 amount :10; /* number of 16 bytes amount that MIU need
++ to fetch from frame buffer */
++
++ u32 reserved_1 :9;
++ u32 bit_spc :3; /* bit space between lines */
++ u32 byt_spc :4; /* byte space between lines */
++ } pack_color;
++ u32 whole;
++};
++
++/* destination stride register and color depth */
++union ge0ar {
++ struct {
++ u32 dst_strid :12; /* destination line stride and color depth */
++ u32 reserved_1 :18;
++ u32 col_dpth :2; /* color depth */
++ } part;
++ u32 whole;
++};
++
++/* graphics controller color pallete */
++union c1xxr {
++ struct {
++ u8 red; /* red color pallete */
++ u8 green; /* green/gray color pallete */
++ u8 blue; /* blue color palette */
++ u8 reserved_1;
++ } part;
++ u32 whole;
++};
++
++/* devicee configuration register 0 */
++union dc00r {
++ struct {
++ u32 osc_bypass :1; /* oscillator bypass */
++ u32 osc_enbl :1; /* oscillator enable */
++ u32 pll1_bypass :1; /* PLL1 bypass */
++ u32 pll1_enbl :1; /* PLL1 enable */
++ u32 pll1_p_par :3; /* PLL1 P parameter */
++ u32 cpu_div :1; /* CPU interface clock divisor */
++ u32 pll1_n_par :5; /* PLL1 N parameter */
++ u32 saisc :1; /* StrongARM interface synchronizer control */
++ u32 s_chp_reset :1; /* software chip reset */
++ u32 mem_enbl :1; /* memory standby enable */
++ u32 pll1_m_par :8; /* PLL 1 M parameter */
++ u32 osc_shaper :1; /* oscillator shaper disable */
++ u32 fast_pwr :1; /* fast power sequencing */
++ u32 osc_frq :2; /* oscillator frequency select */
++ u32 pll1_trim :4; /* PLL 1 trim value */
++ } part;
++ u32 whole;
++};
++
++/* device ID/vendor ID register */
++union pc00r {
++ struct {
++ u16 device; /* device ID */
++ u16 vendor; /* vendor ID */
++ } part;
++ u32 whole;
++};
++
++/* Flat Panel Control Register */
++union fp00r {
++ struct {
++ u32 flatp_enbl : 2; /* Flat Panel Interface Enable */
++ u32 flatp_type : 2; /* Flat Panel Type */
++ u32 mono : 1; /* Mono/Color Panel Select */
++ u32 flatp_intf : 3; /* Flat Panel Interface */
++ u32 dither_pat : 2; /* Dither Pattern */
++ u32 reserved : 2; /* Reserved Must Be 0*/
++ u32 dither_col : 3; /* Dither Base Color */
++ u32 alt_win_ctl: 1; /* Alternate Window Control */
++ u32 frc_ctl : 2; /* FRC Control */
++ u32 dither_adj1: 6; /* Dither Pattern Adjust 1 */
++ u32 dither_adj2: 3; /* Dither Pattern Adjust 2 */
++ u32 dither_adj3: 1; /* Dither Pattern Adjust 3 */
++ u32 test_mode0 : 1; /* Test Mode 0 */
++ u32 test_mode1 : 1; /* Test Mode 1 */
++ u32 test_mode2 : 1; /* Test Mode 2 */
++ u32 test_mode3 : 1; /* Test Mode 3 */
++ } part;
++ u32 whole;
++};
++
++union fp01r {
++ struct {
++ u32 dummy;
++ } part;
++ u32 whole;
++};
++
++union fp02r {
++ struct {
++ u32 dummy;
++ } part;
++ u32 whole;
++};
++
++union fp03r {
++ struct {
++ u32 dummy;
++ } part;
++ u32 whole;
++};
++
++union fp04r {
++ struct {
++ u32 dummy;
++ } part;
++ u32 whole;
++};
++
++union fp05r {
++ struct {
++ u32 dummy;
++ } part;
++ u32 whole;
++};
++
++union fp0fr {
++ struct {
++ u32 dummy;
++ } part;
++ u32 whole;
++};
++
++
++
++
++/****
++ * Others
++ */
++
++#define CHIPNAME "MQ-200"
++
++extern void mq200_external_setpal(unsigned regno, unsigned long color, unsigned long addr);
++extern void mq200_external_setqmode(struct mq200_monitor_info*, unsigned long, spinlock_t *);
++extern void mq200_external_offdisplay(unsigned long);
++extern void mq200_external_ondisplay (unsigned long);
++extern int mq200_external_probe(unsigned long);
++
++
++
++#endif
+Index: linux-2.6.27/drivers/video/mq200/mq_external.c
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.27/drivers/video/mq200/mq_external.c 2008-12-07 01:35:01.269407967 +0100
+@@ -0,0 +1,513 @@
++/*
++ * Copyright (C) 2005 Holger Hans Peter Freyther
++ *
++ * Based ON:
++ *
++ * linux/drivers/video/mq200fb.c -- MQ-200 for a frame buffer device
++ * based on linux/driver/video/pm2fb.c
++ *
++ * 2007/03/11 mrdata:
++ * bug found in gc1_reset(), renaming to gc1_gc2_reset()
++ * extend mq200_external_ondisplay() -> LCD for GC2 and CRT for GC1
++ *
++ * Copyright (C) 2000 Lineo, Japan
++ *
++ * 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 <asm/types.h>
++#include <asm/io.h>
++#include <linux/delay.h>
++#include <linux/spinlock.h>
++
++#include <mach/hardware.h>
++
++#include "mq200_data.h"
++
++
++#if 1
++#define PRINTK(args...) printk(args)
++#else
++#define PRINTK(args...)
++#endif
++
++
++/****
++ * power state transition to "state".
++ */
++static void
++power_state_transition(unsigned long register_base, int state)
++{
++ int i;
++ writel(state, PMCSR(register_base));
++ mdelay(300);
++ for (i = 1; ; i++) {
++ udelay(100);
++ if ((readl(PMCSR(register_base)) & 0x3) == state) {
++ break;
++ }
++ }
++}
++
++
++/****
++ * device configuration initialization.
++ */
++static void
++dc_reset(unsigned long register_base)
++{
++ union dc00r dc00r;
++
++ /* Reset First */
++ dc00r.whole = DC_RESET;
++ writel(dc00r.whole, DC00R(register_base));
++ mdelay(100);
++
++ dc00r.whole = 0xEF2082A;
++ writel(dc00r.whole, DC00R(register_base));
++ mdelay(300);
++ PRINTK(CHIPNAME ": DC00R = 0x%08X\n", readl(DC00R(register_base)));
++}
++
++
++/****
++ * initialize memory interface unit.
++ */
++static void
++miu_reset(unsigned long register_base)
++{
++ union mm00r mm00r;
++ union mm01r mm01r;
++ union mm02r mm02r;
++ union mm03r mm03r;
++ union mm04r mm04r;
++
++ /* MIU interface control 1 */
++ mm00r.whole = 0x4;
++ writel(mm00r.whole, MM00R(register_base));
++ mdelay(50);
++ writel(0, MM00R(register_base));
++ mdelay(50);
++
++ /* MIU interface control 2
++ * o PLL 1 output is used as memory clock source.
++ */
++ mm01r.whole = 0x4143e086;
++ writel(mm01r.whole, MM01R(register_base));
++
++ /* memory interface control 3 */
++ mm02r.whole = 0x6d6aabff;
++ writel(mm02r.whole, MM02R(register_base));
++
++ /* memory interface control 5 */
++ mm04r.whole = 0x10d;
++ writel(mm04r.whole, MM04R(register_base));
++
++ /* memory interface control 4 */
++ mm03r.whole = 0x1;
++ writel(mm03r.whole, MM03R(register_base));
++ mdelay(50);
++
++ /* MIU interface control 1 */
++ mm00r.whole = 0x3;
++ writel(mm00r.whole, MM00R(register_base));
++ mdelay(50);
++}
++
++/****
++ *
++ */
++static
++void fpctrl_reset(unsigned long addr)
++{
++ /*
++ * We're in D0 State, let us set the FPCTRL
++ */
++ union fp00r fp00r;
++ union fp01r fp01r;
++ union fp02r fp02r;
++ union fp03r fp03r;
++ union fp04r fp04r;
++ union fp0fr fp0fr;
++
++ fp00r.whole = 0x6320;
++ writel(fp00r.whole, FP00R(addr));
++
++ fp01r.whole = 0x20;
++ writel(fp01r.whole, FP01R(addr));
++
++ fp04r.whole = 0xBD0001;
++ writel(fp04r.whole, FP04R(addr));
++
++ /* Set Flat Panel General Purpose register first */
++ fp02r.whole = 0x0;
++ writel(fp02r.whole, FP02R(addr));
++
++ fp03r.whole = 0x0;
++ writel(fp03r.whole, FP03R(addr));
++
++ fp0fr.whole = 0xA16c44;
++ writel(fp0fr.whole, FP0FR(addr));
++
++ /* Set them again */
++ fp02r.whole = 0x0;
++ writel(fp02r.whole, FP02R(addr));
++
++ fp03r.whole = 0x0;
++ writel(fp03r.whole, FP03R(addr));
++}
++
++
++/****
++ * initialize power management unit.
++ */
++static void
++pmu_reset(unsigned long register_base)
++{
++ union pm00r pm00r;
++ union pm01r pm01r;
++ union pm02r pm02r;
++
++ /* power management miscellaneous control
++ * o GE is driven by PLL 1 clock.
++ */
++ pm00r.whole = 0xc0900;
++ writel(pm00r.whole, PM00R(register_base));
++
++ /* D1 state control */
++ pm01r.whole = 0x5000271;
++ writel(pm01r.whole, PM01R(register_base));
++
++ /* D2 state control */
++ pm02r.whole = 0x271;
++ writel(pm02r.whole, PM02R(register_base));
++}
++
++/****
++ * initialize graphics controller 1
++ * and graphics controller 2
++ */
++static void
++gc1_gc2_reset(unsigned long register_base, spinlock_t *lock )
++{
++ unsigned long flags;
++ union gc00r gc00r;
++ union gc01r gc01r;
++ union gc02r gc02r;
++ union gc03r gc03r;
++ union gc04r gc04r;
++ union gc05r gc05r;
++ union gc08r gc08r;
++ union gc09r gc09r;
++ union gc0cr gc0cr;
++ union gc0er gc0er;
++ union gc20r gc20r;
++ union gc22r gc22r;
++ union gc23r gc23r;
++ union gc24r gc24r;
++ union gc25r gc25r;
++ union gc28r gc28r;
++ union gc29r gc29r;
++ union gc2cr gc2cr;
++ union gc2er gc2er;
++
++ union pm00r pm00r;
++ union pm06r pm06r;
++ union pm06r pm07r;
++
++ spin_lock_irqsave(lock, flags);
++
++ /* alternate window 1 stride */
++ gc0er.whole = 0x640;
++ writel(gc0er.whole, GC0ER(register_base));
++
++ /* image window 1 start address */
++ gc0cr.whole = 0x0;
++ writel(gc0cr.whole, GC0CR(register_base));
++
++ /* alternate window 2 stride */
++ gc2er.whole = 0x640;
++ writel(gc0er.whole, GC2ER(register_base));
++
++ /* image window 2 start address */
++ gc2cr.whole = 0x0;
++ writel(gc2cr.whole, GC2CR(register_base));
++
++ /* read PM Register */
++ pm00r.whole = readl(PM00R(register_base));
++
++ /* horizontal window 1 control */
++ gc08r.whole = 0x131f0000;
++ writel(gc08r.whole, GC08R(register_base));
++
++ /* vertical window 1 control */
++ gc09r.whole = 0x12570000;
++ writel(gc09r.whole, GC09R(register_base));
++
++ /* horizontal display 1 control */
++ gc02r.whole = 0x320041e;
++ writel(gc02r.whole, GC02R(register_base));
++
++ /* vertical display 1 control */
++ gc03r.whole = 0x2570273;
++ writel(gc03r.whole, GC03R(register_base));
++
++ /* horizontal sync 1 control */
++ gc04r.whole = 0x3c70347;
++ writel(gc04r.whole, GC04R(register_base));
++
++ /* vertical sync 1 control */
++ gc05r.whole = 0x25d0259;
++ writel(gc05r.whole, GC05R(register_base));
++
++ /* graphics controller CRT control */
++ gc01r.whole = 0x800;
++ writel(gc01r.whole, GC01R(register_base));
++
++ /* PLL 2 programming */
++ pm06r.whole = 0xE90830;
++ writel(pm06r.whole, PM06R(register_base));
++
++ /* graphics controller 1 register
++ * o GC1 clock source is PLL 2.
++ * o hardware cursor is disabled.
++ */
++ gc00r.whole = 0x10000C8 | 0x20000;
++ writel(gc00r.whole, GC00R(register_base));
++
++#if 0
++ /* alternate horizontal window 1 control */
++ writel(0, GC0AR(register_base));
++
++ /* alternate vertical window 1 control */
++ writel(0, GC0BR(register_base));
++
++ /* window 1 start address */
++ writel(0x2004100, GC0CR(register_base));
++
++ /* alternate window 1 start address */
++ writel(0, GC0DR(register_base));
++
++ /* window 1 stride */
++ gc0er.whole = 0x5100048;
++ writel(gc0er.whole, GC0ER(register_base));
++
++ /* reserved register - ??? - */
++ writel(0x31f, GC0FR(register_base));
++#endif
++
++#if 0
++ /* hardware cursor 1 position */
++ writel(0, GC10R(register_base));
++
++ /* hardware cursor 1 start address and offset */
++ gc11r.whole = 0x5100048;
++ writel(gc11r.whole, GC11R(register_base));
++
++ /* hardware cursor 1 foreground color */
++ writel(0x00ffffff, GC12R(register_base));
++
++ /* hardware cursor 1 background color */
++ writel(0x00000000, GC13R(register_base));
++#endif
++
++ /* horizontal window 2 control */
++ gc28r.whole = 0x31f0000;
++ writel(gc28r.whole, GC28R(register_base));
++
++ /* vertical window 2 control */
++ gc29r.whole = 0x2570000;
++ writel(gc29r.whole, GC29R(register_base));
++
++ /* horizontal display 2 control */
++ gc22r.whole = 0x320041e;
++ writel(gc22r.whole, GC22R(register_base));
++
++ /* vertical display 2 control */
++ gc23r.whole = 0x2570273;
++ writel(gc23r.whole, GC23R(register_base));
++
++ /* horizontal sync 2 control */
++ gc24r.whole = 0x3c70347;
++ writel(gc24r.whole, GC24R(register_base));
++
++ /* vertical sync 2 control */
++ gc25r.whole = 0x25d0259;
++ writel(gc25r.whole, GC25R(register_base));
++
++ /* graphics controller CRT control */
++ gc01r.whole = 0x800;
++ writel(gc01r.whole, GC01R(register_base));
++
++ /* PLL 3 programming */
++ pm07r.whole = 0xE90830;
++ writel(pm07r.whole, PM07R(register_base));
++
++ /* graphics controller 2 register
++ * o GC2 clock source is PLL 3.
++ * o hardware cursor is disabled.
++ */
++ gc20r.whole = 0x10000C8 | 0x30000;
++ writel(gc20r.whole, GC20R(register_base));
++
++ /*
++ * Enable PLL2 and PLL3 in the PM Register
++ */
++ pm00r.part.pll2_enbl = 0x1;
++ pm00r.part.pll3_enbl = 0x1;
++ writel(pm00r.whole, PM00R(register_base));
++
++ spin_unlock_irqrestore(lock, flags);
++}
++
++
++/****
++ * initialize graphics engine.
++ */
++static void
++ge_reset(unsigned long register_base)
++{
++ /* drawing command register */
++ writel(0, GE00R(register_base));
++
++ /* promary width and height register */
++ writel(0, GE01R(register_base));
++
++ /* primary destination address register */
++ writel(0, GE02R(register_base));
++
++ /* primary source XY register */
++ writel(0, GE03R(register_base));
++
++ /* primary color compare register */
++ writel(0, GE04R(register_base));
++
++ /* primary clip left/top register */
++ writel(0, GE05R(register_base));
++
++ /* primary clip right/bottom register */
++ writel(0, GE06R(register_base));
++
++ /* primary source and pattern offset register */
++ writel(0, GE07R(register_base));
++
++ /* primary foreground color register/rectangle fill color depth */
++ writel(0, GE08R(register_base));
++
++ /* source stride/offset register */
++ writel(0, GE09R(register_base));
++
++ /* destination stride register and color depth */
++ writel(0, GE0AR(register_base));
++
++ /* image base address register */
++ writel(0, GE0BR(register_base));
++}
++
++/****
++ * initialize Color Palette 1.
++ */
++static void
++cp1_reset(unsigned long addr_info)
++{
++ int i;
++
++ for (i = 0; i < 256; i++)
++ writel(0, C1xxR(addr_info, i));
++}
++
++
++/*
++ * Below functions are called from the skeleton
++ */
++void mq200_external_setpal(unsigned regno, unsigned long color, unsigned long addr)
++{
++ writel(color,C1xxR(addr,regno));
++}
++
++void mq200_external_setqmode(struct mq200_monitor_info* info,
++ unsigned long addr, spinlock_t *lock)
++{
++ dc_reset(addr); /* device configuration */
++
++ power_state_transition(addr, 0); /* transition to D0 state */
++
++ pmu_reset(addr); /* power management unit */
++
++ miu_reset(addr); /* memory interface unit */
++
++ ge_reset(addr); /* graphics engine */
++
++ fpctrl_reset(addr); /* reset the panel settings */
++
++ gc1_gc2_reset(addr, lock); /* graphics controller 1 and 2 */
++
++ cp1_reset(addr); /* color palette 1 */
++
++ mq200_external_ondisplay(addr); /* LCD and CRT */
++}
++
++void mq200_external_offdisplay(unsigned long addr)
++{
++ /*
++ * Move the MQ200 to D3 mode
++ */
++ power_state_transition(addr, 3);
++}
++
++/**
++ * to be called after mq200_external_setqmode
++ */
++void mq200_external_ondisplay (unsigned long addr)
++{
++ /*
++ * Set the framebuffer details
++ */
++ union gc00r gc00r;
++ union gc01r gc01r;
++ union gc20r gc20r;
++ union fp00r fp00r;
++
++ /* enable LCD for GC2 */
++ fp00r.whole = readl(FP00R(addr));
++ fp00r.whole &= 0xfffffffc;
++
++ gc20r.whole = readl(GC20R(addr));
++
++ if(!(gc20r.whole & 0x1)) {
++ gc20r.whole |= 0x1;
++ writel(gc20r.whole, GC20R(addr));
++ }
++
++ fp00r.whole |= 0x3;
++ writel(fp00r.whole, FP00R(addr));
++
++ /* enable CRT for GC1 */
++ gc00r.whole = readl(GC00R(addr));
++
++ if(!(gc00r.whole & 0x1)) {
++ gc00r.whole |= 0x1;
++ writel(gc00r.whole, GC00R(addr));
++ }
++
++ gc01r.whole = readl(GC01R(addr));
++ gc01r.whole &= 0xfffffffc;
++
++ gc01r.whole |= 0x1;
++ writel(gc01r.whole, GC01R(addr));
++
++}
++
++int mq200_external_probe(unsigned long addr)
++{
++ union pc00r pc00r;
++ if(readl(PMR(addr)) != PMR_VALUE)
++ return 0;
++
++ pc00r.whole = readl(PC00R(addr));
++ printk(KERN_INFO "mq200 video driver found Vendor: 0x%X Device: 0x%X\n",
++ pc00r.part.device, pc00r.part.vendor);
++ return 1;
++}
+Index: linux-2.6.27/drivers/video/mq200/mq_skeleton.c
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.27/drivers/video/mq200/mq_skeleton.c 2008-12-07 01:34:29.666075531 +0100
+@@ -0,0 +1,398 @@
++/*
++ * Author: Holger Hans Peter Freyther
++ *
++ *
++ * This implements the frame buffer driver interface to communicate
++ * with the kernel.
++ * It uses the mq200 routines from the ucLinux driver from Lineo
++ *
++ * 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/autoconf.h>
++#include <linux/platform_device.h>
++#include <linux/module.h>
++#include <linux/fb.h>
++#include <linux/types.h>
++#include <linux/spinlock.h>
++
++#include "mq200_data.h"
++
++#if CONFIG_SA1100_SIMPAD
++/*
++ * Siemens SIMpad specefic data
++ */
++#include <mach/simpad.h>
++#include <mach/hardware.h>
++
++#define MQ200_REGIONS simpad_mq200_regions
++#define MQ200_MONITOR simpad_mq200_panel
++
++static struct mq200_io_regions simpad_mq200_regions = {
++ .fb_size = MQ200_FB_SIZE,
++ .phys_mmio_base = 0x4be00000,
++ .virt_mmio_base = 0xf2e00000,
++ .phys_fb_base = 0x4b800000,
++ .virt_fb_base = 0xf2800000,
++};
++
++static struct mq200_monitor_info simpad_mq200_panel = {
++ .horizontal_res = 800,
++ .vertical_res = 600,
++ .depth = 16,
++ .refresh = 60,
++ .line_length = 1600,
++ .flags = 0x00130004,
++};
++
++extern long get_cs3_shadow(void);
++extern void set_cs3_bit(int value);
++extern void clear_cs3_bit(int value);
++#endif
++
++
++
++struct mq200_info {
++ struct fb_info fb_info;
++ struct mq200_io_regions io_regions;
++ struct mq200_monitor_info monitor_info;
++
++ /* palette */
++ u32 pseudo_palette[17]; /* 16 colors + 1 in reserve not that well documented... */
++ spinlock_t lock;
++};
++
++
++
++static int mq200_blank( int blank_mode, struct fb_info *info )
++{
++#ifdef CONFIG_SA1100_SIMPAD
++ if(blank_mode ){
++ clear_cs3_bit(DISPLAY_ON);
++ }else {
++ set_cs3_bit(DISPLAY_ON);
++ }
++#endif
++ return 0;
++}
++
++
++static int mq200_check_var(struct fb_var_screeninfo *var,
++ struct fb_info *info )
++{ /* TODO do we need sanity checks here */
++ return 0;
++}
++
++
++static int mq200_set_par( struct fb_info *info )
++{
++ /* TODO set paraemeter */
++ return 0;
++}
++
++static int mq200_setcolreg(unsigned regno, unsigned red, unsigned green,
++ unsigned blue, unsigned transp,
++ struct fb_info *info )
++{
++ struct mq200_info *p;
++ unsigned long color;
++ u32* pal = info->pseudo_palette;
++
++ p = info->par;
++
++ if(regno > 255 )
++ return 1;
++
++ switch( info->var.bits_per_pixel ){
++ case 16:
++ pal[regno] =
++ ((red & 0xf800) >> 0) |
++ ((green & 0xf800) >> 5) | ((blue & 0xf800) >> 11);
++ break;
++ case 24:
++ pal[regno] =
++ ((red & 0xff00) << 8) |
++ ((green & 0xff00)) | ((blue & 0xff00) >> 8);
++ break;
++ case 32:
++ pal[regno] =
++ ((red & 0xff00) >> 8) |
++ ((green & 0xff00)) | ((blue & 0xff00) << 8);
++ break;
++ default:
++ break;
++ }
++
++ red &= 0xFF;
++ green &= 0xFF;
++ blue &= 0xFF;
++
++ color = red | (green << 8) | (blue << 16);
++ mq200_external_setpal(regno, color, p->io_regions.virt_mmio_base);
++
++ return 0;
++}
++
++
++static struct fb_ops mq200_ops = {
++ .owner = THIS_MODULE,
++ .fb_check_var = mq200_check_var,
++ .fb_set_par = mq200_set_par,
++ .fb_setcolreg = mq200_setcolreg,
++#ifdef FB_SOFT_CURSOR
++ .fb_cursor = soft_cursor, /* FIXME use hardware cursor */
++#endif
++ .fb_fillrect = cfb_fillrect,
++ .fb_copyarea = cfb_copyarea,
++ .fb_imageblit = cfb_imageblit,
++ .fb_blank = mq200_blank,
++};
++
++
++/*********************************************************************
++ *
++ * Device driver and module init code
++ * this will register to the fb layer later
++ *
++ *********************************************************************/
++static void mq200_internal_init_color( struct fb_bitfield* red,
++ struct fb_bitfield* green,
++ struct fb_bitfield* blue,
++ int bpp )
++{
++ switch ( bpp )
++ {
++ case 16:
++ red->offset = 11;
++ green->offset = 5;
++ blue->offset = 0;
++
++ red->length = 5;
++ green->length = 6;
++ blue->length = 5;
++ break;
++ case 24:
++ red->offset = 16;
++ green->offset = 8;
++ blue->offset = 0;
++
++ red->length = 8;
++ green->length = 8;
++ blue->length = 8;
++ break;
++ case 32:
++ red->offset = 0;
++ green->offset = 8;
++ blue->offset = 16;
++
++ red->length = 8;
++ green->length = 8;
++ blue->length = 8;
++ case 8: /* fall through */
++ default:
++ red->offset = green->offset = blue->offset = 0;
++ red->length = green->length = blue->length = bpp;
++ break;
++ }
++
++}
++
++
++static struct mq200_info* __init mq200_internal_init_fbinfo(void)
++{
++ struct mq200_info *info = NULL;
++
++ info = (struct mq200_info*)kmalloc(sizeof(*info), GFP_KERNEL);
++ if(!info)
++ return NULL;
++
++ /*
++ * Initialize memory
++ */
++ memset(info, 0, sizeof(struct mq200_info) );
++ spin_lock_init(&info->lock);
++
++ /* set the base IO addresses */
++ info->io_regions = MQ200_REGIONS;
++ info->monitor_info = MQ200_MONITOR;
++
++ info->fb_info.screen_base = (char *)info->io_regions.virt_fb_base;
++
++ /* fb_fix_screeninfo filling */
++ strcpy(info->fb_info.fix.id, "MQ200_FB" );
++ info->fb_info.fix.smem_start = info->io_regions.phys_fb_base;
++ info->fb_info.fix.smem_len = info->io_regions.fb_size; /* - CURSOR_IMAGE */
++ info->fb_info.fix.mmio_start = info->io_regions.phys_mmio_base;
++ info->fb_info.fix.mmio_len = MQ200_REGS_SIZE;
++ info->fb_info.fix.type = FB_TYPE_PACKED_PIXELS;
++ info->fb_info.fix.accel = FB_ACCEL_NONE;
++ info->fb_info.fix.line_length = MQ200_MONITOR_LINE_LENGTH(info);
++
++ if(MQ200_MONITOR_DEPTH(info) <= 8 )
++ info->fb_info.fix.visual = FB_VISUAL_PSEUDOCOLOR;
++ else if( MQ200_MONITOR_DEPTH(info) >= 16 )
++ info->fb_info.fix.visual = FB_VISUAL_DIRECTCOLOR;
++ else
++ panic("Calling mq200 with wrong display data\n");
++
++ /* set the variable screen info */
++ info->fb_info.var.xres = MQ200_MONITOR_HORI_RES(info);
++ info->fb_info.var.yres = MQ200_MONITOR_VERT_RES(info);
++ info->fb_info.var.xres_virtual = MQ200_MONITOR_HORI_RES(info);
++ info->fb_info.var.yres_virtual = MQ200_MONITOR_VERT_RES(info);
++ info->fb_info.var.bits_per_pixel = MQ200_MONITOR_DEPTH(info);
++
++ mq200_internal_init_color(&info->fb_info.var.red,
++ &info->fb_info.var.green,
++ &info->fb_info.var.blue,
++ MQ200_MONITOR_DEPTH(info) );
++
++ info->fb_info.var.transp.length = info->fb_info.var.transp.offset = 0;
++ info->fb_info.var.height = info->fb_info.var.width = -1;
++
++ info->fb_info.var.vmode = FB_VMODE_NONINTERLACED;
++ info->fb_info.var.pixclock = 10000;
++ info->fb_info.var.left_margin = info->fb_info.var.right_margin = 16;
++ info->fb_info.var.upper_margin = info->fb_info.var.lower_margin = 16;
++ info->fb_info.var.hsync_len = info->fb_info.var.vsync_len = 8;
++
++ info->fb_info.var.nonstd = 0;
++ info->fb_info.var.activate = FB_ACTIVATE_NOW;
++ info->fb_info.var.accel_flags = 0;
++
++ return info;
++}
++
++
++extern void mq200_register_attributes(struct device* );
++/*
++ * gets called from the bus
++ * we will register our framebuffer from here
++ */
++static int __init mq200_probe(struct device *dev)
++{
++ struct mq200_info *info = NULL;
++ int retv= 0;
++
++ info = mq200_internal_init_fbinfo();
++ if(!mq200_external_probe(info->io_regions.virt_mmio_base))
++ goto error_out;
++
++ GPDR |= (1<<3);
++ GAFR &= ~(1<<3);
++ GPSR |= (1<<3);
++
++ mq200_external_setqmode(&info->monitor_info,
++ info->io_regions.virt_mmio_base,
++ &info->lock);
++
++ info->fb_info.fbops = &mq200_ops;
++ info->fb_info.flags = FBINFO_FLAG_DEFAULT;
++
++ mq200_check_var(&info->fb_info.var, &info->fb_info );
++
++ fb_alloc_cmap(&info->fb_info.cmap, 1 << MQ200_MONITOR_DEPTH(info), 0 );
++
++ info->fb_info.pseudo_palette = (void*)info->pseudo_palette;
++
++ /* save the pointer to the mq200 struct in var */
++ info->fb_info.par = info;
++
++ retv = register_framebuffer(&info->fb_info );
++ if(retv < 0)
++ goto error_out;
++
++
++ /* will get unset if retv != 0 */
++ dev_set_drvdata(dev, info );
++ return retv;
++
++/*
++ * Free the info and exit
++ */
++error_out:
++ kfree(info);
++ return -EINVAL;
++}
++
++#ifdef CONFIG_PM
++static struct mq200_info* get_mq200_info( struct device *dev)
++{
++ return dev_get_drvdata(dev);
++}
++
++static unsigned long get_mmio_base( struct device *dev )
++{
++ struct mq200_info *info = get_mq200_info(dev);
++ return info->io_regions.virt_mmio_base;
++}
++
++static struct mq200_monitor_info* get_monitor_info( struct device *dev)
++{
++ struct mq200_info *info = get_mq200_info(dev);
++ return &info->monitor_info;
++}
++
++static spinlock_t* get_spinlock( struct device *dev)
++{
++ return &get_mq200_info(dev)->lock;
++}
++
++/*
++ * FIXME: make sure we only call mq200_external_offdisplay only once
++ * a 2nd time will hang the kernel -zecke
++ *
++ * FIXME: save the content of the framebuffer inside dev->saved_state
++ * so on resume we can memcpy it back into the buffer and userspace
++ * does not need to redraw
++ *
++ * functions for suspending and resuming
++ */
++static int mq200_suspend(struct device *dev, pm_message_t state)
++{
++
++ mq200_external_offdisplay( get_mmio_base(dev) );
++ clear_cs3_bit(DISPLAY_ON);
++
++
++ return 0;
++}
++
++static int mq200_resume(struct device *dev)
++{
++ unsigned long mem = get_mmio_base(dev);
++ struct mq200_monitor_info *monitor = get_monitor_info(dev);
++ mq200_external_setqmode(monitor, mem, get_spinlock(dev) );
++
++
++ /*
++ * Set display on if it was on
++ */
++ set_cs3_bit(DISPLAY_ON);
++
++ return 0;
++}
++
++
++#endif
++
++
++static struct device_driver mq200fb_driver = {
++ .name = "simpad-mq200",
++ .bus = &platform_bus_type,
++ .probe = mq200_probe, /* will be called after we've registered the driver */
++ .suspend = mq200_suspend,
++ .resume = mq200_resume
++};
++
++int __devinit mq200_init(void)
++{
++ return driver_register(&mq200fb_driver);
++}
++
++module_init(mq200_init);
++MODULE_DESCRIPTION("MQ200 framebuffer driver");
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Holger Hans Peter Freyther");
diff --git a/recipes/linux/linux/simpad/linux-2.6.27-SIMpad-pcmcia.patch b/recipes/linux/linux/simpad/linux-2.6.27-SIMpad-pcmcia.patch
new file mode 100644
index 0000000000..13abef9ba2
--- /dev/null
+++ b/recipes/linux/linux/simpad/linux-2.6.27-SIMpad-pcmcia.patch
@@ -0,0 +1,226 @@
+Index: linux-2.6.27/drivers/pcmcia/cs.c
+===================================================================
+--- linux-2.6.27.orig/drivers/pcmcia/cs.c 2008-10-10 00:13:53.000000000 +0200
++++ linux-2.6.27/drivers/pcmcia/cs.c 2008-12-04 01:10:04.236701484 +0100
+@@ -10,6 +10,8 @@
+ * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
+ *
+ * (C) 1999 David A. Hinds
++ *
++ * mrdata: -added suspend fix
+ */
+
+ #include <linux/module.h>
+@@ -57,6 +59,10 @@
+ INT_MODULE_PARM(unreset_delay, 10); /* centiseconds */
+ INT_MODULE_PARM(unreset_check, 10); /* centiseconds */
+ INT_MODULE_PARM(unreset_limit, 30); /* unreset_check's */
++// INT_MODULE_PARM(unreset_delay, 20); /* centiseconds */
++// INT_MODULE_PARM(unreset_check, 100); /* centiseconds */
++// INT_MODULE_PARM(unreset_limit, 300); /* unreset_check's */
++
+
+ /* Access speed for attribute memory windows */
+ INT_MODULE_PARM(cis_speed, 300); /* ns */
+@@ -362,6 +368,7 @@
+ skt->ops->set_socket(skt, &skt->socket);
+
+ msleep(unreset_delay * 10);
++
+ for (i = 0; i < unreset_limit; i++) {
+ skt->ops->get_status(skt, &status);
+
+@@ -826,7 +833,7 @@
+ int pcmcia_resume_card(struct pcmcia_socket *skt)
+ {
+ int ret;
+-
++
+ cs_dbg(skt, 1, "waking up socket\n");
+
+ mutex_lock(&skt->skt_mutex);
+@@ -854,7 +861,7 @@
+ int pcmcia_eject_card(struct pcmcia_socket *skt)
+ {
+ int ret;
+-
++
+ cs_dbg(skt, 1, "user eject request\n");
+
+ mutex_lock(&skt->skt_mutex);
+Index: linux-2.6.27/drivers/pcmcia/sa1100_generic.c
+===================================================================
+--- linux-2.6.27.orig/drivers/pcmcia/sa1100_generic.c 2008-10-10 00:13:53.000000000 +0200
++++ linux-2.6.27/drivers/pcmcia/sa1100_generic.c 2008-12-04 01:03:33.558818180 +0100
+@@ -28,6 +28,9 @@
+ the provisions above, a recipient may use your version of this
+ file under either the MPL or the GPL.
+
++ 2007 mrnice: added thesings changes from device_driver
++ to platform_driver - many thx to thesing
++
+ ======================================================================*/
+
+ #include <linux/module.h>
+@@ -81,13 +84,15 @@
+ return ret;
+ }
+
+-static struct device_driver sa11x0_pcmcia_driver = {
+- .probe = sa11x0_drv_pcmcia_probe,
+- .remove = soc_common_drv_pcmcia_remove,
+- .name = "sa11x0-pcmcia",
+- .bus = &platform_bus_type,
+- .suspend = pcmcia_socket_dev_suspend,
+- .resume = pcmcia_socket_dev_resume,
++static struct platform_driver sa11x0_pcmcia_driver = {
++ .driver = {
++ .name = "sa11x0-pcmcia",
++ .probe = sa11x0_drv_pcmcia_probe,
++ .remove = soc_common_drv_pcmcia_remove,
++ .suspend= pcmcia_socket_dev_suspend,
++ .resume = pcmcia_socket_dev_resume,
++ //.bus = &platform_bus_type,
++ },
+ };
+
+ /* sa11x0_pcmcia_init()
+@@ -100,7 +105,7 @@
+ */
+ static int __init sa11x0_pcmcia_init(void)
+ {
+- return driver_register(&sa11x0_pcmcia_driver);
++ return platform_driver_register(&sa11x0_pcmcia_driver);
+ }
+
+ /* sa11x0_pcmcia_exit()
+@@ -110,7 +115,7 @@
+ */
+ static void __exit sa11x0_pcmcia_exit(void)
+ {
+- driver_unregister(&sa11x0_pcmcia_driver);
++ platform_driver_unregister(&sa11x0_pcmcia_driver);
+ }
+
+ MODULE_AUTHOR("John Dorsey <john+@cs.cmu.edu>");
+Index: linux-2.6.27/drivers/pcmcia/sa1100_simpad.c
+===================================================================
+--- linux-2.6.27.orig/drivers/pcmcia/sa1100_simpad.c 2008-10-10 00:13:53.000000000 +0200
++++ linux-2.6.27/drivers/pcmcia/sa1100_simpad.c 2008-12-04 01:10:21.458773451 +0100
+@@ -8,15 +8,17 @@
+ #include <linux/kernel.h>
+ #include <linux/device.h>
+ #include <linux/init.h>
++#include <linux/delay.h>
+
+ #include <mach/hardware.h>
+ #include <asm/mach-types.h>
+ #include <asm/irq.h>
+ #include <mach/simpad.h>
+ #include "sa1100_generic.h"
+-
++
++extern long get_cs3_ro(void);
+ extern long get_cs3_shadow(void);
+-extern void set_cs3_bit(int value);
++extern void set_cs3_bit(int value);
+ extern void clear_cs3_bit(int value);
+
+ static struct pcmcia_irqs irqs[] = {
+@@ -25,8 +27,15 @@
+
+ static int simpad_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
+ {
++ clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1|PCMCIA_RESET);
++
++ set_cs3_bit(PCMCIA_BUFF_DIS);
++
++ msleep(10);
++
++ clear_cs3_bit(PCMCIA_BUFF_DIS);
+
+- clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1);
++ msleep(5);
+
+ skt->irq = IRQ_GPIO_CF_IRQ;
+
+@@ -38,8 +47,8 @@
+ soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
+
+ /* Disable CF bus: */
+- //set_cs3_bit(PCMCIA_BUFF_DIS);
+- clear_cs3_bit(PCMCIA_RESET);
++ set_cs3_bit(PCMCIA_BUFF_DIS);
++ clear_cs3_bit(PCMCIA_RESET);
+ }
+
+ static void
+@@ -47,21 +56,17 @@
+ struct pcmcia_state *state)
+ {
+ unsigned long levels = GPLR;
+- long cs3reg = get_cs3_shadow();
+
+- state->detect=((levels & GPIO_CF_CD)==0)?1:0;
+- state->ready=(levels & GPIO_CF_IRQ)?1:0;
+- state->bvd1=1; /* Not available on Simpad. */
+- state->bvd2=1; /* Not available on Simpad. */
+- state->wrprot=0; /* Not available on Simpad. */
+-
+- if((cs3reg & 0x0c) == 0x0c) {
+- state->vs_3v=0;
+- state->vs_Xv=0;
+- } else {
+- state->vs_3v=1;
+- state->vs_Xv=0;
+- }
++ state->detect = ((levels & GPIO_CF_CD) == 0) ? 1 : 0 ;
++ state->ready = (levels & GPIO_CF_IRQ) ? 1 : 0 ;
++
++ long cs3_ro_reg = get_cs3_ro();
++
++ state->bvd1 = (cs3_ro_reg & PCMCIA_BVD1) ? 1 : 0 ; /* old: =1 Not available on Simpad. */
++ state->bvd2 = (cs3_ro_reg & PCMCIA_BVD2) ? 1 : 0 ; /* old: =1 Not available on Simpad. */
++ state->wrprot = 0 ; /* Not available on Simpad. */
++ state->vs_3v = (cs3_ro_reg & PCMCIA_VS1) ? 0 : 1 ;
++ state->vs_Xv = (cs3_ro_reg & PCMCIA_VS2) ? 0 : 1 ;
+ }
+
+ static int
+@@ -78,7 +83,7 @@
+ clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1);
+ break;
+
+- case 33:
++ case 33:
+ clear_cs3_bit(VCC_3V_EN|EN1);
+ set_cs3_bit(VCC_5V_EN|EN0);
+ break;
+@@ -96,6 +101,10 @@
+ return -1;
+ }
+
++ if (state->flags & SS_RESET)
++ set_cs3_bit(PCMCIA_RESET);
++ else
++ clear_cs3_bit(PCMCIA_RESET);
+
+ local_irq_restore(flags);
+
+@@ -104,6 +113,7 @@
+
+ static void simpad_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
+ {
++ clear_cs3_bit(PCMCIA_RESET);
+ soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
+ }
+
+@@ -113,7 +123,7 @@
+ set_cs3_bit(PCMCIA_RESET);
+ }
+
+-static struct pcmcia_low_level simpad_pcmcia_ops = {
++static struct pcmcia_low_level simpad_pcmcia_ops = {
+ .owner = THIS_MODULE,
+ .hw_init = simpad_pcmcia_hw_init,
+ .hw_shutdown = simpad_pcmcia_hw_shutdown,
diff --git a/recipes/linux/linux/simpad/linux-2.6.27-SIMpad-serial-gpio_keys-and-cs3-ro.patch.v2 b/recipes/linux/linux/simpad/linux-2.6.27-SIMpad-serial-gpio_keys-and-cs3-ro.patch.v2
new file mode 100644
index 0000000000..b044b471c5
--- /dev/null
+++ b/recipes/linux/linux/simpad/linux-2.6.27-SIMpad-serial-gpio_keys-and-cs3-ro.patch.v2
@@ -0,0 +1,358 @@
+diff -Nur linux-2.6.24.vanilla/arch/arm/mach-sa1100/simpad.c linux-2.6.24/arch/arm/mach-sa1100/simpad.c
+--- linux-2.6.24.vanilla/arch/arm/mach-sa1100/simpad.c 2008-10-04 21:47:24.000000000 +0200
++++ linux-2.6.24/arch/arm/mach-sa1100/simpad.c 2008-10-04 22:01:20.000000000 +0200
+@@ -1,5 +1,15 @@
+ /*
+ * linux/arch/arm/mach-sa1100/simpad.c
++ *
++ * 2007/04/11 mrdata:
++ * - insert simpad_uart_set_mctrl()
++ * simpad_uart_get_mctrl()
++ * - internal RS232/DECT/Bluetooth
++ * works again (based on 2.4 simpad-serial.patch)
++ * - added cs3_ro
++ *
++ * 2007/04/12 Bernhard Guillon:
++ * -added gpio_keys (based on h3000.c from hh.org)
+ */
+
+ #include <linux/module.h>
+@@ -9,6 +19,9 @@
+ #include <linux/proc_fs.h>
+ #include <linux/string.h>
+ #include <linux/pm.h>
++
++#include <linux/apm-emulation.h>
++
+ #include <linux/platform_device.h>
+ #include <linux/mtd/mtd.h>
+ #include <linux/mtd/partitions.h>
+@@ -27,12 +40,21 @@
+
+ #include <linux/serial_core.h>
+ #include <linux/ioport.h>
++#include <linux/input.h>
++#include <linux/gpio_keys.h>
+ #include <asm/io.h>
+
+ #include "generic.h"
+
++long cs3_ro;
+ long cs3_shadow;
+
++long get_cs3_ro(void)
++{
++ cs3_ro = *(CS3BUSTYPE *)(CS3_BASE);
++ return cs3_ro;
++}
++
+ long get_cs3_shadow(void)
+ {
+ return cs3_shadow;
+@@ -55,9 +77,12 @@
+ *(CS3BUSTYPE *)(CS3_BASE) = cs3_shadow;
+ }
+
++EXPORT_SYMBOL(get_cs3_ro);
++EXPORT_SYMBOL(get_cs3_shadow);
+ EXPORT_SYMBOL(set_cs3_bit);
+ EXPORT_SYMBOL(clear_cs3_bit);
+
++
+ static struct map_desc simpad_io_desc[] __initdata = {
+ { /* MQ200 */
+ .virtual = 0xf2800000,
+@@ -73,23 +98,71 @@
+ };
+
+
++static void simpad_uart_set_mctrl(struct uart_port *port, u_int mctrl)
++{
++ if (port->mapbase == _Ser1UTCR0) {
++ /* internal serial port (ttySA1, DECT/Bluetooth) */
++ if (mctrl & TIOCM_RTS) GPCR = GPIO_UART1_RTS;
++ else GPSR = GPIO_UART1_RTS;
++
++ if (mctrl & TIOCM_DTR) GPCR = GPIO_UART1_DTR;
++ else GPSR = GPIO_UART1_DTR;
++ }
++
++ else if (port->mapbase == _Ser3UTCR0) {
++ /* external serial port (ttySA0, RS232) */
++ if (mctrl & TIOCM_RTS) GPCR = GPIO_UART3_RTS;
++ else GPSR = GPIO_UART3_RTS;
++
++ if (mctrl & TIOCM_DTR) GPCR = GPIO_UART3_DTR;
++ else GPSR = GPIO_UART3_DTR;
++ }
++}
++
++
++static u_int simpad_uart_get_mctrl(struct uart_port *port)
++{
++ u_int ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR;
++
++ if (port->mapbase == _Ser1UTCR0) {
++ /* internal serial port (ttySA1, DECT/Bluetooth) */
++ int gplr = GPLR;
++ if (gplr & GPIO_UART1_DCD) ret &= ~TIOCM_CD;
++ if (gplr & GPIO_UART1_CTS) ret &= ~TIOCM_CTS;
++ if (gplr & GPIO_UART1_DSR) ret &= ~TIOCM_DSR;
++ }
++
++ else if (port->mapbase == _Ser3UTCR0) {
++ /* external serial port (ttySA0, RS232) */
++ int gplr = GPLR;
++ if (gplr & GPIO_UART3_DCD) ret &= ~TIOCM_CD;
++ if (gplr & GPIO_UART3_CTS) ret &= ~TIOCM_CTS;
++ if (gplr & GPIO_UART3_DSR) ret &= ~TIOCM_DSR;
++ }
++ return ret;
++}
++
++
+ static void simpad_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
+ {
+- if (port->mapbase == (u_int)&Ser1UTCR0) {
+- if (state)
+- {
+- clear_cs3_bit(RS232_ON);
+- clear_cs3_bit(DECT_POWER_ON);
+- }else
+- {
+- set_cs3_bit(RS232_ON);
+- set_cs3_bit(DECT_POWER_ON);
+- }
+- }
++ if (port->mapbase == (u_int)&Ser3UTCR0) {
++ if (state)
++ {
++ clear_cs3_bit(RS232_ON);
++ /* clear_cs3_bit(DECT_POWER_ON); */
++ }else
++ {
++ set_cs3_bit(RS232_ON);
++ /* set_cs3_bit(DECT_POWER_ON); */
++ }
++ }
+ }
+
++
+ static struct sa1100_port_fns simpad_port_fns __initdata = {
+- .pm = simpad_uart_pm,
++ .set_mctrl = simpad_uart_set_mctrl,
++ .get_mctrl = simpad_uart_get_mctrl,
++ .pm = simpad_uart_pm,
+ };
+
+
+@@ -135,7 +208,6 @@
+ };
+
+
+-
+ static void __init simpad_map_io(void)
+ {
+ sa1100_map_io();
+@@ -144,23 +216,45 @@
+
+ set_cs3_bit (EN1 | EN0 | LED2_ON | DISPLAY_ON | RS232_ON |
+ ENABLE_5V | RESET_SIMCARD | DECT_POWER_ON);
+-
+-
++
+ sa1100_register_uart_fns(&simpad_port_fns);
+ sa1100_register_uart(0, 3); /* serial interface */
+ sa1100_register_uart(1, 1); /* DECT */
+
+- // Reassign UART 1 pins
++ /* Reassign UART 1 pins */
++ /* TEST SOME OLD KERNEL STUFF INSTEAD
+ GAFR |= GPIO_UART_TXD | GPIO_UART_RXD;
+ GPDR |= GPIO_UART_TXD | GPIO_LDD13 | GPIO_LDD15;
+ GPDR &= ~GPIO_UART_RXD;
+ PPAR |= PPAR_UPR;
++ */
++
++ // txd and rxd use their alternate function
++ GAFR |= (GPIO_UART_TXD | GPIO_UART_RXD);
++
++ // the control lines are gpio
++ GAFR &= ~(GPIO_UART1_RTS | GPIO_UART1_CTS | GPIO_UART1_DCD);
++ GAFR &= ~(GPIO_UART1_DSR | GPIO_UART1_DTR);
++ GAFR &= ~(GPIO_UART3_RTS | GPIO_UART3_CTS | GPIO_UART3_DCD);
++ GAFR &= ~(GPIO_UART3_DSR | GPIO_UART3_DTR);
++
++ // txd, rts and dtr are outputs
++ GPDR |= GPIO_UART_TXD;
++ GPDR |= GPIO_UART1_RTS | GPIO_UART3_RTS;
++ GPDR |= GPIO_UART1_DTR | GPIO_UART3_DTR;
++
++ // cts, dcd, dsr and rxd are inputs
++ GPDR &= ~(GPIO_UART1_CTS | GPIO_UART3_CTS);
++ GPDR &= ~(GPIO_UART1_DCD | GPIO_UART3_DCD);
++ GPDR &= ~(GPIO_UART1_DSR | GPIO_UART3_DSR);
++ GPDR &= ~GPIO_UART_RXD;
++
++ PPAR |= PPAR_UPR;
+
+ /*
+ * Set up registers for sleep mode.
+ */
+
+-
+ PWER = PWER_GPIO0| PWER_RTC;
+ PGSR = 0x818;
+ PCFR = 0;
+@@ -171,9 +265,10 @@
+ sa11x0_set_mcp_data(&simpad_mcp_data);
+ }
+
++
+ static void simpad_power_off(void)
+ {
+- local_irq_disable(); // was cli
++ local_irq_disable(); /* was cli */
+ set_cs3(0x800); /* only SD_MEDIAQ */
+
+ /* disable internal oscillator, float CS lines */
+@@ -191,31 +286,52 @@
+ while(1);
+
+ local_irq_enable(); /* we won't ever call it */
++}
+
+
+-}
++/*
++ * gpio_keys
++*/
++
++static struct gpio_keys_button simpad_button_table[] = {
++ { KEY_POWER, IRQ_GPIO_POWER_BUTTON, 1, "power button" },
++};
++
++static struct gpio_keys_platform_data simpad_keys_data = {
++ .buttons = simpad_button_table,
++ .nbuttons = ARRAY_SIZE(simpad_button_table),
++};
++
++static struct platform_device simpad_keys = {
++ .name = "gpio-keys",
++ .dev = {
++ .platform_data = &simpad_keys_data,
++ },
++};
+
+
+ /*
+ * MediaQ Video Device
+ */
++
+ static struct platform_device simpad_mq200fb = {
+ .name = "simpad-mq200",
+ .id = 0,
+ };
+
++
+ static struct platform_device *devices[] __initdata = {
+- &simpad_mq200fb
++ &simpad_keys,
++ &simpad_mq200fb,
+ };
+
+
+-
+ static int __init simpad_init(void)
+ {
+ int ret;
+
+ pm_power_off = simpad_power_off;
+-
++
+ ret = platform_add_devices(devices, ARRAY_SIZE(devices));
+ if(ret)
+ printk(KERN_WARNING "simpad: Unable to register mq200 framebuffer device");
+diff -Nur linux-2.6.27/arch/arm/mach-sa1100/include/mach/simpad.h linux-2.6.27/arch/arm/mach-sa1100/include/mach/simpad.h
+--- linux-2.6.27/arch/arm/mach-sa1100/include/mach/simpad.h 2008-10-04 21:47:17.000000000 +0200
++++ linux-2.6.27/arch/arm/mach-sa1100/include/mach/simpad.h 2008-10-04 22:00:57.000000000 +0200
+@@ -12,11 +12,12 @@
+ #define __ASM_ARCH_SIMPAD_H
+
+
+-#define GPIO_UART1_RTS GPIO_GPIO14
++#define GPIO_UART1_RTS GPIO_GPIO9
+ #define GPIO_UART1_DTR GPIO_GPIO7
+ #define GPIO_UART1_CTS GPIO_GPIO8
+ #define GPIO_UART1_DCD GPIO_GPIO23
+ #define GPIO_UART1_DSR GPIO_GPIO6
++#define GPIO_UART1_RI GPIO_GPIO19
+
+ #define GPIO_UART3_RTS GPIO_GPIO12
+ #define GPIO_UART3_DTR GPIO_GPIO16
+@@ -48,9 +49,9 @@
+ #define GPIO_SMART_CARD GPIO_GPIO10
+ #define IRQ_GPIO_SMARD_CARD IRQ_GPIO10
+
+-// CS3 Latch is write only, a shadow is necessary
++// CS3 Latch is write only 16-bit , a shadow is necessary
+
+-#define CS3BUSTYPE unsigned volatile long
++#define CS3BUSTYPE unsigned volatile long
+ #define CS3_BASE 0xf1000000
+
+ #define VCC_5V_EN 0x0001 // For 5V PCMCIA
+@@ -70,43 +71,17 @@
+ #define ENABLE_5V 0x4000 // Enable 5V circuit
+ #define RESET_SIMCARD 0x8000
+
+-#define RS232_ENABLE 0x0440
+-#define PCMCIAMASK 0x402f
++// CS3 Latch is readable only 8-bit interest
+
++#define PCMCIA_BVD1 0x0001
++#define PCMCIA_BVD2 0x0002
++#define PCMCIA_VS1 0x0004 // PCMCIA card voltage select
++#define PCMCIA_VS2 0x0008 // PCMCIA card voltage select, if both are in high state -> 5V PCMCIA card
++#define LOCK_IND 0x0010
++#define CHARGING_STATE 0x0020 // Ladestatus
++#define PCMCIA_SHORT 0x0040 // low active
+
+-struct simpad_battery {
+- unsigned char ac_status; /* line connected yes/no */
+- unsigned char status; /* battery loading yes/no */
+- unsigned char percentage; /* percentage loaded */
+- unsigned short life; /* life till empty */
+-};
+-
+-/* These should match the apm_bios.h definitions */
+-#define SIMPAD_AC_STATUS_AC_OFFLINE 0x00
+-#define SIMPAD_AC_STATUS_AC_ONLINE 0x01
+-#define SIMPAD_AC_STATUS_AC_BACKUP 0x02 /* What does this mean? */
+-#define SIMPAD_AC_STATUS_AC_UNKNOWN 0xff
+-
+-/* These bitfields are rarely "or'd" together */
+-#define SIMPAD_BATT_STATUS_HIGH 0x01
+-#define SIMPAD_BATT_STATUS_LOW 0x02
+-#define SIMPAD_BATT_STATUS_CRITICAL 0x04
+-#define SIMPAD_BATT_STATUS_CHARGING 0x08
+-#define SIMPAD_BATT_STATUS_CHARGE_MAIN 0x10
+-#define SIMPAD_BATT_STATUS_DEAD 0x20 /* Battery will not charge */
+-#define SIMPAD_BATT_NOT_INSTALLED 0x20 /* For expansion pack batteries */
+-#define SIMPAD_BATT_STATUS_FULL 0x40 /* Battery fully charged (and connected to AC) */
+-#define SIMPAD_BATT_STATUS_NOBATT 0x80
+-#define SIMPAD_BATT_STATUS_UNKNOWN 0xff
+-
+-extern int simpad_get_battery(struct simpad_battery* );
++#define RS232_ENABLE 0x0440
++#define PCMCIAMASK 0x402f
+
+ #endif // __ASM_ARCH_SIMPAD_H
+-
+-
+-
+-
+-
+-
+-
+-
diff --git a/recipes/linux/linux/simpad/linux-2.6.27-SIMpad-ucb1x00-switches.patch b/recipes/linux/linux/simpad/linux-2.6.27-SIMpad-ucb1x00-switches.patch
new file mode 100644
index 0000000000..f67a9c29b6
--- /dev/null
+++ b/recipes/linux/linux/simpad/linux-2.6.27-SIMpad-ucb1x00-switches.patch
@@ -0,0 +1,362 @@
+Index: linux-2.6.27/drivers/mfd/Kconfig
+===================================================================
+--- linux-2.6.27.orig/drivers/mfd/Kconfig 2008-12-07 01:18:53.719505919 +0100
++++ linux-2.6.27/drivers/mfd/Kconfig 2008-12-07 01:19:19.436170998 +0100
+@@ -101,4 +101,7 @@
+ tristate "Touchscreen interface support"
+ depends on MCP_UCB1200 && INPUT
+
++config MCP_UCB1200_SWITCHES
++ tristate "SIMpad Switches support"
++ depends on MCP_UCB1200 && INPUT
+ endmenu
+Index: linux-2.6.27/drivers/mfd/Makefile
+===================================================================
+--- linux-2.6.27.orig/drivers/mfd/Makefile 2008-12-07 01:18:53.732838088 +0100
++++ linux-2.6.27/drivers/mfd/Makefile 2008-12-07 01:19:19.436170998 +0100
+@@ -18,7 +18,7 @@
+ obj-$(CONFIG_MCP_SA11X0) += mcp-sa11x0.o
+ obj-$(CONFIG_MCP_UCB1200) += ucb1x00-core.o
+ obj-$(CONFIG_MCP_UCB1200_TS) += ucb1x00-ts.o
+-
++obj-$(CONFIG_MCP_UCB1200_SWITCHES) += ucb1x00-switches.o
+ ifeq ($(CONFIG_SA1100_ASSABET),y)
+ obj-$(CONFIG_MCP_UCB1200) += ucb1x00-assabet.o
+ endif
+Index: linux-2.6.27/drivers/mfd/ucb1x00-switches.c
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.27/drivers/mfd/ucb1x00-switches.c 2008-12-07 01:29:24.479452365 +0100
+@@ -0,0 +1,332 @@
++/*
++ * linux/drivers/mfd/ucb1x00-switches.c
++ *
++ * Copyright (C) 2007 Bernhard Guillon.
++ *
++ * 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.
++ *
++ * This driver is for the Switches of Siemens SIMpad (CL4,SL4,SLC), T-Sinus-Pad and
++ * Swisscom WP50 devices.
++ *
++ * Six switches are routed to GPIO pins on the UCB1300: S3 -- S8.
++ *
++ * This driver is based on the 2.4 ucb1x00-switches, the 2.6 ucb1x00-assabet
++ * and the ucb1x00-ts driver.
++ *
++ * 2007/06/21 mrdata:
++ * - create new thread kswd() to handle irq_events for ucb1300-gpio's
++ * - found out, that not every key-press or key-release
++ * generate a irq_event
++ * -> establish key_state handling
++ * key_state, key_state_last <-> KEY_PRESS, KEY_RELEASE
++ * -> after irq_event polling the ucb1300-gpio's till all keys
++ * in key_state = KEY_RELEASE
++ *
++ */
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/input.h>
++#include <linux/device.h>
++#include <linux/sched.h>
++#include <linux/freezer.h>
++#include <linux/kthread.h>
++
++#include <asm/dma.h>
++
++#include "ucb1x00.h"
++
++#define KEY_PRESS 1
++#define KEY_RELEASE 0
++
++static int key [6] = { KEY_PROG1,KEY_PROG2,KEY_UP,KEY_DOWN,KEY_LEFT,KEY_RIGHT };
++
++static unsigned short int key_state [6] = { 0, 0, 0, 0, 0, 0};
++static unsigned short int key_state_last [6] = { 1, 1, 1, 1, 1, 1};
++
++struct ucb1x00_switches {
++ struct input_dev *idev;
++ struct ucb1x00 *ucb;
++
++ wait_queue_head_t irq_wait;
++ struct task_struct *rtask;
++
++ int idx;
++
++ unsigned int valid:1;
++};
++
++static int ucb1x00_thread(void *_switches_id)
++{
++ unsigned short int this;
++ int idx_tmp;
++ int i;
++ struct ucb1x00_switches *switches = _switches_id;
++ struct input_dev *idev = switches->idev;
++ struct task_struct *tsk = current;
++ DECLARE_WAITQUEUE(wait, tsk);
++
++ add_wait_queue(&switches->irq_wait, &wait);
++
++ while (!kthread_should_stop())
++ {
++ signed long timeout;
++
++ if ((switches->idx >= 0) && (switches->idx <= 5) && (switches->valid == 1))
++ {
++ switches->valid = 0;
++
++ idx_tmp = switches->idx;
++
++ ucb1x00_enable(switches->ucb);
++
++ this = ~ucb1x00_io_read(switches->ucb);
++
++ ucb1x00_disable(switches->ucb);
++
++ if (key_state[idx_tmp] == KEY_RELEASE)
++ {
++ key_state_last[idx_tmp] = KEY_RELEASE;
++ key_state[idx_tmp] = KEY_PRESS;
++
++ input_report_key(idev, key[idx_tmp], KEY_PRESS);
++ input_sync(idev);
++ }
++
++ for (i = 0; i < 6; i++)
++ {
++ if ((key_state[i] == KEY_RELEASE) && (((this & (1 << i)) ? 1 : 0) == KEY_PRESS))
++ {
++ key_state_last[i] = KEY_RELEASE;
++ key_state[i] = KEY_PRESS;
++
++ input_report_key(idev, key[i], KEY_PRESS);
++ input_sync(idev);
++ }
++ }
++
++ for(;;)
++ {
++ ucb1x00_enable(switches->ucb);
++ this = ~ucb1x00_io_read(switches->ucb);
++ ucb1x00_disable(switches->ucb);
++
++ for (i = 0; i < 6; i++)
++ {
++ if ((key_state[i] == KEY_PRESS) && (((this & (1 << i)) ? 1 : 0) == KEY_RELEASE))
++ {
++ key_state_last[i] = KEY_PRESS;
++ key_state[i] = KEY_RELEASE;
++
++ input_report_key(idev, key[i], KEY_RELEASE);
++ input_sync(idev);
++ }
++
++ if ((key_state[i] == KEY_RELEASE) && (((this & (1 << i)) ? 1 : 0) == KEY_PRESS))
++ {
++ key_state_last[i] = KEY_RELEASE;
++ key_state[i] = KEY_PRESS;
++
++ input_report_key(idev, key[i], KEY_PRESS);
++ input_sync(idev);
++ }
++
++ }
++
++ // left loop, if no key press detect
++ if ((this | 0xff80) == 0xff80)
++ {
++ break;
++ }
++
++ set_task_state(tsk, TASK_INTERRUPTIBLE);
++
++ try_to_freeze();
++
++ timeout = HZ / 100;
++
++ schedule_timeout(timeout);
++ }
++ }
++
++ set_task_state(tsk, TASK_INTERRUPTIBLE);
++
++ try_to_freeze();
++
++ timeout = MAX_SCHEDULE_TIMEOUT;
++
++ schedule_timeout(timeout);
++ }
++
++ remove_wait_queue(&switches->irq_wait, &wait);
++
++ switches->rtask = NULL;
++
++ return 0;
++}
++
++
++static void ucb1x00_dev_irq(int idx, void *id)
++{
++ struct ucb1x00_switches *switches = id;
++
++ switches->idx = idx;
++ switches->valid = 1;
++
++ wake_up(&switches->irq_wait);
++}
++
++static int ucb1x00_switches_add(struct ucb1x00_dev *dev)
++{
++ struct ucb1x00_switches *switches;
++ struct input_dev *idev;
++ int err,i;
++
++ switches = kzalloc(sizeof(struct ucb1x00_switches), GFP_KERNEL);
++ idev = input_allocate_device();
++
++ if (!switches || !idev) {
++ err = -ENOMEM;
++ goto fail;
++ }
++
++ switches->ucb = dev->ucb;
++
++ input_set_drvdata(idev, switches);
++ idev->name = "SIMpad Switches";
++ idev->id.product = switches->ucb->id;
++
++ __set_bit(EV_KEY, idev->evbit);
++ __set_bit(EV_REP, idev->evbit);
++ __set_bit(KEY_PROG1, idev->keybit);
++ __set_bit(KEY_PROG2, idev->keybit);
++ __set_bit(KEY_UP, idev->keybit);
++ __set_bit(KEY_DOWN, idev->keybit);
++ __set_bit(KEY_LEFT, idev->keybit);
++ __set_bit(KEY_RIGHT, idev->keybit);
++
++ err = input_register_device(idev);
++ if (err)
++ goto fail;
++ switches->idev = idev;
++ dev->priv = switches;
++
++ BUG_ON(switches->rtask);
++
++ init_waitqueue_head(&switches->irq_wait);
++
++ ucb1x00_enable(switches->ucb);
++
++ ucb1x00_io_set_dir(switches->ucb,
++ UCB_IO_0 | UCB_IO_1 | UCB_IO_2 |
++ UCB_IO_3 | UCB_IO_4 | UCB_IO_5,
++ UCB_IO_8 | UCB_IO_9);
++
++ ucb1x00_disable(switches->ucb);
++
++ for (i = 0; i < 6; ++i) {
++ ucb1x00_enable_irq(switches->ucb, i, UCB_RISING | UCB_FALLING);
++
++ if (ucb1x00_hook_irq(switches->ucb, i, ucb1x00_dev_irq, switches) < 0) {
++ printk(KERN_ERR "unable to hook IRQ for "
++ "UCB1300 SWITCH_%d\n", i);
++ return -EBUSY;
++ }
++ }
++
++ switches->rtask = kthread_run(ucb1x00_thread, switches, "kswd");
++ if (!IS_ERR(switches->rtask))
++ {
++ return 0;
++ }
++ else
++ {
++ input_unregister_device(switches->idev);
++
++ for (i = 5; i >= 0; --i) {
++ ucb1x00_disable_irq(switches->ucb, i, UCB_RISING | UCB_FALLING);
++
++ /* Only error conditions are ENOENT and EINVAL; silently
++ * ignore:
++ */
++ ucb1x00_free_irq(switches->ucb, i, NULL);
++ }
++ switches->rtask = NULL;
++ ucb1x00_disable(switches->ucb);
++ kfree(switches);
++
++ return -EFAULT;
++ }
++
++fail:
++ input_free_device(idev);
++ kfree(switches);
++ return err;
++
++}
++
++static void ucb1x00_switches_remove(struct ucb1x00_dev *dev)
++{
++ int i;
++ struct ucb1x00_switches *switches = dev->priv;
++
++ if (switches->rtask)
++ kthread_stop(switches->rtask);
++
++ switches->rtask = NULL;
++
++ input_unregister_device(switches->idev);
++
++ for (i = 5; i >= 0; --i) {
++ ucb1x00_disable_irq(switches->ucb, i, UCB_RISING | UCB_FALLING);
++
++ /* Only error conditions are ENOENT and EINVAL; silently
++ * ignore:
++ */
++ ucb1x00_free_irq(switches->ucb, i, NULL);
++ }
++ ucb1x00_disable(switches->ucb);
++ kfree(switches);
++}
++
++#ifdef CONFIG_PM
++static int ucb1x00_switches_resume(struct ucb1x00_dev *dev)
++{
++ struct ucb1x00_switches *switches = dev->priv;
++
++ if (switches->rtask != NULL)
++ {
++ switches->valid = 0;
++ wake_up(&switches->irq_wait);
++
++ printk(KERN_DEBUG "ucb1x00-switches.c -> _switches_resume() kswd - restart *DONE*\n");
++ }
++ return 0;
++}
++#else
++#define ucb1x00_switches_resume NULL
++#endif
++
++static struct ucb1x00_driver ucb1x00_switches_driver = {
++ .add = ucb1x00_switches_add,
++ .remove = ucb1x00_switches_remove,
++ .resume = ucb1x00_switches_resume,
++};
++
++static int __init ucb1x00_switches_init(void)
++{
++ return ucb1x00_register_driver(&ucb1x00_switches_driver);
++}
++
++static void __exit ucb1x00_switches_exit(void)
++{
++ ucb1x00_unregister_driver(&ucb1x00_switches_driver);
++}
++
++module_init(ucb1x00_switches_init);
++module_exit(ucb1x00_switches_exit);
++
++MODULE_AUTHOR("Bernhard Guillon <Bernhard.Guillon@opensimpad.org>");
++MODULE_DESCRIPTION("UCB1x00 Switches driver for Siemens SIMpad");
++MODULE_LICENSE("GPL");
diff --git a/recipes/linux/linux/simpad/linux-2.6.27-SIMpad-ucb1x00-ts-supend-and-accuracy.patch b/recipes/linux/linux/simpad/linux-2.6.27-SIMpad-ucb1x00-ts-supend-and-accuracy.patch
new file mode 100644
index 0000000000..ef40cd05ef
--- /dev/null
+++ b/recipes/linux/linux/simpad/linux-2.6.27-SIMpad-ucb1x00-ts-supend-and-accuracy.patch
@@ -0,0 +1,105 @@
+Index: linux-2.6.27/drivers/mfd/ucb1x00-ts.c
+===================================================================
+--- linux-2.6.27.orig/drivers/mfd/ucb1x00-ts.c 2008-10-10 00:13:53.000000000 +0200
++++ linux-2.6.27/drivers/mfd/ucb1x00-ts.c 2008-12-04 01:27:04.168672848 +0100
+@@ -16,6 +16,10 @@
+ * It is important to note that the signal connected to the ADCSYNC
+ * pin should provide pulses even when the LCD is blanked, otherwise
+ * a pen touch needed to unblank the LCD will never be read.
++ *
++ * mrdata: -added some accuracy improvement based on thesings collie patch
++ * -added suspend fix
++ *
+ */
+ #include <linux/module.h>
+ #include <linux/moduleparam.h>
+@@ -103,6 +107,8 @@
+ UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_GND |
+ UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
+
++ udelay(55);
++
+ return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPY, ts->adcsync);
+ }
+ }
+@@ -129,7 +135,7 @@
+ UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
+ UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA);
+
+- udelay(55);
++ udelay(165);
+
+ return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPY, ts->adcsync);
+ }
+@@ -157,7 +163,7 @@
+ UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
+ UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA);
+
+- udelay(55);
++ udelay(165);
+
+ return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPX, ts->adcsync);
+ }
+@@ -218,7 +224,11 @@
+ ucb1x00_adc_enable(ts->ucb);
+
+ x = ucb1x00_ts_read_xpos(ts);
++ ucb1x00_adc_disable(ts->ucb);
++ ucb1x00_adc_enable(ts->ucb);
+ y = ucb1x00_ts_read_ypos(ts);
++ ucb1x00_adc_disable(ts->ucb);
++ ucb1x00_adc_enable(ts->ucb);
+ p = ucb1x00_ts_read_pressure(ts);
+
+ /*
+@@ -229,8 +239,11 @@
+
+ msleep(10);
+
+- ucb1x00_enable(ts->ucb);
++ if ((x < 60) || (y < 60)) {
++ p = 0;
++ }
+
++ ucb1x00_enable(ts->ucb);
+
+ if (ucb1x00_ts_pen_down(ts)) {
+ set_current_state(TASK_INTERRUPTIBLE);
+@@ -248,7 +261,9 @@
+ }
+
+ timeout = MAX_SCHEDULE_TIMEOUT;
++
+ } else {
++
+ ucb1x00_disable(ts->ucb);
+
+ /*
+@@ -267,6 +282,14 @@
+
+ try_to_freeze();
+
++ /*
++ * While suspend the ktsd-thread goes sleep -> try_to_freeze()
++ * While resume the ktsd-thread do wakup and must rune one time
++ * again to do a clean re-setup -> enable_irq: UCB_IRQ_TSPX
++ */
++ if(ts->restart)
++ timeout = HZ / 100;
++
+ schedule_timeout(timeout);
+ }
+
+@@ -349,8 +372,12 @@
+ * TS interrupt mode is set up again
+ * after sleep.
+ */
++
+ ts->restart = 1;
+ wake_up(&ts->irq_wait);
++
++ printk(KERN_INFO "ucb1x00-ts.c -> ucb1x00_ts_resume() ktsd - restart *DONE*\n");
++
+ }
+ return 0;
+ }
diff --git a/recipes/linux/linux/tosa/defconfig b/recipes/linux/linux/tosa/defconfig
new file mode 100644
index 0000000000..6c8383761a
--- /dev/null
+++ b/recipes/linux/linux/tosa/defconfig
@@ -0,0 +1,1988 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.28
+# Thu Feb 19 21:40:37 2009
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ARCH_MTD_XIP=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=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_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+# CONFIG_GROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+# CONFIG_BLK_DEV_INITRD is not set
+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_COMPAT_BRK=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_MODVERSIONS 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
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=m
+CONFIG_IOSCHED_DEADLINE=m
+CONFIG_IOSCHED_CFQ=m
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_NOOP=y
+CONFIG_DEFAULT_IOSCHED="noop"
+CONFIG_CLASSIC_RCU=y
+CONFIG_FREEZER=y
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X 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_KIRKWOOD is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_ORION5X 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
+# CONFIG_ARCH_MSM is not set
+
+#
+# Intel PXA2xx/PXA3xx Implementations
+#
+# CONFIG_ARCH_GUMSTIX is not set
+# CONFIG_ARCH_LUBBOCK is not set
+# CONFIG_MACH_LOGICPD_PXA270 is not set
+# CONFIG_MACH_MAINSTONE is not set
+# CONFIG_MACH_MP900C is not set
+# CONFIG_ARCH_PXA_IDP is not set
+CONFIG_PXA_SHARPSL=y
+# CONFIG_MACH_POODLE is not set
+# CONFIG_MACH_CORGI is not set
+# CONFIG_MACH_SHEPHERD is not set
+# CONFIG_MACH_HUSKY is not set
+# CONFIG_MACH_AKITA is not set
+# CONFIG_MACH_SPITZ is not set
+# CONFIG_MACH_BORZOI is not set
+CONFIG_MACH_TOSA=y
+# CONFIG_ARCH_VIPER is not set
+# CONFIG_ARCH_PXA_ESERIES is not set
+# CONFIG_TRIZEPS_PXA is not set
+# CONFIG_MACH_EM_X270 is not set
+# CONFIG_MACH_COLIBRI is not set
+# CONFIG_MACH_ZYLONITE is not set
+# CONFIG_MACH_LITTLETON is not set
+# CONFIG_MACH_TAVOREVB is not set
+# CONFIG_MACH_SAAR is not set
+# CONFIG_MACH_ARMCORE is not set
+# CONFIG_MACH_CM_X300 is not set
+# CONFIG_MACH_MAGICIAN is not set
+# CONFIG_MACH_MIOA701 is not set
+# CONFIG_MACH_PCM027 is not set
+# CONFIG_ARCH_PXA_PALM is not set
+# CONFIG_PXA_EZX is not set
+CONFIG_PXA25x=y
+# CONFIG_PXA_PWM is not set
+# CONFIG_TOSA_BT is not set
+CONFIG_PXA_HAVE_BOARD_IRQS=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_PABRT_NOIFAR=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 is not set
+CONFIG_XSCALE_PMU=y
+CONFIG_SHARP_PARAM=y
+CONFIG_SHARP_SCOOP=y
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+CONFIG_PCCARD=y
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_LOAD_CIS=y
+# CONFIG_PCMCIA_IOCTL is not set
+
+#
+# PC-card bridges
+#
+CONFIG_PCMCIA_PXA2XX=y
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PREEMPT=y
+CONFIG_HZ=100
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+CONFIG_ARCH_FLATMEM_HAS_HOLES=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_RESOURCES_64BIT is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE=" debug "
+# CONFIG_XIP_KERNEL is not set
+CONFIG_KEXEC=y
+CONFIG_ATAGS_PROC=y
+
+#
+# CPU Power Management
+#
+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_POWERSAVE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+CONFIG_CPU_FREQ_PXA=y
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+CONFIG_BINFMT_AOUT=m
+CONFIG_BINFMT_MISC=m
+
+#
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+CONFIG_APM_EMULATION=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=m
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=m
+CONFIG_NET_KEY=m
+# CONFIG_NET_KEY_MIGRATE 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 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=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=m
+CONFIG_INET_TCP_DIAG=m
+# 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=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 is not set
+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_NDISC_NODETYPE=y
+CONFIG_IPV6_TUNNEL=m
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_MROUTE is not set
+# CONFIG_NETWORK_SECMARK is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_ADVANCED=y
+
+#
+# Core Netfilter Configuration
+#
+# CONFIG_NETFILTER_NETLINK_QUEUE is not set
+# CONFIG_NETFILTER_NETLINK_LOG is not set
+# CONFIG_NF_CONNTRACK is not set
+CONFIG_NETFILTER_XTABLES=m
+# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
+# CONFIG_NETFILTER_XT_TARGET_DSCP is not set
+# CONFIG_NETFILTER_XT_TARGET_MARK is not set
+# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
+# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set
+# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set
+# CONFIG_NETFILTER_XT_TARGET_TRACE is not set
+# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
+# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set
+# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set
+# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
+# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
+# CONFIG_NETFILTER_XT_MATCH_ESP is not set
+# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
+# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set
+# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set
+# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set
+# CONFIG_NETFILTER_XT_MATCH_MAC is not set
+# CONFIG_NETFILTER_XT_MATCH_MARK is not set
+# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set
+# CONFIG_NETFILTER_XT_MATCH_OWNER is not set
+# CONFIG_NETFILTER_XT_MATCH_POLICY is not set
+# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set
+# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set
+# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set
+# CONFIG_NETFILTER_XT_MATCH_REALM is not set
+# CONFIG_NETFILTER_XT_MATCH_RECENT is not set
+# CONFIG_NETFILTER_XT_MATCH_SCTP is not set
+# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set
+# CONFIG_NETFILTER_XT_MATCH_STRING is not set
+# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set
+# CONFIG_NETFILTER_XT_MATCH_TIME is not set
+# CONFIG_NETFILTER_XT_MATCH_U32 is not set
+# CONFIG_IP_VS is not set
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_NF_DEFRAG_IPV4 is not set
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
+CONFIG_IP_NF_MATCH_AH=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_TTL=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_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_TTL=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
+#
+# CONFIG_IP6_NF_QUEUE is not set
+# CONFIG_IP6_NF_IPTABLES is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+CONFIG_IRDA=m
+
+#
+# IrDA protocols
+#
+CONFIG_IRLAN=m
+CONFIG_IRNET=m
+CONFIG_IRCOMM=m
+# CONFIG_IRDA_ULTRA is not set
+
+#
+# IrDA options
+#
+# CONFIG_IRDA_CACHE_LAST_LSAP is not set
+# CONFIG_IRDA_FAST_RR is not set
+# CONFIG_IRDA_DEBUG is not set
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+# CONFIG_IRTTY_SIR is not set
+
+#
+# Dongle support
+#
+# CONFIG_KINGSUN_DONGLE is not set
+# CONFIG_KSDAZZLE_DONGLE is not set
+# CONFIG_KS959_DONGLE is not set
+
+#
+# FIR device drivers
+#
+# CONFIG_USB_IRDA is not set
+# CONFIG_SIGMATEL_FIR is not set
+CONFIG_PXA_FICP=m
+# CONFIG_MCS_FIR 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 is not set
+# CONFIG_BT_HCIBTUSB is not set
+# CONFIG_BT_HCIBTSDIO is not set
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_BCSP=y
+# CONFIG_BT_HCIUART_LL is not set
+CONFIG_BT_HCIBCM203X=m
+CONFIG_BT_HCIBPA10X=m
+CONFIG_BT_HCIBFUSB=m
+CONFIG_BT_HCIDTL1=m
+CONFIG_BT_HCIBT3C=m
+CONFIG_BT_HCIBLUECARD=m
+CONFIG_BT_HCIBTUART=m
+CONFIG_BT_HCIVHCI=m
+# CONFIG_AF_RXRPC is not set
+# CONFIG_PHONET is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+CONFIG_WIRELESS_OLD_REGULATORY=y
+CONFIG_WIRELESS_EXT=y
+CONFIG_WIRELESS_EXT_SYSFS=y
+# CONFIG_MAC80211 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_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_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 is not set
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+CONFIG_MTD_ROM=y
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_SHARP_SL=y
+# 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=y
+# 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_GPIO 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_TMIO=y
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA 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=m
+# 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 is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_ICS932S401 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_C2PORT is not set
+CONFIG_HAVE_IDE=y
+CONFIG_IDE=y
+
+#
+# Please see Documentation/ide/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_IDE_GD=y
+CONFIG_IDE_GD_ATA=y
+# CONFIG_IDE_GD_ATAPI is not set
+CONFIG_BLK_DEV_IDECS=y
+CONFIG_BLK_DEV_IDECD=m
+CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+CONFIG_IDE_PROC_FS=y
+
+#
+# IDE chipset support/bugfixes
+#
+# CONFIG_BLK_DEV_PLATFORM is not set
+# CONFIG_BLK_DEV_IDEDMA is not set
+
+#
+# SCSI device support
+#
+# 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
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+CONFIG_CHR_DEV_SG=m
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+# 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_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_ATA is not set
+CONFIG_MD=y
+# CONFIG_BLK_DEV_MD is not set
+CONFIG_BLK_DEV_DM=m
+# CONFIG_DM_DEBUG is not set
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+# CONFIG_DM_DELAY is not set
+# CONFIG_DM_UEVENT is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+CONFIG_TUN=m
+# CONFIG_VETH is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=m
+# CONFIG_AX88796 is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_ENC28J60 is not set
+# CONFIG_SMC911X is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+CONFIG_NETDEV_1000=y
+CONFIG_NETDEV_10000=y
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+CONFIG_WLAN_80211=y
+# CONFIG_PCMCIA_RAYCS is not set
+CONFIG_LIBERTAS=m
+CONFIG_LIBERTAS_USB=m
+CONFIG_LIBERTAS_CS=m
+CONFIG_LIBERTAS_SDIO=m
+# CONFIG_LIBERTAS_DEBUG is not set
+CONFIG_HERMES=m
+CONFIG_PCMCIA_HERMES=m
+CONFIG_PCMCIA_SPECTRUM=m
+CONFIG_ATMEL=m
+CONFIG_PCMCIA_ATMEL=m
+CONFIG_AIRO_CS=m
+CONFIG_PCMCIA_WL3501=m
+CONFIG_USB_ZD1201=m
+# CONFIG_USB_NET_RNDIS_WLAN is not set
+# CONFIG_IWLWIFI_LEDS is not set
+CONFIG_HOSTAP=m
+CONFIG_HOSTAP_FIRMWARE=y
+# CONFIG_HOSTAP_FIRMWARE_NVRAM is not set
+CONFIG_HOSTAP_CS=m
+
+#
+# USB Network Adapters
+#
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=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_SMSC95XX is not set
+CONFIG_USB_NET_GL620A=m
+CONFIG_USB_NET_NET1080=m
+CONFIG_USB_NET_PLUSB=m
+# CONFIG_USB_NET_MCS7830 is not set
+# CONFIG_USB_NET_RNDIS_HOST is not set
+# CONFIG_USB_NET_CDC_SUBSET is not set
+# CONFIG_USB_NET_ZAURUS is not set
+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
+# 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 is not set
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+# CONFIG_PPP_MPPE is not set
+# CONFIG_PPPOE is not set
+# CONFIG_PPPOL2TP is not set
+# CONFIG_SLIP is not set
+CONFIG_SLHC=m
+# 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=m
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=480
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=640
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+# CONFIG_INPUT_APMPOWER is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_CORGI is not set
+# CONFIG_KEYBOARD_SPITZ is not set
+CONFIG_KEYBOARD_TOSA=y
+# CONFIG_KEYBOARD_TOSA_USE_EXT_KEYCODES is not set
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_INPUT_MOUSE 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_CORGI is not set
+# 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_INEXIO 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_WM97XX=y
+# CONFIG_TOUCHSCREEN_WM9705 is not set
+CONFIG_TOUCHSCREEN_WM9712=y
+# CONFIG_TOUCHSCREEN_WM9713 is not set
+# CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE is not set
+# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
+# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
+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_CM109 is not set
+CONFIG_INPUT_UINPUT=m
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=m
+CONFIG_SERIAL_8250_CS=m
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED 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_HW_RANDOM=m
+# CONFIG_NVRAM is not set
+# CONFIG_R3964 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_IPWIRELESS 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
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_PXA=y
+# CONFIG_I2C_PXA_SLAVE is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_AT24 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_TPS65010 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
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_PXA2XX is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_AT25 is not set
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_GPIO_SYSFS is not set
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_W1 is not set
+CONFIG_POWER_SUPPLY=y
+# CONFIG_POWER_SUPPLY_DEBUG is not set
+CONFIG_PDA_POWER=y
+CONFIG_APM_POWER=y
+# CONFIG_BATTERY_DS2760 is not set
+CONFIG_BATTERY_TOSA=y
+# CONFIG_BATTERY_WM97XX is not set
+# CONFIG_BATTERY_BQ27x00 is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+CONFIG_MFD_CORE=y
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_UCB1400_CORE is not set
+CONFIG_MFD_TMIO=y
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+CONFIG_MFD_TC6393XB=y
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+CONFIG_VIDEO_DEV=m
+CONFIG_VIDEO_V4L2_COMMON=m
+CONFIG_VIDEO_ALLOW_V4L1=y
+CONFIG_VIDEO_V4L1_COMPAT=y
+# CONFIG_DVB_CORE is not set
+CONFIG_VIDEO_MEDIA=m
+
+#
+# Multimedia drivers
+#
+# CONFIG_MEDIA_ATTACH is not set
+CONFIG_MEDIA_TUNER=m
+# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set
+CONFIG_MEDIA_TUNER_SIMPLE=m
+CONFIG_MEDIA_TUNER_TDA8290=m
+CONFIG_MEDIA_TUNER_TDA9887=m
+CONFIG_MEDIA_TUNER_TEA5761=m
+CONFIG_MEDIA_TUNER_TEA5767=m
+CONFIG_MEDIA_TUNER_MT20XX=m
+CONFIG_MEDIA_TUNER_XC2028=m
+CONFIG_MEDIA_TUNER_XC5000=m
+CONFIG_VIDEO_V4L2=m
+CONFIG_VIDEO_V4L1=m
+CONFIG_VIDEO_CAPTURE_DRIVERS=y
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
+CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
+# CONFIG_VIDEO_VIVI is not set
+# 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_SOC_CAMERA is not set
+CONFIG_V4L_USB_DRIVERS=y
+# CONFIG_USB_VIDEO_CLASS is not set
+CONFIG_USB_GSPCA=m
+# CONFIG_USB_M5602 is not set
+# CONFIG_USB_GSPCA_CONEX is not set
+# CONFIG_USB_GSPCA_ETOMS is not set
+# CONFIG_USB_GSPCA_FINEPIX is not set
+# CONFIG_USB_GSPCA_MARS is not set
+# CONFIG_USB_GSPCA_OV519 is not set
+# CONFIG_USB_GSPCA_PAC207 is not set
+# CONFIG_USB_GSPCA_PAC7311 is not set
+# CONFIG_USB_GSPCA_SONIXB is not set
+# CONFIG_USB_GSPCA_SONIXJ is not set
+# CONFIG_USB_GSPCA_SPCA500 is not set
+# CONFIG_USB_GSPCA_SPCA501 is not set
+# CONFIG_USB_GSPCA_SPCA505 is not set
+# CONFIG_USB_GSPCA_SPCA506 is not set
+# CONFIG_USB_GSPCA_SPCA508 is not set
+# CONFIG_USB_GSPCA_SPCA561 is not set
+# CONFIG_USB_GSPCA_STK014 is not set
+# CONFIG_USB_GSPCA_SUNPLUS is not set
+# CONFIG_USB_GSPCA_T613 is not set
+# CONFIG_USB_GSPCA_TV8532 is not set
+# CONFIG_USB_GSPCA_VC032X is not set
+# CONFIG_USB_GSPCA_ZC3XX is not set
+# CONFIG_VIDEO_PVRUSB2 is not set
+# CONFIG_VIDEO_EM28XX is not set
+# CONFIG_VIDEO_USBVISION is not set
+CONFIG_VIDEO_USBVIDEO=m
+CONFIG_USB_VICAM=m
+CONFIG_USB_IBMCAM=m
+CONFIG_USB_KONICAWC=m
+# CONFIG_USB_QUICKCAM_MESSENGER is not set
+# CONFIG_USB_ET61X251 is not set
+# CONFIG_VIDEO_OVCAMCHIP is not set
+CONFIG_USB_OV511=m
+CONFIG_USB_SE401=m
+CONFIG_USB_SN9C102=m
+CONFIG_USB_STV680=m
+# CONFIG_USB_ZC0301 is not set
+# CONFIG_USB_PWC is not set
+# CONFIG_USB_ZR364XX is not set
+# CONFIG_USB_STKWEBCAM is not set
+# CONFIG_USB_S2255 is not set
+CONFIG_RADIO_ADAPTERS=y
+CONFIG_USB_DSBR=m
+# CONFIG_USB_SI470X is not set
+# CONFIG_USB_MR800 is not set
+CONFIG_DAB=y
+CONFIG_USB_DABUSB=m
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_PXA is not set
+# CONFIG_FB_MBX is not set
+# CONFIG_FB_W100 is not set
+CONFIG_FB_TMIO=y
+CONFIG_FB_TMIO_ACCELL=y
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+# CONFIG_LCD_CORGI is not set
+# CONFIG_LCD_LTV350QV is not set
+# CONFIG_LCD_ILI9320 is not set
+# CONFIG_LCD_TDO24M is not set
+# CONFIG_LCD_VGG2432A4 is not set
+# CONFIG_LCD_PLATFORM is not set
+CONFIG_LCD_TOSA=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_CORGI is not set
+CONFIG_BACKLIGHT_TOSA=y
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+# CONFIG_FONT_8x16 is not set
+# 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
+# CONFIG_LOGO is not set
+CONFIG_SOUND=y
+CONFIG_SOUND_OSS_CORE=y
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+CONFIG_SND_HWDEP=m
+CONFIG_SND_RAWMIDI=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 is not set
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+CONFIG_SND_VMASTER=y
+CONFIG_SND_AC97_CODEC=y
+CONFIG_SND_DRIVERS=y
+CONFIG_SND_DUMMY=m
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+# CONFIG_SND_AC97_POWER_SAVE is not set
+CONFIG_SND_ARM=y
+CONFIG_SND_PXA2XX_LIB=y
+CONFIG_SND_PXA2XX_LIB_AC97=y
+# CONFIG_SND_PXA2XX_AC97 is not set
+CONFIG_SND_SPI=y
+CONFIG_SND_USB=y
+CONFIG_SND_USB_AUDIO=m
+# CONFIG_SND_USB_CAIAQ is not set
+CONFIG_SND_PCMCIA=y
+# CONFIG_SND_VXPOCKET is not set
+# CONFIG_SND_PDAUDIOCF is not set
+CONFIG_SND_SOC=y
+CONFIG_SND_SOC_AC97_BUS=y
+CONFIG_SND_PXA2XX_SOC=y
+CONFIG_SND_PXA2XX_SOC_AC97=y
+CONFIG_SND_PXA2XX_SOC_TOSA=y
+# CONFIG_SND_SOC_ALL_CODECS is not set
+CONFIG_SND_SOC_WM9712=y
+# CONFIG_SOUND_PRIME is not set
+CONFIG_AC97_BUS=y
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=m
+# CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=m
+# CONFIG_HID_PID 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
+
+#
+# Special HID drivers
+#
+CONFIG_HID_COMPAT=y
+CONFIG_HID_A4TECH=m
+CONFIG_HID_APPLE=m
+CONFIG_HID_BELKIN=m
+CONFIG_HID_BRIGHT=m
+CONFIG_HID_CHERRY=m
+CONFIG_HID_CHICONY=m
+CONFIG_HID_CYPRESS=m
+CONFIG_HID_DELL=m
+CONFIG_HID_EZKEY=m
+CONFIG_HID_GYRATION=m
+CONFIG_HID_LOGITECH=m
+# CONFIG_LOGITECH_FF is not set
+# CONFIG_LOGIRUMBLEPAD2_FF is not set
+CONFIG_HID_MICROSOFT=m
+CONFIG_HID_MONTEREY=m
+CONFIG_HID_PANTHERLORD=m
+# CONFIG_PANTHERLORD_FF is not set
+CONFIG_HID_PETALYNX=m
+CONFIG_HID_SAMSUNG=m
+CONFIG_HID_SONY=m
+CONFIG_HID_SUNPLUS=m
+# CONFIG_THRUSTMASTER_FF is not set
+# CONFIG_ZEROPLUS_FF 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=m
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_SUSPEND is not set
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+CONFIG_USB_MON=y
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+CONFIG_USB_OHCI_HCD=m
+# 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=m
+CONFIG_USB_SL811_CS=m
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+# CONFIG_USB_MUSB_HDRC is not set
+# CONFIG_USB_GADGET_MUSB_HDRC is not set
+
+#
+# USB Device Class drivers
+#
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD 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_ISD200 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_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+CONFIG_USB_MDC800=m
+CONFIG_USB_MICROTEK=m
+
+#
+# USB port drivers
+#
+CONFIG_USB_SERIAL=m
+CONFIG_USB_EZUSB=y
+CONFIG_USB_SERIAL_GENERIC=y
+# CONFIG_USB_SERIAL_AIRCABLE is not set
+# CONFIG_USB_SERIAL_ARK3116 is not set
+CONFIG_USB_SERIAL_BELKIN=m
+# CONFIG_USB_SERIAL_CH341 is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+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 is not set
+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_IUU is not set
+CONFIG_USB_SERIAL_KEYSPAN_PDA=m
+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 is not set
+# 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=m
+CONFIG_USB_SERIAL_KOBIL_SCT=m
+CONFIG_USB_SERIAL_MCT_U232=m
+# CONFIG_USB_SERIAL_MOS7720 is not set
+# CONFIG_USB_SERIAL_MOS7840 is not set
+# CONFIG_USB_SERIAL_MOTOROLA is not set
+# CONFIG_USB_SERIAL_NAVMAN is not set
+CONFIG_USB_SERIAL_PL2303=m
+# CONFIG_USB_SERIAL_OTI6858 is not set
+# CONFIG_USB_SERIAL_SPCP8X5 is not set
+# CONFIG_USB_SERIAL_HP4X is not set
+CONFIG_USB_SERIAL_SAFE=m
+# CONFIG_USB_SERIAL_SAFE_PADDED is not set
+# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
+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 is not set
+
+#
+# USB Miscellaneous drivers
+#
+CONFIG_USB_EMI62=m
+CONFIG_USB_EMI26=m
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+CONFIG_USB_RIO500=m
+CONFIG_USB_LEGOTOWER=m
+CONFIG_USB_LCD=m
+# CONFIG_USB_BERRY_CHARGE is not set
+CONFIG_USB_LED=m
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+CONFIG_USB_CYTHERM=m
+# CONFIG_USB_PHIDGET is not set
+CONFIG_USB_IDMOUSE=m
+# 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
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
+CONFIG_USB_GADGET=m
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+CONFIG_USB_GADGET_VBUS_DRAW=2
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+CONFIG_USB_GADGET_PXA25X=y
+CONFIG_USB_PXA25X=m
+# CONFIG_USB_PXA25X_SMALL is not set
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_FSL_QE is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+# CONFIG_USB_GADGET_DUALSPEED is not set
+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 is not set
+CONFIG_USB_G_SERIAL=m
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_CDC_COMPOSITE is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_UNSAFE_RESUME=y
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+CONFIG_SDIO_UART=m
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+CONFIG_MMC_PXA=y
+# CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_SPI is not set
+# CONFIG_MMC_TMIO is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+# CONFIG_LEDS_PCA9532 is not set
+# CONFIG_LEDS_GPIO is not set
+# CONFIG_LEDS_PCA955X is not set
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=m
+CONFIG_LEDS_TRIGGER_IDE_DISK=y
+# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
+# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
+# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
+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_DS1374 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
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_DRV_SA1100=y
+# CONFIG_DMADEVICES is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_UIO 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 is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FILE_LOCKING=y
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+# CONFIG_ZISOFS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS 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_FS_WBUF_VERIFY is not set
+CONFIG_JFFS2_SUMMARY=y
+# CONFIG_JFFS2_FS_XATTR is not set
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_ZLIB=y
+CONFIG_JFFS2_LZO=y
+CONFIG_JFFS2_RTIME=y
+CONFIG_JFFS2_RUBIN=y
+# CONFIG_JFFS2_CMODE_NONE is not set
+CONFIG_JFFS2_CMODE_PRIORITY=y
+# CONFIG_JFFS2_CMODE_SIZE is not set
+# CONFIG_JFFS2_CMODE_FAVOURLZO is not set
+CONFIG_CRAMFS=m
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+CONFIG_NFS_V4=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
+CONFIG_SUNRPC_GSS=m
+# CONFIG_SUNRPC_REGISTER_V4 is not set
+CONFIG_RPCSEC_GSS_KRB5=m
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+CONFIG_SMB_FS=m
+CONFIG_SMB_NLS_DEFAULT=y
+CONFIG_SMB_NLS_REMOTE="cp437"
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
+# CONFIG_CIFS_XATTR 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
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=m
+CONFIG_NLS_DEFAULT="cp437"
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+
+#
+# Tracers
+#
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_DEBUG_USER is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=m
+CONFIG_CRYPTO_ALGAPI2=m
+CONFIG_CRYPTO_AEAD=m
+CONFIG_CRYPTO_AEAD2=m
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_BLKCIPHER2=m
+CONFIG_CRYPTO_HASH=m
+CONFIG_CRYPTO_HASH2=m
+CONFIG_CRYPTO_RNG2=m
+CONFIG_CRYPTO_MANAGER=m
+CONFIG_CRYPTO_MANAGER2=m
+# CONFIG_CRYPTO_GF128MUL is not set
+CONFIG_CRYPTO_NULL=m
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_AUTHENC=m
+CONFIG_CRYPTO_TEST=m
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=m
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=m
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=m
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+# CONFIG_CRYPTO_TGR192 is not set
+CONFIG_CRYPTO_WP512=m
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_BLOWFISH=m
+# CONFIG_CRYPTO_CAMELLIA is not set
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_DES=m
+# CONFIG_CRYPTO_FCRYPT is not set
+CONFIG_CRYPTO_KHAZAD=m
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=m
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_CRC_CCITT=m
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/recipes/linux/linux/ts72xx/defconfig b/recipes/linux/linux/ts72xx/defconfig
new file mode 100644
index 0000000000..75931d9cb1
--- /dev/null
+++ b/recipes/linux/linux/ts72xx/defconfig
@@ -0,0 +1,1184 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.22.6
+# Wed Sep 5 00:08:45 2007
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+# CONFIG_GENERIC_GPIO is not set
+# CONFIG_GENERIC_TIME is not set
+# CONFIG_GENERIC_CLOCKEVENTS is not set
+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_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_LOG_BUF_SHIFT=14
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+# CONFIG_BLK_DEV_INITRD is not set
+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_TIMERFD=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
+
+#
+# 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 is not set
+CONFIG_IOSCHED_DEADLINE=y
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_DEFAULT_AS is not set
+CONFIG_DEFAULT_DEADLINE=y
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="deadline"
+
+#
+# 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=y
+# 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_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# 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
+
+#
+# Cirrus EP93xx Implementation Options
+#
+CONFIG_CRUNCH=y
+
+#
+# EP93xx Platforms
+#
+# CONFIG_MACH_ADSSPHERE is not set
+CONFIG_MACH_EDB9302=y
+# CONFIG_MACH_EDB9302A is not set
+# CONFIG_MACH_EDB9312 is not set
+CONFIG_MACH_EDB9315=y
+CONFIG_MACH_EDB9315A=y
+CONFIG_MACH_GESBC9312=y
+# CONFIG_MACH_MICRO9 is not set
+# CONFIG_MACH_MICRO9H is not set
+# CONFIG_MACH_MICRO9M is not set
+# CONFIG_MACH_MICRO9L is not set
+CONFIG_MACH_TS72XX=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM920T=y
+CONFIG_CPU_32v4T=y
+CONFIG_CPU_ABRT_EV4T=y
+CONFIG_CPU_CACHE_V4WT=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_OUTER_CACHE is not set
+CONFIG_ARM_VIC=y
+
+#
+# Bus support
+#
+CONFIG_ARM_AMBA=y
+# 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_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_ZONE_DMA_FLAG=1
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttyAM0,115200 ip=192.168.1.3:192.168.1.2:192.168.1.2:255.255.255.0 root=/dev/nfs nfsroot=192.168.1.2:/media/data/devel/om2007.2/ts72xx/tmp/deploy/glibc/images/ts72xx/nfs_root"
+# 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=y
+# 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
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+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=y
+# CONFIG_NET_KEY_MIGRATE is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+CONFIG_INET_TUNNEL=y
+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=y
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_MIP6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+CONFIG_INET6_XFRM_MODE_TRANSPORT=y
+CONFIG_INET6_XFRM_MODE_TUNNEL=y
+CONFIG_INET6_XFRM_MODE_BEET=y
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=y
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_MULTIPLE_TABLES 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
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# 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
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_REDBOOT_PARTS=y
+CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
+# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
+# CONFIG_MTD_REDBOOT_PARTS_READONLY 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 is not set
+CONFIG_MTD_GEN_PROBE=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_NOSWAP=y
+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_GEOMETRY 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_OTP 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=y
+# CONFIG_MTD_ABSENT 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=0x0
+CONFIG_MTD_PHYSMAP_BANKWIDTH=1
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_VERIFY_WRITE=y
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+CONFIG_MTD_NAND_TS7250=y
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_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=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 is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH 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
+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 is not set
+
+#
+# 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_EP93XX_ETH=y
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 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 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 is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# 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_AMBA_PL010=y
+CONFIG_SERIAL_AMBA_PL010_CONSOLE=y
+# CONFIG_SERIAL_AMBA_PL011 is not set
+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
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_EP93XX_WATCHDOG is not set
+CONFIG_TS72XX_WATCHDOG=y
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+# CONFIG_HW_RANDOM is not set
+# 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_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=y
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+# 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
+# CONFIG_I2C_EP93XX is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 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_I2C_DEBUG_CORE=y
+CONFIG_I2C_DEBUG_ALGO=y
+CONFIG_I2C_DEBUG_BUS=y
+CONFIG_I2C_DEBUG_CHIP=y
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+# CONFIG_HWMON is not set
+
+#
+# Misc devices
+#
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
+# LED devices
+#
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+CONFIG_LEDS_EP93XX=y
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+
+#
+# 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_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+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=y
+CONFIG_USB_DYNAMIC_MINORS=y
+# 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
+
+#
+# USB Device Class drivers
+#
+CONFIG_USB_ACM=y
+# 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 Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_MON is not set
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+CONFIG_USB_SERIAL=y
+CONFIG_USB_SERIAL_CONSOLE=y
+# CONFIG_USB_SERIAL_GENERIC is not set
+# 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=m
+# 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 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=m
+# 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_SERIAL_DEBUG 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 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
+# 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
+#
+
+#
+# Platform 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=y
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_DRV_EP93XX=y
+# CONFIG_RTC_DRV_PL031 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 is not set
+# CONFIG_EXT4DEV_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+# 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 is not set
+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 is not set
+# 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 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=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+
+#
+# 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_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+CONFIG_DEBUG_SLAB=y
+# CONFIG_DEBUG_SLAB_LEAK 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_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_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 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_LIBCRC32C=y
+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/recipes/linux/linux/vmware/defconfig b/recipes/linux/linux/vmware/defconfig
new file mode 100644
index 0000000000..08396faef8
--- /dev/null
+++ b/recipes/linux/linux/vmware/defconfig
@@ -0,0 +1,1242 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.16
+# Sun Mar 26 17:18:35 2006
+#
+CONFIG_X86_32=y
+CONFIG_SEMAPHORE_SLEEPERS=y
+CONFIG_X86=y
+CONFIG_MMU=y
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_GENERIC_IOMAP=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_DMI=y
+
+#
+# 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=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+CONFIG_AUDIT=y
+CONFIG_AUDITSYSCALL=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_UID16=y
+CONFIG_VM86=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+# CONFIG_EMBEDDED is not set
+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_EPOLL=y
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=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_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+# CONFIG_LBD 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"
+
+#
+# Processor type and features
+#
+CONFIG_X86_PC=y
+# CONFIG_X86_ELAN is not set
+# CONFIG_X86_VOYAGER is not set
+# CONFIG_X86_NUMAQ is not set
+# CONFIG_X86_SUMMIT is not set
+# CONFIG_X86_BIGSMP is not set
+# CONFIG_X86_VISWS is not set
+# CONFIG_X86_GENERICARCH is not set
+# CONFIG_X86_ES7000 is not set
+# CONFIG_M386 is not set
+# CONFIG_M486 is not set
+CONFIG_M586=y
+# CONFIG_M586TSC is not set
+# CONFIG_M586MMX is not set
+# CONFIG_M686 is not set
+# CONFIG_MPENTIUMII is not set
+# CONFIG_MPENTIUMIII is not set
+# CONFIG_MPENTIUMM is not set
+# CONFIG_MPENTIUM4 is not set
+# CONFIG_MK6 is not set
+# CONFIG_MK7 is not set
+# CONFIG_MK8 is not set
+# CONFIG_MCRUSOE is not set
+# CONFIG_MEFFICEON is not set
+# CONFIG_MWINCHIPC6 is not set
+# CONFIG_MWINCHIP2 is not set
+# CONFIG_MWINCHIP3D is not set
+# CONFIG_MGEODEGX1 is not set
+# CONFIG_MGEODE_LX is not set
+# CONFIG_MCYRIXIII is not set
+# CONFIG_MVIAC3_2 is not set
+CONFIG_X86_GENERIC=y
+CONFIG_X86_CMPXCHG=y
+CONFIG_X86_XADD=y
+CONFIG_X86_L1_CACHE_SHIFT=7
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_X86_PPRO_FENCE=y
+CONFIG_X86_F00F_BUG=y
+CONFIG_X86_WP_WORKS_OK=y
+CONFIG_X86_INVLPG=y
+CONFIG_X86_BSWAP=y
+CONFIG_X86_POPAD_OK=y
+CONFIG_X86_CMPXCHG64=y
+CONFIG_X86_ALIGNMENT_16=y
+CONFIG_X86_INTEL_USERCOPY=y
+# CONFIG_HPET_TIMER is not set
+# CONFIG_SMP is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+# CONFIG_X86_UP_APIC is not set
+CONFIG_X86_MCE=y
+CONFIG_X86_MCE_NONFATAL=y
+# CONFIG_TOSHIBA is not set
+# CONFIG_I8K is not set
+# CONFIG_X86_REBOOTFIXUPS is not set
+# CONFIG_MICROCODE is not set
+# CONFIG_X86_MSR is not set
+# CONFIG_X86_CPUID is not set
+
+#
+# Firmware Drivers
+#
+# CONFIG_EDD is not set
+# CONFIG_DELL_RBU is not set
+# CONFIG_DCDBAS is not set
+CONFIG_NOHIGHMEM=y
+# CONFIG_HIGHMEM4G is not set
+# CONFIG_HIGHMEM64G is not set
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_3G_OPT is not set
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+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=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_MATH_EMULATION is not set
+CONFIG_MTRR=y
+# CONFIG_EFI is not set
+# CONFIG_REGPARM is not set
+CONFIG_SECCOMP=y
+CONFIG_HZ_100=y
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=100
+# CONFIG_KEXEC is not set
+CONFIG_PHYSICAL_START=0x100000
+CONFIG_DOUBLEFAULT=y
+
+#
+# Power management options (ACPI, APM)
+#
+CONFIG_PM=y
+CONFIG_PM_LEGACY=y
+# CONFIG_PM_DEBUG is not set
+# CONFIG_SOFTWARE_SUSPEND is not set
+
+#
+# ACPI (Advanced Configuration and Power Interface) Support
+#
+CONFIG_ACPI=y
+CONFIG_ACPI_SLEEP=y
+CONFIG_ACPI_SLEEP_PROC_FS=y
+# CONFIG_ACPI_SLEEP_PROC_SLEEP is not set
+CONFIG_ACPI_AC=y
+CONFIG_ACPI_BATTERY=y
+CONFIG_ACPI_BUTTON=y
+CONFIG_ACPI_VIDEO=m
+# CONFIG_ACPI_HOTKEY is not set
+CONFIG_ACPI_FAN=y
+CONFIG_ACPI_PROCESSOR=y
+CONFIG_ACPI_THERMAL=y
+# CONFIG_ACPI_ASUS is not set
+# CONFIG_ACPI_IBM is not set
+# CONFIG_ACPI_TOSHIBA is not set
+CONFIG_ACPI_BLACKLIST_YEAR=0
+# CONFIG_ACPI_DEBUG is not set
+CONFIG_ACPI_EC=y
+CONFIG_ACPI_POWER=y
+CONFIG_ACPI_SYSTEM=y
+CONFIG_X86_PM_TIMER=y
+# CONFIG_ACPI_CONTAINER is not set
+
+#
+# APM (Advanced Power Management) BIOS Support
+#
+# CONFIG_APM is not set
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+#
+CONFIG_PCI=y
+# CONFIG_PCI_GOBIOS is not set
+# CONFIG_PCI_GOMMCONFIG is not set
+# CONFIG_PCI_GODIRECT is not set
+CONFIG_PCI_GOANY=y
+CONFIG_PCI_BIOS=y
+CONFIG_PCI_DIRECT=y
+CONFIG_PCI_MMCONFIG=y
+# CONFIG_PCIEPORTBUS is not set
+CONFIG_PCI_LEGACY_PROC=y
+CONFIG_ISA_DMA_API=y
+CONFIG_ISA=y
+# CONFIG_EISA is not set
+# CONFIG_MCA is not set
+# CONFIG_SCx200 is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_AOUT=y
+CONFIG_BINFMT_MISC=y
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE 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_TUNNEL is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 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_NET_DIVERT 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 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+CONFIG_PNP=y
+# CONFIG_PNP_DEBUG is not set
+
+#
+# Protocols
+#
+# CONFIG_ISAPNP is not set
+# CONFIG_PNPBIOS is not set
+# CONFIG_PNPACPI is not set
+
+#
+# Block devices
+#
+CONFIG_BLK_DEV_FD=y
+# CONFIG_BLK_DEV_XD is not set
+# 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 is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+# CONFIG_BLK_DEV_HD_IDE is not set
+# CONFIG_BLK_DEV_IDEDISK is not set
+# CONFIG_IDEDISK_MULTI_MODE is not set
+CONFIG_BLK_DEV_IDECD=y
+# 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=y
+# CONFIG_BLK_DEV_CMD640 is not set
+# CONFIG_BLK_DEV_IDEPNP is not set
+# CONFIG_BLK_DEV_IDEPCI is not set
+# CONFIG_IDE_ARM is not set
+# CONFIG_IDE_CHIPSETS is not set
+# CONFIG_BLK_DEV_IDEDMA is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+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
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=y
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS 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_7000FASST is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AHA152X is not set
+# CONFIG_SCSI_AHA1542 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_DPT_I2O is not set
+# CONFIG_SCSI_IN2000 is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_DTC3280 is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# CONFIG_SCSI_GENERIC_NCR5380 is not set
+# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_NCR53C406A is not set
+CONFIG_SCSI_SYM53C8XX_2=y
+CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
+CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
+CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
+# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
+# CONFIG_SCSI_IPR is not set
+# CONFIG_SCSI_PAS16 is not set
+# CONFIG_SCSI_PSI240I is not set
+# CONFIG_SCSI_QLOGIC_FAS is not set
+# CONFIG_SCSI_QLOGIC_FC is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_ULTRASTOR is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+CONFIG_FUSION=y
+CONFIG_FUSION_SPI=y
+# CONFIG_FUSION_FC is not set
+# CONFIG_FUSION_SAS is not set
+CONFIG_FUSION_MAX_SGE=128
+# CONFIG_FUSION_CTL 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
+# CONFIG_NET_SB1000 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_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=y
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_AC3200 is not set
+# CONFIG_APRICOT is not set
+# CONFIG_B44 is not set
+# CONFIG_FORCEDETH is not set
+# CONFIG_CS89x0 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 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
+
+#
+# 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
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO 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
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# 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 is not set
+# 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_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_INPORT is not set
+# CONFIG_MOUSE_LOGIBM is not set
+# CONFIG_MOUSE_PC110PAD is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_PCIPS2 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_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+# CONFIG_SERIAL_8250_CONSOLE is not set
+# CONFIG_SERIAL_8250_ACPI is not set
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=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 is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_SONYPI is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+# CONFIG_MWAVE is not set
+# CONFIG_CS5535_GPIO is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_HPET is not set
+# CONFIG_HANGCHECK_TIMER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK 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_F71805F is not set
+# CONFIG_SENSORS_HDAPS is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Misc devices
+#
+# CONFIG_IBM_ASM is not set
+
+#
+# Multimedia Capabilities Port drivers
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+# CONFIG_FB_CIRRUS is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_ARC is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+CONFIG_FB_VGA16=y
+CONFIG_FB_VESA=y
+CONFIG_VIDEO_SELECT=y
+# CONFIG_FB_HGA is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_NVIDIA is not set
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_I810 is not set
+# CONFIG_FB_INTEL is not set
+# CONFIG_FB_MATROX is not set
+# CONFIG_FB_RADEON_OLD is not set
+# CONFIG_FB_RADEON is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_ATY 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_CYBLA is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_GEODE is not set
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+CONFIG_VGA_CONSOLE=y
+# CONFIG_MDA_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=y
+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 is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+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_SUSPEND is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_SPLIT_ISO is not set
+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_OHCI_HCD is not set
+CONFIG_USB_UHCI_HCD=y
+# 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_ISD200 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_LIBUSUAL is not set
+
+#
+# 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 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_MTOUCH is not set
+# CONFIG_USB_ITMTOUCH is not set
+# CONFIG_USB_EGALAX 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 Multimedia devices
+#
+# CONFIG_USB_DABUSB is not set
+
+#
+# Video4Linux support is needed for USB Multimedia device support
+#
+
+#
+# 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 is not set
+# 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_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_CYTHERM is not set
+# CONFIG_USB_PHIDGETKIT is not set
+# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD 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 is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+# CONFIG_EDAC 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_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_OCFS2_FS is not set
+CONFIG_MINIX_FS=y
+CONFIG_ROMFS_FS=y
+CONFIG_INOTIFY=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+CONFIG_AUTOFS4_FS=y
+CONFIG_FUSE_FS=y
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+# CONFIG_ZISOFS is not set
+CONFIG_UDF_FS=y
+CONFIG_UDF_NLS=y
+
+#
+# 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_KCORE=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_HUGETLBFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_RELAYFS_FS is not set
+# 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_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 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
+# 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
+
+#
+# Instrumentation Support
+#
+# CONFIG_PROFILING is not set
+# CONFIG_KPROBES is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_EARLY_PRINTK=y
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_X86_BIOS_REBOOT=y
+CONFIG_KTIME_SCALAR=y
+
+CONFIG_CMDLINE="root=/dev/sda1"
diff --git a/recipes/linux/linux/vortex86sx/defconfig b/recipes/linux/linux/vortex86sx/defconfig
new file mode 100644
index 0000000000..c78bd66d95
--- /dev/null
+++ b/recipes/linux/linux/vortex86sx/defconfig
@@ -0,0 +1,2130 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.29-rc5
+# Fri Feb 20 13:23:22 2009
+#
+# CONFIG_64BIT is not set
+CONFIG_X86_32=y
+# CONFIG_X86_64 is not set
+CONFIG_X86=y
+CONFIG_ARCH_DEFCONFIG="arch/x86/configs/i386_defconfig"
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_CLOCKSOURCE_WATCHDOG=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_FAST_CMPXCHG_LOCAL=y
+CONFIG_MMU=y
+CONFIG_ZONE_DMA=y
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_GENERIC_IOMAP=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+# CONFIG_GENERIC_TIME_VSYSCALL is not set
+CONFIG_ARCH_HAS_CPU_RELAX=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
+CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y
+# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_HAVE_CPUMASK_OF_CPU_MAP is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+# CONFIG_ZONE_DMA32 is not set
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+# CONFIG_AUDIT_ARCH is not set
+CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_X86_BIOS_REBOOT=y
+CONFIG_KTIME_SCALAR=y
+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="-nanopc"
+CONFIG_LOCALVERSION_AUTO=y
+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_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+# CONFIG_CLASSIC_RCU is not set
+# CONFIG_TREE_RCU is not set
+CONFIG_PREEMPT_RCU=y
+# CONFIG_RCU_TRACE is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
+CONFIG_IKCONFIG=m
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_NET_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+# CONFIG_EMBEDDED is not set
+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_PCSPKR_PLATFORM=y
+CONFIG_COMPAT_BRK=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+CONFIG_DEFAULT_DEADLINE=y
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="deadline"
+# CONFIG_FREEZER is not set
+
+#
+# Processor type and features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+# CONFIG_SMP is not set
+CONFIG_X86_PC=y
+# CONFIG_X86_ELAN is not set
+# CONFIG_X86_VOYAGER is not set
+# CONFIG_X86_GENERICARCH is not set
+# CONFIG_X86_VSMP is not set
+CONFIG_X86_RDC321X=y
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
+# CONFIG_PARAVIRT_GUEST is not set
+# CONFIG_MEMTEST is not set
+# CONFIG_M386 is not set
+CONFIG_M486=y
+# CONFIG_M586 is not set
+# CONFIG_M586TSC is not set
+# CONFIG_M586MMX is not set
+# CONFIG_M686 is not set
+# CONFIG_MPENTIUMII is not set
+# CONFIG_MPENTIUMIII is not set
+# CONFIG_MPENTIUMM is not set
+# CONFIG_MPENTIUM4 is not set
+# CONFIG_MK6 is not set
+# CONFIG_MK7 is not set
+# CONFIG_MK8 is not set
+# CONFIG_MCRUSOE is not set
+# CONFIG_MEFFICEON is not set
+# CONFIG_MWINCHIPC6 is not set
+# CONFIG_MWINCHIP3D is not set
+# CONFIG_MGEODEGX1 is not set
+# CONFIG_MGEODE_LX is not set
+# CONFIG_MCYRIXIII is not set
+# CONFIG_MVIAC3_2 is not set
+# CONFIG_MVIAC7 is not set
+# CONFIG_MPSC is not set
+# CONFIG_MCORE2 is not set
+# CONFIG_GENERIC_CPU is not set
+# CONFIG_X86_GENERIC is not set
+CONFIG_X86_CPU=y
+CONFIG_X86_CMPXCHG=y
+CONFIG_X86_L1_CACHE_SHIFT=4
+CONFIG_X86_XADD=y
+# CONFIG_X86_PPRO_FENCE is not set
+CONFIG_X86_F00F_BUG=y
+CONFIG_X86_WP_WORKS_OK=y
+CONFIG_X86_INVLPG=y
+CONFIG_X86_BSWAP=y
+CONFIG_X86_POPAD_OK=y
+CONFIG_X86_ALIGNMENT_16=y
+CONFIG_X86_MINIMUM_CPU_FAMILY=4
+CONFIG_CPU_SUP_INTEL=y
+CONFIG_CPU_SUP_CYRIX_32=y
+CONFIG_CPU_SUP_AMD=y
+CONFIG_CPU_SUP_CENTAUR_32=y
+CONFIG_CPU_SUP_TRANSMETA_32=y
+CONFIG_CPU_SUP_UMC_32=y
+CONFIG_HPET_TIMER=y
+CONFIG_HPET_EMULATE_RTC=y
+CONFIG_DMI=y
+# CONFIG_IOMMU_HELPER is not set
+# CONFIG_IOMMU_API is not set
+CONFIG_NR_CPUS=1
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+# CONFIG_X86_UP_APIC is not set
+# CONFIG_X86_MCE is not set
+CONFIG_VM86=y
+# CONFIG_TOSHIBA is not set
+# CONFIG_I8K is not set
+CONFIG_X86_REBOOTFIXUPS=y
+# CONFIG_MICROCODE is not set
+# CONFIG_X86_MSR is not set
+# CONFIG_X86_CPUID is not set
+CONFIG_NOHIGHMEM=y
+# CONFIG_HIGHMEM4G is not set
+# CONFIG_HIGHMEM64G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+# CONFIG_X86_PAE is not set
+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+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=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
+# CONFIG_X86_CHECK_BIOS_CORRUPTION is not set
+CONFIG_X86_RESERVE_LOW_64K=y
+CONFIG_MATH_EMULATION=y
+# CONFIG_MTRR is not set
+# CONFIG_SECCOMP is not set
+CONFIG_HZ_100=y
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=100
+CONFIG_SCHED_HRTICK=y
+# CONFIG_KEXEC is not set
+CONFIG_PHYSICAL_START=0x100000
+# CONFIG_RELOCATABLE is not set
+CONFIG_PHYSICAL_ALIGN=0x100000
+CONFIG_COMPAT_VDSO=y
+# CONFIG_CMDLINE_BOOL is not set
+
+#
+# Power management and ACPI options
+#
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+# CONFIG_SUSPEND is not set
+# CONFIG_HIBERNATION is not set
+# CONFIG_ACPI is not set
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_IDLE_GOV_LADDER=y
+CONFIG_CPU_IDLE_GOV_MENU=y
+
+#
+# Bus options (PCI etc.)
+#
+CONFIG_PCI=y
+# CONFIG_PCI_GOBIOS is not set
+# CONFIG_PCI_GOMMCONFIG is not set
+# CONFIG_PCI_GODIRECT is not set
+# CONFIG_PCI_GOOLPC is not set
+CONFIG_PCI_GOANY=y
+CONFIG_PCI_BIOS=y
+CONFIG_PCI_DIRECT=y
+CONFIG_PCI_DOMAINS=y
+# CONFIG_PCIEPORTBUS is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_DEBUG is not set
+# CONFIG_PCI_STUB is not set
+CONFIG_ISA_DMA_API=y
+CONFIG_ISA=y
+# CONFIG_EISA is not set
+# CONFIG_MCA is not set
+# CONFIG_SCx200 is not set
+# CONFIG_OLPC is not set
+# CONFIG_PCCARD is not set
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats / Emulations
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+CONFIG_HAVE_ATOMIC_IOMAP=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_COMPAT_NET_DEV_OPS=y
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP 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 is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_ADVANCED=y
+CONFIG_BRIDGE_NETFILTER=y
+
+#
+# Core Netfilter Configuration
+#
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CT_ACCT=y
+CONFIG_NF_CONNTRACK_MARK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CT_PROTO_DCCP=m
+CONFIG_NF_CT_PROTO_GRE=m
+CONFIG_NF_CT_PROTO_SCTP=m
+CONFIG_NF_CT_PROTO_UDPLITE=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_TPROXY is not set
+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_NFLOG=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+# CONFIG_NETFILTER_XT_TARGET_NOTRACK is not set
+CONFIG_NETFILTER_XT_TARGET_RATEEST=m
+# CONFIG_NETFILTER_XT_TARGET_TRACE is not set
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
+# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+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
+CONFIG_NETFILTER_XT_MATCH_DSCP=m
+CONFIG_NETFILTER_XT_MATCH_ESP=m
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
+CONFIG_NETFILTER_XT_MATCH_HELPER=m
+CONFIG_NETFILTER_XT_MATCH_IPRANGE=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_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_OWNER=m
+CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_QUOTA=m
+CONFIG_NETFILTER_XT_MATCH_RATEEST=m
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+# CONFIG_NETFILTER_XT_MATCH_RECENT is not set
+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_TIME=m
+CONFIG_NETFILTER_XT_MATCH_U32=m
+# CONFIG_IP_VS is not set
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_NF_DEFRAG_IPV4=m
+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_ADDRTYPE=m
+CONFIG_IP_NF_MATCH_AH=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_TTL=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_NETMAP=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_NF_NAT_SNMP_BASIC=m
+CONFIG_NF_NAT_PROTO_DCCP=m
+CONFIG_NF_NAT_PROTO_GRE=m
+CONFIG_NF_NAT_PROTO_UDPLITE=m
+CONFIG_NF_NAT_PROTO_SCTP=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_CLUSTERIP=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_TTL=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+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_BRIDGE_EBT_NFLOG=m
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+CONFIG_STP=m
+CONFIG_BRIDGE=m
+# CONFIG_NET_DSA is not set
+CONFIG_VLAN_8021Q=m
+# CONFIG_VLAN_8021Q_GVRP is not set
+# CONFIG_DECNET is not set
+CONFIG_LLC=m
+CONFIG_LLC2=m
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+CONFIG_NET_CLS_ROUTE=y
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+CONFIG_BT=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_HCIBTUSB=m
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_BCSP=y
+CONFIG_BT_HCIUART_LL=y
+CONFIG_BT_HCIBCM203X=m
+CONFIG_BT_HCIBPA10X=m
+CONFIG_BT_HCIBFUSB=m
+CONFIG_BT_HCIVHCI=m
+# CONFIG_AF_RXRPC is not set
+# CONFIG_PHONET is not set
+CONFIG_WIRELESS=y
+CONFIG_CFG80211=m
+# CONFIG_CFG80211_REG_DEBUG is not set
+CONFIG_NL80211=y
+CONFIG_WIRELESS_OLD_REGULATORY=y
+CONFIG_WIRELESS_EXT=y
+CONFIG_WIRELESS_EXT_SYSFS=y
+# CONFIG_LIB80211 is not set
+CONFIG_MAC80211=m
+
+#
+# Rate control algorithm selection
+#
+CONFIG_MAC80211_RC_MINSTREL=y
+# CONFIG_MAC80211_RC_DEFAULT_PID is not set
+CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
+CONFIG_MAC80211_RC_DEFAULT="minstrel"
+CONFIG_MAC80211_MESH=y
+CONFIG_MAC80211_LEDS=y
+# CONFIG_MAC80211_DEBUG_MENU is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+CONFIG_PNP=y
+CONFIG_PNP_DEBUG_MESSAGES=y
+
+#
+# Protocols
+#
+CONFIG_ISAPNP=y
+# CONFIG_PNPBIOS is not set
+# CONFIG_PNPACPI is not set
+CONFIG_BLK_DEV=y
+CONFIG_BLK_DEV_FD=m
+# CONFIG_BLK_DEV_XD is not set
+# 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=m
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+CONFIG_BLK_DEV_NBD=m
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_CDROM_PKTCDVD is not set
+CONFIG_ATA_OVER_ETH=m
+# CONFIG_BLK_DEV_HD is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# 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=y
+CONFIG_SCSI_CONSTANTS=y
+# 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_SRP_ATTRS is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_DH is not set
+CONFIG_ATA=y
+# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_SATA_PMP=y
+# CONFIG_SATA_AHCI is not set
+# CONFIG_SATA_SIL24 is not set
+CONFIG_ATA_SFF=y
+# CONFIG_SATA_SVW is not set
+# CONFIG_ATA_PIIX is not set
+# CONFIG_SATA_MV is not set
+# CONFIG_SATA_NV is not set
+# CONFIG_PDC_ADMA is not set
+# CONFIG_SATA_QSTOR is not set
+# CONFIG_SATA_PROMISE is not set
+# CONFIG_SATA_SX4 is not set
+# CONFIG_SATA_SIL is not set
+# CONFIG_SATA_SIS is not set
+# CONFIG_SATA_ULI is not set
+# CONFIG_SATA_VIA is not set
+# CONFIG_SATA_VITESSE is not set
+# CONFIG_SATA_INIC162X is not set
+# CONFIG_PATA_ALI is not set
+# CONFIG_PATA_AMD is not set
+# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATIIXP is not set
+# CONFIG_PATA_CMD640_PCI is not set
+# CONFIG_PATA_CMD64X is not set
+# CONFIG_PATA_CS5520 is not set
+# CONFIG_PATA_CS5530 is not set
+# CONFIG_PATA_CS5535 is not set
+# CONFIG_PATA_CS5536 is not set
+# CONFIG_PATA_CYPRESS is not set
+# CONFIG_PATA_EFAR is not set
+# CONFIG_ATA_GENERIC is not set
+# CONFIG_PATA_HPT366 is not set
+# CONFIG_PATA_HPT37X is not set
+# CONFIG_PATA_HPT3X2N is not set
+# CONFIG_PATA_HPT3X3 is not set
+# CONFIG_PATA_ISAPNP is not set
+CONFIG_PATA_IT821X=y
+# CONFIG_PATA_IT8213 is not set
+# CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
+# CONFIG_PATA_TRIFLEX is not set
+# CONFIG_PATA_MARVELL is not set
+# CONFIG_PATA_MPIIX is not set
+# CONFIG_PATA_OLDPIIX is not set
+# CONFIG_PATA_NETCELL is not set
+# CONFIG_PATA_NINJA32 is not set
+# CONFIG_PATA_NS87410 is not set
+# CONFIG_PATA_NS87415 is not set
+# CONFIG_PATA_OPTI is not set
+# CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC_OLD is not set
+# CONFIG_PATA_QDI is not set
+# CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RZ1000 is not set
+# CONFIG_PATA_SC1200 is not set
+# CONFIG_PATA_SERVERWORKS is not set
+# CONFIG_PATA_PDC2027X is not set
+# CONFIG_PATA_SIL680 is not set
+# CONFIG_PATA_SIS is not set
+# CONFIG_PATA_VIA is not set
+# CONFIG_PATA_WINBOND is not set
+# CONFIG_PATA_WINBOND_VLB is not set
+# CONFIG_PATA_SCH is not set
+# CONFIG_MD is not set
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# Enable only one of the two stacks, unless you know what you are doing
+#
+# CONFIG_FIREWIRE is not set
+# CONFIG_IEEE1394 is not set
+# CONFIG_I2O is not set
+# CONFIG_MACINTOSH_DRIVERS is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_NET_SB1000 is not set
+# CONFIG_ARCNET is not set
+# CONFIG_PHYLIB is not set
+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_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_NET_TULIP is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_AC3200 is not set
+# CONFIG_APRICOT is not set
+# CONFIG_B44 is not set
+# CONFIG_FORCEDETH is not set
+# CONFIG_CS89x0 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=y
+# 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_R6040=y
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SMSC9420 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_SC92031 is not set
+# CONFIG_ATL2 is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_TR is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
+# 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 is not set
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI 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 is not set
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+CONFIG_PPPOL2TP=m
+# CONFIG_SLIP is not set
+CONFIG_SLHC=m
+# CONFIG_NET_FC is not set
+CONFIG_NETCONSOLE=y
+CONFIG_NETCONSOLE_DYNAMIC=y
+CONFIG_NETPOLL=y
+# CONFIG_NETPOLL_TRAP is not set
+CONFIG_NET_POLL_CONTROLLER=y
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+CONFIG_INPUT_POLLDEV=m
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1280
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=1024
+# CONFIG_INPUT_JOYDEV 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_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=m
+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_ELANTECH is not set
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
+CONFIG_MOUSE_SERIAL=m
+# CONFIG_MOUSE_APPLETOUCH is not set
+# CONFIG_MOUSE_BCM5974 is not set
+# CONFIG_MOUSE_INPORT is not set
+# CONFIG_MOUSE_LOGIBM is not set
+# CONFIG_MOUSE_PC110PAD is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_PCSPKR=m
+# CONFIG_INPUT_APANEL is not set
+# CONFIG_INPUT_WISTRON_BTNS is not set
+# 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_CM109 is not set
+CONFIG_INPUT_UINPUT=m
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_NOZOMI is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_FIX_EARLYCON_MEM=y
+CONFIG_SERIAL_8250_PCI=y
+CONFIG_SERIAL_8250_PNP=y
+CONFIG_SERIAL_8250_NR_UARTS=8
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+# CONFIG_SERIAL_8250_FOURPORT is not set
+# CONFIG_SERIAL_8250_ACCENT is not set
+# CONFIG_SERIAL_8250_BOCA is not set
+# CONFIG_SERIAL_8250_EXAR_ST16C554 is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_RSA is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+CONFIG_NVRAM=m
+CONFIG_RTC=m
+CONFIG_GEN_RTC=m
+CONFIG_GEN_RTC_X=y
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_SONYPI is not set
+# CONFIG_MWAVE is not set
+# CONFIG_PC8736x_GPIO is not set
+# CONFIG_NSC_GPIO is not set
+# CONFIG_CS5535_GPIO is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_HANGCHECK_TIMER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+CONFIG_DEVPORT=y
+CONFIG_I2C=m
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=m
+CONFIG_I2C_HELPER_AUTO=y
+CONFIG_I2C_ALGOBIT=m
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# PC SMBus host controller drivers
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_ISCH is not set
+# CONFIG_I2C_PIIX4 is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+CONFIG_I2C_VIA=m
+CONFIG_I2C_VIAPRO=m
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Graphics adapter I2C/DDC channel drivers
+#
+# CONFIG_I2C_VOODOO3 is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_ELEKTOR is not set
+# CONFIG_I2C_PCA_ISA is not set
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_SCx200_ACB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+CONFIG_DS1682=m
+CONFIG_SENSORS_PCF8574=m
+CONFIG_PCF8575=m
+# CONFIG_SENSORS_PCA9539 is not set
+CONFIG_SENSORS_PCF8591=m
+CONFIG_SENSORS_MAX6875=m
+CONFIG_SENSORS_TSL2550=m
+# 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
+# CONFIG_SPI is not set
+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
+# CONFIG_GPIOLIB 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_BATTERY_DS2760 is not set
+# CONFIG_BATTERY_BQ27x00 is not set
+# CONFIG_HWMON is not set
+CONFIG_THERMAL=y
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+CONFIG_SOFT_WATCHDOG=m
+# CONFIG_ACQUIRE_WDT is not set
+# CONFIG_ADVANTECH_WDT is not set
+# CONFIG_ALIM1535_WDT is not set
+# CONFIG_ALIM7101_WDT is not set
+# CONFIG_SC520_WDT is not set
+# CONFIG_EUROTECH_WDT is not set
+# CONFIG_IB700_WDT is not set
+# CONFIG_IBMASR is not set
+# CONFIG_WAFER_WDT is not set
+# CONFIG_I6300ESB_WDT is not set
+# CONFIG_ITCO_WDT is not set
+# CONFIG_IT8712F_WDT is not set
+# CONFIG_IT87_WDT is not set
+# CONFIG_HP_WATCHDOG is not set
+# CONFIG_SC1200_WDT is not set
+# CONFIG_PC87413_WDT is not set
+# CONFIG_RDC321X_WDT is not set
+# CONFIG_60XX_WDT is not set
+# CONFIG_SBC8360_WDT is not set
+# CONFIG_SBC7240_WDT is not set
+# CONFIG_CPU5_WDT is not set
+# CONFIG_SMSC_SCH311X_WDT is not set
+# CONFIG_SMSC37B787_WDT is not set
+# CONFIG_W83627HF_WDT is not set
+# CONFIG_W83697HF_WDT is not set
+# CONFIG_W83697UG_WDT is not set
+# CONFIG_W83877F_WDT is not set
+# CONFIG_W83977F_WDT is not set
+# CONFIG_MACHZ_WDT is not set
+# CONFIG_SBC_EPX_C3_WATCHDOG is not set
+
+#
+# ISA-based Watchdog Cards
+#
+# CONFIG_PCWATCHDOG is not set
+# CONFIG_MIXCOMWD is not set
+# CONFIG_WDT is not set
+
+#
+# PCI-based Watchdog Cards
+#
+# CONFIG_PCIPCWATCHDOG is not set
+# CONFIG_WDTPCI is not set
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_REGULATOR is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+CONFIG_VIDEO_DEV=m
+CONFIG_VIDEO_V4L2_COMMON=m
+CONFIG_VIDEO_ALLOW_V4L1=y
+CONFIG_VIDEO_V4L1_COMPAT=y
+CONFIG_DVB_CORE=m
+CONFIG_VIDEO_MEDIA=m
+
+#
+# Multimedia drivers
+#
+# CONFIG_MEDIA_ATTACH is not set
+CONFIG_MEDIA_TUNER=m
+# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set
+CONFIG_MEDIA_TUNER_SIMPLE=m
+CONFIG_MEDIA_TUNER_TDA8290=m
+CONFIG_MEDIA_TUNER_TDA9887=m
+CONFIG_MEDIA_TUNER_TEA5761=m
+CONFIG_MEDIA_TUNER_TEA5767=m
+CONFIG_MEDIA_TUNER_MT20XX=m
+CONFIG_MEDIA_TUNER_XC2028=m
+CONFIG_MEDIA_TUNER_XC5000=m
+CONFIG_VIDEO_V4L2=m
+CONFIG_VIDEO_V4L1=m
+CONFIG_VIDEO_CAPTURE_DRIVERS=y
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
+CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
+# CONFIG_VIDEO_VIVI is not set
+# CONFIG_VIDEO_BT848 is not set
+# CONFIG_VIDEO_PMS is not set
+# 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_VIDEO_STRADIS is not set
+# CONFIG_VIDEO_ZORAN is not set
+# CONFIG_VIDEO_SAA7134 is not set
+# CONFIG_VIDEO_MXB is not set
+# CONFIG_VIDEO_HEXIUM_ORION is not set
+# CONFIG_VIDEO_HEXIUM_GEMINI is not set
+# CONFIG_VIDEO_CX88 is not set
+# CONFIG_VIDEO_CX23885 is not set
+# CONFIG_VIDEO_AU0828 is not set
+# CONFIG_VIDEO_IVTV is not set
+# CONFIG_VIDEO_CX18 is not set
+# CONFIG_VIDEO_CAFE_CCIC is not set
+# CONFIG_SOC_CAMERA is not set
+CONFIG_V4L_USB_DRIVERS=y
+CONFIG_USB_VIDEO_CLASS=m
+CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y
+CONFIG_USB_GSPCA=m
+# CONFIG_USB_M5602 is not set
+# CONFIG_USB_STV06XX is not set
+# CONFIG_USB_GSPCA_CONEX is not set
+# CONFIG_USB_GSPCA_ETOMS is not set
+# CONFIG_USB_GSPCA_FINEPIX is not set
+# CONFIG_USB_GSPCA_MARS is not set
+# CONFIG_USB_GSPCA_OV519 is not set
+# CONFIG_USB_GSPCA_OV534 is not set
+# CONFIG_USB_GSPCA_PAC207 is not set
+# CONFIG_USB_GSPCA_PAC7311 is not set
+# CONFIG_USB_GSPCA_SONIXB is not set
+# CONFIG_USB_GSPCA_SONIXJ is not set
+# CONFIG_USB_GSPCA_SPCA500 is not set
+# CONFIG_USB_GSPCA_SPCA501 is not set
+# CONFIG_USB_GSPCA_SPCA505 is not set
+# CONFIG_USB_GSPCA_SPCA506 is not set
+# CONFIG_USB_GSPCA_SPCA508 is not set
+# CONFIG_USB_GSPCA_SPCA561 is not set
+# CONFIG_USB_GSPCA_STK014 is not set
+# CONFIG_USB_GSPCA_SUNPLUS is not set
+# CONFIG_USB_GSPCA_T613 is not set
+# CONFIG_USB_GSPCA_TV8532 is not set
+# CONFIG_USB_GSPCA_VC032X is not set
+# CONFIG_USB_GSPCA_ZC3XX is not set
+# 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=m
+# CONFIG_USB_W9968CF is not set
+CONFIG_USB_OV511=m
+# 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=m
+# CONFIG_USB_PWC_DEBUG is not set
+# CONFIG_USB_ZR364XX is not set
+# CONFIG_USB_STKWEBCAM is not set
+# CONFIG_USB_S2255 is not set
+CONFIG_RADIO_ADAPTERS=y
+# CONFIG_RADIO_CADET is not set
+# CONFIG_RADIO_RTRACK is not set
+# CONFIG_RADIO_RTRACK2 is not set
+# CONFIG_RADIO_AZTECH is not set
+# CONFIG_RADIO_GEMTEK is not set
+# CONFIG_RADIO_GEMTEK_PCI is not set
+# CONFIG_RADIO_MAXIRADIO is not set
+# CONFIG_RADIO_MAESTRO is not set
+# CONFIG_RADIO_SF16FMI is not set
+# CONFIG_RADIO_SF16FMR2 is not set
+# CONFIG_RADIO_TERRATEC is not set
+# CONFIG_RADIO_TRUST is not set
+# CONFIG_RADIO_TYPHOON is not set
+# CONFIG_RADIO_ZOLTRIX is not set
+# CONFIG_USB_DSBR is not set
+# CONFIG_USB_SI470X is not set
+# CONFIG_USB_MR800 is not set
+# CONFIG_RADIO_TEA5764 is not set
+# CONFIG_DVB_DYNAMIC_MINORS is not set
+CONFIG_DVB_CAPTURE_DRIVERS=y
+
+#
+# Supported SAA7146 based PCI Adapters
+#
+# CONFIG_TTPCI_EEPROM is not set
+# CONFIG_DVB_AV7110 is not set
+# CONFIG_DVB_BUDGET_CORE is not set
+
+#
+# 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_SIANO_SMS1XXX is not set
+
+#
+# Supported FlexCopII (B2C2) Adapters
+#
+# CONFIG_DVB_B2C2_FLEXCOP is not set
+
+#
+# Supported BT878 Adapters
+#
+
+#
+# Supported Pluto2 Adapters
+#
+# CONFIG_DVB_PLUTO2 is not set
+
+#
+# Supported SDMC DM1105 Adapters
+#
+# CONFIG_DVB_DM1105 is not set
+
+#
+# Supported DVB Frontends
+#
+
+#
+# Customise DVB Frontends
+#
+# CONFIG_DVB_FE_CUSTOMISE is not set
+
+#
+# Multistandard (satellite) frontends
+#
+# CONFIG_DVB_STB0899 is not set
+# CONFIG_DVB_STB6100 is not set
+
+#
+# DVB-S (satellite) frontends
+#
+# CONFIG_DVB_CX24110 is not set
+# CONFIG_DVB_CX24123 is not set
+# CONFIG_DVB_MT312 is not set
+# CONFIG_DVB_S5H1420 is not set
+# CONFIG_DVB_STV0288 is not set
+# CONFIG_DVB_STB6000 is not set
+# CONFIG_DVB_STV0299 is not set
+# CONFIG_DVB_TDA8083 is not set
+# CONFIG_DVB_TDA10086 is not set
+# CONFIG_DVB_TDA8261 is not set
+# CONFIG_DVB_VES1X93 is not set
+# CONFIG_DVB_TUNER_ITD1000 is not set
+# CONFIG_DVB_TUNER_CX24113 is not set
+# CONFIG_DVB_TDA826X is not set
+# CONFIG_DVB_TUA6100 is not set
+# CONFIG_DVB_CX24116 is not set
+# CONFIG_DVB_SI21XX 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_DRX397XD 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
+# CONFIG_DVB_TDA10048 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
+# CONFIG_DVB_LGDT3304 is not set
+# CONFIG_DVB_S5H1409 is not set
+# CONFIG_DVB_AU8522 is not set
+# CONFIG_DVB_S5H1411 is not set
+
+#
+# ISDB-T (terrestrial) frontends
+#
+# CONFIG_DVB_S921 is not set
+
+#
+# Digital terrestrial only tuners/PLL
+#
+# CONFIG_DVB_PLL is not set
+# CONFIG_DVB_TUNER_DIB0070 is not set
+
+#
+# SEC control devices for DVB-S
+#
+# CONFIG_DVB_LNBP21 is not set
+# CONFIG_DVB_ISL6405 is not set
+# CONFIG_DVB_ISL6421 is not set
+# CONFIG_DVB_LGS8GL5 is not set
+
+#
+# Tools to develop new frontends
+#
+# CONFIG_DVB_DUMMY_FE is not set
+# CONFIG_DVB_AF9013 is not set
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_AGP is not set
+# CONFIG_DRM 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_BOOT_VESA_SUPPORT=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_CIRRUS is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_ARC is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_VGA16 is not set
+# CONFIG_FB_VESA is not set
+# CONFIG_FB_N411 is not set
+# CONFIG_FB_HGA is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_NVIDIA is not set
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_I810 is not set
+# CONFIG_FB_LE80578 is not set
+# CONFIG_FB_INTEL 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=y
+# CONFIG_FB_SIS_300 is not set
+CONFIG_FB_SIS_315=y
+# CONFIG_FB_VIA 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_VT8623 is not set
+# CONFIG_FB_CYBLA is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_ARK is not set
+# CONFIG_FB_PM3 is not set
+# CONFIG_FB_CARMINE is not set
+# CONFIG_FB_GEODE is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+CONFIG_VGA_CONSOLE=y
+# CONFIG_VGACON_SOFT_SCROLLBACK is not set
+# CONFIG_MDA_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
+# CONFIG_SOUND is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+CONFIG_HID_DEBUG=y
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# Special HID drivers
+#
+CONFIG_HID_COMPAT=y
+CONFIG_HID_A4TECH=y
+CONFIG_HID_APPLE=y
+CONFIG_HID_BELKIN=y
+CONFIG_HID_CHERRY=y
+CONFIG_HID_CHICONY=y
+CONFIG_HID_CYPRESS=y
+CONFIG_HID_EZKEY=y
+CONFIG_HID_GYRATION=y
+CONFIG_HID_LOGITECH=y
+# CONFIG_LOGITECH_FF is not set
+# CONFIG_LOGIRUMBLEPAD2_FF is not set
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MONTEREY=y
+CONFIG_HID_NTRIG=y
+CONFIG_HID_PANTHERLORD=y
+# CONFIG_PANTHERLORD_FF is not set
+CONFIG_HID_PETALYNX=y
+CONFIG_HID_SAMSUNG=y
+CONFIG_HID_SONY=y
+CONFIG_HID_SUNPLUS=y
+# CONFIG_GREENASIA_FF is not set
+CONFIG_HID_TOPSEED=y
+# CONFIG_THRUSTMASTER_FF is not set
+# CONFIG_ZEROPLUS_FF is not set
+CONFIG_USB_SUPPORT=y
+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
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_SUSPEND is not set
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_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
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_WHCI_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+
+#
+# USB Device Class drivers
+#
+CONFIG_USB_ACM=m
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD 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_ISD200 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_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+CONFIG_USB_SERIAL=y
+# CONFIG_USB_SERIAL_CONSOLE is not set
+# CONFIG_USB_EZUSB is not set
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_AIRCABLE is not set
+# CONFIG_USB_SERIAL_ARK3116 is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_CH341 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_IUU is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN 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_MOTOROLA is not set
+# CONFIG_USB_SERIAL_NAVMAN is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_OTI6858 is not set
+# CONFIG_USB_SERIAL_SPCP8X5 is not set
+# CONFIG_USB_SERIAL_HP4X is not set
+# CONFIG_USB_SERIAL_SAFE is not set
+# CONFIG_USB_SERIAL_SIEMENS_MPI 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_SERIAL_OPTICON is not set
+# CONFIG_USB_SERIAL_DEBUG 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_SEVSEG 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_SISUSBVGA 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
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
+# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_UWB is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+# CONFIG_LEDS_ALIX2 is not set
+# CONFIG_LEDS_PCA9532 is not set
+# CONFIG_LEDS_CLEVO_MAIL is not set
+# CONFIG_LEDS_PCA955X is not set
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=m
+CONFIG_LEDS_TRIGGER_HEARTBEAT=m
+# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=m
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_INFINIBAND is not set
+# CONFIG_EDAC is not set
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+CONFIG_X86_PLATFORM_DEVICES=y
+
+#
+# Firmware Drivers
+#
+# CONFIG_EDD is not set
+CONFIG_FIRMWARE_MEMMAP=y
+# CONFIG_DELL_RBU is not set
+# CONFIG_DCDBAS is not set
+CONFIG_DMIID=y
+# CONFIG_ISCSI_IBFT_FIND 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 is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_FILE_LOCKING=y
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=m
+
+#
+# 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=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_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLBFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_CONFIGFS_FS=y
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+CONFIG_NFS_V4=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
+CONFIG_NFSD_V4=y
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
+CONFIG_SUNRPC_GSS=m
+# CONFIG_SUNRPC_REGISTER_V4 is not set
+CONFIG_RPCSEC_GSS_KRB5=m
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
+# CONFIG_CIFS_XATTR 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
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="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=m
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_PRINTK_TIME=y
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+CONFIG_TIMER_STATS=y
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+CONFIG_DEBUG_PREEMPT=y
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_VIRTUAL is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+CONFIG_ARCH_WANT_FRAME_POINTERS=y
+# CONFIG_FRAME_POINTER is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_USER_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+
+#
+# Tracers
+#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_PREEMPT_TRACER is not set
+# CONFIG_SYSPROF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_POWER_TRACER is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_MMIOTRACE is not set
+# CONFIG_PROVIDE_OHCI1394_DMA_INIT is not set
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_STRICT_DEVMEM is not set
+CONFIG_X86_VERBOSE_BOOTUP=y
+CONFIG_EARLY_PRINTK=y
+# CONFIG_EARLY_PRINTK_DBGP is not set
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_PAGEALLOC is not set
+# CONFIG_X86_PTDUMP is not set
+CONFIG_DEBUG_RODATA=y
+# CONFIG_DEBUG_RODATA_TEST is not set
+# CONFIG_DEBUG_NX_TEST is not set
+# CONFIG_4KSTACKS is not set
+CONFIG_DOUBLEFAULT=y
+CONFIG_HAVE_MMIOTRACE_SUPPORT=y
+CONFIG_IO_DELAY_TYPE_0X80=0
+CONFIG_IO_DELAY_TYPE_0XED=1
+CONFIG_IO_DELAY_TYPE_UDELAY=2
+CONFIG_IO_DELAY_TYPE_NONE=3
+CONFIG_IO_DELAY_0X80=y
+# CONFIG_IO_DELAY_0XED is not set
+# CONFIG_IO_DELAY_UDELAY is not set
+# CONFIG_IO_DELAY_NONE is not set
+CONFIG_DEFAULT_IO_DELAY_TYPE=0
+# CONFIG_CPA_DEBUG is not set
+# CONFIG_OPTIMIZE_INLINING is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=m
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=m
+CONFIG_CRYPTO_ALGAPI2=m
+CONFIG_CRYPTO_AEAD2=m
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_BLKCIPHER2=m
+CONFIG_CRYPTO_HASH=m
+CONFIG_CRYPTO_HASH2=m
+CONFIG_CRYPTO_RNG2=m
+CONFIG_CRYPTO_MANAGER=m
+CONFIG_CRYPTO_MANAGER2=m
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=m
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=m
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_CRC32C_INTEL is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=m
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+CONFIG_CRYPTO_SHA1=m
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=m
+# CONFIG_CRYPTO_AES_586 is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_ARC4=m
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=m
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SALSA20_586 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_TWOFISH_586 is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_CRYPTO_DEV_PADLOCK is not set
+# CONFIG_CRYPTO_DEV_GEODE is not set
+# CONFIG_CRYPTO_DEV_HIFN_795X is not set
+CONFIG_HAVE_KVM=y
+# CONFIG_VIRTUALIZATION is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_FIRST_BIT=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=m
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+CONFIG_CRC_ITU_T=m
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
+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/recipes/linux/linux/x86/defconfig b/recipes/linux/linux/x86/defconfig
new file mode 100644
index 0000000000..0c5c8cae8a
--- /dev/null
+++ b/recipes/linux/linux/x86/defconfig
@@ -0,0 +1,3283 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.21
+# Mon Oct 22 10:56:59 2007
+#
+CONFIG_X86_32=y
+CONFIG_GENERIC_TIME=y
+CONFIG_CLOCKSOURCE_WATCHDOG=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_SEMAPHORE_SLEEPERS=y
+CONFIG_X86=y
+CONFIG_MMU=y
+CONFIG_ZONE_DMA=y
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_GENERIC_IOMAP=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_DMI=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
+CONFIG_AUDIT=y
+CONFIG_AUDITSYSCALL=y
+# CONFIG_IKCONFIG is not set
+# CONFIG_CPUSETS is not set
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+# CONFIG_EMBEDDED is not set
+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_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=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+CONFIG_STOP_MACHINE=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"
+
+#
+# Processor type and features
+#
+# CONFIG_TICK_ONESHOT is not set
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_SMP=y
+CONFIG_X86_PC=y
+# CONFIG_X86_ELAN is not set
+# CONFIG_X86_VOYAGER is not set
+# CONFIG_X86_NUMAQ is not set
+# CONFIG_X86_SUMMIT is not set
+# CONFIG_X86_BIGSMP is not set
+# CONFIG_X86_VISWS is not set
+# CONFIG_X86_GENERICARCH is not set
+# CONFIG_X86_ES7000 is not set
+# CONFIG_PARAVIRT is not set
+# CONFIG_M386 is not set
+CONFIG_M486=y
+# CONFIG_M586 is not set
+# CONFIG_M586TSC is not set
+# CONFIG_M586MMX is not set
+# CONFIG_M686 is not set
+# CONFIG_MPENTIUMII is not set
+# CONFIG_MPENTIUMIII is not set
+# CONFIG_MPENTIUMM is not set
+# CONFIG_MCORE2 is not set
+# CONFIG_MPENTIUM4 is not set
+# CONFIG_MK6 is not set
+# CONFIG_MK7 is not set
+# CONFIG_MK8 is not set
+# CONFIG_MCRUSOE is not set
+# CONFIG_MEFFICEON is not set
+# CONFIG_MWINCHIPC6 is not set
+# CONFIG_MWINCHIP2 is not set
+# CONFIG_MWINCHIP3D is not set
+# CONFIG_MGEODEGX1 is not set
+# CONFIG_MGEODE_LX is not set
+# CONFIG_MCYRIXIII is not set
+# CONFIG_MVIAC3_2 is not set
+CONFIG_X86_GENERIC=y
+CONFIG_X86_CMPXCHG=y
+CONFIG_X86_L1_CACHE_SHIFT=7
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_X86_PPRO_FENCE=y
+CONFIG_X86_F00F_BUG=y
+CONFIG_X86_WP_WORKS_OK=y
+CONFIG_X86_INVLPG=y
+CONFIG_X86_BSWAP=y
+CONFIG_X86_POPAD_OK=y
+CONFIG_X86_ALIGNMENT_16=y
+CONFIG_X86_INTEL_USERCOPY=y
+CONFIG_HPET_TIMER=y
+CONFIG_NR_CPUS=8
+CONFIG_SCHED_SMT=y
+CONFIG_SCHED_MC=y
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_PREEMPT_BKL=y
+CONFIG_X86_LOCAL_APIC=y
+CONFIG_X86_IO_APIC=y
+CONFIG_X86_MCE=y
+# CONFIG_X86_MCE_NONFATAL is not set
+# CONFIG_X86_MCE_P4THERMAL is not set
+CONFIG_VM86=y
+# CONFIG_TOSHIBA is not set
+# CONFIG_I8K is not set
+# CONFIG_X86_REBOOTFIXUPS is not set
+# CONFIG_MICROCODE is not set
+# CONFIG_X86_MSR is not set
+# CONFIG_X86_CPUID is not set
+
+#
+# Firmware Drivers
+#
+# CONFIG_EDD is not set
+# CONFIG_DELL_RBU is not set
+# CONFIG_DCDBAS is not set
+# CONFIG_NOHIGHMEM is not set
+CONFIG_HIGHMEM4G=y
+# CONFIG_HIGHMEM64G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_HIGHMEM=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+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=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_RESOURCES_64BIT=y
+CONFIG_ZONE_DMA_FLAG=1
+# CONFIG_HIGHPTE is not set
+# CONFIG_MATH_EMULATION is not set
+CONFIG_MTRR=y
+# CONFIG_EFI is not set
+CONFIG_IRQBALANCE=y
+CONFIG_SECCOMP=y
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_KEXEC is not set
+# CONFIG_CRASH_DUMP is not set
+CONFIG_PHYSICAL_START=0x100000
+# CONFIG_RELOCATABLE is not set
+CONFIG_PHYSICAL_ALIGN=0x100000
+# CONFIG_HOTPLUG_CPU is not set
+CONFIG_COMPAT_VDSO=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+
+#
+# Power management options (ACPI, APM)
+#
+CONFIG_PM=y
+CONFIG_PM_LEGACY=y
+# CONFIG_PM_DEBUG is not set
+# CONFIG_PM_SYSFS_DEPRECATED is not set
+
+#
+# ACPI (Advanced Configuration and Power Interface) Support
+#
+CONFIG_ACPI=y
+CONFIG_ACPI_PROCFS=y
+CONFIG_ACPI_AC=y
+CONFIG_ACPI_BATTERY=y
+CONFIG_ACPI_BUTTON=y
+CONFIG_ACPI_VIDEO=m
+CONFIG_ACPI_FAN=y
+# CONFIG_ACPI_DOCK is not set
+CONFIG_ACPI_PROCESSOR=y
+CONFIG_ACPI_THERMAL=y
+# CONFIG_ACPI_ASUS is not set
+CONFIG_ACPI_IBM=m
+# CONFIG_ACPI_IBM_DOCK is not set
+CONFIG_ACPI_IBM_BAY=y
+# CONFIG_ACPI_TOSHIBA is not set
+CONFIG_ACPI_BLACKLIST_YEAR=0
+# CONFIG_ACPI_DEBUG is not set
+CONFIG_ACPI_EC=y
+CONFIG_ACPI_POWER=y
+CONFIG_ACPI_SYSTEM=y
+CONFIG_X86_PM_TIMER=y
+CONFIG_ACPI_CONTAINER=m
+CONFIG_ACPI_SBS=m
+
+#
+# APM (Advanced Power Management) BIOS Support
+#
+CONFIG_APM=y
+# CONFIG_APM_IGNORE_USER_SUSPEND is not set
+# CONFIG_APM_DO_ENABLE is not set
+# CONFIG_APM_CPU_IDLE is not set
+# CONFIG_APM_DISPLAY_BLANK is not set
+# CONFIG_APM_RTC_IS_GMT is not set
+# CONFIG_APM_ALLOW_INTS is not set
+# CONFIG_APM_REAL_MODE_POWER_OFF is not set
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+#
+CONFIG_PCI=y
+# CONFIG_PCI_GOBIOS is not set
+# CONFIG_PCI_GOMMCONFIG is not set
+# CONFIG_PCI_GODIRECT is not set
+CONFIG_PCI_GOANY=y
+CONFIG_PCI_BIOS=y
+CONFIG_PCI_DIRECT=y
+CONFIG_PCI_MMCONFIG=y
+CONFIG_PCIEPORTBUS=y
+# CONFIG_HOTPLUG_PCI_PCIE is not set
+CONFIG_PCIEAER=y
+# CONFIG_PCI_MSI is not set
+CONFIG_HT_IRQ=y
+CONFIG_ISA_DMA_API=y
+# CONFIG_ISA is not set
+# CONFIG_MCA is not set
+CONFIG_SCx200=m
+CONFIG_SCx200HR_TIMER=m
+CONFIG_K8_NB=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+CONFIG_PCCARD=m
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=m
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
+CONFIG_CARDBUS=y
+
+#
+# PC-card bridges
+#
+CONFIG_YENTA=m
+CONFIG_YENTA_O2=y
+CONFIG_YENTA_RICOH=y
+CONFIG_YENTA_TI=y
+CONFIG_YENTA_ENE_TUNE=y
+CONFIG_YENTA_TOSHIBA=y
+CONFIG_PD6729=m
+CONFIG_I82092=m
+CONFIG_PCCARD_NONSTATIC=m
+
+#
+# PCI Hotplug Support
+#
+CONFIG_HOTPLUG_PCI=m
+CONFIG_HOTPLUG_PCI_FAKE=m
+CONFIG_HOTPLUG_PCI_COMPAQ=m
+# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set
+CONFIG_HOTPLUG_PCI_IBM=m
+CONFIG_HOTPLUG_PCI_ACPI=m
+CONFIG_HOTPLUG_PCI_ACPI_IBM=m
+# CONFIG_HOTPLUG_PCI_CPCI is not set
+CONFIG_HOTPLUG_PCI_SHPC=m
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_MISC=y
+
+#
+# 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=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# CONFIG_IP_FIB_TRIE is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_MULTIPATH_CACHED=y
+CONFIG_IP_ROUTE_MULTIPATH_RR=m
+CONFIG_IP_ROUTE_MULTIPATH_RANDOM=m
+CONFIG_IP_ROUTE_MULTIPATH_WRANDOM=m
+CONFIG_IP_ROUTE_MULTIPATH_DRR=m
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+# CONFIG_IP_PIMSM_V1 is not set
+# CONFIG_IP_PIMSM_V2 is not set
+CONFIG_ARPD=y
+# CONFIG_SYN_COOKIES is not set
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_TUNNEL=m
+CONFIG_INET_TUNNEL=y
+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
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+CONFIG_IPV6=y
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+# CONFIG_IPV6_MIP6 is not set
+CONFIG_INET6_XFRM_TUNNEL=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=y
+CONFIG_INET6_XFRM_MODE_TUNNEL=y
+CONFIG_INET6_XFRM_MODE_BEET=y
+CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
+CONFIG_IPV6_SIT=y
+CONFIG_IPV6_TUNNEL=m
+# CONFIG_IPV6_MULTIPLE_TABLES 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_SUPPORT=y
+# CONFIG_IP_NF_CONNTRACK_SUPPORT is not set
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CT_ACCT=y
+CONFIG_NF_CONNTRACK_MARK=y
+# CONFIG_NF_CONNTRACK_EVENTS is not set
+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=y
+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=m
+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
+
+#
+# DECnet: Netfilter Configuration
+#
+# CONFIG_DECNET_NF_GRABULATOR is not set
+
+#
+# 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
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_DCCP=m
+CONFIG_INET_DCCP_DIAG=m
+CONFIG_IP_DCCP_ACKVEC=y
+
+#
+# DCCP CCIDs Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_DCCP_CCID2=m
+# CONFIG_IP_DCCP_CCID2_DEBUG is not set
+CONFIG_IP_DCCP_CCID3=m
+CONFIG_IP_DCCP_TFRC_LIB=m
+# CONFIG_IP_DCCP_CCID3_DEBUG is not set
+CONFIG_IP_DCCP_CCID3_RTO=100
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_SCTP=m
+# CONFIG_SCTP_DBG_MSG is not set
+# CONFIG_SCTP_DBG_OBJCNT is not set
+# CONFIG_SCTP_HMAC_NONE is not set
+# CONFIG_SCTP_HMAC_SHA1 is not set
+CONFIG_SCTP_HMAC_MD5=y
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+CONFIG_TIPC=m
+# CONFIG_TIPC_ADVANCED is not set
+# CONFIG_TIPC_DEBUG is not set
+CONFIG_ATM=m
+CONFIG_ATM_CLIP=m
+# CONFIG_ATM_CLIP_NO_ICMP is not set
+CONFIG_ATM_LANE=m
+CONFIG_ATM_MPOA=m
+CONFIG_ATM_BR2684=m
+# CONFIG_ATM_BR2684_IPFILTER is not set
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_DECNET=m
+# CONFIG_DECNET_ROUTER is not set
+CONFIG_LLC=y
+CONFIG_LLC2=m
+CONFIG_IPX=m
+# CONFIG_IPX_INTERN is not set
+CONFIG_ATALK=m
+CONFIG_DEV_APPLETALK=m
+CONFIG_IPDDP=m
+# CONFIG_IPDDP_ENCAP is not set
+# CONFIG_IPDDP_DECAP is not set
+CONFIG_X25=m
+CONFIG_LAPB=m
+CONFIG_ECONET=m
+# CONFIG_ECONET_AUNUDP is not set
+# CONFIG_ECONET_NATIVE is not set
+CONFIG_WAN_ROUTER=m
+
+#
+# QoS and/or fair queueing
+#
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_FIFO=y
+# CONFIG_NET_SCH_CLK_JIFFIES is not set
+CONFIG_NET_SCH_CLK_GETTIMEOFDAY=y
+# CONFIG_NET_SCH_CLK_CPU is not set
+
+#
+# Queueing/Scheduling
+#
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_ATM=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_INGRESS=m
+
+#
+# Classification
+#
+CONFIG_NET_CLS=y
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+# CONFIG_CLS_U32_PERF is not set
+# CONFIG_CLS_U32_MARK is not set
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+# CONFIG_NET_EMATCH is not set
+# 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
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+CONFIG_IRDA=y
+
+#
+# IrDA protocols
+#
+CONFIG_IRLAN=m
+CONFIG_IRNET=m
+CONFIG_IRCOMM=m
+# CONFIG_IRDA_ULTRA is not set
+
+#
+# IrDA options
+#
+# CONFIG_IRDA_CACHE_LAST_LSAP is not set
+# CONFIG_IRDA_FAST_RR is not set
+# CONFIG_IRDA_DEBUG is not set
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+CONFIG_IRTTY_SIR=m
+
+#
+# Dongle support
+#
+CONFIG_DONGLE=y
+CONFIG_ESI_DONGLE=m
+CONFIG_ACTISYS_DONGLE=m
+CONFIG_TEKRAM_DONGLE=m
+CONFIG_TOIM3232_DONGLE=m
+CONFIG_LITELINK_DONGLE=m
+CONFIG_MA600_DONGLE=m
+CONFIG_GIRBIL_DONGLE=m
+CONFIG_MCP2120_DONGLE=m
+CONFIG_OLD_BELKIN_DONGLE=m
+CONFIG_ACT200L_DONGLE=m
+
+#
+# Old SIR device drivers
+#
+
+#
+# Old Serial dongle support
+#
+
+#
+# FIR device drivers
+#
+CONFIG_USB_IRDA=m
+CONFIG_SIGMATEL_FIR=m
+CONFIG_NSC_FIR=m
+CONFIG_WINBOND_FIR=m
+CONFIG_TOSHIBA_FIR=m
+CONFIG_SMC_IRCC_FIR=m
+CONFIG_ALI_FIR=m
+CONFIG_VLSI_FIR=m
+CONFIG_VIA_FIR=m
+CONFIG_MCS_FIR=m
+CONFIG_BT=y
+# CONFIG_BT_L2CAP is not set
+# CONFIG_BT_SCO is not set
+
+#
+# Bluetooth device drivers
+#
+# CONFIG_BT_HCIUSB is not set
+# CONFIG_BT_HCIUART is not set
+# CONFIG_BT_HCIBCM203X is not set
+# CONFIG_BT_HCIBPA10X is not set
+# CONFIG_BT_HCIBFUSB is not set
+# CONFIG_BT_HCIDTL1 is not set
+# CONFIG_BT_HCIBT3C is not set
+# CONFIG_BT_HCIBLUECARD is not set
+# CONFIG_BT_HCIBTUART is not set
+# CONFIG_BT_HCIVHCI is not set
+CONFIG_IEEE80211=y
+# 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_WIRELESS_EXT=y
+CONFIG_FIB_RULES=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=m
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=m
+# CONFIG_MTD_PARTITIONS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+CONFIG_FTL=m
+CONFIG_NFTL=m
+# CONFIG_NFTL_RW is not set
+CONFIG_INFTL=m
+CONFIG_RFD_FTL=m
+CONFIG_SSFDC=y
+
+#
+# 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=y
+CONFIG_MTD_ROM=y
+CONFIG_MTD_ABSENT=y
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_SC520CDP is not set
+# CONFIG_MTD_TS5500 is not set
+# CONFIG_MTD_AMD76XROM is not set
+# CONFIG_MTD_ICHXROM is not set
+# CONFIG_MTD_ESB2ROM is not set
+# CONFIG_MTD_CK804XROM is not set
+# CONFIG_MTD_SCB2_FLASH is not set
+# CONFIG_MTD_L440GX is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+CONFIG_MTD_PMC551=m
+# CONFIG_MTD_PMC551_BUGFIX is not set
+# CONFIG_MTD_PMC551_DEBUG is not set
+CONFIG_MTD_DATAFLASH=m
+CONFIG_MTD_M25P80=m
+CONFIG_MTD_SLRAM=m
+CONFIG_MTD_PHRAM=m
+# CONFIG_MTD_MTDRAM is not set
+CONFIG_MTD_BLOCK2MTD=y
+
+#
+# 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=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+CONFIG_MTD_NAND_IDS=y
+CONFIG_MTD_NAND_DISKONCHIP=y
+# CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set
+CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0
+# CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE is not set
+CONFIG_MTD_NAND_CAFE=y
+CONFIG_MTD_NAND_CS553X=y
+
+#
+# OneNAND Flash Device Drivers
+#
+CONFIG_MTD_ONENAND=m
+# CONFIG_MTD_ONENAND_VERIFY_WRITE is not set
+# CONFIG_MTD_ONENAND_OTP is not set
+
+#
+# Parallel port support
+#
+CONFIG_PARPORT=y
+CONFIG_PARPORT_PC=y
+# CONFIG_PARPORT_SERIAL is not set
+# CONFIG_PARPORT_PC_FIFO is not set
+# CONFIG_PARPORT_PC_SUPERIO is not set
+# CONFIG_PARPORT_PC_PCMCIA is not set
+# CONFIG_PARPORT_GSC is not set
+CONFIG_PARPORT_AX88796=m
+# CONFIG_PARPORT_1284 is not set
+CONFIG_PARPORT_NOT_PC=y
+
+#
+# Plug and Play support
+#
+CONFIG_PNP=y
+# CONFIG_PNP_DEBUG is not set
+
+#
+# Protocols
+#
+CONFIG_PNPACPI=y
+
+#
+# Block devices
+#
+CONFIG_BLK_DEV_FD=y
+CONFIG_PARIDE=m
+
+#
+# Parallel IDE high-level drivers
+#
+CONFIG_PARIDE_PD=m
+CONFIG_PARIDE_PCD=m
+CONFIG_PARIDE_PF=m
+CONFIG_PARIDE_PT=m
+CONFIG_PARIDE_PG=m
+
+#
+# Parallel IDE protocol modules
+#
+CONFIG_PARIDE_ATEN=m
+CONFIG_PARIDE_BPCK=m
+CONFIG_PARIDE_BPCK6=m
+CONFIG_PARIDE_COMM=m
+CONFIG_PARIDE_DSTR=m
+CONFIG_PARIDE_FIT2=m
+CONFIG_PARIDE_FIT3=m
+CONFIG_PARIDE_EPAT=m
+# CONFIG_PARIDE_EPATC8 is not set
+CONFIG_PARIDE_EPIA=m
+CONFIG_PARIDE_FRIQ=m
+CONFIG_PARIDE_FRPW=m
+CONFIG_PARIDE_KBIC=m
+CONFIG_PARIDE_KTTI=m
+CONFIG_PARIDE_ON20=m
+CONFIG_PARIDE_ON26=m
+CONFIG_BLK_CPQ_DA=m
+CONFIG_BLK_CPQ_CISS_DA=m
+# CONFIG_CISS_SCSI_TAPE is not set
+CONFIG_BLK_DEV_DAC960=m
+CONFIG_BLK_DEV_UMEM=m
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_SX8=m
+CONFIG_BLK_DEV_UB=m
+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=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+CONFIG_ATA_OVER_ETH=m
+
+#
+# Misc devices
+#
+# CONFIG_IBM_ASM is not set
+# CONFIG_SGI_IOC4 is not set
+CONFIG_TIFM_CORE=m
+CONFIG_TIFM_7XX1=m
+# CONFIG_ASUS_LAPTOP is not set
+# CONFIG_MSI_LAPTOP is not set
+# CONFIG_SONY_LAPTOP is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+# CONFIG_BLK_DEV_HD_IDE is not set
+CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_IDEDISK_MULTI_MODE=y
+CONFIG_BLK_DEV_IDECS=m
+CONFIG_BLK_DEV_DELKIN=m
+CONFIG_BLK_DEV_IDECD=y
+CONFIG_BLK_DEV_IDETAPE=m
+CONFIG_BLK_DEV_IDEFLOPPY=m
+CONFIG_BLK_DEV_IDESCSI=m
+# CONFIG_BLK_DEV_IDEACPI is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_CMD640=y
+# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
+# CONFIG_BLK_DEV_IDEPNP is not set
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_IDEPCI_SHARE_IRQ=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_GENERIC=y
+CONFIG_BLK_DEV_OPTI621=y
+CONFIG_BLK_DEV_RZ1000=y
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+# CONFIG_IDEDMA_ONLYDISK is not set
+CONFIG_BLK_DEV_AEC62XX=y
+CONFIG_BLK_DEV_ALI15X3=y
+# CONFIG_WDC_ALI15X3 is not set
+CONFIG_BLK_DEV_AMD74XX=y
+CONFIG_BLK_DEV_ATIIXP=y
+CONFIG_BLK_DEV_CMD64X=y
+CONFIG_BLK_DEV_TRIFLEX=y
+CONFIG_BLK_DEV_CY82C693=y
+CONFIG_BLK_DEV_CS5520=y
+CONFIG_BLK_DEV_CS5530=y
+CONFIG_BLK_DEV_CS5535=y
+CONFIG_BLK_DEV_HPT34X=y
+# CONFIG_HPT34X_AUTODMA is not set
+CONFIG_BLK_DEV_HPT366=y
+CONFIG_BLK_DEV_JMICRON=y
+CONFIG_BLK_DEV_SC1200=y
+CONFIG_BLK_DEV_PIIX=y
+CONFIG_BLK_DEV_IT8213=y
+CONFIG_BLK_DEV_IT821X=y
+CONFIG_BLK_DEV_NS87415=y
+CONFIG_BLK_DEV_PDC202XX_OLD=y
+# CONFIG_PDC202XX_BURST is not set
+CONFIG_BLK_DEV_PDC202XX_NEW=y
+CONFIG_BLK_DEV_SVWKS=y
+CONFIG_BLK_DEV_SIIMAGE=y
+CONFIG_BLK_DEV_SIS5513=y
+CONFIG_BLK_DEV_SLC90E66=y
+CONFIG_BLK_DEV_TRM290=y
+CONFIG_BLK_DEV_VIA82CXXX=y
+CONFIG_BLK_DEV_TC86C001=y
+# CONFIG_IDE_ARM is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI=y
+CONFIG_SCSI_TGT=m
+CONFIG_SCSI_NETLINK=y
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+CONFIG_CHR_DEV_SG=y
+CONFIG_CHR_DEV_SCH=m
+
+#
+# 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=m
+CONFIG_SCSI_FC_ATTRS=m
+CONFIG_SCSI_ISCSI_ATTRS=m
+CONFIG_SCSI_SAS_ATTRS=m
+CONFIG_SCSI_SAS_LIBSAS=m
+CONFIG_SCSI_SAS_LIBSAS_DEBUG=y
+
+#
+# SCSI low-level drivers
+#
+CONFIG_ISCSI_TCP=m
+CONFIG_BLK_DEV_3W_XXXX_RAID=m
+CONFIG_SCSI_3W_9XXX=m
+CONFIG_SCSI_ACARD=m
+CONFIG_SCSI_AACRAID=m
+CONFIG_SCSI_AIC7XXX=m
+CONFIG_AIC7XXX_CMDS_PER_DEVICE=32
+CONFIG_AIC7XXX_RESET_DELAY_MS=5000
+CONFIG_AIC7XXX_DEBUG_ENABLE=y
+CONFIG_AIC7XXX_DEBUG_MASK=0
+CONFIG_AIC7XXX_REG_PRETTY_PRINT=y
+CONFIG_SCSI_AIC7XXX_OLD=m
+CONFIG_SCSI_AIC79XX=m
+CONFIG_AIC79XX_CMDS_PER_DEVICE=32
+CONFIG_AIC79XX_RESET_DELAY_MS=5000
+# CONFIG_AIC79XX_ENABLE_RD_STRM is not set
+CONFIG_AIC79XX_DEBUG_ENABLE=y
+CONFIG_AIC79XX_DEBUG_MASK=0
+CONFIG_AIC79XX_REG_PRETTY_PRINT=y
+CONFIG_SCSI_AIC94XX=m
+CONFIG_AIC94XX_DEBUG=y
+CONFIG_SCSI_DPT_I2O=m
+CONFIG_SCSI_ADVANSYS=m
+CONFIG_SCSI_ARCMSR=m
+# CONFIG_MEGARAID_NEWGEN is not set
+CONFIG_MEGARAID_LEGACY=m
+CONFIG_MEGARAID_SAS=m
+CONFIG_SCSI_HPTIOP=m
+CONFIG_SCSI_BUSLOGIC=m
+# CONFIG_SCSI_OMIT_FLASHPOINT is not set
+CONFIG_SCSI_DMX3191D=m
+CONFIG_SCSI_EATA=m
+# CONFIG_SCSI_EATA_TAGGED_QUEUE is not set
+# CONFIG_SCSI_EATA_LINKED_COMMANDS is not set
+CONFIG_SCSI_EATA_MAX_TAGS=16
+CONFIG_SCSI_FUTURE_DOMAIN=m
+CONFIG_SCSI_GDTH=m
+CONFIG_SCSI_IPS=m
+CONFIG_SCSI_INITIO=m
+CONFIG_SCSI_INIA100=m
+CONFIG_SCSI_PPA=m
+CONFIG_SCSI_IMM=m
+# CONFIG_SCSI_IZIP_EPP16 is not set
+# CONFIG_SCSI_IZIP_SLOW_CTR is not set
+CONFIG_SCSI_STEX=m
+CONFIG_SCSI_SYM53C8XX_2=m
+CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
+CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
+CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
+CONFIG_SCSI_SYM53C8XX_MMIO=y
+# CONFIG_SCSI_IPR is not set
+CONFIG_SCSI_QLOGIC_1280=m
+CONFIG_SCSI_QLA_FC=m
+CONFIG_SCSI_QLA_ISCSI=m
+CONFIG_SCSI_LPFC=m
+CONFIG_SCSI_DC395x=m
+CONFIG_SCSI_DC390T=m
+CONFIG_SCSI_NSP32=m
+CONFIG_SCSI_DEBUG=m
+CONFIG_SCSI_SRP=m
+
+#
+# PCMCIA SCSI adapter support
+#
+CONFIG_PCMCIA_AHA152X=m
+CONFIG_PCMCIA_FDOMAIN=m
+CONFIG_PCMCIA_NINJA_SCSI=m
+CONFIG_PCMCIA_QLOGIC=m
+CONFIG_PCMCIA_SYM53C500=m
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+CONFIG_ATA=y
+# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_SATA_AHCI=y
+CONFIG_SATA_SVW=y
+CONFIG_ATA_PIIX=y
+CONFIG_SATA_MV=y
+CONFIG_SATA_NV=y
+CONFIG_PDC_ADMA=y
+CONFIG_SATA_QSTOR=y
+CONFIG_SATA_PROMISE=y
+CONFIG_SATA_SX4=y
+CONFIG_SATA_SIL=y
+CONFIG_SATA_SIL24=y
+CONFIG_SATA_SIS=y
+CONFIG_SATA_ULI=y
+CONFIG_SATA_VIA=y
+CONFIG_SATA_VITESSE=y
+CONFIG_SATA_INIC162X=y
+CONFIG_SATA_INTEL_COMBINED=y
+CONFIG_SATA_ACPI=y
+CONFIG_PATA_ALI=y
+CONFIG_PATA_AMD=y
+CONFIG_PATA_ARTOP=y
+CONFIG_PATA_ATIIXP=y
+CONFIG_PATA_CMD64X=y
+CONFIG_PATA_CS5520=y
+CONFIG_PATA_CS5530=y
+CONFIG_PATA_CS5535=y
+CONFIG_PATA_CYPRESS=y
+CONFIG_PATA_EFAR=y
+CONFIG_ATA_GENERIC=y
+CONFIG_PATA_HPT366=y
+CONFIG_PATA_HPT37X=y
+CONFIG_PATA_HPT3X2N=y
+CONFIG_PATA_HPT3X3=y
+CONFIG_PATA_IT821X=y
+CONFIG_PATA_IT8213=y
+CONFIG_PATA_JMICRON=y
+CONFIG_PATA_TRIFLEX=y
+CONFIG_PATA_MARVELL=y
+CONFIG_PATA_MPIIX=y
+CONFIG_PATA_OLDPIIX=y
+CONFIG_PATA_NETCELL=y
+CONFIG_PATA_NS87410=y
+CONFIG_PATA_OPTI=y
+CONFIG_PATA_OPTIDMA=y
+CONFIG_PATA_PCMCIA=m
+CONFIG_PATA_PDC_OLD=y
+CONFIG_PATA_RADISYS=y
+CONFIG_PATA_RZ1000=y
+CONFIG_PATA_SC1200=y
+CONFIG_PATA_SERVERWORKS=y
+CONFIG_PATA_PDC2027X=y
+CONFIG_PATA_SIL680=y
+CONFIG_PATA_SIS=y
+CONFIG_PATA_VIA=y
+CONFIG_PATA_WINBOND=y
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=m
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID456=m
+CONFIG_MD_RAID5_RESHAPE=y
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+# CONFIG_DM_DEBUG is not set
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_EMC=m
+
+#
+# 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=y
+
+#
+# Subsystem Options
+#
+# CONFIG_IEEE1394_VERBOSEDEBUG is not set
+CONFIG_IEEE1394_EXTRA_CONFIG_ROMS=y
+CONFIG_IEEE1394_CONFIG_ROM_IP1394=y
+
+#
+# Device Drivers
+#
+CONFIG_IEEE1394_PCILYNX=m
+CONFIG_IEEE1394_OHCI1394=y
+
+#
+# Protocol Drivers
+#
+CONFIG_IEEE1394_VIDEO1394=m
+CONFIG_IEEE1394_SBP2=m
+# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set
+CONFIG_IEEE1394_ETH1394=m
+CONFIG_IEEE1394_DV1394=m
+CONFIG_IEEE1394_RAWIO=y
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Macintosh device drivers
+#
+# CONFIG_MAC_EMUMOUSEBTN is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+CONFIG_EQUALIZER=m
+CONFIG_TUN=m
+CONFIG_NET_SB1000=m
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+CONFIG_VITESSE_PHY=m
+CONFIG_SMSC_PHY=m
+CONFIG_BROADCOM_PHY=m
+CONFIG_FIXED_PHY=m
+# CONFIG_FIXED_MII_10_FDX is not set
+# CONFIG_FIXED_MII_100_FDX 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=y
+CONFIG_VORTEX=m
+CONFIG_TYPHOON=m
+
+#
+# Tulip family network device support
+#
+CONFIG_NET_TULIP=y
+CONFIG_DE2104X=m
+CONFIG_TULIP=m
+# CONFIG_TULIP_MWI is not set
+# CONFIG_TULIP_MMIO is not set
+# CONFIG_TULIP_NAPI is not set
+CONFIG_DE4X5=m
+CONFIG_WINBOND_840=m
+CONFIG_DM9102=m
+CONFIG_ULI526X=m
+# CONFIG_PCMCIA_XIRCOM is not set
+# CONFIG_HP100 is not set
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=m
+# CONFIG_PCNET32_NAPI is not set
+CONFIG_AMD8111_ETH=m
+# CONFIG_AMD8111E_NAPI is not set
+CONFIG_ADAPTEC_STARFIRE=m
+# CONFIG_ADAPTEC_STARFIRE_NAPI is not set
+CONFIG_B44=m
+CONFIG_FORCEDETH=m
+# CONFIG_FORCEDETH_NAPI is not set
+CONFIG_DGRS=m
+CONFIG_EEPRO100=m
+CONFIG_E100=m
+CONFIG_FEALNX=m
+CONFIG_NATSEMI=m
+CONFIG_NE2K_PCI=m
+CONFIG_8139CP=m
+CONFIG_8139TOO=y
+CONFIG_8139TOO_PIO=y
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_OLD_RX_RESET is not set
+CONFIG_SIS900=m
+CONFIG_EPIC100=m
+CONFIG_SUNDANCE=m
+# CONFIG_SUNDANCE_MMIO is not set
+CONFIG_TLAN=m
+CONFIG_VIA_RHINE=m
+# CONFIG_VIA_RHINE_MMIO is not set
+# CONFIG_VIA_RHINE_NAPI is not set
+CONFIG_SC92031=m
+CONFIG_NET_POCKET=y
+CONFIG_ATP=m
+CONFIG_DE600=m
+CONFIG_DE620=m
+
+#
+# Ethernet (1000 Mbit)
+#
+CONFIG_ACENIC=m
+# CONFIG_ACENIC_OMIT_TIGON_I is not set
+CONFIG_DL2K=m
+CONFIG_E1000=m
+# CONFIG_E1000_NAPI is not set
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
+CONFIG_NS83820=m
+CONFIG_HAMACHI=m
+CONFIG_YELLOWFIN=m
+CONFIG_R8169=m
+# CONFIG_R8169_NAPI is not set
+# CONFIG_R8169_VLAN is not set
+CONFIG_SIS190=m
+CONFIG_SKGE=m
+CONFIG_SKY2=m
+CONFIG_SK98LIN=m
+CONFIG_VIA_VELOCITY=m
+CONFIG_TIGON3=m
+CONFIG_BNX2=m
+CONFIG_QLA3XXX=m
+CONFIG_ATL1=m
+
+#
+# Ethernet (10000 Mbit)
+#
+CONFIG_CHELSIO_T1=m
+# CONFIG_CHELSIO_T1_1G is not set
+CONFIG_CHELSIO_T1_NAPI=y
+CONFIG_CHELSIO_T3=m
+CONFIG_IXGB=m
+# CONFIG_IXGB_NAPI is not set
+CONFIG_S2IO=m
+# CONFIG_S2IO_NAPI is not set
+CONFIG_MYRI10GE=m
+CONFIG_NETXEN_NIC=m
+
+#
+# Token Ring devices
+#
+CONFIG_TR=y
+CONFIG_IBMOL=m
+CONFIG_IBMLS=m
+CONFIG_3C359=m
+CONFIG_TMS380TR=m
+CONFIG_TMSPCI=m
+CONFIG_ABYSS=m
+
+#
+# Wireless LAN (non-hamradio)
+#
+CONFIG_NET_RADIO=y
+# CONFIG_NET_WIRELESS_RTNETLINK is not set
+
+#
+# Obsolete Wireless cards support (pre-802.11)
+#
+CONFIG_STRIP=m
+CONFIG_PCMCIA_WAVELAN=m
+CONFIG_PCMCIA_NETWAVE=m
+
+#
+# Wireless 802.11 Frequency Hopping cards support
+#
+CONFIG_PCMCIA_RAYCS=m
+
+#
+# Wireless 802.11b ISA/PCI cards support
+#
+CONFIG_IPW2100=m
+# CONFIG_IPW2100_MONITOR is not set
+# CONFIG_IPW2100_DEBUG is not set
+CONFIG_IPW2200=m
+# CONFIG_IPW2200_MONITOR is not set
+CONFIG_IPW2200_QOS=y
+# CONFIG_IPW2200_DEBUG is not set
+CONFIG_AIRO=m
+CONFIG_HERMES=m
+CONFIG_PLX_HERMES=m
+CONFIG_TMD_HERMES=m
+CONFIG_NORTEL_HERMES=m
+CONFIG_PCI_HERMES=m
+CONFIG_ATMEL=m
+# CONFIG_PCI_ATMEL is not set
+
+#
+# Wireless 802.11b Pcmcia/Cardbus cards support
+#
+CONFIG_PCMCIA_HERMES=m
+CONFIG_PCMCIA_SPECTRUM=m
+CONFIG_AIRO_CS=m
+CONFIG_PCMCIA_ATMEL=m
+CONFIG_PCMCIA_WL3501=m
+
+#
+# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
+#
+CONFIG_PRISM54=m
+CONFIG_USB_ZD1201=m
+CONFIG_HOSTAP=m
+CONFIG_HOSTAP_FIRMWARE=y
+CONFIG_HOSTAP_FIRMWARE_NVRAM=y
+CONFIG_HOSTAP_PLX=m
+CONFIG_HOSTAP_PCI=m
+CONFIG_HOSTAP_CS=m
+CONFIG_BCM43XX=m
+CONFIG_BCM43XX_DEBUG=y
+CONFIG_BCM43XX_DMA=y
+CONFIG_BCM43XX_PIO=y
+CONFIG_BCM43XX_DMA_AND_PIO_MODE=y
+# CONFIG_BCM43XX_DMA_MODE is not set
+# CONFIG_BCM43XX_PIO_MODE is not set
+CONFIG_ZD1211RW=m
+# CONFIG_ZD1211RW_DEBUG is not set
+CONFIG_NET_WIRELESS=y
+
+#
+# PCMCIA network device support
+#
+CONFIG_NET_PCMCIA=y
+CONFIG_PCMCIA_3C589=m
+CONFIG_PCMCIA_3C574=m
+CONFIG_PCMCIA_FMVJ18X=m
+CONFIG_PCMCIA_PCNET=m
+CONFIG_PCMCIA_NMCLAN=m
+CONFIG_PCMCIA_SMC91C92=m
+CONFIG_PCMCIA_XIRC2PS=m
+CONFIG_PCMCIA_AXNET=m
+CONFIG_PCMCIA_IBMTR=m
+
+#
+# Wan interfaces
+#
+CONFIG_WAN=y
+CONFIG_LANMEDIA=m
+CONFIG_HDLC=m
+CONFIG_HDLC_RAW=m
+CONFIG_HDLC_RAW_ETH=m
+CONFIG_HDLC_CISCO=m
+CONFIG_HDLC_FR=m
+CONFIG_HDLC_PPP=m
+# CONFIG_HDLC_X25 is not set
+CONFIG_PCI200SYN=m
+CONFIG_WANXL=m
+CONFIG_PC300=m
+# CONFIG_PC300_MLPPP is not set
+
+#
+# Cyclades-PC300 MLPPP support is disabled.
+#
+
+#
+# Refer to the file README.mlppp, provided by PC300 package.
+#
+CONFIG_PC300TOO=m
+CONFIG_FARSYNC=m
+CONFIG_DSCC4=m
+# CONFIG_DSCC4_PCISYNC is not set
+# CONFIG_DSCC4_PCI_RST is not set
+CONFIG_DLCI=m
+CONFIG_DLCI_MAX=8
+CONFIG_WAN_ROUTER_DRIVERS=m
+CONFIG_CYCLADES_SYNC=m
+# CONFIG_CYCLOMX_X25 is not set
+# CONFIG_LAPBETHER is not set
+# CONFIG_X25_ASY is not set
+CONFIG_SBNI=m
+# CONFIG_SBNI_MULTILINE is not set
+
+#
+# ATM drivers
+#
+CONFIG_ATM_DUMMY=m
+CONFIG_ATM_TCP=m
+CONFIG_ATM_LANAI=m
+CONFIG_ATM_ENI=m
+# CONFIG_ATM_ENI_DEBUG is not set
+# CONFIG_ATM_ENI_TUNE_BURST is not set
+CONFIG_ATM_FIRESTREAM=m
+CONFIG_ATM_ZATM=m
+# CONFIG_ATM_ZATM_DEBUG is not set
+CONFIG_ATM_NICSTAR=m
+# CONFIG_ATM_NICSTAR_USE_SUNI is not set
+# CONFIG_ATM_NICSTAR_USE_IDT77105 is not set
+CONFIG_ATM_IDT77252=m
+# CONFIG_ATM_IDT77252_DEBUG is not set
+# CONFIG_ATM_IDT77252_RCV_ALL is not set
+CONFIG_ATM_IDT77252_USE_SUNI=y
+CONFIG_ATM_AMBASSADOR=m
+# CONFIG_ATM_AMBASSADOR_DEBUG is not set
+CONFIG_ATM_HORIZON=m
+# CONFIG_ATM_HORIZON_DEBUG is not set
+CONFIG_ATM_IA=m
+# CONFIG_ATM_IA_DEBUG is not set
+CONFIG_ATM_FORE200E_MAYBE=m
+# CONFIG_ATM_FORE200E_PCA is not set
+CONFIG_ATM_HE=m
+# CONFIG_ATM_HE_USE_SUNI is not set
+CONFIG_FDDI=y
+CONFIG_DEFXX=m
+# CONFIG_DEFXX_MMIO is not set
+CONFIG_SKFP=m
+# CONFIG_HIPPI is not set
+CONFIG_PLIP=m
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+CONFIG_PPPOATM=m
+CONFIG_SLIP=m
+# CONFIG_SLIP_COMPRESSED is not set
+CONFIG_SLHC=m
+# CONFIG_SLIP_SMART is not set
+# CONFIG_SLIP_MODE_SLIP6 is not set
+# CONFIG_NET_FC is not set
+CONFIG_SHAPER=m
+CONFIG_NETCONSOLE=m
+CONFIG_NETPOLL=y
+# CONFIG_NETPOLL_RX is not set
+# CONFIG_NETPOLL_TRAP is not set
+CONFIG_NET_POLL_CONTROLLER=y
+
+#
+# ISDN subsystem
+#
+CONFIG_ISDN=m
+
+#
+# Old ISDN4Linux
+#
+# CONFIG_ISDN_I4L is not set
+
+#
+# CAPI subsystem
+#
+CONFIG_ISDN_CAPI=m
+# CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON is not set
+CONFIG_CAPI_TRACE=y
+# CONFIG_ISDN_CAPI_MIDDLEWARE is not set
+CONFIG_ISDN_CAPI_CAPI20=m
+
+#
+# CAPI hardware drivers
+#
+
+#
+# Active AVM cards
+#
+CONFIG_CAPI_AVM=y
+CONFIG_ISDN_DRV_AVMB1_B1PCI=m
+CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y
+CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m
+CONFIG_ISDN_DRV_AVMB1_AVM_CS=m
+CONFIG_ISDN_DRV_AVMB1_T1PCI=m
+CONFIG_ISDN_DRV_AVMB1_C4=m
+
+#
+# Active Eicon DIVA Server cards
+#
+CONFIG_CAPI_EICON=y
+CONFIG_ISDN_DIVAS=m
+CONFIG_ISDN_DIVAS_BRIPCI=y
+CONFIG_ISDN_DIVAS_PRIPCI=y
+CONFIG_ISDN_DIVAS_DIVACAPI=m
+CONFIG_ISDN_DIVAS_USERIDI=m
+CONFIG_ISDN_DIVAS_MAINT=m
+
+#
+# Telephony Support
+#
+CONFIG_PHONE=m
+CONFIG_PHONE_IXJ=m
+CONFIG_PHONE_IXJ_PCMCIA=m
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+CONFIG_INPUT_FF_MEMLESS=y
+
+#
+# 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=m
+CONFIG_INPUT_TSDEV=m
+CONFIG_INPUT_TSDEV_SCREEN_X=240
+CONFIG_INPUT_TSDEV_SCREEN_Y=320
+CONFIG_INPUT_EVDEV=m
+CONFIG_INPUT_EVBUG=m
+
+#
+# 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=m
+CONFIG_JOYSTICK_A3D=m
+CONFIG_JOYSTICK_ADI=m
+CONFIG_JOYSTICK_COBRA=m
+CONFIG_JOYSTICK_GF2K=m
+CONFIG_JOYSTICK_GRIP=m
+CONFIG_JOYSTICK_GRIP_MP=m
+CONFIG_JOYSTICK_GUILLEMOT=m
+CONFIG_JOYSTICK_INTERACT=m
+CONFIG_JOYSTICK_SIDEWINDER=m
+CONFIG_JOYSTICK_TMDC=m
+CONFIG_JOYSTICK_IFORCE=m
+# CONFIG_JOYSTICK_IFORCE_USB is not set
+# CONFIG_JOYSTICK_IFORCE_232 is not set
+CONFIG_JOYSTICK_WARRIOR=m
+CONFIG_JOYSTICK_MAGELLAN=m
+CONFIG_JOYSTICK_SPACEORB=m
+CONFIG_JOYSTICK_SPACEBALL=m
+CONFIG_JOYSTICK_STINGER=m
+CONFIG_JOYSTICK_TWIDJOY=m
+CONFIG_JOYSTICK_DB9=m
+CONFIG_JOYSTICK_GAMECON=m
+CONFIG_JOYSTICK_TURBOGRAFX=m
+CONFIG_JOYSTICK_JOYDUMP=m
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_ADS7846=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_INPUT_MISC=y
+CONFIG_INPUT_PCSPKR=m
+CONFIG_INPUT_WISTRON_BTNS=m
+CONFIG_INPUT_ATLAS_BTNS=m
+CONFIG_INPUT_UINPUT=m
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=m
+CONFIG_SERIO_CT82C710=m
+CONFIG_SERIO_PARKBD=m
+CONFIG_SERIO_PCIPS2=m
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIO_RAW=m
+CONFIG_GAMEPORT=m
+CONFIG_GAMEPORT_NS558=m
+CONFIG_GAMEPORT_L4=m
+CONFIG_GAMEPORT_EMU10K1=m
+CONFIG_GAMEPORT_FM801=m
+
+#
+# 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=y
+# CONFIG_SERIAL_8250_CONSOLE is not set
+CONFIG_SERIAL_8250_PCI=y
+CONFIG_SERIAL_8250_PNP=y
+# CONFIG_SERIAL_8250_CS is not set
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+CONFIG_PRINTER=y
+# CONFIG_LP_CONSOLE is not set
+CONFIG_PPDEV=m
+CONFIG_TIPAR=m
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+CONFIG_HW_RANDOM=m
+CONFIG_HW_RANDOM_INTEL=m
+CONFIG_HW_RANDOM_AMD=m
+CONFIG_HW_RANDOM_GEODE=m
+CONFIG_HW_RANDOM_VIA=m
+CONFIG_NVRAM=m
+CONFIG_RTC=m
+CONFIG_GEN_RTC=m
+# CONFIG_GEN_RTC_X is not set
+CONFIG_DTLK=m
+CONFIG_R3964=m
+CONFIG_APPLICOM=m
+CONFIG_SONYPI=m
+CONFIG_AGP=y
+CONFIG_AGP_ALI=m
+CONFIG_AGP_ATI=m
+CONFIG_AGP_AMD=m
+CONFIG_AGP_AMD64=y
+CONFIG_AGP_INTEL=y
+CONFIG_AGP_NVIDIA=m
+CONFIG_AGP_SIS=m
+CONFIG_AGP_SWORKS=m
+CONFIG_AGP_VIA=m
+CONFIG_AGP_EFFICEON=m
+CONFIG_DRM=y
+CONFIG_DRM_TDFX=m
+CONFIG_DRM_R128=m
+CONFIG_DRM_RADEON=m
+CONFIG_DRM_I810=m
+CONFIG_DRM_I830=m
+CONFIG_DRM_I915=m
+CONFIG_DRM_MGA=m
+CONFIG_DRM_SIS=m
+CONFIG_DRM_VIA=m
+CONFIG_DRM_SAVAGE=m
+
+#
+# PCMCIA character devices
+#
+CONFIG_SYNCLINK_CS=m
+CONFIG_CARDMAN_4000=m
+CONFIG_CARDMAN_4040=m
+CONFIG_MWAVE=m
+CONFIG_SCx200_GPIO=m
+CONFIG_PC8736x_GPIO=m
+CONFIG_NSC_GPIO=m
+CONFIG_CS5535_GPIO=m
+CONFIG_RAW_DRIVER=y
+CONFIG_MAX_RAW_DEVS=256
+# CONFIG_HPET is not set
+CONFIG_HANGCHECK_TIMER=m
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+CONFIG_TELCLOCK=m
+
+#
+# I2C support
+#
+CONFIG_I2C=m
+CONFIG_I2C_CHARDEV=m
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=m
+CONFIG_I2C_ALGOPCF=m
+CONFIG_I2C_ALGOPCA=m
+
+#
+# I2C Hardware Bus support
+#
+CONFIG_I2C_ALI1535=m
+CONFIG_I2C_ALI1563=m
+CONFIG_I2C_ALI15X3=m
+CONFIG_I2C_AMD756=m
+CONFIG_I2C_AMD756_S4882=m
+CONFIG_I2C_AMD8111=m
+CONFIG_I2C_I801=m
+CONFIG_I2C_I810=m
+CONFIG_I2C_PIIX4=m
+CONFIG_I2C_ISA=m
+CONFIG_I2C_NFORCE2=m
+CONFIG_I2C_OCORES=m
+CONFIG_I2C_PARPORT=m
+CONFIG_I2C_PARPORT_LIGHT=m
+CONFIG_I2C_PROSAVAGE=m
+CONFIG_I2C_SAVAGE4=m
+CONFIG_SCx200_I2C=m
+CONFIG_SCx200_I2C_SCL=12
+CONFIG_SCx200_I2C_SDA=13
+CONFIG_SCx200_ACB=m
+CONFIG_I2C_SIS5595=m
+CONFIG_I2C_SIS630=m
+CONFIG_I2C_SIS96X=m
+CONFIG_I2C_STUB=m
+CONFIG_I2C_VIA=m
+CONFIG_I2C_VIAPRO=m
+CONFIG_I2C_VOODOO3=m
+CONFIG_I2C_PCA_ISA=m
+
+#
+# Miscellaneous I2C Chip support
+#
+CONFIG_SENSORS_DS1337=m
+CONFIG_SENSORS_DS1374=m
+CONFIG_SENSORS_EEPROM=m
+CONFIG_SENSORS_PCF8574=m
+CONFIG_SENSORS_PCA9539=m
+CONFIG_SENSORS_PCF8591=m
+CONFIG_SENSORS_MAX6875=m
+# CONFIG_SENSORS_TSC2003 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_BITBANG=m
+CONFIG_SPI_BUTTERFLY=m
+
+#
+# SPI Protocol Masters
+#
+CONFIG_SPI_AT25=m
+
+#
+# Dallas's 1-wire bus
+#
+CONFIG_W1=m
+
+#
+# 1-wire Bus Masters
+#
+CONFIG_W1_MASTER_MATROX=m
+CONFIG_W1_MASTER_DS2490=m
+CONFIG_W1_MASTER_DS2482=m
+
+#
+# 1-wire Slaves
+#
+CONFIG_W1_SLAVE_THERM=m
+CONFIG_W1_SLAVE_SMEM=m
+CONFIG_W1_SLAVE_DS2433=m
+# CONFIG_W1_SLAVE_DS2433_CRC is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+CONFIG_HWMON_VID=m
+CONFIG_SENSORS_ABITUGURU=m
+CONFIG_SENSORS_ADM1021=m
+CONFIG_SENSORS_ADM1025=m
+CONFIG_SENSORS_ADM1026=m
+CONFIG_SENSORS_ADM1029=m
+CONFIG_SENSORS_ADM1031=m
+CONFIG_SENSORS_ADM9240=m
+CONFIG_SENSORS_K8TEMP=m
+CONFIG_SENSORS_ASB100=m
+CONFIG_SENSORS_ATXP1=m
+CONFIG_SENSORS_DS1621=m
+CONFIG_SENSORS_F71805F=m
+CONFIG_SENSORS_FSCHER=m
+CONFIG_SENSORS_FSCPOS=m
+CONFIG_SENSORS_GL518SM=m
+CONFIG_SENSORS_GL520SM=m
+CONFIG_SENSORS_IT87=m
+CONFIG_SENSORS_LM63=m
+CONFIG_SENSORS_LM70=m
+CONFIG_SENSORS_LM75=m
+CONFIG_SENSORS_LM77=m
+CONFIG_SENSORS_LM78=m
+CONFIG_SENSORS_LM80=m
+CONFIG_SENSORS_LM83=m
+CONFIG_SENSORS_LM85=m
+CONFIG_SENSORS_LM87=m
+CONFIG_SENSORS_LM90=m
+CONFIG_SENSORS_LM92=m
+CONFIG_SENSORS_MAX1619=m
+CONFIG_SENSORS_PC87360=m
+CONFIG_SENSORS_PC87427=m
+CONFIG_SENSORS_SIS5595=m
+CONFIG_SENSORS_SMSC47M1=m
+CONFIG_SENSORS_SMSC47M192=m
+CONFIG_SENSORS_SMSC47B397=m
+CONFIG_SENSORS_VIA686A=m
+CONFIG_SENSORS_VT1211=m
+CONFIG_SENSORS_VT8231=m
+CONFIG_SENSORS_W83781D=m
+CONFIG_SENSORS_W83791D=m
+CONFIG_SENSORS_W83792D=m
+CONFIG_SENSORS_W83793=m
+CONFIG_SENSORS_W83L785TS=m
+CONFIG_SENSORS_W83627HF=m
+CONFIG_SENSORS_W83627EHF=m
+CONFIG_SENSORS_HDAPS=m
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Multifunction device drivers
+#
+CONFIG_MFD_SM501=m
+
+#
+# Multimedia devices
+#
+CONFIG_VIDEO_DEV=m
+CONFIG_VIDEO_V4L1=y
+CONFIG_VIDEO_V4L1_COMPAT=y
+CONFIG_VIDEO_V4L2=y
+
+#
+# Video Capture Adapters
+#
+
+#
+# Video Capture Adapters
+#
+# CONFIG_VIDEO_ADV_DEBUG is not set
+CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
+CONFIG_VIDEO_TVAUDIO=m
+CONFIG_VIDEO_TDA7432=m
+CONFIG_VIDEO_TDA9840=m
+CONFIG_VIDEO_TDA9875=m
+CONFIG_VIDEO_TEA6415C=m
+CONFIG_VIDEO_TEA6420=m
+CONFIG_VIDEO_MSP3400=m
+CONFIG_VIDEO_WM8775=m
+CONFIG_VIDEO_BT819=m
+CONFIG_VIDEO_BT856=m
+CONFIG_VIDEO_KS0127=m
+CONFIG_VIDEO_OV7670=m
+CONFIG_VIDEO_SAA7110=m
+CONFIG_VIDEO_SAA7111=m
+CONFIG_VIDEO_SAA7114=m
+CONFIG_VIDEO_SAA711X=m
+CONFIG_VIDEO_TVP5150=m
+CONFIG_VIDEO_VPX3220=m
+CONFIG_VIDEO_CX25840=m
+CONFIG_VIDEO_CX2341X=m
+CONFIG_VIDEO_SAA7185=m
+CONFIG_VIDEO_ADV7170=m
+CONFIG_VIDEO_ADV7175=m
+CONFIG_VIDEO_VIVI=m
+CONFIG_VIDEO_BT848=m
+# CONFIG_VIDEO_BT848_DVB is not set
+CONFIG_VIDEO_SAA6588=m
+CONFIG_VIDEO_BWQCAM=m
+CONFIG_VIDEO_CQCAM=m
+CONFIG_VIDEO_CPIA=m
+CONFIG_VIDEO_CPIA_USB=m
+CONFIG_VIDEO_CPIA2=m
+CONFIG_VIDEO_SAA5246A=m
+CONFIG_VIDEO_SAA5249=m
+CONFIG_TUNER_3036=m
+CONFIG_VIDEO_STRADIS=m
+CONFIG_VIDEO_ZORAN_ZR36060=m
+CONFIG_VIDEO_ZORAN=m
+CONFIG_VIDEO_ZORAN_BUZ=m
+CONFIG_VIDEO_ZORAN_DC10=m
+CONFIG_VIDEO_ZORAN_DC30=m
+CONFIG_VIDEO_ZORAN_LML33=m
+CONFIG_VIDEO_ZORAN_LML33R10=m
+CONFIG_VIDEO_ZORAN_AVS6EYES=m
+CONFIG_VIDEO_MEYE=m
+CONFIG_VIDEO_SAA7134=m
+CONFIG_VIDEO_SAA7134_ALSA=m
+CONFIG_VIDEO_SAA7134_OSS=m
+CONFIG_VIDEO_SAA7134_DVB=m
+CONFIG_VIDEO_MXB=m
+CONFIG_VIDEO_DPC=m
+CONFIG_VIDEO_HEXIUM_ORION=m
+CONFIG_VIDEO_HEXIUM_GEMINI=m
+CONFIG_VIDEO_CX88=m
+CONFIG_VIDEO_CX88_ALSA=m
+CONFIG_VIDEO_CX88_BLACKBIRD=m
+CONFIG_VIDEO_CX88_DVB=m
+CONFIG_VIDEO_CX88_VP3054=m
+CONFIG_VIDEO_CAFE_CCIC=m
+
+#
+# V4L USB devices
+#
+CONFIG_VIDEO_PVRUSB2=m
+CONFIG_VIDEO_PVRUSB2_29XXX=y
+CONFIG_VIDEO_PVRUSB2_24XXX=y
+CONFIG_VIDEO_PVRUSB2_SYSFS=y
+# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set
+CONFIG_VIDEO_EM28XX=m
+CONFIG_VIDEO_USBVISION=m
+CONFIG_VIDEO_USBVIDEO=m
+CONFIG_USB_VICAM=m
+CONFIG_USB_IBMCAM=m
+CONFIG_USB_KONICAWC=m
+CONFIG_USB_QUICKCAM_MESSENGER=m
+CONFIG_USB_ET61X251=m
+CONFIG_VIDEO_OVCAMCHIP=m
+CONFIG_USB_W9968CF=m
+CONFIG_USB_OV511=m
+CONFIG_USB_SE401=m
+CONFIG_USB_SN9C102=m
+CONFIG_USB_STV680=m
+CONFIG_USB_ZC0301=m
+CONFIG_USB_PWC=m
+# CONFIG_USB_PWC_DEBUG is not set
+
+#
+# Radio Adapters
+#
+CONFIG_RADIO_GEMTEK_PCI=m
+CONFIG_RADIO_MAXIRADIO=m
+CONFIG_RADIO_MAESTRO=m
+CONFIG_USB_DSBR=m
+
+#
+# Digital Video Broadcasting Devices
+#
+CONFIG_DVB=y
+CONFIG_DVB_CORE=m
+# CONFIG_DVB_CORE_ATTACH is not set
+
+#
+# Supported SAA7146 based PCI Adapters
+#
+CONFIG_DVB_AV7110=m
+CONFIG_DVB_AV7110_OSD=y
+CONFIG_DVB_BUDGET=m
+CONFIG_DVB_BUDGET_CI=m
+CONFIG_DVB_BUDGET_AV=m
+CONFIG_DVB_BUDGET_PATCH=m
+
+#
+# Supported USB Adapters
+#
+CONFIG_DVB_USB=m
+# CONFIG_DVB_USB_DEBUG is not set
+CONFIG_DVB_USB_A800=m
+CONFIG_DVB_USB_DIBUSB_MB=m
+# CONFIG_DVB_USB_DIBUSB_MB_FAULTY is not set
+CONFIG_DVB_USB_DIBUSB_MC=m
+CONFIG_DVB_USB_DIB0700=m
+CONFIG_DVB_USB_UMT_010=m
+CONFIG_DVB_USB_CXUSB=m
+CONFIG_DVB_USB_M920X=m
+CONFIG_DVB_USB_GL861=m
+CONFIG_DVB_USB_AU6610=m
+CONFIG_DVB_USB_DIGITV=m
+CONFIG_DVB_USB_VP7045=m
+CONFIG_DVB_USB_VP702X=m
+CONFIG_DVB_USB_GP8PSK=m
+CONFIG_DVB_USB_NOVA_T_USB2=m
+CONFIG_DVB_USB_TTUSB2=m
+CONFIG_DVB_USB_DTT200U=m
+CONFIG_DVB_TTUSB_BUDGET=m
+CONFIG_DVB_TTUSB_DEC=m
+CONFIG_DVB_CINERGYT2=m
+# CONFIG_DVB_CINERGYT2_TUNING is not set
+
+#
+# Supported FlexCopII (B2C2) Adapters
+#
+CONFIG_DVB_B2C2_FLEXCOP=m
+CONFIG_DVB_B2C2_FLEXCOP_PCI=m
+CONFIG_DVB_B2C2_FLEXCOP_USB=m
+# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set
+
+#
+# Supported BT878 Adapters
+#
+CONFIG_DVB_BT8XX=m
+
+#
+# Supported Pluto2 Adapters
+#
+CONFIG_DVB_PLUTO2=m
+
+#
+# Supported DVB Frontends
+#
+
+#
+# Customise DVB Frontends
+#
+CONFIG_DVB_FE_CUSTOMISE=y
+
+#
+# DVB-S (satellite) frontends
+#
+CONFIG_DVB_STV0299=m
+CONFIG_DVB_CX24110=m
+CONFIG_DVB_CX24123=m
+CONFIG_DVB_TDA8083=m
+CONFIG_DVB_MT312=m
+CONFIG_DVB_VES1X93=m
+CONFIG_DVB_S5H1420=m
+CONFIG_DVB_TDA10086=m
+
+#
+# DVB-T (terrestrial) frontends
+#
+CONFIG_DVB_SP8870=m
+CONFIG_DVB_SP887X=m
+CONFIG_DVB_CX22700=m
+CONFIG_DVB_CX22702=m
+CONFIG_DVB_L64781=m
+CONFIG_DVB_TDA1004X=m
+CONFIG_DVB_NXT6000=m
+CONFIG_DVB_MT352=m
+CONFIG_DVB_ZL10353=m
+CONFIG_DVB_DIB3000MB=m
+CONFIG_DVB_DIB3000MC=m
+CONFIG_DVB_DIB7000M=m
+CONFIG_DVB_DIB7000P=m
+
+#
+# DVB-C (cable) frontends
+#
+CONFIG_DVB_VES1820=m
+CONFIG_DVB_TDA10021=m
+CONFIG_DVB_STV0297=m
+
+#
+# ATSC (North American/Korean Terrestrial/Cable DTV) frontends
+#
+CONFIG_DVB_NXT200X=m
+CONFIG_DVB_OR51211=m
+CONFIG_DVB_OR51132=m
+CONFIG_DVB_BCM3510=m
+CONFIG_DVB_LGDT330X=m
+
+#
+# Tuners/PLL support
+#
+CONFIG_DVB_PLL=m
+CONFIG_DVB_TDA826X=m
+CONFIG_DVB_TUNER_QT1010=m
+CONFIG_DVB_TUNER_MT2060=m
+CONFIG_DVB_TUNER_LGH06XF=m
+
+#
+# Miscellaneous devices
+#
+CONFIG_DVB_LNBP21=m
+CONFIG_DVB_ISL6421=m
+CONFIG_DVB_TUA6100=m
+CONFIG_VIDEO_SAA7146=m
+CONFIG_VIDEO_SAA7146_VV=m
+CONFIG_VIDEO_TUNER=m
+CONFIG_VIDEO_BUF=m
+CONFIG_VIDEO_BUF_DVB=m
+CONFIG_VIDEO_BTCX=m
+CONFIG_VIDEO_IR=m
+CONFIG_VIDEO_TVEEPROM=m
+CONFIG_USB_DABUSB=m
+
+#
+# Graphics support
+#
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_LCD_CLASS_DEVICE=m
+CONFIG_BACKLIGHT_PROGEAR=m
+CONFIG_FB=y
+CONFIG_FIRMWARE_EDID=y
+CONFIG_FB_DDC=m
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+CONFIG_FB_SVGALIB=m
+# CONFIG_FB_MACMODES is not set
+CONFIG_FB_BACKLIGHT=y
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_TILEBLITTING=y
+
+#
+# Frame buffer hardware drivers
+#
+CONFIG_FB_CIRRUS=m
+CONFIG_FB_PM2=m
+# CONFIG_FB_PM2_FIFO_DISCONNECT is not set
+CONFIG_FB_CYBER2000=m
+CONFIG_FB_ARC=m
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+CONFIG_FB_VGA16=y
+CONFIG_FB_VESA=y
+CONFIG_FB_HGA=m
+# CONFIG_FB_HGA_ACCEL is not set
+CONFIG_FB_S1D13XXX=m
+CONFIG_FB_NVIDIA=m
+# CONFIG_FB_NVIDIA_I2C is not set
+CONFIG_FB_NVIDIA_BACKLIGHT=y
+CONFIG_FB_RIVA=m
+# CONFIG_FB_RIVA_I2C is not set
+# CONFIG_FB_RIVA_DEBUG is not set
+CONFIG_FB_RIVA_BACKLIGHT=y
+CONFIG_FB_I810=m
+# CONFIG_FB_I810_GTF is not set
+CONFIG_FB_INTEL=m
+# CONFIG_FB_INTEL_DEBUG is not set
+CONFIG_FB_INTEL_I2C=y
+CONFIG_FB_MATROX=m
+# CONFIG_FB_MATROX_MILLENIUM is not set
+# CONFIG_FB_MATROX_MYSTIQUE is not set
+# CONFIG_FB_MATROX_G is not set
+CONFIG_FB_MATROX_I2C=m
+# CONFIG_FB_MATROX_MULTIHEAD is not set
+CONFIG_FB_RADEON=m
+CONFIG_FB_RADEON_I2C=y
+CONFIG_FB_RADEON_BACKLIGHT=y
+# CONFIG_FB_RADEON_DEBUG is not set
+CONFIG_FB_ATY128=m
+CONFIG_FB_ATY128_BACKLIGHT=y
+CONFIG_FB_ATY=m
+# CONFIG_FB_ATY_CT is not set
+# CONFIG_FB_ATY_GX is not set
+CONFIG_FB_ATY_BACKLIGHT=y
+CONFIG_FB_S3=m
+CONFIG_FB_SAVAGE=m
+# CONFIG_FB_SAVAGE_I2C is not set
+# CONFIG_FB_SAVAGE_ACCEL is not set
+CONFIG_FB_SIS=m
+# CONFIG_FB_SIS_300 is not set
+# CONFIG_FB_SIS_315 is not set
+CONFIG_FB_NEOMAGIC=m
+CONFIG_FB_KYRO=m
+CONFIG_FB_3DFX=m
+# CONFIG_FB_3DFX_ACCEL is not set
+CONFIG_FB_VOODOO1=m
+CONFIG_FB_CYBLA=m
+CONFIG_FB_TRIDENT=m
+# CONFIG_FB_TRIDENT_ACCEL is not set
+CONFIG_FB_GEODE=y
+CONFIG_FB_GEODE_GX=m
+# CONFIG_FB_GEODE_GX_SET_FBSIZE is not set
+CONFIG_FB_GEODE_GX1=m
+# CONFIG_FB_SM501 is not set
+CONFIG_FB_VIRTUAL=m
+
+#
+# Console display driver support
+#
+CONFIG_VGA_CONSOLE=y
+# CONFIG_VGACON_SOFT_SCROLLBACK is not set
+CONFIG_VIDEO_SELECT=y
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+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 is not set
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+CONFIG_SND_HWDEP=m
+CONFIG_SND_RAWMIDI=m
+CONFIG_SND_SEQUENCER=y
+# CONFIG_SND_SEQ_DUMMY 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_SEQUENCER_OSS=y
+CONFIG_SND_RTCTIMER=m
+CONFIG_SND_SEQ_RTCTIMER_DEFAULT=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_MPU401_UART=m
+CONFIG_SND_OPL3_LIB=m
+CONFIG_SND_VX_LIB=m
+CONFIG_SND_AC97_CODEC=y
+CONFIG_SND_DUMMY=m
+CONFIG_SND_VIRMIDI=m
+CONFIG_SND_MTPAV=m
+CONFIG_SND_MTS64=m
+CONFIG_SND_SERIAL_U16550=m
+CONFIG_SND_MPU401=m
+CONFIG_SND_PORTMAN2X4=m
+
+#
+# PCI devices
+#
+CONFIG_SND_AD1889=m
+CONFIG_SND_ALS300=m
+CONFIG_SND_ALS4000=m
+CONFIG_SND_ALI5451=m
+CONFIG_SND_ATIIXP=m
+CONFIG_SND_ATIIXP_MODEM=m
+CONFIG_SND_AU8810=m
+CONFIG_SND_AU8820=m
+CONFIG_SND_AU8830=m
+CONFIG_SND_AZT3328=m
+CONFIG_SND_BT87X=m
+# CONFIG_SND_BT87X_OVERCLOCK is not set
+CONFIG_SND_CA0106=m
+CONFIG_SND_CMIPCI=m
+CONFIG_SND_CS4281=m
+CONFIG_SND_CS46XX=m
+CONFIG_SND_CS46XX_NEW_DSP=y
+CONFIG_SND_CS5535AUDIO=m
+CONFIG_SND_DARLA20=m
+CONFIG_SND_GINA20=m
+CONFIG_SND_LAYLA20=m
+CONFIG_SND_DARLA24=m
+CONFIG_SND_GINA24=m
+CONFIG_SND_LAYLA24=m
+CONFIG_SND_MONA=m
+CONFIG_SND_MIA=m
+CONFIG_SND_ECHO3G=m
+CONFIG_SND_INDIGO=m
+CONFIG_SND_INDIGOIO=m
+CONFIG_SND_INDIGODJ=m
+CONFIG_SND_EMU10K1=m
+CONFIG_SND_EMU10K1X=m
+CONFIG_SND_ENS1370=m
+CONFIG_SND_ENS1371=m
+CONFIG_SND_ES1938=m
+CONFIG_SND_ES1968=m
+CONFIG_SND_FM801=m
+# CONFIG_SND_FM801_TEA575X_BOOL is not set
+CONFIG_SND_HDA_INTEL=m
+CONFIG_SND_HDSP=m
+CONFIG_SND_HDSPM=m
+CONFIG_SND_ICE1712=m
+CONFIG_SND_ICE1724=m
+CONFIG_SND_INTEL8X0=y
+CONFIG_SND_INTEL8X0M=m
+CONFIG_SND_KORG1212=m
+CONFIG_SND_MAESTRO3=m
+CONFIG_SND_MIXART=m
+CONFIG_SND_NM256=m
+CONFIG_SND_PCXHR=m
+CONFIG_SND_RIPTIDE=m
+CONFIG_SND_RME32=m
+CONFIG_SND_RME96=m
+CONFIG_SND_RME9652=m
+CONFIG_SND_SONICVIBES=m
+CONFIG_SND_TRIDENT=m
+CONFIG_SND_VIA82XX=m
+CONFIG_SND_VIA82XX_MODEM=m
+CONFIG_SND_VX222=m
+CONFIG_SND_YMFPCI=m
+# CONFIG_SND_AC97_POWER_SAVE is not set
+
+#
+# USB devices
+#
+CONFIG_SND_USB_AUDIO=m
+CONFIG_SND_USB_USX2Y=m
+
+#
+# PCMCIA devices
+#
+CONFIG_SND_VXPOCKET=m
+CONFIG_SND_PDAUDIOCF=m
+
+#
+# SoC audio support
+#
+CONFIG_SND_SOC=m
+
+#
+# SoC Platforms
+#
+
+#
+# SoC Audio for the Atmel AT91
+#
+
+#
+# SoC Audio for the Intel PXA2xx
+#
+
+#
+# Open Sound System
+#
+CONFIG_SOUND_PRIME=y
+# CONFIG_OBSOLETE_OSS is not set
+CONFIG_SOUND_BT878=m
+CONFIG_SOUND_ICH=m
+CONFIG_SOUND_TRIDENT=m
+CONFIG_SOUND_MSNDCLAS=m
+CONFIG_MSNDCLAS_INIT_FILE="/etc/sound/msndinit.bin"
+CONFIG_MSNDCLAS_PERM_FILE="/etc/sound/msndperm.bin"
+CONFIG_SOUND_MSNDPIN=m
+CONFIG_MSNDPIN_INIT_FILE="/etc/sound/pndspini.bin"
+CONFIG_MSNDPIN_PERM_FILE="/etc/sound/pndsperm.bin"
+CONFIG_SOUND_VIA82CXXX=m
+# CONFIG_MIDI_VIA82CXXX is not set
+CONFIG_SOUND_OSS=m
+# CONFIG_SOUND_TRACEINIT is not set
+# CONFIG_SOUND_DMAP is not set
+CONFIG_SOUND_CS4232=m
+CONFIG_SOUND_SSCAPE=m
+CONFIG_SOUND_VMIDI=m
+CONFIG_SOUND_TRIX=m
+CONFIG_SOUND_MSS=m
+CONFIG_SOUND_MPU401=m
+CONFIG_SOUND_PAS=m
+CONFIG_SOUND_PSS=m
+# CONFIG_PSS_MIXER is not set
+CONFIG_SOUND_SB=m
+CONFIG_SOUND_YM3812=m
+CONFIG_SOUND_UART6850=m
+CONFIG_SOUND_AEDSP16=m
+# CONFIG_SC6600 is not set
+# CONFIG_AEDSP16_MSS is not set
+# CONFIG_AEDSP16_SBPRO is not set
+CONFIG_SOUND_TVMIXER=m
+CONFIG_SOUND_KAHLUA=m
+CONFIG_AC97_BUS=y
+
+#
+# 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=y
+# CONFIG_USB_EHCI_SPLIT_ISO is not set
+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_USB_EHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_ISP116X_HCD=y
+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=y
+# CONFIG_USB_U132_HCD is not set
+CONFIG_USB_SL811_HCD=y
+# CONFIG_USB_SL811_CS 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=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_DPCM=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_STORAGE_ALAUDA=y
+CONFIG_USB_STORAGE_KARMA=y
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+CONFIG_USB_HIDINPUT_POWERBOOK=y
+CONFIG_HID_FF=y
+CONFIG_HID_PID=y
+CONFIG_LOGITECH_FF=y
+CONFIG_PANTHERLORD_FF=y
+CONFIG_THRUSTMASTER_FF=y
+CONFIG_ZEROPLUS_FF=y
+CONFIG_USB_HIDDEV=y
+CONFIG_USB_AIPTEK=m
+CONFIG_USB_WACOM=m
+CONFIG_USB_ACECAD=m
+CONFIG_USB_KBTAB=m
+CONFIG_USB_POWERMATE=m
+CONFIG_USB_TOUCHSCREEN=m
+CONFIG_USB_TOUCHSCREEN_EGALAX=y
+CONFIG_USB_TOUCHSCREEN_PANJIT=y
+CONFIG_USB_TOUCHSCREEN_3M=y
+CONFIG_USB_TOUCHSCREEN_ITM=y
+CONFIG_USB_TOUCHSCREEN_ETURBO=y
+CONFIG_USB_TOUCHSCREEN_GUNZE=y
+CONFIG_USB_TOUCHSCREEN_DMC_TSC10=y
+CONFIG_USB_YEALINK=m
+CONFIG_USB_XPAD=m
+CONFIG_USB_ATI_REMOTE=m
+CONFIG_USB_ATI_REMOTE2=m
+CONFIG_USB_KEYSPAN_REMOTE=m
+CONFIG_USB_APPLETOUCH=m
+CONFIG_USB_GTCO=m
+
+#
+# USB Imaging devices
+#
+CONFIG_USB_MDC800=m
+CONFIG_USB_MICROTEK=m
+
+#
+# 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=m
+CONFIG_USB_NET_CDC_SUBSET=m
+CONFIG_USB_ALI_M5632=y
+CONFIG_USB_AN2720=y
+CONFIG_USB_BELKIN=y
+CONFIG_USB_ARMLINUX=y
+CONFIG_USB_EPSON2888=y
+# CONFIG_USB_KC2190 is not set
+CONFIG_USB_NET_ZAURUS=m
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+CONFIG_USB_USS720=m
+
+#
+# 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=m
+CONFIG_USB_SERIAL_OMNINET=m
+CONFIG_USB_SERIAL_DEBUG=m
+CONFIG_USB_EZUSB=y
+
+#
+# USB Miscellaneous drivers
+#
+CONFIG_USB_EMI62=m
+CONFIG_USB_EMI26=m
+CONFIG_USB_ADUTUX=m
+CONFIG_USB_AUERSWALD=m
+CONFIG_USB_RIO500=m
+CONFIG_USB_LEGOTOWER=m
+CONFIG_USB_LCD=m
+CONFIG_USB_BERRY_CHARGE=m
+CONFIG_USB_LED=m
+CONFIG_USB_CYPRESS_CY7C63=m
+CONFIG_USB_CYTHERM=m
+CONFIG_USB_PHIDGET=m
+CONFIG_USB_PHIDGETKIT=m
+CONFIG_USB_PHIDGETMOTORCONTROL=m
+CONFIG_USB_PHIDGETSERVO=m
+CONFIG_USB_IDMOUSE=m
+CONFIG_USB_FTDI_ELAN=m
+CONFIG_USB_APPLEDISPLAY=m
+CONFIG_USB_SISUSBVGA=m
+# CONFIG_USB_SISUSBVGA_CON is not set
+CONFIG_USB_LD=m
+CONFIG_USB_TRANCEVIBRATOR=m
+CONFIG_USB_IOWARRIOR=m
+CONFIG_USB_TEST=m
+
+#
+# USB DSL modem support
+#
+CONFIG_USB_ATM=m
+CONFIG_USB_SPEEDTOUCH=m
+CONFIG_USB_CXACRU=m
+CONFIG_USB_UEAGLEATM=m
+CONFIG_USB_XUSBATM=m
+
+#
+# USB Gadget Support
+#
+CONFIG_USB_GADGET=m
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+CONFIG_USB_GADGET_SELECTED=y
+CONFIG_USB_GADGET_NET2280=y
+CONFIG_USB_NET2280=m
+# 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 is not set
+CONFIG_USB_G_SERIAL=m
+CONFIG_USB_MIDI_GADGET=m
+
+#
+# MMC/SD Card support
+#
+CONFIG_MMC=m
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_BLOCK=m
+CONFIG_MMC_SDHCI=m
+CONFIG_MMC_WBSD=m
+CONFIG_MMC_TIFM_SD=m
+
+#
+# LED devices
+#
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=m
+
+#
+# LED drivers
+#
+CONFIG_LEDS_NET48XX=m
+CONFIG_LEDS_WRAP=m
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=m
+CONFIG_LEDS_TRIGGER_IDE_DISK=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=m
+
+#
+# InfiniBand support
+#
+CONFIG_INFINIBAND=m
+CONFIG_INFINIBAND_USER_MAD=m
+CONFIG_INFINIBAND_USER_ACCESS=m
+CONFIG_INFINIBAND_ADDR_TRANS=y
+CONFIG_INFINIBAND_MTHCA=m
+CONFIG_INFINIBAND_MTHCA_DEBUG=y
+CONFIG_INFINIBAND_AMSO1100=m
+# CONFIG_INFINIBAND_AMSO1100_DEBUG is not set
+# CONFIG_INFINIBAND_CXGB3 is not set
+CONFIG_INFINIBAND_IPOIB=m
+# CONFIG_INFINIBAND_IPOIB_CM is not set
+CONFIG_INFINIBAND_IPOIB_DEBUG=y
+# CONFIG_INFINIBAND_IPOIB_DEBUG_DATA is not set
+CONFIG_INFINIBAND_SRP=m
+CONFIG_INFINIBAND_ISER=m
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+CONFIG_EDAC=m
+
+#
+# Reporting subsystems
+#
+# CONFIG_EDAC_DEBUG is not set
+CONFIG_EDAC_MM_EDAC=m
+CONFIG_EDAC_AMD76X=m
+CONFIG_EDAC_E7XXX=m
+CONFIG_EDAC_E752X=m
+CONFIG_EDAC_I82875P=m
+CONFIG_EDAC_I82860=m
+CONFIG_EDAC_R82600=m
+CONFIG_EDAC_POLL=y
+
+#
+# Real Time Clock
+#
+CONFIG_RTC_LIB=m
+CONFIG_RTC_CLASS=m
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=m
+CONFIG_RTC_INTF_PROC=m
+CONFIG_RTC_INTF_DEV=m
+CONFIG_RTC_INTF_DEV_UIE_EMUL=y
+
+#
+# RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+CONFIG_RTC_DRV_X1205=m
+CONFIG_RTC_DRV_DS1307=m
+CONFIG_RTC_DRV_DS1553=m
+CONFIG_RTC_DRV_ISL1208=m
+CONFIG_RTC_DRV_DS1672=m
+CONFIG_RTC_DRV_DS1742=m
+CONFIG_RTC_DRV_PCF8563=m
+CONFIG_RTC_DRV_RS5C348=m
+CONFIG_RTC_DRV_RS5C372=m
+CONFIG_RTC_DRV_M48T86=m
+CONFIG_RTC_DRV_TEST=m
+CONFIG_RTC_DRV_MAX6902=m
+CONFIG_RTC_DRV_V3020=m
+
+#
+# DMA Engine support
+#
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+CONFIG_NET_DMA=y
+
+#
+# DMA Devices
+#
+CONFIG_INTEL_IOATDMA=m
+
+#
+# Auxiliary Display support
+#
+CONFIG_KS0108=m
+CONFIG_KS0108_PORT=0x378
+CONFIG_KS0108_DELAY=2
+CONFIG_CFAG12864B=m
+CONFIG_CFAG12864B_RATE=20
+
+#
+# Virtualization
+#
+CONFIG_KVM=m
+CONFIG_KVM_INTEL=m
+CONFIG_KVM_AMD=m
+
+#
+# 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=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=m
+CONFIG_AUTOFS4_FS=y
+CONFIG_FUSE_FS=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+# CONFIG_ZISOFS is not set
+CONFIG_UDF_FS=y
+CONFIG_UDF_NLS=y
+
+#
+# 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_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLBFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+CONFIG_CONFIGFS_FS=m
+
+#
+# Miscellaneous filesystems
+#
+CONFIG_ADFS_FS=m
+# CONFIG_ADFS_FS_RW is not set
+CONFIG_AFFS_FS=m
+CONFIG_HFS_FS=m
+CONFIG_HFSPLUS_FS=m
+CONFIG_BEFS_FS=m
+# CONFIG_BEFS_DEBUG is not set
+CONFIG_BFS_FS=m
+CONFIG_EFS_FS=m
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_SUMMARY is not set
+# 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=m
+CONFIG_VXFS_FS=m
+CONFIG_HPFS_FS=m
+CONFIG_QNX4FS_FS=m
+CONFIG_SYSV_FS=m
+CONFIG_UFS_FS=m
+# CONFIG_UFS_FS_WRITE is not set
+# CONFIG_UFS_DEBUG is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_DIRECTIO=y
+CONFIG_NFSD=y
+CONFIG_NFSD_V2_ACL=y
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_NFSD_TCP=y
+# CONFIG_ROOT_NFS is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=y
+CONFIG_NFS_ACL_SUPPORT=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+CONFIG_RPCSEC_GSS_SPKM3=m
+CONFIG_SMB_FS=m
+# CONFIG_SMB_NLS_DEFAULT is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
+# CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
+CONFIG_NCP_FS=m
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+CONFIG_CODA_FS=m
+# CONFIG_CODA_FS_OLD_API is not set
+CONFIG_AFS_FS=m
+CONFIG_RXRPC=m
+CONFIG_9P_FS=m
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+
+#
+# Distributed Lock Manager
+#
+CONFIG_DLM=m
+CONFIG_DLM_TCP=y
+# CONFIG_DLM_SCTP is not set
+# CONFIG_DLM_DEBUG is not set
+
+#
+# Instrumentation Support
+#
+# CONFIG_PROFILING is not set
+# CONFIG_KPROBES is not set
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_UNUSED_SYMBOLS=y
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=15
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_X86_FIND_SMP_CONFIG=y
+CONFIG_X86_MPPARSE=y
+CONFIG_DOUBLEFAULT=y
+
+#
+# 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_HASH=m
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_HMAC=m
+CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_GF128MUL=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
+CONFIG_CRYPTO_TWOFISH_586=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_AES_586=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_CAMELLIA=m
+CONFIG_CRYPTO_TEST=m
+
+#
+# Hardware crypto devices
+#
+CONFIG_CRYPTO_DEV_PADLOCK=m
+CONFIG_CRYPTO_DEV_PADLOCK_AES=m
+CONFIG_CRYPTO_DEV_PADLOCK_SHA=m
+CONFIG_CRYPTO_DEV_GEODE=m
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_CRC_CCITT=y
+CONFIG_CRC16=m
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_AUDIT_GENERIC=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_REED_SOLOMON=y
+CONFIG_REED_SOLOMON_DEC16=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_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_PENDING_IRQ=y
+CONFIG_X86_SMP=y
+CONFIG_X86_HT=y
+CONFIG_X86_BIOS_REBOOT=y
+CONFIG_X86_TRAMPOLINE=y
+CONFIG_KTIME_SCALAR=y