Browse Source

Add omap24xx.

Boots the kernel with working video and serial console. Userland is untested.

SVN-Revision: 22530
Michael Büsch 15 years ago
parent
commit
975ba9a88d

+ 22 - 0
target/linux/omap24xx/Makefile

@@ -0,0 +1,22 @@
+#
+# Copyright (C) 2010 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+include $(TOPDIR)/rules.mk
+
+ARCH:=arm
+BOARD:=omap24xx
+BOARDNAME:=TI OMAP-24xx
+FEATURES:=jffs2
+
+LINUX_VERSION:=2.6.35
+
+define Target/Description
+	TI OMAP-24xx
+endef
+
+include $(INCLUDE_DIR)/target.mk
+
+$(eval $(call BuildTarget))

+ 519 - 0
target/linux/omap24xx/config-2.6.35

@@ -0,0 +1,519 @@
+# CONFIG_ADIS16209 is not set
+# CONFIG_ADIS16220 is not set
+# CONFIG_ADIS16240 is not set
+# CONFIG_ADIS16260 is not set
+# CONFIG_ADIS16300 is not set
+# CONFIG_ADIS16350 is not set
+# CONFIG_ADIS16400 is not set
+CONFIG_AEABI=y
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_APM_EMULATION is not set
+# CONFIG_ARCH_CNS3XXX is not set
+CONFIG_ARCH_HAS_CPUFREQ=y
+CONFIG_ARCH_HAS_HOLES_MEMORYMODEL=y
+# CONFIG_ARCH_NUC93X is not set
+CONFIG_ARCH_OMAP=y
+# CONFIG_ARCH_OMAP1 is not set
+CONFIG_ARCH_OMAP2=y
+CONFIG_ARCH_OMAP2420=y
+# CONFIG_ARCH_OMAP2430 is not set
+CONFIG_ARCH_OMAP2PLUS=y
+# CONFIG_ARCH_OMAP3 is not set
+# CONFIG_ARCH_OMAP4 is not set
+CONFIG_ARCH_OMAP_OTG=y
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+# CONFIG_ARCH_S5P6440 is not set
+# CONFIG_ARCH_S5P6442 is not set
+# CONFIG_ARCH_S5PC100 is not set
+# CONFIG_ARCH_S5PV210 is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_ARCH_SHMOBILE is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+# CONFIG_ARCH_USES_GETTIMEOFFSET is not set
+# CONFIG_ARCH_VEXPRESS is not set
+CONFIG_ARM=y
+CONFIG_ARM_DMA_MEM_BUFFERABLE=y
+CONFIG_ARM_ERRATA_411920=y
+CONFIG_ARM_L1_CACHE_SHIFT=5
+CONFIG_ARM_THUMB=y
+CONFIG_ARM_UNWIND=y
+# CONFIG_ARPD is not set
+CONFIG_ATAGS_PROC=y
+CONFIG_BINFMT_MISC=y
+CONFIG_BITREVERSE=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_SD=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_BRANCH_PROFILE_NONE=y
+CONFIG_BRIDGE=m
+CONFIG_BRIDGE_NETFILTER=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_BT=m
+CONFIG_BT_BNEP=m
+# CONFIG_BT_BNEP_MC_FILTER is not set
+# CONFIG_BT_BNEP_PROTO_FILTER is not set
+CONFIG_BT_HCIH4P=m
+CONFIG_BT_HIDP=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_SCO=m
+CONFIG_CBUS=y
+CONFIG_CBUS_RETU=y
+# CONFIG_CBUS_RETU_HEADSET is not set
+CONFIG_CBUS_RETU_POWERBUTTON=y
+CONFIG_CBUS_RETU_RTC=y
+CONFIG_CBUS_RETU_USER=y
+CONFIG_CBUS_RETU_WDT=y
+CONFIG_CBUS_TAHVO=y
+CONFIG_CBUS_TAHVO_USER=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_CMDLINE="root=1f03 rootfstype=jffs2 console=ttyS2,115200 console=tty0"
+CONFIG_CMDLINE_FORCE=y
+CONFIG_COMMON_CLKDEV=y
+CONFIG_COMPAT_BRK=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_CPU_32v6=y
+# CONFIG_CPU_32v6K is not set
+CONFIG_CPU_ABRT_EV6=y
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_CPU_CACHE_V6=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_HAS_PMU=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+CONFIG_CPU_PABRT_V6=y
+CONFIG_CPU_TLB_V6=y
+CONFIG_CPU_V6=y
+CONFIG_CRC16=y
+CONFIG_CRC7=y
+CONFIG_CRC_CCITT=y
+CONFIG_CRC_ITU_T=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_AES=y
+CONFIG_CRYPTO_ANSI_CPRNG=y
+CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+# CONFIG_CRYPTO_DEV_OMAP_SHAM is not set
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_HASH=m
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_HW=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+CONFIG_CRYPTO_RNG=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_ZLIB is not set
+CONFIG_CUSE=m
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_ERRORS=y
+# CONFIG_DEBUG_FS is not set
+CONFIG_DEBUG_GPIO=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_DEBUG_PREEMPT=y
+CONFIG_DEBUG_USER=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_LZO=y
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_DEFAULT_TCP_CONG="cubic"
+CONFIG_DETECT_HUNG_TASK=y
+CONFIG_DETECT_SOFTLOCKUP=y
+CONFIG_DEVKMEM=y
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_DNOTIFY=y
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_ELF_CORE=y
+# CONFIG_EMBEDDED is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+# CONFIG_EXT2_FS_SECURITY is not set
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_XIP=y
+CONFIG_EXT3_DEFAULTS_TO_ORDERED=y
+CONFIG_EXT3_FS=m
+CONFIG_EXT3_FS_POSIX_ACL=y
+# CONFIG_EXT3_FS_SECURITY is not set
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_FAT_FS=y
+CONFIG_FB=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+CONFIG_FB_OMAP=y
+CONFIG_FB_OMAP_BOOTLOADER_INIT=y
+CONFIG_FB_OMAP_CONSISTENT_DMA_SIZE=2
+CONFIG_FB_OMAP_LCDC_BLIZZARD=y
+CONFIG_FB_OMAP_LCDC_EXTERNAL=y
+# CONFIG_FB_OMAP_LCDC_HWA742 is not set
+CONFIG_FB_OMAP_LCD_MIPID=y
+# CONFIG_FB_OMAP_MANUAL_UPDATE is not set
+# CONFIG_FB_SM7XX is not set
+# CONFIG_FIRMWARE_EDID is not set
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_FONTS=y
+# CONFIG_FONT_10x18 is not set
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+CONFIG_FONT_8x16=y
+CONFIG_FONT_8x8=y
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FONT_MINI_4x6 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+CONFIG_FREEZER=y
+CONFIG_FS_MBCACHE=y
+CONFIG_FS_POSIX_ACL=y
+CONFIG_FS_XIP=y
+CONFIG_FTRACE=y
+CONFIG_FUSE_FS=m
+CONFIG_GENERIC_ACL=y
+CONFIG_GENERIC_ATOMIC64=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_SYSFS=y
+# CONFIG_HAMRADIO is not set
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_HAS_DMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAVE_AOUT=y
+CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_HAVE_IDE=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_HAVE_MTD_OTP=y
+CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_HAVE_PROC_CPU=y
+CONFIG_HID=y
+CONFIG_HID_APPLE=m
+CONFIG_HID_SUPPORT=y
+CONFIG_HID_WACOM=m
+# CONFIG_HID_WACOM_POWER_SUPPLY is not set
+CONFIG_HWMON=m
+# CONFIG_HWMON_DEBUG_CHIP is not set
+CONFIG_HW_CONSOLE=y
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_OMAP=y
+CONFIG_HZ=128
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_HELPER_AUTO=y
+CONFIG_I2C_OMAP=y
+CONFIG_IIO=y
+# CONFIG_IIO_RING_BUFFER is not set
+# CONFIG_IIO_TRIGGER is not set
+CONFIG_INET6_XFRM_MODE_BEET=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_INPUT=y
+CONFIG_INPUT_EVDEV=y
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_INPUT_MISC is not set
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=800
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_IPV6=y
+CONFIG_IPV6_MIP6=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_SIT=m
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_MROUTE is not set
+CONFIG_IP_NF_FILTER=y
+CONFIG_IP_NF_IPTABLES=y
+CONFIG_IR_CORE=m
+# CONFIG_ISDN is not set
+CONFIG_JBD=m
+CONFIG_JFFS2_LZO=y
+CONFIG_JFFS2_ZLIB=y
+CONFIG_KALLSYMS=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_LZMA is not set
+CONFIG_KEXEC=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_GPIO is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+CONFIG_KEYBOARD_LM8323=y
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OMAP is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KXSD9 is not set
+# CONFIG_LBDAF is not set
+CONFIG_LEDS=y
+# CONFIG_LEDS_GPIO is not set
+CONFIG_LEDS_TRIGGER_BACKLIGHT=y
+CONFIG_LEDS_TRIGGER_GPIO=y
+# CONFIG_LIS3L02DQ is not set
+CONFIG_LLC=m
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_LOG_BUF_SHIFT=21
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_MACH_NOKIA_N800=y
+CONFIG_MACH_NOKIA_N810=y
+CONFIG_MACH_NOKIA_N810_WIMAX=y
+CONFIG_MACH_NOKIA_N8X0=y
+CONFIG_MACH_NOKIA_N8X0_LCD=y
+CONFIG_MACH_NOKIA_N8X0_USB=y
+CONFIG_MACH_OMAP2_TUSB6010=y
+# CONFIG_MACH_OMAP_2430SDP is not set
+# CONFIG_MACH_OMAP_APOLLON is not set
+# CONFIG_MACH_OMAP_GENERIC is not set
+# CONFIG_MACH_OMAP_H4 is not set
+CONFIG_MACVLAN=m
+# CONFIG_MAX1363 is not set
+CONFIG_MEDIA_ATTACH=y
+CONFIG_MEDIA_SUPPORT=m
+CONFIG_MEDIA_TUNER=m
+CONFIG_MEDIA_TUNER_MC44S803=m
+CONFIG_MEDIA_TUNER_MT20XX=m
+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_XC2028=m
+CONFIG_MEDIA_TUNER_XC5000=m
+CONFIG_MENELAUS=y
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_MMC=y
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_OMAP=y
+CONFIG_MMC_SPI=y
+CONFIG_MMC_UNSAFE_RESUME=y
+CONFIG_MODULE_FORCE_LOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MSDOS_FS=y
+CONFIG_MTD_BLOCK2MTD=y
+# CONFIG_MTD_CFI is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_ONENAND=y
+# CONFIG_MTD_ONENAND_2X_PROGRAM is not set
+# CONFIG_MTD_ONENAND_GENERIC is not set
+CONFIG_MTD_ONENAND_OMAP2=y
+CONFIG_MTD_ONENAND_OTP=y
+# CONFIG_MTD_ONENAND_SIM is not set
+# CONFIG_MTD_ONENAND_VERIFY_WRITE is not set
+CONFIG_NAMESPACES=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_NETDEV_10000=y
+CONFIG_NETFILTER_XTABLES=y
+# CONFIG_NET_ETHERNET is not set
+# CONFIG_NET_NS is not set
+# CONFIG_NET_SCHED is not set
+CONFIG_NLS=y
+CONFIG_NO_HZ=y
+CONFIG_OABI_COMPAT=y
+# CONFIG_OMAP2_DSS is not set
+CONFIG_OMAP_32K_TIMER=y
+CONFIG_OMAP_32K_TIMER_HZ=128
+CONFIG_OMAP_BOOT_REASON=y
+CONFIG_OMAP_BOOT_TAG=y
+CONFIG_OMAP_COMPONENT_VERSION=y
+CONFIG_OMAP_DM_TIMER=y
+CONFIG_OMAP_MBOX_FWK=y
+CONFIG_OMAP_MCBSP=y
+# CONFIG_OMAP_MPU_TIMER is not set
+CONFIG_OMAP_MUX=y
+# CONFIG_OMAP_MUX_DEBUG is not set
+CONFIG_OMAP_MUX_WARNINGS=y
+# CONFIG_OMAP_PM_NONE is not set
+CONFIG_OMAP_PM_NOOP=y
+CONFIG_OMAP_RESET_CLOCKS=y
+CONFIG_OMAP_WATCHDOG=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_PAGE_OFFSET=0xC0000000
+# CONFIG_PARTITION_ADVANCED is not set
+# CONFIG_PCI_SYSCALL is not set
+CONFIG_PERF_USE_VMALLOC=y
+# CONFIG_PLAT_SPEAR is not set
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_OPS=y
+# CONFIG_PM_RUNTIME is not set
+CONFIG_PM_SLEEP=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+CONFIG_PPP=m
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_MPPE=m
+# CONFIG_PPP_MULTILINK is not set
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PREEMPT=y
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_TRACER is not set
+CONFIG_PRINTK_TIME=y
+CONFIG_PROC_PAGE_MONITOR=y
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+CONFIG_RAMZSWAP=m
+CONFIG_RAMZSWAP_STATS=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_GZIP=y
+CONFIG_RD_LZO=y
+CONFIG_SCHED_DEBUG=y
+CONFIG_SCSI=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_SCSI_MOD=y
+CONFIG_SDIO_UART=m
+CONFIG_SENSORS_LM75=m
+CONFIG_SENSORS_TSL2563=m
+# CONFIG_SERIAL_8250_EXTENDED is not set
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+CONFIG_SERIO=y
+# CONFIG_SERIO_RAW is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SLAB is not set
+CONFIG_SLHC=m
+CONFIG_SLUB=y
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+CONFIG_SND=m
+CONFIG_SND_ARM=y
+# CONFIG_SND_EMU10K1_SEQ is not set
+CONFIG_SND_JACK=y
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_OMAP_SOC=m
+CONFIG_SND_OMAP_SOC_MCBSP=m
+CONFIG_SND_OMAP_SOC_N810=m
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+CONFIG_SND_PCM=m
+CONFIG_SND_PCM_OSS=m
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+CONFIG_SND_SOC=m
+# CONFIG_SND_SOC_ALL_CODECS is not set
+CONFIG_SND_SOC_I2C_AND_SPI=m
+CONFIG_SND_SOC_TLV320AIC3X=m
+CONFIG_SND_SPI=y
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_TIMER=m
+CONFIG_SOUND=m
+CONFIG_SOUND_OSS_CORE=y
+CONFIG_SOUND_OSS_CORE_PRECLAIM=y
+CONFIG_SPI=y
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
+CONFIG_SPI_MASTER=y
+CONFIG_SPI_OMAP24XX=y
+# CONFIG_SPI_SPIDEV is not set
+CONFIG_STP=m
+# CONFIG_STRIP_ASM_SYMS is not set
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+CONFIG_SUSPEND_NVS=y
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+# CONFIG_TINY_RCU is not set
+CONFIG_TMPFS_POSIX_ACL=y
+# CONFIG_TOUCHSCREEN_DYNAPRO is not set
+# CONFIG_TOUCHSCREEN_HAMPSHIRE is not set
+# CONFIG_TOUCHSCREEN_MCS5000 is not set
+# CONFIG_TOUCHSCREEN_TPS6507X is not set
+CONFIG_TOUCHSCREEN_TSC2005=y
+CONFIG_TREE_RCU=y
+CONFIG_TUN=m
+CONFIG_UID16=y
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB_SUPPORT=y
+# CONFIG_USER_NS is not set
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_VFAT_FS=y
+CONFIG_VFP=y
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_VIDEO_ALLOW_V4L1=y
+CONFIG_VIDEO_CAPTURE_DRIVERS=y
+CONFIG_VIDEO_DEV=m
+CONFIG_VIDEO_IR=m
+CONFIG_VIDEO_IR_I2C=m
+CONFIG_VIDEO_MEDIA=m
+# CONFIG_VIDEO_OMAP2 is not set
+# CONFIG_VIDEO_OMAP2_VOUT is not set
+CONFIG_VIDEO_TCM825X=m
+CONFIG_VIDEO_V4L1=m
+CONFIG_VIDEO_V4L2=m
+CONFIG_VIDEO_V4L2_COMMON=m
+CONFIG_VLAN_8021Q=m
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_WATCHDOG_NOWAYOUT=y
+# CONFIG_ZBOOT_ROM is not set
+CONFIG_ZBOOT_ROM_BSS=0x10200000
+CONFIG_ZBOOT_ROM_TEXT=0x10C08000
+CONFIG_ZONE_DMA_FLAG=0

+ 29 - 0
target/linux/omap24xx/image/Makefile

@@ -0,0 +1,29 @@
+# 
+# Copyright (C) 2010 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/image.mk
+
+JFFS2_BLOCKSIZE=128k
+JFFS2OPTS += --little-endian --pagesize=0x800 --no-cleanmarkers --pad
+
+
+define Image/BuildKernel
+	$(CP) $(LINUX_DIR)/arch/arm/boot/zImage $(BIN_DIR)/$(IMG_PREFIX)-zImage
+	chmod 0644 $(BIN_DIR)/$(IMG_PREFIX)-zImage
+endef
+
+define Image/Build/squashfs
+    $(call prepare_generic_squashfs,$(BIN_DIR)/$(IMG_PREFIX)-root.$(1))
+endef
+
+define Image/Build
+	$(CP) $(KDIR)/root.$(1) $(BIN_DIR)/$(IMG_PREFIX)-root.$(1)
+	$(call Image/Build/$(1),$(1))
+endef
+
+
+$(eval $(call BuildImage))

+ 355 - 0
target/linux/omap24xx/patches-2.6.35/100-optimized-arm-div.patch

@@ -0,0 +1,355 @@
+---
+ arch/arm/boot/compressed/lib1funcs.S |  348 +++++++++++++++++++++++++++++++++++
+ 1 file changed, 348 insertions(+)
+
+--- /dev/null
++++ linux-2.6.35/arch/arm/boot/compressed/lib1funcs.S
+@@ -0,0 +1,348 @@
++/*
++ * linux/arch/arm/lib/lib1funcs.S: Optimized ARM division routines
++ *
++ * Author: Nicolas Pitre <[email protected]>
++ *   - contributed to gcc-3.4 on Sep 30, 2003
++ *   - adapted for the Linux kernel on Oct 2, 2003
++ */
++
++/* Copyright 1995, 1996, 1998, 1999, 2000, 2003 Free Software Foundation, Inc.
++
++This file is free software; you can redistribute it and/or modify it
++under the terms of the GNU General Public License as published by the
++Free Software Foundation; either version 2, or (at your option) any
++later version.
++
++In addition to the permissions in the GNU General Public License, the
++Free Software Foundation gives you unlimited permission to link the
++compiled version of this file into combinations with other programs,
++and to distribute those combinations without any restriction coming
++from the use of this file.  (The General Public License restrictions
++do apply in other respects; for example, they cover modification of
++the file, and distribution when not linked into a combine
++executable.)
++
++This file 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; see the file COPYING.  If not, write to
++the Free Software Foundation, 59 Temple Place - Suite 330,
++Boston, MA 02111-1307, USA.  */
++
++
++#include <linux/linkage.h>
++#include <asm/assembler.h>
++
++
++.macro ARM_DIV_BODY dividend, divisor, result, curbit
++
++#if __LINUX_ARM_ARCH__ >= 5
++
++	clz	\curbit, \divisor
++	clz	\result, \dividend
++	sub	\result, \curbit, \result
++	mov	\curbit, #1
++	mov	\divisor, \divisor, lsl \result
++	mov	\curbit, \curbit, lsl \result
++	mov	\result, #0
++	
++#else
++
++	@ Initially shift the divisor left 3 bits if possible,
++	@ set curbit accordingly.  This allows for curbit to be located
++	@ at the left end of each 4 bit nibbles in the division loop
++	@ to save one loop in most cases.
++	tst	\divisor, #0xe0000000
++	moveq	\divisor, \divisor, lsl #3
++	moveq	\curbit, #8
++	movne	\curbit, #1
++
++	@ Unless the divisor is very big, shift it up in multiples of
++	@ four bits, since this is the amount of unwinding in the main
++	@ division loop.  Continue shifting until the divisor is 
++	@ larger than the dividend.
++1:	cmp	\divisor, #0x10000000
++	cmplo	\divisor, \dividend
++	movlo	\divisor, \divisor, lsl #4
++	movlo	\curbit, \curbit, lsl #4
++	blo	1b
++
++	@ For very big divisors, we must shift it a bit at a time, or
++	@ we will be in danger of overflowing.
++1:	cmp	\divisor, #0x80000000
++	cmplo	\divisor, \dividend
++	movlo	\divisor, \divisor, lsl #1
++	movlo	\curbit, \curbit, lsl #1
++	blo	1b
++
++	mov	\result, #0
++
++#endif
++
++	@ Division loop
++1:	cmp	\dividend, \divisor
++	subhs	\dividend, \dividend, \divisor
++	orrhs	\result,   \result,   \curbit
++	cmp	\dividend, \divisor,  lsr #1
++	subhs	\dividend, \dividend, \divisor, lsr #1
++	orrhs	\result,   \result,   \curbit,  lsr #1
++	cmp	\dividend, \divisor,  lsr #2
++	subhs	\dividend, \dividend, \divisor, lsr #2
++	orrhs	\result,   \result,   \curbit,  lsr #2
++	cmp	\dividend, \divisor,  lsr #3
++	subhs	\dividend, \dividend, \divisor, lsr #3
++	orrhs	\result,   \result,   \curbit,  lsr #3
++	cmp	\dividend, #0			@ Early termination?
++	movnes	\curbit,   \curbit,  lsr #4	@ No, any more bits to do?
++	movne	\divisor,  \divisor, lsr #4
++	bne	1b
++
++.endm
++
++
++.macro ARM_DIV2_ORDER divisor, order
++
++#if __LINUX_ARM_ARCH__ >= 5
++
++	clz	\order, \divisor
++	rsb	\order, \order, #31
++
++#else
++
++	cmp	\divisor, #(1 << 16)
++	movhs	\divisor, \divisor, lsr #16
++	movhs	\order, #16
++	movlo	\order, #0
++
++	cmp	\divisor, #(1 << 8)
++	movhs	\divisor, \divisor, lsr #8
++	addhs	\order, \order, #8
++
++	cmp	\divisor, #(1 << 4)
++	movhs	\divisor, \divisor, lsr #4
++	addhs	\order, \order, #4
++
++	cmp	\divisor, #(1 << 2)
++	addhi	\order, \order, #3
++	addls	\order, \order, \divisor, lsr #1
++
++#endif
++
++.endm
++
++
++.macro ARM_MOD_BODY dividend, divisor, order, spare
++
++#if __LINUX_ARM_ARCH__ >= 5
++
++	clz	\order, \divisor
++	clz	\spare, \dividend
++	sub	\order, \order, \spare
++	mov	\divisor, \divisor, lsl \order
++
++#else
++
++	mov	\order, #0
++
++	@ Unless the divisor is very big, shift it up in multiples of
++	@ four bits, since this is the amount of unwinding in the main
++	@ division loop.  Continue shifting until the divisor is 
++	@ larger than the dividend.
++1:	cmp	\divisor, #0x10000000
++	cmplo	\divisor, \dividend
++	movlo	\divisor, \divisor, lsl #4
++	addlo	\order, \order, #4
++	blo	1b
++
++	@ For very big divisors, we must shift it a bit at a time, or
++	@ we will be in danger of overflowing.
++1:	cmp	\divisor, #0x80000000
++	cmplo	\divisor, \dividend
++	movlo	\divisor, \divisor, lsl #1
++	addlo	\order, \order, #1
++	blo	1b
++
++#endif
++
++	@ Perform all needed substractions to keep only the reminder.
++	@ Do comparisons in batch of 4 first.
++	subs	\order, \order, #3		@ yes, 3 is intended here
++	blt	2f
++
++1:	cmp	\dividend, \divisor
++	subhs	\dividend, \dividend, \divisor
++	cmp	\dividend, \divisor,  lsr #1
++	subhs	\dividend, \dividend, \divisor, lsr #1
++	cmp	\dividend, \divisor,  lsr #2
++	subhs	\dividend, \dividend, \divisor, lsr #2
++	cmp	\dividend, \divisor,  lsr #3
++	subhs	\dividend, \dividend, \divisor, lsr #3
++	cmp	\dividend, #1
++	mov	\divisor, \divisor, lsr #4
++	subges	\order, \order, #4
++	bge	1b
++
++	tst	\order, #3
++	teqne	\dividend, #0
++	beq	5f
++
++	@ Either 1, 2 or 3 comparison/substractions are left.
++2:	cmn	\order, #2
++	blt	4f
++	beq	3f
++	cmp	\dividend, \divisor
++	subhs	\dividend, \dividend, \divisor
++	mov	\divisor,  \divisor,  lsr #1
++3:	cmp	\dividend, \divisor
++	subhs	\dividend, \dividend, \divisor
++	mov	\divisor,  \divisor,  lsr #1
++4:	cmp	\dividend, \divisor
++	subhs	\dividend, \dividend, \divisor
++5:
++.endm
++
++
++ENTRY(__udivsi3)
++ENTRY(__aeabi_uidiv)
++
++	subs	r2, r1, #1
++	moveq	pc, lr
++	bcc	Ldiv0
++	cmp	r0, r1
++	bls	11f
++	tst	r1, r2
++	beq	12f
++
++	ARM_DIV_BODY r0, r1, r2, r3
++
++	mov	r0, r2
++	mov	pc, lr
++
++11:	moveq	r0, #1
++	movne	r0, #0
++	mov	pc, lr
++
++12:	ARM_DIV2_ORDER r1, r2
++
++	mov	r0, r0, lsr r2
++	mov	pc, lr
++
++ENDPROC(__udivsi3)
++ENDPROC(__aeabi_uidiv)
++
++ENTRY(__umodsi3)
++
++	subs	r2, r1, #1			@ compare divisor with 1
++	bcc	Ldiv0
++	cmpne	r0, r1				@ compare dividend with divisor
++	moveq   r0, #0
++	tsthi	r1, r2				@ see if divisor is power of 2
++	andeq	r0, r0, r2
++	movls	pc, lr
++
++	ARM_MOD_BODY r0, r1, r2, r3
++
++	mov	pc, lr
++
++ENDPROC(__umodsi3)
++
++ENTRY(__divsi3)
++ENTRY(__aeabi_idiv)
++
++	cmp	r1, #0
++	eor	ip, r0, r1			@ save the sign of the result.
++	beq	Ldiv0
++	rsbmi	r1, r1, #0			@ loops below use unsigned.
++	subs	r2, r1, #1			@ division by 1 or -1 ?
++	beq	10f
++	movs	r3, r0
++	rsbmi	r3, r0, #0			@ positive dividend value
++	cmp	r3, r1
++	bls	11f
++	tst	r1, r2				@ divisor is power of 2 ?
++	beq	12f
++
++	ARM_DIV_BODY r3, r1, r0, r2
++
++	cmp	ip, #0
++	rsbmi	r0, r0, #0
++	mov	pc, lr
++
++10:	teq	ip, r0				@ same sign ?
++	rsbmi	r0, r0, #0
++	mov	pc, lr
++
++11:	movlo	r0, #0
++	moveq	r0, ip, asr #31
++	orreq	r0, r0, #1
++	mov	pc, lr
++
++12:	ARM_DIV2_ORDER r1, r2
++
++	cmp	ip, #0
++	mov	r0, r3, lsr r2
++	rsbmi	r0, r0, #0
++	mov	pc, lr
++
++ENDPROC(__divsi3)
++ENDPROC(__aeabi_idiv)
++
++ENTRY(__modsi3)
++
++	cmp	r1, #0
++	beq	Ldiv0
++	rsbmi	r1, r1, #0			@ loops below use unsigned.
++	movs	ip, r0				@ preserve sign of dividend
++	rsbmi	r0, r0, #0			@ if negative make positive
++	subs	r2, r1, #1			@ compare divisor with 1
++	cmpne	r0, r1				@ compare dividend with divisor
++	moveq	r0, #0
++	tsthi	r1, r2				@ see if divisor is power of 2
++	andeq	r0, r0, r2
++	bls	10f
++
++	ARM_MOD_BODY r0, r1, r2, r3
++
++10:	cmp	ip, #0
++	rsbmi	r0, r0, #0
++	mov	pc, lr
++
++ENDPROC(__modsi3)
++
++#ifdef CONFIG_AEABI
++
++ENTRY(__aeabi_uidivmod)
++
++	stmfd	sp!, {r0, r1, ip, lr}
++	bl	__aeabi_uidiv
++	ldmfd	sp!, {r1, r2, ip, lr}
++	mul	r3, r0, r2
++	sub	r1, r1, r3
++	mov	pc, lr
++
++ENDPROC(__aeabi_uidivmod)
++
++ENTRY(__aeabi_idivmod)
++
++	stmfd	sp!, {r0, r1, ip, lr}
++	bl	__aeabi_idiv
++	ldmfd	sp!, {r1, r2, ip, lr}
++	mul	r3, r0, r2
++	sub	r1, r1, r3
++	mov	pc, lr
++
++ENDPROC(__aeabi_idivmod)
++
++#endif
++
++Ldiv0:
++
++	str	lr, [sp, #-8]!
++	bl	__div0
++	mov	r0, #0			@ About as wrong as it could be.
++	ldr	pc, [sp], #8
++
++

+ 10422 - 0
target/linux/omap24xx/patches-2.6.35/200-omap-platform.patch

@@ -0,0 +1,10422 @@
+Index: linux-2.6.35/arch/arm/plat-omap/bootreason.c
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/bootreason.c	2010-08-08 12:56:34.000000000 +0200
+@@ -0,0 +1,79 @@
++/*
++ * linux/arch/arm/plat-omap/bootreason.c
++ *
++ * OMAP Bootreason passing
++ *
++ * Copyright (c) 2004 Nokia
++ *
++ * Written by David Weinehall <[email protected]>
++ *
++ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ *
++ * 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.,
++ * 675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++#include <linux/proc_fs.h>
++#include <linux/errno.h>
++#include <plat/board.h>
++
++static char boot_reason[16];
++
++static int omap_bootreason_read_proc(char *page, char **start, off_t off,
++					 int count, int *eof, void *data)
++{
++	int len = 0;
++
++	len += sprintf(page + len, "%s\n", boot_reason);
++
++	*start = page + off;
++
++	if (len > off)
++		len -= off;
++	else
++		len = 0;
++
++	return len < count ? len  : count;
++}
++
++static int __init bootreason_init(void)
++{
++	const struct omap_boot_reason_config *cfg;
++	int reason_valid = 0;
++
++	cfg = omap_get_config(OMAP_TAG_BOOT_REASON, struct omap_boot_reason_config);
++	if (cfg != NULL) {
++		strncpy(boot_reason, cfg->reason_str, sizeof(cfg->reason_str));
++		boot_reason[sizeof(cfg->reason_str)] = 0;
++		reason_valid = 1;
++	} else {
++		/* Read the boot reason from the OMAP registers */
++	}
++
++	if (!reason_valid)
++		return -ENOENT;
++
++	printk(KERN_INFO "Bootup reason: %s\n", boot_reason);
++
++	if (!create_proc_read_entry("bootreason", S_IRUGO, NULL,
++					omap_bootreason_read_proc, NULL))
++		return -ENOMEM;
++
++	return 0;
++}
++
++late_initcall(bootreason_init);
+Index: linux-2.6.35/arch/arm/plat-omap/common.c
+===================================================================
+--- linux-2.6.35.orig/arch/arm/plat-omap/common.c	2010-08-08 12:56:15.000000000 +0200
++++ linux-2.6.35/arch/arm/plat-omap/common.c	2010-08-08 12:56:35.000000000 +0200
+@@ -47,11 +47,81 @@
+ struct omap_board_config_kernel *omap_board_config;
+ int omap_board_config_size;
+ 
++unsigned char omap_bootloader_tag[1024];
++int omap_bootloader_tag_len;
++
++/* used by omap-smp.c and board-4430sdp.c */
++void __iomem *gic_cpu_base_addr;
++
++#ifdef CONFIG_OMAP_BOOT_TAG
++
++static int __init parse_tag_omap(const struct tag *tag)
++{
++	u32 size = tag->hdr.size - (sizeof(tag->hdr) >> 2);
++
++        size <<= 2;
++	if (size > sizeof(omap_bootloader_tag))
++		return -1;
++
++	memcpy(omap_bootloader_tag, tag->u.omap.data, size);
++	omap_bootloader_tag_len = size;
++
++        return 0;
++}
++
++__tagtable(ATAG_BOARD, parse_tag_omap);
++
++#endif
++
+ static const void *get_config(u16 tag, size_t len, int skip, size_t *len_out)
+ {
+ 	struct omap_board_config_kernel *kinfo = NULL;
+ 	int i;
+ 
++#ifdef CONFIG_OMAP_BOOT_TAG
++	struct omap_board_config_entry *info = NULL;
++
++	if (omap_bootloader_tag_len > 4)
++		info = (struct omap_board_config_entry *) omap_bootloader_tag;
++	while (info != NULL) {
++		u8 *next;
++
++		if (info->tag == tag) {
++			if (skip == 0)
++				break;
++			skip--;
++		}
++
++		if ((info->len & 0x03) != 0) {
++			/* We bail out to avoid an alignment fault */
++			printk(KERN_ERR "OMAP peripheral config: Length (%d) not word-aligned (tag %04x)\n",
++			       info->len, info->tag);
++			return NULL;
++		}
++		next = (u8 *) info + sizeof(*info) + info->len;
++		if (next >= omap_bootloader_tag + omap_bootloader_tag_len)
++			info = NULL;
++		else
++			info = (struct omap_board_config_entry *) next;
++	}
++	if (info != NULL) {
++		/* Check the length as a lame attempt to check for
++		 * binary inconsistency. */
++		if (len != NO_LENGTH_CHECK) {
++			/* Word-align len */
++			if (len & 0x03)
++				len = (len + 3) & ~0x03;
++			if (info->len != len) {
++				printk(KERN_ERR "OMAP peripheral config: Length mismatch with tag %x (want %d, got %d)\n",
++				       tag, len, info->len);
++				return NULL;
++			}
++		}
++		if (len_out != NULL)
++			*len_out = info->len;
++		return info->data;
++	}
++#endif
+ 	/* Try to find the config from the board-specific structures
+ 	 * in the kernel. */
+ 	for (i = 0; i < omap_board_config_size; i++) {
+Index: linux-2.6.35/arch/arm/plat-omap/component-version.c
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/component-version.c	2010-08-08 12:56:36.000000000 +0200
+@@ -0,0 +1,64 @@
++/*
++ *  linux/arch/arm/plat-omap/component-version.c
++ *
++ *  Copyright (C) 2005 Nokia Corporation
++ *  Written by Juha Yrjölä <[email protected]>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/err.h>
++#include <linux/proc_fs.h>
++#include <plat/board.h>
++
++static int component_version_read_proc(char *page, char **start, off_t off,
++				       int count, int *eof, void *data)
++{
++	int len, i;
++	const struct omap_version_config *ver;
++	char *p;
++
++	i = 0;
++	p = page;
++	while ((ver = omap_get_nr_config(OMAP_TAG_VERSION_STR,
++					 struct omap_version_config, i)) != NULL) {
++		p += sprintf(p, "%-12s%s\n", ver->component, ver->version);
++		i++;
++	}
++
++	len = (p - page) - off;
++	if (len < 0)
++		len = 0;
++
++	*eof = (len <= count) ? 1 : 0;
++	*start = page + off;
++
++	return len;
++}
++
++static int __init component_version_init(void)
++{
++	if (omap_get_config(OMAP_TAG_VERSION_STR, struct omap_version_config) == NULL)
++		return -ENODEV;
++	if (!create_proc_read_entry("component_version", S_IRUGO, NULL,
++				    component_version_read_proc, NULL))
++		return -ENOMEM;
++
++	return 0;
++}
++
++static void __exit component_version_exit(void)
++{
++	remove_proc_entry("component_version", NULL);
++}
++
++late_initcall(component_version_init);
++module_exit(component_version_exit);
++
++MODULE_AUTHOR("Juha Yrjölä <[email protected]>");
++MODULE_DESCRIPTION("Component version driver");
++MODULE_LICENSE("GPL");
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/blizzard.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/blizzard.h	2010-08-08 12:56:36.000000000 +0200
+@@ -0,0 +1,12 @@
++#ifndef _BLIZZARD_H
++#define _BLIZZARD_H
++
++struct blizzard_platform_data {
++	void		(*power_up)(struct device *dev);
++	void		(*power_down)(struct device *dev);
++	unsigned long	(*get_clock_rate)(struct device *dev);
++
++	unsigned	te_connected : 1;
++};
++
++#endif
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/board-ams-delta.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/board-ams-delta.h	2010-08-08 12:56:37.000000000 +0200
+@@ -0,0 +1,76 @@
++/*
++ * arch/arm/plat-omap/include/mach/board-ams-delta.h
++ *
++ * Copyright (C) 2006 Jonathan McDowell <[email protected]>
++ *
++ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ *
++ * 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.,
++ * 675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++#ifndef __ASM_ARCH_OMAP_AMS_DELTA_H
++#define __ASM_ARCH_OMAP_AMS_DELTA_H
++
++#if defined (CONFIG_MACH_AMS_DELTA)
++
++#define AMS_DELTA_LATCH1_PHYS		0x01000000
++#define AMS_DELTA_LATCH1_VIRT		0xEA000000
++#define AMS_DELTA_MODEM_PHYS		0x04000000
++#define AMS_DELTA_MODEM_VIRT		0xEB000000
++#define AMS_DELTA_LATCH2_PHYS		0x08000000
++#define AMS_DELTA_LATCH2_VIRT		0xEC000000
++
++#define AMS_DELTA_LATCH1_LED_CAMERA	0x01
++#define AMS_DELTA_LATCH1_LED_ADVERT	0x02
++#define AMS_DELTA_LATCH1_LED_EMAIL	0x04
++#define AMS_DELTA_LATCH1_LED_HANDSFREE	0x08
++#define AMS_DELTA_LATCH1_LED_VOICEMAIL	0x10
++#define AMS_DELTA_LATCH1_LED_VOICE	0x20
++
++#define AMS_DELTA_LATCH2_LCD_VBLEN	0x0001
++#define AMS_DELTA_LATCH2_LCD_NDISP	0x0002
++#define AMS_DELTA_LATCH2_NAND_NCE	0x0004
++#define AMS_DELTA_LATCH2_NAND_NRE	0x0008
++#define AMS_DELTA_LATCH2_NAND_NWP	0x0010
++#define AMS_DELTA_LATCH2_NAND_NWE	0x0020
++#define AMS_DELTA_LATCH2_NAND_ALE	0x0040
++#define AMS_DELTA_LATCH2_NAND_CLE	0x0080
++#define AMD_DELTA_LATCH2_KEYBRD_PWR	0x0100
++#define AMD_DELTA_LATCH2_KEYBRD_DATA	0x0200
++#define AMD_DELTA_LATCH2_SCARD_RSTIN	0x0400
++#define AMD_DELTA_LATCH2_SCARD_CMDVCC	0x0800
++#define AMS_DELTA_LATCH2_MODEM_NRESET	0x1000
++#define AMS_DELTA_LATCH2_MODEM_CODEC	0x2000
++
++#define AMS_DELTA_GPIO_PIN_KEYBRD_DATA	0
++#define AMS_DELTA_GPIO_PIN_KEYBRD_CLK	1
++#define AMS_DELTA_GPIO_PIN_MODEM_IRQ	2
++#define AMS_DELTA_GPIO_PIN_HOOK_SWITCH	4
++#define AMS_DELTA_GPIO_PIN_SCARD_NOFF	6
++#define AMS_DELTA_GPIO_PIN_SCARD_IO	7
++#define AMS_DELTA_GPIO_PIN_CONFIG	11
++#define AMS_DELTA_GPIO_PIN_NAND_RB	12
++
++#ifndef __ASSEMBLY__
++void ams_delta_latch1_write(u8 mask, u8 value);
++void ams_delta_latch2_write(u16 mask, u16 value);
++#endif
++
++#endif /* CONFIG_MACH_AMS_DELTA */
++
++#endif /* __ASM_ARCH_OMAP_AMS_DELTA_H */
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/board.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/board.h	2010-08-08 12:56:37.000000000 +0200
+@@ -0,0 +1,169 @@
++/*
++ *  arch/arm/plat-omap/include/mach/board.h
++ *
++ *  Information structures for board-specific data
++ *
++ *  Copyright (C) 2004	Nokia Corporation
++ *  Written by Juha Yrjölä <[email protected]>
++ */
++
++#ifndef _OMAP_BOARD_H
++#define _OMAP_BOARD_H
++
++#include <linux/types.h>
++
++#include <plat/gpio-switch.h>
++
++/*
++ * OMAP35x EVM revision
++ * Run time detection of EVM revision is done by reading Ethernet
++ * PHY ID -
++ *	GEN_1	= 0x01150000
++ *	GEN_2	= 0x92200000
++ */
++enum {
++	OMAP3EVM_BOARD_GEN_1 = 0,	/* EVM Rev between  A - D */
++	OMAP3EVM_BOARD_GEN_2,		/* EVM Rev >= Rev E */
++};
++
++/* Different peripheral ids */
++#define OMAP_TAG_CLOCK		0x4f01
++#define OMAP_TAG_LCD		0x4f05
++#define OMAP_TAG_GPIO_SWITCH	0x4f06
++#define OMAP_TAG_FBMEM		0x4f08
++#define OMAP_TAG_STI_CONSOLE	0x4f09
++#define OMAP_TAG_CAMERA_SENSOR	0x4f0a
++
++#define OMAP_TAG_BOOT_REASON    0x4f80
++#define OMAP_TAG_FLASH_PART	0x4f81
++#define OMAP_TAG_VERSION_STR	0x4f82
++
++struct omap_clock_config {
++	/* 0 for 12 MHz, 1 for 13 MHz and 2 for 19.2 MHz */
++	u8 system_clock_type;
++};
++
++struct omap_serial_console_config {
++	u8 console_uart;
++	u32 console_speed;
++};
++
++struct omap_sti_console_config {
++	unsigned enable:1;
++	u8 channel;
++};
++
++struct omap_camera_sensor_config {
++	u16 reset_gpio;
++	int (*power_on)(void * data);
++	int (*power_off)(void * data);
++};
++
++struct omap_usb_config {
++	/* Configure drivers according to the connectors on your board:
++	 *  - "A" connector (rectagular)
++	 *	... for host/OHCI use, set "register_host".
++	 *  - "B" connector (squarish) or "Mini-B"
++	 *	... for device/gadget use, set "register_dev".
++	 *  - "Mini-AB" connector (very similar to Mini-B)
++	 *	... for OTG use as device OR host, initialize "otg"
++	 */
++	unsigned	register_host:1;
++	unsigned	register_dev:1;
++	u8		otg;	/* port number, 1-based:  usb1 == 2 */
++
++	u8		hmc_mode;
++
++	/* implicitly true if otg:  host supports remote wakeup? */
++	u8		rwc;
++
++	/* signaling pins used to talk to transceiver on usbN:
++	 *  0 == usbN unused
++	 *  2 == usb0-only, using internal transceiver
++	 *  3 == 3 wire bidirectional
++	 *  4 == 4 wire bidirectional
++	 *  6 == 6 wire unidirectional (or TLL)
++	 */
++	u8		pins[3];
++};
++
++struct omap_lcd_config {
++	char panel_name[16];
++	char ctrl_name[16];
++	s16  nreset_gpio;
++	u8   data_lines;
++};
++
++struct device;
++struct fb_info;
++struct omap_backlight_config {
++	int default_intensity;
++	int (*set_power)(struct device *dev, int state);
++	int (*check_fb)(struct fb_info *fb);
++};
++
++struct omap_fbmem_config {
++	u32 start;
++	u32 size;
++};
++
++struct omap_pwm_led_platform_data {
++	const char *name;
++	int intensity_timer;
++	int blink_timer;
++	void (*set_power)(struct omap_pwm_led_platform_data *self, int on_off);
++};
++
++struct omap_uart_config {
++	/* Bit field of UARTs present; bit 0 --> UART1 */
++	unsigned int enabled_uarts;
++};
++
++
++struct omap_flash_part_config {
++	char part_table[0];
++};
++
++struct omap_boot_reason_config {
++	char reason_str[12];
++};
++
++struct omap_version_config {
++	char component[12];
++	char version[12];
++};
++
++struct omap_board_config_entry {
++	u16 tag;
++	u16 len;
++	u8  data[0];
++};
++
++struct omap_board_config_kernel {
++	u16 tag;
++	const void *data;
++};
++
++extern const void *__omap_get_config(u16 tag, size_t len, int nr);
++
++#define omap_get_config(tag, type) \
++	((const type *) __omap_get_config((tag), sizeof(type), 0))
++#define omap_get_nr_config(tag, type, nr) \
++	((const type *) __omap_get_config((tag), sizeof(type), (nr)))
++
++extern const void *omap_get_var_config(u16 tag, size_t *len);
++
++extern struct omap_board_config_kernel *omap_board_config;
++extern int omap_board_config_size;
++
++
++/* for TI reference platforms sharing the same debug card */
++extern int debug_card_init(u32 addr, unsigned gpio);
++
++/* OMAP3EVM revision */
++#if defined(CONFIG_MACH_OMAP3EVM)
++u8 get_omap3_evm_rev(void);
++#else
++#define get_omap3_evm_rev() (-EINVAL)
++#endif
++#endif
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/board-sx1.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/board-sx1.h	2010-08-08 12:56:38.000000000 +0200
+@@ -0,0 +1,52 @@
++/*
++ * Siemens SX1 board definitions
++ *
++ * Copyright: Vovan888 at gmail com
++ *
++ * This package is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
++ */
++
++#ifndef __ASM_ARCH_SX1_I2C_CHIPS_H
++#define __ASM_ARCH_SX1_I2C_CHIPS_H
++
++#define SOFIA_MAX_LIGHT_VAL	0x2B
++
++#define SOFIA_I2C_ADDR		0x32
++/* Sofia reg 3 bits masks */
++#define SOFIA_POWER1_REG	0x03
++
++#define	SOFIA_USB_POWER		0x01
++#define	SOFIA_MMC_POWER		0x04
++#define	SOFIA_BLUETOOTH_POWER	0x08
++#define	SOFIA_MMILIGHT_POWER	0x20
++
++#define SOFIA_POWER2_REG	0x04
++#define SOFIA_BACKLIGHT_REG	0x06
++#define SOFIA_KEYLIGHT_REG	0x07
++#define SOFIA_DIMMING_REG	0x09
++
++
++/* Function Prototypes for SX1 devices control on I2C bus */
++
++int sx1_setbacklight(u8 backlight);
++int sx1_getbacklight(u8 *backlight);
++int sx1_setkeylight(u8 keylight);
++int sx1_getkeylight(u8 *keylight);
++
++int sx1_setmmipower(u8 onoff);
++int sx1_setusbpower(u8 onoff);
++int sx1_i2c_read_byte(u8 devaddr, u8 regoffset, u8 *value);
++int sx1_i2c_write_byte(u8 devaddr, u8 regoffset, u8 value);
++
++/* MMC prototypes */
++
++extern void sx1_mmc_init(void);
++extern void sx1_mmc_slot_cover_handler(void *arg, int state);
++
++#endif /* __ASM_ARCH_SX1_I2C_CHIPS_H */
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/board-voiceblue.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/board-voiceblue.h	2010-08-08 12:56:39.000000000 +0200
+@@ -0,0 +1,19 @@
++/*
++ * Copyright (C) 2004 2N Telekomunikace, Ladislav Michl <[email protected]>
++ *
++ * Hardware definitions for OMAP5910 based VoiceBlue board.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#ifndef __ASM_ARCH_VOICEBLUE_H
++#define __ASM_ARCH_VOICEBLUE_H
++
++extern void voiceblue_wdt_enable(void);
++extern void voiceblue_wdt_disable(void);
++extern void voiceblue_wdt_ping(void);
++
++#endif /*  __ASM_ARCH_VOICEBLUE_H */
++
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/cbus.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/cbus.h	2010-08-08 12:56:39.000000000 +0200
+@@ -0,0 +1,31 @@
++/*
++ * cbus.h - CBUS platform_data definition
++ *
++ * Copyright (C) 2004 - 2009 Nokia Corporation
++ *
++ * Written by Felipe Balbi <[email protected]>
++ *
++ * 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.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ */
++
++#ifndef __PLAT_CBUS_H
++#define __PLAT_CBUS_H
++
++struct cbus_host_platform_data {
++	int	dat_gpio;
++	int	clk_gpio;
++	int	sel_gpio;
++};
++
++#endif /* __PLAT_CBUS_H */
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/clkdev.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/clkdev.h	2010-08-08 12:56:40.000000000 +0200
+@@ -0,0 +1,13 @@
++#ifndef __MACH_CLKDEV_H
++#define __MACH_CLKDEV_H
++
++static inline int __clk_get(struct clk *clk)
++{
++	return 1;
++}
++
++static inline void __clk_put(struct clk *clk)
++{
++}
++
++#endif
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/clkdev_omap.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/clkdev_omap.h	2010-08-08 12:56:40.000000000 +0200
+@@ -0,0 +1,41 @@
++/*
++ * clkdev <-> OMAP integration
++ *
++ * Russell King <[email protected]>
++ *
++ */
++
++#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_PLAT_CLKDEV_OMAP_H
++#define __ARCH_ARM_PLAT_OMAP_INCLUDE_PLAT_CLKDEV_OMAP_H
++
++#include <asm/clkdev.h>
++
++struct omap_clk {
++	u16				cpu;
++	struct clk_lookup		lk;
++};
++
++#define CLK(dev, con, ck, cp) 		\
++	{				\
++		 .cpu = cp,		\
++		.lk = {			\
++			.dev_id = dev,	\
++			.con_id = con,	\
++			.clk = ck,	\
++		},			\
++	}
++
++
++#define CK_310		(1 << 0)
++#define CK_7XX		(1 << 1)
++#define CK_1510		(1 << 2)
++#define CK_16XX		(1 << 3)
++#define CK_243X		(1 << 4)
++#define CK_242X		(1 << 5)
++#define CK_343X		(1 << 6)
++#define CK_3430ES1	(1 << 7)
++#define CK_3430ES2	(1 << 8)
++#define CK_443X		(1 << 9)
++
++#endif
++
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/clockdomain.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/clockdomain.h	2010-08-08 12:56:41.000000000 +0200
+@@ -0,0 +1,111 @@
++/*
++ * arch/arm/plat-omap/include/mach/clockdomain.h
++ *
++ * OMAP2/3 clockdomain framework functions
++ *
++ * Copyright (C) 2008 Texas Instruments, Inc.
++ * Copyright (C) 2008 Nokia Corporation
++ *
++ * Written by Paul Walmsley
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#ifndef __ASM_ARM_ARCH_OMAP_CLOCKDOMAIN_H
++#define __ASM_ARM_ARCH_OMAP_CLOCKDOMAIN_H
++
++#include <plat/powerdomain.h>
++#include <plat/clock.h>
++#include <plat/cpu.h>
++
++/* Clockdomain capability flags */
++#define CLKDM_CAN_FORCE_SLEEP			(1 << 0)
++#define CLKDM_CAN_FORCE_WAKEUP			(1 << 1)
++#define CLKDM_CAN_ENABLE_AUTO			(1 << 2)
++#define CLKDM_CAN_DISABLE_AUTO			(1 << 3)
++
++#define CLKDM_CAN_HWSUP		(CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_DISABLE_AUTO)
++#define CLKDM_CAN_SWSUP		(CLKDM_CAN_FORCE_SLEEP | CLKDM_CAN_FORCE_WAKEUP)
++#define CLKDM_CAN_HWSUP_SWSUP	(CLKDM_CAN_SWSUP | CLKDM_CAN_HWSUP)
++
++/* OMAP24XX CM_CLKSTCTRL_*.AUTOSTATE_* register bit values */
++#define OMAP24XX_CLKSTCTRL_DISABLE_AUTO		0x0
++#define OMAP24XX_CLKSTCTRL_ENABLE_AUTO		0x1
++
++/* OMAP3XXX CM_CLKSTCTRL_*.CLKTRCTRL_* register bit values */
++#define OMAP34XX_CLKSTCTRL_DISABLE_AUTO		0x0
++#define OMAP34XX_CLKSTCTRL_FORCE_SLEEP		0x1
++#define OMAP34XX_CLKSTCTRL_FORCE_WAKEUP		0x2
++#define OMAP34XX_CLKSTCTRL_ENABLE_AUTO		0x3
++
++/*
++ * struct clkdm_pwrdm_autodep - a powerdomain that should have wkdeps
++ * and sleepdeps added when a powerdomain should stay active in hwsup mode;
++ * and conversely, removed when the powerdomain should be allowed to go
++ * inactive in hwsup mode.
++ */
++struct clkdm_pwrdm_autodep {
++
++	union {
++		/* Name of the powerdomain to add a wkdep/sleepdep on */
++		const char *name;
++
++		/* Powerdomain pointer (looked up at clkdm_init() time) */
++		struct powerdomain *ptr;
++	} pwrdm;
++
++	/* OMAP chip types that this clockdomain dep is valid on */
++	const struct omap_chip_id omap_chip;
++
++};
++
++struct clockdomain {
++
++	/* Clockdomain name */
++	const char *name;
++
++	union {
++		/* Powerdomain enclosing this clockdomain */
++		const char *name;
++
++		/* Powerdomain pointer assigned at clkdm_register() */
++		struct powerdomain *ptr;
++	} pwrdm;
++
++	/* CLKTRCTRL/AUTOSTATE field mask in CM_CLKSTCTRL reg */
++	const u16 clktrctrl_mask;
++
++	/* Clockdomain capability flags */
++	const u8 flags;
++
++	/* OMAP chip types that this clockdomain is valid on */
++	const struct omap_chip_id omap_chip;
++
++	/* Usecount tracking */
++	atomic_t usecount;
++
++	struct list_head node;
++
++};
++
++void clkdm_init(struct clockdomain **clkdms, struct clkdm_pwrdm_autodep *autodeps);
++int clkdm_register(struct clockdomain *clkdm);
++int clkdm_unregister(struct clockdomain *clkdm);
++struct clockdomain *clkdm_lookup(const char *name);
++
++int clkdm_for_each(int (*fn)(struct clockdomain *clkdm, void *user),
++			void *user);
++struct powerdomain *clkdm_get_pwrdm(struct clockdomain *clkdm);
++
++void omap2_clkdm_allow_idle(struct clockdomain *clkdm);
++void omap2_clkdm_deny_idle(struct clockdomain *clkdm);
++
++int omap2_clkdm_wakeup(struct clockdomain *clkdm);
++int omap2_clkdm_sleep(struct clockdomain *clkdm);
++
++int omap2_clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk);
++int omap2_clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk);
++
++#endif
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/clock.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/clock.h	2010-08-08 12:56:42.000000000 +0200
+@@ -0,0 +1,168 @@
++/*
++ *  arch/arm/plat-omap/include/mach/clock.h
++ *
++ *  Copyright (C) 2004 - 2005 Nokia corporation
++ *  Written by Tuukka Tikkanen <[email protected]>
++ *  Based on clocks.h by Tony Lindgren, Gordon McNutt and RidgeRun, Inc
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#ifndef __ARCH_ARM_OMAP_CLOCK_H
++#define __ARCH_ARM_OMAP_CLOCK_H
++
++#include <linux/list.h>
++
++struct module;
++struct clk;
++struct clockdomain;
++
++struct clkops {
++	int			(*enable)(struct clk *);
++	void			(*disable)(struct clk *);
++	void			(*find_idlest)(struct clk *, void __iomem **, u8 *);
++	void			(*find_companion)(struct clk *, void __iomem **, u8 *);
++};
++
++#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) || \
++		defined(CONFIG_ARCH_OMAP4)
++
++struct clksel_rate {
++	u32			val;
++	u8			div;
++	u8			flags;
++};
++
++struct clksel {
++	struct clk		 *parent;
++	const struct clksel_rate *rates;
++};
++
++struct dpll_data {
++	void __iomem		*mult_div1_reg;
++	u32			mult_mask;
++	u32			div1_mask;
++	struct clk		*clk_bypass;
++	struct clk		*clk_ref;
++	void __iomem		*control_reg;
++	u32			enable_mask;
++	unsigned int		rate_tolerance;
++	unsigned long		last_rounded_rate;
++	u16			last_rounded_m;
++	u8			last_rounded_n;
++	u8			min_divider;
++	u8			max_divider;
++	u32			max_tolerance;
++	u16			max_multiplier;
++#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
++	u8			modes;
++	void __iomem		*autoidle_reg;
++	void __iomem		*idlest_reg;
++	u32			autoidle_mask;
++	u32			freqsel_mask;
++	u32			idlest_mask;
++	u8			auto_recal_bit;
++	u8			recal_en_bit;
++	u8			recal_st_bit;
++#  endif
++};
++
++#endif
++
++struct clk {
++	struct list_head	node;
++	const struct clkops	*ops;
++	const char		*name;
++	int			id;
++	struct clk		*parent;
++	struct list_head	children;
++	struct list_head	sibling;	/* node for children */
++	unsigned long		rate;
++	__u32			flags;
++	void __iomem		*enable_reg;
++	unsigned long		(*recalc)(struct clk *);
++	int			(*set_rate)(struct clk *, unsigned long);
++	long			(*round_rate)(struct clk *, unsigned long);
++	void			(*init)(struct clk *);
++	__u8			enable_bit;
++	__s8			usecount;
++#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) || \
++		defined(CONFIG_ARCH_OMAP4)
++	u8			fixed_div;
++	void __iomem		*clksel_reg;
++	u32			clksel_mask;
++	const struct clksel	*clksel;
++	struct dpll_data	*dpll_data;
++	const char		*clkdm_name;
++	struct clockdomain	*clkdm;
++#else
++	__u8			rate_offset;
++	__u8			src_offset;
++#endif
++#if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS)
++	struct dentry		*dent;	/* For visible tree hierarchy */
++#endif
++};
++
++struct cpufreq_frequency_table;
++
++struct clk_functions {
++	int		(*clk_enable)(struct clk *clk);
++	void		(*clk_disable)(struct clk *clk);
++	long		(*clk_round_rate)(struct clk *clk, unsigned long rate);
++	int		(*clk_set_rate)(struct clk *clk, unsigned long rate);
++	int		(*clk_set_parent)(struct clk *clk, struct clk *parent);
++	void		(*clk_allow_idle)(struct clk *clk);
++	void		(*clk_deny_idle)(struct clk *clk);
++	void		(*clk_disable_unused)(struct clk *clk);
++#ifdef CONFIG_CPU_FREQ
++	void		(*clk_init_cpufreq_table)(struct cpufreq_frequency_table **);
++#endif
++};
++
++extern unsigned int mpurate;
++
++extern int clk_init(struct clk_functions *custom_clocks);
++extern void clk_preinit(struct clk *clk);
++extern int clk_register(struct clk *clk);
++extern void clk_reparent(struct clk *child, struct clk *parent);
++extern void clk_unregister(struct clk *clk);
++extern void propagate_rate(struct clk *clk);
++extern void recalculate_root_clocks(void);
++extern unsigned long followparent_recalc(struct clk *clk);
++extern void clk_enable_init_clocks(void);
++#ifdef CONFIG_CPU_FREQ
++extern void clk_init_cpufreq_table(struct cpufreq_frequency_table **table);
++#endif
++
++extern const struct clkops clkops_null;
++
++/* Clock flags */
++/* bit 0 is free */
++#define RATE_FIXED		(1 << 1)	/* Fixed clock rate */
++/* bits 2-4 are free */
++#define ENABLE_REG_32BIT	(1 << 5)	/* Use 32-bit access */
++#define CLOCK_IDLE_CONTROL	(1 << 7)
++#define CLOCK_NO_IDLE_PARENT	(1 << 8)
++#define DELAYED_APP		(1 << 9)	/* Delay application of clock */
++#define CONFIG_PARTICIPANT	(1 << 10)	/* Fundamental clock */
++#define ENABLE_ON_INIT		(1 << 11)	/* Enable upon framework init */
++#define INVERT_ENABLE           (1 << 12)       /* 0 enables, 1 disables */
++#define CLOCK_IN_OMAP4430	(1 << 13)
++#define ALWAYS_ENABLED		(1 << 14)
++/* bits 13-31 are currently free */
++
++/* Clksel_rate flags */
++#define DEFAULT_RATE		(1 << 0)
++#define RATE_IN_242X		(1 << 1)
++#define RATE_IN_243X		(1 << 2)
++#define RATE_IN_343X		(1 << 3)	/* rates common to all 343X */
++#define RATE_IN_3430ES2		(1 << 4)	/* 3430ES2 rates only */
++#define RATE_IN_4430            (1 << 5)
++
++#define RATE_IN_24XX		(RATE_IN_242X | RATE_IN_243X)
++
++
++#endif
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/common.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/common.h	2010-08-08 12:56:43.000000000 +0200
+@@ -0,0 +1,83 @@
++/*
++ * arch/arm/plat-omap/include/mach/common.h
++ *
++ * Header for code common to all OMAP machines.
++ *
++ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ *
++ * 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.,
++ * 675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++
++#ifndef __ARCH_ARM_MACH_OMAP_COMMON_H
++#define __ARCH_ARM_MACH_OMAP_COMMON_H
++
++#include <plat/i2c.h>
++
++struct sys_timer;
++
++/* used by omap-smp.c and board-4430sdp.c */
++extern void __iomem *gic_cpu_base_addr;
++
++extern void omap_map_common_io(void);
++extern struct sys_timer omap_timer;
++
++/* IO bases for various OMAP processors */
++struct omap_globals {
++	u32		class;		/* OMAP class to detect */
++	void __iomem	*tap;		/* Control module ID code */
++	void __iomem	*sdrc;		/* SDRAM Controller */
++	void __iomem	*sms;		/* SDRAM Memory Scheduler */
++	void __iomem	*ctrl;		/* System Control Module */
++	void __iomem	*prm;		/* Power and Reset Management */
++	void __iomem	*cm;		/* Clock Management */
++	void __iomem	*cm2;
++};
++
++void omap2_set_globals_242x(void);
++void omap2_set_globals_243x(void);
++void omap2_set_globals_343x(void);
++void omap2_set_globals_443x(void);
++
++/* These get called from omap2_set_globals_xxxx(), do not call these */
++void omap2_set_globals_tap(struct omap_globals *);
++void omap2_set_globals_sdrc(struct omap_globals *);
++void omap2_set_globals_control(struct omap_globals *);
++void omap2_set_globals_prcm(struct omap_globals *);
++
++/**
++ * omap_test_timeout - busy-loop, testing a condition
++ * @cond: condition to test until it evaluates to true
++ * @timeout: maximum number of microseconds in the timeout
++ * @index: loop index (integer)
++ *
++ * Loop waiting for @cond to become true or until at least @timeout
++ * microseconds have passed.  To use, define some integer @index in the
++ * calling code.  After running, if @index == @timeout, then the loop has
++ * timed out.
++ */
++#define omap_test_timeout(cond, timeout, index)			\
++({								\
++	for (index = 0; index < timeout; index++) {		\
++		if (cond)					\
++			break;					\
++		udelay(1);					\
++	}							\
++})
++
++#endif /* __ARCH_ARM_MACH_OMAP_COMMON_H */
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/control.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/control.h	2010-08-08 12:56:44.000000000 +0200
+@@ -0,0 +1,325 @@
++/*
++ * arch/arm/plat-omap/include/mach/control.h
++ *
++ * OMAP2/3/4 System Control Module definitions
++ *
++ * Copyright (C) 2007-2009 Texas Instruments, Inc.
++ * Copyright (C) 2007-2008 Nokia Corporation
++ *
++ * Written by Paul Walmsley
++ *
++ * 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.
++ */
++
++#ifndef __ASM_ARCH_CONTROL_H
++#define __ASM_ARCH_CONTROL_H
++
++#include <mach/io.h>
++
++#ifndef __ASSEMBLY__
++#define OMAP242X_CTRL_REGADDR(reg)					\
++		OMAP2_L4_IO_ADDRESS(OMAP242X_CTRL_BASE + (reg))
++#define OMAP243X_CTRL_REGADDR(reg)					\
++		OMAP2_L4_IO_ADDRESS(OMAP243X_CTRL_BASE + (reg))
++#define OMAP343X_CTRL_REGADDR(reg)					\
++		OMAP2_L4_IO_ADDRESS(OMAP343X_CTRL_BASE + (reg))
++#else
++#define OMAP242X_CTRL_REGADDR(reg)					\
++		OMAP2_L4_IO_ADDRESS(OMAP242X_CTRL_BASE + (reg))
++#define OMAP243X_CTRL_REGADDR(reg)					\
++		OMAP2_L4_IO_ADDRESS(OMAP243X_CTRL_BASE + (reg))
++#define OMAP343X_CTRL_REGADDR(reg)					\
++		OMAP2_L4_IO_ADDRESS(OMAP343X_CTRL_BASE + (reg))
++#endif /* __ASSEMBLY__ */
++
++/*
++ * As elsewhere, the "OMAP2_" prefix indicates that the macro is valid for
++ * OMAP24XX and OMAP34XX.
++ */
++
++/* Control submodule offsets */
++
++#define OMAP2_CONTROL_INTERFACE		0x000
++#define OMAP2_CONTROL_PADCONFS		0x030
++#define OMAP2_CONTROL_GENERAL		0x270
++#define OMAP343X_CONTROL_MEM_WKUP	0x600
++#define OMAP343X_CONTROL_PADCONFS_WKUP	0xa00
++#define OMAP343X_CONTROL_GENERAL_WKUP	0xa60
++
++/* Control register offsets - read/write with omap_ctrl_{read,write}{bwl}() */
++
++#define OMAP2_CONTROL_SYSCONFIG		(OMAP2_CONTROL_INTERFACE + 0x10)
++
++/* CONTROL_GENERAL register offsets common to OMAP2 & 3 */
++#define OMAP2_CONTROL_DEVCONF0		(OMAP2_CONTROL_GENERAL + 0x0004)
++#define OMAP2_CONTROL_MSUSPENDMUX_0	(OMAP2_CONTROL_GENERAL + 0x0020)
++#define OMAP2_CONTROL_MSUSPENDMUX_1	(OMAP2_CONTROL_GENERAL + 0x0024)
++#define OMAP2_CONTROL_MSUSPENDMUX_2	(OMAP2_CONTROL_GENERAL + 0x0028)
++#define OMAP2_CONTROL_MSUSPENDMUX_3	(OMAP2_CONTROL_GENERAL + 0x002c)
++#define OMAP2_CONTROL_MSUSPENDMUX_4	(OMAP2_CONTROL_GENERAL + 0x0030)
++#define OMAP2_CONTROL_MSUSPENDMUX_5	(OMAP2_CONTROL_GENERAL + 0x0034)
++#define OMAP2_CONTROL_SEC_CTRL		(OMAP2_CONTROL_GENERAL + 0x0040)
++#define OMAP2_CONTROL_RPUB_KEY_H_0	(OMAP2_CONTROL_GENERAL + 0x0090)
++#define OMAP2_CONTROL_RPUB_KEY_H_1	(OMAP2_CONTROL_GENERAL + 0x0094)
++#define OMAP2_CONTROL_RPUB_KEY_H_2	(OMAP2_CONTROL_GENERAL + 0x0098)
++#define OMAP2_CONTROL_RPUB_KEY_H_3	(OMAP2_CONTROL_GENERAL + 0x009c)
++
++/* 242x-only CONTROL_GENERAL register offsets */
++#define OMAP242X_CONTROL_DEVCONF	OMAP2_CONTROL_DEVCONF0 /* match TRM */
++#define OMAP242X_CONTROL_OCM_RAM_PERM	(OMAP2_CONTROL_GENERAL + 0x0068)
++
++/* 243x-only CONTROL_GENERAL register offsets */
++/* CONTROL_IVA2_BOOT{ADDR,MOD} are at the same place on 343x - noted below */
++#define OMAP243X_CONTROL_DEVCONF1	(OMAP2_CONTROL_GENERAL + 0x0078)
++#define OMAP243X_CONTROL_CSIRXFE	(OMAP2_CONTROL_GENERAL + 0x007c)
++#define OMAP243X_CONTROL_IVA2_BOOTADDR	(OMAP2_CONTROL_GENERAL + 0x0190)
++#define OMAP243X_CONTROL_IVA2_BOOTMOD	(OMAP2_CONTROL_GENERAL + 0x0194)
++#define OMAP243X_CONTROL_IVA2_GEMCFG	(OMAP2_CONTROL_GENERAL + 0x0198)
++#define OMAP243X_CONTROL_PBIAS_LITE	(OMAP2_CONTROL_GENERAL + 0x0230)
++
++/* 24xx-only CONTROL_GENERAL register offsets */
++#define OMAP24XX_CONTROL_DEBOBS		(OMAP2_CONTROL_GENERAL + 0x0000)
++#define OMAP24XX_CONTROL_EMU_SUPPORT	(OMAP2_CONTROL_GENERAL + 0x0008)
++#define OMAP24XX_CONTROL_SEC_TEST	(OMAP2_CONTROL_GENERAL + 0x0044)
++#define OMAP24XX_CONTROL_PSA_CTRL	(OMAP2_CONTROL_GENERAL + 0x0048)
++#define OMAP24XX_CONTROL_PSA_CMD	(OMAP2_CONTROL_GENERAL + 0x004c)
++#define OMAP24XX_CONTROL_PSA_VALUE	(OMAP2_CONTROL_GENERAL + 0x0050)
++#define OMAP24XX_CONTROL_SEC_EMU	(OMAP2_CONTROL_GENERAL + 0x0060)
++#define OMAP24XX_CONTROL_SEC_TAP	(OMAP2_CONTROL_GENERAL + 0x0064)
++#define OMAP24XX_CONTROL_OCM_PUB_RAM_ADD	(OMAP2_CONTROL_GENERAL + 0x006c)
++#define OMAP24XX_CONTROL_EXT_SEC_RAM_START_ADD	(OMAP2_CONTROL_GENERAL + 0x0070)
++#define OMAP24XX_CONTROL_EXT_SEC_RAM_STOP_ADD	(OMAP2_CONTROL_GENERAL + 0x0074)
++#define OMAP24XX_CONTROL_SEC_STATUS		(OMAP2_CONTROL_GENERAL + 0x0080)
++#define OMAP24XX_CONTROL_SEC_ERR_STATUS		(OMAP2_CONTROL_GENERAL + 0x0084)
++#define OMAP24XX_CONTROL_STATUS			(OMAP2_CONTROL_GENERAL + 0x0088)
++#define OMAP24XX_CONTROL_GENERAL_PURPOSE_STATUS	(OMAP2_CONTROL_GENERAL + 0x008c)
++#define OMAP24XX_CONTROL_RAND_KEY_0	(OMAP2_CONTROL_GENERAL + 0x00a0)
++#define OMAP24XX_CONTROL_RAND_KEY_1	(OMAP2_CONTROL_GENERAL + 0x00a4)
++#define OMAP24XX_CONTROL_RAND_KEY_2	(OMAP2_CONTROL_GENERAL + 0x00a8)
++#define OMAP24XX_CONTROL_RAND_KEY_3	(OMAP2_CONTROL_GENERAL + 0x00ac)
++#define OMAP24XX_CONTROL_CUST_KEY_0	(OMAP2_CONTROL_GENERAL + 0x00b0)
++#define OMAP24XX_CONTROL_CUST_KEY_1	(OMAP2_CONTROL_GENERAL + 0x00b4)
++#define OMAP24XX_CONTROL_TEST_KEY_0	(OMAP2_CONTROL_GENERAL + 0x00c0)
++#define OMAP24XX_CONTROL_TEST_KEY_1	(OMAP2_CONTROL_GENERAL + 0x00c4)
++#define OMAP24XX_CONTROL_TEST_KEY_2	(OMAP2_CONTROL_GENERAL + 0x00c8)
++#define OMAP24XX_CONTROL_TEST_KEY_3	(OMAP2_CONTROL_GENERAL + 0x00cc)
++#define OMAP24XX_CONTROL_TEST_KEY_4	(OMAP2_CONTROL_GENERAL + 0x00d0)
++#define OMAP24XX_CONTROL_TEST_KEY_5	(OMAP2_CONTROL_GENERAL + 0x00d4)
++#define OMAP24XX_CONTROL_TEST_KEY_6	(OMAP2_CONTROL_GENERAL + 0x00d8)
++#define OMAP24XX_CONTROL_TEST_KEY_7	(OMAP2_CONTROL_GENERAL + 0x00dc)
++#define OMAP24XX_CONTROL_TEST_KEY_8	(OMAP2_CONTROL_GENERAL + 0x00e0)
++#define OMAP24XX_CONTROL_TEST_KEY_9	(OMAP2_CONTROL_GENERAL + 0x00e4)
++
++#define OMAP343X_CONTROL_PADCONF_SYSNIRQ (OMAP2_CONTROL_INTERFACE + 0x01b0)
++
++/* 34xx-only CONTROL_GENERAL register offsets */
++#define OMAP343X_CONTROL_PADCONF_OFF	(OMAP2_CONTROL_GENERAL + 0x0000)
++#define OMAP343X_CONTROL_MEM_DFTRW0	(OMAP2_CONTROL_GENERAL + 0x0008)
++#define OMAP343X_CONTROL_MEM_DFTRW1	(OMAP2_CONTROL_GENERAL + 0x000c)
++#define OMAP343X_CONTROL_DEVCONF1	(OMAP2_CONTROL_GENERAL + 0x0068)
++#define OMAP343X_CONTROL_CSIRXFE		(OMAP2_CONTROL_GENERAL + 0x006c)
++#define OMAP343X_CONTROL_SEC_STATUS		(OMAP2_CONTROL_GENERAL + 0x0070)
++#define OMAP343X_CONTROL_SEC_ERR_STATUS		(OMAP2_CONTROL_GENERAL + 0x0074)
++#define OMAP343X_CONTROL_SEC_ERR_STATUS_DEBUG	(OMAP2_CONTROL_GENERAL + 0x0078)
++#define OMAP343X_CONTROL_STATUS			(OMAP2_CONTROL_GENERAL + 0x0080)
++#define OMAP343X_CONTROL_GENERAL_PURPOSE_STATUS	(OMAP2_CONTROL_GENERAL + 0x0084)
++#define OMAP343X_CONTROL_RPUB_KEY_H_4	(OMAP2_CONTROL_GENERAL + 0x00a0)
++#define OMAP343X_CONTROL_RAND_KEY_0	(OMAP2_CONTROL_GENERAL + 0x00a8)
++#define OMAP343X_CONTROL_RAND_KEY_1	(OMAP2_CONTROL_GENERAL + 0x00ac)
++#define OMAP343X_CONTROL_RAND_KEY_2	(OMAP2_CONTROL_GENERAL + 0x00b0)
++#define OMAP343X_CONTROL_RAND_KEY_3	(OMAP2_CONTROL_GENERAL + 0x00b4)
++#define OMAP343X_CONTROL_TEST_KEY_0	(OMAP2_CONTROL_GENERAL + 0x00c8)
++#define OMAP343X_CONTROL_TEST_KEY_1	(OMAP2_CONTROL_GENERAL + 0x00cc)
++#define OMAP343X_CONTROL_TEST_KEY_2	(OMAP2_CONTROL_GENERAL + 0x00d0)
++#define OMAP343X_CONTROL_TEST_KEY_3	(OMAP2_CONTROL_GENERAL + 0x00d4)
++#define OMAP343X_CONTROL_TEST_KEY_4	(OMAP2_CONTROL_GENERAL + 0x00d8)
++#define OMAP343X_CONTROL_TEST_KEY_5	(OMAP2_CONTROL_GENERAL + 0x00dc)
++#define OMAP343X_CONTROL_TEST_KEY_6	(OMAP2_CONTROL_GENERAL + 0x00e0)
++#define OMAP343X_CONTROL_TEST_KEY_7	(OMAP2_CONTROL_GENERAL + 0x00e4)
++#define OMAP343X_CONTROL_TEST_KEY_8	(OMAP2_CONTROL_GENERAL + 0x00e8)
++#define OMAP343X_CONTROL_TEST_KEY_9	(OMAP2_CONTROL_GENERAL + 0x00ec)
++#define OMAP343X_CONTROL_TEST_KEY_10	(OMAP2_CONTROL_GENERAL + 0x00f0)
++#define OMAP343X_CONTROL_TEST_KEY_11	(OMAP2_CONTROL_GENERAL + 0x00f4)
++#define OMAP343X_CONTROL_TEST_KEY_12	(OMAP2_CONTROL_GENERAL + 0x00f8)
++#define OMAP343X_CONTROL_TEST_KEY_13	(OMAP2_CONTROL_GENERAL + 0x00fc)
++#define OMAP343X_CONTROL_IVA2_BOOTADDR	(OMAP2_CONTROL_GENERAL + 0x0190)
++#define OMAP343X_CONTROL_IVA2_BOOTMOD	(OMAP2_CONTROL_GENERAL + 0x0194)
++#define OMAP343X_CONTROL_DEBOBS(i)	(OMAP2_CONTROL_GENERAL + 0x01B0 \
++					+ ((i) >> 1) * 4 + (!(i) & 1) * 2)
++#define OMAP343X_CONTROL_PROG_IO0	(OMAP2_CONTROL_GENERAL + 0x01D4)
++#define OMAP343X_CONTROL_PROG_IO1	(OMAP2_CONTROL_GENERAL + 0x01D8)
++#define OMAP343X_CONTROL_DSS_DPLL_SPREADING	(OMAP2_CONTROL_GENERAL + 0x01E0)
++#define OMAP343X_CONTROL_CORE_DPLL_SPREADING	(OMAP2_CONTROL_GENERAL + 0x01E4)
++#define OMAP343X_CONTROL_PER_DPLL_SPREADING	(OMAP2_CONTROL_GENERAL + 0x01E8)
++#define OMAP343X_CONTROL_USBHOST_DPLL_SPREADING	(OMAP2_CONTROL_GENERAL + 0x01EC)
++#define OMAP343X_CONTROL_PBIAS_LITE	(OMAP2_CONTROL_GENERAL + 0x02B0)
++#define OMAP343X_CONTROL_TEMP_SENSOR	(OMAP2_CONTROL_GENERAL + 0x02B4)
++#define OMAP343X_CONTROL_SRAMLDO4	(OMAP2_CONTROL_GENERAL + 0x02B8)
++#define OMAP343X_CONTROL_SRAMLDO5	(OMAP2_CONTROL_GENERAL + 0x02C0)
++#define OMAP343X_CONTROL_CSI		(OMAP2_CONTROL_GENERAL + 0x02C4)
++
++
++/* 34xx PADCONF register offsets */
++#define OMAP343X_PADCONF_ETK(i)		(OMAP2_CONTROL_PADCONFS + 0x5a8 + \
++						(i)*2)
++#define OMAP343X_PADCONF_ETK_CLK	OMAP343X_PADCONF_ETK(0)
++#define OMAP343X_PADCONF_ETK_CTL	OMAP343X_PADCONF_ETK(1)
++#define OMAP343X_PADCONF_ETK_D0		OMAP343X_PADCONF_ETK(2)
++#define OMAP343X_PADCONF_ETK_D1		OMAP343X_PADCONF_ETK(3)
++#define OMAP343X_PADCONF_ETK_D2		OMAP343X_PADCONF_ETK(4)
++#define OMAP343X_PADCONF_ETK_D3		OMAP343X_PADCONF_ETK(5)
++#define OMAP343X_PADCONF_ETK_D4		OMAP343X_PADCONF_ETK(6)
++#define OMAP343X_PADCONF_ETK_D5		OMAP343X_PADCONF_ETK(7)
++#define OMAP343X_PADCONF_ETK_D6		OMAP343X_PADCONF_ETK(8)
++#define OMAP343X_PADCONF_ETK_D7		OMAP343X_PADCONF_ETK(9)
++#define OMAP343X_PADCONF_ETK_D8		OMAP343X_PADCONF_ETK(10)
++#define OMAP343X_PADCONF_ETK_D9		OMAP343X_PADCONF_ETK(11)
++#define OMAP343X_PADCONF_ETK_D10	OMAP343X_PADCONF_ETK(12)
++#define OMAP343X_PADCONF_ETK_D11	OMAP343X_PADCONF_ETK(13)
++#define OMAP343X_PADCONF_ETK_D12	OMAP343X_PADCONF_ETK(14)
++#define OMAP343X_PADCONF_ETK_D13	OMAP343X_PADCONF_ETK(15)
++#define OMAP343X_PADCONF_ETK_D14	OMAP343X_PADCONF_ETK(16)
++#define OMAP343X_PADCONF_ETK_D15	OMAP343X_PADCONF_ETK(17)
++
++/* 34xx GENERAL_WKUP regist offsets */
++#define OMAP343X_CONTROL_WKUP_DEBOBSMUX(i) (OMAP343X_CONTROL_GENERAL_WKUP + \
++						0x008 + (i))
++#define OMAP343X_CONTROL_WKUP_DEBOBS0 (OMAP343X_CONTROL_GENERAL_WKUP + 0x008)
++#define OMAP343X_CONTROL_WKUP_DEBOBS1 (OMAP343X_CONTROL_GENERAL_WKUP + 0x00C)
++#define OMAP343X_CONTROL_WKUP_DEBOBS2 (OMAP343X_CONTROL_GENERAL_WKUP + 0x010)
++#define OMAP343X_CONTROL_WKUP_DEBOBS3 (OMAP343X_CONTROL_GENERAL_WKUP + 0x014)
++#define OMAP343X_CONTROL_WKUP_DEBOBS4 (OMAP343X_CONTROL_GENERAL_WKUP + 0x018)
++
++/* 34xx D2D idle-related pins, handled by PM core */
++#define OMAP3_PADCONF_SAD2D_MSTANDBY   0x250
++#define OMAP3_PADCONF_SAD2D_IDLEACK    0x254
++
++/*
++ * REVISIT: This list of registers is not comprehensive - there are more
++ * that should be added.
++ */
++
++/*
++ * Control module register bit defines - these should eventually go into
++ * their own regbits file.  Some of these will be complicated, depending
++ * on the device type (general-purpose, emulator, test, secure, bad, other)
++ * and the security mode (secure, non-secure, don't care)
++ */
++/* CONTROL_DEVCONF0 bits */
++#define OMAP2_MMCSDIO1ADPCLKISEL	(1 << 24) /* MMC1 loop back clock */
++#define OMAP24XX_USBSTANDBYCTRL		(1 << 15)
++#define OMAP2_MCBSP2_CLKS_MASK		(1 << 6)
++#define OMAP2_MCBSP1_CLKS_MASK		(1 << 2)
++
++/* CONTROL_DEVCONF1 bits */
++#define OMAP243X_MMC1_ACTIVE_OVERWRITE	(1 << 31)
++#define OMAP2_MMCSDIO2ADPCLKISEL	(1 << 6) /* MMC2 loop back clock */
++#define OMAP2_MCBSP5_CLKS_MASK		(1 << 4) /* > 242x */
++#define OMAP2_MCBSP4_CLKS_MASK		(1 << 2) /* > 242x */
++#define OMAP2_MCBSP3_CLKS_MASK		(1 << 0) /* > 242x */
++
++/* CONTROL_STATUS bits */
++#define OMAP2_DEVICETYPE_MASK		(0x7 << 8)
++#define OMAP2_SYSBOOT_5_MASK		(1 << 5)
++#define OMAP2_SYSBOOT_4_MASK		(1 << 4)
++#define OMAP2_SYSBOOT_3_MASK		(1 << 3)
++#define OMAP2_SYSBOOT_2_MASK		(1 << 2)
++#define OMAP2_SYSBOOT_1_MASK		(1 << 1)
++#define OMAP2_SYSBOOT_0_MASK		(1 << 0)
++
++/* CONTROL_PBIAS_LITE bits */
++#define OMAP343X_PBIASLITESUPPLY_HIGH1	(1 << 15)
++#define OMAP343X_PBIASLITEVMODEERROR1	(1 << 11)
++#define OMAP343X_PBIASSPEEDCTRL1	(1 << 10)
++#define OMAP343X_PBIASLITEPWRDNZ1	(1 << 9)
++#define OMAP343X_PBIASLITEVMODE1	(1 << 8)
++#define OMAP343X_PBIASLITESUPPLY_HIGH0	(1 << 7)
++#define OMAP343X_PBIASLITEVMODEERROR0	(1 << 3)
++#define OMAP2_PBIASSPEEDCTRL0		(1 << 2)
++#define OMAP2_PBIASLITEPWRDNZ0		(1 << 1)
++#define OMAP2_PBIASLITEVMODE0		(1 << 0)
++
++/* CONTROL_PROG_IO1 bits */
++#define OMAP3630_PRG_SDMMC1_SPEEDCTRL	(1 << 20)
++
++/* CONTROL_IVA2_BOOTMOD bits */
++#define OMAP3_IVA2_BOOTMOD_SHIFT	0
++#define OMAP3_IVA2_BOOTMOD_MASK		(0xf << 0)
++#define OMAP3_IVA2_BOOTMOD_IDLE		(0x1 << 0)
++
++/* CONTROL_PADCONF_X bits */
++#define OMAP3_PADCONF_WAKEUPEVENT0	(1 << 15)
++#define OMAP3_PADCONF_WAKEUPENABLE0	(1 << 14)
++
++#define OMAP343X_SCRATCHPAD_ROM		(OMAP343X_CTRL_BASE + 0x860)
++#define OMAP343X_SCRATCHPAD		(OMAP343X_CTRL_BASE + 0x910)
++#define OMAP343X_SCRATCHPAD_ROM_OFFSET	0x19C
++
++/*
++ * CONTROL OMAP STATUS register to identify OMAP3 features
++ */
++#define OMAP3_CONTROL_OMAP_STATUS	0x044c
++
++#define OMAP3_SGX_SHIFT			13
++#define OMAP3_SGX_MASK			(3 << OMAP3_SGX_SHIFT)
++#define		FEAT_SGX_FULL		0
++#define		FEAT_SGX_HALF		1
++#define		FEAT_SGX_NONE		2
++
++#define OMAP3_IVA_SHIFT			12
++#define OMAP3_IVA_MASK			(1 << OMAP3_SGX_SHIFT)
++#define		FEAT_IVA		0
++#define		FEAT_IVA_NONE		1
++
++#define OMAP3_L2CACHE_SHIFT		10
++#define OMAP3_L2CACHE_MASK		(3 << OMAP3_L2CACHE_SHIFT)
++#define		FEAT_L2CACHE_NONE	0
++#define		FEAT_L2CACHE_64KB	1
++#define		FEAT_L2CACHE_128KB	2
++#define		FEAT_L2CACHE_256KB	3
++
++#define OMAP3_ISP_SHIFT			5
++#define OMAP3_ISP_MASK			(1<< OMAP3_ISP_SHIFT)
++#define		FEAT_ISP		0
++#define		FEAT_ISP_NONE		1
++
++#define OMAP3_NEON_SHIFT		4
++#define OMAP3_NEON_MASK			(1<< OMAP3_NEON_SHIFT)
++#define		FEAT_NEON		0
++#define		FEAT_NEON_NONE		1
++
++
++#ifndef __ASSEMBLY__
++#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) || \
++		defined(CONFIG_ARCH_OMAP4)
++extern void __iomem *omap_ctrl_base_get(void);
++extern u8 omap_ctrl_readb(u16 offset);
++extern u16 omap_ctrl_readw(u16 offset);
++extern u32 omap_ctrl_readl(u16 offset);
++extern void omap_ctrl_writeb(u8 val, u16 offset);
++extern void omap_ctrl_writew(u16 val, u16 offset);
++extern void omap_ctrl_writel(u32 val, u16 offset);
++
++extern void omap3_save_scratchpad_contents(void);
++extern void omap3_clear_scratchpad_contents(void);
++extern u32 *get_restore_pointer(void);
++extern u32 *get_es3_restore_pointer(void);
++extern u32 omap3_arm_context[128];
++extern void omap3_control_save_context(void);
++extern void omap3_control_restore_context(void);
++
++#else
++#define omap_ctrl_base_get()		0
++#define omap_ctrl_readb(x)		0
++#define omap_ctrl_readw(x)		0
++#define omap_ctrl_readl(x)		0
++#define omap_ctrl_writeb(x, y)		WARN_ON(1)
++#define omap_ctrl_writew(x, y)		WARN_ON(1)
++#define omap_ctrl_writel(x, y)		WARN_ON(1)
++#endif
++#endif	/* __ASSEMBLY__ */
++
++#endif /* __ASM_ARCH_CONTROL_H */
++
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/cpu.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/cpu.h	2010-08-08 12:56:44.000000000 +0200
+@@ -0,0 +1,516 @@
++/*
++ * arch/arm/plat-omap/include/mach/cpu.h
++ *
++ * OMAP cpu type detection
++ *
++ * Copyright (C) 2004, 2008 Nokia Corporation
++ *
++ * Copyright (C) 2009 Texas Instruments.
++ *
++ * Written by Tony Lindgren <[email protected]>
++ *
++ * Added OMAP4 specific defines - Santosh Shilimkar<[email protected]>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#ifndef __ASM_ARCH_OMAP_CPU_H
++#define __ASM_ARCH_OMAP_CPU_H
++
++#include <linux/bitops.h>
++
++/*
++ * Omap device type i.e. EMU/HS/TST/GP/BAD
++ */
++#define OMAP2_DEVICE_TYPE_TEST		0
++#define OMAP2_DEVICE_TYPE_EMU		1
++#define OMAP2_DEVICE_TYPE_SEC		2
++#define OMAP2_DEVICE_TYPE_GP		3
++#define OMAP2_DEVICE_TYPE_BAD		4
++
++int omap_type(void);
++
++struct omap_chip_id {
++	u8 oc;
++	u8 type;
++};
++
++#define OMAP_CHIP_INIT(x)	{ .oc = x }
++
++/*
++ * omap_rev bits:
++ * CPU id bits	(0730, 1510, 1710, 2422...)	[31:16]
++ * CPU revision	(See _REV_ defined in cpu.h)	[15:08]
++ * CPU class bits (15xx, 16xx, 24xx, 34xx...)	[07:00]
++ */
++unsigned int omap_rev(void);
++
++/*
++ * Define CPU revision bits
++ *
++ * Verbose meaning of the revision bits may be different for a silicon
++ * family. This difference can be handled separately.
++ */
++#define OMAP_REVBITS_00		0x00
++#define OMAP_REVBITS_10		0x10
++#define OMAP_REVBITS_20		0x20
++#define OMAP_REVBITS_30		0x30
++#define OMAP_REVBITS_40		0x40
++
++/*
++ * Get the CPU revision for OMAP devices
++ */
++#define GET_OMAP_REVISION()	((omap_rev() >> 8) & 0xff)
++
++/*
++ * Test if multicore OMAP support is needed
++ */
++#undef MULTI_OMAP1
++#undef MULTI_OMAP2
++#undef OMAP_NAME
++
++#ifdef CONFIG_ARCH_OMAP730
++# ifdef OMAP_NAME
++#  undef  MULTI_OMAP1
++#  define MULTI_OMAP1
++# else
++#  define OMAP_NAME omap730
++# endif
++#endif
++#ifdef CONFIG_ARCH_OMAP850
++# ifdef OMAP_NAME
++#  undef  MULTI_OMAP1
++#  define MULTI_OMAP1
++# else
++#  define OMAP_NAME omap850
++# endif
++#endif
++#ifdef CONFIG_ARCH_OMAP15XX
++# ifdef OMAP_NAME
++#  undef  MULTI_OMAP1
++#  define MULTI_OMAP1
++# else
++#  define OMAP_NAME omap1510
++# endif
++#endif
++#ifdef CONFIG_ARCH_OMAP16XX
++# ifdef OMAP_NAME
++#  undef  MULTI_OMAP1
++#  define MULTI_OMAP1
++# else
++#  define OMAP_NAME omap16xx
++# endif
++#endif
++#if (defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX))
++# if (defined(OMAP_NAME) || defined(MULTI_OMAP1))
++#  error "OMAP1 and OMAP2 can't be selected at the same time"
++# endif
++#endif
++#ifdef CONFIG_ARCH_OMAP2420
++# ifdef OMAP_NAME
++#  undef  MULTI_OMAP2
++#  define MULTI_OMAP2
++# else
++#  define OMAP_NAME omap2420
++# endif
++#endif
++#ifdef CONFIG_ARCH_OMAP2430
++# ifdef OMAP_NAME
++#  undef  MULTI_OMAP2
++#  define MULTI_OMAP2
++# else
++#  define OMAP_NAME omap2430
++# endif
++#endif
++#ifdef CONFIG_ARCH_OMAP3430
++# ifdef OMAP_NAME
++#  undef  MULTI_OMAP2
++#  define MULTI_OMAP2
++# else
++#  define OMAP_NAME omap3430
++# endif
++#endif
++
++/*
++ * Macros to group OMAP into cpu classes.
++ * These can be used in most places.
++ * cpu_is_omap7xx():	True for OMAP730, OMAP850
++ * cpu_is_omap15xx():	True for OMAP1510, OMAP5910 and OMAP310
++ * cpu_is_omap16xx():	True for OMAP1610, OMAP5912 and OMAP1710
++ * cpu_is_omap24xx():	True for OMAP2420, OMAP2422, OMAP2423, OMAP2430
++ * cpu_is_omap242x():	True for OMAP2420, OMAP2422, OMAP2423
++ * cpu_is_omap243x():	True for OMAP2430
++ * cpu_is_omap343x():	True for OMAP3430
++ */
++#define GET_OMAP_CLASS	(omap_rev() & 0xff)
++
++#define IS_OMAP_CLASS(class, id)			\
++static inline int is_omap ##class (void)		\
++{							\
++	return (GET_OMAP_CLASS == (id)) ? 1 : 0;	\
++}
++
++#define GET_OMAP_SUBCLASS	((omap_rev() >> 20) & 0x0fff)
++
++#define IS_OMAP_SUBCLASS(subclass, id)			\
++static inline int is_omap ##subclass (void)		\
++{							\
++	return (GET_OMAP_SUBCLASS == (id)) ? 1 : 0;	\
++}
++
++IS_OMAP_CLASS(7xx, 0x07)
++IS_OMAP_CLASS(15xx, 0x15)
++IS_OMAP_CLASS(16xx, 0x16)
++IS_OMAP_CLASS(24xx, 0x24)
++IS_OMAP_CLASS(34xx, 0x34)
++IS_OMAP_CLASS(44xx, 0x44)
++
++IS_OMAP_SUBCLASS(242x, 0x242)
++IS_OMAP_SUBCLASS(243x, 0x243)
++IS_OMAP_SUBCLASS(343x, 0x343)
++IS_OMAP_SUBCLASS(363x, 0x363)
++IS_OMAP_SUBCLASS(443x, 0x443)
++
++#define cpu_is_omap7xx()		0
++#define cpu_is_omap15xx()		0
++#define cpu_is_omap16xx()		0
++#define cpu_is_omap24xx()		0
++#define cpu_is_omap242x()		0
++#define cpu_is_omap243x()		0
++#define cpu_is_omap34xx()		0
++#define cpu_is_omap343x()		0
++#define cpu_is_omap44xx()		0
++#define cpu_is_omap443x()		0
++
++#if defined(MULTI_OMAP1)
++# if defined(CONFIG_ARCH_OMAP730)
++#  undef  cpu_is_omap7xx
++#  define cpu_is_omap7xx()		is_omap7xx()
++# endif
++# if defined(CONFIG_ARCH_OMAP850)
++#  undef  cpu_is_omap7xx
++#  define cpu_is_omap7xx()		is_omap7xx()
++# endif
++# if defined(CONFIG_ARCH_OMAP15XX)
++#  undef  cpu_is_omap15xx
++#  define cpu_is_omap15xx()		is_omap15xx()
++# endif
++# if defined(CONFIG_ARCH_OMAP16XX)
++#  undef  cpu_is_omap16xx
++#  define cpu_is_omap16xx()		is_omap16xx()
++# endif
++#else
++# if defined(CONFIG_ARCH_OMAP730)
++#  undef  cpu_is_omap7xx
++#  define cpu_is_omap7xx()		1
++# endif
++# if defined(CONFIG_ARCH_OMAP850)
++#  undef  cpu_is_omap7xx
++#  define cpu_is_omap7xx()		1
++# endif
++# if defined(CONFIG_ARCH_OMAP15XX)
++#  undef  cpu_is_omap15xx
++#  define cpu_is_omap15xx()		1
++# endif
++# if defined(CONFIG_ARCH_OMAP16XX)
++#  undef  cpu_is_omap16xx
++#  define cpu_is_omap16xx()		1
++# endif
++#endif
++
++#if defined(MULTI_OMAP2)
++# if defined(CONFIG_ARCH_OMAP24XX)
++#  undef  cpu_is_omap24xx
++#  undef  cpu_is_omap242x
++#  undef  cpu_is_omap243x
++#  define cpu_is_omap24xx()		is_omap24xx()
++#  define cpu_is_omap242x()		is_omap242x()
++#  define cpu_is_omap243x()		is_omap243x()
++# endif
++# if defined(CONFIG_ARCH_OMAP34XX)
++#  undef  cpu_is_omap34xx
++#  undef  cpu_is_omap343x
++#  define cpu_is_omap34xx()		is_omap34xx()
++#  define cpu_is_omap343x()		is_omap343x()
++# endif
++#else
++# if defined(CONFIG_ARCH_OMAP24XX)
++#  undef  cpu_is_omap24xx
++#  define cpu_is_omap24xx()		1
++# endif
++# if defined(CONFIG_ARCH_OMAP2420)
++#  undef  cpu_is_omap242x
++#  define cpu_is_omap242x()		1
++# endif
++# if defined(CONFIG_ARCH_OMAP2430)
++#  undef  cpu_is_omap243x
++#  define cpu_is_omap243x()		1
++# endif
++# if defined(CONFIG_ARCH_OMAP34XX)
++#  undef  cpu_is_omap34xx
++#  define cpu_is_omap34xx()		1
++# endif
++# if defined(CONFIG_ARCH_OMAP3430)
++#  undef  cpu_is_omap343x
++#  define cpu_is_omap343x()		1
++# endif
++#endif
++
++/*
++ * Macros to detect individual cpu types.
++ * These are only rarely needed.
++ * cpu_is_omap330():	True for OMAP330
++ * cpu_is_omap730():	True for OMAP730
++ * cpu_is_omap850():	True for OMAP850
++ * cpu_is_omap1510():	True for OMAP1510
++ * cpu_is_omap1610():	True for OMAP1610
++ * cpu_is_omap1611():	True for OMAP1611
++ * cpu_is_omap5912():	True for OMAP5912
++ * cpu_is_omap1621():	True for OMAP1621
++ * cpu_is_omap1710():	True for OMAP1710
++ * cpu_is_omap2420():	True for OMAP2420
++ * cpu_is_omap2422():	True for OMAP2422
++ * cpu_is_omap2423():	True for OMAP2423
++ * cpu_is_omap2430():	True for OMAP2430
++ * cpu_is_omap3430():	True for OMAP3430
++ * cpu_is_omap3505():	True for OMAP3505
++ * cpu_is_omap3517():	True for OMAP3517
++ */
++#define GET_OMAP_TYPE	((omap_rev() >> 16) & 0xffff)
++
++#define IS_OMAP_TYPE(type, id)				\
++static inline int is_omap ##type (void)			\
++{							\
++	return (GET_OMAP_TYPE == (id)) ? 1 : 0;		\
++}
++
++IS_OMAP_TYPE(310, 0x0310)
++IS_OMAP_TYPE(730, 0x0730)
++IS_OMAP_TYPE(850, 0x0850)
++IS_OMAP_TYPE(1510, 0x1510)
++IS_OMAP_TYPE(1610, 0x1610)
++IS_OMAP_TYPE(1611, 0x1611)
++IS_OMAP_TYPE(5912, 0x1611)
++IS_OMAP_TYPE(1621, 0x1621)
++IS_OMAP_TYPE(1710, 0x1710)
++IS_OMAP_TYPE(2420, 0x2420)
++IS_OMAP_TYPE(2422, 0x2422)
++IS_OMAP_TYPE(2423, 0x2423)
++IS_OMAP_TYPE(2430, 0x2430)
++IS_OMAP_TYPE(3430, 0x3430)
++IS_OMAP_TYPE(3505, 0x3505)
++IS_OMAP_TYPE(3517, 0x3517)
++
++#define cpu_is_omap310()		0
++#define cpu_is_omap730()		0
++#define cpu_is_omap850()		0
++#define cpu_is_omap1510()		0
++#define cpu_is_omap1610()		0
++#define cpu_is_omap5912()		0
++#define cpu_is_omap1611()		0
++#define cpu_is_omap1621()		0
++#define cpu_is_omap1710()		0
++#define cpu_is_omap2420()		0
++#define cpu_is_omap2422()		0
++#define cpu_is_omap2423()		0
++#define cpu_is_omap2430()		0
++#define cpu_is_omap3503()		0
++#define cpu_is_omap3515()		0
++#define cpu_is_omap3525()		0
++#define cpu_is_omap3530()		0
++#define cpu_is_omap3505()		0
++#define cpu_is_omap3517()		0
++#define cpu_is_omap3430()		0
++#define cpu_is_omap3630()		0
++
++/*
++ * Whether we have MULTI_OMAP1 or not, we still need to distinguish
++ * between 730 vs 850, 330 vs. 1510 and 1611B/5912 vs. 1710.
++ */
++
++#if defined(CONFIG_ARCH_OMAP730)
++# undef  cpu_is_omap730
++# define cpu_is_omap730()		is_omap730()
++#endif
++
++#if defined(CONFIG_ARCH_OMAP850)
++# undef  cpu_is_omap850
++# define cpu_is_omap850()		is_omap850()
++#endif
++
++#if defined(CONFIG_ARCH_OMAP15XX)
++# undef  cpu_is_omap310
++# undef  cpu_is_omap1510
++# define cpu_is_omap310()		is_omap310()
++# define cpu_is_omap1510()		is_omap1510()
++#endif
++
++#if defined(CONFIG_ARCH_OMAP16XX)
++# undef  cpu_is_omap1610
++# undef  cpu_is_omap1611
++# undef  cpu_is_omap5912
++# undef  cpu_is_omap1621
++# undef  cpu_is_omap1710
++# define cpu_is_omap1610()		is_omap1610()
++# define cpu_is_omap1611()		is_omap1611()
++# define cpu_is_omap5912()		is_omap5912()
++# define cpu_is_omap1621()		is_omap1621()
++# define cpu_is_omap1710()		is_omap1710()
++#endif
++
++#if defined(CONFIG_ARCH_OMAP24XX)
++# undef  cpu_is_omap2420
++# undef  cpu_is_omap2422
++# undef  cpu_is_omap2423
++# undef  cpu_is_omap2430
++# define cpu_is_omap2420()		is_omap2420()
++# define cpu_is_omap2422()		is_omap2422()
++# define cpu_is_omap2423()		is_omap2423()
++# define cpu_is_omap2430()		is_omap2430()
++#endif
++
++#if defined(CONFIG_ARCH_OMAP34XX)
++# undef cpu_is_omap3430
++# undef cpu_is_omap3503
++# undef cpu_is_omap3515
++# undef cpu_is_omap3525
++# undef cpu_is_omap3530
++# undef cpu_is_omap3505
++# undef cpu_is_omap3517
++# define cpu_is_omap3430()		is_omap3430()
++# define cpu_is_omap3503()		(cpu_is_omap3430() &&		\
++						(!omap3_has_iva()) &&	\
++						(!omap3_has_sgx()))
++# define cpu_is_omap3515()		(cpu_is_omap3430() &&		\
++						(!omap3_has_iva()) &&	\
++						(omap3_has_sgx()))
++# define cpu_is_omap3525()		(cpu_is_omap3430() &&		\
++						(!omap3_has_sgx()) &&	\
++						(omap3_has_iva()))
++# define cpu_is_omap3530()		(cpu_is_omap3430())
++# define cpu_is_omap3505()		is_omap3505()
++# define cpu_is_omap3517()		is_omap3517()
++# undef cpu_is_omap3630
++# define cpu_is_omap3630()		is_omap363x()
++#endif
++
++# if defined(CONFIG_ARCH_OMAP4)
++# undef cpu_is_omap44xx
++# undef cpu_is_omap443x
++# define cpu_is_omap44xx()		is_omap44xx()
++# define cpu_is_omap443x()		is_omap443x()
++# endif
++
++/* Macros to detect if we have OMAP1 or OMAP2 */
++#define cpu_class_is_omap1()	(cpu_is_omap7xx() || cpu_is_omap15xx() || \
++				cpu_is_omap16xx())
++#define cpu_class_is_omap2()	(cpu_is_omap24xx() || cpu_is_omap34xx() || \
++				cpu_is_omap44xx())
++
++/* Various silicon revisions for omap2 */
++#define OMAP242X_CLASS		0x24200024
++#define OMAP2420_REV_ES1_0	0x24200024
++#define OMAP2420_REV_ES2_0	0x24201024
++
++#define OMAP243X_CLASS		0x24300024
++#define OMAP2430_REV_ES1_0	0x24300024
++
++#define OMAP343X_CLASS		0x34300034
++#define OMAP3430_REV_ES1_0	0x34300034
++#define OMAP3430_REV_ES2_0	0x34301034
++#define OMAP3430_REV_ES2_1	0x34302034
++#define OMAP3430_REV_ES3_0	0x34303034
++#define OMAP3430_REV_ES3_1	0x34304034
++
++#define OMAP3630_REV_ES1_0	0x36300034
++
++#define OMAP35XX_CLASS		0x35000034
++#define OMAP3503_REV(v)		(OMAP35XX_CLASS | (0x3503 << 16) | (v << 8))
++#define OMAP3515_REV(v)		(OMAP35XX_CLASS | (0x3515 << 16) | (v << 8))
++#define OMAP3525_REV(v)		(OMAP35XX_CLASS | (0x3525 << 16) | (v << 8))
++#define OMAP3530_REV(v)		(OMAP35XX_CLASS | (0x3530 << 16) | (v << 8))
++#define OMAP3505_REV(v)		(OMAP35XX_CLASS | (0x3505 << 16) | (v << 8))
++#define OMAP3517_REV(v)		(OMAP35XX_CLASS | (0x3517 << 16) | (v << 8))
++
++#define OMAP443X_CLASS		0x44300044
++#define OMAP4430_REV_ES1_0	0x44300044
++
++/*
++ * omap_chip bits
++ *
++ * CHIP_IS_OMAP{2420,2430,3430} indicate that a particular structure is
++ * valid on all chips of that type.  CHIP_IS_OMAP3430ES{1,2} indicates
++ * something that is only valid on that particular ES revision.
++ *
++ * These bits may be ORed together to indicate structures that are
++ * available on multiple chip types.
++ *
++ * To test whether a particular structure matches the current OMAP chip type,
++ * use omap_chip_is().
++ *
++ */
++#define CHIP_IS_OMAP2420		(1 << 0)
++#define CHIP_IS_OMAP2430		(1 << 1)
++#define CHIP_IS_OMAP3430		(1 << 2)
++#define CHIP_IS_OMAP3430ES1		(1 << 3)
++#define CHIP_IS_OMAP3430ES2		(1 << 4)
++#define CHIP_IS_OMAP3430ES3_0		(1 << 5)
++#define CHIP_IS_OMAP3430ES3_1		(1 << 6)
++#define CHIP_IS_OMAP3630ES1		(1 << 7)
++
++#define CHIP_IS_OMAP24XX		(CHIP_IS_OMAP2420 | CHIP_IS_OMAP2430)
++
++/*
++ * "GE" here represents "greater than or equal to" in terms of ES
++ * levels.  So CHIP_GE_OMAP3430ES2 is intended to match all OMAP3430
++ * chips at ES2 and beyond, but not, for example, any OMAP lines after
++ * OMAP3.
++ */
++#define CHIP_GE_OMAP3430ES2		(CHIP_IS_OMAP3430ES2 | \
++					 CHIP_IS_OMAP3430ES3_0 | \
++					 CHIP_IS_OMAP3430ES3_1 | \
++					 CHIP_IS_OMAP3630ES1)
++#define CHIP_GE_OMAP3430ES3_1		(CHIP_IS_OMAP3430ES3_1 | \
++					 CHIP_IS_OMAP3630ES1)
++
++
++int omap_chip_is(struct omap_chip_id oci);
++void omap2_check_revision(void);
++
++/*
++ * Runtime detection of OMAP3 features
++ */
++extern u32 omap3_features;
++
++#define OMAP3_HAS_L2CACHE		BIT(0)
++#define OMAP3_HAS_IVA			BIT(1)
++#define OMAP3_HAS_SGX			BIT(2)
++#define OMAP3_HAS_NEON			BIT(3)
++#define OMAP3_HAS_ISP			BIT(4)
++
++#define OMAP3_HAS_FEATURE(feat,flag)			\
++static inline unsigned int omap3_has_ ##feat(void)	\
++{							\
++	return (omap3_features & OMAP3_HAS_ ##flag);	\
++}							\
++
++OMAP3_HAS_FEATURE(l2cache, L2CACHE)
++OMAP3_HAS_FEATURE(sgx, SGX)
++OMAP3_HAS_FEATURE(iva, IVA)
++OMAP3_HAS_FEATURE(neon, NEON)
++OMAP3_HAS_FEATURE(isp, ISP)
++
++#endif
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/display.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/display.h	2010-08-08 12:56:45.000000000 +0200
+@@ -0,0 +1,575 @@
++/*
++ * linux/include/asm-arm/arch-omap/display.h
++ *
++ * Copyright (C) 2008 Nokia Corporation
++ * Author: Tomi Valkeinen <[email protected]>
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 as published by
++ * the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
++ * more details.
++ *
++ * You should have received a copy of the GNU General Public License along with
++ * this program.  If not, see <http://www.gnu.org/licenses/>.
++ */
++
++#ifndef __ASM_ARCH_OMAP_DISPLAY_H
++#define __ASM_ARCH_OMAP_DISPLAY_H
++
++#include <linux/list.h>
++#include <linux/kobject.h>
++#include <linux/device.h>
++#include <asm/atomic.h>
++
++#define DISPC_IRQ_FRAMEDONE		(1 << 0)
++#define DISPC_IRQ_VSYNC			(1 << 1)
++#define DISPC_IRQ_EVSYNC_EVEN		(1 << 2)
++#define DISPC_IRQ_EVSYNC_ODD		(1 << 3)
++#define DISPC_IRQ_ACBIAS_COUNT_STAT	(1 << 4)
++#define DISPC_IRQ_PROG_LINE_NUM		(1 << 5)
++#define DISPC_IRQ_GFX_FIFO_UNDERFLOW	(1 << 6)
++#define DISPC_IRQ_GFX_END_WIN		(1 << 7)
++#define DISPC_IRQ_PAL_GAMMA_MASK	(1 << 8)
++#define DISPC_IRQ_OCP_ERR		(1 << 9)
++#define DISPC_IRQ_VID1_FIFO_UNDERFLOW	(1 << 10)
++#define DISPC_IRQ_VID1_END_WIN		(1 << 11)
++#define DISPC_IRQ_VID2_FIFO_UNDERFLOW	(1 << 12)
++#define DISPC_IRQ_VID2_END_WIN		(1 << 13)
++#define DISPC_IRQ_SYNC_LOST		(1 << 14)
++#define DISPC_IRQ_SYNC_LOST_DIGIT	(1 << 15)
++#define DISPC_IRQ_WAKEUP		(1 << 16)
++
++struct omap_dss_device;
++struct omap_overlay_manager;
++
++enum omap_display_type {
++	OMAP_DISPLAY_TYPE_NONE		= 0,
++	OMAP_DISPLAY_TYPE_DPI		= 1 << 0,
++	OMAP_DISPLAY_TYPE_DBI		= 1 << 1,
++	OMAP_DISPLAY_TYPE_SDI		= 1 << 2,
++	OMAP_DISPLAY_TYPE_DSI		= 1 << 3,
++	OMAP_DISPLAY_TYPE_VENC		= 1 << 4,
++};
++
++enum omap_plane {
++	OMAP_DSS_GFX	= 0,
++	OMAP_DSS_VIDEO1	= 1,
++	OMAP_DSS_VIDEO2	= 2
++};
++
++enum omap_channel {
++	OMAP_DSS_CHANNEL_LCD	= 0,
++	OMAP_DSS_CHANNEL_DIGIT	= 1,
++};
++
++enum omap_color_mode {
++	OMAP_DSS_COLOR_CLUT1	= 1 << 0,  /* BITMAP 1 */
++	OMAP_DSS_COLOR_CLUT2	= 1 << 1,  /* BITMAP 2 */
++	OMAP_DSS_COLOR_CLUT4	= 1 << 2,  /* BITMAP 4 */
++	OMAP_DSS_COLOR_CLUT8	= 1 << 3,  /* BITMAP 8 */
++	OMAP_DSS_COLOR_RGB12U	= 1 << 4,  /* RGB12, 16-bit container */
++	OMAP_DSS_COLOR_ARGB16	= 1 << 5,  /* ARGB16 */
++	OMAP_DSS_COLOR_RGB16	= 1 << 6,  /* RGB16 */
++	OMAP_DSS_COLOR_RGB24U	= 1 << 7,  /* RGB24, 32-bit container */
++	OMAP_DSS_COLOR_RGB24P	= 1 << 8,  /* RGB24, 24-bit container */
++	OMAP_DSS_COLOR_YUV2	= 1 << 9,  /* YUV2 4:2:2 co-sited */
++	OMAP_DSS_COLOR_UYVY	= 1 << 10, /* UYVY 4:2:2 co-sited */
++	OMAP_DSS_COLOR_ARGB32	= 1 << 11, /* ARGB32 */
++	OMAP_DSS_COLOR_RGBA32	= 1 << 12, /* RGBA32 */
++	OMAP_DSS_COLOR_RGBX32	= 1 << 13, /* RGBx32 */
++
++	OMAP_DSS_COLOR_GFX_OMAP2 =
++		OMAP_DSS_COLOR_CLUT1 | OMAP_DSS_COLOR_CLUT2 |
++		OMAP_DSS_COLOR_CLUT4 | OMAP_DSS_COLOR_CLUT8 |
++		OMAP_DSS_COLOR_RGB12U | OMAP_DSS_COLOR_RGB16 |
++		OMAP_DSS_COLOR_RGB24U | OMAP_DSS_COLOR_RGB24P,
++
++	OMAP_DSS_COLOR_VID_OMAP2 =
++		OMAP_DSS_COLOR_RGB16 | OMAP_DSS_COLOR_RGB24U |
++		OMAP_DSS_COLOR_RGB24P | OMAP_DSS_COLOR_YUV2 |
++		OMAP_DSS_COLOR_UYVY,
++
++	OMAP_DSS_COLOR_GFX_OMAP3 =
++		OMAP_DSS_COLOR_CLUT1 | OMAP_DSS_COLOR_CLUT2 |
++		OMAP_DSS_COLOR_CLUT4 | OMAP_DSS_COLOR_CLUT8 |
++		OMAP_DSS_COLOR_RGB12U | OMAP_DSS_COLOR_ARGB16 |
++		OMAP_DSS_COLOR_RGB16 | OMAP_DSS_COLOR_RGB24U |
++		OMAP_DSS_COLOR_RGB24P | OMAP_DSS_COLOR_ARGB32 |
++		OMAP_DSS_COLOR_RGBA32 | OMAP_DSS_COLOR_RGBX32,
++
++	OMAP_DSS_COLOR_VID1_OMAP3 =
++		OMAP_DSS_COLOR_RGB12U | OMAP_DSS_COLOR_RGB16 |
++		OMAP_DSS_COLOR_RGB24U | OMAP_DSS_COLOR_RGB24P |
++		OMAP_DSS_COLOR_YUV2 | OMAP_DSS_COLOR_UYVY,
++
++	OMAP_DSS_COLOR_VID2_OMAP3 =
++		OMAP_DSS_COLOR_RGB12U | OMAP_DSS_COLOR_ARGB16 |
++		OMAP_DSS_COLOR_RGB16 | OMAP_DSS_COLOR_RGB24U |
++		OMAP_DSS_COLOR_RGB24P | OMAP_DSS_COLOR_YUV2 |
++		OMAP_DSS_COLOR_UYVY | OMAP_DSS_COLOR_ARGB32 |
++		OMAP_DSS_COLOR_RGBA32 | OMAP_DSS_COLOR_RGBX32,
++};
++
++enum omap_lcd_display_type {
++	OMAP_DSS_LCD_DISPLAY_STN,
++	OMAP_DSS_LCD_DISPLAY_TFT,
++};
++
++enum omap_dss_load_mode {
++	OMAP_DSS_LOAD_CLUT_AND_FRAME	= 0,
++	OMAP_DSS_LOAD_CLUT_ONLY		= 1,
++	OMAP_DSS_LOAD_FRAME_ONLY	= 2,
++	OMAP_DSS_LOAD_CLUT_ONCE_FRAME	= 3,
++};
++
++enum omap_dss_trans_key_type {
++	OMAP_DSS_COLOR_KEY_GFX_DST = 0,
++	OMAP_DSS_COLOR_KEY_VID_SRC = 1,
++};
++
++enum omap_rfbi_te_mode {
++	OMAP_DSS_RFBI_TE_MODE_1 = 1,
++	OMAP_DSS_RFBI_TE_MODE_2 = 2,
++};
++
++enum omap_panel_config {
++	OMAP_DSS_LCD_IVS		= 1<<0,
++	OMAP_DSS_LCD_IHS		= 1<<1,
++	OMAP_DSS_LCD_IPC		= 1<<2,
++	OMAP_DSS_LCD_IEO		= 1<<3,
++	OMAP_DSS_LCD_RF			= 1<<4,
++	OMAP_DSS_LCD_ONOFF		= 1<<5,
++
++	OMAP_DSS_LCD_TFT		= 1<<20,
++};
++
++enum omap_dss_venc_type {
++	OMAP_DSS_VENC_TYPE_COMPOSITE,
++	OMAP_DSS_VENC_TYPE_SVIDEO,
++};
++
++enum omap_display_caps {
++	OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE	= 1 << 0,
++	OMAP_DSS_DISPLAY_CAP_TEAR_ELIM		= 1 << 1,
++};
++
++enum omap_dss_update_mode {
++	OMAP_DSS_UPDATE_DISABLED = 0,
++	OMAP_DSS_UPDATE_AUTO,
++	OMAP_DSS_UPDATE_MANUAL,
++};
++
++enum omap_dss_display_state {
++	OMAP_DSS_DISPLAY_DISABLED = 0,
++	OMAP_DSS_DISPLAY_ACTIVE,
++	OMAP_DSS_DISPLAY_SUSPENDED,
++};
++
++/* XXX perhaps this should be removed */
++enum omap_dss_overlay_managers {
++	OMAP_DSS_OVL_MGR_LCD,
++	OMAP_DSS_OVL_MGR_TV,
++};
++
++enum omap_dss_rotation_type {
++	OMAP_DSS_ROT_DMA = 0,
++	OMAP_DSS_ROT_VRFB = 1,
++};
++
++/* clockwise rotation angle */
++enum omap_dss_rotation_angle {
++	OMAP_DSS_ROT_0   = 0,
++	OMAP_DSS_ROT_90  = 1,
++	OMAP_DSS_ROT_180 = 2,
++	OMAP_DSS_ROT_270 = 3,
++};
++
++enum omap_overlay_caps {
++	OMAP_DSS_OVL_CAP_SCALE = 1 << 0,
++	OMAP_DSS_OVL_CAP_DISPC = 1 << 1,
++};
++
++enum omap_overlay_manager_caps {
++	OMAP_DSS_OVL_MGR_CAP_DISPC = 1 << 0,
++};
++
++/* RFBI */
++
++struct rfbi_timings {
++	int cs_on_time;
++	int cs_off_time;
++	int we_on_time;
++	int we_off_time;
++	int re_on_time;
++	int re_off_time;
++	int we_cycle_time;
++	int re_cycle_time;
++	int cs_pulse_width;
++	int access_time;
++
++	int clk_div;
++
++	u32 tim[5];             /* set by rfbi_convert_timings() */
++
++	int converted;
++};
++
++void omap_rfbi_write_command(const void *buf, u32 len);
++void omap_rfbi_read_data(void *buf, u32 len);
++void omap_rfbi_write_data(const void *buf, u32 len);
++void omap_rfbi_write_pixels(const void __iomem *buf, int scr_width,
++		u16 x, u16 y,
++		u16 w, u16 h);
++int omap_rfbi_enable_te(bool enable, unsigned line);
++int omap_rfbi_setup_te(enum omap_rfbi_te_mode mode,
++			     unsigned hs_pulse_time, unsigned vs_pulse_time,
++			     int hs_pol_inv, int vs_pol_inv, int extif_div);
++
++/* DSI */
++void dsi_bus_lock(void);
++void dsi_bus_unlock(void);
++int dsi_vc_dcs_write(int channel, u8 *data, int len);
++int dsi_vc_dcs_write_nosync(int channel, u8 *data, int len);
++int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen);
++int dsi_vc_set_max_rx_packet_size(int channel, u16 len);
++int dsi_vc_send_null(int channel);
++int dsi_vc_send_bta_sync(int channel);
++
++/* Board specific data */
++struct omap_dss_board_info {
++	int (*get_last_off_on_transaction_id)(struct device *dev);
++	int num_devices;
++	struct omap_dss_device **devices;
++	struct omap_dss_device *default_device;
++};
++
++struct omap_video_timings {
++	/* Unit: pixels */
++	u16 x_res;
++	/* Unit: pixels */
++	u16 y_res;
++	/* Unit: KHz */
++	u32 pixel_clock;
++	/* Unit: pixel clocks */
++	u16 hsw;	/* Horizontal synchronization pulse width */
++	/* Unit: pixel clocks */
++	u16 hfp;	/* Horizontal front porch */
++	/* Unit: pixel clocks */
++	u16 hbp;	/* Horizontal back porch */
++	/* Unit: line clocks */
++	u16 vsw;	/* Vertical synchronization pulse width */
++	/* Unit: line clocks */
++	u16 vfp;	/* Vertical front porch */
++	/* Unit: line clocks */
++	u16 vbp;	/* Vertical back porch */
++};
++
++#ifdef CONFIG_OMAP2_DSS_VENC
++/* Hardcoded timings for tv modes. Venc only uses these to
++ * identify the mode, and does not actually use the configs
++ * itself. However, the configs should be something that
++ * a normal monitor can also show */
++const extern struct omap_video_timings omap_dss_pal_timings;
++const extern struct omap_video_timings omap_dss_ntsc_timings;
++#endif
++
++struct omap_overlay_info {
++	bool enabled;
++
++	u32 paddr;
++	void __iomem *vaddr;
++	u16 screen_width;
++	u16 width;
++	u16 height;
++	enum omap_color_mode color_mode;
++	u8 rotation;
++	enum omap_dss_rotation_type rotation_type;
++	bool mirror;
++
++	u16 pos_x;
++	u16 pos_y;
++	u16 out_width;	/* if 0, out_width == width */
++	u16 out_height;	/* if 0, out_height == height */
++	u8 global_alpha;
++};
++
++struct omap_overlay {
++	struct kobject kobj;
++	struct list_head list;
++
++	/* static fields */
++	const char *name;
++	int id;
++	enum omap_color_mode supported_modes;
++	enum omap_overlay_caps caps;
++
++	/* dynamic fields */
++	struct omap_overlay_manager *manager;
++	struct omap_overlay_info info;
++
++	/* if true, info has been changed, but not applied() yet */
++	bool info_dirty;
++
++	int (*set_manager)(struct omap_overlay *ovl,
++		struct omap_overlay_manager *mgr);
++	int (*unset_manager)(struct omap_overlay *ovl);
++
++	int (*set_overlay_info)(struct omap_overlay *ovl,
++			struct omap_overlay_info *info);
++	void (*get_overlay_info)(struct omap_overlay *ovl,
++			struct omap_overlay_info *info);
++
++	int (*wait_for_go)(struct omap_overlay *ovl);
++};
++
++struct omap_overlay_manager_info {
++	u32 default_color;
++
++	enum omap_dss_trans_key_type trans_key_type;
++	u32 trans_key;
++	bool trans_enabled;
++
++	bool alpha_enabled;
++};
++
++struct omap_overlay_manager {
++	struct kobject kobj;
++	struct list_head list;
++
++	/* static fields */
++	const char *name;
++	int id;
++	enum omap_overlay_manager_caps caps;
++	int num_overlays;
++	struct omap_overlay **overlays;
++	enum omap_display_type supported_displays;
++
++	/* dynamic fields */
++	struct omap_dss_device *device;
++	struct omap_overlay_manager_info info;
++
++	bool device_changed;
++	/* if true, info has been changed but not applied() yet */
++	bool info_dirty;
++
++	int (*set_device)(struct omap_overlay_manager *mgr,
++		struct omap_dss_device *dssdev);
++	int (*unset_device)(struct omap_overlay_manager *mgr);
++
++	int (*set_manager_info)(struct omap_overlay_manager *mgr,
++			struct omap_overlay_manager_info *info);
++	void (*get_manager_info)(struct omap_overlay_manager *mgr,
++			struct omap_overlay_manager_info *info);
++
++	int (*apply)(struct omap_overlay_manager *mgr);
++	int (*wait_for_go)(struct omap_overlay_manager *mgr);
++};
++
++struct omap_dss_device {
++	struct device dev;
++
++	enum omap_display_type type;
++
++	union {
++		struct {
++			u8 data_lines;
++		} dpi;
++
++		struct {
++			u8 channel;
++			u8 data_lines;
++		} rfbi;
++
++		struct {
++			u8 datapairs;
++		} sdi;
++
++		struct {
++			u8 clk_lane;
++			u8 clk_pol;
++			u8 data1_lane;
++			u8 data1_pol;
++			u8 data2_lane;
++			u8 data2_pol;
++
++			struct {
++				u16 regn;
++				u16 regm;
++				u16 regm3;
++				u16 regm4;
++
++				u16 lp_clk_div;
++
++				u16 lck_div;
++				u16 pck_div;
++			} div;
++
++			bool ext_te;
++			u8 ext_te_gpio;
++		} dsi;
++
++		struct {
++			enum omap_dss_venc_type type;
++			bool invert_polarity;
++		} venc;
++	} phy;
++
++	struct {
++		struct omap_video_timings timings;
++
++		int acbi;	/* ac-bias pin transitions per interrupt */
++		/* Unit: line clocks */
++		int acb;	/* ac-bias pin frequency */
++
++		enum omap_panel_config config;
++
++		u8 recommended_bpp;
++
++		struct omap_dss_device *ctrl;
++	} panel;
++
++	struct {
++		u8 pixel_size;
++		struct rfbi_timings rfbi_timings;
++		struct omap_dss_device *panel;
++	} ctrl;
++
++	int reset_gpio;
++
++	int max_backlight_level;
++
++	const char *name;
++
++	/* used to match device to driver */
++	const char *driver_name;
++
++	void *data;
++
++	struct omap_dss_driver *driver;
++
++	/* helper variable for driver suspend/resume */
++	bool activate_after_resume;
++
++	enum omap_display_caps caps;
++
++	struct omap_overlay_manager *manager;
++
++	enum omap_dss_display_state state;
++
++	int (*enable)(struct omap_dss_device *dssdev);
++	void (*disable)(struct omap_dss_device *dssdev);
++
++	int (*suspend)(struct omap_dss_device *dssdev);
++	int (*resume)(struct omap_dss_device *dssdev);
++
++	void (*get_resolution)(struct omap_dss_device *dssdev,
++			u16 *xres, u16 *yres);
++	int (*get_recommended_bpp)(struct omap_dss_device *dssdev);
++
++	int (*check_timings)(struct omap_dss_device *dssdev,
++			struct omap_video_timings *timings);
++	void (*set_timings)(struct omap_dss_device *dssdev,
++			struct omap_video_timings *timings);
++	void (*get_timings)(struct omap_dss_device *dssdev,
++			struct omap_video_timings *timings);
++	int (*update)(struct omap_dss_device *dssdev,
++			       u16 x, u16 y, u16 w, u16 h);
++	int (*sync)(struct omap_dss_device *dssdev);
++	int (*wait_vsync)(struct omap_dss_device *dssdev);
++
++	int (*set_update_mode)(struct omap_dss_device *dssdev,
++			enum omap_dss_update_mode);
++	enum omap_dss_update_mode (*get_update_mode)
++		(struct omap_dss_device *dssdev);
++
++	int (*enable_te)(struct omap_dss_device *dssdev, bool enable);
++	int (*get_te)(struct omap_dss_device *dssdev);
++
++	u8 (*get_rotate)(struct omap_dss_device *dssdev);
++	int (*set_rotate)(struct omap_dss_device *dssdev, u8 rotate);
++
++	bool (*get_mirror)(struct omap_dss_device *dssdev);
++	int (*set_mirror)(struct omap_dss_device *dssdev, bool enable);
++
++	int (*run_test)(struct omap_dss_device *dssdev, int test);
++	int (*memory_read)(struct omap_dss_device *dssdev,
++			void *buf, size_t size,
++			u16 x, u16 y, u16 w, u16 h);
++
++	int (*set_wss)(struct omap_dss_device *dssdev, u32 wss);
++	u32 (*get_wss)(struct omap_dss_device *dssdev);
++
++	/* platform specific  */
++	int (*platform_enable)(struct omap_dss_device *dssdev);
++	void (*platform_disable)(struct omap_dss_device *dssdev);
++	int (*set_backlight)(struct omap_dss_device *dssdev, int level);
++	int (*get_backlight)(struct omap_dss_device *dssdev);
++};
++
++struct omap_dss_driver {
++	struct device_driver driver;
++
++	int (*probe)(struct omap_dss_device *);
++	void (*remove)(struct omap_dss_device *);
++
++	int (*enable)(struct omap_dss_device *display);
++	void (*disable)(struct omap_dss_device *display);
++	int (*suspend)(struct omap_dss_device *display);
++	int (*resume)(struct omap_dss_device *display);
++	int (*run_test)(struct omap_dss_device *display, int test);
++
++	void (*setup_update)(struct omap_dss_device *dssdev,
++			u16 x, u16 y, u16 w, u16 h);
++
++	int (*enable_te)(struct omap_dss_device *dssdev, bool enable);
++	int (*wait_for_te)(struct omap_dss_device *dssdev);
++
++	u8 (*get_rotate)(struct omap_dss_device *dssdev);
++	int (*set_rotate)(struct omap_dss_device *dssdev, u8 rotate);
++
++	bool (*get_mirror)(struct omap_dss_device *dssdev);
++	int (*set_mirror)(struct omap_dss_device *dssdev, bool enable);
++
++	int (*memory_read)(struct omap_dss_device *dssdev,
++			void *buf, size_t size,
++			u16 x, u16 y, u16 w, u16 h);
++};
++
++int omap_dss_register_driver(struct omap_dss_driver *);
++void omap_dss_unregister_driver(struct omap_dss_driver *);
++
++int omap_dss_register_device(struct omap_dss_device *);
++void omap_dss_unregister_device(struct omap_dss_device *);
++
++void omap_dss_get_device(struct omap_dss_device *dssdev);
++void omap_dss_put_device(struct omap_dss_device *dssdev);
++#define for_each_dss_dev(d) while ((d = omap_dss_get_next_device(d)) != NULL)
++struct omap_dss_device *omap_dss_get_next_device(struct omap_dss_device *from);
++struct omap_dss_device *omap_dss_find_device(void *data,
++		int (*match)(struct omap_dss_device *dssdev, void *data));
++
++int omap_dss_start_device(struct omap_dss_device *dssdev);
++void omap_dss_stop_device(struct omap_dss_device *dssdev);
++
++int omap_dss_get_num_overlay_managers(void);
++struct omap_overlay_manager *omap_dss_get_overlay_manager(int num);
++
++int omap_dss_get_num_overlays(void);
++struct omap_overlay *omap_dss_get_overlay(int num);
++
++typedef void (*omap_dispc_isr_t) (void *arg, u32 mask);
++int omap_dispc_register_isr(omap_dispc_isr_t isr, void *arg, u32 mask);
++int omap_dispc_unregister_isr(omap_dispc_isr_t isr, void *arg, u32 mask);
++
++int omap_dispc_wait_for_irq_timeout(u32 irqmask, unsigned long timeout);
++int omap_dispc_wait_for_irq_interruptible_timeout(u32 irqmask,
++		unsigned long timeout);
++
++#define to_dss_driver(x) container_of((x), struct omap_dss_driver, driver)
++#define to_dss_device(x) container_of((x), struct omap_dss_device, dev)
++
++#endif
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/dma.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/dma.h	2010-08-08 12:56:46.000000000 +0200
+@@ -0,0 +1,640 @@
++/*
++ *  arch/arm/plat-omap/include/mach/dma.h
++ *
++ *  Copyright (C) 2003 Nokia Corporation
++ *  Author: Juha Yrjölä <[email protected]>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++#ifndef __ASM_ARCH_DMA_H
++#define __ASM_ARCH_DMA_H
++
++/* Hardware registers for omap1 */
++#define OMAP1_DMA_BASE			(0xfffed800)
++
++#define OMAP1_DMA_GCR			0x400
++#define OMAP1_DMA_GSCR			0x404
++#define OMAP1_DMA_GRST			0x408
++#define OMAP1_DMA_HW_ID			0x442
++#define OMAP1_DMA_PCH2_ID		0x444
++#define OMAP1_DMA_PCH0_ID		0x446
++#define OMAP1_DMA_PCH1_ID		0x448
++#define OMAP1_DMA_PCHG_ID		0x44a
++#define OMAP1_DMA_PCHD_ID		0x44c
++#define OMAP1_DMA_CAPS_0_U		0x44e
++#define OMAP1_DMA_CAPS_0_L		0x450
++#define OMAP1_DMA_CAPS_1_U		0x452
++#define OMAP1_DMA_CAPS_1_L		0x454
++#define OMAP1_DMA_CAPS_2		0x456
++#define OMAP1_DMA_CAPS_3		0x458
++#define OMAP1_DMA_CAPS_4		0x45a
++#define OMAP1_DMA_PCH2_SR		0x460
++#define OMAP1_DMA_PCH0_SR		0x480
++#define OMAP1_DMA_PCH1_SR		0x482
++#define OMAP1_DMA_PCHD_SR		0x4c0
++
++/* Hardware registers for omap2 and omap3 */
++#define OMAP24XX_DMA4_BASE		(L4_24XX_BASE + 0x56000)
++#define OMAP34XX_DMA4_BASE		(L4_34XX_BASE + 0x56000)
++#define OMAP44XX_DMA4_BASE		(L4_44XX_BASE + 0x56000)
++
++#define OMAP_DMA4_REVISION		0x00
++#define OMAP_DMA4_GCR			0x78
++#define OMAP_DMA4_IRQSTATUS_L0		0x08
++#define OMAP_DMA4_IRQSTATUS_L1		0x0c
++#define OMAP_DMA4_IRQSTATUS_L2		0x10
++#define OMAP_DMA4_IRQSTATUS_L3		0x14
++#define OMAP_DMA4_IRQENABLE_L0		0x18
++#define OMAP_DMA4_IRQENABLE_L1		0x1c
++#define OMAP_DMA4_IRQENABLE_L2		0x20
++#define OMAP_DMA4_IRQENABLE_L3		0x24
++#define OMAP_DMA4_SYSSTATUS		0x28
++#define OMAP_DMA4_OCP_SYSCONFIG		0x2c
++#define OMAP_DMA4_CAPS_0		0x64
++#define OMAP_DMA4_CAPS_2		0x6c
++#define OMAP_DMA4_CAPS_3		0x70
++#define OMAP_DMA4_CAPS_4		0x74
++
++#define OMAP1_LOGICAL_DMA_CH_COUNT	17
++#define OMAP_DMA4_LOGICAL_DMA_CH_COUNT	32	/* REVISIT: Is this 32 + 2? */
++
++/* Common channel specific registers for omap1 */
++#define OMAP1_DMA_CH_BASE(n)		(0x40 * (n) + 0x00)
++#define OMAP1_DMA_CSDP(n)		(0x40 * (n) + 0x00)
++#define OMAP1_DMA_CCR(n)		(0x40 * (n) + 0x02)
++#define OMAP1_DMA_CICR(n)		(0x40 * (n) + 0x04)
++#define OMAP1_DMA_CSR(n)		(0x40 * (n) + 0x06)
++#define OMAP1_DMA_CEN(n)		(0x40 * (n) + 0x10)
++#define OMAP1_DMA_CFN(n)		(0x40 * (n) + 0x12)
++#define OMAP1_DMA_CSFI(n)		(0x40 * (n) + 0x14)
++#define OMAP1_DMA_CSEI(n)		(0x40 * (n) + 0x16)
++#define OMAP1_DMA_CPC(n)		(0x40 * (n) + 0x18)	/* 15xx only */
++#define OMAP1_DMA_CSAC(n)		(0x40 * (n) + 0x18)
++#define OMAP1_DMA_CDAC(n)		(0x40 * (n) + 0x1a)
++#define OMAP1_DMA_CDEI(n)		(0x40 * (n) + 0x1c)
++#define OMAP1_DMA_CDFI(n)		(0x40 * (n) + 0x1e)
++#define OMAP1_DMA_CLNK_CTRL(n)		(0x40 * (n) + 0x28)
++
++/* Common channel specific registers for omap2 */
++#define OMAP_DMA4_CH_BASE(n)		(0x60 * (n) + 0x80)
++#define OMAP_DMA4_CCR(n)		(0x60 * (n) + 0x80)
++#define OMAP_DMA4_CLNK_CTRL(n)		(0x60 * (n) + 0x84)
++#define OMAP_DMA4_CICR(n)		(0x60 * (n) + 0x88)
++#define OMAP_DMA4_CSR(n)		(0x60 * (n) + 0x8c)
++#define OMAP_DMA4_CSDP(n)		(0x60 * (n) + 0x90)
++#define OMAP_DMA4_CEN(n)		(0x60 * (n) + 0x94)
++#define OMAP_DMA4_CFN(n)		(0x60 * (n) + 0x98)
++#define OMAP_DMA4_CSEI(n)		(0x60 * (n) + 0xa4)
++#define OMAP_DMA4_CSFI(n)		(0x60 * (n) + 0xa8)
++#define OMAP_DMA4_CDEI(n)		(0x60 * (n) + 0xac)
++#define OMAP_DMA4_CDFI(n)		(0x60 * (n) + 0xb0)
++#define OMAP_DMA4_CSAC(n)		(0x60 * (n) + 0xb4)
++#define OMAP_DMA4_CDAC(n)		(0x60 * (n) + 0xb8)
++
++/* Channel specific registers only on omap1 */
++#define OMAP1_DMA_CSSA_L(n)		(0x40 * (n) + 0x08)
++#define OMAP1_DMA_CSSA_U(n)		(0x40 * (n) + 0x0a)
++#define OMAP1_DMA_CDSA_L(n)		(0x40 * (n) + 0x0c)
++#define OMAP1_DMA_CDSA_U(n)		(0x40 * (n) + 0x0e)
++#define OMAP1_DMA_COLOR_L(n)		(0x40 * (n) + 0x20)
++#define OMAP1_DMA_COLOR_U(n)		(0x40 * (n) + 0x22)
++#define OMAP1_DMA_CCR2(n)		(0x40 * (n) + 0x24)
++#define OMAP1_DMA_LCH_CTRL(n)		(0x40 * (n) + 0x2a)	/* not on 15xx */
++#define OMAP1_DMA_CCEN(n)		0
++#define OMAP1_DMA_CCFN(n)		0
++
++/* Channel specific registers only on omap2 */
++#define OMAP_DMA4_CSSA(n)		(0x60 * (n) + 0x9c)
++#define OMAP_DMA4_CDSA(n)		(0x60 * (n) + 0xa0)
++#define OMAP_DMA4_CCEN(n)		(0x60 * (n) + 0xbc)
++#define OMAP_DMA4_CCFN(n)		(0x60 * (n) + 0xc0)
++#define OMAP_DMA4_COLOR(n)		(0x60 * (n) + 0xc4)
++
++/* Additional registers available on OMAP4 */
++#define OMAP_DMA4_CDP(n)		(0x60 * (n) + 0xd0)
++#define OMAP_DMA4_CNDP(n)		(0x60 * (n) + 0xd4)
++#define OMAP_DMA4_CCDN(n)		(0x60 * (n) + 0xd8)
++
++/* Dummy defines to keep multi-omap compiles happy */
++#define OMAP1_DMA_REVISION		0
++#define OMAP1_DMA_IRQSTATUS_L0		0
++#define OMAP1_DMA_IRQENABLE_L0		0
++#define OMAP1_DMA_OCP_SYSCONFIG		0
++#define OMAP_DMA4_HW_ID			0
++#define OMAP_DMA4_CAPS_0_L		0
++#define OMAP_DMA4_CAPS_0_U		0
++#define OMAP_DMA4_CAPS_1_L		0
++#define OMAP_DMA4_CAPS_1_U		0
++#define OMAP_DMA4_GSCR			0
++#define OMAP_DMA4_CPC(n)		0
++
++#define OMAP_DMA4_LCH_CTRL(n)		0
++#define OMAP_DMA4_COLOR_L(n)		0
++#define OMAP_DMA4_COLOR_U(n)		0
++#define OMAP_DMA4_CCR2(n)		0
++#define OMAP1_DMA_CSSA(n)		0
++#define OMAP1_DMA_CDSA(n)		0
++#define OMAP_DMA4_CSSA_L(n)		0
++#define OMAP_DMA4_CSSA_U(n)		0
++#define OMAP_DMA4_CDSA_L(n)		0
++#define OMAP_DMA4_CDSA_U(n)		0
++#define OMAP1_DMA_COLOR(n)		0
++
++/*----------------------------------------------------------------------------*/
++
++/* DMA channels for omap1 */
++#define OMAP_DMA_NO_DEVICE		0
++#define OMAP_DMA_MCSI1_TX		1
++#define OMAP_DMA_MCSI1_RX		2
++#define OMAP_DMA_I2C_RX			3
++#define OMAP_DMA_I2C_TX			4
++#define OMAP_DMA_EXT_NDMA_REQ		5
++#define OMAP_DMA_EXT_NDMA_REQ2		6
++#define OMAP_DMA_UWIRE_TX		7
++#define OMAP_DMA_MCBSP1_TX		8
++#define OMAP_DMA_MCBSP1_RX		9
++#define OMAP_DMA_MCBSP3_TX		10
++#define OMAP_DMA_MCBSP3_RX		11
++#define OMAP_DMA_UART1_TX		12
++#define OMAP_DMA_UART1_RX		13
++#define OMAP_DMA_UART2_TX		14
++#define OMAP_DMA_UART2_RX		15
++#define OMAP_DMA_MCBSP2_TX		16
++#define OMAP_DMA_MCBSP2_RX		17
++#define OMAP_DMA_UART3_TX		18
++#define OMAP_DMA_UART3_RX		19
++#define OMAP_DMA_CAMERA_IF_RX		20
++#define OMAP_DMA_MMC_TX			21
++#define OMAP_DMA_MMC_RX			22
++#define OMAP_DMA_NAND			23
++#define OMAP_DMA_IRQ_LCD_LINE		24
++#define OMAP_DMA_MEMORY_STICK		25
++#define OMAP_DMA_USB_W2FC_RX0		26
++#define OMAP_DMA_USB_W2FC_RX1		27
++#define OMAP_DMA_USB_W2FC_RX2		28
++#define OMAP_DMA_USB_W2FC_TX0		29
++#define OMAP_DMA_USB_W2FC_TX1		30
++#define OMAP_DMA_USB_W2FC_TX2		31
++
++/* These are only for 1610 */
++#define OMAP_DMA_CRYPTO_DES_IN		32
++#define OMAP_DMA_SPI_TX			33
++#define OMAP_DMA_SPI_RX			34
++#define OMAP_DMA_CRYPTO_HASH		35
++#define OMAP_DMA_CCP_ATTN		36
++#define OMAP_DMA_CCP_FIFO_NOT_EMPTY	37
++#define OMAP_DMA_CMT_APE_TX_CHAN_0	38
++#define OMAP_DMA_CMT_APE_RV_CHAN_0	39
++#define OMAP_DMA_CMT_APE_TX_CHAN_1	40
++#define OMAP_DMA_CMT_APE_RV_CHAN_1	41
++#define OMAP_DMA_CMT_APE_TX_CHAN_2	42
++#define OMAP_DMA_CMT_APE_RV_CHAN_2	43
++#define OMAP_DMA_CMT_APE_TX_CHAN_3	44
++#define OMAP_DMA_CMT_APE_RV_CHAN_3	45
++#define OMAP_DMA_CMT_APE_TX_CHAN_4	46
++#define OMAP_DMA_CMT_APE_RV_CHAN_4	47
++#define OMAP_DMA_CMT_APE_TX_CHAN_5	48
++#define OMAP_DMA_CMT_APE_RV_CHAN_5	49
++#define OMAP_DMA_CMT_APE_TX_CHAN_6	50
++#define OMAP_DMA_CMT_APE_RV_CHAN_6	51
++#define OMAP_DMA_CMT_APE_TX_CHAN_7	52
++#define OMAP_DMA_CMT_APE_RV_CHAN_7	53
++#define OMAP_DMA_MMC2_TX		54
++#define OMAP_DMA_MMC2_RX		55
++#define OMAP_DMA_CRYPTO_DES_OUT		56
++
++/* DMA channels for 24xx */
++#define OMAP24XX_DMA_NO_DEVICE		0
++#define OMAP24XX_DMA_XTI_DMA		1	/* S_DMA_0 */
++#define OMAP24XX_DMA_EXT_DMAREQ0	2	/* S_DMA_1 */
++#define OMAP24XX_DMA_EXT_DMAREQ1	3	/* S_DMA_2 */
++#define OMAP24XX_DMA_GPMC		4	/* S_DMA_3 */
++#define OMAP24XX_DMA_GFX		5	/* S_DMA_4 */
++#define OMAP24XX_DMA_DSS		6	/* S_DMA_5 */
++#define OMAP242X_DMA_VLYNQ_TX		7	/* S_DMA_6 */
++#define OMAP24XX_DMA_EXT_DMAREQ2	7	/* S_DMA_6 */
++#define OMAP24XX_DMA_CWT		8	/* S_DMA_7 */
++#define OMAP24XX_DMA_AES_TX		9	/* S_DMA_8 */
++#define OMAP24XX_DMA_AES_RX		10	/* S_DMA_9 */
++#define OMAP24XX_DMA_DES_TX		11	/* S_DMA_10 */
++#define OMAP24XX_DMA_DES_RX		12	/* S_DMA_11 */
++#define OMAP24XX_DMA_SHA1MD5_RX		13	/* S_DMA_12 */
++#define OMAP34XX_DMA_SHA2MD5_RX		13	/* S_DMA_12 */
++#define OMAP242X_DMA_EXT_DMAREQ2	14	/* S_DMA_13 */
++#define OMAP242X_DMA_EXT_DMAREQ3	15	/* S_DMA_14 */
++#define OMAP242X_DMA_EXT_DMAREQ4	16	/* S_DMA_15 */
++#define OMAP242X_DMA_EAC_AC_RD		17	/* S_DMA_16 */
++#define OMAP242X_DMA_EAC_AC_WR		18	/* S_DMA_17 */
++#define OMAP242X_DMA_EAC_MD_UL_RD	19	/* S_DMA_18 */
++#define OMAP242X_DMA_EAC_MD_UL_WR	20	/* S_DMA_19 */
++#define OMAP242X_DMA_EAC_MD_DL_RD	21	/* S_DMA_20 */
++#define OMAP242X_DMA_EAC_MD_DL_WR	22	/* S_DMA_21 */
++#define OMAP242X_DMA_EAC_BT_UL_RD	23	/* S_DMA_22 */
++#define OMAP242X_DMA_EAC_BT_UL_WR	24	/* S_DMA_23 */
++#define OMAP242X_DMA_EAC_BT_DL_RD	25	/* S_DMA_24 */
++#define OMAP242X_DMA_EAC_BT_DL_WR	26	/* S_DMA_25 */
++#define OMAP243X_DMA_EXT_DMAREQ3	14	/* S_DMA_13 */
++#define OMAP24XX_DMA_SPI3_TX0		15	/* S_DMA_14 */
++#define OMAP24XX_DMA_SPI3_RX0		16	/* S_DMA_15 */
++#define OMAP24XX_DMA_MCBSP3_TX		17	/* S_DMA_16 */
++#define OMAP24XX_DMA_MCBSP3_RX		18	/* S_DMA_17 */
++#define OMAP24XX_DMA_MCBSP4_TX		19	/* S_DMA_18 */
++#define OMAP24XX_DMA_MCBSP4_RX		20	/* S_DMA_19 */
++#define OMAP24XX_DMA_MCBSP5_TX		21	/* S_DMA_20 */
++#define OMAP24XX_DMA_MCBSP5_RX		22	/* S_DMA_21 */
++#define OMAP24XX_DMA_SPI3_TX1		23	/* S_DMA_22 */
++#define OMAP24XX_DMA_SPI3_RX1		24	/* S_DMA_23 */
++#define OMAP243X_DMA_EXT_DMAREQ4	25	/* S_DMA_24 */
++#define OMAP243X_DMA_EXT_DMAREQ5	26	/* S_DMA_25 */
++#define OMAP34XX_DMA_I2C3_TX		25	/* S_DMA_24 */
++#define OMAP34XX_DMA_I2C3_RX		26	/* S_DMA_25 */
++#define OMAP24XX_DMA_I2C1_TX		27	/* S_DMA_26 */
++#define OMAP24XX_DMA_I2C1_RX		28	/* S_DMA_27 */
++#define OMAP24XX_DMA_I2C2_TX		29	/* S_DMA_28 */
++#define OMAP24XX_DMA_I2C2_RX		30	/* S_DMA_29 */
++#define OMAP24XX_DMA_MCBSP1_TX		31	/* S_DMA_30 */
++#define OMAP24XX_DMA_MCBSP1_RX		32	/* S_DMA_31 */
++#define OMAP24XX_DMA_MCBSP2_TX		33	/* S_DMA_32 */
++#define OMAP24XX_DMA_MCBSP2_RX		34	/* S_DMA_33 */
++#define OMAP24XX_DMA_SPI1_TX0		35	/* S_DMA_34 */
++#define OMAP24XX_DMA_SPI1_RX0		36	/* S_DMA_35 */
++#define OMAP24XX_DMA_SPI1_TX1		37	/* S_DMA_36 */
++#define OMAP24XX_DMA_SPI1_RX1		38	/* S_DMA_37 */
++#define OMAP24XX_DMA_SPI1_TX2		39	/* S_DMA_38 */
++#define OMAP24XX_DMA_SPI1_RX2		40	/* S_DMA_39 */
++#define OMAP24XX_DMA_SPI1_TX3		41	/* S_DMA_40 */
++#define OMAP24XX_DMA_SPI1_RX3		42	/* S_DMA_41 */
++#define OMAP24XX_DMA_SPI2_TX0		43	/* S_DMA_42 */
++#define OMAP24XX_DMA_SPI2_RX0		44	/* S_DMA_43 */
++#define OMAP24XX_DMA_SPI2_TX1		45	/* S_DMA_44 */
++#define OMAP24XX_DMA_SPI2_RX1		46	/* S_DMA_45 */
++#define OMAP24XX_DMA_MMC2_TX		47	/* S_DMA_46 */
++#define OMAP24XX_DMA_MMC2_RX		48	/* S_DMA_47 */
++#define OMAP24XX_DMA_UART1_TX		49	/* S_DMA_48 */
++#define OMAP24XX_DMA_UART1_RX		50	/* S_DMA_49 */
++#define OMAP24XX_DMA_UART2_TX		51	/* S_DMA_50 */
++#define OMAP24XX_DMA_UART2_RX		52	/* S_DMA_51 */
++#define OMAP24XX_DMA_UART3_TX		53	/* S_DMA_52 */
++#define OMAP24XX_DMA_UART3_RX		54	/* S_DMA_53 */
++#define OMAP24XX_DMA_USB_W2FC_TX0	55	/* S_DMA_54 */
++#define OMAP24XX_DMA_USB_W2FC_RX0	56	/* S_DMA_55 */
++#define OMAP24XX_DMA_USB_W2FC_TX1	57	/* S_DMA_56 */
++#define OMAP24XX_DMA_USB_W2FC_RX1	58	/* S_DMA_57 */
++#define OMAP24XX_DMA_USB_W2FC_TX2	59	/* S_DMA_58 */
++#define OMAP24XX_DMA_USB_W2FC_RX2	60	/* S_DMA_59 */
++#define OMAP24XX_DMA_MMC1_TX		61	/* S_DMA_60 */
++#define OMAP24XX_DMA_MMC1_RX		62	/* S_DMA_61 */
++#define OMAP24XX_DMA_MS			63	/* S_DMA_62 */
++#define OMAP242X_DMA_EXT_DMAREQ5	64	/* S_DMA_63 */
++#define OMAP243X_DMA_EXT_DMAREQ6	64	/* S_DMA_63 */
++#define OMAP34XX_DMA_EXT_DMAREQ3	64	/* S_DMA_63 */
++#define OMAP34XX_DMA_AES2_TX		65	/* S_DMA_64 */
++#define OMAP34XX_DMA_AES2_RX		66	/* S_DMA_65 */
++#define OMAP34XX_DMA_DES2_TX		67	/* S_DMA_66 */
++#define OMAP34XX_DMA_DES2_RX		68	/* S_DMA_67 */
++#define OMAP34XX_DMA_SHA1MD5_RX		69	/* S_DMA_68 */
++#define OMAP34XX_DMA_SPI4_TX0		70	/* S_DMA_69 */
++#define OMAP34XX_DMA_SPI4_RX0		71	/* S_DMA_70 */
++#define OMAP34XX_DSS_DMA0		72	/* S_DMA_71 */
++#define OMAP34XX_DSS_DMA1		73	/* S_DMA_72 */
++#define OMAP34XX_DSS_DMA2		74	/* S_DMA_73 */
++#define OMAP34XX_DSS_DMA3		75	/* S_DMA_74 */
++#define OMAP34XX_DMA_MMC3_TX		77	/* S_DMA_76 */
++#define OMAP34XX_DMA_MMC3_RX		78	/* S_DMA_77 */
++#define OMAP34XX_DMA_USIM_TX		79	/* S_DMA_78 */
++#define OMAP34XX_DMA_USIM_RX		80	/* S_DMA_79 */
++
++/* DMA request lines for 44xx */
++#define OMAP44XX_DMA_DSS_DISPC_REQ	6	/* S_DMA_5 */
++#define OMAP44XX_DMA_SYS_REQ2		7	/* S_DMA_6 */
++#define OMAP44XX_DMA_ISS_REQ1		9	/* S_DMA_8 */
++#define OMAP44XX_DMA_ISS_REQ2		10	/* S_DMA_9 */
++#define OMAP44XX_DMA_ISS_REQ3		12	/* S_DMA_11 */
++#define OMAP44XX_DMA_ISS_REQ4		13	/* S_DMA_12 */
++#define OMAP44XX_DMA_DSS_RFBI_REQ	14	/* S_DMA_13 */
++#define OMAP44XX_DMA_SPI3_TX0		15	/* S_DMA_14 */
++#define OMAP44XX_DMA_SPI3_RX0		16	/* S_DMA_15 */
++#define OMAP44XX_DMA_MCBSP2_TX		17	/* S_DMA_16 */
++#define OMAP44XX_DMA_MCBSP2_RX		18	/* S_DMA_17 */
++#define OMAP44XX_DMA_MCBSP3_TX		19	/* S_DMA_18 */
++#define OMAP44XX_DMA_MCBSP3_RX		20	/* S_DMA_19 */
++#define OMAP44XX_DMA_SPI3_TX1		23	/* S_DMA_22 */
++#define OMAP44XX_DMA_SPI3_RX1		24	/* S_DMA_23 */
++#define OMAP44XX_DMA_I2C3_TX		25	/* S_DMA_24 */
++#define OMAP44XX_DMA_I2C3_RX		26	/* S_DMA_25 */
++#define OMAP44XX_DMA_I2C1_TX		27	/* S_DMA_26 */
++#define OMAP44XX_DMA_I2C1_RX		28	/* S_DMA_27 */
++#define OMAP44XX_DMA_I2C2_TX		29	/* S_DMA_28 */
++#define OMAP44XX_DMA_I2C2_RX		30	/* S_DMA_29 */
++#define OMAP44XX_DMA_MCBSP4_TX		31	/* S_DMA_30 */
++#define OMAP44XX_DMA_MCBSP4_RX		32	/* S_DMA_31 */
++#define OMAP44XX_DMA_MCBSP1_TX		33	/* S_DMA_32 */
++#define OMAP44XX_DMA_MCBSP1_RX		34	/* S_DMA_33 */
++#define OMAP44XX_DMA_SPI1_TX0		35	/* S_DMA_34 */
++#define OMAP44XX_DMA_SPI1_RX0		36	/* S_DMA_35 */
++#define OMAP44XX_DMA_SPI1_TX1		37	/* S_DMA_36 */
++#define OMAP44XX_DMA_SPI1_RX1		38	/* S_DMA_37 */
++#define OMAP44XX_DMA_SPI1_TX2		39	/* S_DMA_38 */
++#define OMAP44XX_DMA_SPI1_RX2		40	/* S_DMA_39 */
++#define OMAP44XX_DMA_SPI1_TX3		41	/* S_DMA_40 */
++#define OMAP44XX_DMA_SPI1_RX3		42	/* S_DMA_41 */
++#define OMAP44XX_DMA_SPI2_TX0		43	/* S_DMA_42 */
++#define OMAP44XX_DMA_SPI2_RX0		44	/* S_DMA_43 */
++#define OMAP44XX_DMA_SPI2_TX1		45	/* S_DMA_44 */
++#define OMAP44XX_DMA_SPI2_RX1		46	/* S_DMA_45 */
++#define OMAP44XX_DMA_MMC2_TX		47	/* S_DMA_46 */
++#define OMAP44XX_DMA_MMC2_RX		48	/* S_DMA_47 */
++#define OMAP44XX_DMA_UART1_TX		49	/* S_DMA_48 */
++#define OMAP44XX_DMA_UART1_RX		50	/* S_DMA_49 */
++#define OMAP44XX_DMA_UART2_TX		51	/* S_DMA_50 */
++#define OMAP44XX_DMA_UART2_RX		52	/* S_DMA_51 */
++#define OMAP44XX_DMA_UART3_TX		53	/* S_DMA_52 */
++#define OMAP44XX_DMA_UART3_RX		54	/* S_DMA_53 */
++#define OMAP44XX_DMA_UART4_TX		55	/* S_DMA_54 */
++#define OMAP44XX_DMA_UART4_RX		56	/* S_DMA_55 */
++#define OMAP44XX_DMA_MMC4_TX		57	/* S_DMA_56 */
++#define OMAP44XX_DMA_MMC4_RX		58	/* S_DMA_57 */
++#define OMAP44XX_DMA_MMC5_TX		59	/* S_DMA_58 */
++#define OMAP44XX_DMA_MMC5_RX		60	/* S_DMA_59 */
++#define OMAP44XX_DMA_MMC1_TX		61	/* S_DMA_60 */
++#define OMAP44XX_DMA_MMC1_RX		62	/* S_DMA_61 */
++#define OMAP44XX_DMA_SYS_REQ3		64	/* S_DMA_63 */
++#define OMAP44XX_DMA_MCPDM_UP		65	/* S_DMA_64 */
++#define OMAP44XX_DMA_MCPDM_DL		66	/* S_DMA_65 */
++#define OMAP44XX_DMA_SPI4_TX0		70	/* S_DMA_69 */
++#define OMAP44XX_DMA_SPI4_RX0		71	/* S_DMA_70 */
++#define OMAP44XX_DMA_DSS_DSI1_REQ0	72	/* S_DMA_71 */
++#define OMAP44XX_DMA_DSS_DSI1_REQ1	73	/* S_DMA_72 */
++#define OMAP44XX_DMA_DSS_DSI1_REQ2	74	/* S_DMA_73 */
++#define OMAP44XX_DMA_DSS_DSI1_REQ3	75	/* S_DMA_74 */
++#define OMAP44XX_DMA_DSS_HDMI_REQ	76	/* S_DMA_75 */
++#define OMAP44XX_DMA_MMC3_TX		77	/* S_DMA_76 */
++#define OMAP44XX_DMA_MMC3_RX		78	/* S_DMA_77 */
++#define OMAP44XX_DMA_USIM_TX		79	/* S_DMA_78 */
++#define OMAP44XX_DMA_USIM_RX		80	/* S_DMA_79 */
++#define OMAP44XX_DMA_DSS_DSI2_REQ0	81	/* S_DMA_80 */
++#define OMAP44XX_DMA_DSS_DSI2_REQ1	82	/* S_DMA_81 */
++#define OMAP44XX_DMA_DSS_DSI2_REQ2	83	/* S_DMA_82 */
++#define OMAP44XX_DMA_DSS_DSI2_REQ3	84	/* S_DMA_83 */
++#define OMAP44XX_DMA_ABE_REQ0		101	/* S_DMA_100 */
++#define OMAP44XX_DMA_ABE_REQ1		102	/* S_DMA_101 */
++#define OMAP44XX_DMA_ABE_REQ2		103	/* S_DMA_102 */
++#define OMAP44XX_DMA_ABE_REQ3		104	/* S_DMA_103 */
++#define OMAP44XX_DMA_ABE_REQ4		105	/* S_DMA_104 */
++#define OMAP44XX_DMA_ABE_REQ5		106	/* S_DMA_105 */
++#define OMAP44XX_DMA_ABE_REQ6		107	/* S_DMA_106 */
++#define OMAP44XX_DMA_ABE_REQ7		108	/* S_DMA_107 */
++#define OMAP44XX_DMA_I2C4_TX		124	/* S_DMA_123 */
++#define OMAP44XX_DMA_I2C4_RX		125	/* S_DMA_124 */
++
++/*----------------------------------------------------------------------------*/
++
++#define OMAP1_DMA_TOUT_IRQ		(1 << 0)
++#define OMAP_DMA_DROP_IRQ		(1 << 1)
++#define OMAP_DMA_HALF_IRQ		(1 << 2)
++#define OMAP_DMA_FRAME_IRQ		(1 << 3)
++#define OMAP_DMA_LAST_IRQ		(1 << 4)
++#define OMAP_DMA_BLOCK_IRQ		(1 << 5)
++#define OMAP1_DMA_SYNC_IRQ		(1 << 6)
++#define OMAP2_DMA_PKT_IRQ		(1 << 7)
++#define OMAP2_DMA_TRANS_ERR_IRQ		(1 << 8)
++#define OMAP2_DMA_SECURE_ERR_IRQ	(1 << 9)
++#define OMAP2_DMA_SUPERVISOR_ERR_IRQ	(1 << 10)
++#define OMAP2_DMA_MISALIGNED_ERR_IRQ	(1 << 11)
++
++#define OMAP_DMA_CCR_EN			(1 << 7)
++
++#define OMAP_DMA_DATA_TYPE_S8		0x00
++#define OMAP_DMA_DATA_TYPE_S16		0x01
++#define OMAP_DMA_DATA_TYPE_S32		0x02
++
++#define OMAP_DMA_SYNC_ELEMENT		0x00
++#define OMAP_DMA_SYNC_FRAME		0x01
++#define OMAP_DMA_SYNC_BLOCK		0x02
++#define OMAP_DMA_SYNC_PACKET		0x03
++
++#define OMAP_DMA_SRC_SYNC		0x01
++#define OMAP_DMA_DST_SYNC		0x00
++
++#define OMAP_DMA_PORT_EMIFF		0x00
++#define OMAP_DMA_PORT_EMIFS		0x01
++#define OMAP_DMA_PORT_OCP_T1		0x02
++#define OMAP_DMA_PORT_TIPB		0x03
++#define OMAP_DMA_PORT_OCP_T2		0x04
++#define OMAP_DMA_PORT_MPUI		0x05
++
++#define OMAP_DMA_AMODE_CONSTANT		0x00
++#define OMAP_DMA_AMODE_POST_INC		0x01
++#define OMAP_DMA_AMODE_SINGLE_IDX	0x02
++#define OMAP_DMA_AMODE_DOUBLE_IDX	0x03
++
++#define DMA_DEFAULT_FIFO_DEPTH		0x10
++#define DMA_DEFAULT_ARB_RATE		0x01
++/* Pass THREAD_RESERVE ORed with THREAD_FIFO for tparams */
++#define DMA_THREAD_RESERVE_NORM		(0x00 << 12) /* Def */
++#define DMA_THREAD_RESERVE_ONET		(0x01 << 12)
++#define DMA_THREAD_RESERVE_TWOT		(0x02 << 12)
++#define DMA_THREAD_RESERVE_THREET	(0x03 << 12)
++#define DMA_THREAD_FIFO_NONE		(0x00 << 14) /* Def */
++#define DMA_THREAD_FIFO_75		(0x01 << 14)
++#define DMA_THREAD_FIFO_25		(0x02 << 14)
++#define DMA_THREAD_FIFO_50		(0x03 << 14)
++
++/* DMA4_OCP_SYSCONFIG bits */
++#define DMA_SYSCONFIG_MIDLEMODE_MASK		(3 << 12)
++#define DMA_SYSCONFIG_CLOCKACTIVITY_MASK	(3 << 8)
++#define DMA_SYSCONFIG_EMUFREE			(1 << 5)
++#define DMA_SYSCONFIG_SIDLEMODE_MASK		(3 << 3)
++#define DMA_SYSCONFIG_SOFTRESET			(1 << 2)
++#define DMA_SYSCONFIG_AUTOIDLE			(1 << 0)
++
++#define DMA_SYSCONFIG_MIDLEMODE(n)		((n) << 12)
++#define DMA_SYSCONFIG_SIDLEMODE(n)		((n) << 3)
++
++#define DMA_IDLEMODE_SMARTIDLE			0x2
++#define DMA_IDLEMODE_NO_IDLE			0x1
++#define DMA_IDLEMODE_FORCE_IDLE			0x0
++
++/* Chaining modes*/
++#ifndef CONFIG_ARCH_OMAP1
++#define OMAP_DMA_STATIC_CHAIN		0x1
++#define OMAP_DMA_DYNAMIC_CHAIN		0x2
++#define OMAP_DMA_CHAIN_ACTIVE		0x1
++#define OMAP_DMA_CHAIN_INACTIVE		0x0
++#endif
++
++#define DMA_CH_PRIO_HIGH		0x1
++#define DMA_CH_PRIO_LOW			0x0 /* Def */
++
++enum omap_dma_burst_mode {
++	OMAP_DMA_DATA_BURST_DIS = 0,
++	OMAP_DMA_DATA_BURST_4,
++	OMAP_DMA_DATA_BURST_8,
++	OMAP_DMA_DATA_BURST_16,
++};
++
++enum end_type {
++	OMAP_DMA_LITTLE_ENDIAN = 0,
++	OMAP_DMA_BIG_ENDIAN
++};
++
++enum omap_dma_color_mode {
++	OMAP_DMA_COLOR_DIS = 0,
++	OMAP_DMA_CONSTANT_FILL,
++	OMAP_DMA_TRANSPARENT_COPY
++};
++
++enum omap_dma_write_mode {
++	OMAP_DMA_WRITE_NON_POSTED = 0,
++	OMAP_DMA_WRITE_POSTED,
++	OMAP_DMA_WRITE_LAST_NON_POSTED
++};
++
++enum omap_dma_channel_mode {
++	OMAP_DMA_LCH_2D = 0,
++	OMAP_DMA_LCH_G,
++	OMAP_DMA_LCH_P,
++	OMAP_DMA_LCH_PD
++};
++
++struct omap_dma_channel_params {
++	int data_type;		/* data type 8,16,32 */
++	int elem_count;		/* number of elements in a frame */
++	int frame_count;	/* number of frames in a element */
++
++	int src_port;		/* Only on OMAP1 REVISIT: Is this needed? */
++	int src_amode;		/* constant, post increment, indexed,
++					double indexed */
++	unsigned long src_start;	/* source address : physical */
++	int src_ei;		/* source element index */
++	int src_fi;		/* source frame index */
++
++	int dst_port;		/* Only on OMAP1 REVISIT: Is this needed? */
++	int dst_amode;		/* constant, post increment, indexed,
++					double indexed */
++	unsigned long dst_start;	/* source address : physical */
++	int dst_ei;		/* source element index */
++	int dst_fi;		/* source frame index */
++
++	int trigger;		/* trigger attached if the channel is
++					synchronized */
++	int sync_mode;		/* sycn on element, frame , block or packet */
++	int src_or_dst_synch;	/* source synch(1) or destination synch(0) */
++
++	int ie;			/* interrupt enabled */
++
++	unsigned char read_prio;/* read priority */
++	unsigned char write_prio;/* write priority */
++
++#ifndef CONFIG_ARCH_OMAP1
++	enum omap_dma_burst_mode burst_mode; /* Burst mode 4/8/16 words */
++#endif
++};
++
++
++extern void omap_set_dma_priority(int lch, int dst_port, int priority);
++extern int omap_request_dma(int dev_id, const char *dev_name,
++			void (*callback)(int lch, u16 ch_status, void *data),
++			void *data, int *dma_ch);
++extern void omap_enable_dma_irq(int ch, u16 irq_bits);
++extern void omap_disable_dma_irq(int ch, u16 irq_bits);
++extern void omap_free_dma(int ch);
++extern void omap_start_dma(int lch);
++extern void omap_stop_dma(int lch);
++extern void omap_set_dma_transfer_params(int lch, int data_type,
++					 int elem_count, int frame_count,
++					 int sync_mode,
++					 int dma_trigger, int src_or_dst_synch);
++extern void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode,
++				    u32 color);
++extern void omap_set_dma_write_mode(int lch, enum omap_dma_write_mode mode);
++extern void omap_set_dma_channel_mode(int lch, enum omap_dma_channel_mode mode);
++
++extern void omap_set_dma_src_params(int lch, int src_port, int src_amode,
++				    unsigned long src_start,
++				    int src_ei, int src_fi);
++extern void omap_set_dma_src_index(int lch, int eidx, int fidx);
++extern void omap_set_dma_src_data_pack(int lch, int enable);
++extern void omap_set_dma_src_burst_mode(int lch,
++					enum omap_dma_burst_mode burst_mode);
++
++extern void omap_set_dma_dest_params(int lch, int dest_port, int dest_amode,
++				     unsigned long dest_start,
++				     int dst_ei, int dst_fi);
++extern void omap_set_dma_dest_index(int lch, int eidx, int fidx);
++extern void omap_set_dma_dest_data_pack(int lch, int enable);
++extern void omap_set_dma_dest_burst_mode(int lch,
++					 enum omap_dma_burst_mode burst_mode);
++
++extern void omap_set_dma_params(int lch,
++				struct omap_dma_channel_params *params);
++
++extern void omap_dma_link_lch(int lch_head, int lch_queue);
++extern void omap_dma_unlink_lch(int lch_head, int lch_queue);
++
++extern int omap_set_dma_callback(int lch,
++			void (*callback)(int lch, u16 ch_status, void *data),
++			void *data);
++extern dma_addr_t omap_get_dma_src_pos(int lch);
++extern dma_addr_t omap_get_dma_dst_pos(int lch);
++extern void omap_clear_dma(int lch);
++extern int omap_get_dma_active_status(int lch);
++extern int omap_dma_running(void);
++extern void omap_dma_set_global_params(int arb_rate, int max_fifo_depth,
++				       int tparams);
++extern int omap_dma_set_prio_lch(int lch, unsigned char read_prio,
++				 unsigned char write_prio);
++extern void omap_set_dma_dst_endian_type(int lch, enum end_type etype);
++extern void omap_set_dma_src_endian_type(int lch, enum end_type etype);
++extern int omap_get_dma_index(int lch, int *ei, int *fi);
++
++void omap_dma_global_context_save(void);
++void omap_dma_global_context_restore(void);
++
++extern void omap_dma_disable_irq(int lch);
++
++/* Chaining APIs */
++#ifndef CONFIG_ARCH_OMAP1
++extern int omap_request_dma_chain(int dev_id, const char *dev_name,
++				  void (*callback) (int lch, u16 ch_status,
++						    void *data),
++				  int *chain_id, int no_of_chans,
++				  int chain_mode,
++				  struct omap_dma_channel_params params);
++extern int omap_free_dma_chain(int chain_id);
++extern int omap_dma_chain_a_transfer(int chain_id, int src_start,
++				     int dest_start, int elem_count,
++				     int frame_count, void *callbk_data);
++extern int omap_start_dma_chain_transfers(int chain_id);
++extern int omap_stop_dma_chain_transfers(int chain_id);
++extern int omap_get_dma_chain_index(int chain_id, int *ei, int *fi);
++extern int omap_get_dma_chain_dst_pos(int chain_id);
++extern int omap_get_dma_chain_src_pos(int chain_id);
++
++extern int omap_modify_dma_chain_params(int chain_id,
++					struct omap_dma_channel_params params);
++extern int omap_dma_chain_status(int chain_id);
++#endif
++
++#if defined(CONFIG_ARCH_OMAP1) && defined(CONFIG_FB_OMAP)
++#include <mach/lcd_dma.h>
++#else
++static inline int omap_lcd_dma_running(void)
++{
++	return 0;
++}
++#endif
++
++#endif /* __ASM_ARCH_DMA_H */
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/dmtimer.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/dmtimer.h	2010-08-08 12:56:47.000000000 +0200
+@@ -0,0 +1,84 @@
++/*
++ * arch/arm/plat-omap/include/mach/dmtimer.h
++ *
++ * OMAP Dual-Mode Timers
++ *
++ * Copyright (C) 2005 Nokia Corporation
++ * Author: Lauri Leukkunen <[email protected]>
++ * PWM and clock framwork support by Timo Teras.
++ *
++ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ *
++ * 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.,
++ * 675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++
++#ifndef __ASM_ARCH_DMTIMER_H
++#define __ASM_ARCH_DMTIMER_H
++
++/* clock sources */
++#define OMAP_TIMER_SRC_SYS_CLK			0x00
++#define OMAP_TIMER_SRC_32_KHZ			0x01
++#define OMAP_TIMER_SRC_EXT_CLK			0x02
++
++/* timer interrupt enable bits */
++#define OMAP_TIMER_INT_CAPTURE			(1 << 2)
++#define OMAP_TIMER_INT_OVERFLOW			(1 << 1)
++#define OMAP_TIMER_INT_MATCH			(1 << 0)
++
++/* trigger types */
++#define OMAP_TIMER_TRIGGER_NONE			0x00
++#define OMAP_TIMER_TRIGGER_OVERFLOW		0x01
++#define OMAP_TIMER_TRIGGER_OVERFLOW_AND_COMPARE	0x02
++
++struct omap_dm_timer;
++struct clk;
++
++int omap_dm_timer_init(void);
++
++struct omap_dm_timer *omap_dm_timer_request(void);
++struct omap_dm_timer *omap_dm_timer_request_specific(int timer_id);
++void omap_dm_timer_free(struct omap_dm_timer *timer);
++void omap_dm_timer_enable(struct omap_dm_timer *timer);
++void omap_dm_timer_disable(struct omap_dm_timer *timer);
++
++int omap_dm_timer_get_irq(struct omap_dm_timer *timer);
++
++u32 omap_dm_timer_modify_idlect_mask(u32 inputmask);
++struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer);
++
++void omap_dm_timer_trigger(struct omap_dm_timer *timer);
++void omap_dm_timer_start(struct omap_dm_timer *timer);
++void omap_dm_timer_stop(struct omap_dm_timer *timer);
++
++int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source);
++void omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload, unsigned int value);
++void omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload, unsigned int value);
++void omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable, unsigned int match);
++void omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on, int toggle, int trigger);
++void omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, int prescaler);
++
++void omap_dm_timer_set_int_enable(struct omap_dm_timer *timer, unsigned int value);
++
++unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer);
++void omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value);
++unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer);
++void omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value);
++
++int omap_dm_timers_active(void);
++
++
++#endif /* __ASM_ARCH_DMTIMER_H */
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/dsp_common.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/dsp_common.h	2010-08-08 12:56:48.000000000 +0200
+@@ -0,0 +1,40 @@
++/*
++ * This file is part of OMAP DSP driver (DSP Gateway version 3.3.1)
++ *
++ * Copyright (C) 2004-2006 Nokia Corporation. All rights reserved.
++ *
++ * Contact: Toshihiro Kobayashi <[email protected]>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * version 2 as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
++ * 02110-1301 USA
++ *
++ */
++
++#ifndef ASM_ARCH_DSP_COMMON_H
++#define ASM_ARCH_DSP_COMMON_H
++
++#if defined(CONFIG_ARCH_OMAP1) && defined(CONFIG_OMAP_MMU_FWK)
++extern void omap_dsp_request_mpui(void);
++extern void omap_dsp_release_mpui(void);
++extern int omap_dsp_request_mem(void);
++extern int omap_dsp_release_mem(void);
++#else
++static inline int omap_dsp_request_mem(void)
++{
++	return 0;
++}
++#define omap_dsp_release_mem()	do {} while (0)
++#endif
++
++#endif /* ASM_ARCH_DSP_COMMON_H */
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/fpga.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/fpga.h	2010-08-08 12:56:49.000000000 +0200
+@@ -0,0 +1,197 @@
++/*
++ * arch/arm/plat-omap/include/mach/fpga.h
++ *
++ * Interrupt handler for OMAP-1510 FPGA
++ *
++ * Copyright (C) 2001 RidgeRun, Inc.
++ * Author: Greg Lonnon <[email protected]>
++ *
++ * Copyright (C) 2002 MontaVista Software, Inc.
++ *
++ * Separated FPGA interrupts from innovator1510.c and cleaned up for 2.6
++ * Copyright (C) 2004 Nokia Corporation by Tony Lindrgen <[email protected]>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#ifndef __ASM_ARCH_OMAP_FPGA_H
++#define __ASM_ARCH_OMAP_FPGA_H
++
++#if defined(CONFIG_MACH_OMAP_INNOVATOR) && defined(CONFIG_ARCH_OMAP15XX)
++extern void omap1510_fpga_init_irq(void);
++#else
++#define omap1510_fpga_init_irq()	(0)
++#endif
++
++#define fpga_read(reg)			__raw_readb(reg)
++#define fpga_write(val, reg)		__raw_writeb(val, reg)
++
++/*
++ * ---------------------------------------------------------------------------
++ *  H2/P2 Debug board FPGA
++ * ---------------------------------------------------------------------------
++ */
++/* maps in the FPGA registers and the ETHR registers */
++#define H2P2_DBG_FPGA_BASE		IOMEM(0xE8000000)	/* VA */
++#define H2P2_DBG_FPGA_SIZE		SZ_4K			/* SIZE */
++#define H2P2_DBG_FPGA_START		0x04000000		/* PA */
++
++#define H2P2_DBG_FPGA_ETHR_START	(H2P2_DBG_FPGA_START + 0x300)
++#define H2P2_DBG_FPGA_FPGA_REV		(H2P2_DBG_FPGA_BASE + 0x10)	/* FPGA Revision */
++#define H2P2_DBG_FPGA_BOARD_REV		(H2P2_DBG_FPGA_BASE + 0x12)	/* Board Revision */
++#define H2P2_DBG_FPGA_GPIO		(H2P2_DBG_FPGA_BASE + 0x14)	/* GPIO outputs */
++#define H2P2_DBG_FPGA_LEDS		(H2P2_DBG_FPGA_BASE + 0x16)	/* LEDs outputs */
++#define H2P2_DBG_FPGA_MISC_INPUTS	(H2P2_DBG_FPGA_BASE + 0x18)	/* Misc inputs */
++#define H2P2_DBG_FPGA_LAN_STATUS	(H2P2_DBG_FPGA_BASE + 0x1A)	/* LAN Status line */
++#define H2P2_DBG_FPGA_LAN_RESET		(H2P2_DBG_FPGA_BASE + 0x1C)	/* LAN Reset line */
++
++/* NOTE:  most boards don't have a static mapping for the FPGA ... */
++struct h2p2_dbg_fpga {
++	/* offset 0x00 */
++	u16		smc91x[8];
++	/* offset 0x10 */
++	u16		fpga_rev;
++	u16		board_rev;
++	u16		gpio_outputs;
++	u16		leds;
++	/* offset 0x18 */
++	u16		misc_inputs;
++	u16		lan_status;
++	u16		lan_reset;
++	u16		reserved0;
++	/* offset 0x20 */
++	u16		ps2_data;
++	u16		ps2_ctrl;
++	/* plus also 4 rs232 ports ... */
++};
++
++/* LEDs definition on debug board (16 LEDs, all physically green) */
++#define H2P2_DBG_FPGA_LED_GREEN		(1 << 15)
++#define H2P2_DBG_FPGA_LED_AMBER		(1 << 14)
++#define H2P2_DBG_FPGA_LED_RED		(1 << 13)
++#define H2P2_DBG_FPGA_LED_BLUE		(1 << 12)
++/*  cpu0 load-meter LEDs */
++#define H2P2_DBG_FPGA_LOAD_METER	(1 << 0)	// A bit of fun on our board ...
++#define H2P2_DBG_FPGA_LOAD_METER_SIZE	11
++#define H2P2_DBG_FPGA_LOAD_METER_MASK	((1 << H2P2_DBG_FPGA_LOAD_METER_SIZE) - 1)
++
++#define H2P2_DBG_FPGA_P2_LED_TIMER		(1 << 0)
++#define H2P2_DBG_FPGA_P2_LED_IDLE		(1 << 1)
++
++/*
++ * ---------------------------------------------------------------------------
++ *  OMAP-1510 FPGA
++ * ---------------------------------------------------------------------------
++ */
++#define OMAP1510_FPGA_BASE		IOMEM(0xE8000000)	/* VA */
++#define OMAP1510_FPGA_SIZE		SZ_4K
++#define OMAP1510_FPGA_START		0x08000000		/* PA */
++
++/* Revision */
++#define OMAP1510_FPGA_REV_LOW			(OMAP1510_FPGA_BASE + 0x0)
++#define OMAP1510_FPGA_REV_HIGH			(OMAP1510_FPGA_BASE + 0x1)
++
++#define OMAP1510_FPGA_LCD_PANEL_CONTROL		(OMAP1510_FPGA_BASE + 0x2)
++#define OMAP1510_FPGA_LED_DIGIT			(OMAP1510_FPGA_BASE + 0x3)
++#define INNOVATOR_FPGA_HID_SPI			(OMAP1510_FPGA_BASE + 0x4)
++#define OMAP1510_FPGA_POWER			(OMAP1510_FPGA_BASE + 0x5)
++
++/* Interrupt status */
++#define OMAP1510_FPGA_ISR_LO			(OMAP1510_FPGA_BASE + 0x6)
++#define OMAP1510_FPGA_ISR_HI			(OMAP1510_FPGA_BASE + 0x7)
++
++/* Interrupt mask */
++#define OMAP1510_FPGA_IMR_LO			(OMAP1510_FPGA_BASE + 0x8)
++#define OMAP1510_FPGA_IMR_HI			(OMAP1510_FPGA_BASE + 0x9)
++
++/* Reset registers */
++#define OMAP1510_FPGA_HOST_RESET		(OMAP1510_FPGA_BASE + 0xa)
++#define OMAP1510_FPGA_RST			(OMAP1510_FPGA_BASE + 0xb)
++
++#define OMAP1510_FPGA_AUDIO			(OMAP1510_FPGA_BASE + 0xc)
++#define OMAP1510_FPGA_DIP			(OMAP1510_FPGA_BASE + 0xe)
++#define OMAP1510_FPGA_FPGA_IO			(OMAP1510_FPGA_BASE + 0xf)
++#define OMAP1510_FPGA_UART1			(OMAP1510_FPGA_BASE + 0x14)
++#define OMAP1510_FPGA_UART2			(OMAP1510_FPGA_BASE + 0x15)
++#define OMAP1510_FPGA_OMAP1510_STATUS		(OMAP1510_FPGA_BASE + 0x16)
++#define OMAP1510_FPGA_BOARD_REV			(OMAP1510_FPGA_BASE + 0x18)
++#define OMAP1510P1_PPT_DATA			(OMAP1510_FPGA_BASE + 0x100)
++#define OMAP1510P1_PPT_STATUS			(OMAP1510_FPGA_BASE + 0x101)
++#define OMAP1510P1_PPT_CONTROL			(OMAP1510_FPGA_BASE + 0x102)
++
++#define OMAP1510_FPGA_TOUCHSCREEN		(OMAP1510_FPGA_BASE + 0x204)
++
++#define INNOVATOR_FPGA_INFO			(OMAP1510_FPGA_BASE + 0x205)
++#define INNOVATOR_FPGA_LCD_BRIGHT_LO		(OMAP1510_FPGA_BASE + 0x206)
++#define INNOVATOR_FPGA_LCD_BRIGHT_HI		(OMAP1510_FPGA_BASE + 0x207)
++#define INNOVATOR_FPGA_LED_GRN_LO		(OMAP1510_FPGA_BASE + 0x208)
++#define INNOVATOR_FPGA_LED_GRN_HI		(OMAP1510_FPGA_BASE + 0x209)
++#define INNOVATOR_FPGA_LED_RED_LO		(OMAP1510_FPGA_BASE + 0x20a)
++#define INNOVATOR_FPGA_LED_RED_HI		(OMAP1510_FPGA_BASE + 0x20b)
++#define INNOVATOR_FPGA_CAM_USB_CONTROL		(OMAP1510_FPGA_BASE + 0x20c)
++#define INNOVATOR_FPGA_EXP_CONTROL		(OMAP1510_FPGA_BASE + 0x20d)
++#define INNOVATOR_FPGA_ISR2			(OMAP1510_FPGA_BASE + 0x20e)
++#define INNOVATOR_FPGA_IMR2			(OMAP1510_FPGA_BASE + 0x210)
++
++#define OMAP1510_FPGA_ETHR_START		(OMAP1510_FPGA_START + 0x300)
++
++/*
++ * Power up Giga UART driver, turn on HID clock.
++ * Turn off BT power, since we're not using it and it
++ * draws power.
++ */
++#define OMAP1510_FPGA_RESET_VALUE		0x42
++
++#define OMAP1510_FPGA_PCR_IF_PD0		(1 << 7)
++#define OMAP1510_FPGA_PCR_COM2_EN		(1 << 6)
++#define OMAP1510_FPGA_PCR_COM1_EN		(1 << 5)
++#define OMAP1510_FPGA_PCR_EXP_PD0		(1 << 4)
++#define OMAP1510_FPGA_PCR_EXP_PD1		(1 << 3)
++#define OMAP1510_FPGA_PCR_48MHZ_CLK		(1 << 2)
++#define OMAP1510_FPGA_PCR_4MHZ_CLK		(1 << 1)
++#define OMAP1510_FPGA_PCR_RSRVD_BIT0		(1 << 0)
++
++/*
++ * Innovator/OMAP1510 FPGA HID register bit definitions
++ */
++#define OMAP1510_FPGA_HID_SCLK	(1<<0)	/* output */
++#define OMAP1510_FPGA_HID_MOSI	(1<<1)	/* output */
++#define OMAP1510_FPGA_HID_nSS	(1<<2)	/* output 0/1 chip idle/select */
++#define OMAP1510_FPGA_HID_nHSUS	(1<<3)	/* output 0/1 host active/suspended */
++#define OMAP1510_FPGA_HID_MISO	(1<<4)	/* input */
++#define OMAP1510_FPGA_HID_ATN	(1<<5)	/* input  0/1 chip idle/ATN */
++#define OMAP1510_FPGA_HID_rsrvd	(1<<6)
++#define OMAP1510_FPGA_HID_RESETn (1<<7)	/* output - 0/1 USAR reset/run */
++
++/* The FPGA IRQ is cascaded through GPIO_13 */
++#define OMAP1510_INT_FPGA		(IH_GPIO_BASE + 13)
++
++/* IRQ Numbers for interrupts muxed through the FPGA */
++#define OMAP1510_INT_FPGA_ATN		(OMAP_FPGA_IRQ_BASE + 0)
++#define OMAP1510_INT_FPGA_ACK		(OMAP_FPGA_IRQ_BASE + 1)
++#define OMAP1510_INT_FPGA2		(OMAP_FPGA_IRQ_BASE + 2)
++#define OMAP1510_INT_FPGA3		(OMAP_FPGA_IRQ_BASE + 3)
++#define OMAP1510_INT_FPGA4		(OMAP_FPGA_IRQ_BASE + 4)
++#define OMAP1510_INT_FPGA5		(OMAP_FPGA_IRQ_BASE + 5)
++#define OMAP1510_INT_FPGA6		(OMAP_FPGA_IRQ_BASE + 6)
++#define OMAP1510_INT_FPGA7		(OMAP_FPGA_IRQ_BASE + 7)
++#define OMAP1510_INT_FPGA8		(OMAP_FPGA_IRQ_BASE + 8)
++#define OMAP1510_INT_FPGA9		(OMAP_FPGA_IRQ_BASE + 9)
++#define OMAP1510_INT_FPGA10		(OMAP_FPGA_IRQ_BASE + 10)
++#define OMAP1510_INT_FPGA11		(OMAP_FPGA_IRQ_BASE + 11)
++#define OMAP1510_INT_FPGA12		(OMAP_FPGA_IRQ_BASE + 12)
++#define OMAP1510_INT_ETHER		(OMAP_FPGA_IRQ_BASE + 13)
++#define OMAP1510_INT_FPGAUART1		(OMAP_FPGA_IRQ_BASE + 14)
++#define OMAP1510_INT_FPGAUART2		(OMAP_FPGA_IRQ_BASE + 15)
++#define OMAP1510_INT_FPGA_TS		(OMAP_FPGA_IRQ_BASE + 16)
++#define OMAP1510_INT_FPGA17		(OMAP_FPGA_IRQ_BASE + 17)
++#define OMAP1510_INT_FPGA_CAM		(OMAP_FPGA_IRQ_BASE + 18)
++#define OMAP1510_INT_FPGA_RTC_A		(OMAP_FPGA_IRQ_BASE + 19)
++#define OMAP1510_INT_FPGA_RTC_B		(OMAP_FPGA_IRQ_BASE + 20)
++#define OMAP1510_INT_FPGA_CD		(OMAP_FPGA_IRQ_BASE + 21)
++#define OMAP1510_INT_FPGA22		(OMAP_FPGA_IRQ_BASE + 22)
++#define OMAP1510_INT_FPGA23		(OMAP_FPGA_IRQ_BASE + 23)
++
++#endif
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/gpio.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/gpio.h	2010-08-08 12:56:49.000000000 +0200
+@@ -0,0 +1,129 @@
++/*
++ * arch/arm/plat-omap/include/mach/gpio.h
++ *
++ * OMAP GPIO handling defines and functions
++ *
++ * Copyright (C) 2003-2005 Nokia Corporation
++ *
++ * Written by Juha Yrjölä <[email protected]>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#ifndef __ASM_ARCH_OMAP_GPIO_H
++#define __ASM_ARCH_OMAP_GPIO_H
++
++#include <linux/io.h>
++#include <mach/irqs.h>
++
++#define OMAP1_MPUIO_BASE			0xfffb5000
++
++#if (defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850))
++
++#define OMAP_MPUIO_INPUT_LATCH		0x00
++#define OMAP_MPUIO_OUTPUT		0x02
++#define OMAP_MPUIO_IO_CNTL		0x04
++#define OMAP_MPUIO_KBR_LATCH		0x08
++#define OMAP_MPUIO_KBC			0x0a
++#define OMAP_MPUIO_GPIO_EVENT_MODE	0x0c
++#define OMAP_MPUIO_GPIO_INT_EDGE	0x0e
++#define OMAP_MPUIO_KBD_INT		0x10
++#define OMAP_MPUIO_GPIO_INT		0x12
++#define OMAP_MPUIO_KBD_MASKIT		0x14
++#define OMAP_MPUIO_GPIO_MASKIT		0x16
++#define OMAP_MPUIO_GPIO_DEBOUNCING	0x18
++#define OMAP_MPUIO_LATCH		0x1a
++#else
++#define OMAP_MPUIO_INPUT_LATCH		0x00
++#define OMAP_MPUIO_OUTPUT		0x04
++#define OMAP_MPUIO_IO_CNTL		0x08
++#define OMAP_MPUIO_KBR_LATCH		0x10
++#define OMAP_MPUIO_KBC			0x14
++#define OMAP_MPUIO_GPIO_EVENT_MODE	0x18
++#define OMAP_MPUIO_GPIO_INT_EDGE	0x1c
++#define OMAP_MPUIO_KBD_INT		0x20
++#define OMAP_MPUIO_GPIO_INT		0x24
++#define OMAP_MPUIO_KBD_MASKIT		0x28
++#define OMAP_MPUIO_GPIO_MASKIT		0x2c
++#define OMAP_MPUIO_GPIO_DEBOUNCING	0x30
++#define OMAP_MPUIO_LATCH		0x34
++#endif
++
++#define OMAP34XX_NR_GPIOS		6
++
++#define OMAP_MPUIO(nr)		(OMAP_MAX_GPIO_LINES + (nr))
++#define OMAP_GPIO_IS_MPUIO(nr)	((nr) >= OMAP_MAX_GPIO_LINES)
++
++#define OMAP_GPIO_IRQ(nr)	(OMAP_GPIO_IS_MPUIO(nr) ? \
++				 IH_MPUIO_BASE + ((nr) & 0x0f) : \
++				 IH_GPIO_BASE + (nr))
++
++extern int omap_gpio_init(void);	/* Call from board init only */
++extern void omap2_gpio_prepare_for_retention(void);
++extern void omap2_gpio_resume_after_retention(void);
++extern void omap_set_gpio_debounce(int gpio, int enable);
++extern void omap_set_gpio_debounce_time(int gpio, int enable);
++extern void omap_gpio_save_context(void);
++extern void omap_gpio_restore_context(void);
++/*-------------------------------------------------------------------------*/
++
++/* Wrappers for "new style" GPIO calls, using the new infrastructure
++ * which lets us plug in FPGA, I2C, and other implementations.
++ * *
++ * The original OMAP-specfic calls should eventually be removed.
++ */
++
++#include <linux/errno.h>
++#include <asm-generic/gpio.h>
++
++static inline int gpio_get_value(unsigned gpio)
++{
++	return __gpio_get_value(gpio);
++}
++
++static inline void gpio_set_value(unsigned gpio, int value)
++{
++	__gpio_set_value(gpio, value);
++}
++
++static inline int gpio_cansleep(unsigned gpio)
++{
++	return __gpio_cansleep(gpio);
++}
++
++static inline int gpio_to_irq(unsigned gpio)
++{
++	return __gpio_to_irq(gpio);
++}
++
++static inline int irq_to_gpio(unsigned irq)
++{
++	int tmp;
++
++	/* omap1 SOC mpuio */
++	if (cpu_class_is_omap1() && (irq < (IH_MPUIO_BASE + 16)))
++		return (irq - IH_MPUIO_BASE) + OMAP_MAX_GPIO_LINES;
++
++	/* SOC gpio */
++	tmp = irq - IH_GPIO_BASE;
++	if (tmp < OMAP_MAX_GPIO_LINES)
++		return tmp;
++
++	/* we don't supply reverse mappings for non-SOC gpios */
++	return -EIO;
++}
++
++#endif
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/gpio-switch.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/gpio-switch.h	2010-08-08 12:56:50.000000000 +0200
+@@ -0,0 +1,54 @@
++/*
++ * GPIO switch definitions
++ *
++ * Copyright (C) 2006 Nokia Corporation
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#ifndef __ASM_ARCH_OMAP_GPIO_SWITCH_H
++#define __ASM_ARCH_OMAP_GPIO_SWITCH_H
++
++#include <linux/types.h>
++
++/* Cover:
++ *	high -> closed
++ *	low  -> open
++ * Connection:
++ *	high -> connected
++ *	low  -> disconnected
++ * Activity:
++ *	high -> active
++ *	low  -> inactive
++ *
++ */
++#define OMAP_GPIO_SWITCH_TYPE_COVER		0x0000
++#define OMAP_GPIO_SWITCH_TYPE_CONNECTION	0x0001
++#define OMAP_GPIO_SWITCH_TYPE_ACTIVITY		0x0002
++#define OMAP_GPIO_SWITCH_FLAG_INVERTED		0x0001
++#define OMAP_GPIO_SWITCH_FLAG_OUTPUT		0x0002
++
++struct omap_gpio_switch {
++	const char *name;
++	s16 gpio;
++	unsigned flags:4;
++	unsigned type:4;
++
++	/* Time in ms to debounce when transitioning from
++	 * inactive state to active state. */
++	u16 debounce_rising;
++	/* Same for transition from active to inactive state. */
++	u16 debounce_falling;
++
++	/* notify board-specific code about state changes */
++	void (* notify)(void *data, int state);
++	void *notify_data;
++};
++
++/* Call at init time only */
++extern void omap_register_gpio_switches(const struct omap_gpio_switch *tbl,
++					int count);
++
++#endif
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/gpmc.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/gpmc.h	2010-08-08 12:56:51.000000000 +0200
+@@ -0,0 +1,115 @@
++/*
++ * General-Purpose Memory Controller for OMAP2
++ *
++ * Copyright (C) 2005-2006 Nokia Corporation
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#ifndef __OMAP2_GPMC_H
++#define __OMAP2_GPMC_H
++
++/* Maximum Number of Chip Selects */
++#define GPMC_CS_NUM		8
++
++#define GPMC_CS_CONFIG1		0x00
++#define GPMC_CS_CONFIG2		0x04
++#define GPMC_CS_CONFIG3		0x08
++#define GPMC_CS_CONFIG4		0x0c
++#define GPMC_CS_CONFIG5		0x10
++#define GPMC_CS_CONFIG6		0x14
++#define GPMC_CS_CONFIG7		0x18
++#define GPMC_CS_NAND_COMMAND	0x1c
++#define GPMC_CS_NAND_ADDRESS	0x20
++#define GPMC_CS_NAND_DATA	0x24
++
++#define GPMC_CONFIG		0x50
++#define GPMC_STATUS		0x54
++
++#define GPMC_CONFIG1_WRAPBURST_SUPP     (1 << 31)
++#define GPMC_CONFIG1_READMULTIPLE_SUPP  (1 << 30)
++#define GPMC_CONFIG1_READTYPE_ASYNC     (0 << 29)
++#define GPMC_CONFIG1_READTYPE_SYNC      (1 << 29)
++#define GPMC_CONFIG1_WRITEMULTIPLE_SUPP (1 << 28)
++#define GPMC_CONFIG1_WRITETYPE_ASYNC    (0 << 27)
++#define GPMC_CONFIG1_WRITETYPE_SYNC     (1 << 27)
++#define GPMC_CONFIG1_CLKACTIVATIONTIME(val) ((val & 3) << 25)
++#define GPMC_CONFIG1_PAGE_LEN(val)      ((val & 3) << 23)
++#define GPMC_CONFIG1_WAIT_READ_MON      (1 << 22)
++#define GPMC_CONFIG1_WAIT_WRITE_MON     (1 << 21)
++#define GPMC_CONFIG1_WAIT_MON_IIME(val) ((val & 3) << 18)
++#define GPMC_CONFIG1_WAIT_PIN_SEL(val)  ((val & 3) << 16)
++#define GPMC_CONFIG1_DEVICESIZE(val)    ((val & 3) << 12)
++#define GPMC_CONFIG1_DEVICESIZE_16      GPMC_CONFIG1_DEVICESIZE(1)
++#define GPMC_CONFIG1_DEVICETYPE(val)    ((val & 3) << 10)
++#define GPMC_CONFIG1_DEVICETYPE_NOR     GPMC_CONFIG1_DEVICETYPE(0)
++#define GPMC_CONFIG1_DEVICETYPE_NAND    GPMC_CONFIG1_DEVICETYPE(2)
++#define GPMC_CONFIG1_MUXADDDATA         (1 << 9)
++#define GPMC_CONFIG1_TIME_PARA_GRAN     (1 << 4)
++#define GPMC_CONFIG1_FCLK_DIV(val)      (val & 3)
++#define GPMC_CONFIG1_FCLK_DIV2          (GPMC_CONFIG1_FCLK_DIV(1))
++#define GPMC_CONFIG1_FCLK_DIV3          (GPMC_CONFIG1_FCLK_DIV(2))
++#define GPMC_CONFIG1_FCLK_DIV4          (GPMC_CONFIG1_FCLK_DIV(3))
++#define GPMC_CONFIG7_CSVALID		(1 << 6)
++
++/*
++ * Note that all values in this struct are in nanoseconds, while
++ * the register values are in gpmc_fck cycles.
++ */
++struct gpmc_timings {
++	/* Minimum clock period for synchronous mode */
++	u16 sync_clk;
++
++	/* Chip-select signal timings corresponding to GPMC_CS_CONFIG2 */
++	u16 cs_on;		/* Assertion time */
++	u16 cs_rd_off;		/* Read deassertion time */
++	u16 cs_wr_off;		/* Write deassertion time */
++
++	/* ADV signal timings corresponding to GPMC_CONFIG3 */
++	u16 adv_on;		/* Assertion time */
++	u16 adv_rd_off;		/* Read deassertion time */
++	u16 adv_wr_off;		/* Write deassertion time */
++
++	/* WE signals timings corresponding to GPMC_CONFIG4 */
++	u16 we_on;		/* WE assertion time */
++	u16 we_off;		/* WE deassertion time */
++
++	/* OE signals timings corresponding to GPMC_CONFIG4 */
++	u16 oe_on;		/* OE assertion time */
++	u16 oe_off;		/* OE deassertion time */
++
++	/* Access time and cycle time timings corresponding to GPMC_CONFIG5 */
++	u16 page_burst_access;	/* Multiple access word delay */
++	u16 access;		/* Start-cycle to first data valid delay */
++	u16 rd_cycle;		/* Total read cycle time */
++	u16 wr_cycle;		/* Total write cycle time */
++
++	/* The following are only on OMAP3430 */
++	u16 wr_access;		/* WRACCESSTIME */
++	u16 wr_data_mux_bus;	/* WRDATAONADMUXBUS */
++};
++
++extern unsigned int gpmc_ns_to_ticks(unsigned int time_ns);
++extern unsigned int gpmc_ticks_to_ns(unsigned int ticks);
++extern unsigned int gpmc_round_ns_to_ticks(unsigned int time_ns);
++extern unsigned long gpmc_get_fclk_period(void);
++
++extern void gpmc_cs_write_reg(int cs, int idx, u32 val);
++extern u32 gpmc_cs_read_reg(int cs, int idx);
++extern int gpmc_cs_calc_divider(int cs, unsigned int sync_clk);
++extern int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t);
++extern int gpmc_cs_request(int cs, unsigned long size, unsigned long *base);
++extern void gpmc_cs_free(int cs);
++extern int gpmc_cs_set_reserved(int cs, int reserved);
++extern int gpmc_cs_reserved(int cs);
++extern int gpmc_prefetch_enable(int cs, int dma_mode,
++					unsigned int u32_count, int is_write);
++extern void gpmc_prefetch_reset(void);
++extern int gpmc_prefetch_status(void);
++extern void omap3_gpmc_save_context(void);
++extern void omap3_gpmc_restore_context(void);
++extern void __init gpmc_init(void);
++
++#endif
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/gpmc-smc91x.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/gpmc-smc91x.h	2010-08-08 12:56:51.000000000 +0200
+@@ -0,0 +1,42 @@
++/*
++ * arch/arm/plat-omap/include/mach/gpmc-smc91x.h
++ *
++ * Copyright (C) 2009 Nokia Corporation
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#ifndef __ASM_ARCH_OMAP_GPMC_SMC91X_H__
++
++#define GPMC_TIMINGS_SMC91C96	(1 << 4)
++#define GPMC_MUX_ADD_DATA	(1 << 5) /* GPMC_CONFIG1_MUXADDDATA */
++#define GPMC_READ_MON		(1 << 6) /* GPMC_CONFIG1_WAIT_READ_MON */
++#define GPMC_WRITE_MON		(1 << 7) /* GPMC_CONFIG1_WAIT_WRITE_MON */
++
++struct omap_smc91x_platform_data {
++	int	cs;
++	int	gpio_irq;
++	int	gpio_pwrdwn;
++	int	gpio_reset;
++	int	wait_pin;	/* Optional GPMC_CONFIG1_WAITPINSELECT */
++	u32	flags;
++	int	(*retime)(void);
++};
++
++#if defined(CONFIG_SMC91X) || \
++	defined(CONFIG_SMC91X_MODULE)
++
++extern void gpmc_smc91x_init(struct omap_smc91x_platform_data *d);
++
++#else
++
++#define board_smc91x_data	NULL
++
++static inline void gpmc_smc91x_init(struct omap_smc91x_platform_data *d)
++{
++}
++
++#endif
++#endif
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/hardware.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/hardware.h	2010-08-08 12:56:52.000000000 +0200
+@@ -0,0 +1,290 @@
++/*
++ * arch/arm/plat-omap/include/mach/hardware.h
++ *
++ * Hardware definitions for TI OMAP processors and boards
++ *
++ * NOTE: Please put device driver specific defines into a separate header
++ *	 file for each driver.
++ *
++ * Copyright (C) 2001 RidgeRun, Inc.
++ * Author: RidgeRun, Inc. Greg Lonnon <[email protected]>
++ *
++ * Reorganized for Linux-2.6 by Tony Lindgren <[email protected]>
++ *                          and Dirk Behme <[email protected]>
++ *
++ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ *
++ * 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.,
++ * 675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++
++#ifndef __ASM_ARCH_OMAP_HARDWARE_H
++#define __ASM_ARCH_OMAP_HARDWARE_H
++
++#include <asm/sizes.h>
++#ifndef __ASSEMBLER__
++#include <asm/types.h>
++#include <plat/cpu.h>
++#endif
++#include <plat/serial.h>
++
++/*
++ * ---------------------------------------------------------------------------
++ * Common definitions for all OMAP processors
++ * NOTE: Put all processor or board specific parts to the special header
++ *	 files.
++ * ---------------------------------------------------------------------------
++ */
++
++/*
++ * ----------------------------------------------------------------------------
++ * Timers
++ * ----------------------------------------------------------------------------
++ */
++#define OMAP_MPU_TIMER1_BASE	(0xfffec500)
++#define OMAP_MPU_TIMER2_BASE	(0xfffec600)
++#define OMAP_MPU_TIMER3_BASE	(0xfffec700)
++#define MPU_TIMER_FREE		(1 << 6)
++#define MPU_TIMER_CLOCK_ENABLE	(1 << 5)
++#define MPU_TIMER_AR		(1 << 1)
++#define MPU_TIMER_ST		(1 << 0)
++
++/*
++ * ----------------------------------------------------------------------------
++ * Clocks
++ * ----------------------------------------------------------------------------
++ */
++#define CLKGEN_REG_BASE		(0xfffece00)
++#define ARM_CKCTL		(CLKGEN_REG_BASE + 0x0)
++#define ARM_IDLECT1		(CLKGEN_REG_BASE + 0x4)
++#define ARM_IDLECT2		(CLKGEN_REG_BASE + 0x8)
++#define ARM_EWUPCT		(CLKGEN_REG_BASE + 0xC)
++#define ARM_RSTCT1		(CLKGEN_REG_BASE + 0x10)
++#define ARM_RSTCT2		(CLKGEN_REG_BASE + 0x14)
++#define ARM_SYSST		(CLKGEN_REG_BASE + 0x18)
++#define ARM_IDLECT3		(CLKGEN_REG_BASE + 0x24)
++
++#define CK_RATEF		1
++#define CK_IDLEF		2
++#define CK_ENABLEF		4
++#define CK_SELECTF		8
++#define SETARM_IDLE_SHIFT
++
++/* DPLL control registers */
++#define DPLL_CTL		(0xfffecf00)
++
++/* DSP clock control. Must use __raw_readw() and __raw_writew() with these */
++#define DSP_CONFIG_REG_BASE     IOMEM(0xe1008000)
++#define DSP_CKCTL		(DSP_CONFIG_REG_BASE + 0x0)
++#define DSP_IDLECT1		(DSP_CONFIG_REG_BASE + 0x4)
++#define DSP_IDLECT2		(DSP_CONFIG_REG_BASE + 0x8)
++#define DSP_RSTCT2		(DSP_CONFIG_REG_BASE + 0x14)
++
++/*
++ * ---------------------------------------------------------------------------
++ * UPLD
++ * ---------------------------------------------------------------------------
++ */
++#define ULPD_REG_BASE		(0xfffe0800)
++#define ULPD_IT_STATUS		(ULPD_REG_BASE + 0x14)
++#define ULPD_SETUP_ANALOG_CELL_3	(ULPD_REG_BASE + 0x24)
++#define ULPD_CLOCK_CTRL		(ULPD_REG_BASE + 0x30)
++#	define DIS_USB_PVCI_CLK		(1 << 5)	/* no USB/FAC synch */
++#	define USB_MCLK_EN		(1 << 4)	/* enable W4_USB_CLKO */
++#define ULPD_SOFT_REQ		(ULPD_REG_BASE + 0x34)
++#	define SOFT_UDC_REQ		(1 << 4)
++#	define SOFT_USB_CLK_REQ		(1 << 3)
++#	define SOFT_DPLL_REQ		(1 << 0)
++#define ULPD_DPLL_CTRL		(ULPD_REG_BASE + 0x3c)
++#define ULPD_STATUS_REQ		(ULPD_REG_BASE + 0x40)
++#define ULPD_APLL_CTRL		(ULPD_REG_BASE + 0x4c)
++#define ULPD_POWER_CTRL		(ULPD_REG_BASE + 0x50)
++#define ULPD_SOFT_DISABLE_REQ_REG	(ULPD_REG_BASE + 0x68)
++#	define DIS_MMC2_DPLL_REQ	(1 << 11)
++#	define DIS_MMC1_DPLL_REQ	(1 << 10)
++#	define DIS_UART3_DPLL_REQ	(1 << 9)
++#	define DIS_UART2_DPLL_REQ	(1 << 8)
++#	define DIS_UART1_DPLL_REQ	(1 << 7)
++#	define DIS_USB_HOST_DPLL_REQ	(1 << 6)
++#define ULPD_SDW_CLK_DIV_CTRL_SEL	(ULPD_REG_BASE + 0x74)
++#define ULPD_CAM_CLK_CTRL	(ULPD_REG_BASE + 0x7c)
++
++/*
++ * ---------------------------------------------------------------------------
++ * Watchdog timer
++ * ---------------------------------------------------------------------------
++ */
++
++/* Watchdog timer within the OMAP3.2 gigacell */
++#define OMAP_MPU_WATCHDOG_BASE	(0xfffec800)
++#define OMAP_WDT_TIMER		(OMAP_MPU_WATCHDOG_BASE + 0x0)
++#define OMAP_WDT_LOAD_TIM	(OMAP_MPU_WATCHDOG_BASE + 0x4)
++#define OMAP_WDT_READ_TIM	(OMAP_MPU_WATCHDOG_BASE + 0x4)
++#define OMAP_WDT_TIMER_MODE	(OMAP_MPU_WATCHDOG_BASE + 0x8)
++
++/*
++ * ---------------------------------------------------------------------------
++ * Interrupts
++ * ---------------------------------------------------------------------------
++ */
++#ifdef CONFIG_ARCH_OMAP1
++
++/*
++ * XXX: These probably want to be moved to arch/arm/mach-omap/omap1/irq.c
++ * or something similar.. -- PFM.
++ */
++
++#define OMAP_IH1_BASE		0xfffecb00
++#define OMAP_IH2_BASE		0xfffe0000
++
++#define OMAP_IH1_ITR		(OMAP_IH1_BASE + 0x00)
++#define OMAP_IH1_MIR		(OMAP_IH1_BASE + 0x04)
++#define OMAP_IH1_SIR_IRQ	(OMAP_IH1_BASE + 0x10)
++#define OMAP_IH1_SIR_FIQ	(OMAP_IH1_BASE + 0x14)
++#define OMAP_IH1_CONTROL	(OMAP_IH1_BASE + 0x18)
++#define OMAP_IH1_ILR0		(OMAP_IH1_BASE + 0x1c)
++#define OMAP_IH1_ISR		(OMAP_IH1_BASE + 0x9c)
++
++#define OMAP_IH2_ITR		(OMAP_IH2_BASE + 0x00)
++#define OMAP_IH2_MIR		(OMAP_IH2_BASE + 0x04)
++#define OMAP_IH2_SIR_IRQ	(OMAP_IH2_BASE + 0x10)
++#define OMAP_IH2_SIR_FIQ	(OMAP_IH2_BASE + 0x14)
++#define OMAP_IH2_CONTROL	(OMAP_IH2_BASE + 0x18)
++#define OMAP_IH2_ILR0		(OMAP_IH2_BASE + 0x1c)
++#define OMAP_IH2_ISR		(OMAP_IH2_BASE + 0x9c)
++
++#define IRQ_ITR_REG_OFFSET	0x00
++#define IRQ_MIR_REG_OFFSET	0x04
++#define IRQ_SIR_IRQ_REG_OFFSET	0x10
++#define IRQ_SIR_FIQ_REG_OFFSET	0x14
++#define IRQ_CONTROL_REG_OFFSET	0x18
++#define IRQ_ISR_REG_OFFSET	0x9c
++#define IRQ_ILR0_REG_OFFSET	0x1c
++#define IRQ_GMR_REG_OFFSET	0xa0
++
++#endif
++
++/*
++ * ----------------------------------------------------------------------------
++ * System control registers
++ * ----------------------------------------------------------------------------
++ */
++#define MOD_CONF_CTRL_0		0xfffe1080
++#define MOD_CONF_CTRL_1		0xfffe1110
++
++/*
++ * ----------------------------------------------------------------------------
++ * Pin multiplexing registers
++ * ----------------------------------------------------------------------------
++ */
++#define FUNC_MUX_CTRL_0		0xfffe1000
++#define FUNC_MUX_CTRL_1		0xfffe1004
++#define FUNC_MUX_CTRL_2		0xfffe1008
++#define COMP_MODE_CTRL_0	0xfffe100c
++#define FUNC_MUX_CTRL_3		0xfffe1010
++#define FUNC_MUX_CTRL_4		0xfffe1014
++#define FUNC_MUX_CTRL_5		0xfffe1018
++#define FUNC_MUX_CTRL_6		0xfffe101C
++#define FUNC_MUX_CTRL_7		0xfffe1020
++#define FUNC_MUX_CTRL_8		0xfffe1024
++#define FUNC_MUX_CTRL_9		0xfffe1028
++#define FUNC_MUX_CTRL_A		0xfffe102C
++#define FUNC_MUX_CTRL_B		0xfffe1030
++#define FUNC_MUX_CTRL_C		0xfffe1034
++#define FUNC_MUX_CTRL_D		0xfffe1038
++#define PULL_DWN_CTRL_0		0xfffe1040
++#define PULL_DWN_CTRL_1		0xfffe1044
++#define PULL_DWN_CTRL_2		0xfffe1048
++#define PULL_DWN_CTRL_3		0xfffe104c
++#define PULL_DWN_CTRL_4		0xfffe10ac
++
++/* OMAP-1610 specific multiplexing registers */
++#define FUNC_MUX_CTRL_E		0xfffe1090
++#define FUNC_MUX_CTRL_F		0xfffe1094
++#define FUNC_MUX_CTRL_10	0xfffe1098
++#define FUNC_MUX_CTRL_11	0xfffe109c
++#define FUNC_MUX_CTRL_12	0xfffe10a0
++#define PU_PD_SEL_0		0xfffe10b4
++#define PU_PD_SEL_1		0xfffe10b8
++#define PU_PD_SEL_2		0xfffe10bc
++#define PU_PD_SEL_3		0xfffe10c0
++#define PU_PD_SEL_4		0xfffe10c4
++
++/* Timer32K for 1610 and 1710*/
++#define OMAP_TIMER32K_BASE	0xFFFBC400
++
++/*
++ * ---------------------------------------------------------------------------
++ * TIPB bus interface
++ * ---------------------------------------------------------------------------
++ */
++#define TIPB_PUBLIC_CNTL_BASE		0xfffed300
++#define MPU_PUBLIC_TIPB_CNTL		(TIPB_PUBLIC_CNTL_BASE + 0x8)
++#define TIPB_PRIVATE_CNTL_BASE		0xfffeca00
++#define MPU_PRIVATE_TIPB_CNTL		(TIPB_PRIVATE_CNTL_BASE + 0x8)
++
++/*
++ * ----------------------------------------------------------------------------
++ * MPUI interface
++ * ----------------------------------------------------------------------------
++ */
++#define MPUI_BASE			(0xfffec900)
++#define MPUI_CTRL			(MPUI_BASE + 0x0)
++#define MPUI_DEBUG_ADDR			(MPUI_BASE + 0x4)
++#define MPUI_DEBUG_DATA			(MPUI_BASE + 0x8)
++#define MPUI_DEBUG_FLAG			(MPUI_BASE + 0xc)
++#define MPUI_STATUS_REG			(MPUI_BASE + 0x10)
++#define MPUI_DSP_STATUS			(MPUI_BASE + 0x14)
++#define MPUI_DSP_BOOT_CONFIG		(MPUI_BASE + 0x18)
++#define MPUI_DSP_API_CONFIG		(MPUI_BASE + 0x1c)
++
++/*
++ * ----------------------------------------------------------------------------
++ * LED Pulse Generator
++ * ----------------------------------------------------------------------------
++ */
++#define OMAP_LPG1_BASE			0xfffbd000
++#define OMAP_LPG2_BASE			0xfffbd800
++#define OMAP_LPG1_LCR			(OMAP_LPG1_BASE + 0x00)
++#define OMAP_LPG1_PMR			(OMAP_LPG1_BASE + 0x04)
++#define OMAP_LPG2_LCR			(OMAP_LPG2_BASE + 0x00)
++#define OMAP_LPG2_PMR			(OMAP_LPG2_BASE + 0x04)
++
++/*
++ * ----------------------------------------------------------------------------
++ * Pulse-Width Light
++ * ----------------------------------------------------------------------------
++ */
++#define OMAP_PWL_BASE			0xfffb5800
++#define OMAP_PWL_ENABLE			(OMAP_PWL_BASE + 0x00)
++#define OMAP_PWL_CLK_ENABLE		(OMAP_PWL_BASE + 0x04)
++
++/*
++ * ---------------------------------------------------------------------------
++ * Processor specific defines
++ * ---------------------------------------------------------------------------
++ */
++
++#include <plat/omap7xx.h>
++#include <plat/omap1510.h>
++#include <plat/omap16xx.h>
++#include <plat/omap24xx.h>
++#include <plat/omap34xx.h>
++#include <plat/omap44xx.h>
++
++#endif	/* __ASM_ARCH_OMAP_HARDWARE_H */
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/hwa742.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/hwa742.h	2010-08-08 12:56:53.000000000 +0200
+@@ -0,0 +1,8 @@
++#ifndef _HWA742_H
++#define _HWA742_H
++
++struct hwa742_platform_data {
++	unsigned	te_connected:1;
++};
++
++#endif
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/i2c.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/i2c.h	2010-08-08 12:56:53.000000000 +0200
+@@ -0,0 +1,39 @@
++/*
++ * Helper module for board specific I2C bus registration
++ *
++ * Copyright (C) 2009 Nokia Corporation.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * version 2 as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
++ * 02110-1301 USA
++ *
++ */
++
++#include <linux/i2c.h>
++
++#if defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE)
++extern int omap_register_i2c_bus(int bus_id, u32 clkrate,
++				 struct i2c_board_info const *info,
++				 unsigned len);
++#else
++static inline int omap_register_i2c_bus(int bus_id, u32 clkrate,
++				 struct i2c_board_info const *info,
++				 unsigned len)
++{
++	return 0;
++}
++#endif
++
++int omap_plat_register_i2c_bus(int bus_id, u32 clkrate,
++				 struct i2c_board_info const *info,
++				 unsigned len);
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/io.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/io.h	2010-08-08 12:56:54.000000000 +0200
+@@ -0,0 +1,287 @@
++/*
++ * arch/arm/plat-omap/include/mach/io.h
++ *
++ * IO definitions for TI OMAP processors and boards
++ *
++ * Copied from arch/arm/mach-sa1100/include/mach/io.h
++ * Copyright (C) 1997-1999 Russell King
++ *
++ * Copyright (C) 2009 Texas Instruments
++ * Added OMAP4 support - Santosh Shilimkar <[email protected]>
++ *
++ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ *
++ * 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.,
++ * 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Modifications:
++ *  06-12-1997	RMK	Created.
++ *  07-04-1999	RMK	Major cleanup
++ */
++
++#ifndef __ASM_ARM_ARCH_IO_H
++#define __ASM_ARM_ARCH_IO_H
++
++#include <mach/hardware.h>
++
++#define IO_SPACE_LIMIT 0xffffffff
++
++/*
++ * We don't actually have real ISA nor PCI buses, but there is so many
++ * drivers out there that might just work if we fake them...
++ */
++#define __io(a)		__typesafe_io(a)
++#define __mem_pci(a)	(a)
++
++/*
++ * ----------------------------------------------------------------------------
++ * I/O mapping
++ * ----------------------------------------------------------------------------
++ */
++
++#ifdef __ASSEMBLER__
++#define IOMEM(x)		(x)
++#else
++#define IOMEM(x)		((void __force __iomem *)(x))
++#endif
++
++#define OMAP1_IO_OFFSET		0x01000000	/* Virtual IO = 0xfefb0000 */
++#define OMAP1_IO_ADDRESS(pa)	IOMEM((pa) - OMAP1_IO_OFFSET)
++
++#define OMAP2_L3_IO_OFFSET	0x90000000
++#define OMAP2_L3_IO_ADDRESS(pa)	IOMEM((pa) + OMAP2_L3_IO_OFFSET) /* L3 */
++
++
++#define OMAP2_L4_IO_OFFSET	0xb2000000
++#define OMAP2_L4_IO_ADDRESS(pa)	IOMEM((pa) + OMAP2_L4_IO_OFFSET) /* L4 */
++
++#define OMAP4_L3_IO_OFFSET	0xb4000000
++#define OMAP4_L3_IO_ADDRESS(pa)	IOMEM((pa) + OMAP4_L3_IO_OFFSET) /* L3 */
++
++#define OMAP4_L3_PER_IO_OFFSET	0xb1100000
++#define OMAP4_L3_PER_IO_ADDRESS(pa)	IOMEM((pa) + OMAP4_L3_PER_IO_OFFSET)
++
++#define OMAP4_GPMC_IO_OFFSET		0xa9000000
++#define OMAP4_GPMC_IO_ADDRESS(pa)	IOMEM((pa) + OMAP4_GPMC_IO_OFFSET)
++
++#define OMAP2_EMU_IO_OFFSET		0xaa800000	/* Emulation */
++#define OMAP2_EMU_IO_ADDRESS(pa)	IOMEM((pa) + OMAP2_EMU_IO_OFFSET)
++
++/*
++ * ----------------------------------------------------------------------------
++ * Omap1 specific IO mapping
++ * ----------------------------------------------------------------------------
++ */
++
++#define OMAP1_IO_PHYS		0xFFFB0000
++#define OMAP1_IO_SIZE		0x40000
++#define OMAP1_IO_VIRT		(OMAP1_IO_PHYS - OMAP1_IO_OFFSET)
++
++/*
++ * ----------------------------------------------------------------------------
++ * Omap2 specific IO mapping
++ * ----------------------------------------------------------------------------
++ */
++
++/* We map both L3 and L4 on OMAP2 */
++#define L3_24XX_PHYS	L3_24XX_BASE	/* 0x68000000 --> 0xf8000000*/
++#define L3_24XX_VIRT	(L3_24XX_PHYS + OMAP2_L3_IO_OFFSET)
++#define L3_24XX_SIZE	SZ_1M		/* 44kB of 128MB used, want 1MB sect */
++#define L4_24XX_PHYS	L4_24XX_BASE	/* 0x48000000 --> 0xfa000000 */
++#define L4_24XX_VIRT	(L4_24XX_PHYS + OMAP2_L4_IO_OFFSET)
++#define L4_24XX_SIZE	SZ_1M		/* 1MB of 128MB used, want 1MB sect */
++
++#define L4_WK_243X_PHYS		L4_WK_243X_BASE	/* 0x49000000 --> 0xfb000000 */
++#define L4_WK_243X_VIRT		(L4_WK_243X_PHYS + OMAP2_L4_IO_OFFSET)
++#define L4_WK_243X_SIZE		SZ_1M
++#define OMAP243X_GPMC_PHYS	OMAP243X_GPMC_BASE
++#define OMAP243X_GPMC_VIRT	(OMAP243X_GPMC_PHYS + OMAP2_L3_IO_OFFSET)
++						/* 0x6e000000 --> 0xfe000000 */
++#define OMAP243X_GPMC_SIZE	SZ_1M
++#define OMAP243X_SDRC_PHYS	OMAP243X_SDRC_BASE
++						/* 0x6D000000 --> 0xfd000000 */
++#define OMAP243X_SDRC_VIRT	(OMAP243X_SDRC_PHYS + OMAP2_L3_IO_OFFSET)
++#define OMAP243X_SDRC_SIZE	SZ_1M
++#define OMAP243X_SMS_PHYS	OMAP243X_SMS_BASE
++						/* 0x6c000000 --> 0xfc000000 */
++#define OMAP243X_SMS_VIRT	(OMAP243X_SMS_PHYS + OMAP2_L3_IO_OFFSET)
++#define OMAP243X_SMS_SIZE	SZ_1M
++
++/* DSP */
++#define DSP_MEM_24XX_PHYS	OMAP2420_DSP_MEM_BASE	/* 0x58000000 */
++#define DSP_MEM_24XX_VIRT	0xe0000000
++#define DSP_MEM_24XX_SIZE	0x28000
++#define DSP_IPI_24XX_PHYS	OMAP2420_DSP_IPI_BASE	/* 0x59000000 */
++#define DSP_IPI_24XX_VIRT	0xe1000000
++#define DSP_IPI_24XX_SIZE	SZ_4K
++#define DSP_MMU_24XX_PHYS	OMAP2420_DSP_MMU_BASE	/* 0x5a000000 */
++#define DSP_MMU_24XX_VIRT	0xe2000000
++#define DSP_MMU_24XX_SIZE	SZ_4K
++
++/*
++ * ----------------------------------------------------------------------------
++ * Omap3 specific IO mapping
++ * ----------------------------------------------------------------------------
++ */
++
++/* We map both L3 and L4 on OMAP3 */
++#define L3_34XX_PHYS		L3_34XX_BASE	/* 0x68000000 --> 0xf8000000 */
++#define L3_34XX_VIRT		(L3_34XX_PHYS + OMAP2_L3_IO_OFFSET)
++#define L3_34XX_SIZE		SZ_1M   /* 44kB of 128MB used, want 1MB sect */
++
++#define L4_34XX_PHYS		L4_34XX_BASE	/* 0x48000000 --> 0xfa000000 */
++#define L4_34XX_VIRT		(L4_34XX_PHYS + OMAP2_L4_IO_OFFSET)
++#define L4_34XX_SIZE		SZ_4M   /* 1MB of 128MB used, want 1MB sect */
++
++/*
++ * Need to look at the Size 4M for L4.
++ * VPOM3430 was not working for Int controller
++ */
++
++#define L4_WK_34XX_PHYS		L4_WK_34XX_BASE	/* 0x48300000 --> 0xfa300000 */
++#define L4_WK_34XX_VIRT		(L4_WK_34XX_PHYS + OMAP2_L4_IO_OFFSET)
++#define L4_WK_34XX_SIZE		SZ_1M
++
++#define L4_PER_34XX_PHYS	L4_PER_34XX_BASE
++						/* 0x49000000 --> 0xfb000000 */
++#define L4_PER_34XX_VIRT	(L4_PER_34XX_PHYS + OMAP2_L4_IO_OFFSET)
++#define L4_PER_34XX_SIZE	SZ_1M
++
++#define L4_EMU_34XX_PHYS	L4_EMU_34XX_BASE
++						/* 0x54000000 --> 0xfe800000 */
++#define L4_EMU_34XX_VIRT	(L4_EMU_34XX_PHYS + OMAP2_EMU_IO_OFFSET)
++#define L4_EMU_34XX_SIZE	SZ_8M
++
++#define OMAP34XX_GPMC_PHYS	OMAP34XX_GPMC_BASE
++						/* 0x6e000000 --> 0xfe000000 */
++#define OMAP34XX_GPMC_VIRT	(OMAP34XX_GPMC_PHYS + OMAP2_L3_IO_OFFSET)
++#define OMAP34XX_GPMC_SIZE	SZ_1M
++
++#define OMAP343X_SMS_PHYS	OMAP343X_SMS_BASE
++						/* 0x6c000000 --> 0xfc000000 */
++#define OMAP343X_SMS_VIRT	(OMAP343X_SMS_PHYS + OMAP2_L3_IO_OFFSET)
++#define OMAP343X_SMS_SIZE	SZ_1M
++
++#define OMAP343X_SDRC_PHYS	OMAP343X_SDRC_BASE
++						/* 0x6D000000 --> 0xfd000000 */
++#define OMAP343X_SDRC_VIRT	(OMAP343X_SDRC_PHYS + OMAP2_L3_IO_OFFSET)
++#define OMAP343X_SDRC_SIZE	SZ_1M
++
++/* DSP */
++#define DSP_MEM_34XX_PHYS	OMAP34XX_DSP_MEM_BASE	/* 0x58000000 */
++#define DSP_MEM_34XX_VIRT	0xe0000000
++#define DSP_MEM_34XX_SIZE	0x28000
++#define DSP_IPI_34XX_PHYS	OMAP34XX_DSP_IPI_BASE	/* 0x59000000 */
++#define DSP_IPI_34XX_VIRT	0xe1000000
++#define DSP_IPI_34XX_SIZE	SZ_4K
++#define DSP_MMU_34XX_PHYS	OMAP34XX_DSP_MMU_BASE	/* 0x5a000000 */
++#define DSP_MMU_34XX_VIRT	0xe2000000
++#define DSP_MMU_34XX_SIZE	SZ_4K
++
++/*
++ * ----------------------------------------------------------------------------
++ * Omap4 specific IO mapping
++ * ----------------------------------------------------------------------------
++ */
++
++/* We map both L3 and L4 on OMAP4 */
++#define L3_44XX_PHYS		L3_44XX_BASE	/* 0x44000000 --> 0xf8000000 */
++#define L3_44XX_VIRT		(L3_44XX_PHYS + OMAP4_L3_IO_OFFSET)
++#define L3_44XX_SIZE		SZ_1M
++
++#define L4_44XX_PHYS		L4_44XX_BASE	/* 0x4a000000 --> 0xfc000000 */
++#define L4_44XX_VIRT		(L4_44XX_PHYS + OMAP2_L4_IO_OFFSET)
++#define L4_44XX_SIZE		SZ_4M
++
++
++#define L4_WK_44XX_PHYS		L4_WK_44XX_BASE	/* 0x4a300000 --> 0xfc300000 */
++#define L4_WK_44XX_VIRT		(L4_WK_44XX_PHYS + OMAP2_L4_IO_OFFSET)
++#define L4_WK_44XX_SIZE		SZ_1M
++
++#define L4_PER_44XX_PHYS	L4_PER_44XX_BASE
++						/* 0x48000000 --> 0xfa000000 */
++#define L4_PER_44XX_VIRT	(L4_PER_44XX_PHYS + OMAP2_L4_IO_OFFSET)
++#define L4_PER_44XX_SIZE	SZ_4M
++
++#define L4_ABE_44XX_PHYS	L4_ABE_44XX_BASE
++						/* 0x49000000 --> 0xfb000000 */
++#define L4_ABE_44XX_VIRT	(L4_ABE_44XX_PHYS + OMAP2_L4_IO_OFFSET)
++#define L4_ABE_44XX_SIZE	SZ_1M
++
++#define L4_EMU_44XX_PHYS	L4_EMU_44XX_BASE
++						/* 0x54000000 --> 0xfe800000 */
++#define L4_EMU_44XX_VIRT	(L4_EMU_44XX_PHYS + OMAP2_EMU_IO_OFFSET)
++#define L4_EMU_44XX_SIZE	SZ_8M
++
++#define OMAP44XX_GPMC_PHYS	OMAP44XX_GPMC_BASE
++						/* 0x50000000 --> 0xf9000000 */
++#define OMAP44XX_GPMC_VIRT	(OMAP44XX_GPMC_PHYS + OMAP4_GPMC_IO_OFFSET)
++#define OMAP44XX_GPMC_SIZE	SZ_1M
++
++
++#define OMAP44XX_EMIF1_PHYS	OMAP44XX_EMIF1_BASE
++						/* 0x4c000000 --> 0xfd100000 */
++#define OMAP44XX_EMIF1_VIRT	(OMAP44XX_EMIF1_PHYS + OMAP4_L3_PER_IO_OFFSET)
++#define OMAP44XX_EMIF1_SIZE	SZ_1M
++
++#define OMAP44XX_EMIF2_PHYS	OMAP44XX_EMIF2_BASE
++						/* 0x4d000000 --> 0xfd200000 */
++#define OMAP44XX_EMIF2_VIRT	(OMAP44XX_EMIF2_PHYS + OMAP4_L3_PER_IO_OFFSET)
++#define OMAP44XX_EMIF2_SIZE	SZ_1M
++
++#define OMAP44XX_DMM_PHYS	OMAP44XX_DMM_BASE
++						/* 0x4e000000 --> 0xfd300000 */
++#define OMAP44XX_DMM_VIRT	(OMAP44XX_DMM_PHYS + OMAP4_L3_PER_IO_OFFSET)
++#define OMAP44XX_DMM_SIZE	SZ_1M
++/*
++ * ----------------------------------------------------------------------------
++ * Omap specific register access
++ * ----------------------------------------------------------------------------
++ */
++
++#ifndef __ASSEMBLER__
++
++/*
++ * NOTE: Please use ioremap + __raw_read/write where possible instead of these
++ */
++
++extern u8 omap_readb(u32 pa);
++extern u16 omap_readw(u32 pa);
++extern u32 omap_readl(u32 pa);
++extern void omap_writeb(u8 v, u32 pa);
++extern void omap_writew(u16 v, u32 pa);
++extern void omap_writel(u32 v, u32 pa);
++
++struct omap_sdrc_params;
++
++extern void omap1_map_common_io(void);
++extern void omap1_init_common_hw(void);
++
++extern void omap2_map_common_io(void);
++extern void omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0,
++				 struct omap_sdrc_params *sdrc_cs1);
++
++#define __arch_ioremap(p,s,t)	omap_ioremap(p,s,t)
++#define __arch_iounmap(v)	omap_iounmap(v)
++
++void __iomem *omap_ioremap(unsigned long phys, size_t size, unsigned int type);
++void omap_iounmap(volatile void __iomem *addr);
++
++#endif
++
++#endif
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/iommu2.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/iommu2.h	2010-08-08 12:56:54.000000000 +0200
+@@ -0,0 +1,96 @@
++/*
++ * omap iommu: omap2 architecture specific definitions
++ *
++ * Copyright (C) 2008-2009 Nokia Corporation
++ *
++ * Written by Hiroshi DOYU <[email protected]>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#ifndef __MACH_IOMMU2_H
++#define __MACH_IOMMU2_H
++
++#include <linux/io.h>
++
++/*
++ * MMU Register offsets
++ */
++#define MMU_REVISION		0x00
++#define MMU_SYSCONFIG		0x10
++#define MMU_SYSSTATUS		0x14
++#define MMU_IRQSTATUS		0x18
++#define MMU_IRQENABLE		0x1c
++#define MMU_WALKING_ST		0x40
++#define MMU_CNTL		0x44
++#define MMU_FAULT_AD		0x48
++#define MMU_TTB			0x4c
++#define MMU_LOCK		0x50
++#define MMU_LD_TLB		0x54
++#define MMU_CAM			0x58
++#define MMU_RAM			0x5c
++#define MMU_GFLUSH		0x60
++#define MMU_FLUSH_ENTRY		0x64
++#define MMU_READ_CAM		0x68
++#define MMU_READ_RAM		0x6c
++#define MMU_EMU_FAULT_AD	0x70
++
++#define MMU_REG_SIZE		256
++
++/*
++ * MMU Register bit definitions
++ */
++#define MMU_LOCK_BASE_SHIFT	10
++#define MMU_LOCK_BASE_MASK	(0x1f << MMU_LOCK_BASE_SHIFT)
++#define MMU_LOCK_BASE(x)	\
++	((x & MMU_LOCK_BASE_MASK) >> MMU_LOCK_BASE_SHIFT)
++
++#define MMU_LOCK_VICT_SHIFT	4
++#define MMU_LOCK_VICT_MASK	(0x1f << MMU_LOCK_VICT_SHIFT)
++#define MMU_LOCK_VICT(x)	\
++	((x & MMU_LOCK_VICT_MASK) >> MMU_LOCK_VICT_SHIFT)
++
++#define MMU_CAM_VATAG_SHIFT	12
++#define MMU_CAM_VATAG_MASK \
++	((~0UL >> MMU_CAM_VATAG_SHIFT) << MMU_CAM_VATAG_SHIFT)
++#define MMU_CAM_P		(1 << 3)
++#define MMU_CAM_V		(1 << 2)
++#define MMU_CAM_PGSZ_MASK	3
++#define MMU_CAM_PGSZ_1M		(0 << 0)
++#define MMU_CAM_PGSZ_64K	(1 << 0)
++#define MMU_CAM_PGSZ_4K		(2 << 0)
++#define MMU_CAM_PGSZ_16M	(3 << 0)
++
++#define MMU_RAM_PADDR_SHIFT	12
++#define MMU_RAM_PADDR_MASK \
++	((~0UL >> MMU_RAM_PADDR_SHIFT) << MMU_RAM_PADDR_SHIFT)
++#define MMU_RAM_ENDIAN_SHIFT	9
++#define MMU_RAM_ENDIAN_MASK	(1 << MMU_RAM_ENDIAN_SHIFT)
++#define MMU_RAM_ENDIAN_BIG	(1 << MMU_RAM_ENDIAN_SHIFT)
++#define MMU_RAM_ENDIAN_LITTLE	(0 << MMU_RAM_ENDIAN_SHIFT)
++#define MMU_RAM_ELSZ_SHIFT	7
++#define MMU_RAM_ELSZ_MASK	(3 << MMU_RAM_ELSZ_SHIFT)
++#define MMU_RAM_ELSZ_8		(0 << MMU_RAM_ELSZ_SHIFT)
++#define MMU_RAM_ELSZ_16		(1 << MMU_RAM_ELSZ_SHIFT)
++#define MMU_RAM_ELSZ_32		(2 << MMU_RAM_ELSZ_SHIFT)
++#define MMU_RAM_ELSZ_NONE	(3 << MMU_RAM_ELSZ_SHIFT)
++#define MMU_RAM_MIXED_SHIFT	6
++#define MMU_RAM_MIXED_MASK	(1 << MMU_RAM_MIXED_SHIFT)
++#define MMU_RAM_MIXED		MMU_RAM_MIXED_MASK
++
++/*
++ * register accessors
++ */
++static inline u32 iommu_read_reg(struct iommu *obj, size_t offs)
++{
++	return __raw_readl(obj->regbase + offs);
++}
++
++static inline void iommu_write_reg(struct iommu *obj, u32 val, size_t offs)
++{
++	__raw_writel(val, obj->regbase + offs);
++}
++
++#endif /* __MACH_IOMMU2_H */
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/iommu.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/iommu.h	2010-08-08 12:56:55.000000000 +0200
+@@ -0,0 +1,168 @@
++/*
++ * omap iommu: main structures
++ *
++ * Copyright (C) 2008-2009 Nokia Corporation
++ *
++ * Written by Hiroshi DOYU <[email protected]>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#ifndef __MACH_IOMMU_H
++#define __MACH_IOMMU_H
++
++struct iotlb_entry {
++	u32 da;
++	u32 pa;
++	u32 pgsz, prsvd, valid;
++	union {
++		u16 ap;
++		struct {
++			u32 endian, elsz, mixed;
++		};
++	};
++};
++
++struct iommu {
++	const char	*name;
++	struct module	*owner;
++	struct clk	*clk;
++	void __iomem	*regbase;
++	struct device	*dev;
++
++	unsigned int	refcount;
++	struct mutex	iommu_lock;	/* global for this whole object */
++
++	/*
++	 * We don't change iopgd for a situation like pgd for a task,
++	 * but share it globally for each iommu.
++	 */
++	u32		*iopgd;
++	spinlock_t	page_table_lock; /* protect iopgd */
++
++	int		nr_tlb_entries;
++
++	struct list_head	mmap;
++	struct mutex		mmap_lock; /* protect mmap */
++
++	int (*isr)(struct iommu *obj);
++
++	void *ctx; /* iommu context: registres saved area */
++};
++
++struct cr_regs {
++	union {
++		struct {
++			u16 cam_l;
++			u16 cam_h;
++		};
++		u32 cam;
++	};
++	union {
++		struct {
++			u16 ram_l;
++			u16 ram_h;
++		};
++		u32 ram;
++	};
++};
++
++struct iotlb_lock {
++	short base;
++	short vict;
++};
++
++/* architecture specific functions */
++struct iommu_functions {
++	unsigned long	version;
++
++	int (*enable)(struct iommu *obj);
++	void (*disable)(struct iommu *obj);
++	u32 (*fault_isr)(struct iommu *obj, u32 *ra);
++
++	void (*tlb_read_cr)(struct iommu *obj, struct cr_regs *cr);
++	void (*tlb_load_cr)(struct iommu *obj, struct cr_regs *cr);
++
++	struct cr_regs *(*alloc_cr)(struct iommu *obj, struct iotlb_entry *e);
++	int (*cr_valid)(struct cr_regs *cr);
++	u32 (*cr_to_virt)(struct cr_regs *cr);
++	void (*cr_to_e)(struct cr_regs *cr, struct iotlb_entry *e);
++	ssize_t (*dump_cr)(struct iommu *obj, struct cr_regs *cr, char *buf);
++
++	u32 (*get_pte_attr)(struct iotlb_entry *e);
++
++	void (*save_ctx)(struct iommu *obj);
++	void (*restore_ctx)(struct iommu *obj);
++	ssize_t (*dump_ctx)(struct iommu *obj, char *buf, ssize_t len);
++};
++
++struct iommu_platform_data {
++	const char *name;
++	const char *clk_name;
++	const int nr_tlb_entries;
++};
++
++#if defined(CONFIG_ARCH_OMAP1)
++#error "iommu for this processor not implemented yet"
++#else
++#include <plat/iommu2.h>
++#endif
++
++/*
++ * utilities for super page(16MB, 1MB, 64KB and 4KB)
++ */
++
++#define iopgsz_max(bytes)			\
++	(((bytes) >= SZ_16M) ? SZ_16M :		\
++	 ((bytes) >= SZ_1M)  ? SZ_1M  :		\
++	 ((bytes) >= SZ_64K) ? SZ_64K :		\
++	 ((bytes) >= SZ_4K)  ? SZ_4K  :	0)
++
++#define bytes_to_iopgsz(bytes)				\
++	(((bytes) == SZ_16M) ? MMU_CAM_PGSZ_16M :	\
++	 ((bytes) == SZ_1M)  ? MMU_CAM_PGSZ_1M  :	\
++	 ((bytes) == SZ_64K) ? MMU_CAM_PGSZ_64K :	\
++	 ((bytes) == SZ_4K)  ? MMU_CAM_PGSZ_4K  : -1)
++
++#define iopgsz_to_bytes(iopgsz)				\
++	(((iopgsz) == MMU_CAM_PGSZ_16M)	? SZ_16M :	\
++	 ((iopgsz) == MMU_CAM_PGSZ_1M)	? SZ_1M  :	\
++	 ((iopgsz) == MMU_CAM_PGSZ_64K)	? SZ_64K :	\
++	 ((iopgsz) == MMU_CAM_PGSZ_4K)	? SZ_4K  : 0)
++
++#define iopgsz_ok(bytes) (bytes_to_iopgsz(bytes) >= 0)
++
++/*
++ * global functions
++ */
++extern u32 iommu_arch_version(void);
++
++extern void iotlb_cr_to_e(struct cr_regs *cr, struct iotlb_entry *e);
++extern u32 iotlb_cr_to_virt(struct cr_regs *cr);
++
++extern int load_iotlb_entry(struct iommu *obj, struct iotlb_entry *e);
++extern void flush_iotlb_page(struct iommu *obj, u32 da);
++extern void flush_iotlb_range(struct iommu *obj, u32 start, u32 end);
++extern void flush_iotlb_all(struct iommu *obj);
++
++extern int iopgtable_store_entry(struct iommu *obj, struct iotlb_entry *e);
++extern size_t iopgtable_clear_entry(struct iommu *obj, u32 iova);
++
++extern struct iommu *iommu_get(const char *name);
++extern void iommu_put(struct iommu *obj);
++
++extern void iommu_save_ctx(struct iommu *obj);
++extern void iommu_restore_ctx(struct iommu *obj);
++
++extern int install_iommu_arch(const struct iommu_functions *ops);
++extern void uninstall_iommu_arch(const struct iommu_functions *ops);
++
++extern int foreach_iommu_device(void *data,
++				int (*fn)(struct device *, void *));
++
++extern ssize_t iommu_dump_ctx(struct iommu *obj, char *buf, ssize_t len);
++extern size_t dump_tlb_entries(struct iommu *obj, char *buf, ssize_t len);
++
++#endif /* __MACH_IOMMU_H */
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/iovmm.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/iovmm.h	2010-08-08 12:56:56.000000000 +0200
+@@ -0,0 +1,94 @@
++/*
++ * omap iommu: simple virtual address space management
++ *
++ * Copyright (C) 2008-2009 Nokia Corporation
++ *
++ * Written by Hiroshi DOYU <[email protected]>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#ifndef __IOMMU_MMAP_H
++#define __IOMMU_MMAP_H
++
++struct iovm_struct {
++	struct iommu		*iommu;	/* iommu object which this belongs to */
++	u32			da_start; /* area definition */
++	u32			da_end;
++	u32			flags; /* IOVMF_: see below */
++	struct list_head	list; /* linked in ascending order */
++	const struct sg_table	*sgt; /* keep 'page' <-> 'da' mapping */
++	void			*va; /* mpu side mapped address */
++};
++
++/*
++ * IOVMF_FLAGS: attribute for iommu virtual memory area(iovma)
++ *
++ * lower 16 bit is used for h/w and upper 16 bit is for s/w.
++ */
++#define IOVMF_SW_SHIFT		16
++#define IOVMF_HW_SIZE		(1 << IOVMF_SW_SHIFT)
++#define IOVMF_HW_MASK		(IOVMF_HW_SIZE - 1)
++#define IOVMF_SW_MASK		(~IOVMF_HW_MASK)UL
++
++/*
++ * iovma: h/w flags derived from cam and ram attribute
++ */
++#define IOVMF_CAM_MASK		(~((1 << 10) - 1))
++#define IOVMF_RAM_MASK		(~IOVMF_CAM_MASK)
++
++#define IOVMF_PGSZ_MASK		(3 << 0)
++#define IOVMF_PGSZ_1M		MMU_CAM_PGSZ_1M
++#define IOVMF_PGSZ_64K		MMU_CAM_PGSZ_64K
++#define IOVMF_PGSZ_4K		MMU_CAM_PGSZ_4K
++#define IOVMF_PGSZ_16M		MMU_CAM_PGSZ_16M
++
++#define IOVMF_ENDIAN_MASK	(1 << 9)
++#define IOVMF_ENDIAN_BIG	MMU_RAM_ENDIAN_BIG
++#define IOVMF_ENDIAN_LITTLE	MMU_RAM_ENDIAN_LITTLE
++
++#define IOVMF_ELSZ_MASK		(3 << 7)
++#define IOVMF_ELSZ_8		MMU_RAM_ELSZ_8
++#define IOVMF_ELSZ_16		MMU_RAM_ELSZ_16
++#define IOVMF_ELSZ_32		MMU_RAM_ELSZ_32
++#define IOVMF_ELSZ_NONE		MMU_RAM_ELSZ_NONE
++
++#define IOVMF_MIXED_MASK	(1 << 6)
++#define IOVMF_MIXED		MMU_RAM_MIXED
++
++/*
++ * iovma: s/w flags, used for mapping and umapping internally.
++ */
++#define IOVMF_MMIO		(1 << IOVMF_SW_SHIFT)
++#define IOVMF_ALLOC		(2 << IOVMF_SW_SHIFT)
++#define IOVMF_ALLOC_MASK	(3 << IOVMF_SW_SHIFT)
++
++/* "superpages" is supported just with physically linear pages */
++#define IOVMF_DISCONT		(1 << (2 + IOVMF_SW_SHIFT))
++#define IOVMF_LINEAR		(2 << (2 + IOVMF_SW_SHIFT))
++#define IOVMF_LINEAR_MASK	(3 << (2 + IOVMF_SW_SHIFT))
++
++#define IOVMF_DA_FIXED		(1 << (4 + IOVMF_SW_SHIFT))
++#define IOVMF_DA_ANON		(2 << (4 + IOVMF_SW_SHIFT))
++#define IOVMF_DA_MASK		(3 << (4 + IOVMF_SW_SHIFT))
++
++
++extern struct iovm_struct *find_iovm_area(struct iommu *obj, u32 da);
++extern u32 iommu_vmap(struct iommu *obj, u32 da,
++			const struct sg_table *sgt, u32 flags);
++extern struct sg_table *iommu_vunmap(struct iommu *obj, u32 da);
++extern u32 iommu_vmalloc(struct iommu *obj, u32 da, size_t bytes,
++			   u32 flags);
++extern void iommu_vfree(struct iommu *obj, const u32 da);
++extern u32 iommu_kmap(struct iommu *obj, u32 da, u32 pa, size_t bytes,
++			u32 flags);
++extern void iommu_kunmap(struct iommu *obj, u32 da);
++extern u32 iommu_kmalloc(struct iommu *obj, u32 da, size_t bytes,
++			   u32 flags);
++extern void iommu_kfree(struct iommu *obj, u32 da);
++
++extern void *da_to_va(struct iommu *obj, u32 da);
++
++#endif /* __IOMMU_MMAP_H */
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/irda.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/irda.h	2010-08-08 12:56:57.000000000 +0200
+@@ -0,0 +1,33 @@
++/*
++ *  arch/arm/plat-omap/include/mach/irda.h
++ *
++ *  Copyright (C) 2005-2006 Komal Shah <[email protected]>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++#ifndef ASMARM_ARCH_IRDA_H
++#define ASMARM_ARCH_IRDA_H
++
++/* board specific transceiver capabilities */
++
++#define IR_SEL		1	/* Selects IrDA */
++#define IR_SIRMODE	2
++#define IR_FIRMODE	4
++#define IR_MIRMODE	8
++
++struct omap_irda_config {
++	int transceiver_cap;
++	int (*transceiver_mode)(struct device *dev, int mode);
++	int (*select_irda)(struct device *dev, int state);
++	int rx_channel;
++	int tx_channel;
++	unsigned long dest_start;
++	unsigned long src_start;
++	int tx_trigger;
++	int rx_trigger;
++	int mode;
++};
++
++#endif
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/irqs.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/irqs.h	2010-08-08 12:56:57.000000000 +0200
+@@ -0,0 +1,506 @@
++/*
++ *  arch/arm/plat-omap/include/mach/irqs.h
++ *
++ *  Copyright (C) Greg Lonnon 2001
++ *  Updated for OMAP-1610 by Tony Lindgren <[email protected]>
++ *
++ * Copyright (C) 2009 Texas Instruments
++ * Added OMAP4 support - Santosh Shilimkar <[email protected]>
++ *
++ * 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
++ *
++ * NOTE: The interrupt vectors for the OMAP-1509, OMAP-1510, and OMAP-1610
++ *	 are different.
++ */
++
++#ifndef __ASM_ARCH_OMAP15XX_IRQS_H
++#define __ASM_ARCH_OMAP15XX_IRQS_H
++
++/*
++ * IRQ numbers for interrupt handler 1
++ *
++ * NOTE: See also the OMAP-1510 and 1610 specific IRQ numbers below
++ *
++ */
++#define INT_CAMERA		1
++#define INT_FIQ			3
++#define INT_RTDX		6
++#define INT_DSP_MMU_ABORT	7
++#define INT_HOST		8
++#define INT_ABORT		9
++#define INT_BRIDGE_PRIV		13
++#define INT_GPIO_BANK1		14
++#define INT_UART3		15
++#define INT_TIMER3		16
++#define INT_DMA_CH0_6		19
++#define INT_DMA_CH1_7		20
++#define INT_DMA_CH2_8		21
++#define INT_DMA_CH3		22
++#define INT_DMA_CH4		23
++#define INT_DMA_CH5		24
++#define INT_DMA_LCD		25
++#define INT_TIMER1		26
++#define INT_WD_TIMER		27
++#define INT_BRIDGE_PUB		28
++#define INT_TIMER2		30
++#define INT_LCD_CTRL		31
++
++/*
++ * OMAP-1510 specific IRQ numbers for interrupt handler 1
++ */
++#define INT_1510_IH2_IRQ	0
++#define INT_1510_RES2		2
++#define INT_1510_SPI_TX		4
++#define INT_1510_SPI_RX		5
++#define INT_1510_DSP_MAILBOX1	10
++#define INT_1510_DSP_MAILBOX2	11
++#define INT_1510_RES12		12
++#define INT_1510_LB_MMU		17
++#define INT_1510_RES18		18
++#define INT_1510_LOCAL_BUS	29
++
++/*
++ * OMAP-1610 specific IRQ numbers for interrupt handler 1
++ */
++#define INT_1610_IH2_IRQ	0
++#define INT_1610_IH2_FIQ	2
++#define INT_1610_McBSP2_TX	4
++#define INT_1610_McBSP2_RX	5
++#define INT_1610_DSP_MAILBOX1	10
++#define INT_1610_DSP_MAILBOX2	11
++#define INT_1610_LCD_LINE	12
++#define INT_1610_GPTIMER1	17
++#define INT_1610_GPTIMER2	18
++#define INT_1610_SSR_FIFO_0	29
++
++/*
++ * OMAP-7xx specific IRQ numbers for interrupt handler 1
++ */
++#define INT_7XX_IH2_FIQ		0
++#define INT_7XX_IH2_IRQ		1
++#define INT_7XX_USB_NON_ISO	2
++#define INT_7XX_USB_ISO		3
++#define INT_7XX_ICR		4
++#define INT_7XX_EAC		5
++#define INT_7XX_GPIO_BANK1	6
++#define INT_7XX_GPIO_BANK2	7
++#define INT_7XX_GPIO_BANK3	8
++#define INT_7XX_McBSP2TX	10
++#define INT_7XX_McBSP2RX	11
++#define INT_7XX_McBSP2RX_OVF	12
++#define INT_7XX_LCD_LINE	14
++#define INT_7XX_GSM_PROTECT	15
++#define INT_7XX_TIMER3		16
++#define INT_7XX_GPIO_BANK5	17
++#define INT_7XX_GPIO_BANK6	18
++#define INT_7XX_SPGIO_WR	29
++
++/*
++ * IRQ numbers for interrupt handler 2
++ *
++ * NOTE: See also the OMAP-1510 and 1610 specific IRQ numbers below
++ */
++#define IH2_BASE		32
++
++#define INT_KEYBOARD		(1 + IH2_BASE)
++#define INT_uWireTX		(2 + IH2_BASE)
++#define INT_uWireRX		(3 + IH2_BASE)
++#define INT_I2C			(4 + IH2_BASE)
++#define INT_MPUIO		(5 + IH2_BASE)
++#define INT_USB_HHC_1		(6 + IH2_BASE)
++#define INT_McBSP3TX		(10 + IH2_BASE)
++#define INT_McBSP3RX		(11 + IH2_BASE)
++#define INT_McBSP1TX		(12 + IH2_BASE)
++#define INT_McBSP1RX		(13 + IH2_BASE)
++#define INT_UART1		(14 + IH2_BASE)
++#define INT_UART2		(15 + IH2_BASE)
++#define INT_BT_MCSI1TX		(16 + IH2_BASE)
++#define INT_BT_MCSI1RX		(17 + IH2_BASE)
++#define INT_SOSSI_MATCH		(19 + IH2_BASE)
++#define INT_USB_W2FC		(20 + IH2_BASE)
++#define INT_1WIRE		(21 + IH2_BASE)
++#define INT_OS_TIMER		(22 + IH2_BASE)
++#define INT_MMC			(23 + IH2_BASE)
++#define INT_GAUGE_32K		(24 + IH2_BASE)
++#define INT_RTC_TIMER		(25 + IH2_BASE)
++#define INT_RTC_ALARM		(26 + IH2_BASE)
++#define INT_MEM_STICK		(27 + IH2_BASE)
++
++/*
++ * OMAP-1510 specific IRQ numbers for interrupt handler 2
++ */
++#define INT_1510_DSP_MMU	(28 + IH2_BASE)
++#define INT_1510_COM_SPI_RO	(31 + IH2_BASE)
++
++/*
++ * OMAP-1610 specific IRQ numbers for interrupt handler 2
++ */
++#define INT_1610_FAC		(0 + IH2_BASE)
++#define INT_1610_USB_HHC_2	(7 + IH2_BASE)
++#define INT_1610_USB_OTG	(8 + IH2_BASE)
++#define INT_1610_SoSSI		(9 + IH2_BASE)
++#define INT_1610_SoSSI_MATCH	(19 + IH2_BASE)
++#define INT_1610_DSP_MMU	(28 + IH2_BASE)
++#define INT_1610_McBSP2RX_OF	(31 + IH2_BASE)
++#define INT_1610_STI		(32 + IH2_BASE)
++#define INT_1610_STI_WAKEUP	(33 + IH2_BASE)
++#define INT_1610_GPTIMER3	(34 + IH2_BASE)
++#define INT_1610_GPTIMER4	(35 + IH2_BASE)
++#define INT_1610_GPTIMER5	(36 + IH2_BASE)
++#define INT_1610_GPTIMER6	(37 + IH2_BASE)
++#define INT_1610_GPTIMER7	(38 + IH2_BASE)
++#define INT_1610_GPTIMER8	(39 + IH2_BASE)
++#define INT_1610_GPIO_BANK2	(40 + IH2_BASE)
++#define INT_1610_GPIO_BANK3	(41 + IH2_BASE)
++#define INT_1610_MMC2		(42 + IH2_BASE)
++#define INT_1610_CF		(43 + IH2_BASE)
++#define INT_1610_WAKE_UP_REQ	(46 + IH2_BASE)
++#define INT_1610_GPIO_BANK4	(48 + IH2_BASE)
++#define INT_1610_SPI		(49 + IH2_BASE)
++#define INT_1610_DMA_CH6	(53 + IH2_BASE)
++#define INT_1610_DMA_CH7	(54 + IH2_BASE)
++#define INT_1610_DMA_CH8	(55 + IH2_BASE)
++#define INT_1610_DMA_CH9	(56 + IH2_BASE)
++#define INT_1610_DMA_CH10	(57 + IH2_BASE)
++#define INT_1610_DMA_CH11	(58 + IH2_BASE)
++#define INT_1610_DMA_CH12	(59 + IH2_BASE)
++#define INT_1610_DMA_CH13	(60 + IH2_BASE)
++#define INT_1610_DMA_CH14	(61 + IH2_BASE)
++#define INT_1610_DMA_CH15	(62 + IH2_BASE)
++#define INT_1610_NAND		(63 + IH2_BASE)
++#define INT_1610_SHA1MD5	(91 + IH2_BASE)
++
++/*
++ * OMAP-7xx specific IRQ numbers for interrupt handler 2
++ */
++#define INT_7XX_HW_ERRORS	(0 + IH2_BASE)
++#define INT_7XX_NFIQ_PWR_FAIL	(1 + IH2_BASE)
++#define INT_7XX_CFCD		(2 + IH2_BASE)
++#define INT_7XX_CFIREQ		(3 + IH2_BASE)
++#define INT_7XX_I2C		(4 + IH2_BASE)
++#define INT_7XX_PCC		(5 + IH2_BASE)
++#define INT_7XX_MPU_EXT_NIRQ	(6 + IH2_BASE)
++#define INT_7XX_SPI_100K_1	(7 + IH2_BASE)
++#define INT_7XX_SYREN_SPI	(8 + IH2_BASE)
++#define INT_7XX_VLYNQ		(9 + IH2_BASE)
++#define INT_7XX_GPIO_BANK4	(10 + IH2_BASE)
++#define INT_7XX_McBSP1TX	(11 + IH2_BASE)
++#define INT_7XX_McBSP1RX	(12 + IH2_BASE)
++#define INT_7XX_McBSP1RX_OF	(13 + IH2_BASE)
++#define INT_7XX_UART_MODEM_IRDA_2 (14 + IH2_BASE)
++#define INT_7XX_UART_MODEM_1	(15 + IH2_BASE)
++#define INT_7XX_MCSI		(16 + IH2_BASE)
++#define INT_7XX_uWireTX		(17 + IH2_BASE)
++#define INT_7XX_uWireRX		(18 + IH2_BASE)
++#define INT_7XX_SMC_CD		(19 + IH2_BASE)
++#define INT_7XX_SMC_IREQ	(20 + IH2_BASE)
++#define INT_7XX_HDQ_1WIRE	(21 + IH2_BASE)
++#define INT_7XX_TIMER32K	(22 + IH2_BASE)
++#define INT_7XX_MMC_SDIO	(23 + IH2_BASE)
++#define INT_7XX_UPLD		(24 + IH2_BASE)
++#define INT_7XX_USB_HHC_1	(27 + IH2_BASE)
++#define INT_7XX_USB_HHC_2	(28 + IH2_BASE)
++#define INT_7XX_USB_GENI	(29 + IH2_BASE)
++#define INT_7XX_USB_OTG		(30 + IH2_BASE)
++#define INT_7XX_CAMERA_IF	(31 + IH2_BASE)
++#define INT_7XX_RNG		(32 + IH2_BASE)
++#define INT_7XX_DUAL_MODE_TIMER (33 + IH2_BASE)
++#define INT_7XX_DBB_RF_EN	(34 + IH2_BASE)
++#define INT_7XX_MPUIO_KEYPAD	(35 + IH2_BASE)
++#define INT_7XX_SHA1_MD5	(36 + IH2_BASE)
++#define INT_7XX_SPI_100K_2	(37 + IH2_BASE)
++#define INT_7XX_RNG_IDLE	(38 + IH2_BASE)
++#define INT_7XX_MPUIO		(39 + IH2_BASE)
++#define INT_7XX_LLPC_LCD_CTRL_CAN_BE_OFF	(40 + IH2_BASE)
++#define INT_7XX_LLPC_OE_FALLING (41 + IH2_BASE)
++#define INT_7XX_LLPC_OE_RISING	(42 + IH2_BASE)
++#define INT_7XX_LLPC_VSYNC	(43 + IH2_BASE)
++#define INT_7XX_WAKE_UP_REQ	(46 + IH2_BASE)
++#define INT_7XX_DMA_CH6		(53 + IH2_BASE)
++#define INT_7XX_DMA_CH7		(54 + IH2_BASE)
++#define INT_7XX_DMA_CH8		(55 + IH2_BASE)
++#define INT_7XX_DMA_CH9		(56 + IH2_BASE)
++#define INT_7XX_DMA_CH10	(57 + IH2_BASE)
++#define INT_7XX_DMA_CH11	(58 + IH2_BASE)
++#define INT_7XX_DMA_CH12	(59 + IH2_BASE)
++#define INT_7XX_DMA_CH13	(60 + IH2_BASE)
++#define INT_7XX_DMA_CH14	(61 + IH2_BASE)
++#define INT_7XX_DMA_CH15	(62 + IH2_BASE)
++#define INT_7XX_NAND		(63 + IH2_BASE)
++
++#define INT_24XX_SYS_NIRQ	7
++#define INT_24XX_SDMA_IRQ0	12
++#define INT_24XX_SDMA_IRQ1	13
++#define INT_24XX_SDMA_IRQ2	14
++#define INT_24XX_SDMA_IRQ3	15
++#define INT_24XX_CAM_IRQ	24
++#define INT_24XX_DSS_IRQ	25
++#define INT_24XX_MAIL_U0_MPU	26
++#define INT_24XX_DSP_UMA	27
++#define INT_24XX_DSP_MMU	28
++#define INT_24XX_GPIO_BANK1	29
++#define INT_24XX_GPIO_BANK2	30
++#define INT_24XX_GPIO_BANK3	31
++#define INT_24XX_GPIO_BANK4	32
++#define INT_24XX_GPIO_BANK5	33
++#define INT_24XX_MAIL_U3_MPU	34
++#define INT_24XX_GPTIMER1	37
++#define INT_24XX_GPTIMER2	38
++#define INT_24XX_GPTIMER3	39
++#define INT_24XX_GPTIMER4	40
++#define INT_24XX_GPTIMER5	41
++#define INT_24XX_GPTIMER6	42
++#define INT_24XX_GPTIMER7	43
++#define INT_24XX_GPTIMER8	44
++#define INT_24XX_GPTIMER9	45
++#define INT_24XX_GPTIMER10	46
++#define INT_24XX_GPTIMER11	47
++#define INT_24XX_GPTIMER12	48
++#define INT_24XX_SHA1MD5	51
++#define INT_24XX_MCBSP4_IRQ_TX	54
++#define INT_24XX_MCBSP4_IRQ_RX	55
++#define INT_24XX_I2C1_IRQ	56
++#define INT_24XX_I2C2_IRQ	57
++#define INT_24XX_HDQ_IRQ	58
++#define INT_24XX_MCBSP1_IRQ_TX	59
++#define INT_24XX_MCBSP1_IRQ_RX	60
++#define INT_24XX_MCBSP2_IRQ_TX	62
++#define INT_24XX_MCBSP2_IRQ_RX	63
++#define INT_24XX_SPI1_IRQ	65
++#define INT_24XX_SPI2_IRQ	66
++#define INT_24XX_UART1_IRQ	72
++#define INT_24XX_UART2_IRQ	73
++#define INT_24XX_UART3_IRQ	74
++#define INT_24XX_USB_IRQ_GEN	75
++#define INT_24XX_USB_IRQ_NISO	76
++#define INT_24XX_USB_IRQ_ISO	77
++#define INT_24XX_USB_IRQ_HGEN	78
++#define INT_24XX_USB_IRQ_HSOF	79
++#define INT_24XX_USB_IRQ_OTG	80
++#define INT_24XX_MCBSP5_IRQ_TX	81
++#define INT_24XX_MCBSP5_IRQ_RX	82
++#define INT_24XX_MMC_IRQ	83
++#define INT_24XX_MMC2_IRQ	86
++#define INT_24XX_MCBSP3_IRQ_TX	89
++#define INT_24XX_MCBSP3_IRQ_RX	90
++#define INT_24XX_SPI3_IRQ	91
++
++#define INT_243X_MCBSP2_IRQ	16
++#define INT_243X_MCBSP3_IRQ	17
++#define INT_243X_MCBSP4_IRQ	18
++#define INT_243X_MCBSP5_IRQ	19
++#define INT_243X_MCBSP1_IRQ	64
++#define INT_243X_HS_USB_MC	92
++#define INT_243X_HS_USB_DMA	93
++#define INT_243X_CARKIT_IRQ	94
++
++#define INT_34XX_BENCH_MPU_EMUL	3
++#define INT_34XX_ST_MCBSP2_IRQ	4
++#define INT_34XX_ST_MCBSP3_IRQ	5
++#define INT_34XX_SSM_ABORT_IRQ	6
++#define INT_34XX_SYS_NIRQ	7
++#define INT_34XX_D2D_FW_IRQ	8
++#define INT_34XX_PRCM_MPU_IRQ	11
++#define INT_34XX_MCBSP1_IRQ	16
++#define INT_34XX_MCBSP2_IRQ	17
++#define INT_34XX_MCBSP3_IRQ	22
++#define INT_34XX_MCBSP4_IRQ	23
++#define INT_34XX_CAM_IRQ	24
++#define INT_34XX_MCBSP5_IRQ	27
++#define INT_34XX_GPIO_BANK1	29
++#define INT_34XX_GPIO_BANK2	30
++#define INT_34XX_GPIO_BANK3	31
++#define INT_34XX_GPIO_BANK4	32
++#define INT_34XX_GPIO_BANK5	33
++#define INT_34XX_GPIO_BANK6	34
++#define INT_34XX_USIM_IRQ	35
++#define INT_34XX_WDT3_IRQ	36
++#define INT_34XX_SPI4_IRQ	48
++#define INT_34XX_SHA1MD52_IRQ	49
++#define INT_34XX_FPKA_READY_IRQ	50
++#define INT_34XX_SHA1MD51_IRQ	51
++#define INT_34XX_RNG_IRQ	52
++#define INT_34XX_I2C3_IRQ	61
++#define INT_34XX_FPKA_ERROR_IRQ	64
++#define INT_34XX_PBIAS_IRQ	75
++#define INT_34XX_OHCI_IRQ	76
++#define INT_34XX_EHCI_IRQ	77
++#define INT_34XX_TLL_IRQ	78
++#define INT_34XX_PARTHASH_IRQ	79
++#define INT_34XX_MMC3_IRQ	94
++#define INT_34XX_GPT12_IRQ	95
++
++#define	INT_34XX_BENCH_MPU_EMUL	3
++
++
++#define IRQ_GIC_START		32
++#define INT_44XX_LOCALTIMER_IRQ	29
++#define INT_44XX_LOCALWDT_IRQ	30
++
++#define INT_44XX_BENCH_MPU_EMUL	(3 + IRQ_GIC_START)
++#define INT_44XX_SSM_ABORT_IRQ	(6 + IRQ_GIC_START)
++#define INT_44XX_SYS_NIRQ	(7 + IRQ_GIC_START)
++#define INT_44XX_D2D_FW_IRQ	(8 + IRQ_GIC_START)
++#define INT_44XX_PRCM_MPU_IRQ	(11 + IRQ_GIC_START)
++#define INT_44XX_SDMA_IRQ0	(12 + IRQ_GIC_START)
++#define INT_44XX_SDMA_IRQ1	(13 + IRQ_GIC_START)
++#define INT_44XX_SDMA_IRQ2	(14 + IRQ_GIC_START)
++#define INT_44XX_SDMA_IRQ3	(15 + IRQ_GIC_START)
++#define INT_44XX_ISS_IRQ	(24 + IRQ_GIC_START)
++#define INT_44XX_DSS_IRQ	(25 + IRQ_GIC_START)
++#define INT_44XX_MAIL_U0_MPU	(26 + IRQ_GIC_START)
++#define INT_44XX_DSP_MMU	(28 + IRQ_GIC_START)
++#define INT_44XX_GPTIMER1	(37 + IRQ_GIC_START)
++#define INT_44XX_GPTIMER2	(38 + IRQ_GIC_START)
++#define INT_44XX_GPTIMER3	(39 + IRQ_GIC_START)
++#define INT_44XX_GPTIMER4	(40 + IRQ_GIC_START)
++#define INT_44XX_GPTIMER5	(41 + IRQ_GIC_START)
++#define INT_44XX_GPTIMER6	(42 + IRQ_GIC_START)
++#define INT_44XX_GPTIMER7	(43 + IRQ_GIC_START)
++#define INT_44XX_GPTIMER8	(44 + IRQ_GIC_START)
++#define INT_44XX_GPTIMER9	(45 + IRQ_GIC_START)
++#define INT_44XX_GPTIMER10	(46 + IRQ_GIC_START)
++#define INT_44XX_GPTIMER11	(47 + IRQ_GIC_START)
++#define INT_44XX_GPTIMER12	(95 + IRQ_GIC_START)
++#define INT_44XX_SHA1MD5	(51 + IRQ_GIC_START)
++#define INT_44XX_I2C1_IRQ	(56 + IRQ_GIC_START)
++#define INT_44XX_I2C2_IRQ	(57 + IRQ_GIC_START)
++#define INT_44XX_HDQ_IRQ	(58 + IRQ_GIC_START)
++#define INT_44XX_SPI1_IRQ	(65 + IRQ_GIC_START)
++#define INT_44XX_SPI2_IRQ	(66 + IRQ_GIC_START)
++#define INT_44XX_HSI_1_IRQ0	(67 + IRQ_GIC_START)
++#define INT_44XX_HSI_2_IRQ1	(68 + IRQ_GIC_START)
++#define INT_44XX_HSI_1_DMAIRQ	(71 + IRQ_GIC_START)
++#define INT_44XX_UART1_IRQ	(72 + IRQ_GIC_START)
++#define INT_44XX_UART2_IRQ	(73 + IRQ_GIC_START)
++#define INT_44XX_UART3_IRQ	(74 + IRQ_GIC_START)
++#define INT_44XX_UART4_IRQ	(70 + IRQ_GIC_START)
++#define INT_44XX_USB_IRQ_NISO	(76 + IRQ_GIC_START)
++#define INT_44XX_USB_IRQ_ISO	(77 + IRQ_GIC_START)
++#define INT_44XX_USB_IRQ_HGEN	(78 + IRQ_GIC_START)
++#define INT_44XX_USB_IRQ_HSOF	(79 + IRQ_GIC_START)
++#define INT_44XX_USB_IRQ_OTG	(80 + IRQ_GIC_START)
++#define INT_44XX_MCBSP4_IRQ_TX	(81 + IRQ_GIC_START)
++#define INT_44XX_MCBSP4_IRQ_RX	(82 + IRQ_GIC_START)
++#define INT_44XX_MMC_IRQ	(83 + IRQ_GIC_START)
++#define INT_44XX_MMC2_IRQ	(86 + IRQ_GIC_START)
++#define INT_44XX_MCBSP2_IRQ_TX	(89 + IRQ_GIC_START)
++#define INT_44XX_MCBSP2_IRQ_RX	(90 + IRQ_GIC_START)
++#define INT_44XX_SPI3_IRQ	(91 + IRQ_GIC_START)
++#define INT_44XX_SPI5_IRQ	(69 + IRQ_GIC_START)
++
++#define INT_44XX_MCBSP5_IRQ	(16 + IRQ_GIC_START)
++#define INT_44xX_MCBSP1_IRQ	(17 + IRQ_GIC_START)
++#define INT_44XX_MCBSP2_IRQ	(22 + IRQ_GIC_START)
++#define INT_44XX_MCBSP3_IRQ	(23 + IRQ_GIC_START)
++#define INT_44XX_MCBSP4_IRQ	(27 + IRQ_GIC_START)
++#define INT_44XX_HS_USB_MC	(92 + IRQ_GIC_START)
++#define INT_44XX_HS_USB_DMA	(93 + IRQ_GIC_START)
++
++#define INT_44XX_GPIO_BANK1	(29 + IRQ_GIC_START)
++#define INT_44XX_GPIO_BANK2	(30 + IRQ_GIC_START)
++#define INT_44XX_GPIO_BANK3	(31 + IRQ_GIC_START)
++#define INT_44XX_GPIO_BANK4	(32 + IRQ_GIC_START)
++#define INT_44XX_GPIO_BANK5	(33 + IRQ_GIC_START)
++#define INT_44XX_GPIO_BANK6	(34 + IRQ_GIC_START)
++#define INT_44XX_USIM_IRQ	(35 + IRQ_GIC_START)
++#define INT_44XX_WDT3_IRQ	(36 + IRQ_GIC_START)
++#define INT_44XX_SPI4_IRQ	(48 + IRQ_GIC_START)
++#define INT_44XX_SHA1MD52_IRQ	(49 + IRQ_GIC_START)
++#define INT_44XX_FPKA_READY_IRQ	(50 + IRQ_GIC_START)
++#define INT_44XX_SHA1MD51_IRQ	(51 + IRQ_GIC_START)
++#define INT_44XX_RNG_IRQ	(52 + IRQ_GIC_START)
++#define INT_44XX_MMC5_IRQ	(59 + IRQ_GIC_START)
++#define INT_44XX_I2C3_IRQ	(61 + IRQ_GIC_START)
++#define INT_44XX_FPKA_ERROR_IRQ	(64 + IRQ_GIC_START)
++#define INT_44XX_PBIAS_IRQ	(75 + IRQ_GIC_START)
++#define INT_44XX_OHCI_IRQ	(76 + IRQ_GIC_START)
++#define INT_44XX_EHCI_IRQ	(77 + IRQ_GIC_START)
++#define INT_44XX_TLL_IRQ	(78 + IRQ_GIC_START)
++#define INT_44XX_PARTHASH_IRQ	(79 + IRQ_GIC_START)
++#define INT_44XX_MMC3_IRQ	(94 + IRQ_GIC_START)
++#define INT_44XX_MMC4_IRQ	(96 + IRQ_GIC_START)
++
++
++/* Max. 128 level 2 IRQs (OMAP1610), 192 GPIOs (OMAP730/850) and
++ * 16 MPUIO lines */
++#define OMAP_MAX_GPIO_LINES	192
++#define IH_GPIO_BASE		(128 + IH2_BASE)
++#define IH_MPUIO_BASE		(OMAP_MAX_GPIO_LINES + IH_GPIO_BASE)
++#define OMAP_IRQ_END		(IH_MPUIO_BASE + 16)
++
++/* External FPGA handles interrupts on Innovator boards */
++#define	OMAP_FPGA_IRQ_BASE	(OMAP_IRQ_END)
++#ifdef	CONFIG_MACH_OMAP_INNOVATOR
++#define OMAP_FPGA_NR_IRQS	24
++#else
++#define OMAP_FPGA_NR_IRQS	0
++#endif
++#define OMAP_FPGA_IRQ_END	(OMAP_FPGA_IRQ_BASE + OMAP_FPGA_NR_IRQS)
++
++/* External TWL4030 can handle interrupts on 2430 and 34xx boards */
++#define	TWL4030_IRQ_BASE	(OMAP_FPGA_IRQ_END)
++#ifdef	CONFIG_TWL4030_CORE
++#define	TWL4030_BASE_NR_IRQS	8
++#define	TWL4030_PWR_NR_IRQS	8
++#else
++#define	TWL4030_BASE_NR_IRQS	0
++#define	TWL4030_PWR_NR_IRQS	0
++#endif
++#define TWL4030_IRQ_END		(TWL4030_IRQ_BASE + TWL4030_BASE_NR_IRQS)
++#define TWL4030_PWR_IRQ_BASE	TWL4030_IRQ_END
++#define	TWL4030_PWR_IRQ_END	(TWL4030_PWR_IRQ_BASE + TWL4030_PWR_NR_IRQS)
++
++/* External TWL4030 gpio interrupts are optional */
++#define TWL4030_GPIO_IRQ_BASE	TWL4030_PWR_IRQ_END
++#ifdef	CONFIG_GPIO_TWL4030
++#define TWL4030_GPIO_NR_IRQS	18
++#else
++#define	TWL4030_GPIO_NR_IRQS	0
++#endif
++#define TWL4030_GPIO_IRQ_END	(TWL4030_GPIO_IRQ_BASE + TWL4030_GPIO_NR_IRQS)
++
++#define	TWL6030_IRQ_BASE	(OMAP_FPGA_IRQ_END)
++#ifdef CONFIG_TWL4030_CORE
++#define	TWL6030_BASE_NR_IRQS	20
++#else
++#define	TWL6030_BASE_NR_IRQS	0
++#endif
++#define TWL6030_IRQ_END		(TWL6030_IRQ_BASE + TWL6030_BASE_NR_IRQS)
++
++/* Total number of interrupts depends on the enabled blocks above */
++#if (TWL4030_GPIO_IRQ_END > TWL6030_IRQ_END)
++#define TWL_IRQ_END 		TWL4030_GPIO_IRQ_END
++#else
++#define TWL_IRQ_END		TWL6030_IRQ_END
++#endif
++
++#define NR_IRQS			TWL_IRQ_END
++
++#define OMAP_IRQ_BIT(irq)	(1 << ((irq) % 32))
++
++#define INTCPS_NR_MIR_REGS	3
++#define INTCPS_NR_IRQS		96
++
++#ifndef __ASSEMBLY__
++extern void omap_init_irq(void);
++extern int omap_irq_pending(void);
++void omap_intc_save_context(void);
++void omap_intc_restore_context(void);
++#endif
++
++#include <mach/hardware.h>
++
++#endif
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/keypad.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/keypad.h	2010-08-08 12:56:58.000000000 +0200
+@@ -0,0 +1,45 @@
++/*
++ *  arch/arm/plat-omap/include/mach/keypad.h
++ *
++ *  Copyright (C) 2006 Komal Shah <[email protected]>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++#ifndef ASMARM_ARCH_KEYPAD_H
++#define ASMARM_ARCH_KEYPAD_H
++
++#warning: Please update the board to use matrix_keypad.h instead
++
++struct omap_kp_platform_data {
++	int rows;
++	int cols;
++	int *keymap;
++	unsigned int keymapsize;
++	unsigned int rep:1;
++	unsigned long delay;
++	unsigned int dbounce:1;
++	/* specific to OMAP242x*/
++	unsigned int *row_gpios;
++	unsigned int *col_gpios;
++};
++
++/* Group (0..3) -- when multiple keys are pressed, only the
++ * keys pressed in the same group are considered as pressed. This is
++ * in order to workaround certain crappy HW designs that produce ghost
++ * keypresses. */
++#define GROUP_0		(0 << 16)
++#define GROUP_1		(1 << 16)
++#define GROUP_2		(2 << 16)
++#define GROUP_3		(3 << 16)
++#define GROUP_MASK	GROUP_3
++
++#define KEY_PERSISTENT		0x00800000
++#define KEYNUM_MASK		0x00EFFFFF
++#define KEY(col, row, val) (((col) << 28) | ((row) << 24) | (val))
++#define PERSISTENT_KEY(col, row) (((col) << 28) | ((row) << 24) | \
++						KEY_PERSISTENT)
++
++#endif
++
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/lcd_mipid.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/lcd_mipid.h	2010-08-08 12:56:59.000000000 +0200
+@@ -0,0 +1,29 @@
++#ifndef __LCD_MIPID_H
++#define __LCD_MIPID_H
++
++enum mipid_test_num {
++	MIPID_TEST_RGB_LINES,
++};
++
++enum mipid_test_result {
++	MIPID_TEST_SUCCESS,
++	MIPID_TEST_INVALID,
++	MIPID_TEST_FAILED,
++};
++
++#ifdef __KERNEL__
++
++struct mipid_platform_data {
++	int	nreset_gpio;
++	int	data_lines;
++
++	void	(*shutdown)(struct mipid_platform_data *pdata);
++	void	(*set_bklight_level)(struct mipid_platform_data *pdata,
++				     int level);
++	int	(*get_bklight_level)(struct mipid_platform_data *pdata);
++	int	(*get_bklight_max)(struct mipid_platform_data *pdata);
++};
++
++#endif
++
++#endif
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/led.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/led.h	2010-08-08 12:56:59.000000000 +0200
+@@ -0,0 +1,24 @@
++/*
++ *  arch/arm/plat-omap/include/mach/led.h
++ *
++ *  Copyright (C) 2006 Samsung Electronics
++ *  Kyungmin Park <[email protected]>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++#ifndef ASMARM_ARCH_LED_H
++#define ASMARM_ARCH_LED_H
++
++struct omap_led_config {
++	struct led_classdev	cdev;
++	s16			gpio;
++};
++
++struct omap_led_platform_data {
++	s16			nr_leds;
++	struct omap_led_config	*leds;
++};
++
++#endif
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/mailbox.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/mailbox.h	2010-08-08 12:57:00.000000000 +0200
+@@ -0,0 +1,111 @@
++/* mailbox.h */
++
++#ifndef MAILBOX_H
++#define MAILBOX_H
++
++#include <linux/wait.h>
++#include <linux/workqueue.h>
++#include <linux/blkdev.h>
++#include <linux/interrupt.h>
++
++typedef u32 mbox_msg_t;
++struct omap_mbox;
++
++typedef int __bitwise omap_mbox_irq_t;
++#define IRQ_TX ((__force omap_mbox_irq_t) 1)
++#define IRQ_RX ((__force omap_mbox_irq_t) 2)
++
++typedef int __bitwise omap_mbox_type_t;
++#define OMAP_MBOX_TYPE1 ((__force omap_mbox_type_t) 1)
++#define OMAP_MBOX_TYPE2 ((__force omap_mbox_type_t) 2)
++
++struct omap_mbox_ops {
++	omap_mbox_type_t	type;
++	int		(*startup)(struct omap_mbox *mbox);
++	void		(*shutdown)(struct omap_mbox *mbox);
++	/* fifo */
++	mbox_msg_t	(*fifo_read)(struct omap_mbox *mbox);
++	void		(*fifo_write)(struct omap_mbox *mbox, mbox_msg_t msg);
++	int		(*fifo_empty)(struct omap_mbox *mbox);
++	int		(*fifo_full)(struct omap_mbox *mbox);
++	/* irq */
++	void		(*enable_irq)(struct omap_mbox *mbox,
++						omap_mbox_irq_t irq);
++	void		(*disable_irq)(struct omap_mbox *mbox,
++						omap_mbox_irq_t irq);
++	void		(*ack_irq)(struct omap_mbox *mbox, omap_mbox_irq_t irq);
++	int		(*is_irq)(struct omap_mbox *mbox, omap_mbox_irq_t irq);
++	/* ctx */
++	void		(*save_ctx)(struct omap_mbox *mbox);
++	void		(*restore_ctx)(struct omap_mbox *mbox);
++};
++
++struct omap_mbox_queue {
++	spinlock_t		lock;
++	struct request_queue	*queue;
++	struct work_struct	work;
++	struct tasklet_struct	tasklet;
++	int	(*callback)(void *);
++	struct omap_mbox	*mbox;
++};
++
++struct omap_mbox {
++	char			*name;
++	unsigned int		irq;
++
++	struct omap_mbox_queue	*txq, *rxq;
++
++	struct omap_mbox_ops	*ops;
++
++	mbox_msg_t		seq_snd, seq_rcv;
++
++	struct device		*dev;
++
++	struct omap_mbox	*next;
++	void			*priv;
++
++	void			(*err_notify)(void);
++};
++
++int omap_mbox_msg_send(struct omap_mbox *, mbox_msg_t msg);
++void omap_mbox_init_seq(struct omap_mbox *);
++
++struct omap_mbox *omap_mbox_get(const char *);
++void omap_mbox_put(struct omap_mbox *);
++
++int omap_mbox_register(struct device *parent, struct omap_mbox *);
++int omap_mbox_unregister(struct omap_mbox *);
++
++static inline void omap_mbox_save_ctx(struct omap_mbox *mbox)
++{
++	if (!mbox->ops->save_ctx) {
++		dev_err(mbox->dev, "%s:\tno save\n", __func__);
++		return;
++	}
++
++	mbox->ops->save_ctx(mbox);
++}
++
++static inline void omap_mbox_restore_ctx(struct omap_mbox *mbox)
++{
++	if (!mbox->ops->restore_ctx) {
++		dev_err(mbox->dev, "%s:\tno restore\n", __func__);
++		return;
++	}
++
++	mbox->ops->restore_ctx(mbox);
++}
++
++static inline void omap_mbox_enable_irq(struct omap_mbox *mbox,
++					omap_mbox_irq_t irq)
++{
++	mbox->ops->enable_irq(mbox, irq);
++}
++
++static inline void omap_mbox_disable_irq(struct omap_mbox *mbox,
++					 omap_mbox_irq_t irq)
++{
++	mbox->ops->disable_irq(mbox, irq);
++}
++
++#endif /* MAILBOX_H */
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/mcbsp.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/mcbsp.h	2010-08-08 12:57:01.000000000 +0200
+@@ -0,0 +1,462 @@
++/*
++ * arch/arm/plat-omap/include/mach/mcbsp.h
++ *
++ * Defines for Multi-Channel Buffered Serial Port
++ *
++ * Copyright (C) 2002 RidgeRun, Inc.
++ * Author: Steve Johnson
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++#ifndef __ASM_ARCH_OMAP_MCBSP_H
++#define __ASM_ARCH_OMAP_MCBSP_H
++
++#include <linux/completion.h>
++#include <linux/spinlock.h>
++
++#include <mach/hardware.h>
++#include <plat/clock.h>
++
++#define OMAP7XX_MCBSP1_BASE	0xfffb1000
++#define OMAP7XX_MCBSP2_BASE	0xfffb1800
++
++#define OMAP1510_MCBSP1_BASE	0xe1011800
++#define OMAP1510_MCBSP2_BASE	0xfffb1000
++#define OMAP1510_MCBSP3_BASE	0xe1017000
++
++#define OMAP1610_MCBSP1_BASE	0xe1011800
++#define OMAP1610_MCBSP2_BASE	0xfffb1000
++#define OMAP1610_MCBSP3_BASE	0xe1017000
++
++#define OMAP24XX_MCBSP1_BASE	0x48074000
++#define OMAP24XX_MCBSP2_BASE	0x48076000
++#define OMAP2430_MCBSP3_BASE	0x4808c000
++#define OMAP2430_MCBSP4_BASE	0x4808e000
++#define OMAP2430_MCBSP5_BASE	0x48096000
++
++#define OMAP34XX_MCBSP1_BASE	0x48074000
++#define OMAP34XX_MCBSP2_BASE	0x49022000
++#define OMAP34XX_MCBSP3_BASE	0x49024000
++#define OMAP34XX_MCBSP4_BASE	0x49026000
++#define OMAP34XX_MCBSP5_BASE	0x48096000
++
++#define OMAP44XX_MCBSP1_BASE	0x49022000
++#define OMAP44XX_MCBSP2_BASE	0x49024000
++#define OMAP44XX_MCBSP3_BASE	0x49026000
++#define OMAP44XX_MCBSP4_BASE	0x48074000
++
++#if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
++
++#define OMAP_MCBSP_REG_DRR2	0x00
++#define OMAP_MCBSP_REG_DRR1	0x02
++#define OMAP_MCBSP_REG_DXR2	0x04
++#define OMAP_MCBSP_REG_DXR1	0x06
++#define OMAP_MCBSP_REG_SPCR2	0x08
++#define OMAP_MCBSP_REG_SPCR1	0x0a
++#define OMAP_MCBSP_REG_RCR2	0x0c
++#define OMAP_MCBSP_REG_RCR1	0x0e
++#define OMAP_MCBSP_REG_XCR2	0x10
++#define OMAP_MCBSP_REG_XCR1	0x12
++#define OMAP_MCBSP_REG_SRGR2	0x14
++#define OMAP_MCBSP_REG_SRGR1	0x16
++#define OMAP_MCBSP_REG_MCR2	0x18
++#define OMAP_MCBSP_REG_MCR1	0x1a
++#define OMAP_MCBSP_REG_RCERA	0x1c
++#define OMAP_MCBSP_REG_RCERB	0x1e
++#define OMAP_MCBSP_REG_XCERA	0x20
++#define OMAP_MCBSP_REG_XCERB	0x22
++#define OMAP_MCBSP_REG_PCR0	0x24
++#define OMAP_MCBSP_REG_RCERC	0x26
++#define OMAP_MCBSP_REG_RCERD	0x28
++#define OMAP_MCBSP_REG_XCERC	0x2A
++#define OMAP_MCBSP_REG_XCERD	0x2C
++#define OMAP_MCBSP_REG_RCERE	0x2E
++#define OMAP_MCBSP_REG_RCERF	0x30
++#define OMAP_MCBSP_REG_XCERE	0x32
++#define OMAP_MCBSP_REG_XCERF	0x34
++#define OMAP_MCBSP_REG_RCERG	0x36
++#define OMAP_MCBSP_REG_RCERH	0x38
++#define OMAP_MCBSP_REG_XCERG	0x3A
++#define OMAP_MCBSP_REG_XCERH	0x3C
++
++/* Dummy defines, these are not available on omap1 */
++#define OMAP_MCBSP_REG_XCCR	0x00
++#define OMAP_MCBSP_REG_RCCR	0x00
++
++#define AUDIO_MCBSP_DATAWRITE	(OMAP1510_MCBSP1_BASE + OMAP_MCBSP_REG_DXR1)
++#define AUDIO_MCBSP_DATAREAD	(OMAP1510_MCBSP1_BASE + OMAP_MCBSP_REG_DRR1)
++
++#define AUDIO_MCBSP		OMAP_MCBSP1
++#define AUDIO_DMA_TX		OMAP_DMA_MCBSP1_TX
++#define AUDIO_DMA_RX		OMAP_DMA_MCBSP1_RX
++
++#elif defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
++	defined(CONFIG_ARCH_OMAP4)
++
++#define OMAP_MCBSP_REG_DRR2	0x00
++#define OMAP_MCBSP_REG_DRR1	0x04
++#define OMAP_MCBSP_REG_DXR2	0x08
++#define OMAP_MCBSP_REG_DXR1	0x0C
++#define OMAP_MCBSP_REG_DRR	0x00
++#define OMAP_MCBSP_REG_DXR	0x08
++#define OMAP_MCBSP_REG_SPCR2	0x10
++#define OMAP_MCBSP_REG_SPCR1	0x14
++#define OMAP_MCBSP_REG_RCR2	0x18
++#define OMAP_MCBSP_REG_RCR1	0x1C
++#define OMAP_MCBSP_REG_XCR2	0x20
++#define OMAP_MCBSP_REG_XCR1	0x24
++#define OMAP_MCBSP_REG_SRGR2	0x28
++#define OMAP_MCBSP_REG_SRGR1	0x2C
++#define OMAP_MCBSP_REG_MCR2	0x30
++#define OMAP_MCBSP_REG_MCR1	0x34
++#define OMAP_MCBSP_REG_RCERA	0x38
++#define OMAP_MCBSP_REG_RCERB	0x3C
++#define OMAP_MCBSP_REG_XCERA	0x40
++#define OMAP_MCBSP_REG_XCERB	0x44
++#define OMAP_MCBSP_REG_PCR0	0x48
++#define OMAP_MCBSP_REG_RCERC	0x4C
++#define OMAP_MCBSP_REG_RCERD	0x50
++#define OMAP_MCBSP_REG_XCERC	0x54
++#define OMAP_MCBSP_REG_XCERD	0x58
++#define OMAP_MCBSP_REG_RCERE	0x5C
++#define OMAP_MCBSP_REG_RCERF	0x60
++#define OMAP_MCBSP_REG_XCERE	0x64
++#define OMAP_MCBSP_REG_XCERF	0x68
++#define OMAP_MCBSP_REG_RCERG	0x6C
++#define OMAP_MCBSP_REG_RCERH	0x70
++#define OMAP_MCBSP_REG_XCERG	0x74
++#define OMAP_MCBSP_REG_XCERH	0x78
++#define OMAP_MCBSP_REG_SYSCON	0x8C
++#define OMAP_MCBSP_REG_THRSH2	0x90
++#define OMAP_MCBSP_REG_THRSH1	0x94
++#define OMAP_MCBSP_REG_IRQST	0xA0
++#define OMAP_MCBSP_REG_IRQEN	0xA4
++#define OMAP_MCBSP_REG_WAKEUPEN	0xA8
++#define OMAP_MCBSP_REG_XCCR	0xAC
++#define OMAP_MCBSP_REG_RCCR	0xB0
++
++#define AUDIO_MCBSP_DATAWRITE	(OMAP24XX_MCBSP2_BASE + OMAP_MCBSP_REG_DXR1)
++#define AUDIO_MCBSP_DATAREAD	(OMAP24XX_MCBSP2_BASE + OMAP_MCBSP_REG_DRR1)
++
++#define AUDIO_MCBSP		OMAP_MCBSP2
++#define AUDIO_DMA_TX		OMAP24XX_DMA_MCBSP2_TX
++#define AUDIO_DMA_RX		OMAP24XX_DMA_MCBSP2_RX
++
++#endif
++
++/************************** McBSP SPCR1 bit definitions ***********************/
++#define RRST			0x0001
++#define RRDY			0x0002
++#define RFULL			0x0004
++#define RSYNC_ERR		0x0008
++#define RINTM(value)		((value)<<4)	/* bits 4:5 */
++#define ABIS			0x0040
++#define DXENA			0x0080
++#define CLKSTP(value)		((value)<<11)	/* bits 11:12 */
++#define RJUST(value)		((value)<<13)	/* bits 13:14 */
++#define ALB			0x8000
++#define DLB			0x8000
++
++/************************** McBSP SPCR2 bit definitions ***********************/
++#define XRST		0x0001
++#define XRDY		0x0002
++#define XEMPTY		0x0004
++#define XSYNC_ERR	0x0008
++#define XINTM(value)	((value)<<4)		/* bits 4:5 */
++#define GRST		0x0040
++#define FRST		0x0080
++#define SOFT		0x0100
++#define FREE		0x0200
++
++/************************** McBSP PCR bit definitions *************************/
++#define CLKRP		0x0001
++#define CLKXP		0x0002
++#define FSRP		0x0004
++#define FSXP		0x0008
++#define DR_STAT		0x0010
++#define DX_STAT		0x0020
++#define CLKS_STAT	0x0040
++#define SCLKME		0x0080
++#define CLKRM		0x0100
++#define CLKXM		0x0200
++#define FSRM		0x0400
++#define FSXM		0x0800
++#define RIOEN		0x1000
++#define XIOEN		0x2000
++#define IDLE_EN		0x4000
++
++/************************** McBSP RCR1 bit definitions ************************/
++#define RWDLEN1(value)		((value)<<5)	/* Bits 5:7 */
++#define RFRLEN1(value)		((value)<<8)	/* Bits 8:14 */
++
++/************************** McBSP XCR1 bit definitions ************************/
++#define XWDLEN1(value)		((value)<<5)	/* Bits 5:7 */
++#define XFRLEN1(value)		((value)<<8)	/* Bits 8:14 */
++
++/*************************** McBSP RCR2 bit definitions ***********************/
++#define RDATDLY(value)		(value)		/* Bits 0:1 */
++#define RFIG			0x0004
++#define RCOMPAND(value)		((value)<<3)	/* Bits 3:4 */
++#define RWDLEN2(value)		((value)<<5)	/* Bits 5:7 */
++#define RFRLEN2(value)		((value)<<8)	/* Bits 8:14 */
++#define RPHASE			0x8000
++
++/*************************** McBSP XCR2 bit definitions ***********************/
++#define XDATDLY(value)		(value)		/* Bits 0:1 */
++#define XFIG			0x0004
++#define XCOMPAND(value)		((value)<<3)	/* Bits 3:4 */
++#define XWDLEN2(value)		((value)<<5)	/* Bits 5:7 */
++#define XFRLEN2(value)		((value)<<8)	/* Bits 8:14 */
++#define XPHASE			0x8000
++
++/************************* McBSP SRGR1 bit definitions ************************/
++#define CLKGDV(value)		(value)		/* Bits 0:7 */
++#define FWID(value)		((value)<<8)	/* Bits 8:15 */
++
++/************************* McBSP SRGR2 bit definitions ************************/
++#define FPER(value)		(value)		/* Bits 0:11 */
++#define FSGM			0x1000
++#define CLKSM			0x2000
++#define CLKSP			0x4000
++#define GSYNC			0x8000
++
++/************************* McBSP MCR1 bit definitions *************************/
++#define RMCM			0x0001
++#define RCBLK(value)		((value)<<2)	/* Bits 2:4 */
++#define RPABLK(value)		((value)<<5)	/* Bits 5:6 */
++#define RPBBLK(value)		((value)<<7)	/* Bits 7:8 */
++
++/************************* McBSP MCR2 bit definitions *************************/
++#define XMCM(value)		(value)		/* Bits 0:1 */
++#define XCBLK(value)		((value)<<2)	/* Bits 2:4 */
++#define XPABLK(value)		((value)<<5)	/* Bits 5:6 */
++#define XPBBLK(value)		((value)<<7)	/* Bits 7:8 */
++
++/*********************** McBSP XCCR bit definitions *************************/
++#define EXTCLKGATE		0x8000
++#define PPCONNECT		0x4000
++#define DXENDLY(value)		((value)<<12)	/* Bits 12:13 */
++#define XFULL_CYCLE		0x0800
++#define DILB			0x0020
++#define XDMAEN			0x0008
++#define XDISABLE		0x0001
++
++/********************** McBSP RCCR bit definitions *************************/
++#define RFULL_CYCLE		0x0800
++#define RDMAEN			0x0008
++#define RDISABLE		0x0001
++
++/********************** McBSP SYSCONFIG bit definitions ********************/
++#define CLOCKACTIVITY(value)	((value)<<8)
++#define SIDLEMODE(value)	((value)<<3)
++#define ENAWAKEUP		0x0004
++#define SOFTRST			0x0002
++
++/********************** McBSP DMA operating modes **************************/
++#define MCBSP_DMA_MODE_ELEMENT		0
++#define MCBSP_DMA_MODE_THRESHOLD	1
++#define MCBSP_DMA_MODE_FRAME		2
++
++/********************** McBSP WAKEUPEN bit definitions *********************/
++#define XEMPTYEOFEN		0x4000
++#define XRDYEN			0x0400
++#define XEOFEN			0x0200
++#define XFSXEN			0x0100
++#define XSYNCERREN		0x0080
++#define RRDYEN			0x0008
++#define REOFEN			0x0004
++#define RFSREN			0x0002
++#define RSYNCERREN		0x0001
++
++/* we don't do multichannel for now */
++struct omap_mcbsp_reg_cfg {
++	u16 spcr2;
++	u16 spcr1;
++	u16 rcr2;
++	u16 rcr1;
++	u16 xcr2;
++	u16 xcr1;
++	u16 srgr2;
++	u16 srgr1;
++	u16 mcr2;
++	u16 mcr1;
++	u16 pcr0;
++	u16 rcerc;
++	u16 rcerd;
++	u16 xcerc;
++	u16 xcerd;
++	u16 rcere;
++	u16 rcerf;
++	u16 xcere;
++	u16 xcerf;
++	u16 rcerg;
++	u16 rcerh;
++	u16 xcerg;
++	u16 xcerh;
++	u16 xccr;
++	u16 rccr;
++};
++
++typedef enum {
++	OMAP_MCBSP1 = 0,
++	OMAP_MCBSP2,
++	OMAP_MCBSP3,
++	OMAP_MCBSP4,
++	OMAP_MCBSP5
++} omap_mcbsp_id;
++
++typedef int __bitwise omap_mcbsp_io_type_t;
++#define OMAP_MCBSP_IRQ_IO ((__force omap_mcbsp_io_type_t) 1)
++#define OMAP_MCBSP_POLL_IO ((__force omap_mcbsp_io_type_t) 2)
++
++typedef enum {
++	OMAP_MCBSP_WORD_8 = 0,
++	OMAP_MCBSP_WORD_12,
++	OMAP_MCBSP_WORD_16,
++	OMAP_MCBSP_WORD_20,
++	OMAP_MCBSP_WORD_24,
++	OMAP_MCBSP_WORD_32,
++} omap_mcbsp_word_length;
++
++typedef enum {
++	OMAP_MCBSP_CLK_RISING = 0,
++	OMAP_MCBSP_CLK_FALLING,
++} omap_mcbsp_clk_polarity;
++
++typedef enum {
++	OMAP_MCBSP_FS_ACTIVE_HIGH = 0,
++	OMAP_MCBSP_FS_ACTIVE_LOW,
++} omap_mcbsp_fs_polarity;
++
++typedef enum {
++	OMAP_MCBSP_CLK_STP_MODE_NO_DELAY = 0,
++	OMAP_MCBSP_CLK_STP_MODE_DELAY,
++} omap_mcbsp_clk_stp_mode;
++
++
++/******* SPI specific mode **********/
++typedef enum {
++	OMAP_MCBSP_SPI_MASTER = 0,
++	OMAP_MCBSP_SPI_SLAVE,
++} omap_mcbsp_spi_mode;
++
++struct omap_mcbsp_spi_cfg {
++	omap_mcbsp_spi_mode		spi_mode;
++	omap_mcbsp_clk_polarity		rx_clock_polarity;
++	omap_mcbsp_clk_polarity		tx_clock_polarity;
++	omap_mcbsp_fs_polarity		fsx_polarity;
++	u8				clk_div;
++	omap_mcbsp_clk_stp_mode		clk_stp_mode;
++	omap_mcbsp_word_length		word_length;
++};
++
++/* Platform specific configuration */
++struct omap_mcbsp_ops {
++	void (*request)(unsigned int);
++	void (*free)(unsigned int);
++};
++
++struct omap_mcbsp_platform_data {
++	unsigned long phys_base;
++	u8 dma_rx_sync, dma_tx_sync;
++	u16 rx_irq, tx_irq;
++	struct omap_mcbsp_ops *ops;
++#ifdef CONFIG_ARCH_OMAP34XX
++	u16 buffer_size;
++#endif
++};
++
++struct omap_mcbsp {
++	struct device *dev;
++	unsigned long phys_base;
++	void __iomem *io_base;
++	u8 id;
++	u8 free;
++	omap_mcbsp_word_length rx_word_length;
++	omap_mcbsp_word_length tx_word_length;
++
++	omap_mcbsp_io_type_t io_type; /* IRQ or poll */
++	/* IRQ based TX/RX */
++	int rx_irq;
++	int tx_irq;
++
++	/* DMA stuff */
++	u8 dma_rx_sync;
++	short dma_rx_lch;
++	u8 dma_tx_sync;
++	short dma_tx_lch;
++
++	/* Completion queues */
++	struct completion tx_irq_completion;
++	struct completion rx_irq_completion;
++	struct completion tx_dma_completion;
++	struct completion rx_dma_completion;
++
++	/* Protect the field .free, while checking if the mcbsp is in use */
++	spinlock_t lock;
++	struct omap_mcbsp_platform_data *pdata;
++	struct clk *iclk;
++	struct clk *fclk;
++#ifdef CONFIG_ARCH_OMAP34XX
++	int dma_op_mode;
++	u16 max_tx_thres;
++	u16 max_rx_thres;
++#endif
++};
++extern struct omap_mcbsp **mcbsp_ptr;
++extern int omap_mcbsp_count;
++
++int omap_mcbsp_init(void);
++void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config,
++					int size);
++void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg * config);
++#ifdef CONFIG_ARCH_OMAP34XX
++void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold);
++void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold);
++u16 omap_mcbsp_get_max_tx_threshold(unsigned int id);
++u16 omap_mcbsp_get_max_rx_threshold(unsigned int id);
++int omap_mcbsp_get_dma_op_mode(unsigned int id);
++#else
++static inline void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold)
++{ }
++static inline void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold)
++{ }
++static inline u16 omap_mcbsp_get_max_tx_threshold(unsigned int id) { return 0; }
++static inline u16 omap_mcbsp_get_max_rx_threshold(unsigned int id) { return 0; }
++static inline int omap_mcbsp_get_dma_op_mode(unsigned int id) { return 0; }
++#endif
++int omap_mcbsp_request(unsigned int id);
++void omap_mcbsp_free(unsigned int id);
++void omap_mcbsp_start(unsigned int id, int tx, int rx);
++void omap_mcbsp_stop(unsigned int id, int tx, int rx);
++void omap_mcbsp_xmit_word(unsigned int id, u32 word);
++u32 omap_mcbsp_recv_word(unsigned int id);
++
++int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, unsigned int length);
++int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, unsigned int length);
++int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word);
++int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 * word);
++
++
++/* SPI specific API */
++void omap_mcbsp_set_spi_mode(unsigned int id, const struct omap_mcbsp_spi_cfg * spi_cfg);
++
++/* Polled read/write functions */
++int omap_mcbsp_pollread(unsigned int id, u16 * buf);
++int omap_mcbsp_pollwrite(unsigned int id, u16 buf);
++int omap_mcbsp_set_io_type(unsigned int id, omap_mcbsp_io_type_t io_type);
++
++#endif
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/mcspi.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/mcspi.h	2010-08-08 12:57:01.000000000 +0200
+@@ -0,0 +1,15 @@
++#ifndef _OMAP2_MCSPI_H
++#define _OMAP2_MCSPI_H
++
++struct omap2_mcspi_platform_config {
++	unsigned short	num_cs;
++};
++
++struct omap2_mcspi_device_config {
++	unsigned turbo_mode:1;
++
++	/* Do we want one channel enabled at the same time? */
++	unsigned single_channel:1;
++};
++
++#endif
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/memory.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/memory.h	2010-08-08 12:57:02.000000000 +0200
+@@ -0,0 +1,103 @@
++/*
++ * arch/arm/plat-omap/include/mach/memory.h
++ *
++ * Memory map for OMAP-1510 and 1610
++ *
++ * Copyright (C) 2000 RidgeRun, Inc.
++ * Author: Greg Lonnon <[email protected]>
++ *
++ * This file was derived from arch/arm/mach-intergrator/include/mach/memory.h
++ * Copyright (C) 1999 ARM Limited
++ *
++ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ *
++ * 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.,
++ * 675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++
++#ifndef __ASM_ARCH_MEMORY_H
++#define __ASM_ARCH_MEMORY_H
++
++/*
++ * Physical DRAM offset.
++ */
++#if defined(CONFIG_ARCH_OMAP1)
++#define PHYS_OFFSET		UL(0x10000000)
++#elif defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) || \
++			defined(CONFIG_ARCH_OMAP4)
++#define PHYS_OFFSET		UL(0x80000000)
++#endif
++
++/*
++ * Bus address is physical address, except for OMAP-1510 Local Bus.
++ * OMAP-1510 bus address is translated into a Local Bus address if the
++ * OMAP bus type is lbus. We do the address translation based on the
++ * device overriding the defaults used in the dma-mapping API.
++ * Note that the is_lbus_device() test is not very efficient on 1510
++ * because of the strncmp().
++ */
++#ifdef CONFIG_ARCH_OMAP15XX
++
++/*
++ * OMAP-1510 Local Bus address offset
++ */
++#define OMAP1510_LB_OFFSET	UL(0x30000000)
++
++#define virt_to_lbus(x)		((x) - PAGE_OFFSET + OMAP1510_LB_OFFSET)
++#define lbus_to_virt(x)		((x) - OMAP1510_LB_OFFSET + PAGE_OFFSET)
++#define is_lbus_device(dev)	(cpu_is_omap15xx() && dev && (strncmp(dev_name(dev), "ohci", 4) == 0))
++
++#define __arch_page_to_dma(dev, page)	\
++	({ dma_addr_t __dma = page_to_phys(page); \
++	   if (is_lbus_device(dev)) \
++		__dma = __dma - PHYS_OFFSET + OMAP1510_LB_OFFSET; \
++	   __dma; })
++
++#define __arch_dma_to_page(dev, addr)	\
++	({ dma_addr_t __dma = addr;				\
++	   if (is_lbus_device(dev))				\
++		__dma += PHYS_OFFSET - OMAP1510_LB_OFFSET;	\
++	   phys_to_page(__dma);					\
++	})
++
++#define __arch_dma_to_virt(dev, addr)	({ (void *) (is_lbus_device(dev) ? \
++						lbus_to_virt(addr) : \
++						__phys_to_virt(addr)); })
++
++#define __arch_virt_to_dma(dev, addr)	({ unsigned long __addr = (unsigned long)(addr); \
++					   (dma_addr_t) (is_lbus_device(dev) ? \
++						virt_to_lbus(__addr) : \
++						__virt_to_phys(__addr)); })
++
++#endif	/* CONFIG_ARCH_OMAP15XX */
++
++/* Override the ARM default */
++#ifdef CONFIG_FB_OMAP_CONSISTENT_DMA_SIZE
++
++#if (CONFIG_FB_OMAP_CONSISTENT_DMA_SIZE == 0)
++#undef CONFIG_FB_OMAP_CONSISTENT_DMA_SIZE
++#define CONFIG_FB_OMAP_CONSISTENT_DMA_SIZE 2
++#endif
++
++#define CONSISTENT_DMA_SIZE \
++	(((CONFIG_FB_OMAP_CONSISTENT_DMA_SIZE + 1) & ~1) * 1024 * 1024)
++
++#endif
++
++#endif
++
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/menelaus.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/menelaus.h	2010-08-08 12:57:02.000000000 +0200
+@@ -0,0 +1,49 @@
++/*
++ * arch/arm/plat-omap/include/mach/menelaus.h
++ *
++ * Functions to access Menelaus power management chip
++ */
++
++#ifndef __ASM_ARCH_MENELAUS_H
++#define __ASM_ARCH_MENELAUS_H
++
++struct device;
++
++struct menelaus_platform_data {
++	int (* late_init)(struct device *dev);
++};
++
++extern int menelaus_register_mmc_callback(void (*callback)(void *data, u8 card_mask),
++					  void *data);
++extern void menelaus_unregister_mmc_callback(void);
++extern int menelaus_set_mmc_opendrain(int slot, int enable);
++extern int menelaus_set_mmc_slot(int slot, int enable, int power, int cd_on);
++
++extern int menelaus_set_vmem(unsigned int mV);
++extern int menelaus_set_vio(unsigned int mV);
++extern int menelaus_set_vmmc(unsigned int mV);
++extern int menelaus_set_vaux(unsigned int mV);
++extern int menelaus_set_vdcdc(int dcdc, unsigned int mV);
++extern int menelaus_set_slot_sel(int enable);
++extern int menelaus_get_slot_pin_states(void);
++extern int menelaus_set_vcore_sw(unsigned int mV);
++extern int menelaus_set_vcore_hw(unsigned int roof_mV, unsigned int floor_mV);
++
++#define EN_VPLL_SLEEP	(1 << 7)
++#define EN_VMMC_SLEEP	(1 << 6)
++#define EN_VAUX_SLEEP	(1 << 5)
++#define EN_VIO_SLEEP	(1 << 4)
++#define EN_VMEM_SLEEP	(1 << 3)
++#define EN_DC3_SLEEP	(1 << 2)
++#define EN_DC2_SLEEP	(1 << 1)
++#define EN_VC_SLEEP	(1 << 0)
++
++extern int menelaus_set_regulator_sleep(int enable, u32 val);
++
++#if defined(CONFIG_ARCH_OMAP24XX) && defined(CONFIG_MENELAUS)
++#define omap_has_menelaus()	1
++#else
++#define omap_has_menelaus()	0
++#endif
++
++#endif
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/mmc.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/mmc.h	2010-08-08 12:57:03.000000000 +0200
+@@ -0,0 +1,157 @@
++/*
++ * MMC definitions for OMAP2
++ *
++ * Copyright (C) 2006 Nokia Corporation
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#ifndef __OMAP2_MMC_H
++#define __OMAP2_MMC_H
++
++#include <linux/types.h>
++#include <linux/device.h>
++#include <linux/mmc/host.h>
++
++#include <plat/board.h>
++
++#define OMAP15XX_NR_MMC		1
++#define OMAP16XX_NR_MMC		2
++#define OMAP1_MMC_SIZE		0x080
++#define OMAP1_MMC1_BASE		0xfffb7800
++#define OMAP1_MMC2_BASE		0xfffb7c00	/* omap16xx only */
++
++#define OMAP24XX_NR_MMC		2
++#define OMAP34XX_NR_MMC		3
++#define OMAP44XX_NR_MMC		5
++#define OMAP2420_MMC_SIZE	OMAP1_MMC_SIZE
++#define OMAP3_HSMMC_SIZE	0x200
++#define OMAP4_HSMMC_SIZE	0x1000
++#define OMAP2_MMC1_BASE		0x4809c000
++#define OMAP2_MMC2_BASE		0x480b4000
++#define OMAP3_MMC3_BASE		0x480ad000
++#define OMAP4_MMC4_BASE		0x480d1000
++#define OMAP4_MMC5_BASE		0x480d5000
++#define OMAP4_MMC_REG_OFFSET	0x100
++#define HSMMC5			(1 << 4)
++#define HSMMC4			(1 << 3)
++#define HSMMC3			(1 << 2)
++#define HSMMC2			(1 << 1)
++#define HSMMC1			(1 << 0)
++
++#define OMAP_MMC_MAX_SLOTS	2
++
++struct omap_mmc_platform_data {
++	/* back-link to device */
++	struct device *dev;
++
++	/* number of slots per controller */
++	unsigned nr_slots:2;
++
++	/* set if your board has components or wiring that limits the
++	 * maximum frequency on the MMC bus */
++	unsigned int max_freq;
++
++	/* switch the bus to a new slot */
++	int (* switch_slot)(struct device *dev, int slot);
++	/* initialize board-specific MMC functionality, can be NULL if
++	 * not supported */
++	int (* init)(struct device *dev);
++	void (* cleanup)(struct device *dev);
++	void (* shutdown)(struct device *dev);
++
++	/* To handle board related suspend/resume functionality for MMC */
++	int (*suspend)(struct device *dev, int slot);
++	int (*resume)(struct device *dev, int slot);
++
++	/* Return context loss count due to PM states changing */
++	int (*get_context_loss_count)(struct device *dev);
++
++	u64 dma_mask;
++
++	struct omap_mmc_slot_data {
++
++		/* 4 wire signaling is optional, and is used for SD/SDIO/HSMMC;
++		 * 8 wire signaling is also optional, and is used with HSMMC
++		 */
++		u8 wires;
++
++		/*
++		 * nomux means "standard" muxing is wrong on this board, and
++		 * that board-specific code handled it before common init logic.
++		 */
++		unsigned nomux:1;
++
++		/* switch pin can be for card detect (default) or card cover */
++		unsigned cover:1;
++
++		/* use the internal clock */
++		unsigned internal_clock:1;
++
++		/* nonremovable e.g. eMMC */
++		unsigned nonremovable:1;
++
++		/* Try to sleep or power off when possible */
++		unsigned power_saving:1;
++
++		int switch_pin;			/* gpio (card detect) */
++		int gpio_wp;			/* gpio (write protect) */
++
++		int (* set_bus_mode)(struct device *dev, int slot, int bus_mode);
++		int (* set_power)(struct device *dev, int slot, int power_on, int vdd);
++		int (* get_ro)(struct device *dev, int slot);
++		int (*set_sleep)(struct device *dev, int slot, int sleep,
++				 int vdd, int cardsleep);
++
++		/* return MMC cover switch state, can be NULL if not supported.
++		 *
++		 * possible return values:
++		 *   0 - closed
++		 *   1 - open
++		 */
++		int (* get_cover_state)(struct device *dev, int slot);
++
++		const char *name;
++		u32 ocr_mask;
++
++		/* Card detection IRQs */
++		int card_detect_irq;
++		int (* card_detect)(int irq);
++
++		unsigned int ban_openended:1;
++
++	} slots[OMAP_MMC_MAX_SLOTS];
++};
++
++/* called from board-specific card detection service routine */
++extern void omap_mmc_notify_cover_event(struct device *dev, int slot, int is_closed);
++
++#if	defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \
++	defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
++void omap1_init_mmc(struct omap_mmc_platform_data **mmc_data,
++				int nr_controllers);
++void omap2_init_mmc(struct omap_mmc_platform_data **mmc_data,
++				int nr_controllers);
++int omap_mmc_add(const char *name, int id, unsigned long base,
++				unsigned long size, unsigned int irq,
++				struct omap_mmc_platform_data *data);
++#else
++static inline void omap1_init_mmc(struct omap_mmc_platform_data **mmc_data,
++				int nr_controllers)
++{
++}
++static inline void omap2_init_mmc(struct omap_mmc_platform_data **mmc_data,
++				int nr_controllers)
++{
++}
++static inline int omap_mmc_add(const char *name, int id, unsigned long base,
++				unsigned long size, unsigned int irq,
++				struct omap_mmc_platform_data *data)
++{
++	return 0;
++}
++
++#endif
++#endif
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/mux.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/mux.h	2010-08-08 12:57:04.000000000 +0200
+@@ -0,0 +1,662 @@
++/*
++ * arch/arm/plat-omap/include/mach/mux.h
++ *
++ * Table of the Omap register configurations for the FUNC_MUX and
++ * PULL_DWN combinations.
++ *
++ * Copyright (C) 2004 - 2008 Texas Instruments Inc.
++ * Copyright (C) 2003 - 2008 Nokia Corporation
++ *
++ * Written by Tony Lindgren
++ *
++ * 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
++ *
++ * NOTE: Please use the following naming style for new pin entries.
++ *	 For example, W8_1610_MMC2_DAT0, where:
++ *	 - W8	     = ball
++ *	 - 1610	     = 1510 or 1610, none if common for both 1510 and 1610
++ *	 - MMC2_DAT0 = function
++ */
++
++#ifndef __ASM_ARCH_MUX_H
++#define __ASM_ARCH_MUX_H
++
++#define PU_PD_SEL_NA		0	/* No pu_pd reg available */
++#define PULL_DWN_CTRL_NA	0	/* No pull-down control needed */
++
++#ifdef	CONFIG_OMAP_MUX_DEBUG
++#define MUX_REG(reg, mode_offset, mode) .mux_reg_name = "FUNC_MUX_CTRL_"#reg, \
++					.mux_reg = FUNC_MUX_CTRL_##reg, \
++					.mask_offset = mode_offset, \
++					.mask = mode,
++
++#define PULL_REG(reg, bit, status)	.pull_name = "PULL_DWN_CTRL_"#reg, \
++					.pull_reg = PULL_DWN_CTRL_##reg, \
++					.pull_bit = bit, \
++					.pull_val = status,
++
++#define PU_PD_REG(reg, status)		.pu_pd_name = "PU_PD_SEL_"#reg, \
++					.pu_pd_reg = PU_PD_SEL_##reg, \
++					.pu_pd_val = status,
++
++#define MUX_REG_7XX(reg, mode_offset, mode) .mux_reg_name = "OMAP7XX_IO_CONF_"#reg, \
++					.mux_reg = OMAP7XX_IO_CONF_##reg, \
++					.mask_offset = mode_offset, \
++					.mask = mode,
++
++#define PULL_REG_7XX(reg, bit, status)	.pull_name = "OMAP7XX_IO_CONF_"#reg, \
++					.pull_reg = OMAP7XX_IO_CONF_##reg, \
++					.pull_bit = bit, \
++					.pull_val = status,
++
++#else
++
++#define MUX_REG(reg, mode_offset, mode) .mux_reg = FUNC_MUX_CTRL_##reg, \
++					.mask_offset = mode_offset, \
++					.mask = mode,
++
++#define PULL_REG(reg, bit, status)	.pull_reg = PULL_DWN_CTRL_##reg, \
++					.pull_bit = bit, \
++					.pull_val = status,
++
++#define PU_PD_REG(reg, status)		.pu_pd_reg = PU_PD_SEL_##reg, \
++					.pu_pd_val = status,
++
++#define MUX_REG_7XX(reg, mode_offset, mode) \
++					.mux_reg = OMAP7XX_IO_CONF_##reg, \
++					.mask_offset = mode_offset, \
++					.mask = mode,
++
++#define PULL_REG_7XX(reg, bit, status)	.pull_reg = OMAP7XX_IO_CONF_##reg, \
++					.pull_bit = bit, \
++					.pull_val = status,
++
++#endif /* CONFIG_OMAP_MUX_DEBUG */
++
++#define MUX_CFG(desc, mux_reg, mode_offset, mode,	\
++		pull_reg, pull_bit, pull_status,	\
++		pu_pd_reg, pu_pd_status, debug_status)	\
++{							\
++	.name =	 desc,					\
++	.debug = debug_status,				\
++	MUX_REG(mux_reg, mode_offset, mode)		\
++	PULL_REG(pull_reg, pull_bit, pull_status)	\
++	PU_PD_REG(pu_pd_reg, pu_pd_status)		\
++},
++
++
++/*
++ * OMAP730/850 has a slightly different config for the pin mux.
++ * - config regs are the OMAP7XX_IO_CONF_x regs (see omap730.h) regs and
++ *   not the FUNC_MUX_CTRL_x regs from hardware.h
++ * - for pull-up/down, only has one enable bit which is is in the same register
++ *   as mux config
++ */
++#define MUX_CFG_7XX(desc, mux_reg, mode_offset, mode,	\
++		   pull_bit, pull_status, debug_status)\
++{							\
++	.name =	 desc,					\
++	.debug = debug_status,				\
++	MUX_REG_7XX(mux_reg, mode_offset, mode)		\
++	PULL_REG_7XX(mux_reg, pull_bit, pull_status)	\
++	PU_PD_REG(NA, 0)		\
++},
++
++#define MUX_CFG_24XX(desc, reg_offset, mode,			\
++				pull_en, pull_mode, dbg)	\
++{								\
++	.name		= desc,					\
++	.debug		= dbg,					\
++	.mux_reg	= reg_offset,				\
++	.mask		= mode,					\
++	.pull_val	= pull_en,				\
++	.pu_pd_val	= pull_mode,				\
++},
++
++/* 24xx/34xx mux bit defines */
++#define OMAP2_PULL_ENA		(1 << 3)
++#define OMAP2_PULL_UP		(1 << 4)
++#define OMAP2_ALTELECTRICALSEL	(1 << 5)
++
++struct pin_config {
++	char 			*name;
++	const unsigned int 	mux_reg;
++	unsigned char		debug;
++
++#if	defined(CONFIG_ARCH_OMAP1) || defined(CONFIG_ARCH_OMAP24XX)
++	const unsigned char mask_offset;
++	const unsigned char mask;
++
++	const char *pull_name;
++	const unsigned int pull_reg;
++	const unsigned char pull_val;
++	const unsigned char pull_bit;
++
++	const char *pu_pd_name;
++	const unsigned int pu_pd_reg;
++	const unsigned char pu_pd_val;
++#endif
++
++#if	defined(CONFIG_OMAP_MUX_DEBUG) || defined(CONFIG_OMAP_MUX_WARNINGS)
++	const char *mux_reg_name;
++#endif
++
++};
++
++enum omap7xx_index {
++	/* OMAP 730 keyboard */
++	E2_7XX_KBR0,
++	J7_7XX_KBR1,
++	E1_7XX_KBR2,
++	F3_7XX_KBR3,
++	D2_7XX_KBR4,
++	C2_7XX_KBC0,
++	D3_7XX_KBC1,
++	E4_7XX_KBC2,
++	F4_7XX_KBC3,
++	E3_7XX_KBC4,
++
++	/* USB */
++	AA17_7XX_USB_DM,
++	W16_7XX_USB_PU_EN,
++	W17_7XX_USB_VBUSI,
++	W18_7XX_USB_DMCK_OUT,
++	W19_7XX_USB_DCRST,
++
++	/* MMC */
++	MMC_7XX_CMD,
++	MMC_7XX_CLK,
++	MMC_7XX_DAT0,
++
++	/* I2C */
++	I2C_7XX_SCL,
++	I2C_7XX_SDA,
++};
++
++enum omap1xxx_index {
++	/* UART1 (BT_UART_GATING)*/
++	UART1_TX = 0,
++	UART1_RTS,
++
++	/* UART2 (COM_UART_GATING)*/
++	UART2_TX,
++	UART2_RX,
++	UART2_CTS,
++	UART2_RTS,
++
++	/* UART3 (GIGA_UART_GATING) */
++	UART3_TX,
++	UART3_RX,
++	UART3_CTS,
++	UART3_RTS,
++	UART3_CLKREQ,
++	UART3_BCLK,	/* 12MHz clock out */
++	Y15_1610_UART3_RTS,
++
++	/* PWT & PWL */
++	PWT,
++	PWL,
++
++	/* USB master generic */
++	R18_USB_VBUS,
++	R18_1510_USB_GPIO0,
++	W4_USB_PUEN,
++	W4_USB_CLKO,
++	W4_USB_HIGHZ,
++	W4_GPIO58,
++
++	/* USB1 master */
++	USB1_SUSP,
++	USB1_SEO,
++	W13_1610_USB1_SE0,
++	USB1_TXEN,
++	USB1_TXD,
++	USB1_VP,
++	USB1_VM,
++	USB1_RCV,
++	USB1_SPEED,
++	R13_1610_USB1_SPEED,
++	R13_1710_USB1_SE0,
++
++	/* USB2 master */
++	USB2_SUSP,
++	USB2_VP,
++	USB2_TXEN,
++	USB2_VM,
++	USB2_RCV,
++	USB2_SEO,
++	USB2_TXD,
++
++	/* OMAP-1510 GPIO */
++	R18_1510_GPIO0,
++	R19_1510_GPIO1,
++	M14_1510_GPIO2,
++
++	/* OMAP1610 GPIO */
++	P18_1610_GPIO3,
++	Y15_1610_GPIO17,
++
++	/* OMAP-1710 GPIO */
++	R18_1710_GPIO0,
++	V2_1710_GPIO10,
++	N21_1710_GPIO14,
++	W15_1710_GPIO40,
++
++	/* MPUIO */
++	MPUIO2,
++	N15_1610_MPUIO2,
++	MPUIO4,
++	MPUIO5,
++	T20_1610_MPUIO5,
++	W11_1610_MPUIO6,
++	V10_1610_MPUIO7,
++	W11_1610_MPUIO9,
++	V10_1610_MPUIO10,
++	W10_1610_MPUIO11,
++	E20_1610_MPUIO13,
++	U20_1610_MPUIO14,
++	E19_1610_MPUIO15,
++
++	/* MCBSP2 */
++	MCBSP2_CLKR,
++	MCBSP2_CLKX,
++	MCBSP2_DR,
++	MCBSP2_DX,
++	MCBSP2_FSR,
++	MCBSP2_FSX,
++
++	/* MCBSP3 */
++	MCBSP3_CLKX,
++
++	/* Misc ballouts */
++	BALLOUT_V8_ARMIO3,
++	N20_HDQ,
++
++	/* OMAP-1610 MMC2 */
++	W8_1610_MMC2_DAT0,
++	V8_1610_MMC2_DAT1,
++	W15_1610_MMC2_DAT2,
++	R10_1610_MMC2_DAT3,
++	Y10_1610_MMC2_CLK,
++	Y8_1610_MMC2_CMD,
++	V9_1610_MMC2_CMDDIR,
++	V5_1610_MMC2_DATDIR0,
++	W19_1610_MMC2_DATDIR1,
++	R18_1610_MMC2_CLKIN,
++
++	/* OMAP-1610 External Trace Interface */
++	M19_1610_ETM_PSTAT0,
++	L15_1610_ETM_PSTAT1,
++	L18_1610_ETM_PSTAT2,
++	L19_1610_ETM_D0,
++	J19_1610_ETM_D6,
++	J18_1610_ETM_D7,
++
++	/* OMAP16XX GPIO */
++	P20_1610_GPIO4,
++	V9_1610_GPIO7,
++	W8_1610_GPIO9,
++	N20_1610_GPIO11,
++	N19_1610_GPIO13,
++	P10_1610_GPIO22,
++	V5_1610_GPIO24,
++	AA20_1610_GPIO_41,
++	W19_1610_GPIO48,
++	M7_1610_GPIO62,
++	V14_16XX_GPIO37,
++	R9_16XX_GPIO18,
++	L14_16XX_GPIO49,
++
++	/* OMAP-1610 uWire */
++	V19_1610_UWIRE_SCLK,
++	U18_1610_UWIRE_SDI,
++	W21_1610_UWIRE_SDO,
++	N14_1610_UWIRE_CS0,
++	P15_1610_UWIRE_CS3,
++	N15_1610_UWIRE_CS1,
++
++	/* OMAP-1610 SPI */
++	U19_1610_SPIF_SCK,
++	U18_1610_SPIF_DIN,
++	P20_1610_SPIF_DIN,
++	W21_1610_SPIF_DOUT,
++	R18_1610_SPIF_DOUT,
++	N14_1610_SPIF_CS0,
++	N15_1610_SPIF_CS1,
++	T19_1610_SPIF_CS2,
++	P15_1610_SPIF_CS3,
++
++	/* OMAP-1610 Flash */
++	L3_1610_FLASH_CS2B_OE,
++	M8_1610_FLASH_CS2B_WE,
++
++	/* First MMC */
++	MMC_CMD,
++	MMC_DAT1,
++	MMC_DAT2,
++	MMC_DAT0,
++	MMC_CLK,
++	MMC_DAT3,
++
++	/* OMAP-1710 MMC CMDDIR and DATDIR0 */
++	M15_1710_MMC_CLKI,
++	P19_1710_MMC_CMDDIR,
++	P20_1710_MMC_DATDIR0,
++
++	/* OMAP-1610 USB0 alternate pin configuration */
++	W9_USB0_TXEN,
++	AA9_USB0_VP,
++	Y5_USB0_RCV,
++	R9_USB0_VM,
++	V6_USB0_TXD,
++	W5_USB0_SE0,
++	V9_USB0_SPEED,
++	V9_USB0_SUSP,
++
++	/* USB2 */
++	W9_USB2_TXEN,
++	AA9_USB2_VP,
++	Y5_USB2_RCV,
++	R9_USB2_VM,
++	V6_USB2_TXD,
++	W5_USB2_SE0,
++
++	/* 16XX UART */
++	R13_1610_UART1_TX,
++	V14_16XX_UART1_RX,
++	R14_1610_UART1_CTS,
++	AA15_1610_UART1_RTS,
++	R9_16XX_UART2_RX,
++	L14_16XX_UART3_RX,
++
++	/* I2C OMAP-1610 */
++	I2C_SCL,
++	I2C_SDA,
++
++	/* Keypad */
++	F18_1610_KBC0,
++	D20_1610_KBC1,
++	D19_1610_KBC2,
++	E18_1610_KBC3,
++	C21_1610_KBC4,
++	G18_1610_KBR0,
++	F19_1610_KBR1,
++	H14_1610_KBR2,
++	E20_1610_KBR3,
++	E19_1610_KBR4,
++	N19_1610_KBR5,
++
++	/* Power management */
++	T20_1610_LOW_PWR,
++
++	/* MCLK Settings */
++	V5_1710_MCLK_ON,
++	V5_1710_MCLK_OFF,
++	R10_1610_MCLK_ON,
++	R10_1610_MCLK_OFF,
++
++	/* CompactFlash controller */
++	P11_1610_CF_CD2,
++	R11_1610_CF_IOIS16,
++	V10_1610_CF_IREQ,
++	W10_1610_CF_RESET,
++	W11_1610_CF_CD1,
++
++	/* parallel camera */
++	J15_1610_CAM_LCLK,
++	J18_1610_CAM_D7,
++	J19_1610_CAM_D6,
++	J14_1610_CAM_D5,
++	K18_1610_CAM_D4,
++	K19_1610_CAM_D3,
++	K15_1610_CAM_D2,
++	K14_1610_CAM_D1,
++	L19_1610_CAM_D0,
++	L18_1610_CAM_VS,
++	L15_1610_CAM_HS,
++	M19_1610_CAM_RSTZ,
++	Y15_1610_CAM_OUTCLK,
++
++	/* serial camera */
++	H19_1610_CAM_EXCLK,
++	Y12_1610_CCP_CLKP,
++	W13_1610_CCP_CLKM,
++	W14_1610_CCP_DATAP,
++	Y14_1610_CCP_DATAM,
++
++};
++
++enum omap24xx_index {
++	/* 24xx I2C */
++	M19_24XX_I2C1_SCL,
++	L15_24XX_I2C1_SDA,
++	J15_24XX_I2C2_SCL,
++	H19_24XX_I2C2_SDA,
++
++	/* 24xx Menelaus interrupt */
++	W19_24XX_SYS_NIRQ,
++
++	/* 24xx clock */
++	W14_24XX_SYS_CLKOUT,
++
++	/* 24xx GPMC chipselects, wait pin monitoring */
++	E2_GPMC_NCS2,
++	L2_GPMC_NCS7,
++	L3_GPMC_WAIT0,
++	N7_GPMC_WAIT1,
++	M1_GPMC_WAIT2,
++	P1_GPMC_WAIT3,
++
++	/* 242X McBSP */
++	Y15_24XX_MCBSP2_CLKX,
++	R14_24XX_MCBSP2_FSX,
++	W15_24XX_MCBSP2_DR,
++	V15_24XX_MCBSP2_DX,
++
++	/* 24xx GPIO */
++	M21_242X_GPIO11,
++	P21_242X_GPIO12,
++	AA10_242X_GPIO13,
++	AA6_242X_GPIO14,
++	AA4_242X_GPIO15,
++	Y11_242X_GPIO16,
++	AA12_242X_GPIO17,
++	AA8_242X_GPIO58,
++	Y20_24XX_GPIO60,
++	W4__24XX_GPIO74,
++	N15_24XX_GPIO85,
++	M15_24XX_GPIO92,
++	P20_24XX_GPIO93,
++	P18_24XX_GPIO95,
++	M18_24XX_GPIO96,
++	L14_24XX_GPIO97,
++	J15_24XX_GPIO99,
++	V14_24XX_GPIO117,
++	P14_24XX_GPIO125,
++
++	/* 242x DBG GPIO */
++	V4_242X_GPIO49,
++	W2_242X_GPIO50,
++	U4_242X_GPIO51,
++	V3_242X_GPIO52,
++	V2_242X_GPIO53,
++	V6_242X_GPIO53,
++	T4_242X_GPIO54,
++	Y4_242X_GPIO54,
++	T3_242X_GPIO55,
++	U2_242X_GPIO56,
++
++	/* 24xx external DMA requests */
++	AA10_242X_DMAREQ0,
++	AA6_242X_DMAREQ1,
++	E4_242X_DMAREQ2,
++	G4_242X_DMAREQ3,
++	D3_242X_DMAREQ4,
++	E3_242X_DMAREQ5,
++
++	/* UART3 */
++	K15_24XX_UART3_TX,
++	K14_24XX_UART3_RX,
++
++	/* MMC/SDIO */
++	G19_24XX_MMC_CLKO,
++	H18_24XX_MMC_CMD,
++	F20_24XX_MMC_DAT0,
++	H14_24XX_MMC_DAT1,
++	E19_24XX_MMC_DAT2,
++	D19_24XX_MMC_DAT3,
++	F19_24XX_MMC_DAT_DIR0,
++	E20_24XX_MMC_DAT_DIR1,
++	F18_24XX_MMC_DAT_DIR2,
++	E18_24XX_MMC_DAT_DIR3,
++	G18_24XX_MMC_CMD_DIR,
++	H15_24XX_MMC_CLKI,
++
++	/* Full speed USB */
++	J20_24XX_USB0_PUEN,
++	J19_24XX_USB0_VP,
++	K20_24XX_USB0_VM,
++	J18_24XX_USB0_RCV,
++	K19_24XX_USB0_TXEN,
++	J14_24XX_USB0_SE0,
++	K18_24XX_USB0_DAT,
++
++	N14_24XX_USB1_SE0,
++	W12_24XX_USB1_SE0,
++	P15_24XX_USB1_DAT,
++	R13_24XX_USB1_DAT,
++	W20_24XX_USB1_TXEN,
++	P13_24XX_USB1_TXEN,
++	V19_24XX_USB1_RCV,
++	V12_24XX_USB1_RCV,
++
++	AA10_24XX_USB2_SE0,
++	Y11_24XX_USB2_DAT,
++	AA12_24XX_USB2_TXEN,
++	AA6_24XX_USB2_RCV,
++	AA4_24XX_USB2_TLLSE0,
++
++	/* Keypad GPIO*/
++	T19_24XX_KBR0,
++	R19_24XX_KBR1,
++	V18_24XX_KBR2,
++	M21_24XX_KBR3,
++	E5__24XX_KBR4,
++	M18_24XX_KBR5,
++	R20_24XX_KBC0,
++	M14_24XX_KBC1,
++	H19_24XX_KBC2,
++	V17_24XX_KBC3,
++	P21_24XX_KBC4,
++	L14_24XX_KBC5,
++	N19_24XX_KBC6,
++
++	/* 24xx Menelaus Keypad GPIO */
++	B3__24XX_KBR5,
++	AA4_24XX_KBC2,
++	B13_24XX_KBC6,
++
++	/* 2430 USB */
++	AD9_2430_USB0_PUEN,
++	Y11_2430_USB0_VP,
++	AD7_2430_USB0_VM,
++	AE7_2430_USB0_RCV,
++	AD4_2430_USB0_TXEN,
++	AF9_2430_USB0_SE0,
++	AE6_2430_USB0_DAT,
++	AD24_2430_USB1_SE0,
++	AB24_2430_USB1_RCV,
++	Y25_2430_USB1_TXEN,
++	AA26_2430_USB1_DAT,
++
++	/* 2430 HS-USB */
++	AD9_2430_USB0HS_DATA3,
++	Y11_2430_USB0HS_DATA4,
++	AD7_2430_USB0HS_DATA5,
++	AE7_2430_USB0HS_DATA6,
++	AD4_2430_USB0HS_DATA2,
++	AF9_2430_USB0HS_DATA0,
++	AE6_2430_USB0HS_DATA1,
++	AE8_2430_USB0HS_CLK,
++	AD8_2430_USB0HS_DIR,
++	AE5_2430_USB0HS_STP,
++	AE9_2430_USB0HS_NXT,
++	AC7_2430_USB0HS_DATA7,
++
++	/* 2430 McBSP */
++	AD6_2430_MCBSP_CLKS,
++
++	AB2_2430_MCBSP1_CLKR,
++	AD5_2430_MCBSP1_FSR,
++	AA1_2430_MCBSP1_DX,
++	AF3_2430_MCBSP1_DR,
++	AB3_2430_MCBSP1_FSX,
++	Y9_2430_MCBSP1_CLKX,
++
++	AC10_2430_MCBSP2_FSX,
++	AD16_2430_MCBSP2_CLX,
++	AE13_2430_MCBSP2_DX,
++	AD13_2430_MCBSP2_DR,
++	AC10_2430_MCBSP2_FSX_OFF,
++	AD16_2430_MCBSP2_CLX_OFF,
++	AE13_2430_MCBSP2_DX_OFF,
++	AD13_2430_MCBSP2_DR_OFF,
++
++	AC9_2430_MCBSP3_CLKX,
++	AE4_2430_MCBSP3_FSX,
++	AE2_2430_MCBSP3_DR,
++	AF4_2430_MCBSP3_DX,
++
++	N3_2430_MCBSP4_CLKX,
++	AD23_2430_MCBSP4_DR,
++	AB25_2430_MCBSP4_DX,
++	AC25_2430_MCBSP4_FSX,
++
++	AE16_2430_MCBSP5_CLKX,
++	AF12_2430_MCBSP5_FSX,
++	K7_2430_MCBSP5_DX,
++	M1_2430_MCBSP5_DR,
++
++	/* 2430 McSPI*/
++	Y18_2430_MCSPI1_CLK,
++	AD15_2430_MCSPI1_SIMO,
++	AE17_2430_MCSPI1_SOMI,
++	U1_2430_MCSPI1_CS0,
++
++	/* Touchscreen GPIO */
++	AF19_2430_GPIO_85,
++
++};
++
++struct omap_mux_cfg {
++	struct pin_config	*pins;
++	unsigned long		size;
++	int			(*cfg_reg)(const struct pin_config *cfg);
++};
++
++#ifdef	CONFIG_OMAP_MUX
++/* setup pin muxing in Linux */
++extern int omap1_mux_init(void);
++extern int omap_mux_register(struct omap_mux_cfg *);
++extern int omap_cfg_reg(unsigned long reg_cfg);
++#else
++/* boot loader does it all (no warnings from CONFIG_OMAP_MUX_WARNINGS) */
++static inline int omap1_mux_init(void) { return 0; }
++static inline int omap_cfg_reg(unsigned long reg_cfg) { return 0; }
++#endif
++
++extern int omap2_mux_init(void);
++
++#endif
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/nand.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/nand.h	2010-08-08 12:57:04.000000000 +0200
+@@ -0,0 +1,24 @@
++/*
++ * arch/arm/plat-omap/include/mach/nand.h
++ *
++ * Copyright (C) 2006 Micron Technology Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#include <linux/mtd/partitions.h>
++
++struct omap_nand_platform_data {
++	unsigned int		options;
++	int			cs;
++	int			gpio_irq;
++	struct mtd_partition	*parts;
++	int			nr_parts;
++	int			(*nand_setup)(void __iomem *);
++	int			(*dev_ready)(struct omap_nand_platform_data *);
++	int			dma_channel;
++	void __iomem		*gpmc_cs_baseaddr;
++	void __iomem		*gpmc_baseaddr;
++};
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/omap1510.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/omap1510.h	2010-08-08 12:57:05.000000000 +0200
+@@ -0,0 +1,50 @@
++/* arch/arm/plat-omap/include/mach/omap1510.h
++ *
++ * Hardware definitions for TI OMAP1510 processor.
++ *
++ * Cleanup for Linux-2.6 by Dirk Behme <[email protected]>
++ *
++ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ *
++ * 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.,
++ * 675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++
++#ifndef __ASM_ARCH_OMAP15XX_H
++#define __ASM_ARCH_OMAP15XX_H
++
++/*
++ * ----------------------------------------------------------------------------
++ * Base addresses
++ * ----------------------------------------------------------------------------
++ */
++
++/* Syntax: XX_BASE = Virtual base address, XX_START = Physical base address */
++
++#define OMAP1510_DSP_BASE	0xE0000000
++#define OMAP1510_DSP_SIZE	0x28000
++#define OMAP1510_DSP_START	0xE0000000
++
++#define OMAP1510_DSPREG_BASE	0xE1000000
++#define OMAP1510_DSPREG_SIZE	SZ_128K
++#define OMAP1510_DSPREG_START	0xE1000000
++
++#define OMAP1510_DSP_MMU_BASE	(0xfffed200)
++
++#endif /*  __ASM_ARCH_OMAP15XX_H */
++
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/omap16xx.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/omap16xx.h	2010-08-08 12:57:06.000000000 +0200
+@@ -0,0 +1,202 @@
++/* arch/arm/plat-omap/include/mach/omap16xx.h
++ *
++ * Hardware definitions for TI OMAP1610/5912/1710 processors.
++ *
++ * Cleanup for Linux-2.6 by Dirk Behme <[email protected]>
++ *
++ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ *
++ * 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.,
++ * 675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++
++#ifndef __ASM_ARCH_OMAP16XX_H
++#define __ASM_ARCH_OMAP16XX_H
++
++/*
++ * ----------------------------------------------------------------------------
++ * Base addresses
++ * ----------------------------------------------------------------------------
++ */
++
++/* Syntax: XX_BASE = Virtual base address, XX_START = Physical base address */
++
++#define OMAP16XX_DSP_BASE	0xE0000000
++#define OMAP16XX_DSP_SIZE	0x28000
++#define OMAP16XX_DSP_START	0xE0000000
++
++#define OMAP16XX_DSPREG_BASE	0xE1000000
++#define OMAP16XX_DSPREG_SIZE	SZ_128K
++#define OMAP16XX_DSPREG_START	0xE1000000
++
++#define OMAP16XX_SEC_BASE	0xFFFE4000
++#define OMAP16XX_SEC_DES	(OMAP16XX_SEC_BASE + 0x0000)
++#define OMAP16XX_SEC_SHA1MD5	(OMAP16XX_SEC_BASE + 0x0800)
++#define OMAP16XX_SEC_RNG	(OMAP16XX_SEC_BASE + 0x1000)
++
++/*
++ * ---------------------------------------------------------------------------
++ * Interrupts
++ * ---------------------------------------------------------------------------
++ */
++#define OMAP_IH2_0_BASE		(0xfffe0000)
++#define OMAP_IH2_1_BASE		(0xfffe0100)
++#define OMAP_IH2_2_BASE		(0xfffe0200)
++#define OMAP_IH2_3_BASE		(0xfffe0300)
++
++#define OMAP_IH2_0_ITR		(OMAP_IH2_0_BASE + 0x00)
++#define OMAP_IH2_0_MIR		(OMAP_IH2_0_BASE + 0x04)
++#define OMAP_IH2_0_SIR_IRQ	(OMAP_IH2_0_BASE + 0x10)
++#define OMAP_IH2_0_SIR_FIQ	(OMAP_IH2_0_BASE + 0x14)
++#define OMAP_IH2_0_CONTROL	(OMAP_IH2_0_BASE + 0x18)
++#define OMAP_IH2_0_ILR0		(OMAP_IH2_0_BASE + 0x1c)
++#define OMAP_IH2_0_ISR		(OMAP_IH2_0_BASE + 0x9c)
++
++#define OMAP_IH2_1_ITR		(OMAP_IH2_1_BASE + 0x00)
++#define OMAP_IH2_1_MIR		(OMAP_IH2_1_BASE + 0x04)
++#define OMAP_IH2_1_SIR_IRQ	(OMAP_IH2_1_BASE + 0x10)
++#define OMAP_IH2_1_SIR_FIQ	(OMAP_IH2_1_BASE + 0x14)
++#define OMAP_IH2_1_CONTROL	(OMAP_IH2_1_BASE + 0x18)
++#define OMAP_IH2_1_ILR1		(OMAP_IH2_1_BASE + 0x1c)
++#define OMAP_IH2_1_ISR		(OMAP_IH2_1_BASE + 0x9c)
++
++#define OMAP_IH2_2_ITR		(OMAP_IH2_2_BASE + 0x00)
++#define OMAP_IH2_2_MIR		(OMAP_IH2_2_BASE + 0x04)
++#define OMAP_IH2_2_SIR_IRQ	(OMAP_IH2_2_BASE + 0x10)
++#define OMAP_IH2_2_SIR_FIQ	(OMAP_IH2_2_BASE + 0x14)
++#define OMAP_IH2_2_CONTROL	(OMAP_IH2_2_BASE + 0x18)
++#define OMAP_IH2_2_ILR2		(OMAP_IH2_2_BASE + 0x1c)
++#define OMAP_IH2_2_ISR		(OMAP_IH2_2_BASE + 0x9c)
++
++#define OMAP_IH2_3_ITR		(OMAP_IH2_3_BASE + 0x00)
++#define OMAP_IH2_3_MIR		(OMAP_IH2_3_BASE + 0x04)
++#define OMAP_IH2_3_SIR_IRQ	(OMAP_IH2_3_BASE + 0x10)
++#define OMAP_IH2_3_SIR_FIQ	(OMAP_IH2_3_BASE + 0x14)
++#define OMAP_IH2_3_CONTROL	(OMAP_IH2_3_BASE + 0x18)
++#define OMAP_IH2_3_ILR3		(OMAP_IH2_3_BASE + 0x1c)
++#define OMAP_IH2_3_ISR		(OMAP_IH2_3_BASE + 0x9c)
++
++/*
++ * ----------------------------------------------------------------------------
++ * Clocks
++ * ----------------------------------------------------------------------------
++ */
++#define OMAP16XX_ARM_IDLECT3	(CLKGEN_REG_BASE + 0x24)
++
++/*
++ * ----------------------------------------------------------------------------
++ * Pin configuration registers
++ * ----------------------------------------------------------------------------
++ */
++#define OMAP16XX_CONF_VOLTAGE_VDDSHV6	(1 << 8)
++#define OMAP16XX_CONF_VOLTAGE_VDDSHV7	(1 << 9)
++#define OMAP16XX_CONF_VOLTAGE_VDDSHV8	(1 << 10)
++#define OMAP16XX_CONF_VOLTAGE_VDDSHV9	(1 << 11)
++#define OMAP16XX_SUBLVDS_CONF_VALID	(1 << 13)
++
++/*
++ * ----------------------------------------------------------------------------
++ * System control registers
++ * ----------------------------------------------------------------------------
++ */
++#define OMAP1610_RESET_CONTROL  0xfffe1140
++
++/*
++ * ---------------------------------------------------------------------------
++ * TIPB bus interface
++ * ---------------------------------------------------------------------------
++ */
++#define TIPB_SWITCH_BASE		 (0xfffbc800)
++#define OMAP16XX_MMCSD2_SSW_MPU_CONF	(TIPB_SWITCH_BASE + 0x160)
++
++/* UART3 Registers Mapping through MPU bus */
++#define UART3_RHR               (OMAP_UART3_BASE + 0)
++#define UART3_THR               (OMAP_UART3_BASE + 0)
++#define UART3_DLL               (OMAP_UART3_BASE + 0)
++#define UART3_IER               (OMAP_UART3_BASE + 4)
++#define UART3_DLH               (OMAP_UART3_BASE + 4)
++#define UART3_IIR               (OMAP_UART3_BASE + 8)
++#define UART3_FCR               (OMAP_UART3_BASE + 8)
++#define UART3_EFR               (OMAP_UART3_BASE + 8)
++#define UART3_LCR               (OMAP_UART3_BASE + 0x0C)
++#define UART3_MCR               (OMAP_UART3_BASE + 0x10)
++#define UART3_XON1_ADDR1        (OMAP_UART3_BASE + 0x10)
++#define UART3_XON2_ADDR2        (OMAP_UART3_BASE + 0x14)
++#define UART3_LSR               (OMAP_UART3_BASE + 0x14)
++#define UART3_TCR               (OMAP_UART3_BASE + 0x18)
++#define UART3_MSR               (OMAP_UART3_BASE + 0x18)
++#define UART3_XOFF1             (OMAP_UART3_BASE + 0x18)
++#define UART3_XOFF2             (OMAP_UART3_BASE + 0x1C)
++#define UART3_SPR               (OMAP_UART3_BASE + 0x1C)
++#define UART3_TLR               (OMAP_UART3_BASE + 0x1C)
++#define UART3_MDR1              (OMAP_UART3_BASE + 0x20)
++#define UART3_MDR2              (OMAP_UART3_BASE + 0x24)
++#define UART3_SFLSR             (OMAP_UART3_BASE + 0x28)
++#define UART3_TXFLL             (OMAP_UART3_BASE + 0x28)
++#define UART3_RESUME            (OMAP_UART3_BASE + 0x2C)
++#define UART3_TXFLH             (OMAP_UART3_BASE + 0x2C)
++#define UART3_SFREGL            (OMAP_UART3_BASE + 0x30)
++#define UART3_RXFLL             (OMAP_UART3_BASE + 0x30)
++#define UART3_SFREGH            (OMAP_UART3_BASE + 0x34)
++#define UART3_RXFLH             (OMAP_UART3_BASE + 0x34)
++#define UART3_BLR               (OMAP_UART3_BASE + 0x38)
++#define UART3_ACREG             (OMAP_UART3_BASE + 0x3C)
++#define UART3_DIV16             (OMAP_UART3_BASE + 0x3C)
++#define UART3_SCR               (OMAP_UART3_BASE + 0x40)
++#define UART3_SSR               (OMAP_UART3_BASE + 0x44)
++#define UART3_EBLR              (OMAP_UART3_BASE + 0x48)
++#define UART3_OSC_12M_SEL       (OMAP_UART3_BASE + 0x4C)
++#define UART3_MVR               (OMAP_UART3_BASE + 0x50)
++
++/*
++ * ---------------------------------------------------------------------------
++ * Watchdog timer
++ * ---------------------------------------------------------------------------
++ */
++
++/* 32-bit Watchdog timer in OMAP 16XX */
++#define OMAP_16XX_WATCHDOG_BASE        (0xfffeb000)
++#define OMAP_16XX_WIDR         (OMAP_16XX_WATCHDOG_BASE + 0x00)
++#define OMAP_16XX_WD_SYSCONFIG (OMAP_16XX_WATCHDOG_BASE + 0x10)
++#define OMAP_16XX_WD_SYSSTATUS (OMAP_16XX_WATCHDOG_BASE + 0x14)
++#define OMAP_16XX_WCLR         (OMAP_16XX_WATCHDOG_BASE + 0x24)
++#define OMAP_16XX_WCRR         (OMAP_16XX_WATCHDOG_BASE + 0x28)
++#define OMAP_16XX_WLDR         (OMAP_16XX_WATCHDOG_BASE + 0x2c)
++#define OMAP_16XX_WTGR         (OMAP_16XX_WATCHDOG_BASE + 0x30)
++#define OMAP_16XX_WWPS         (OMAP_16XX_WATCHDOG_BASE + 0x34)
++#define OMAP_16XX_WSPR         (OMAP_16XX_WATCHDOG_BASE + 0x48)
++
++#define WCLR_PRE_SHIFT         5
++#define WCLR_PTV_SHIFT         2
++
++#define WWPS_W_PEND_WSPR       (1 << 4)
++#define WWPS_W_PEND_WTGR       (1 << 3)
++#define WWPS_W_PEND_WLDR       (1 << 2)
++#define WWPS_W_PEND_WCRR       (1 << 1)
++#define WWPS_W_PEND_WCLR       (1 << 0)
++
++#define WSPR_ENABLE_0          (0x0000bbbb)
++#define WSPR_ENABLE_1          (0x00004444)
++#define WSPR_DISABLE_0         (0x0000aaaa)
++#define WSPR_DISABLE_1         (0x00005555)
++
++#define OMAP16XX_DSP_MMU_BASE	(0xfffed200)
++#define OMAP16XX_MAILBOX_BASE	(0xfffcf000)
++
++#endif /*  __ASM_ARCH_OMAP16XX_H */
++
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/omap24xx.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/omap24xx.h	2010-08-08 12:57:06.000000000 +0200
+@@ -0,0 +1,89 @@
++/*
++ * arch/arm/plat-omap/include/mach/omap24xx.h
++ *
++ * This file contains the processor specific definitions
++ * of the TI OMAP24XX.
++ *
++ * Copyright (C) 2007 Texas Instruments.
++ * Copyright (C) 2007 Nokia Corporation.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ *
++ */
++
++#ifndef __ASM_ARCH_OMAP24XX_H
++#define __ASM_ARCH_OMAP24XX_H
++
++/*
++ * Please place only base defines here and put the rest in device
++ * specific headers. Note also that some of these defines are needed
++ * for omap1 to compile without adding ifdefs.
++ */
++
++#define L4_24XX_BASE		0x48000000
++#define L4_WK_243X_BASE		0x49000000
++#define L3_24XX_BASE		0x68000000
++
++/* interrupt controller */
++#define OMAP24XX_IC_BASE	(L4_24XX_BASE + 0xfe000)
++#define OMAP24XX_IVA_INTC_BASE	0x40000000
++
++#define OMAP2420_CTRL_BASE	L4_24XX_BASE
++#define OMAP2420_32KSYNCT_BASE	(L4_24XX_BASE + 0x4000)
++#define OMAP2420_PRCM_BASE	(L4_24XX_BASE + 0x8000)
++#define OMAP2420_CM_BASE	(L4_24XX_BASE + 0x8000)
++#define OMAP2420_PRM_BASE	OMAP2420_CM_BASE
++#define OMAP2420_SDRC_BASE	(L3_24XX_BASE + 0x9000)
++#define OMAP2420_SMS_BASE	0x68008000
++#define OMAP2420_GPMC_BASE	0x6800a000
++
++#define OMAP2430_32KSYNCT_BASE	(L4_WK_243X_BASE + 0x20000)
++#define OMAP2430_PRCM_BASE	(L4_WK_243X_BASE + 0x6000)
++#define OMAP2430_CM_BASE	(L4_WK_243X_BASE + 0x6000)
++#define OMAP2430_PRM_BASE	OMAP2430_CM_BASE
++
++#define OMAP243X_SMS_BASE	0x6C000000
++#define OMAP243X_SDRC_BASE	0x6D000000
++#define OMAP243X_GPMC_BASE	0x6E000000
++#define OMAP243X_SCM_BASE	(L4_WK_243X_BASE + 0x2000)
++#define OMAP243X_CTRL_BASE	OMAP243X_SCM_BASE
++#define OMAP243X_HS_BASE	(L4_24XX_BASE + 0x000ac000)
++
++/* DSP SS */
++#define OMAP2420_DSP_BASE	0x58000000
++#define OMAP2420_DSP_MEM_BASE	(OMAP2420_DSP_BASE + 0x0)
++#define OMAP2420_DSP_IPI_BASE	(OMAP2420_DSP_BASE + 0x1000000)
++#define OMAP2420_DSP_MMU_BASE	(OMAP2420_DSP_BASE + 0x2000000)
++
++#define OMAP243X_DSP_BASE	0x5C000000
++#define OMAP243X_DSP_MEM_BASE	(OMAP243X_DSP_BASE + 0x0)
++#define OMAP243X_DSP_MMU_BASE	(OMAP243X_DSP_BASE + 0x1000000)
++
++/* Mailbox */
++#define OMAP24XX_MAILBOX_BASE	(L4_24XX_BASE + 0x94000)
++
++/* Camera */
++#define OMAP24XX_CAMERA_BASE	(L4_24XX_BASE + 0x52000)
++
++/* Security */
++#define OMAP24XX_SEC_BASE	(L4_24XX_BASE + 0xA0000)
++#define OMAP24XX_SEC_RNG_BASE	(OMAP24XX_SEC_BASE + 0x0000)
++#define OMAP24XX_SEC_DES_BASE	(OMAP24XX_SEC_BASE + 0x2000)
++#define OMAP24XX_SEC_SHA1MD5_BASE (OMAP24XX_SEC_BASE + 0x4000)
++#define OMAP24XX_SEC_AES_BASE	(OMAP24XX_SEC_BASE + 0x6000)
++#define OMAP24XX_SEC_PKA_BASE	(OMAP24XX_SEC_BASE + 0x8000)
++
++#endif /* __ASM_ARCH_OMAP24XX_H */
++
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/omap34xx.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/omap34xx.h	2010-08-08 12:57:07.000000000 +0200
+@@ -0,0 +1,86 @@
++/*
++ * arch/arm/plat-omap/include/mach/omap34xx.h
++ *
++ * This file contains the processor specific definitions of the TI OMAP34XX.
++ *
++ * Copyright (C) 2007 Texas Instruments.
++ * Copyright (C) 2007 Nokia Corporation.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ */
++
++#ifndef __ASM_ARCH_OMAP34XX_H
++#define __ASM_ARCH_OMAP34XX_H
++
++/*
++ * Please place only base defines here and put the rest in device
++ * specific headers.
++ */
++
++#define L4_34XX_BASE		0x48000000
++#define L4_WK_34XX_BASE		0x48300000
++#define L4_PER_34XX_BASE	0x49000000
++#define L4_EMU_34XX_BASE	0x54000000
++#define L3_34XX_BASE		0x68000000
++
++#define OMAP3430_32KSYNCT_BASE	0x48320000
++#define OMAP3430_CM_BASE	0x48004800
++#define OMAP3430_PRM_BASE	0x48306800
++#define OMAP343X_SMS_BASE	0x6C000000
++#define OMAP343X_SDRC_BASE	0x6D000000
++#define OMAP34XX_GPMC_BASE	0x6E000000
++#define OMAP343X_SCM_BASE	0x48002000
++#define OMAP343X_CTRL_BASE	OMAP343X_SCM_BASE
++
++#define OMAP34XX_IC_BASE	0x48200000
++
++#define OMAP3430_ISP_BASE		(L4_34XX_BASE + 0xBC000)
++#define OMAP3430_ISP_CBUFF_BASE		(OMAP3430_ISP_BASE + 0x0100)
++#define OMAP3430_ISP_CCP2_BASE		(OMAP3430_ISP_BASE + 0x0400)
++#define OMAP3430_ISP_CCDC_BASE		(OMAP3430_ISP_BASE + 0x0600)
++#define OMAP3430_ISP_HIST_BASE		(OMAP3430_ISP_BASE + 0x0A00)
++#define OMAP3430_ISP_H3A_BASE		(OMAP3430_ISP_BASE + 0x0C00)
++#define OMAP3430_ISP_PREV_BASE		(OMAP3430_ISP_BASE + 0x0E00)
++#define OMAP3430_ISP_RESZ_BASE		(OMAP3430_ISP_BASE + 0x1000)
++#define OMAP3430_ISP_SBL_BASE		(OMAP3430_ISP_BASE + 0x1200)
++#define OMAP3430_ISP_MMU_BASE		(OMAP3430_ISP_BASE + 0x1400)
++#define OMAP3430_ISP_CSI2A_BASE		(OMAP3430_ISP_BASE + 0x1800)
++#define OMAP3430_ISP_CSI2PHY_BASE	(OMAP3430_ISP_BASE + 0x1970)
++
++#define OMAP3430_ISP_END		(OMAP3430_ISP_BASE         + 0x06F)
++#define OMAP3430_ISP_CBUFF_END		(OMAP3430_ISP_CBUFF_BASE   + 0x077)
++#define OMAP3430_ISP_CCP2_END		(OMAP3430_ISP_CCP2_BASE    + 0x1EF)
++#define OMAP3430_ISP_CCDC_END		(OMAP3430_ISP_CCDC_BASE    + 0x0A7)
++#define OMAP3430_ISP_HIST_END		(OMAP3430_ISP_HIST_BASE    + 0x047)
++#define OMAP3430_ISP_H3A_END		(OMAP3430_ISP_H3A_BASE     + 0x05F)
++#define OMAP3430_ISP_PREV_END		(OMAP3430_ISP_PREV_BASE    + 0x09F)
++#define OMAP3430_ISP_RESZ_END		(OMAP3430_ISP_RESZ_BASE    + 0x0AB)
++#define OMAP3430_ISP_SBL_END		(OMAP3430_ISP_SBL_BASE     + 0x0FB)
++#define OMAP3430_ISP_MMU_END		(OMAP3430_ISP_MMU_BASE     + 0x06F)
++#define OMAP3430_ISP_CSI2A_END		(OMAP3430_ISP_CSI2A_BASE   + 0x16F)
++#define OMAP3430_ISP_CSI2PHY_END	(OMAP3430_ISP_CSI2PHY_BASE + 0x007)
++
++#define OMAP34XX_HSUSB_OTG_BASE	(L4_34XX_BASE + 0xAB000)
++#define OMAP34XX_USBTLL_BASE	(L4_34XX_BASE + 0x62000)
++#define OMAP34XX_UHH_CONFIG_BASE	(L4_34XX_BASE + 0x64000)
++#define OMAP34XX_OHCI_BASE	(L4_34XX_BASE + 0x64400)
++#define OMAP34XX_EHCI_BASE	(L4_34XX_BASE + 0x64800)
++#define OMAP34XX_SR1_BASE	0x480C9000
++#define OMAP34XX_SR2_BASE	0x480CB000
++
++#define OMAP34XX_MAILBOX_BASE		(L4_34XX_BASE + 0x94000)
++
++#endif /* __ASM_ARCH_OMAP34XX_H */
++
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/omap44xx.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/omap44xx.h	2010-08-08 12:57:07.000000000 +0200
+@@ -0,0 +1,48 @@
++/*:
++ * Address mappings and base address for OMAP4 interconnects
++ * and peripherals.
++ *
++ * Copyright (C) 2009 Texas Instruments
++ *
++ * Author: Santosh Shilimkar <[email protected]>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++#ifndef __ASM_ARCH_OMAP44XX_H
++#define __ASM_ARCH_OMAP44XX_H
++
++/*
++ * Please place only base defines here and put the rest in device
++ * specific headers.
++ */
++#define L4_44XX_BASE			0x4a000000
++#define L4_WK_44XX_BASE			0x4a300000
++#define L4_PER_44XX_BASE		0x48000000
++#define L4_EMU_44XX_BASE		0x54000000
++#define L3_44XX_BASE			0x44000000
++#define OMAP44XX_EMIF1_BASE		0x4c000000
++#define OMAP44XX_EMIF2_BASE		0x4d000000
++#define OMAP44XX_DMM_BASE		0x4e000000
++#define OMAP4430_32KSYNCT_BASE		0x4a304000
++#define OMAP4430_CM1_BASE		0x4a004000
++#define OMAP4430_CM_BASE		OMAP4430_CM1_BASE
++#define OMAP4430_CM2_BASE		0x4a008000
++#define OMAP4430_PRM_BASE		0x4a306000
++#define OMAP44XX_GPMC_BASE		0x50000000
++#define OMAP443X_SCM_BASE		0x4a002000
++#define OMAP443X_CTRL_BASE		OMAP443X_SCM_BASE
++#define OMAP44XX_IC_BASE		0x48200000
++#define OMAP44XX_IVA_INTC_BASE		0x40000000
++#define IRQ_SIR_IRQ			0x0040
++#define OMAP44XX_GIC_DIST_BASE		0x48241000
++#define OMAP44XX_GIC_CPU_BASE		0x48240100
++#define OMAP44XX_SCU_BASE		0x48240000
++#define OMAP44XX_LOCAL_TWD_BASE		0x48240600
++#define OMAP44XX_WKUPGEN_BASE		0x48281000
++
++#define OMAP44XX_MAILBOX_BASE		(L4_44XX_BASE + 0xF4000)
++
++#endif /* __ASM_ARCH_OMAP44XX_H */
++
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/omap730.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/omap730.h	2010-08-08 12:57:08.000000000 +0200
+@@ -0,0 +1,102 @@
++/* arch/arm/plat-omap/include/mach/omap730.h
++ *
++ * Hardware definitions for TI OMAP730 processor.
++ *
++ * Cleanup for Linux-2.6 by Dirk Behme <[email protected]>
++ *
++ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ *
++ * 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.,
++ * 675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++
++#ifndef __ASM_ARCH_OMAP730_H
++#define __ASM_ARCH_OMAP730_H
++
++/*
++ * ----------------------------------------------------------------------------
++ * Base addresses
++ * ----------------------------------------------------------------------------
++ */
++
++/* Syntax: XX_BASE = Virtual base address, XX_START = Physical base address */
++
++#define OMAP730_DSP_BASE	0xE0000000
++#define OMAP730_DSP_SIZE	0x50000
++#define OMAP730_DSP_START	0xE0000000
++
++#define OMAP730_DSPREG_BASE	0xE1000000
++#define OMAP730_DSPREG_SIZE	SZ_128K
++#define OMAP730_DSPREG_START	0xE1000000
++
++/*
++ * ----------------------------------------------------------------------------
++ * OMAP730 specific configuration registers
++ * ----------------------------------------------------------------------------
++ */
++#define OMAP730_CONFIG_BASE	0xfffe1000
++#define OMAP730_IO_CONF_0	0xfffe1070
++#define OMAP730_IO_CONF_1	0xfffe1074
++#define OMAP730_IO_CONF_2	0xfffe1078
++#define OMAP730_IO_CONF_3	0xfffe107c
++#define OMAP730_IO_CONF_4	0xfffe1080
++#define OMAP730_IO_CONF_5	0xfffe1084
++#define OMAP730_IO_CONF_6	0xfffe1088
++#define OMAP730_IO_CONF_7	0xfffe108c
++#define OMAP730_IO_CONF_8	0xfffe1090
++#define OMAP730_IO_CONF_9	0xfffe1094
++#define OMAP730_IO_CONF_10	0xfffe1098
++#define OMAP730_IO_CONF_11	0xfffe109c
++#define OMAP730_IO_CONF_12	0xfffe10a0
++#define OMAP730_IO_CONF_13	0xfffe10a4
++
++#define OMAP730_MODE_1		0xfffe1010
++#define OMAP730_MODE_2		0xfffe1014
++
++/* CSMI specials: in terms of base + offset */
++#define OMAP730_MODE2_OFFSET	0x14
++
++/*
++ * ----------------------------------------------------------------------------
++ * OMAP730 traffic controller configuration registers
++ * ----------------------------------------------------------------------------
++ */
++#define OMAP730_FLASH_CFG_0	0xfffecc10
++#define OMAP730_FLASH_ACFG_0	0xfffecc50
++#define OMAP730_FLASH_CFG_1	0xfffecc14
++#define OMAP730_FLASH_ACFG_1	0xfffecc54
++
++/*
++ * ----------------------------------------------------------------------------
++ * OMAP730 DSP control registers
++ * ----------------------------------------------------------------------------
++ */
++#define OMAP730_ICR_BASE	0xfffbb800
++#define OMAP730_DSP_M_CTL	0xfffbb804
++#define OMAP730_DSP_MMU_BASE	0xfffed200
++
++/*
++ * ----------------------------------------------------------------------------
++ * OMAP730 PCC_UPLD configuration registers
++ * ----------------------------------------------------------------------------
++ */
++#define OMAP730_PCC_UPLD_CTRL_BASE	(0xfffe0900)
++#define OMAP730_PCC_UPLD_CTRL		(OMAP730_PCC_UPLD_CTRL_BASE + 0x00)
++
++#endif /*  __ASM_ARCH_OMAP730_H */
++
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/omap7xx.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/omap7xx.h	2010-08-08 12:57:09.000000000 +0200
+@@ -0,0 +1,104 @@
++/* arch/arm/plat-omap/include/mach/omap7xx.h
++ *
++ * Hardware definitions for TI OMAP7XX processor.
++ *
++ * Cleanup for Linux-2.6 by Dirk Behme <[email protected]>
++ * Adapted for omap850 by Zebediah C. McClure <[email protected]>
++ * Adapted for omap7xx by Alistair Buxton <[email protected]>
++ *
++ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ *
++ * 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.,
++ * 675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++
++#ifndef __ASM_ARCH_OMAP7XX_H
++#define __ASM_ARCH_OMAP7XX_H
++
++/*
++ * ----------------------------------------------------------------------------
++ * Base addresses
++ * ----------------------------------------------------------------------------
++ */
++
++/* Syntax: XX_BASE = Virtual base address, XX_START = Physical base address */
++
++#define OMAP7XX_DSP_BASE	0xE0000000
++#define OMAP7XX_DSP_SIZE	0x50000
++#define OMAP7XX_DSP_START	0xE0000000
++
++#define OMAP7XX_DSPREG_BASE	0xE1000000
++#define OMAP7XX_DSPREG_SIZE	SZ_128K
++#define OMAP7XX_DSPREG_START	0xE1000000
++
++/*
++ * ----------------------------------------------------------------------------
++ * OMAP7XX specific configuration registers
++ * ----------------------------------------------------------------------------
++ */
++#define OMAP7XX_CONFIG_BASE	0xfffe1000
++#define OMAP7XX_IO_CONF_0	0xfffe1070
++#define OMAP7XX_IO_CONF_1	0xfffe1074
++#define OMAP7XX_IO_CONF_2	0xfffe1078
++#define OMAP7XX_IO_CONF_3	0xfffe107c
++#define OMAP7XX_IO_CONF_4	0xfffe1080
++#define OMAP7XX_IO_CONF_5	0xfffe1084
++#define OMAP7XX_IO_CONF_6	0xfffe1088
++#define OMAP7XX_IO_CONF_7	0xfffe108c
++#define OMAP7XX_IO_CONF_8	0xfffe1090
++#define OMAP7XX_IO_CONF_9	0xfffe1094
++#define OMAP7XX_IO_CONF_10	0xfffe1098
++#define OMAP7XX_IO_CONF_11	0xfffe109c
++#define OMAP7XX_IO_CONF_12	0xfffe10a0
++#define OMAP7XX_IO_CONF_13	0xfffe10a4
++
++#define OMAP7XX_MODE_1		0xfffe1010
++#define OMAP7XX_MODE_2		0xfffe1014
++
++/* CSMI specials: in terms of base + offset */
++#define OMAP7XX_MODE2_OFFSET	0x14
++
++/*
++ * ----------------------------------------------------------------------------
++ * OMAP7XX traffic controller configuration registers
++ * ----------------------------------------------------------------------------
++ */
++#define OMAP7XX_FLASH_CFG_0	0xfffecc10
++#define OMAP7XX_FLASH_ACFG_0	0xfffecc50
++#define OMAP7XX_FLASH_CFG_1	0xfffecc14
++#define OMAP7XX_FLASH_ACFG_1	0xfffecc54
++
++/*
++ * ----------------------------------------------------------------------------
++ * OMAP7XX DSP control registers
++ * ----------------------------------------------------------------------------
++ */
++#define OMAP7XX_ICR_BASE	0xfffbb800
++#define OMAP7XX_DSP_M_CTL	0xfffbb804
++#define OMAP7XX_DSP_MMU_BASE	0xfffed200
++
++/*
++ * ----------------------------------------------------------------------------
++ * OMAP7XX PCC_UPLD configuration registers
++ * ----------------------------------------------------------------------------
++ */
++#define OMAP7XX_PCC_UPLD_CTRL_BASE	(0xfffe0900)
++#define OMAP7XX_PCC_UPLD_CTRL		(OMAP7XX_PCC_UPLD_CTRL_BASE + 0x00)
++
++#endif /*  __ASM_ARCH_OMAP7XX_H */
++
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/omap850.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/omap850.h	2010-08-08 12:57:09.000000000 +0200
+@@ -0,0 +1,102 @@
++/* arch/arm/plat-omap/include/mach/omap850.h
++ *
++ * Hardware definitions for TI OMAP850 processor.
++ *
++ * Derived from omap730.h by Zebediah C. McClure <[email protected]>
++ *
++ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ *
++ * 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.,
++ * 675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++
++#ifndef __ASM_ARCH_OMAP850_H
++#define __ASM_ARCH_OMAP850_H
++
++/*
++ * ----------------------------------------------------------------------------
++ * Base addresses
++ * ----------------------------------------------------------------------------
++ */
++
++/* Syntax: XX_BASE = Virtual base address, XX_START = Physical base address */
++
++#define OMAP850_DSP_BASE	0xE0000000
++#define OMAP850_DSP_SIZE	0x50000
++#define OMAP850_DSP_START	0xE0000000
++
++#define OMAP850_DSPREG_BASE	0xE1000000
++#define OMAP850_DSPREG_SIZE	SZ_128K
++#define OMAP850_DSPREG_START	0xE1000000
++
++/*
++ * ----------------------------------------------------------------------------
++ * OMAP850 specific configuration registers
++ * ----------------------------------------------------------------------------
++ */
++#define OMAP850_CONFIG_BASE	0xfffe1000
++#define OMAP850_IO_CONF_0	0xfffe1070
++#define OMAP850_IO_CONF_1	0xfffe1074
++#define OMAP850_IO_CONF_2	0xfffe1078
++#define OMAP850_IO_CONF_3	0xfffe107c
++#define OMAP850_IO_CONF_4	0xfffe1080
++#define OMAP850_IO_CONF_5	0xfffe1084
++#define OMAP850_IO_CONF_6	0xfffe1088
++#define OMAP850_IO_CONF_7	0xfffe108c
++#define OMAP850_IO_CONF_8	0xfffe1090
++#define OMAP850_IO_CONF_9	0xfffe1094
++#define OMAP850_IO_CONF_10	0xfffe1098
++#define OMAP850_IO_CONF_11	0xfffe109c
++#define OMAP850_IO_CONF_12	0xfffe10a0
++#define OMAP850_IO_CONF_13	0xfffe10a4
++
++#define OMAP850_MODE_1		0xfffe1010
++#define OMAP850_MODE_2		0xfffe1014
++
++/* CSMI specials: in terms of base + offset */
++#define OMAP850_MODE2_OFFSET	0x14
++
++/*
++ * ----------------------------------------------------------------------------
++ * OMAP850 traffic controller configuration registers
++ * ----------------------------------------------------------------------------
++ */
++#define OMAP850_FLASH_CFG_0	0xfffecc10
++#define OMAP850_FLASH_ACFG_0	0xfffecc50
++#define OMAP850_FLASH_CFG_1	0xfffecc14
++#define OMAP850_FLASH_ACFG_1	0xfffecc54
++
++/*
++ * ----------------------------------------------------------------------------
++ * OMAP850 DSP control registers
++ * ----------------------------------------------------------------------------
++ */
++#define OMAP850_ICR_BASE	0xfffbb800
++#define OMAP850_DSP_M_CTL	0xfffbb804
++#define OMAP850_DSP_MMU_BASE	0xfffed200
++
++/*
++ * ----------------------------------------------------------------------------
++ * OMAP850 PCC_UPLD configuration registers
++ * ----------------------------------------------------------------------------
++ */
++#define OMAP850_PCC_UPLD_CTRL_BASE	(0xfffe0900)
++#define OMAP850_PCC_UPLD_CTRL		(OMAP850_PCC_UPLD_CTRL_BASE + 0x00)
++
++#endif /*  __ASM_ARCH_OMAP850_H */
++
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/omap-alsa.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/omap-alsa.h	2010-08-08 12:57:10.000000000 +0200
+@@ -0,0 +1,123 @@
++/*
++ * arch/arm/plat-omap/include/mach/omap-alsa.h
++ *
++ * Alsa Driver for AIC23 and TSC2101 codecs on OMAP platform boards.
++ *
++ * Copyright (C) 2006 Mika Laitio <[email protected]>
++ *
++ * Copyright (C) 2005 Instituto Nokia de Tecnologia - INdT - Manaus Brazil
++ * Written by Daniel Petrini, David Cohen, Anderson Briglia
++ *            {daniel.petrini, david.cohen, anderson.briglia}@indt.org.br
++ *
++ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ *
++ * 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.,
++ * 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ *  History
++ *  -------
++ *
++ *  2005/07/25 INdT-10LE Kernel Team - 	Alsa driver for omap osk,
++ *  					original version based in sa1100 driver
++ *  					and omap oss driver.
++ */
++
++#ifndef __OMAP_ALSA_H
++#define __OMAP_ALSA_H
++
++#include <plat/dma.h>
++#include <sound/core.h>
++#include <sound/pcm.h>
++#include <plat/mcbsp.h>
++#include <linux/platform_device.h>
++
++#define DMA_BUF_SIZE	(1024 * 8)
++
++/*
++ * Buffer management for alsa and dma
++ */
++struct audio_stream {
++	char *id;		/* identification string */
++	int stream_id;		/* numeric identification */
++	int dma_dev;		/* dma number of that device */
++	int *lch;		/* Chain of channels this stream is linked to */
++	char started;		/* to store if the chain was started or not */
++	int dma_q_head;		/* DMA Channel Q Head */
++	int dma_q_tail;		/* DMA Channel Q Tail */
++	char dma_q_count;	/* DMA Channel Q Count */
++	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 */
++	spinlock_t dma_lock;	/* for locking in DMA operations */
++	struct snd_pcm_substream *stream;	/* the pcm stream */
++	unsigned linked:1;	/* dma channels linked */
++	int offset;		/* store start position of the last period in the alsa buffer */
++	int (*hw_start)(void);  /* interface to start HW interface, e.g. McBSP */
++	int (*hw_stop)(void);   /* interface to stop HW interface, e.g. McBSP */
++};
++
++/*
++ * Alsa card structure for aic23
++ */
++struct snd_card_omap_codec {
++	struct snd_card *card;
++	struct snd_pcm *pcm;
++	long samplerate;
++	struct audio_stream s[2];	/* playback & capture */
++};
++
++/* Codec specific information and function pointers.
++ * Codec (omap-alsa-aic23.c and omap-alsa-tsc2101.c)
++ * are responsible for defining the function pointers.
++ */
++struct omap_alsa_codec_config {
++	char 	*name;
++	struct	omap_mcbsp_reg_cfg *mcbsp_regs_alsa;
++	struct	snd_pcm_hw_constraint_list *hw_constraints_rates;
++	struct	snd_pcm_hardware *snd_omap_alsa_playback;
++	struct	snd_pcm_hardware *snd_omap_alsa_capture;
++	void	(*codec_configure_dev)(void);
++	void	(*codec_set_samplerate)(long);
++	void	(*codec_clock_setup)(void);
++	int	(*codec_clock_on)(void);
++	int 	(*codec_clock_off)(void);
++	int	(*get_default_samplerate)(void);
++};
++
++/*********** Mixer function prototypes *************************/
++int snd_omap_mixer(struct snd_card_omap_codec *);
++void snd_omap_init_mixer(void);
++
++#ifdef CONFIG_PM
++void snd_omap_suspend_mixer(void);
++void snd_omap_resume_mixer(void);
++#endif
++
++int snd_omap_alsa_post_probe(struct platform_device *pdev, struct omap_alsa_codec_config *config);
++int snd_omap_alsa_remove(struct platform_device *pdev);
++#ifdef CONFIG_PM
++int snd_omap_alsa_suspend(struct platform_device *pdev, pm_message_t state);
++int snd_omap_alsa_resume(struct platform_device *pdev);
++#else
++#define snd_omap_alsa_suspend	NULL
++#define snd_omap_alsa_resume	NULL
++#endif
++
++void callback_omap_alsa_sound_dma(void *);
++
++#endif
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/omap_device.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/omap_device.h	2010-08-08 12:57:10.000000000 +0200
+@@ -0,0 +1,143 @@
++/*
++ * omap_device headers
++ *
++ * Copyright (C) 2009 Nokia Corporation
++ * Paul Walmsley
++ *
++ * Developed in collaboration with (alphabetical order): Benoit
++ * Cousson, Kevin Hilman, Tony Lindgren, Rajendra Nayak, Vikram
++ * Pandita, Sakari Poussa, Anand Sawant, Santosh Shilimkar, Richard
++ * Woodruff
++ *
++ * 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.
++ *
++ * Eventually this type of functionality should either be
++ * a) implemented via arch-specific pointers in platform_device
++ * or
++ * b) implemented as a proper omap_bus/omap_device in Linux, no more
++ *    platform_device
++ *
++ * omap_device differs from omap_hwmod in that it includes external
++ * (e.g., board- and system-level) integration details.  omap_hwmod
++ * stores hardware data that is invariant for a given OMAP chip.
++ *
++ * To do:
++ * - GPIO integration
++ * - regulator integration
++ *
++ */
++#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_DEVICE_H
++#define __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_DEVICE_H
++
++#include <linux/kernel.h>
++#include <linux/platform_device.h>
++
++#include <plat/omap_hwmod.h>
++
++/* omap_device._state values */
++#define OMAP_DEVICE_STATE_UNKNOWN	0
++#define OMAP_DEVICE_STATE_ENABLED	1
++#define OMAP_DEVICE_STATE_IDLE		2
++#define OMAP_DEVICE_STATE_SHUTDOWN	3
++
++/**
++ * struct omap_device - omap_device wrapper for platform_devices
++ * @pdev: platform_device
++ * @hwmods: (one .. many per omap_device)
++ * @hwmods_cnt: ARRAY_SIZE() of @hwmods
++ * @pm_lats: ptr to an omap_device_pm_latency table
++ * @pm_lats_cnt: ARRAY_SIZE() of what is passed to @pm_lats
++ * @pm_lat_level: array index of the last odpl entry executed - -1 if never
++ * @dev_wakeup_lat: dev wakeup latency in nanoseconds
++ * @_dev_wakeup_lat_limit: dev wakeup latency limit in nsec - set by OMAP PM
++ * @_state: one of OMAP_DEVICE_STATE_* (see above)
++ * @flags: device flags
++ *
++ * Integrates omap_hwmod data into Linux platform_device.
++ *
++ * Field names beginning with underscores are for the internal use of
++ * the omap_device code.
++ *
++ */
++struct omap_device {
++	struct platform_device		pdev;
++	struct omap_hwmod		**hwmods;
++	struct omap_device_pm_latency	*pm_lats;
++	u32				dev_wakeup_lat;
++	u32				_dev_wakeup_lat_limit;
++	u8				pm_lats_cnt;
++	s8				pm_lat_level;
++	u8				hwmods_cnt;
++	u8				_state;
++};
++
++/* Device driver interface (call via platform_data fn ptrs) */
++
++int omap_device_enable(struct platform_device *pdev);
++int omap_device_idle(struct platform_device *pdev);
++int omap_device_shutdown(struct platform_device *pdev);
++
++/* Core code interface */
++
++int omap_device_count_resources(struct omap_device *od);
++int omap_device_fill_resources(struct omap_device *od, struct resource *res);
++
++struct omap_device *omap_device_build(const char *pdev_name, int pdev_id,
++				      struct omap_hwmod *oh, void *pdata,
++				      int pdata_len,
++				      struct omap_device_pm_latency *pm_lats,
++				      int pm_lats_cnt);
++
++struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id,
++					 struct omap_hwmod **oh, int oh_cnt,
++					 void *pdata, int pdata_len,
++					 struct omap_device_pm_latency *pm_lats,
++					 int pm_lats_cnt);
++
++int omap_device_register(struct omap_device *od);
++
++/* OMAP PM interface */
++int omap_device_align_pm_lat(struct platform_device *pdev,
++			     u32 new_wakeup_lat_limit);
++struct powerdomain *omap_device_get_pwrdm(struct omap_device *od);
++
++/* Other */
++
++int omap_device_idle_hwmods(struct omap_device *od);
++int omap_device_enable_hwmods(struct omap_device *od);
++
++int omap_device_disable_clocks(struct omap_device *od);
++int omap_device_enable_clocks(struct omap_device *od);
++
++
++/*
++ * Entries should be kept in latency order ascending
++ *
++ * deact_lat is the maximum number of microseconds required to complete
++ * deactivate_func() at the device's slowest OPP.
++ *
++ * act_lat is the maximum number of microseconds required to complete
++ * activate_func() at the device's slowest OPP.
++ *
++ * This will result in some suboptimal power management decisions at fast
++ * OPPs, but avoids having to recompute all device power management decisions
++ * if the system shifts from a fast OPP to a slow OPP (in order to meet
++ * latency requirements).
++ *
++ * XXX should deactivate_func/activate_func() take platform_device pointers
++ * rather than omap_device pointers?
++ */
++struct omap_device_pm_latency {
++	u32 deactivate_lat;
++	int (*deactivate_func)(struct omap_device *od);
++	u32 activate_lat;
++	int (*activate_func)(struct omap_device *od);
++};
++
++
++/* Get omap_device pointer from platform_device pointer */
++#define to_omap_device(x) container_of((x), struct omap_device, pdev)
++
++#endif
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/omap_hwmod.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/omap_hwmod.h	2010-08-08 12:57:11.000000000 +0200
+@@ -0,0 +1,467 @@
++/*
++ * omap_hwmod macros, structures
++ *
++ * Copyright (C) 2009 Nokia Corporation
++ * Paul Walmsley
++ *
++ * Created in collaboration with (alphabetical order): Benoit Cousson,
++ * Kevin Hilman, Tony Lindgren, Rajendra Nayak, Vikram Pandita, Sakari
++ * Poussa, Anand Sawant, Santosh Shilimkar, Richard Woodruff
++ *
++ * 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.
++ *
++ * These headers and macros are used to define OMAP on-chip module
++ * data and their integration with other OMAP modules and Linux.
++ *
++ * References:
++ * - OMAP2420 Multimedia Processor Silicon Revision 2.1.1, 2.2 (SWPU064)
++ * - OMAP2430 Multimedia Device POP Silicon Revision 2.1 (SWPU090)
++ * - OMAP34xx Multimedia Device Silicon Revision 3.1 (SWPU108)
++ * - OMAP4430 Multimedia Device Silicon Revision 1.0 (SWPU140)
++ * - Open Core Protocol Specification 2.2
++ *
++ * To do:
++ * - add interconnect error log structures
++ * - add pinmuxing
++ * - init_conn_id_bit (CONNID_BIT_VECTOR)
++ * - implement default hwmod SMS/SDRC flags?
++ *
++ */
++#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_HWMOD_H
++#define __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_HWMOD_H
++
++#include <linux/kernel.h>
++#include <linux/ioport.h>
++
++#include <plat/cpu.h>
++
++struct omap_device;
++
++/* OCP SYSCONFIG bit shifts/masks */
++#define SYSC_MIDLEMODE_SHIFT		12
++#define SYSC_MIDLEMODE_MASK		(0x3 << SYSC_MIDLEMODE_SHIFT)
++#define SYSC_CLOCKACTIVITY_SHIFT	8
++#define SYSC_CLOCKACTIVITY_MASK		(0x3 << SYSC_CLOCKACTIVITY_SHIFT)
++#define SYSC_SIDLEMODE_SHIFT		3
++#define SYSC_SIDLEMODE_MASK		(0x3 << SYSC_SIDLEMODE_SHIFT)
++#define SYSC_ENAWAKEUP_SHIFT		2
++#define SYSC_ENAWAKEUP_MASK		(1 << SYSC_ENAWAKEUP_SHIFT)
++#define SYSC_SOFTRESET_SHIFT		1
++#define SYSC_SOFTRESET_MASK		(1 << SYSC_SOFTRESET_SHIFT)
++#define SYSC_AUTOIDLE_SHIFT		0
++#define SYSC_AUTOIDLE_MASK		(1 << SYSC_AUTOIDLE_SHIFT)
++
++/* OCP SYSSTATUS bit shifts/masks */
++#define SYSS_RESETDONE_SHIFT		0
++#define SYSS_RESETDONE_MASK		(1 << SYSS_RESETDONE_SHIFT)
++
++/* Master standby/slave idle mode flags */
++#define HWMOD_IDLEMODE_FORCE		(1 << 0)
++#define HWMOD_IDLEMODE_NO		(1 << 1)
++#define HWMOD_IDLEMODE_SMART		(1 << 2)
++
++
++/**
++ * struct omap_hwmod_irq_info - MPU IRQs used by the hwmod
++ * @name: name of the IRQ channel (module local name)
++ * @irq_ch: IRQ channel ID
++ *
++ * @name should be something short, e.g., "tx" or "rx".  It is for use
++ * by platform_get_resource_byname().  It is defined locally to the
++ * hwmod.
++ */
++struct omap_hwmod_irq_info {
++	const char	*name;
++	u16		irq;
++};
++
++/**
++ * struct omap_hwmod_dma_info - DMA channels used by the hwmod
++ * @name: name of the DMA channel (module local name)
++ * @dma_ch: DMA channel ID
++ *
++ * @name should be something short, e.g., "tx" or "rx".  It is for use
++ * by platform_get_resource_byname().  It is defined locally to the
++ * hwmod.
++ */
++struct omap_hwmod_dma_info {
++	const char	*name;
++	u16		dma_ch;
++};
++
++/**
++ * struct omap_hwmod_opt_clk - optional clocks used by this hwmod
++ * @role: "sys", "32k", "tv", etc -- for use in clk_get()
++ * @clkdev_dev_id: opt clock: clkdev dev_id string
++ * @clkdev_con_id: opt clock: clkdev con_id string
++ * @_clk: pointer to the struct clk (filled in at runtime)
++ *
++ * The module's interface clock and main functional clock should not
++ * be added as optional clocks.
++ */
++struct omap_hwmod_opt_clk {
++	const char	*role;
++	const char	*clkdev_dev_id;
++	const char	*clkdev_con_id;
++	struct clk	*_clk;
++};
++
++
++/* omap_hwmod_omap2_firewall.flags bits */
++#define OMAP_FIREWALL_L3		(1 << 0)
++#define OMAP_FIREWALL_L4		(1 << 1)
++
++/**
++ * struct omap_hwmod_omap2_firewall - OMAP2/3 device firewall data
++ * @l3_perm_bit: bit shift for L3_PM_*_PERMISSION_*
++ * @l4_fw_region: L4 firewall region ID
++ * @l4_prot_group: L4 protection group ID
++ * @flags: (see omap_hwmod_omap2_firewall.flags macros above)
++ */
++struct omap_hwmod_omap2_firewall {
++	u8 l3_perm_bit;
++	u8 l4_fw_region;
++	u8 l4_prot_group;
++	u8 flags;
++};
++
++
++/*
++ * omap_hwmod_addr_space.flags bits
++ *
++ * ADDR_MAP_ON_INIT: Map this address space during omap_hwmod init.
++ * ADDR_TYPE_RT: Address space contains module register target data.
++ */
++#define ADDR_MAP_ON_INIT	(1 << 0)
++#define ADDR_TYPE_RT		(1 << 1)
++
++/**
++ * struct omap_hwmod_addr_space - MPU address space handled by the hwmod
++ * @pa_start: starting physical address
++ * @pa_end: ending physical address
++ * @flags: (see omap_hwmod_addr_space.flags macros above)
++ *
++ * Address space doesn't necessarily follow physical interconnect
++ * structure.  GPMC is one example.
++ */
++struct omap_hwmod_addr_space {
++	u32 pa_start;
++	u32 pa_end;
++	u8 flags;
++};
++
++
++/*
++ * omap_hwmod_ocp_if.user bits: these indicate the initiators that use this
++ * interface to interact with the hwmod.  Used to add sleep dependencies
++ * when the module is enabled or disabled.
++ */
++#define OCP_USER_MPU			(1 << 0)
++#define OCP_USER_SDMA			(1 << 1)
++
++/* omap_hwmod_ocp_if.flags bits */
++#define OCPIF_HAS_IDLEST		(1 << 0)
++#define OCPIF_SWSUP_IDLE		(1 << 1)
++#define OCPIF_CAN_BURST			(1 << 2)
++
++/**
++ * struct omap_hwmod_ocp_if - OCP interface data
++ * @master: struct omap_hwmod that initiates OCP transactions on this link
++ * @slave: struct omap_hwmod that responds to OCP transactions on this link
++ * @addr: address space associated with this link
++ * @clkdev_dev_id: interface clock: clkdev dev_id string
++ * @clkdev_con_id: interface clock: clkdev con_id string
++ * @_clk: pointer to the interface struct clk (filled in at runtime)
++ * @fw: interface firewall data
++ * @addr_cnt: ARRAY_SIZE(@addr)
++ * @width: OCP data width
++ * @thread_cnt: number of threads
++ * @max_burst_len: maximum burst length in @width sized words (0 if unlimited)
++ * @user: initiators using this interface (see OCP_USER_* macros above)
++ * @flags: OCP interface flags (see OCPIF_* macros above)
++ *
++ * It may also be useful to add a tag_cnt field for OCP2.x devices.
++ *
++ * Parameter names beginning with an underscore are managed internally by
++ * the omap_hwmod code and should not be set during initialization.
++ */
++struct omap_hwmod_ocp_if {
++	struct omap_hwmod		*master;
++	struct omap_hwmod		*slave;
++	struct omap_hwmod_addr_space	*addr;
++	const char			*clkdev_dev_id;
++	const char			*clkdev_con_id;
++	struct clk			*_clk;
++	union {
++		struct omap_hwmod_omap2_firewall omap2;
++	}				fw;
++	u8				addr_cnt;
++	u8				width;
++	u8				thread_cnt;
++	u8				max_burst_len;
++	u8				user;
++	u8				flags;
++};
++
++
++/* Macros for use in struct omap_hwmod_sysconfig */
++
++/* Flags for use in omap_hwmod_sysconfig.idlemodes */
++#define MASTER_STANDBY_SHIFT	2
++#define SLAVE_IDLE_SHIFT	0
++#define SIDLE_FORCE		(HWMOD_IDLEMODE_FORCE << SLAVE_IDLE_SHIFT)
++#define SIDLE_NO		(HWMOD_IDLEMODE_NO << SLAVE_IDLE_SHIFT)
++#define SIDLE_SMART		(HWMOD_IDLEMODE_SMART << SLAVE_IDLE_SHIFT)
++#define MSTANDBY_FORCE		(HWMOD_IDLEMODE_FORCE << MASTER_STANDBY_SHIFT)
++#define MSTANDBY_NO		(HWMOD_IDLEMODE_NO << MASTER_STANDBY_SHIFT)
++#define MSTANDBY_SMART		(HWMOD_IDLEMODE_SMART << MASTER_STANDBY_SHIFT)
++
++/* omap_hwmod_sysconfig.sysc_flags capability flags */
++#define SYSC_HAS_AUTOIDLE	(1 << 0)
++#define SYSC_HAS_SOFTRESET	(1 << 1)
++#define SYSC_HAS_ENAWAKEUP	(1 << 2)
++#define SYSC_HAS_EMUFREE	(1 << 3)
++#define SYSC_HAS_CLOCKACTIVITY	(1 << 4)
++#define SYSC_HAS_SIDLEMODE	(1 << 5)
++#define SYSC_HAS_MIDLEMODE	(1 << 6)
++#define SYSS_MISSING		(1 << 7)
++
++/* omap_hwmod_sysconfig.clockact flags */
++#define CLOCKACT_TEST_BOTH	0x0
++#define CLOCKACT_TEST_MAIN	0x1
++#define CLOCKACT_TEST_ICLK	0x2
++#define CLOCKACT_TEST_NONE	0x3
++
++/**
++ * struct omap_hwmod_sysconfig - hwmod OCP_SYSCONFIG/OCP_SYSSTATUS data
++ * @rev_offs: IP block revision register offset (from module base addr)
++ * @sysc_offs: OCP_SYSCONFIG register offset (from module base addr)
++ * @syss_offs: OCP_SYSSTATUS register offset (from module base addr)
++ * @idlemodes: One or more of {SIDLE,MSTANDBY}_{OFF,FORCE,SMART}
++ * @sysc_flags: SYS{C,S}_HAS* flags indicating SYSCONFIG bits supported
++ * @clockact: the default value of the module CLOCKACTIVITY bits
++ *
++ * @clockact describes to the module which clocks are likely to be
++ * disabled when the PRCM issues its idle request to the module.  Some
++ * modules have separate clockdomains for the interface clock and main
++ * functional clock, and can check whether they should acknowledge the
++ * idle request based on the internal module functionality that has
++ * been associated with the clocks marked in @clockact.  This field is
++ * only used if HWMOD_SET_DEFAULT_CLOCKACT is set (see below)
++ *
++ */
++struct omap_hwmod_sysconfig {
++	u16 rev_offs;
++	u16 sysc_offs;
++	u16 syss_offs;
++	u8 idlemodes;
++	u8 sysc_flags;
++	u8 clockact;
++};
++
++/**
++ * struct omap_hwmod_omap2_prcm - OMAP2/3-specific PRCM data
++ * @module_offs: PRCM submodule offset from the start of the PRM/CM
++ * @prcm_reg_id: PRCM register ID (e.g., 3 for CM_AUTOIDLE3)
++ * @module_bit: register bit shift for AUTOIDLE, WKST, WKEN, GRPSEL regs
++ * @idlest_reg_id: IDLEST register ID (e.g., 3 for CM_IDLEST3)
++ * @idlest_idle_bit: register bit shift for CM_IDLEST slave idle bit
++ * @idlest_stdby_bit: register bit shift for CM_IDLEST master standby bit
++ *
++ * @prcm_reg_id and @module_bit are specific to the AUTOIDLE, WKST,
++ * WKEN, GRPSEL registers.  In an ideal world, no extra information
++ * would be needed for IDLEST information, but alas, there are some
++ * exceptions, so @idlest_reg_id, @idlest_idle_bit, @idlest_stdby_bit
++ * are needed for the IDLEST registers (c.f. 2430 I2CHS, 3430 USBHOST)
++ */
++struct omap_hwmod_omap2_prcm {
++	s16 module_offs;
++	u8 prcm_reg_id;
++	u8 module_bit;
++	u8 idlest_reg_id;
++	u8 idlest_idle_bit;
++	u8 idlest_stdby_bit;
++};
++
++
++/**
++ * struct omap_hwmod_omap4_prcm - OMAP4-specific PRCM data
++ * @module_offs: PRCM submodule offset from the start of the PRM/CM1/CM2
++ * @device_offs: device register offset from @module_offs
++ * @submodule_wkdep_bit: bit shift of the WKDEP range
++ */
++struct omap_hwmod_omap4_prcm {
++	u32 module_offs;
++	u16 device_offs;
++	u8 submodule_wkdep_bit;
++};
++
++
++/*
++ * omap_hwmod.flags definitions
++ *
++ * HWMOD_SWSUP_SIDLE: omap_hwmod code should manually bring module in and out
++ *     of idle, rather than relying on module smart-idle
++ * HWMOD_SWSUP_MSTDBY: omap_hwmod code should manually bring module in and out
++ *     of standby, rather than relying on module smart-standby
++ * HWMOD_INIT_NO_RESET: don't reset this module at boot - important for
++ *     SDRAM controller, etc.
++ * HWMOD_INIT_NO_IDLE: don't idle this module at boot - important for SDRAM
++ *     controller, etc.
++ * HWMOD_NO_AUTOIDLE: disable module autoidle (OCP_SYSCONFIG.AUTOIDLE)
++ *     when module is enabled, rather than the default, which is to
++ *     enable autoidle
++ * HWMOD_SET_DEFAULT_CLOCKACT: program CLOCKACTIVITY bits at startup
++ */
++#define HWMOD_SWSUP_SIDLE			(1 << 0)
++#define HWMOD_SWSUP_MSTANDBY			(1 << 1)
++#define HWMOD_INIT_NO_RESET			(1 << 2)
++#define HWMOD_INIT_NO_IDLE			(1 << 3)
++#define HWMOD_NO_OCP_AUTOIDLE			(1 << 4)
++#define HWMOD_SET_DEFAULT_CLOCKACT		(1 << 5)
++
++/*
++ * omap_hwmod._int_flags definitions
++ * These are for internal use only and are managed by the omap_hwmod code.
++ *
++ * _HWMOD_NO_MPU_PORT: no path exists for the MPU to write to this module
++ * _HWMOD_WAKEUP_ENABLED: set when the omap_hwmod code has enabled ENAWAKEUP
++ * _HWMOD_SYSCONFIG_LOADED: set when the OCP_SYSCONFIG value has been cached
++ */
++#define _HWMOD_NO_MPU_PORT			(1 << 0)
++#define _HWMOD_WAKEUP_ENABLED			(1 << 1)
++#define _HWMOD_SYSCONFIG_LOADED			(1 << 2)
++
++/*
++ * omap_hwmod._state definitions
++ *
++ * INITIALIZED: reset (optionally), initialized, enabled, disabled
++ *              (optionally)
++ *
++ *
++ */
++#define _HWMOD_STATE_UNKNOWN			0
++#define _HWMOD_STATE_REGISTERED			1
++#define _HWMOD_STATE_CLKS_INITED		2
++#define _HWMOD_STATE_INITIALIZED		3
++#define _HWMOD_STATE_ENABLED			4
++#define _HWMOD_STATE_IDLE			5
++#define _HWMOD_STATE_DISABLED			6
++
++/**
++ * struct omap_hwmod - integration data for OMAP hardware "modules" (IP blocks)
++ * @name: name of the hwmod
++ * @od: struct omap_device currently associated with this hwmod (internal use)
++ * @mpu_irqs: ptr to an array of MPU IRQs (see also mpu_irqs_cnt)
++ * @sdma_chs: ptr to an array of SDMA channel IDs (see also sdma_chs_cnt)
++ * @prcm: PRCM data pertaining to this hwmod
++ * @clkdev_dev_id: main clock: clkdev dev_id string
++ * @clkdev_con_id: main clock: clkdev con_id string
++ * @_clk: pointer to the main struct clk (filled in at runtime)
++ * @opt_clks: other device clocks that drivers can request (0..*)
++ * @masters: ptr to array of OCP ifs that this hwmod can initiate on
++ * @slaves: ptr to array of OCP ifs that this hwmod can respond on
++ * @sysconfig: device SYSCONFIG/SYSSTATUS register data
++ * @dev_attr: arbitrary device attributes that can be passed to the driver
++ * @_sysc_cache: internal-use hwmod flags
++ * @_rt_va: cached register target start address (internal use)
++ * @_mpu_port_index: cached MPU register target slave ID (internal use)
++ * @msuspendmux_reg_id: CONTROL_MSUSPENDMUX register ID (1-6)
++ * @msuspendmux_shift: CONTROL_MSUSPENDMUX register bit shift
++ * @mpu_irqs_cnt: number of @mpu_irqs
++ * @sdma_chs_cnt: number of @sdma_chs
++ * @opt_clks_cnt: number of @opt_clks
++ * @master_cnt: number of @master entries
++ * @slaves_cnt: number of @slave entries
++ * @response_lat: device OCP response latency (in interface clock cycles)
++ * @_int_flags: internal-use hwmod flags
++ * @_state: internal-use hwmod state
++ * @flags: hwmod flags (documented below)
++ * @omap_chip: OMAP chips this hwmod is present on
++ * @node: list node for hwmod list (internal use)
++ *
++ * @clkdev_dev_id, @clkdev_con_id, and @clk all refer to this module's "main
++ * clock," which for our purposes is defined as "the functional clock needed
++ * for register accesses to complete."  Modules may not have a main clock if
++ * the interface clock also serves as a main clock.
++ *
++ * Parameter names beginning with an underscore are managed internally by
++ * the omap_hwmod code and should not be set during initialization.
++ */
++struct omap_hwmod {
++	const char			*name;
++	struct omap_device		*od;
++	struct omap_hwmod_irq_info	*mpu_irqs;
++	struct omap_hwmod_dma_info	*sdma_chs;
++	union {
++		struct omap_hwmod_omap2_prcm omap2;
++		struct omap_hwmod_omap4_prcm omap4;
++	}				prcm;
++	const char			*clkdev_dev_id;
++	const char			*clkdev_con_id;
++	struct clk			*_clk;
++	struct omap_hwmod_opt_clk	*opt_clks;
++	struct omap_hwmod_ocp_if	**masters; /* connect to *_IA */
++	struct omap_hwmod_ocp_if	**slaves;  /* connect to *_TA */
++	struct omap_hwmod_sysconfig	*sysconfig;
++	void				*dev_attr;
++	u32				_sysc_cache;
++	void __iomem			*_rt_va;
++	struct list_head		node;
++	u16				flags;
++	u8				_mpu_port_index;
++	u8				msuspendmux_reg_id;
++	u8				msuspendmux_shift;
++	u8				response_lat;
++	u8				mpu_irqs_cnt;
++	u8				sdma_chs_cnt;
++	u8				opt_clks_cnt;
++	u8				masters_cnt;
++	u8				slaves_cnt;
++	u8				hwmods_cnt;
++	u8				_int_flags;
++	u8				_state;
++	const struct omap_chip_id	omap_chip;
++};
++
++int omap_hwmod_init(struct omap_hwmod **ohs);
++int omap_hwmod_register(struct omap_hwmod *oh);
++int omap_hwmod_unregister(struct omap_hwmod *oh);
++struct omap_hwmod *omap_hwmod_lookup(const char *name);
++int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh));
++int omap_hwmod_late_init(void);
++
++int omap_hwmod_enable(struct omap_hwmod *oh);
++int omap_hwmod_idle(struct omap_hwmod *oh);
++int omap_hwmod_shutdown(struct omap_hwmod *oh);
++
++int omap_hwmod_enable_clocks(struct omap_hwmod *oh);
++int omap_hwmod_disable_clocks(struct omap_hwmod *oh);
++
++int omap_hwmod_reset(struct omap_hwmod *oh);
++void omap_hwmod_ocp_barrier(struct omap_hwmod *oh);
++
++void omap_hwmod_writel(u32 v, struct omap_hwmod *oh, u16 reg_offs);
++u32 omap_hwmod_readl(struct omap_hwmod *oh, u16 reg_offs);
++
++int omap_hwmod_count_resources(struct omap_hwmod *oh);
++int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res);
++
++struct powerdomain *omap_hwmod_get_pwrdm(struct omap_hwmod *oh);
++
++int omap_hwmod_add_initiator_dep(struct omap_hwmod *oh,
++				 struct omap_hwmod *init_oh);
++int omap_hwmod_del_initiator_dep(struct omap_hwmod *oh,
++				 struct omap_hwmod *init_oh);
++
++int omap_hwmod_set_clockact_both(struct omap_hwmod *oh);
++int omap_hwmod_set_clockact_main(struct omap_hwmod *oh);
++int omap_hwmod_set_clockact_iclk(struct omap_hwmod *oh);
++int omap_hwmod_set_clockact_none(struct omap_hwmod *oh);
++
++int omap_hwmod_enable_wakeup(struct omap_hwmod *oh);
++int omap_hwmod_disable_wakeup(struct omap_hwmod *oh);
++
++#endif
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/omap-pm.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/omap-pm.h	2010-08-08 12:57:12.000000000 +0200
+@@ -0,0 +1,301 @@
++/*
++ * omap-pm.h - OMAP power management interface
++ *
++ * Copyright (C) 2008-2009 Texas Instruments, Inc.
++ * Copyright (C) 2008-2009 Nokia Corporation
++ * Paul Walmsley
++ *
++ * Interface developed by (in alphabetical order): Karthik Dasu, Jouni
++ * Högander, Tony Lindgren, Rajendra Nayak, Sakari Poussa,
++ * Veeramanikandan Raju, Anand Sawant, Igor Stoppa, Paul Walmsley,
++ * Richard Woodruff
++ */
++
++#ifndef ASM_ARM_ARCH_OMAP_OMAP_PM_H
++#define ASM_ARM_ARCH_OMAP_OMAP_PM_H
++
++#include <linux/device.h>
++#include <linux/cpufreq.h>
++
++#include "powerdomain.h"
++
++/**
++ * struct omap_opp - clock frequency-to-OPP ID table for DSP, MPU
++ * @rate: target clock rate
++ * @opp_id: OPP ID
++ * @min_vdd: minimum VDD1 voltage (in millivolts) for this OPP
++ *
++ * Operating performance point data.  Can vary by OMAP chip and board.
++ */
++struct omap_opp {
++	unsigned long rate;
++	u8 opp_id;
++	u16 min_vdd;
++};
++
++extern struct omap_opp *mpu_opps;
++extern struct omap_opp *dsp_opps;
++extern struct omap_opp *l3_opps;
++
++/*
++ * agent_id values for use with omap_pm_set_min_bus_tput():
++ *
++ * OCP_INITIATOR_AGENT is only valid for devices that can act as
++ * initiators -- it represents the device's L3 interconnect
++ * connection.  OCP_TARGET_AGENT represents the device's L4
++ * interconnect connection.
++ */
++#define OCP_TARGET_AGENT		1
++#define OCP_INITIATOR_AGENT		2
++
++/**
++ * omap_pm_if_early_init - OMAP PM init code called before clock fw init
++ * @mpu_opp_table: array ptr to struct omap_opp for MPU
++ * @dsp_opp_table: array ptr to struct omap_opp for DSP
++ * @l3_opp_table : array ptr to struct omap_opp for CORE
++ *
++ * Initialize anything that must be configured before the clock
++ * framework starts.  The "_if_" is to avoid name collisions with the
++ * PM idle-loop code.
++ */
++int __init omap_pm_if_early_init(struct omap_opp *mpu_opp_table,
++				 struct omap_opp *dsp_opp_table,
++				 struct omap_opp *l3_opp_table);
++
++/**
++ * omap_pm_if_init - OMAP PM init code called after clock fw init
++ *
++ * The main initialization code.  OPP tables are passed in here.  The
++ * "_if_" is to avoid name collisions with the PM idle-loop code.
++ */
++int __init omap_pm_if_init(void);
++
++/**
++ * omap_pm_if_exit - OMAP PM exit code
++ *
++ * Exit code; currently unused.  The "_if_" is to avoid name
++ * collisions with the PM idle-loop code.
++ */
++void omap_pm_if_exit(void);
++
++/*
++ * Device-driver-originated constraints (via board-*.c files, platform_data)
++ */
++
++
++/**
++ * omap_pm_set_max_mpu_wakeup_lat - set the maximum MPU wakeup latency
++ * @dev: struct device * requesting the constraint
++ * @t: maximum MPU wakeup latency in microseconds
++ *
++ * Request that the maximum interrupt latency for the MPU to be no
++ * greater than 't' microseconds. "Interrupt latency" in this case is
++ * defined as the elapsed time from the occurrence of a hardware or
++ * timer interrupt to the time when the device driver's interrupt
++ * service routine has been entered by the MPU.
++ *
++ * It is intended that underlying PM code will use this information to
++ * determine what power state to put the MPU powerdomain into, and
++ * possibly the CORE powerdomain as well, since interrupt handling
++ * code currently runs from SDRAM.  Advanced PM or board*.c code may
++ * also configure interrupt controller priorities, OCP bus priorities,
++ * CPU speed(s), etc.
++ *
++ * This function will not affect device wakeup latency, e.g., time
++ * elapsed from when a device driver enables a hardware device with
++ * clk_enable(), to when the device is ready for register access or
++ * other use.  To control this device wakeup latency, use
++ * set_max_dev_wakeup_lat()
++ *
++ * Multiple calls to set_max_mpu_wakeup_lat() will replace the
++ * previous t value.  To remove the latency target for the MPU, call
++ * with t = -1.
++ *
++ * No return value.
++ */
++void omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t);
++
++
++/**
++ * omap_pm_set_min_bus_tput - set minimum bus throughput needed by device
++ * @dev: struct device * requesting the constraint
++ * @tbus_id: interconnect to operate on (OCP_{INITIATOR,TARGET}_AGENT)
++ * @r: minimum throughput (in KiB/s)
++ *
++ * Request that the minimum data throughput on the OCP interconnect
++ * attached to device 'dev' interconnect agent 'tbus_id' be no less
++ * than 'r' KiB/s.
++ *
++ * It is expected that the OMAP PM or bus code will use this
++ * information to set the interconnect clock to run at the lowest
++ * possible speed that satisfies all current system users.  The PM or
++ * bus code will adjust the estimate based on its model of the bus, so
++ * device driver authors should attempt to specify an accurate
++ * quantity for their device use case, and let the PM or bus code
++ * overestimate the numbers as necessary to handle request/response
++ * latency, other competing users on the system, etc.  On OMAP2/3, if
++ * a driver requests a minimum L4 interconnect speed constraint, the
++ * code will also need to add an minimum L3 interconnect speed
++ * constraint,
++ *
++ * Multiple calls to set_min_bus_tput() will replace the previous rate
++ * value for this device.  To remove the interconnect throughput
++ * restriction for this device, call with r = 0.
++ *
++ * No return value.
++ */
++void omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r);
++
++
++/**
++ * omap_pm_set_max_dev_wakeup_lat - set the maximum device enable latency
++ * @dev: struct device *
++ * @t: maximum device wakeup latency in microseconds
++ *
++ * Request that the maximum amount of time necessary for a device to
++ * become accessible after its clocks are enabled should be no greater
++ * than 't' microseconds.  Specifically, this represents the time from
++ * when a device driver enables device clocks with clk_enable(), to
++ * when the register reads and writes on the device will succeed.
++ * This function should be called before clk_disable() is called,
++ * since the power state transition decision may be made during
++ * clk_disable().
++ *
++ * It is intended that underlying PM code will use this information to
++ * determine what power state to put the powerdomain enclosing this
++ * device into.
++ *
++ * Multiple calls to set_max_dev_wakeup_lat() will replace the
++ * previous wakeup latency values for this device.  To remove the wakeup
++ * latency restriction for this device, call with t = -1.
++ *
++ * No return value.
++ */
++void omap_pm_set_max_dev_wakeup_lat(struct device *dev, long t);
++
++
++/**
++ * omap_pm_set_max_sdma_lat - set the maximum system DMA transfer start latency
++ * @dev: struct device *
++ * @t: maximum DMA transfer start latency in microseconds
++ *
++ * Request that the maximum system DMA transfer start latency for this
++ * device 'dev' should be no greater than 't' microseconds.  "DMA
++ * transfer start latency" here is defined as the elapsed time from
++ * when a device (e.g., McBSP) requests that a system DMA transfer
++ * start or continue, to the time at which data starts to flow into
++ * that device from the system DMA controller.
++ *
++ * It is intended that underlying PM code will use this information to
++ * determine what power state to put the CORE powerdomain into.
++ *
++ * Since system DMA transfers may not involve the MPU, this function
++ * will not affect MPU wakeup latency.  Use set_max_cpu_lat() to do
++ * so.  Similarly, this function will not affect device wakeup latency
++ * -- use set_max_dev_wakeup_lat() to affect that.
++ *
++ * Multiple calls to set_max_sdma_lat() will replace the previous t
++ * value for this device.  To remove the maximum DMA latency for this
++ * device, call with t = -1.
++ *
++ * No return value.
++ */
++void omap_pm_set_max_sdma_lat(struct device *dev, long t);
++
++
++/*
++ * DSP Bridge-specific constraints
++ */
++
++/**
++ * omap_pm_dsp_get_opp_table - get OPP->DSP clock frequency table
++ *
++ * Intended for use by DSPBridge.  Returns an array of OPP->DSP clock
++ * frequency entries.  The final item in the array should have .rate =
++ * .opp_id = 0.
++ */
++const struct omap_opp *omap_pm_dsp_get_opp_table(void);
++
++/**
++ * omap_pm_dsp_set_min_opp - receive desired OPP target ID from DSP Bridge
++ * @opp_id: target DSP OPP ID
++ *
++ * Set a minimum OPP ID for the DSP.  This is intended to be called
++ * only from the DSP Bridge MPU-side driver.  Unfortunately, the only
++ * information that code receives from the DSP/BIOS load estimator is the
++ * target OPP ID; hence, this interface.  No return value.
++ */
++void omap_pm_dsp_set_min_opp(u8 opp_id);
++
++/**
++ * omap_pm_dsp_get_opp - report the current DSP OPP ID
++ *
++ * Report the current OPP for the DSP.  Since on OMAP3, the DSP and
++ * MPU share a single voltage domain, the OPP ID returned back may
++ * represent a higher DSP speed than the OPP requested via
++ * omap_pm_dsp_set_min_opp().
++ *
++ * Returns the current VDD1 OPP ID, or 0 upon error.
++ */
++u8 omap_pm_dsp_get_opp(void);
++
++
++/*
++ * CPUFreq-originated constraint
++ *
++ * In the future, this should be handled by custom OPP clocktype
++ * functions.
++ */
++
++/**
++ * omap_pm_cpu_get_freq_table - return a cpufreq_frequency_table array ptr
++ *
++ * Provide a frequency table usable by CPUFreq for the current chip/board.
++ * Returns a pointer to a struct cpufreq_frequency_table array or NULL
++ * upon error.
++ */
++struct cpufreq_frequency_table **omap_pm_cpu_get_freq_table(void);
++
++/**
++ * omap_pm_cpu_set_freq - set the current minimum MPU frequency
++ * @f: MPU frequency in Hz
++ *
++ * Set the current minimum CPU frequency.  The actual CPU frequency
++ * used could end up higher if the DSP requested a higher OPP.
++ * Intended to be called by plat-omap/cpu_omap.c:omap_target().  No
++ * return value.
++ */
++void omap_pm_cpu_set_freq(unsigned long f);
++
++/**
++ * omap_pm_cpu_get_freq - report the current CPU frequency
++ *
++ * Returns the current MPU frequency, or 0 upon error.
++ */
++unsigned long omap_pm_cpu_get_freq(void);
++
++
++/*
++ * Device context loss tracking
++ */
++
++/**
++ * omap_pm_get_dev_context_loss_count - return count of times dev has lost ctx
++ * @dev: struct device *
++ *
++ * This function returns the number of times that the device @dev has
++ * lost its internal context.  This generally occurs on a powerdomain
++ * transition to OFF.  Drivers use this as an optimization to avoid restoring
++ * context if the device hasn't lost it.  To use, drivers should initially
++ * call this in their context save functions and store the result.  Early in
++ * the driver's context restore function, the driver should call this function
++ * again, and compare the result to the stored counter.  If they differ, the
++ * driver must restore device context.   If the number of context losses
++ * exceeds the maximum positive integer, the function will wrap to 0 and
++ * continue counting.  Returns the number of context losses for this device,
++ * or -EINVAL upon error.
++ */
++int omap_pm_get_dev_context_loss_count(struct device *dev);
++
++
++#endif
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/onenand.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/onenand.h	2010-08-08 12:57:12.000000000 +0200
+@@ -0,0 +1,43 @@
++/*
++ * arch/arm/plat-omap/include/mach/onenand.h
++ *
++ * Copyright (C) 2006 Nokia Corporation
++ * Author: Juha Yrjola
++ *
++ * 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/mtd/mtd.h>
++#include <linux/mtd/partitions.h>
++
++#define ONENAND_SYNC_READ	(1 << 0)
++#define ONENAND_SYNC_READWRITE	(1 << 1)
++
++struct omap_onenand_platform_data {
++	int			cs;
++	int			gpio_irq;
++	struct mtd_partition	*parts;
++	int			nr_parts;
++	int                     (*onenand_setup)(void __iomem *, int freq);
++	int			dma_channel;
++	u8			flags;
++};
++
++#define ONENAND_MAX_PARTITIONS 8
++
++#if defined(CONFIG_MTD_ONENAND_OMAP2) || \
++	defined(CONFIG_MTD_ONENAND_OMAP2_MODULE)
++
++extern void gpmc_onenand_init(struct omap_onenand_platform_data *d);
++
++#else
++
++#define board_onenand_data	NULL
++
++static inline void gpmc_onenand_init(struct omap_onenand_platform_data *d)
++{
++}
++
++#endif
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/param.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/param.h	2010-08-08 12:57:13.000000000 +0200
+@@ -0,0 +1,8 @@
++/*
++ *  arch/arm/plat-omap/include/mach/param.h
++ *
++ */
++
++#ifdef CONFIG_OMAP_32K_TIMER_HZ
++#define HZ	CONFIG_OMAP_32K_TIMER_HZ
++#endif
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/powerdomain.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/powerdomain.h	2010-08-08 12:57:13.000000000 +0200
+@@ -0,0 +1,187 @@
++/*
++ * OMAP2/3 powerdomain control
++ *
++ * Copyright (C) 2007-8 Texas Instruments, Inc.
++ * Copyright (C) 2007-8 Nokia Corporation
++ *
++ * Written by Paul Walmsley
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#ifndef ASM_ARM_ARCH_OMAP_POWERDOMAIN
++#define ASM_ARM_ARCH_OMAP_POWERDOMAIN
++
++#include <linux/types.h>
++#include <linux/list.h>
++
++#include <asm/atomic.h>
++
++#include <plat/cpu.h>
++
++
++/* Powerdomain basic power states */
++#define PWRDM_POWER_OFF		0x0
++#define PWRDM_POWER_RET		0x1
++#define PWRDM_POWER_INACTIVE	0x2
++#define PWRDM_POWER_ON		0x3
++
++#define PWRDM_MAX_PWRSTS	4
++
++/* Powerdomain allowable state bitfields */
++#define PWRSTS_OFF_ON		((1 << PWRDM_POWER_OFF) | \
++				 (1 << PWRDM_POWER_ON))
++
++#define PWRSTS_OFF_RET		((1 << PWRDM_POWER_OFF) | \
++				 (1 << PWRDM_POWER_RET))
++
++#define PWRSTS_OFF_RET_ON	(PWRSTS_OFF_RET | (1 << PWRDM_POWER_ON))
++
++
++/* Powerdomain flags */
++#define PWRDM_HAS_HDWR_SAR	(1 << 0) /* hardware save-and-restore support */
++#define PWRDM_HAS_MPU_QUIRK	(1 << 1) /* MPU pwr domain has MEM bank 0 bits
++					  * in MEM bank 1 position. This is
++					  * true for OMAP3430
++					  */
++
++/*
++ * Number of memory banks that are power-controllable.	On OMAP3430, the
++ * maximum is 4.
++ */
++#define PWRDM_MAX_MEM_BANKS	4
++
++/*
++ * Maximum number of clockdomains that can be associated with a powerdomain.
++ * CORE powerdomain on OMAP3 is the worst case
++ */
++#define PWRDM_MAX_CLKDMS	4
++
++/* XXX A completely arbitrary number. What is reasonable here? */
++#define PWRDM_TRANSITION_BAILOUT 100000
++
++struct clockdomain;
++struct powerdomain;
++
++/* Encodes dependencies between powerdomains - statically defined */
++struct pwrdm_dep {
++
++	/* Powerdomain name */
++	const char *pwrdm_name;
++
++	/* Powerdomain pointer - resolved by the powerdomain code */
++	struct powerdomain *pwrdm;
++
++	/* Flags to mark OMAP chip restrictions, etc. */
++	const struct omap_chip_id omap_chip;
++
++};
++
++struct powerdomain {
++
++	/* Powerdomain name */
++	const char *name;
++
++	/* the address offset from CM_BASE/PRM_BASE */
++	const s16 prcm_offs;
++
++	/* Used to represent the OMAP chip types containing this pwrdm */
++	const struct omap_chip_id omap_chip;
++
++	/* Powerdomains that can be told to wake this powerdomain up */
++	struct pwrdm_dep *wkdep_srcs;
++
++	/* Powerdomains that can be told to keep this pwrdm from inactivity */
++	struct pwrdm_dep *sleepdep_srcs;
++
++	/* Bit shift of this powerdomain's PM_WKDEP/CM_SLEEPDEP bit */
++	const u8 dep_bit;
++
++	/* Possible powerdomain power states */
++	const u8 pwrsts;
++
++	/* Possible logic power states when pwrdm in RETENTION */
++	const u8 pwrsts_logic_ret;
++
++	/* Powerdomain flags */
++	const u8 flags;
++
++	/* Number of software-controllable memory banks in this powerdomain */
++	const u8 banks;
++
++	/* Possible memory bank pwrstates when pwrdm in RETENTION */
++	const u8 pwrsts_mem_ret[PWRDM_MAX_MEM_BANKS];
++
++	/* Possible memory bank pwrstates when pwrdm is ON */
++	const u8 pwrsts_mem_on[PWRDM_MAX_MEM_BANKS];
++
++	/* Clockdomains in this powerdomain */
++	struct clockdomain *pwrdm_clkdms[PWRDM_MAX_CLKDMS];
++
++	struct list_head node;
++
++	int state;
++	unsigned state_counter[PWRDM_MAX_PWRSTS];
++
++#ifdef CONFIG_PM_DEBUG
++	s64 timer;
++	s64 state_timer[PWRDM_MAX_PWRSTS];
++#endif
++};
++
++
++void pwrdm_init(struct powerdomain **pwrdm_list);
++
++int pwrdm_register(struct powerdomain *pwrdm);
++int pwrdm_unregister(struct powerdomain *pwrdm);
++struct powerdomain *pwrdm_lookup(const char *name);
++
++int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm, void *user),
++			void *user);
++int pwrdm_for_each_nolock(int (*fn)(struct powerdomain *pwrdm, void *user),
++			void *user);
++
++int pwrdm_add_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm);
++int pwrdm_del_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm);
++int pwrdm_for_each_clkdm(struct powerdomain *pwrdm,
++			 int (*fn)(struct powerdomain *pwrdm,
++				   struct clockdomain *clkdm));
++
++int pwrdm_add_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2);
++int pwrdm_del_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2);
++int pwrdm_read_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2);
++int pwrdm_add_sleepdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2);
++int pwrdm_del_sleepdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2);
++int pwrdm_read_sleepdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2);
++
++int pwrdm_get_mem_bank_count(struct powerdomain *pwrdm);
++
++int pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst);
++int pwrdm_read_next_pwrst(struct powerdomain *pwrdm);
++int pwrdm_read_pwrst(struct powerdomain *pwrdm);
++int pwrdm_read_prev_pwrst(struct powerdomain *pwrdm);
++int pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm);
++
++int pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst);
++int pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, u8 pwrst);
++int pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, u8 pwrst);
++
++int pwrdm_read_logic_pwrst(struct powerdomain *pwrdm);
++int pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm);
++int pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank);
++int pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank);
++
++int pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm);
++int pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm);
++bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm);
++
++int pwrdm_wait_transition(struct powerdomain *pwrdm);
++
++int pwrdm_state_switch(struct powerdomain *pwrdm);
++int pwrdm_clkdm_state_switch(struct clockdomain *clkdm);
++int pwrdm_pre_transition(void);
++int pwrdm_post_transition(void);
++
++#endif
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/prcm.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/prcm.h	2010-08-08 12:57:14.000000000 +0200
+@@ -0,0 +1,39 @@
++/*
++ * arch/arm/plat-omap/include/mach/prcm.h
++ *
++ * Access definations for use in OMAP24XX clock and power management
++ *
++ * Copyright (C) 2005 Texas Instruments, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++
++#ifndef __ASM_ARM_ARCH_OMAP_PRCM_H
++#define __ASM_ARM_ARCH_OMAP_PRCM_H
++
++u32 omap_prcm_get_reset_sources(void);
++void omap_prcm_arch_reset(char mode);
++int omap2_cm_wait_idlest(void __iomem *reg, u32 mask, const char *name);
++
++#define START_PADCONF_SAVE 0x2
++#define PADCONF_SAVE_DONE  0x1
++
++void omap3_prcm_save_context(void);
++void omap3_prcm_restore_context(void);
++
++#endif
++
++
++
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/sdrc.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/sdrc.h	2010-08-08 12:57:15.000000000 +0200
+@@ -0,0 +1,158 @@
++#ifndef ____ASM_ARCH_SDRC_H
++#define ____ASM_ARCH_SDRC_H
++
++/*
++ * OMAP2/3 SDRC/SMS register definitions
++ *
++ * Copyright (C) 2007-2008 Texas Instruments, Inc.
++ * Copyright (C) 2007-2008 Nokia Corporation
++ *
++ * Tony Lindgren
++ * Paul Walmsley
++ * Richard Woodruff
++ *
++ * 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 <mach/io.h>
++
++/* SDRC register offsets - read/write with sdrc_{read,write}_reg() */
++
++#define SDRC_SYSCONFIG		0x010
++#define SDRC_CS_CFG		0x040
++#define SDRC_SHARING		0x044
++#define SDRC_ERR_TYPE		0x04C
++#define SDRC_DLLA_CTRL		0x060
++#define SDRC_DLLA_STATUS	0x064
++#define SDRC_DLLB_CTRL		0x068
++#define SDRC_DLLB_STATUS	0x06C
++#define SDRC_POWER		0x070
++#define SDRC_MCFG_0		0x080
++#define SDRC_MR_0		0x084
++#define SDRC_EMR2_0		0x08c
++#define SDRC_ACTIM_CTRL_A_0	0x09c
++#define SDRC_ACTIM_CTRL_B_0	0x0a0
++#define SDRC_RFR_CTRL_0		0x0a4
++#define SDRC_MANUAL_0		0x0a8
++#define SDRC_MCFG_1		0x0B0
++#define SDRC_MR_1		0x0B4
++#define SDRC_EMR2_1		0x0BC
++#define SDRC_ACTIM_CTRL_A_1	0x0C4
++#define SDRC_ACTIM_CTRL_B_1	0x0C8
++#define SDRC_RFR_CTRL_1		0x0D4
++#define SDRC_MANUAL_1		0x0D8
++
++#define SDRC_POWER_AUTOCOUNT_SHIFT	8
++#define SDRC_POWER_AUTOCOUNT_MASK	(0xffff << SDRC_POWER_AUTOCOUNT_SHIFT)
++#define SDRC_POWER_CLKCTRL_SHIFT	4
++#define SDRC_POWER_CLKCTRL_MASK		(0x3 << SDRC_POWER_CLKCTRL_SHIFT)
++#define SDRC_SELF_REFRESH_ON_AUTOCOUNT	(0x2 << SDRC_POWER_CLKCTRL_SHIFT)
++
++/*
++ * These values represent the number of memory clock cycles between
++ * autorefresh initiation.  They assume 1 refresh per 64 ms (JEDEC), 8192
++ * rows per device, and include a subtraction of a 50 cycle window in the
++ * event that the autorefresh command is delayed due to other SDRC activity.
++ * The '| 1' sets the ARE field to send one autorefresh when the autorefresh
++ * counter reaches 0.
++ *
++ * These represent optimal values for common parts, it won't work for all.
++ * As long as you scale down, most parameters are still work, they just
++ * become sub-optimal. The RFR value goes in the opposite direction. If you
++ * don't adjust it down as your clock period increases the refresh interval
++ * will not be met. Setting all parameters for complete worst case may work,
++ * but may cut memory performance by 2x. Due to errata the DLLs need to be
++ * unlocked and their value needs run time calibration.	A dynamic call is
++ * need for that as no single right value exists acorss production samples.
++ *
++ * Only the FULL speed values are given. Current code is such that rate
++ * changes must be made at DPLLoutx2. The actual value adjustment for low
++ * frequency operation will be handled by omap_set_performance()
++ *
++ * By having the boot loader boot up in the fastest L4 speed available likely
++ * will result in something which you can switch between.
++ */
++#define SDRC_RFR_CTRL_165MHz	(0x00044c00 | 1)
++#define SDRC_RFR_CTRL_133MHz	(0x0003de00 | 1)
++#define SDRC_RFR_CTRL_100MHz	(0x0002da01 | 1)
++#define SDRC_RFR_CTRL_110MHz	(0x0002da01 | 1) /* Need to calc */
++#define SDRC_RFR_CTRL_BYPASS	(0x00005000 | 1) /* Need to calc */
++
++
++/*
++ * SMS register access
++ */
++
++#define OMAP242X_SMS_REGADDR(reg)					\
++		(void __iomem *)OMAP2_L3_IO_ADDRESS(OMAP2420_SMS_BASE + reg)
++#define OMAP243X_SMS_REGADDR(reg)					\
++		(void __iomem *)OMAP2_L3_IO_ADDRESS(OMAP243X_SMS_BASE + reg)
++#define OMAP343X_SMS_REGADDR(reg)					\
++		(void __iomem *)OMAP2_L3_IO_ADDRESS(OMAP343X_SMS_BASE + reg)
++
++/* SMS register offsets - read/write with sms_{read,write}_reg() */
++
++#define SMS_SYSCONFIG			0x010
++#define SMS_ROT_CONTROL(context)	(0x180 + 0x10 * context)
++#define SMS_ROT_SIZE(context)		(0x184 + 0x10 * context)
++#define SMS_ROT_PHYSICAL_BA(context)	(0x188 + 0x10 * context)
++/* REVISIT: fill in other SMS registers here */
++
++
++#ifndef __ASSEMBLER__
++
++/**
++ * struct omap_sdrc_params - SDRC parameters for a given SDRC clock rate
++ * @rate: SDRC clock rate (in Hz)
++ * @actim_ctrla: Value to program to SDRC_ACTIM_CTRLA for this rate
++ * @actim_ctrlb: Value to program to SDRC_ACTIM_CTRLB for this rate
++ * @rfr_ctrl: Value to program to SDRC_RFR_CTRL for this rate
++ * @mr: Value to program to SDRC_MR for this rate
++ *
++ * This structure holds a pre-computed set of register values for the
++ * SDRC for a given SDRC clock rate and SDRAM chip.  These are
++ * intended to be pre-computed and specified in an array in the board-*.c
++ * files.  The structure is keyed off the 'rate' field.
++ */
++struct omap_sdrc_params {
++	unsigned long rate;
++	u32 actim_ctrla;
++	u32 actim_ctrlb;
++	u32 rfr_ctrl;
++	u32 mr;
++};
++
++void __init omap2_sdrc_init(struct omap_sdrc_params *sdrc_cs0,
++			    struct omap_sdrc_params *sdrc_cs1);
++int omap2_sdrc_get_params(unsigned long r,
++			  struct omap_sdrc_params **sdrc_cs0,
++			  struct omap_sdrc_params **sdrc_cs1);
++void omap2_sms_save_context(void);
++void omap2_sms_restore_context(void);
++
++void omap2_sms_write_rot_control(u32 val, unsigned ctx);
++void omap2_sms_write_rot_size(u32 val, unsigned ctx);
++void omap2_sms_write_rot_physical_ba(u32 val, unsigned ctx);
++
++#ifdef CONFIG_ARCH_OMAP2
++
++struct memory_timings {
++	u32 m_type;		/* ddr = 1, sdr = 0 */
++	u32 dll_mode;		/* use lock mode = 1, unlock mode = 0 */
++	u32 slow_dll_ctrl;	/* unlock mode, dll value for slow speed */
++	u32 fast_dll_ctrl;	/* unlock mode, dll value for fast speed */
++	u32 base_cs;		/* base chip select to use for calculations */
++};
++
++extern void omap2xxx_sdrc_init_params(u32 force_lock_to_unlock_mode);
++
++u32 omap2xxx_sdrc_dll_is_unlocked(void);
++u32 omap2xxx_sdrc_reprogram(u32 level, u32 force);
++
++#endif  /* CONFIG_ARCH_OMAP2 */
++
++#endif  /* __ASSEMBLER__ */
++
++#endif
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/serial.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/serial.h	2010-08-08 12:57:15.000000000 +0200
+@@ -0,0 +1,65 @@
++/*
++ * arch/arm/plat-omap/include/mach/serial.h
++ *
++ * Copyright (C) 2009 Texas Instruments
++ * Addded OMAP4 support- Santosh Shilimkar <[email protected]>
++ *
++ * 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.
++ */
++
++#ifndef __ASM_ARCH_SERIAL_H
++#define __ASM_ARCH_SERIAL_H
++
++#include <linux/init.h>
++
++#if defined(CONFIG_ARCH_OMAP1)
++/* OMAP1 serial ports */
++#define OMAP_UART1_BASE		0xfffb0000
++#define OMAP_UART2_BASE		0xfffb0800
++#define OMAP_UART3_BASE		0xfffb9800
++#elif defined(CONFIG_ARCH_OMAP2)
++/* OMAP2 serial ports */
++#define OMAP_UART1_BASE		0x4806a000
++#define OMAP_UART2_BASE		0x4806c000
++#define OMAP_UART3_BASE		0x4806e000
++#elif defined(CONFIG_ARCH_OMAP3)
++/* OMAP3 serial ports */
++#define OMAP_UART1_BASE		0x4806a000
++#define OMAP_UART2_BASE		0x4806c000
++#define OMAP_UART3_BASE		0x49020000
++#elif defined(CONFIG_ARCH_OMAP4)
++/* OMAP4 serial ports */
++#define OMAP_UART1_BASE		0x4806a000
++#define OMAP_UART2_BASE		0x4806c000
++#define OMAP_UART3_BASE		0x48020000
++#define OMAP_UART4_BASE		0x4806e000
++#endif
++
++#define OMAP1510_BASE_BAUD	(12000000/16)
++#define OMAP16XX_BASE_BAUD	(48000000/16)
++#define OMAP24XX_BASE_BAUD	(48000000/16)
++
++#define is_omap_port(pt)	({int __ret = 0;			\
++			if ((pt)->port.mapbase == OMAP_UART1_BASE ||	\
++			    (pt)->port.mapbase == OMAP_UART2_BASE ||	\
++			    (pt)->port.mapbase == OMAP_UART3_BASE)	\
++				__ret = 1;				\
++			__ret;						\
++			})
++
++#ifndef __ASSEMBLER__
++extern void __init omap_serial_early_init(void);
++extern void omap_serial_init(void);
++extern void omap_serial_init_port(int port);
++extern int omap_uart_can_sleep(void);
++extern void omap_uart_check_wakeup(void);
++extern void omap_uart_prepare_suspend(void);
++extern void omap_uart_prepare_idle(int num);
++extern void omap_uart_resume_idle(int num);
++extern void omap_uart_enable_irqs(int enable);
++#endif
++
++#endif
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/smp.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/smp.h	2010-08-08 12:57:16.000000000 +0200
+@@ -0,0 +1,53 @@
++/*
++ * OMAP4 machine specific smp.h
++ *
++ * Copyright (C) 2009 Texas Instruments, Inc.
++ *
++ * Author:
++ *	Santosh Shilimkar <[email protected]>
++ *
++ * Interface functions needed for the SMP. This file is based on arm
++ * realview smp platform.
++ * Copyright (c) 2003 ARM Limited.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++#ifndef OMAP_ARCH_SMP_H
++#define OMAP_ARCH_SMP_H
++
++#include <asm/hardware/gic.h>
++
++/*
++ * set_event() is used to wake up secondary core from wfe using sev. ROM
++ * code puts the second core into wfe(standby).
++ *
++ */
++#define set_event()	__asm__ __volatile__ ("sev" : : : "memory")
++
++/* Needed for secondary core boot */
++extern void omap_secondary_startup(void);
++extern u32 omap_modify_auxcoreboot0(u32 set_mask, u32 clear_mask);
++extern void omap_auxcoreboot_addr(u32 cpu_addr);
++
++/*
++ * We use Soft IRQ1 as the IPI
++ */
++static inline void smp_cross_call(const struct cpumask *mask)
++{
++	gic_raise_softirq(mask, 1);
++}
++
++/*
++ * Read MPIDR: Multiprocessor affinity register
++ */
++#define hard_smp_processor_id()			\
++	({						\
++		unsigned int cpunum;			\
++		__asm__("mrc p15, 0, %0, c0, c0, 5"	\
++			: "=r" (cpunum));		\
++		cpunum &= 0x0F;				\
++	})
++
++#endif
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/sram.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/sram.h	2010-08-08 12:57:16.000000000 +0200
+@@ -0,0 +1,78 @@
++/*
++ * arch/arm/plat-omap/include/mach/sram.h
++ *
++ * Interface for functions that need to be run in internal SRAM
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#ifndef __ARCH_ARM_OMAP_SRAM_H
++#define __ARCH_ARM_OMAP_SRAM_H
++
++extern int __init omap_sram_init(void);
++extern void * omap_sram_push(void * start, unsigned long size);
++extern void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl);
++
++extern void omap2_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl,
++				u32 base_cs, u32 force_unlock);
++extern void omap2_sram_reprogram_sdrc(u32 perf_level, u32 dll_val,
++				      u32 mem_type);
++extern u32 omap2_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass);
++
++extern u32 omap3_configure_core_dpll(
++			u32 m2, u32 unlock_dll, u32 f, u32 inc,
++			u32 sdrc_rfr_ctrl_0, u32 sdrc_actim_ctrl_a_0,
++			u32 sdrc_actim_ctrl_b_0, u32 sdrc_mr_0,
++			u32 sdrc_rfr_ctrl_1, u32 sdrc_actim_ctrl_a_1,
++			u32 sdrc_actim_ctrl_b_1, u32 sdrc_mr_1);
++extern void omap3_sram_restore_context(void);
++
++/* Do not use these */
++extern void omap1_sram_reprogram_clock(u32 ckctl, u32 dpllctl);
++extern unsigned long omap1_sram_reprogram_clock_sz;
++
++extern void omap24xx_sram_reprogram_clock(u32 ckctl, u32 dpllctl);
++extern unsigned long omap24xx_sram_reprogram_clock_sz;
++
++extern void omap242x_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl,
++						u32 base_cs, u32 force_unlock);
++extern unsigned long omap242x_sram_ddr_init_sz;
++
++extern u32 omap242x_sram_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val,
++						int bypass);
++extern unsigned long omap242x_sram_set_prcm_sz;
++
++extern void omap242x_sram_reprogram_sdrc(u32 perf_level, u32 dll_val,
++						u32 mem_type);
++extern unsigned long omap242x_sram_reprogram_sdrc_sz;
++
++
++extern void omap243x_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl,
++						u32 base_cs, u32 force_unlock);
++extern unsigned long omap243x_sram_ddr_init_sz;
++
++extern u32 omap243x_sram_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val,
++						int bypass);
++extern unsigned long omap243x_sram_set_prcm_sz;
++
++extern void omap243x_sram_reprogram_sdrc(u32 perf_level, u32 dll_val,
++						u32 mem_type);
++extern unsigned long omap243x_sram_reprogram_sdrc_sz;
++
++extern u32 omap3_sram_configure_core_dpll(
++			u32 m2, u32 unlock_dll, u32 f, u32 inc,
++			u32 sdrc_rfr_ctrl_0, u32 sdrc_actim_ctrl_a_0,
++			u32 sdrc_actim_ctrl_b_0, u32 sdrc_mr_0,
++			u32 sdrc_rfr_ctrl_1, u32 sdrc_actim_ctrl_a_1,
++			u32 sdrc_actim_ctrl_b_1, u32 sdrc_mr_1);
++extern unsigned long omap3_sram_configure_core_dpll_sz;
++
++#ifdef CONFIG_PM
++extern void omap_push_sram_idle(void);
++#else
++static inline void omap_push_sram_idle(void) {}
++#endif /* CONFIG_PM */
++
++#endif
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/system.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/system.h	2010-08-08 12:57:17.000000000 +0200
+@@ -0,0 +1,51 @@
++/*
++ * Copied from arch/arm/mach-sa1100/include/mach/system.h
++ * Copyright (c) 1999 Nicolas Pitre <[email protected]>
++ */
++#ifndef __ASM_ARCH_SYSTEM_H
++#define __ASM_ARCH_SYSTEM_H
++#include <linux/clk.h>
++
++#include <asm/mach-types.h>
++#include <mach/hardware.h>
++
++#include <plat/prcm.h>
++
++#ifndef CONFIG_MACH_VOICEBLUE
++#define voiceblue_reset()		do {} while (0)
++#else
++extern void voiceblue_reset(void);
++#endif
++
++static inline void arch_idle(void)
++{
++	cpu_do_idle();
++}
++
++static inline void omap1_arch_reset(char mode)
++{
++	/*
++	 * Workaround for 5912/1611b bug mentioned in sprz209d.pdf p. 28
++	 * "Global Software Reset Affects Traffic Controller Frequency".
++	 */
++	if (cpu_is_omap5912()) {
++		omap_writew(omap_readw(DPLL_CTL) & ~(1 << 4),
++				 DPLL_CTL);
++		omap_writew(0x8, ARM_RSTCT1);
++	}
++
++	if (machine_is_voiceblue())
++		voiceblue_reset();
++	else
++		omap_writew(1, ARM_RSTCT1);
++}
++
++static inline void arch_reset(char mode, const char *cmd)
++{
++	if (!cpu_class_is_omap2())
++		omap1_arch_reset(mode);
++	else
++		omap_prcm_arch_reset(mode);
++}
++
++#endif
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/tc.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/tc.h	2010-08-08 12:57:18.000000000 +0200
+@@ -0,0 +1,106 @@
++/*
++ * arch/arm/plat-omap/include/mach/tc.h
++ *
++ * OMAP Traffic Controller
++ *
++ * Copyright (C) 2004 Nokia Corporation
++ * Author: Imre Deak <[email protected]>
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License along
++ * with this program; if not, write to the Free Software Foundation, Inc.,
++ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
++ */
++
++#ifndef __ASM_ARCH_TC_H
++#define __ASM_ARCH_TC_H
++
++#define TCMIF_BASE		0xfffecc00
++#define OMAP_TC_OCPT1_PRIOR	(TCMIF_BASE + 0x00)
++#define OMAP_TC_EMIFS_PRIOR	(TCMIF_BASE + 0x04)
++#define OMAP_TC_EMIFF_PRIOR	(TCMIF_BASE + 0x08)
++#define EMIFS_CONFIG		(TCMIF_BASE + 0x0c)
++#define EMIFS_CS0_CONFIG	(TCMIF_BASE + 0x10)
++#define EMIFS_CS1_CONFIG	(TCMIF_BASE + 0x14)
++#define EMIFS_CS2_CONFIG	(TCMIF_BASE + 0x18)
++#define EMIFS_CS3_CONFIG	(TCMIF_BASE + 0x1c)
++#define EMIFF_SDRAM_CONFIG	(TCMIF_BASE + 0x20)
++#define EMIFF_MRS		(TCMIF_BASE + 0x24)
++#define TC_TIMEOUT1		(TCMIF_BASE + 0x28)
++#define TC_TIMEOUT2		(TCMIF_BASE + 0x2c)
++#define TC_TIMEOUT3		(TCMIF_BASE + 0x30)
++#define TC_ENDIANISM		(TCMIF_BASE + 0x34)
++#define EMIFF_SDRAM_CONFIG_2	(TCMIF_BASE + 0x3c)
++#define EMIF_CFG_DYNAMIC_WS	(TCMIF_BASE + 0x40)
++#define EMIFS_ACS0		(TCMIF_BASE + 0x50)
++#define EMIFS_ACS1		(TCMIF_BASE + 0x54)
++#define EMIFS_ACS2		(TCMIF_BASE + 0x58)
++#define EMIFS_ACS3		(TCMIF_BASE + 0x5c)
++#define OMAP_TC_OCPT2_PRIOR	(TCMIF_BASE + 0xd0)
++
++/* external EMIFS chipselect regions */
++#define	OMAP_CS0_PHYS		0x00000000
++#define	OMAP_CS0_SIZE		SZ_64M
++
++#define	OMAP_CS1_PHYS		0x04000000
++#define	OMAP_CS1_SIZE		SZ_64M
++
++#define	OMAP_CS1A_PHYS		OMAP_CS1_PHYS
++#define	OMAP_CS1A_SIZE		SZ_32M
++
++#define	OMAP_CS1B_PHYS		(OMAP_CS1A_PHYS + OMAP_CS1A_SIZE)
++#define	OMAP_CS1B_SIZE		SZ_32M
++
++#define	OMAP_CS2_PHYS		0x08000000
++#define	OMAP_CS2_SIZE		SZ_64M
++
++#define	OMAP_CS2A_PHYS		OMAP_CS2_PHYS
++#define	OMAP_CS2A_SIZE		SZ_32M
++
++#define	OMAP_CS2B_PHYS		(OMAP_CS2A_PHYS + OMAP_CS2A_SIZE)
++#define	OMAP_CS2B_SIZE		SZ_32M
++
++#define	OMAP_CS3_PHYS		0x0c000000
++#define	OMAP_CS3_SIZE		SZ_64M
++
++#ifndef	__ASSEMBLER__
++
++/* EMIF Slow Interface Configuration Register */
++#define OMAP_EMIFS_CONFIG_FR		(1 << 4)
++#define OMAP_EMIFS_CONFIG_PDE		(1 << 3)
++#define OMAP_EMIFS_CONFIG_PWD_EN	(1 << 2)
++#define OMAP_EMIFS_CONFIG_BM		(1 << 1)
++#define OMAP_EMIFS_CONFIG_WP		(1 << 0)
++
++#define EMIFS_CCS(n)		(EMIFS_CS0_CONFIG + (4 * (n)))
++#define EMIFS_ACS(n)		(EMIFS_ACS0 + (4 * (n)))
++
++/* Almost all documentation for chip and board memory maps assumes
++ * BM is clear.  Most devel boards have a switch to control booting
++ * from NOR flash (using external chipselect 3) rather than mask ROM,
++ * which uses BM to interchange the physical CS0 and CS3 addresses.
++ */
++static inline u32 omap_cs0_phys(void)
++{
++	return (omap_readl(EMIFS_CONFIG) & OMAP_EMIFS_CONFIG_BM)
++			?  OMAP_CS3_PHYS : 0;
++}
++
++static inline u32 omap_cs3_phys(void)
++{
++	return (omap_readl(EMIFS_CONFIG) & OMAP_EMIFS_CONFIG_BM)
++			? 0 : OMAP_CS3_PHYS;
++}
++
++#endif	/* __ASSEMBLER__ */
++
++#endif	/* __ASM_ARCH_TC_H */
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/timer-gp.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/timer-gp.h	2010-08-08 12:57:18.000000000 +0200
+@@ -0,0 +1,17 @@
++/*
++ * OMAP2/3 GPTIMER support.headers
++ *
++ * Copyright (C) 2009 Nokia Corporation
++ *
++ * This file is subject to the terms and conditions of the GNU General Public
++ * License. See the file "COPYING" in the main directory of this archive
++ * for more details.
++ */
++
++#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_TIMER_GP_H
++#define __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_TIMER_GP_H
++
++int __init omap2_gp_clockevent_set_gptimer(u8 id);
++
++#endif
++
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/timex.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/timex.h	2010-08-08 12:57:19.000000000 +0200
+@@ -0,0 +1,41 @@
++/*
++ * arch/arm/plat-omap/include/mach/timex.h
++ *
++ * Copyright (C) 2000 RidgeRun, Inc.
++ * Author:  Greg Lonnon <[email protected]>
++ *
++ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ *
++ * 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.,
++ * 675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++
++#if !defined(__ASM_ARCH_OMAP_TIMEX_H)
++#define __ASM_ARCH_OMAP_TIMEX_H
++
++/*
++ * OMAP 32KHz timer updates time one jiffie at a time from a secondary timer,
++ * and that's why the CLOCK_TICK_RATE is not 32768.
++ */
++#ifdef CONFIG_OMAP_32K_TIMER
++#define CLOCK_TICK_RATE		(CONFIG_OMAP_32K_TIMER_HZ)
++#else
++#define CLOCK_TICK_RATE		(HZ * 100000UL)
++#endif
++
++#endif /* __ASM_ARCH_OMAP_TIMEX_H */
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/uncompress.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/uncompress.h	2010-08-08 12:57:19.000000000 +0200
+@@ -0,0 +1,88 @@
++/*
++ * arch/arm/plat-omap/include/mach/uncompress.h
++ *
++ * Serial port stubs for kernel decompress status messages
++ *
++ * Initially based on:
++ * linux-2.4.15-rmk1-dsplinux1.6/arch/arm/plat-omap/include/mach1510/uncompress.h
++ * Copyright (C) 2000 RidgeRun, Inc.
++ * Author: Greg Lonnon <[email protected]>
++ *
++ * Rewritten by:
++ * Author: <[email protected]>
++ * 2004 (c) MontaVista Software, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include <linux/types.h>
++#include <linux/serial_reg.h>
++#include <plat/serial.h>
++
++unsigned int system_rev;
++
++#define UART_OMAP_MDR1		0x08	/* mode definition register */
++#define OMAP_ID_730		0x355F
++#define OMAP_ID_850		0x362C
++#define ID_MASK			0x7fff
++#define check_port(base, shift) ((base[UART_OMAP_MDR1 << shift] & 7) == 0)
++#define omap_get_id() ((*(volatile unsigned int *)(0xfffed404)) >> 12) & ID_MASK
++
++static void putc(int c)
++{
++	volatile u8 * uart = 0;
++	int shift = 2;
++
++#ifdef CONFIG_MACH_OMAP_PALMTE
++	return;
++#endif
++
++#ifdef CONFIG_ARCH_OMAP
++#ifdef	CONFIG_OMAP_LL_DEBUG_UART3
++	uart = (volatile u8 *)(OMAP_UART3_BASE);
++#elif defined(CONFIG_OMAP_LL_DEBUG_UART2)
++	uart = (volatile u8 *)(OMAP_UART2_BASE);
++#elif defined(CONFIG_OMAP_LL_DEBUG_UART1)
++	uart = (volatile u8 *)(OMAP_UART1_BASE);
++#elif defined(CONFIG_OMAP_LL_DEBUG_NONE)
++	return;
++#else
++	return;
++#endif
++
++#ifdef CONFIG_ARCH_OMAP1
++	/* Determine which serial port to use */
++	do {
++		/* MMU is not on, so cpu_is_omapXXXX() won't work here */
++		unsigned int omap_id = omap_get_id();
++
++		if (omap_id == OMAP_ID_730 || omap_id == OMAP_ID_850)
++			shift = 0;
++
++		if (check_port(uart, shift))
++			break;
++		/* Silent boot if no serial ports are enabled. */
++		return;
++	} while (0);
++#endif /* CONFIG_ARCH_OMAP1 */
++#endif
++
++	/*
++	 * Now, xmit each character
++	 */
++	while (!(uart[UART_LSR << shift] & UART_LSR_THRE))
++		barrier();
++	uart[UART_TX << shift] = c;
++}
++
++static inline void flush(void)
++{
++}
++
++/*
++ * nothing to do
++ */
++#define arch_decomp_setup()
++#define arch_decomp_wdog()
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/usb.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/usb.h	2010-08-08 12:57:20.000000000 +0200
+@@ -0,0 +1,162 @@
++// include/asm-arm/mach-omap/usb.h
++
++#ifndef	__ASM_ARCH_OMAP_USB_H
++#define	__ASM_ARCH_OMAP_USB_H
++
++#include <plat/board.h>
++
++#define OMAP3_HS_USB_PORTS	3
++enum ehci_hcd_omap_mode {
++	EHCI_HCD_OMAP_MODE_UNKNOWN,
++	EHCI_HCD_OMAP_MODE_PHY,
++	EHCI_HCD_OMAP_MODE_TLL,
++};
++
++struct ehci_hcd_omap_platform_data {
++	enum ehci_hcd_omap_mode		port_mode[OMAP3_HS_USB_PORTS];
++	unsigned			phy_reset:1;
++
++	/* have to be valid if phy_reset is true and portx is in phy mode */
++	int	reset_gpio_port[OMAP3_HS_USB_PORTS];
++};
++
++/*-------------------------------------------------------------------------*/
++
++#define OMAP1_OTG_BASE			0xfffb0400
++#define OMAP1_UDC_BASE			0xfffb4000
++#define OMAP1_OHCI_BASE			0xfffba000
++
++#define OMAP2_OHCI_BASE			0x4805e000
++#define OMAP2_UDC_BASE			0x4805e200
++#define OMAP2_OTG_BASE			0x4805e300
++
++#ifdef CONFIG_ARCH_OMAP1
++
++#define OTG_BASE			OMAP1_OTG_BASE
++#define UDC_BASE			OMAP1_UDC_BASE
++#define OMAP_OHCI_BASE			OMAP1_OHCI_BASE
++
++#else
++
++#define OTG_BASE			OMAP2_OTG_BASE
++#define UDC_BASE			OMAP2_UDC_BASE
++#define OMAP_OHCI_BASE			OMAP2_OHCI_BASE
++
++extern void usb_musb_init(void);
++
++extern void usb_ehci_init(struct ehci_hcd_omap_platform_data *pdata);
++
++#endif
++
++void omap_usb_init(struct omap_usb_config *pdata);
++
++/*-------------------------------------------------------------------------*/
++
++/*
++ * OTG and transceiver registers, for OMAPs starting with ARM926
++ */
++#define OTG_REV				(OTG_BASE + 0x00)
++#define OTG_SYSCON_1			(OTG_BASE + 0x04)
++#	define	 USB2_TRX_MODE(w)	(((w)>>24)&0x07)
++#	define	 USB1_TRX_MODE(w)	(((w)>>20)&0x07)
++#	define	 USB0_TRX_MODE(w)	(((w)>>16)&0x07)
++#	define	 OTG_IDLE_EN		(1 << 15)
++#	define	 HST_IDLE_EN		(1 << 14)
++#	define	 DEV_IDLE_EN		(1 << 13)
++#	define	 OTG_RESET_DONE		(1 << 2)
++#	define	 OTG_SOFT_RESET		(1 << 1)
++#define OTG_SYSCON_2			(OTG_BASE + 0x08)
++#	define	 OTG_EN			(1 << 31)
++#	define	 USBX_SYNCHRO		(1 << 30)
++#	define	 OTG_MST16		(1 << 29)
++#	define	 SRP_GPDATA		(1 << 28)
++#	define	 SRP_GPDVBUS		(1 << 27)
++#	define	 SRP_GPUVBUS(w)		(((w)>>24)&0x07)
++#	define	 A_WAIT_VRISE(w)	(((w)>>20)&0x07)
++#	define	 B_ASE_BRST(w)		(((w)>>16)&0x07)
++#	define	 SRP_DPW		(1 << 14)
++#	define	 SRP_DATA		(1 << 13)
++#	define	 SRP_VBUS		(1 << 12)
++#	define	 OTG_PADEN		(1 << 10)
++#	define	 HMC_PADEN		(1 << 9)
++#	define	 UHOST_EN		(1 << 8)
++#	define	 HMC_TLLSPEED		(1 << 7)
++#	define	 HMC_TLLATTACH		(1 << 6)
++#	define	 OTG_HMC(w)		(((w)>>0)&0x3f)
++#define OTG_CTRL			(OTG_BASE + 0x0c)
++#	define	 OTG_USB2_EN		(1 << 29)
++#	define	 OTG_USB2_DP		(1 << 28)
++#	define	 OTG_USB2_DM		(1 << 27)
++#	define	 OTG_USB1_EN		(1 << 26)
++#	define	 OTG_USB1_DP		(1 << 25)
++#	define	 OTG_USB1_DM		(1 << 24)
++#	define	 OTG_USB0_EN		(1 << 23)
++#	define	 OTG_USB0_DP		(1 << 22)
++#	define	 OTG_USB0_DM		(1 << 21)
++#	define	 OTG_ASESSVLD		(1 << 20)
++#	define	 OTG_BSESSEND		(1 << 19)
++#	define	 OTG_BSESSVLD		(1 << 18)
++#	define	 OTG_VBUSVLD		(1 << 17)
++#	define	 OTG_ID			(1 << 16)
++#	define	 OTG_DRIVER_SEL		(1 << 15)
++#	define	 OTG_A_SETB_HNPEN	(1 << 12)
++#	define	 OTG_A_BUSREQ		(1 << 11)
++#	define	 OTG_B_HNPEN		(1 << 9)
++#	define	 OTG_B_BUSREQ		(1 << 8)
++#	define	 OTG_BUSDROP		(1 << 7)
++#	define	 OTG_PULLDOWN		(1 << 5)
++#	define	 OTG_PULLUP		(1 << 4)
++#	define	 OTG_DRV_VBUS		(1 << 3)
++#	define	 OTG_PD_VBUS		(1 << 2)
++#	define	 OTG_PU_VBUS		(1 << 1)
++#	define	 OTG_PU_ID		(1 << 0)
++#define OTG_IRQ_EN			(OTG_BASE + 0x10)	/* 16-bit */
++#	define	 DRIVER_SWITCH		(1 << 15)
++#	define	 A_VBUS_ERR		(1 << 13)
++#	define	 A_REQ_TMROUT		(1 << 12)
++#	define	 A_SRP_DETECT		(1 << 11)
++#	define	 B_HNP_FAIL		(1 << 10)
++#	define	 B_SRP_TMROUT		(1 << 9)
++#	define	 B_SRP_DONE		(1 << 8)
++#	define	 B_SRP_STARTED		(1 << 7)
++#	define	 OPRT_CHG		(1 << 0)
++#define OTG_IRQ_SRC			(OTG_BASE + 0x14)	/* 16-bit */
++	// same bits as in IRQ_EN
++#define OTG_OUTCTRL			(OTG_BASE + 0x18)	/* 16-bit */
++#	define	 OTGVPD			(1 << 14)
++#	define	 OTGVPU			(1 << 13)
++#	define	 OTGPUID		(1 << 12)
++#	define	 USB2VDR		(1 << 10)
++#	define	 USB2PDEN		(1 << 9)
++#	define	 USB2PUEN		(1 << 8)
++#	define	 USB1VDR		(1 << 6)
++#	define	 USB1PDEN		(1 << 5)
++#	define	 USB1PUEN		(1 << 4)
++#	define	 USB0VDR		(1 << 2)
++#	define	 USB0PDEN		(1 << 1)
++#	define	 USB0PUEN		(1 << 0)
++#define OTG_TEST			(OTG_BASE + 0x20)	/* 16-bit */
++#define OTG_VENDOR_CODE			(OTG_BASE + 0xfc)	/* 16-bit */
++
++/*-------------------------------------------------------------------------*/
++
++/* OMAP1 */
++#define	USB_TRANSCEIVER_CTRL		(0xfffe1000 + 0x0064)
++#	define	CONF_USB2_UNI_R		(1 << 8)
++#	define	CONF_USB1_UNI_R		(1 << 7)
++#	define	CONF_USB_PORT0_R(x)	(((x)>>4)&0x7)
++#	define	CONF_USB0_ISOLATE_R	(1 << 3)
++#	define	CONF_USB_PWRDN_DM_R	(1 << 2)
++#	define	CONF_USB_PWRDN_DP_R	(1 << 1)
++
++/* OMAP2 */
++#	define	USB_UNIDIR			0x0
++#	define	USB_UNIDIR_TLL			0x1
++#	define	USB_BIDIR			0x2
++#	define	USB_BIDIR_TLL			0x3
++#	define	USBTXWRMODEI(port, x)	((x) << (22 - (port * 2)))
++#	define	USBT2TLL5PI		(1 << 17)
++#	define	USB0PUENACTLOI		(1 << 16)
++#	define	USBSTANDBYCTRL		(1 << 15)
++
++#endif	/* __ASM_ARCH_OMAP_USB_H */
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/vram.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/vram.h	2010-08-08 12:57:21.000000000 +0200
+@@ -0,0 +1,62 @@
++/*
++ * VRAM manager for OMAP
++ *
++ * Copyright (C) 2009 Nokia Corporation
++ * Author: Tomi Valkeinen <[email protected]>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License along
++ * with this program; if not, write to the Free Software Foundation, Inc.,
++ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
++ */
++
++#ifndef __OMAP_VRAM_H__
++#define __OMAP_VRAM_H__
++
++#include <linux/types.h>
++
++#define OMAP_VRAM_MEMTYPE_SDRAM		0
++#define OMAP_VRAM_MEMTYPE_SRAM		1
++#define OMAP_VRAM_MEMTYPE_MAX		1
++
++extern int omap_vram_add_region(unsigned long paddr, size_t size);
++extern int omap_vram_free(unsigned long paddr, size_t size);
++extern int omap_vram_alloc(int mtype, size_t size, unsigned long *paddr);
++extern int omap_vram_reserve(unsigned long paddr, size_t size);
++extern void omap_vram_get_info(unsigned long *vram, unsigned long *free_vram,
++		unsigned long *largest_free_block);
++
++#ifdef CONFIG_OMAP2_VRAM
++extern void omap_vram_set_sdram_vram(u32 size, u32 start);
++extern void omap_vram_set_sram_vram(u32 size, u32 start);
++
++extern void omap_vram_reserve_sdram(void);
++extern unsigned long omap_vram_reserve_sram(unsigned long sram_pstart,
++					    unsigned long sram_vstart,
++					    unsigned long sram_size,
++					    unsigned long pstart_avail,
++					    unsigned long size_avail);
++#else
++static inline void omap_vram_set_sdram_vram(u32 size, u32 start) { }
++static inline void omap_vram_set_sram_vram(u32 size, u32 start) { }
++
++static inline void omap_vram_reserve_sdram(void) { }
++static inline unsigned long omap_vram_reserve_sram(unsigned long sram_pstart,
++					    unsigned long sram_vstart,
++					    unsigned long sram_size,
++					    unsigned long pstart_avail,
++					    unsigned long size_avail)
++{
++	return 0;
++}
++#endif
++
++#endif
+Index: linux-2.6.35/arch/arm/plat-omap/include/mach/vrfb.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/mach/vrfb.h	2010-08-08 12:57:21.000000000 +0200
+@@ -0,0 +1,50 @@
++/*
++ * VRFB Rotation Engine
++ *
++ * Copyright (C) 2009 Nokia Corporation
++ * Author: Tomi Valkeinen <[email protected]>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License along
++ * with this program; if not, write to the Free Software Foundation, Inc.,
++ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
++ */
++
++#ifndef __OMAP_VRFB_H__
++#define __OMAP_VRFB_H__
++
++#define OMAP_VRFB_LINE_LEN 2048
++
++struct vrfb {
++	u8 context;
++	void __iomem *vaddr[4];
++	unsigned long paddr[4];
++	u16 xres;
++	u16 yres;
++	u16 xoffset;
++	u16 yoffset;
++	u8 bytespp;
++	bool yuv_mode;
++};
++
++extern int omap_vrfb_request_ctx(struct vrfb *vrfb);
++extern void omap_vrfb_release_ctx(struct vrfb *vrfb);
++extern void omap_vrfb_adjust_size(u16 *width, u16 *height,
++		u8 bytespp);
++extern u32 omap_vrfb_min_phys_size(u16 width, u16 height, u8 bytespp);
++extern u16 omap_vrfb_max_height(u32 phys_size, u16 width, u8 bytespp);
++extern void omap_vrfb_setup(struct vrfb *vrfb, unsigned long paddr,
++		u16 width, u16 height,
++		unsigned bytespp, bool yuv_mode);
++extern int omap_vrfb_map_angle(struct vrfb *vrfb, u16 height, u8 rot);
++extern void omap_vrfb_restore_context(void);
++
++#endif /* __VRFB_H */
+Index: linux-2.6.35/arch/arm/plat-omap/include/plat/cbus.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/plat-omap/include/plat/cbus.h	2010-08-08 12:57:22.000000000 +0200
+@@ -0,0 +1,31 @@
++/*
++ * cbus.h - CBUS platform_data definition
++ *
++ * Copyright (C) 2004 - 2009 Nokia Corporation
++ *
++ * Written by Felipe Balbi <[email protected]>
++ *
++ * 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.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ */
++
++#ifndef __PLAT_CBUS_H
++#define __PLAT_CBUS_H
++
++struct cbus_host_platform_data {
++	int	dat_gpio;
++	int	clk_gpio;
++	int	sel_gpio;
++};
++
++#endif /* __PLAT_CBUS_H */
+Index: linux-2.6.35/arch/arm/plat-omap/Kconfig
+===================================================================
+--- linux-2.6.35.orig/arch/arm/plat-omap/Kconfig	2010-08-08 12:56:11.000000000 +0200
++++ linux-2.6.35/arch/arm/plat-omap/Kconfig	2010-08-08 12:57:22.000000000 +0200
+@@ -65,6 +65,30 @@ config OMAP_RESET_CLOCKS
+ 	  probably do not want this option enabled until your
+ 	  device drivers work properly.
+ 
++config OMAP_BOOT_TAG
++	bool "OMAP bootloader information passing"
++        depends on ARCH_OMAP
++        default n
++        help
++          Say Y, if you have a bootloader which passes information
++          about your board and its peripheral configuration.
++
++config OMAP_BOOT_REASON
++	bool "Support for boot reason"
++        depends on OMAP_BOOT_TAG
++        default n
++        help
++          Say Y, if you want to have a procfs entry for reading the boot
++          reason in user-space.
++
++config OMAP_COMPONENT_VERSION
++	bool "Support for component version display"
++	depends on OMAP_BOOT_TAG && PROC_FS
++	default n
++	help
++	  Say Y, if you want to have a procfs entry for reading component
++	  versions (supplied by the bootloader) in user-space.
++
+ config OMAP_MUX
+ 	bool "OMAP multiplexing support"
+ 	depends on ARCH_OMAP
+Index: linux-2.6.35/arch/arm/plat-omap/Makefile
+===================================================================
+--- linux-2.6.35.orig/arch/arm/plat-omap/Makefile	2010-08-08 12:56:11.000000000 +0200
++++ linux-2.6.35/arch/arm/plat-omap/Makefile	2010-08-08 12:57:23.000000000 +0200
+@@ -22,6 +22,8 @@ obj-$(CONFIG_OMAP_IOMMU_DEBUG) += iommu-
+ 
+ obj-$(CONFIG_CPU_FREQ) += cpu-omap.o
+ obj-$(CONFIG_OMAP_DM_TIMER) += dmtimer.o
++obj-$(CONFIG_OMAP_BOOT_REASON) += bootreason.o
++obj-$(CONFIG_OMAP_COMPONENT_VERSION) += component-version.o
+ obj-$(CONFIG_OMAP_DEBUG_DEVICES) += debug-devices.o
+ obj-$(CONFIG_OMAP_DEBUG_LEDS) += debug-leds.o
+ i2c-omap-$(CONFIG_I2C_OMAP) := i2c.o
+Index: linux-2.6.35/arch/arm/include/asm/setup.h
+===================================================================
+--- linux-2.6.35.orig/arch/arm/include/asm/setup.h	2010-08-08 12:56:16.000000000 +0200
++++ linux-2.6.35/arch/arm/include/asm/setup.h	2010-08-08 12:56:28.000000000 +0200
+@@ -136,6 +136,13 @@ struct tag_acorn {
+ 	__u8 adfsdrives;
+ };
+ 
++/* TI OMAP specific information */
++#define ATAG_BOARD       0x414f4d50
++
++struct tag_omap {
++	u8 data[0];
++};
++
+ /* footbridge memory clock, see arch/arm/mach-footbridge/arch.c */
+ #define ATAG_MEMCLK	0x41000402
+ 
+@@ -162,6 +169,11 @@ struct tag {
+ 		struct tag_acorn	acorn;
+ 
+ 		/*
++		 * OMAP specific
++                 */
++                struct tag_omap         omap;
++
++		/*
+ 		 * DC21285 specific
+ 		 */
+ 		struct tag_memclk	memclk;

+ 733 - 0
target/linux/omap24xx/patches-2.6.35/300-nokia-board.patch

@@ -0,0 +1,733 @@
+Index: linux-2.6.35/arch/arm/mach-omap1/board-nokia770.c
+===================================================================
+--- linux-2.6.35.orig/arch/arm/mach-omap1/board-nokia770.c	2010-08-08 12:56:15.000000000 +0200
++++ linux-2.6.35/arch/arm/mach-omap1/board-nokia770.c	2010-08-08 12:56:30.000000000 +0200
+@@ -37,6 +37,7 @@
+ #include <plat/lcd_mipid.h>
+ #include <plat/mmc.h>
+ #include <plat/clock.h>
++#include <plat/cbus.h>
+ 
+ #define ADS7846_PENDOWN_GPIO	15
+ 
+@@ -96,8 +97,23 @@ static struct platform_device nokia770_k
+ 	.resource	= nokia770_kp_resources,
+ };
+ 
++static struct cbus_host_platform_data nokia770_cbus_data = {
++	.clk_gpio	= OMAP_MPUIO(11),
++	.dat_gpio	= OMAP_MPUIO(10),
++	.sel_gpio	= OMAP_MPUIO(9),
++};
++
++static struct platform_device nokia770_cbus_device = {
++	.name		= "cbus",
++	.id		= -1,
++	.dev		= {
++		.platform_data = &nokia770_cbus_data,
++	},
++};
++
+ static struct platform_device *nokia770_devices[] __initdata = {
+ 	&nokia770_kp_device,
++	&nokia770_cbus_device,
+ };
+ 
+ static void mipid_shutdown(struct mipid_platform_data *pdata)
+Index: linux-2.6.35/arch/arm/mach-omap2/board-n8x0.c
+===================================================================
+--- linux-2.6.35.orig/arch/arm/mach-omap2/board-n8x0.c	2010-08-08 12:56:15.000000000 +0200
++++ linux-2.6.35/arch/arm/mach-omap2/board-n8x0.c	2010-08-08 12:56:30.000000000 +0200
+@@ -18,8 +18,12 @@
+ #include <linux/io.h>
+ #include <linux/stddef.h>
+ #include <linux/i2c.h>
++#include <linux/platform_device.h>
+ #include <linux/spi/spi.h>
++#include <linux/spi/tsc2005.h>
++#include <linux/input.h>
+ #include <linux/usb/musb.h>
++#include <linux/i2c/lm8323.h>
+ 
+ #include <asm/mach/arch.h>
+ #include <asm/mach-types.h>
+@@ -32,6 +36,117 @@
+ #include <plat/onenand.h>
+ #include <plat/mmc.h>
+ #include <plat/serial.h>
++#include <plat/cbus.h>
++
++#define	RX51_TSC2005_RESET_GPIO	94
++#define	RX51_TSC2005_IRQ_GPIO	106
++#define OMAP_TAG_NOKIA_BT	0x4e01
++
++static s16 rx44_keymap[LM8323_KEYMAP_SIZE] = {
++	[0x01] = KEY_Q,
++	[0x02] = KEY_K,
++	[0x03] = KEY_O,
++	[0x04] = KEY_P,
++	[0x05] = KEY_BACKSPACE,
++	[0x06] = KEY_A,
++	[0x07] = KEY_S,
++	[0x08] = KEY_D,
++	[0x09] = KEY_F,
++	[0x0a] = KEY_G,
++	[0x0b] = KEY_H,
++	[0x0c] = KEY_J,
++
++	[0x11] = KEY_W,
++	[0x12] = KEY_F4,
++	[0x13] = KEY_L,
++	[0x14] = KEY_APOSTROPHE,
++	[0x16] = KEY_Z,
++	[0x17] = KEY_X,
++	[0x18] = KEY_C,
++	[0x19] = KEY_V,
++	[0x1a] = KEY_B,
++	[0x1b] = KEY_N,
++	[0x1c] = KEY_LEFTSHIFT, /* Actually, this is both shift keys */
++	[0x1f] = KEY_F7,
++
++	[0x21] = KEY_E,
++	[0x22] = KEY_SEMICOLON,
++	[0x23] = KEY_MINUS,
++	[0x24] = KEY_EQUAL,
++	[0x2b] = KEY_FN,
++	[0x2c] = KEY_M,
++	[0x2f] = KEY_F8,
++
++	[0x31] = KEY_R,
++	[0x32] = KEY_RIGHTCTRL,
++	[0x34] = KEY_SPACE,
++	[0x35] = KEY_COMMA,
++	[0x37] = KEY_UP,
++	[0x3c] = KEY_COMPOSE,
++	[0x3f] = KEY_F6,
++
++	[0x41] = KEY_T,
++	[0x44] = KEY_DOT,
++	[0x46] = KEY_RIGHT,
++	[0x4f] = KEY_F5,
++	[0x51] = KEY_Y,
++	[0x53] = KEY_DOWN,
++	[0x55] = KEY_ENTER,
++	[0x5f] = KEY_ESC,
++
++	[0x61] = KEY_U,
++	[0x64] = KEY_LEFT,
++
++	[0x71] = KEY_I,
++	[0x75] = KEY_KPENTER,
++};
++
++static struct lm8323_platform_data lm8323_pdata = {
++	.repeat		= 0, /* Repeat is handled in userspace for now. */
++	.keymap		= rx44_keymap,
++	.size_x		= 8,
++	.size_y		= 12,
++	.debounce_time	= 12,
++	.active_time	= 500,
++
++	.name		= "Internal keyboard",
++	.pwm_names[0] 	= "n810::keyboard",
++	.pwm_names[1] 	= "n810::cover",
++	//.pwm1_name	= "n810::keyboard",
++	//.pwm2_name	= "n810::cover",
++};
++
++struct omap_bluetooth_config {
++	u8    chip_type;
++	u8    bt_wakeup_gpio;
++	u8    host_wakeup_gpio;
++	u8    reset_gpio;
++	u8    bt_uart;
++	u8    bd_addr[6];
++	u8    bt_sysclk;
++};
++
++static struct platform_device n8x0_bt_device = {
++	.name           = "hci_h4p",
++	.id             = -1,
++	.num_resources  = 0,
++};
++
++void __init n8x0_bt_init(void)
++{
++	const struct omap_bluetooth_config *bt_config;
++
++	bt_config = (void *) omap_get_config(OMAP_TAG_NOKIA_BT,
++					     struct omap_bluetooth_config);
++	n8x0_bt_device.dev.platform_data = (void *) bt_config;
++	if (platform_device_register(&n8x0_bt_device) < 0)
++		BUG();
++}
++
++static struct omap2_mcspi_device_config mipid_mcspi_config = {
++	.turbo_mode	= 0,
++	.single_channel	= 1,
++};
+ 
+ static int slot1_cover_open;
+ static int slot2_cover_open;
+@@ -139,7 +254,34 @@ static struct omap2_mcspi_device_config
+ 	.single_channel = 1,
+ };
+ 
++#ifdef CONFIG_MACH_NOKIA_N8X0_LCD
++extern struct mipid_platform_data n8x0_mipid_platform_data;
++#endif
++
++#ifdef CONFIG_TOUCHSCREEN_TSC2005
++static struct tsc2005_platform_data tsc2005_config;
++static void rx51_tsc2005_set_reset(bool enable)
++{
++	gpio_set_value(RX51_TSC2005_RESET_GPIO, enable);
++}
++
++static struct omap2_mcspi_device_config tsc2005_mcspi_config = {
++	.turbo_mode	= 0,
++	.single_channel = 1,
++};
++#endif
++
+ static struct spi_board_info n800_spi_board_info[] __initdata = {
++#ifdef CONFIG_MACH_NOKIA_N8X0_LCD
++	{
++		.modalias	= "lcd_mipid",
++		.bus_num	= 1,
++		.chip_select	= 1,
++		.max_speed_hz	= 4000000,
++		.controller_data= &mipid_mcspi_config,
++		.platform_data	= &n8x0_mipid_platform_data,
++	},
++#endif
+ 	{
+ 		.modalias	= "p54spi",
+ 		.bus_num	= 2,
+@@ -147,6 +289,68 @@ static struct spi_board_info n800_spi_bo
+ 		.max_speed_hz   = 48000000,
+ 		.controller_data = &p54spi_mcspi_config,
+ 	},
++	{
++		.modalias	 = "tsc2005",
++		.bus_num	 = 1,
++		.chip_select	 = 0,
++		.irq		 = OMAP_GPIO_IRQ(RX51_TSC2005_IRQ_GPIO),
++		.max_speed_hz    = 6000000,
++		.controller_data = &tsc2005_mcspi_config,
++		.platform_data   = &tsc2005_config,
++	},
++};
++
++static void __init tsc2005_set_config(void)
++{
++	const struct omap_lcd_config *conf;
++
++	conf = omap_get_config(OMAP_TAG_LCD, struct omap_lcd_config);
++	if (conf != NULL) {
++#ifdef CONFIG_TOUCHSCREEN_TSC2005
++		if (strcmp(conf->panel_name, "lph8923") == 0) {
++			tsc2005_config.ts_x_plate_ohm = 180;
++			tsc2005_config.ts_hw_avg = 0;
++			tsc2005_config.ts_ignore_last = 0;
++			tsc2005_config.ts_touch_pressure = 1500;
++			tsc2005_config.ts_stab_time = 100;
++			tsc2005_config.ts_pressure_max = 2048;
++			tsc2005_config.ts_pressure_fudge = 2;
++			tsc2005_config.ts_x_max = 4096;
++			tsc2005_config.ts_x_fudge = 4;
++			tsc2005_config.ts_y_max = 4096;
++			tsc2005_config.ts_y_fudge = 7;
++			tsc2005_config.set_reset = rx51_tsc2005_set_reset;
++		} else if (strcmp(conf->panel_name, "ls041y3") == 0) {
++			tsc2005_config.ts_x_plate_ohm = 280;
++			tsc2005_config.ts_hw_avg = 0;
++			tsc2005_config.ts_ignore_last = 0;
++			tsc2005_config.ts_touch_pressure = 1500;
++			tsc2005_config.ts_stab_time = 1000;
++			tsc2005_config.ts_pressure_max = 2048;
++			tsc2005_config.ts_pressure_fudge = 2;
++			tsc2005_config.ts_x_max = 4096;
++			tsc2005_config.ts_x_fudge = 4;
++			tsc2005_config.ts_y_max = 4096;
++			tsc2005_config.ts_y_fudge = 7;
++			tsc2005_config.set_reset = rx51_tsc2005_set_reset;
++		} else {
++			printk(KERN_ERR "Unknown panel type, set default "
++			       "touchscreen configuration\n");
++			tsc2005_config.ts_x_plate_ohm = 200;
++			tsc2005_config.ts_stab_time = 100;
++		}
++#endif
++	}
++}
++
++static struct i2c_board_info __initdata_or_module n8x0_i2c_board_info_2[] = {};
++
++static struct i2c_board_info __initdata_or_module n810_i2c_board_info_2[] = {
++	{
++		I2C_BOARD_INFO("lm8323", 0x45),
++		.irq		= OMAP_GPIO_IRQ(109),
++		.platform_data	= &lm8323_pdata,
++	},
+ };
+ 
+ #if defined(CONFIG_MTD_ONENAND_OMAP2) || \
+@@ -181,6 +385,20 @@ static struct mtd_partition onenand_part
+ 	},
+ };
+ 
++static struct cbus_host_platform_data n8x0_cbus_data = {
++	.clk_gpio	= 66,
++	.dat_gpio	= 65,
++	.sel_gpio	= 64,
++};
++
++static struct platform_device n8x0_cbus_device = {
++	.name		= "cbus",
++	.id		= -1,
++	.dev		= {
++		.platform_data = &n8x0_cbus_data,
++	},
++};
++
+ static struct omap_onenand_platform_data board_onenand_data = {
+ 	.cs		= 0,
+ 	.gpio_irq	= 26,
+@@ -649,14 +867,37 @@ static void __init n8x0_init_irq(void)
+ 	omap_gpio_init();
+ }
+ 
++#ifdef CONFIG_MACH_NOKIA_N8X0_LCD
++extern void n8x0_mipid_init(void);
++extern void n8x0_blizzard_init(void);
++#else
++#define n8x0_mipid_init() 0
++#define n8x0_blizzard_init() 0
++#endif
++
+ static void __init n8x0_init_machine(void)
+ {
++	platform_device_register(&n8x0_cbus_device);
++
++	n8x0_bt_init();
++
+ 	/* FIXME: add n810 spi devices */
++	tsc2005_set_config();
+ 	spi_register_board_info(n800_spi_board_info,
+ 				ARRAY_SIZE(n800_spi_board_info));
+ 
+ 	omap_serial_init();
+ 	n8x0_menelaus_init();
++
++	omap_register_i2c_bus(2, 400, n8x0_i2c_board_info_2,
++			      ARRAY_SIZE(n8x0_i2c_board_info_2));
++
++	i2c_register_board_info(2, n810_i2c_board_info_2,
++				ARRAY_SIZE(n810_i2c_board_info_2));
++
++	n8x0_mipid_init();
++	n8x0_blizzard_init();
++
+ 	n8x0_onenand_init();
+ 	n8x0_mmc_init();
+ 	n8x0_usb_init();
+Index: linux-2.6.35/arch/arm/mach-omap2/board-n8x0-lcd.c
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/mach-omap2/board-n8x0-lcd.c	2010-08-08 12:56:31.000000000 +0200
+@@ -0,0 +1,127 @@
++/*
++ * linux/arch/arm/mach-omap2/board-n8x0.c
++ *
++ * Copyright (C) 2005-2009 Nokia Corporation
++ * Author: Juha Yrjola <[email protected]>
++ *
++ * Modified from mach-omap2/board-generic.c
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#include <linux/clk.h>
++#include <linux/delay.h>
++#include <linux/gpio.h>
++#include <linux/omapfb.h>
++
++#include <plat/lcd_mipid.h>
++#include <plat/blizzard.h>
++
++#include <../drivers/cbus/tahvo.h>
++
++#define N8X0_BLIZZARD_POWERDOWN_GPIO	15
++
++// MIPID LCD Panel
++
++static void mipid_shutdown(struct mipid_platform_data *pdata)
++{
++	if (pdata->nreset_gpio != -1) {
++		pr_info("shutdown LCD\n");
++		gpio_set_value(pdata->nreset_gpio, 0);
++		msleep(120);
++	}
++}
++
++struct mipid_platform_data n8x0_mipid_platform_data = {
++	.shutdown = mipid_shutdown,
++};
++
++void __init n8x0_mipid_init(void)
++{
++	const struct omap_lcd_config *conf;
++
++	conf = omap_get_config(OMAP_TAG_LCD, struct omap_lcd_config);
++	if (conf != NULL) {
++		n8x0_mipid_platform_data.nreset_gpio = conf->nreset_gpio;
++		n8x0_mipid_platform_data.data_lines = conf->data_lines;
++		printk(KERN_INFO "N8x0 MIPID config loaded");
++	}
++	else
++		printk(KERN_INFO "N8x0 MIPID config not provided");
++}
++
++
++// Epson Blizzard LCD Controller
++
++static struct {
++	struct clk *sys_ck;
++} blizzard;
++
++static int blizzard_get_clocks(void)
++{
++	blizzard.sys_ck = clk_get(0, "osc_ck");
++	if (IS_ERR(blizzard.sys_ck)) {
++		printk(KERN_ERR "can't get Blizzard clock\n");
++		return PTR_ERR(blizzard.sys_ck);
++	}
++	return 0;
++}
++
++static unsigned long blizzard_get_clock_rate(struct device *dev)
++{
++	return clk_get_rate(blizzard.sys_ck);
++}
++
++static void blizzard_enable_clocks(int enable)
++{
++	if (enable)
++		clk_enable(blizzard.sys_ck);
++	else
++		clk_disable(blizzard.sys_ck);
++}
++
++static void blizzard_power_up(struct device *dev)
++{
++	/* Vcore to 1.475V */
++	tahvo_set_clear_reg_bits(0x07, 0, 0xf);
++	msleep(10);
++
++	blizzard_enable_clocks(1);
++	gpio_set_value(N8X0_BLIZZARD_POWERDOWN_GPIO, 1);
++}
++
++static void blizzard_power_down(struct device *dev)
++{
++	gpio_set_value(N8X0_BLIZZARD_POWERDOWN_GPIO, 0);
++	blizzard_enable_clocks(0);
++
++	/* Vcore to 1.005V */
++	tahvo_set_clear_reg_bits(0x07, 0xf, 0);
++}
++
++static struct blizzard_platform_data n8x0_blizzard_data = {
++	.power_up	= blizzard_power_up,
++	.power_down	= blizzard_power_down,
++	.get_clock_rate	= blizzard_get_clock_rate,
++	.te_connected	= 1,
++};
++
++void __init n8x0_blizzard_init(void)
++{
++	int r;
++
++	r = gpio_request(N8X0_BLIZZARD_POWERDOWN_GPIO, "Blizzard pd");
++	if (r < 0)
++	{
++		printk(KERN_ERR "Can't get N8x0 Blizzard powerdown GPIO %d\n", N8X0_BLIZZARD_POWERDOWN_GPIO);
++		return;
++	}
++	gpio_direction_output(N8X0_BLIZZARD_POWERDOWN_GPIO, 1);
++
++	blizzard_get_clocks();
++	omapfb_set_ctrl_platform_data(&n8x0_blizzard_data);
++
++	printk(KERN_INFO "N8x0 Blizzard initialized");
++}
+Index: linux-2.6.35/arch/arm/mach-omap2/board-n8x0-usb.c
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/arch/arm/mach-omap2/board-n8x0-usb.c	2010-08-08 12:56:31.000000000 +0200
+@@ -0,0 +1,175 @@
++/*
++ * linux/arch/arm/mach-omap2/board-n8x0-usb.c
++ *
++ * Copyright (C) 2006 Nokia Corporation
++ * Author: Juha Yrjola
++ *
++ * 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/types.h>
++#include <linux/delay.h>
++#include <linux/platform_device.h>
++#include <linux/clk.h>
++#include <linux/err.h>
++#include <linux/gpio.h>
++#include <linux/usb/musb.h>
++
++#include <plat/gpmc.h>
++
++#define TUSB_ASYNC_CS		1
++#define TUSB_SYNC_CS		4
++#define GPIO_TUSB_INT		58
++#define GPIO_TUSB_ENABLE	0
++
++static int tusb_set_power(int state);
++static int tusb_set_clock(struct clk *osc_ck, int state);
++
++#if	defined(CONFIG_USB_MUSB_OTG)
++#	define BOARD_MODE	MUSB_OTG
++#elif	defined(CONFIG_USB_MUSB_PERIPHERAL)
++#	define BOARD_MODE	MUSB_PERIPHERAL
++#else	/* defined(CONFIG_USB_MUSB_HOST) */
++#	define BOARD_MODE	MUSB_HOST
++#endif
++
++static struct musb_hdrc_eps_bits musb_eps[] = {
++	{	"ep1_tx", 5,	},
++	{	"ep1_rx", 5,	},
++	{	"ep2_tx", 5,	},
++	{	"ep2_rx", 5,	},
++	{	"ep3_tx", 3,	},
++	{	"ep3_rx", 3,	},
++	{	"ep4_tx", 3,	},
++	{	"ep4_rx", 3,	},
++	{	"ep5_tx", 2,	},
++	{	"ep5_rx", 2,	},
++	{	"ep6_tx", 2,	},
++	{	"ep6_rx", 2,	},
++	{	"ep7_tx", 2,	},
++	{	"ep7_rx", 2,	},
++	{	"ep8_tx", 2,	},
++	{	"ep8_rx", 2,	},
++	{	"ep9_tx", 2,	},
++	{	"ep9_rx", 2,	},
++	{	"ep10_tx", 2,	},
++	{	"ep10_rx", 2,	},
++	{	"ep11_tx", 2,	},
++	{	"ep11_rx", 2,	},
++	{	"ep12_tx", 2,	},
++	{	"ep12_rx", 2,	},
++	{	"ep13_tx", 2,	},
++	{	"ep13_rx", 2,	},
++	{	"ep14_tx", 2,	},
++	{	"ep14_rx", 2,	},
++	{	"ep15_tx", 2,	},
++	{	"ep15_rx", 2,	},
++};
++
++static struct musb_hdrc_config musb_config = {
++	.multipoint	= 1,
++	.dyn_fifo	= 1,
++	.soft_con	= 1,
++	.dma		= 1,
++	.num_eps	= 16,
++	.dma_channels	= 7,
++	.ram_bits	= 12,
++	.eps_bits	= musb_eps,
++};
++
++static struct musb_hdrc_platform_data tusb_data = {
++	.mode		= BOARD_MODE,
++	.set_power	= tusb_set_power,
++	.set_clock	= tusb_set_clock,
++	.min_power	= 25,	/* x2 = 50 mA drawn from VBUS as peripheral */
++	.power		= 100,	/* Max 100 mA VBUS for host mode */
++	.clock		= "osc_ck",
++	.config		= &musb_config,
++};
++
++/*
++ * Enable or disable power to TUSB6010. When enabling, turn on 3.3 V and
++ * 1.5 V voltage regulators of PM companion chip. Companion chip will then
++ * provide then PGOOD signal to TUSB6010 which will release it from reset.
++ */
++static int tusb_set_power(int state)
++{
++	int i, retval = 0;
++
++	if (state) {
++		gpio_set_value(GPIO_TUSB_ENABLE, 1);
++		msleep(1);
++
++		/* Wait until TUSB6010 pulls INT pin down */
++		i = 100;
++		while (i && gpio_get_value(GPIO_TUSB_INT)) {
++			msleep(1);
++			i--;
++		}
++
++		if (!i) {
++			printk(KERN_ERR "tusb: powerup failed\n");
++			retval = -ENODEV;
++		}
++	} else {
++		gpio_set_value(GPIO_TUSB_ENABLE, 0);
++		msleep(10);
++	}
++
++	return retval;
++}
++
++static int		osc_ck_on;
++
++static int tusb_set_clock(struct clk *osc_ck, int state)
++{
++	if (state) {
++		if (osc_ck_on > 0)
++			return -ENODEV;
++
++		//omap2_block_sleep();
++		clk_enable(osc_ck);
++		osc_ck_on = 1;
++	} else {
++		if (osc_ck_on == 0)
++			return -ENODEV;
++
++		clk_disable(osc_ck);
++		osc_ck_on = 0;
++		//omap2_allow_sleep();
++	}
++
++	return 0;
++}
++
++void __init n8x0_usb_init(void)
++{
++	int ret = 0;
++	static char	announce[] __initdata = KERN_INFO "TUSB 6010\n";
++
++	/* PM companion chip power control pin */
++	ret = gpio_request(GPIO_TUSB_ENABLE, "TUSB6010 enable");
++	if (ret != 0) {
++		printk(KERN_ERR "Could not get TUSB power GPIO%i\n",
++		       GPIO_TUSB_ENABLE);
++		return;
++	}
++	gpio_direction_output(GPIO_TUSB_ENABLE, 0);
++
++	tusb_set_power(0);
++
++	ret = tusb6010_setup_interface(&tusb_data, TUSB6010_REFCLK_19, 2,
++					TUSB_ASYNC_CS, TUSB_SYNC_CS,
++					GPIO_TUSB_INT, 0x3f);
++	if (ret != 0)
++		goto err;
++
++	printk(announce);
++
++	return;
++
++err:
++	gpio_free(GPIO_TUSB_ENABLE);
++}
+Index: linux-2.6.35/arch/arm/mach-omap2/control.c
+===================================================================
+--- linux-2.6.35.orig/arch/arm/mach-omap2/control.c	2010-08-08 12:56:15.000000000 +0200
++++ linux-2.6.35/arch/arm/mach-omap2/control.c	2010-08-08 12:56:32.000000000 +0200
+@@ -162,6 +162,7 @@ u16 omap_ctrl_readw(u16 offset)
+ 	return __raw_readw(OMAP_CTRL_REGADDR(offset));
+ }
+ 
++EXPORT_SYMBOL_GPL(omap_ctrl_readl);
+ u32 omap_ctrl_readl(u16 offset)
+ {
+ 	return __raw_readl(OMAP_CTRL_REGADDR(offset));
+@@ -177,6 +178,7 @@ void omap_ctrl_writew(u16 val, u16 offse
+ 	__raw_writew(val, OMAP_CTRL_REGADDR(offset));
+ }
+ 
++EXPORT_SYMBOL_GPL(omap_ctrl_writel);
+ void omap_ctrl_writel(u32 val, u16 offset)
+ {
+ 	__raw_writel(val, OMAP_CTRL_REGADDR(offset));
+Index: linux-2.6.35/arch/arm/mach-omap2/Kconfig
+===================================================================
+--- linux-2.6.35.orig/arch/arm/mach-omap2/Kconfig	2010-08-08 12:56:15.000000000 +0200
++++ linux-2.6.35/arch/arm/mach-omap2/Kconfig	2010-08-08 12:56:33.000000000 +0200
+@@ -116,6 +116,16 @@ config MACH_NOKIA_N8X0
+ 	select MACH_NOKIA_N810
+ 	select MACH_NOKIA_N810_WIMAX
+ 
++config MACH_NOKIA_N8X0_LCD
++	bool
++	depends on MACH_NOKIA_N8X0 && FB_OMAP_LCDC_BLIZZARD && FB_OMAP_LCD_MIPID
++	default y
++
++config MACH_NOKIA_N8X0_USB
++	bool
++	depends on MACH_NOKIA_N8X0 && MACH_OMAP2_TUSB6010
++	default y
++
+ config MACH_NOKIA_RX51
+ 	bool "Nokia RX-51 board"
+ 	depends on ARCH_OMAP3
+Index: linux-2.6.35/arch/arm/mach-omap2/Makefile
+===================================================================
+--- linux-2.6.35.orig/arch/arm/mach-omap2/Makefile	2010-08-08 12:56:15.000000000 +0200
++++ linux-2.6.35/arch/arm/mach-omap2/Makefile	2010-08-08 12:56:33.000000000 +0200
+@@ -116,6 +116,8 @@ obj-$(CONFIG_MACH_OMAP_3430SDP)		+= boar
+ 					   hsmmc.o \
+ 					   board-sdp-flash.o
+ obj-$(CONFIG_MACH_NOKIA_N8X0)		+= board-n8x0.o
++obj-$(CONFIG_MACH_NOKIA_N8X0_LCD)	+= board-n8x0-lcd.o
++obj-$(CONFIG_MACH_NOKIA_N8X0_USB)	+= board-n8x0-usb.o
+ obj-$(CONFIG_MACH_NOKIA_RX51)		+= board-rx51.o \
+ 					   board-rx51-sdram.o \
+ 					   board-rx51-peripherals.o \
+Index: linux-2.6.35/arch/arm/mach-omap2/serial.c
+===================================================================
+--- linux-2.6.35.orig/arch/arm/mach-omap2/serial.c	2010-08-08 12:56:15.000000000 +0200
++++ linux-2.6.35/arch/arm/mach-omap2/serial.c	2010-08-08 12:56:34.000000000 +0200
+@@ -495,10 +495,10 @@ static void omap_uart_idle_init(struct o
+ 		uart->padconf = 0;
+ 	}
+ 
+-	p->irqflags |= IRQF_SHARED;
++/*	p->irqflags |= IRQF_SHARED;
+ 	ret = request_irq(p->irq, omap_uart_interrupt, IRQF_SHARED,
+ 			  "serial idle", (void *)uart);
+-	WARN_ON(ret);
++	WARN_ON(ret); */
+ }
+ 
+ void omap_uart_enable_irqs(int enable)
+@@ -506,13 +506,13 @@ void omap_uart_enable_irqs(int enable)
+ 	int ret;
+ 	struct omap_uart_state *uart;
+ 
+-	list_for_each_entry(uart, &uart_list, node) {
++/*	list_for_each_entry(uart, &uart_list, node) {
+ 		if (enable)
+ 			ret = request_irq(uart->p->irq, omap_uart_interrupt,
+ 				IRQF_SHARED, "serial idle", (void *)uart);
+ 		else
+ 			free_irq(uart->p->irq, (void *)uart);
+-	}
++	} */
+ }
+ 
+ static ssize_t sleep_timeout_show(struct device *dev,

+ 1933 - 0
target/linux/omap24xx/patches-2.6.35/400-bluetooth-hci_h4p.patch

@@ -0,0 +1,1933 @@
+Index: linux-2.6.35/drivers/bluetooth/hci_h4p/core.c
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/drivers/bluetooth/hci_h4p/core.c	2010-08-08 12:57:24.000000000 +0200
+@@ -0,0 +1,1023 @@
++/*
++ * This file is part of hci_h4p bluetooth driver
++ *
++ * Copyright (C) 2005, 2006 Nokia Corporation.
++ *
++ * Contact: Ville Tervo <[email protected]>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * version 2 as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
++ * 02110-1301 USA
++ *
++ */
++
++#include <linux/module.h>
++
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/errno.h>
++#include <linux/delay.h>
++#include <linux/spinlock.h>
++#include <linux/serial_reg.h>
++#include <linux/skbuff.h>
++#include <linux/timer.h>
++#include <linux/device.h>
++#include <linux/platform_device.h>
++#include <linux/clk.h>
++#include <linux/gpio.h>
++
++#include <mach/hardware.h>
++#include <mach/board.h>
++#include <mach/irqs.h>
++//#include <mach/pm.h>
++
++#include <net/bluetooth/bluetooth.h>
++#include <net/bluetooth/hci_core.h>
++#include <net/bluetooth/hci.h>
++
++#include "hci_h4p.h"
++
++#define PM_TIMEOUT 200
++
++struct omap_bluetooth_config {
++	u8    chip_type;
++	u8    bt_wakeup_gpio;
++	u8    host_wakeup_gpio;
++	u8    reset_gpio;
++	u8    bt_uart;
++	u8    bd_addr[6];
++	u8    bt_sysclk;
++};
++
++/* This should be used in function that cannot release clocks */
++static void hci_h4p_set_clk(struct hci_h4p_info *info, int *clock, int enable)
++{
++	unsigned long flags;
++
++	spin_lock_irqsave(&info->clocks_lock, flags);
++	if (enable && !*clock) {
++		NBT_DBG_POWER("Enabling %p\n", clock);
++		clk_enable(info->uart_fclk);
++#ifdef CONFIG_ARCH_OMAP2
++		if (cpu_is_omap24xx()) {
++			clk_enable(info->uart_iclk);
++			//omap2_block_sleep();
++		}
++#endif
++	}
++	if (!enable && *clock) {
++		NBT_DBG_POWER("Disabling %p\n", clock);
++		clk_disable(info->uart_fclk);
++#ifdef CONFIG_ARCH_OMAP2
++		if (cpu_is_omap24xx()) {
++			clk_disable(info->uart_iclk);
++			//omap2_allow_sleep();
++		}
++#endif
++	}
++
++	*clock = enable;
++	spin_unlock_irqrestore(&info->clocks_lock, flags);
++}
++
++/* Power management functions */
++static void hci_h4p_disable_tx(struct hci_h4p_info *info)
++{
++	NBT_DBG_POWER("\n");
++
++	if (!info->pm_enabled)
++		return;
++
++	mod_timer(&info->tx_pm_timer, jiffies + msecs_to_jiffies(PM_TIMEOUT));
++}
++
++static void hci_h4p_enable_tx(struct hci_h4p_info *info)
++{
++	NBT_DBG_POWER("\n");
++
++	if (!info->pm_enabled)
++		return;
++
++	del_timer_sync(&info->tx_pm_timer);
++	if (info->tx_pm_enabled) {
++		info->tx_pm_enabled = 0;
++		hci_h4p_set_clk(info, &info->tx_clocks_en, 1);
++		gpio_set_value(info->bt_wakeup_gpio, 1);
++	}
++}
++
++static void hci_h4p_tx_pm_timer(unsigned long data)
++{
++	struct hci_h4p_info *info;
++
++	NBT_DBG_POWER("\n");
++
++	info = (struct hci_h4p_info *)data;
++
++	if (hci_h4p_inb(info, UART_LSR) & UART_LSR_TEMT) {
++		gpio_set_value(info->bt_wakeup_gpio, 0);
++		hci_h4p_set_clk(info, &info->tx_clocks_en, 0);
++		info->tx_pm_enabled = 1;
++	}
++	else {
++		mod_timer(&info->tx_pm_timer, jiffies + msecs_to_jiffies(PM_TIMEOUT));
++	}
++}
++
++static void hci_h4p_disable_rx(struct hci_h4p_info *info)
++{
++	if (!info->pm_enabled)
++		return;
++
++	mod_timer(&info->rx_pm_timer, jiffies + msecs_to_jiffies(PM_TIMEOUT));
++}
++
++static void hci_h4p_enable_rx(struct hci_h4p_info *info)
++{
++	unsigned long flags;
++
++	if (!info->pm_enabled)
++		return;
++
++	del_timer_sync(&info->rx_pm_timer);
++	spin_lock_irqsave(&info->lock, flags);
++	if (info->rx_pm_enabled) {
++		hci_h4p_set_clk(info, &info->rx_clocks_en, 1);
++		hci_h4p_outb(info, UART_IER, hci_h4p_inb(info, UART_IER) | UART_IER_RDI);
++		__hci_h4p_set_auto_ctsrts(info, 1, UART_EFR_RTS);
++		info->rx_pm_enabled = 0;
++	}
++	spin_unlock_irqrestore(&info->lock, flags);
++}
++
++static void hci_h4p_rx_pm_timer(unsigned long data)
++{
++	unsigned long flags;
++	struct hci_h4p_info *info = (struct hci_h4p_info *)data;
++
++	spin_lock_irqsave(&info->lock, flags);
++	if (!(hci_h4p_inb(info, UART_LSR) & UART_LSR_DR)) {
++		__hci_h4p_set_auto_ctsrts(info, 0, UART_EFR_RTS);
++		hci_h4p_set_rts(info, 0);
++		hci_h4p_outb(info, UART_IER, hci_h4p_inb(info, UART_IER) & ~UART_IER_RDI);
++		hci_h4p_set_clk(info, &info->rx_clocks_en, 0);
++		info->rx_pm_enabled = 1;
++	}
++	else {
++		mod_timer(&info->rx_pm_timer, jiffies + msecs_to_jiffies(PM_TIMEOUT));
++	}
++	spin_unlock_irqrestore(&info->lock, flags);
++}
++
++/* Negotiation functions */
++int hci_h4p_send_alive_packet(struct hci_h4p_info *info)
++{
++	NBT_DBG("Sending alive packet\n");
++
++	if (!info->alive_cmd_skb)
++		return -EINVAL;
++
++	/* Keep reference to buffer so we can reuse it */
++	info->alive_cmd_skb = skb_get(info->alive_cmd_skb);
++
++	skb_queue_tail(&info->txq, info->alive_cmd_skb);
++	tasklet_schedule(&info->tx_task);
++
++	NBT_DBG("Alive packet sent\n");
++
++	return 0;
++}
++
++static void hci_h4p_alive_packet(struct hci_h4p_info *info, struct sk_buff *skb)
++{
++	NBT_DBG("Received alive packet\n");
++	if (skb->data[1] == 0xCC) {
++		complete(&info->init_completion);
++	}
++
++	kfree_skb(skb);
++}
++
++static int hci_h4p_send_negotiation(struct hci_h4p_info *info, struct sk_buff *skb)
++{
++	NBT_DBG("Sending negotiation..\n");
++
++	hci_h4p_change_speed(info, INIT_SPEED);
++
++	info->init_error = 0;
++	init_completion(&info->init_completion);
++	skb_queue_tail(&info->txq, skb);
++	tasklet_schedule(&info->tx_task);
++
++	if (!wait_for_completion_interruptible_timeout(&info->init_completion,
++				msecs_to_jiffies(1000)))
++		return -ETIMEDOUT;
++
++	NBT_DBG("Negotiation sent\n");
++	return info->init_error;
++}
++
++static void hci_h4p_negotiation_packet(struct hci_h4p_info *info,
++				       struct sk_buff *skb)
++{
++	int err = 0;
++
++	if (skb->data[1] == 0x20) {
++		/* Change to operational settings */
++		hci_h4p_set_rts(info, 0);
++
++		err = hci_h4p_wait_for_cts(info, 0, 100);
++		if (err < 0)
++			goto neg_ret;
++
++		hci_h4p_change_speed(info, MAX_BAUD_RATE);
++
++		err = hci_h4p_wait_for_cts(info, 1, 100);
++		if (err < 0)
++			goto neg_ret;
++
++		hci_h4p_set_auto_ctsrts(info, 1, UART_EFR_CTS | UART_EFR_RTS);
++
++		err = hci_h4p_send_alive_packet(info);
++		if (err < 0)
++			goto neg_ret;
++	} else {
++		dev_err(info->dev, "Could not negotiate hci_h4p settings\n");
++		err = -EINVAL;
++		goto neg_ret;
++	}
++
++	kfree_skb(skb);
++	return;
++
++neg_ret:
++	info->init_error = err;
++	complete(&info->init_completion);
++	kfree_skb(skb);
++}
++
++/* H4 packet handling functions */
++static int hci_h4p_get_hdr_len(struct hci_h4p_info *info, u8 pkt_type)
++{
++	long retval;
++
++	switch (pkt_type) {
++	case H4_EVT_PKT:
++		retval = HCI_EVENT_HDR_SIZE;
++		break;
++	case H4_ACL_PKT:
++		retval = HCI_ACL_HDR_SIZE;
++		break;
++	case H4_SCO_PKT:
++		retval = HCI_SCO_HDR_SIZE;
++		break;
++	case H4_NEG_PKT:
++		retval = 11;
++		break;
++	case H4_ALIVE_PKT:
++		retval = 3;
++		break;
++	default:
++		dev_err(info->dev, "Unknown H4 packet type 0x%.2x\n", pkt_type);
++		retval = -1;
++		break;
++	}
++
++	return retval;
++}
++
++static unsigned int hci_h4p_get_data_len(struct hci_h4p_info *info,
++					 struct sk_buff *skb)
++{
++	long retval = -1;
++	struct hci_event_hdr *evt_hdr;
++	struct hci_acl_hdr *acl_hdr;
++	struct hci_sco_hdr *sco_hdr;
++
++	switch (bt_cb(skb)->pkt_type) {
++	case H4_EVT_PKT:
++		evt_hdr = (struct hci_event_hdr *)skb->data;
++		retval = evt_hdr->plen;
++		break;
++	case H4_ACL_PKT:
++		acl_hdr = (struct hci_acl_hdr *)skb->data;
++		retval = le16_to_cpu(acl_hdr->dlen);
++		break;
++	case H4_SCO_PKT:
++		sco_hdr = (struct hci_sco_hdr *)skb->data;
++		retval = sco_hdr->dlen;
++		break;
++	case H4_NEG_PKT:
++		retval = 0;
++		break;
++	case H4_ALIVE_PKT:
++		retval = 0;
++		break;
++	}
++
++	return retval;
++}
++
++static inline void hci_h4p_recv_frame(struct hci_h4p_info *info,
++				      struct sk_buff *skb)
++{
++
++	if (unlikely(!test_bit(HCI_RUNNING, &info->hdev->flags))) {
++		NBT_DBG("fw_event\n");
++		hci_h4p_parse_fw_event(info, skb);
++	} else {
++		hci_recv_frame(skb);
++		NBT_DBG("Frame sent to upper layer\n");
++	}
++}
++
++static void hci_h4p_rx_tasklet(unsigned long data)
++{
++	u8 byte;
++	unsigned long flags;
++	struct hci_h4p_info *info = (struct hci_h4p_info *)data;
++
++	NBT_DBG("tasklet woke up\n");
++	NBT_DBG_TRANSFER("rx_tasklet woke up\ndata ");
++
++	while (hci_h4p_inb(info, UART_LSR) & UART_LSR_DR) {
++		byte = hci_h4p_inb(info, UART_RX);
++		if (info->garbage_bytes) {
++			info->garbage_bytes--;
++			continue;
++		}
++		if (info->rx_skb == NULL) {
++			info->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC | GFP_DMA);
++			if (!info->rx_skb) {
++				dev_err(info->dev, "Can't allocate memory for new packet\n");
++				goto finish_task;
++			}
++			info->rx_state = WAIT_FOR_PKT_TYPE;
++			info->rx_skb->dev = (void *)info->hdev;
++		}
++		info->hdev->stat.byte_rx++;
++		NBT_DBG_TRANSFER_NF("0x%.2x  ", byte);
++		switch (info->rx_state) {
++		case WAIT_FOR_PKT_TYPE:
++			bt_cb(info->rx_skb)->pkt_type = byte;
++			info->rx_count = hci_h4p_get_hdr_len(info, byte);
++			if (info->rx_count < 0) {
++				info->hdev->stat.err_rx++;
++				kfree_skb(info->rx_skb);
++				info->rx_skb = NULL;
++			} else {
++				info->rx_state = WAIT_FOR_HEADER;
++			}
++			break;
++		case WAIT_FOR_HEADER:
++			info->rx_count--;
++			*skb_put(info->rx_skb, 1) = byte;
++			if (info->rx_count == 0) {
++				info->rx_count = hci_h4p_get_data_len(info, info->rx_skb);
++				if (info->rx_count > skb_tailroom(info->rx_skb)) {
++					dev_err(info->dev, "Frame is %ld bytes too long.\n",
++					       info->rx_count - skb_tailroom(info->rx_skb));
++					kfree_skb(info->rx_skb);
++					info->rx_skb = NULL;
++					info->garbage_bytes = info->rx_count - skb_tailroom(info->rx_skb);
++					break;
++				}
++				info->rx_state = WAIT_FOR_DATA;
++
++				if (bt_cb(info->rx_skb)->pkt_type == H4_NEG_PKT) {
++					hci_h4p_negotiation_packet(info, info->rx_skb);
++					info->rx_skb = NULL;
++					info->rx_state = WAIT_FOR_PKT_TYPE;
++					goto finish_task;
++				}
++				if (bt_cb(info->rx_skb)->pkt_type == H4_ALIVE_PKT) {
++					hci_h4p_alive_packet(info, info->rx_skb);
++					info->rx_skb = NULL;
++					info->rx_state = WAIT_FOR_PKT_TYPE;
++					goto finish_task;
++				}
++			}
++			break;
++		case WAIT_FOR_DATA:
++			info->rx_count--;
++			*skb_put(info->rx_skb, 1) = byte;
++			if (info->rx_count == 0) {
++				/* H4+ devices should allways send word aligned packets */
++				if (!(info->rx_skb->len % 2)) {
++					info->garbage_bytes++;
++				}
++				hci_h4p_recv_frame(info, info->rx_skb);
++				info->rx_skb = NULL;
++			}
++			break;
++		default:
++			WARN_ON(1);
++			break;
++		}
++	}
++
++finish_task:
++	spin_lock_irqsave(&info->lock, flags);
++	hci_h4p_outb(info, UART_IER, hci_h4p_inb(info, UART_IER) | UART_IER_RDI);
++	spin_unlock_irqrestore(&info->lock, flags);
++
++	NBT_DBG_TRANSFER_NF("\n");
++	NBT_DBG("rx_ended\n");
++}
++
++static void hci_h4p_tx_tasklet(unsigned long data)
++{
++	unsigned int sent = 0;
++	unsigned long flags;
++	struct sk_buff *skb;
++	struct hci_h4p_info *info = (struct hci_h4p_info *)data;
++
++	NBT_DBG("tasklet woke up\n");
++	NBT_DBG_TRANSFER("tx_tasklet woke up\n data ");
++
++	skb = skb_dequeue(&info->txq);
++	if (!skb) {
++		/* No data in buffer */
++		NBT_DBG("skb ready\n");
++		hci_h4p_disable_tx(info);
++		return;
++	}
++
++	/* Copy data to tx fifo */
++	while (!(hci_h4p_inb(info, UART_OMAP_SSR) & UART_OMAP_SSR_TXFULL) &&
++	       (sent < skb->len)) {
++		NBT_DBG_TRANSFER_NF("0x%.2x ", skb->data[sent]);
++		hci_h4p_outb(info, UART_TX, skb->data[sent]);
++		sent++;
++	}
++
++	info->hdev->stat.byte_tx += sent;
++	NBT_DBG_TRANSFER_NF("\n");
++	if (skb->len == sent) {
++		kfree_skb(skb);
++	} else {
++		skb_pull(skb, sent);
++		skb_queue_head(&info->txq, skb);
++	}
++
++	spin_lock_irqsave(&info->lock, flags);
++	hci_h4p_outb(info, UART_IER, hci_h4p_inb(info, UART_IER) | UART_IER_THRI);
++	spin_unlock_irqrestore(&info->lock, flags);
++}
++
++static irqreturn_t hci_h4p_interrupt(int irq, void *data)
++{
++	struct hci_h4p_info *info = (struct hci_h4p_info *)data;
++	u8 iir, msr;
++	int ret;
++	unsigned long flags;
++
++	ret = IRQ_NONE;
++
++	iir = hci_h4p_inb(info, UART_IIR);
++	if (iir & UART_IIR_NO_INT) {
++		dev_err(info->dev, "Interrupt but no reason irq 0x%.2x\n", iir);
++		return IRQ_HANDLED;
++	}
++
++	NBT_DBG("In interrupt handler iir 0x%.2x\n", iir);
++
++	iir &= UART_IIR_ID;
++
++	if (iir == UART_IIR_MSI) {
++		msr = hci_h4p_inb(info, UART_MSR);
++		ret = IRQ_HANDLED;
++	}
++	if (iir == UART_IIR_RLSI) {
++		hci_h4p_inb(info, UART_RX);
++		hci_h4p_inb(info, UART_LSR);
++		ret = IRQ_HANDLED;
++	}
++
++	if (iir == UART_IIR_RDI) {
++		spin_lock_irqsave(&info->lock, flags);
++		hci_h4p_outb(info, UART_IER, hci_h4p_inb(info, UART_IER) & ~UART_IER_RDI);
++		spin_unlock_irqrestore(&info->lock, flags);
++		tasklet_schedule(&info->rx_task);
++		ret = IRQ_HANDLED;
++	}
++
++	if (iir == UART_IIR_THRI) {
++		spin_lock_irqsave(&info->lock, flags);
++		hci_h4p_outb(info, UART_IER, hci_h4p_inb(info, UART_IER) & ~UART_IER_THRI);
++		spin_unlock_irqrestore(&info->lock, flags);
++		tasklet_schedule(&info->tx_task);
++		ret = IRQ_HANDLED;
++	}
++
++	return ret;
++}
++
++static irqreturn_t hci_h4p_wakeup_interrupt(int irq, void *dev_inst)
++{
++	struct hci_h4p_info *info = dev_inst;
++	int should_wakeup;
++	struct hci_dev *hdev;
++
++	if (!info->hdev)
++		return IRQ_HANDLED;
++
++	hdev = info->hdev;
++
++	if (!test_bit(HCI_RUNNING, &hdev->flags))
++		return IRQ_HANDLED;
++
++	should_wakeup = gpio_get_value(info->host_wakeup_gpio);
++	NBT_DBG_POWER("gpio interrupt %d\n", should_wakeup);
++	if (should_wakeup) {
++		hci_h4p_enable_rx(info);
++	} else {
++		hci_h4p_disable_rx(info);
++	}
++
++	return IRQ_HANDLED;
++}
++
++static int hci_h4p_reset(struct hci_h4p_info *info)
++{
++	int err;
++
++	hci_h4p_init_uart(info);
++	hci_h4p_set_rts(info, 0);
++
++	gpio_set_value(info->reset_gpio, 0);
++	msleep(100);
++	gpio_set_value(info->bt_wakeup_gpio, 1);
++	gpio_set_value(info->reset_gpio, 1);
++	msleep(100);
++
++	err = hci_h4p_wait_for_cts(info, 1, 10);
++	if (err < 0) {
++		dev_err(info->dev, "No cts from bt chip\n");
++		return err;
++	}
++
++	hci_h4p_set_rts(info, 1);
++
++	return 0;
++}
++
++/* hci callback functions */
++static int hci_h4p_hci_flush(struct hci_dev *hdev)
++{
++	struct hci_h4p_info *info;
++	info = hdev->driver_data;
++
++	skb_queue_purge(&info->txq);
++
++	return 0;
++}
++
++static int hci_h4p_hci_open(struct hci_dev *hdev)
++{
++	struct hci_h4p_info *info;
++	int err;
++	struct sk_buff *neg_cmd_skb;
++	struct sk_buff_head fw_queue;
++
++	info = hdev->driver_data;
++
++	if (test_bit(HCI_RUNNING, &hdev->flags))
++		return 0;
++
++	skb_queue_head_init(&fw_queue);
++	err = hci_h4p_read_fw(info, &fw_queue);
++	if (err < 0) {
++		dev_err(info->dev, "Cannot read firmware\n");
++		return err;
++	}
++	neg_cmd_skb = skb_dequeue(&fw_queue);
++	if (!neg_cmd_skb) {
++		err = -EPROTO;
++		goto err_clean;
++	}
++	info->alive_cmd_skb = skb_dequeue(&fw_queue);
++	if (!info->alive_cmd_skb) {
++		err = -EPROTO;
++		goto err_clean;
++	}
++
++	hci_h4p_set_clk(info, &info->tx_clocks_en, 1);
++	hci_h4p_set_clk(info, &info->rx_clocks_en, 1);
++
++	tasklet_enable(&info->tx_task);
++	tasklet_enable(&info->rx_task);
++	info->rx_state = WAIT_FOR_PKT_TYPE;
++	info->rx_count = 0;
++	info->garbage_bytes = 0;
++	info->rx_skb = NULL;
++	info->pm_enabled = 0;
++	init_completion(&info->fw_completion);
++
++	err = hci_h4p_reset(info);
++	if (err < 0)
++		goto err_clean;
++
++	err = hci_h4p_send_negotiation(info, neg_cmd_skb);
++	neg_cmd_skb = NULL;
++	if (err < 0)
++		goto err_clean;
++
++	err = hci_h4p_send_fw(info, &fw_queue);
++	if (err < 0) {
++		dev_err(info->dev, "Sending firmware failed.\n");
++		goto err_clean;
++	}
++
++	kfree_skb(info->alive_cmd_skb);
++	info->alive_cmd_skb = NULL;
++	info->pm_enabled = 1;
++	info->tx_pm_enabled = 1;
++	info->rx_pm_enabled = 0;
++	set_bit(HCI_RUNNING, &hdev->flags);
++
++	NBT_DBG("hci up and running\n");
++	return 0;
++
++err_clean:
++	hci_h4p_hci_flush(hdev);
++	tasklet_disable(&info->tx_task);
++	tasklet_disable(&info->rx_task);
++	hci_h4p_reset_uart(info);
++	hci_h4p_set_clk(info, &info->tx_clocks_en, 0);
++	hci_h4p_set_clk(info, &info->rx_clocks_en, 0);
++	gpio_set_value(info->reset_gpio, 0);
++	gpio_set_value(info->bt_wakeup_gpio, 0);
++	skb_queue_purge(&fw_queue);
++	kfree_skb(neg_cmd_skb);
++	neg_cmd_skb = NULL;
++	kfree_skb(info->alive_cmd_skb);
++	info->alive_cmd_skb = NULL;
++	kfree_skb(info->rx_skb);
++
++	return err;
++}
++
++static int hci_h4p_hci_close(struct hci_dev *hdev)
++{
++	struct hci_h4p_info *info = hdev->driver_data;
++
++	if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
++		return 0;
++
++	hci_h4p_hci_flush(hdev);
++	del_timer_sync(&info->tx_pm_timer);
++	del_timer_sync(&info->rx_pm_timer);
++	tasklet_disable(&info->tx_task);
++	tasklet_disable(&info->rx_task);
++	hci_h4p_set_clk(info, &info->tx_clocks_en, 1);
++	hci_h4p_set_clk(info, &info->rx_clocks_en, 1);
++	hci_h4p_reset_uart(info);
++	hci_h4p_set_clk(info, &info->tx_clocks_en, 0);
++	hci_h4p_set_clk(info, &info->rx_clocks_en, 0);
++	gpio_set_value(info->reset_gpio, 0);
++	gpio_set_value(info->bt_wakeup_gpio, 0);
++	kfree_skb(info->rx_skb);
++
++	return 0;
++}
++
++static void hci_h4p_hci_destruct(struct hci_dev *hdev)
++{
++}
++
++static int hci_h4p_hci_send_frame(struct sk_buff *skb)
++{
++	struct hci_h4p_info *info;
++	struct hci_dev *hdev = (struct hci_dev *)skb->dev;
++	int err = 0;
++
++	if (!hdev) {
++		printk(KERN_WARNING "hci_h4p: Frame for unknown device\n");
++		return -ENODEV;
++	}
++
++	NBT_DBG("dev %p, skb %p\n", hdev, skb);
++
++	info = hdev->driver_data;
++
++	if (!test_bit(HCI_RUNNING, &hdev->flags)) {
++		dev_warn(info->dev, "Frame for non-running device\n");
++		return -EIO;
++	}
++
++	switch (bt_cb(skb)->pkt_type) {
++	case HCI_COMMAND_PKT:
++		hdev->stat.cmd_tx++;
++		break;
++	case HCI_ACLDATA_PKT:
++		hdev->stat.acl_tx++;
++		break;
++	case HCI_SCODATA_PKT:
++		hdev->stat.sco_tx++;
++		break;
++	}
++
++	/* Push frame type to skb */
++	*skb_push(skb, 1) = (bt_cb(skb)->pkt_type);
++	/* We should allways send word aligned data to h4+ devices */
++	if (skb->len % 2) {
++		err = skb_pad(skb, 1);
++	}
++	if (err)
++		return err;
++
++	hci_h4p_enable_tx(info);
++	skb_queue_tail(&info->txq, skb);
++	tasklet_schedule(&info->tx_task);
++
++	return 0;
++}
++
++static int hci_h4p_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
++{
++	return -ENOIOCTLCMD;
++}
++
++static int hci_h4p_register_hdev(struct hci_h4p_info *info)
++{
++	struct hci_dev *hdev;
++
++	/* Initialize and register HCI device */
++
++	hdev = hci_alloc_dev();
++	if (!hdev) {
++		dev_err(info->dev, "Can't allocate memory for device\n");
++		return -ENOMEM;
++	}
++	info->hdev = hdev;
++
++	hdev->type = HCI_UART;
++	hdev->driver_data = info;
++
++	hdev->open = hci_h4p_hci_open;
++	hdev->close = hci_h4p_hci_close;
++	hdev->flush = hci_h4p_hci_flush;
++	hdev->send = hci_h4p_hci_send_frame;
++	hdev->destruct = hci_h4p_hci_destruct;
++	hdev->ioctl = hci_h4p_hci_ioctl;
++
++	hdev->owner = THIS_MODULE;
++
++	if (hci_register_dev(hdev) < 0) {
++		dev_err(info->dev, "hci_h4p: Can't register HCI device %s.\n", hdev->name);
++		return -ENODEV;
++	}
++
++	return 0;
++}
++
++static int hci_h4p_probe(struct platform_device *pdev)
++{
++	struct omap_bluetooth_config *bt_config;
++	struct hci_h4p_info *info;
++	int irq, err;
++
++	dev_info(&pdev->dev, "Registering HCI H4P device\n");
++	info = kzalloc(sizeof(struct hci_h4p_info), GFP_KERNEL);
++	if (!info)
++		return -ENOMEM;
++
++	info->dev = &pdev->dev;
++	info->pm_enabled = 0;
++	info->tx_pm_enabled = 0;
++	info->rx_pm_enabled = 0;
++	info->garbage_bytes = 0;
++	info->tx_clocks_en = 0;
++	info->rx_clocks_en = 0;
++	tasklet_init(&info->tx_task, hci_h4p_tx_tasklet, (unsigned long)info);
++	tasklet_init(&info->rx_task, hci_h4p_rx_tasklet, (unsigned long)info);
++	/* hci_h4p_hci_open assumes that tasklet is disabled in startup */
++	tasklet_disable(&info->tx_task);
++	tasklet_disable(&info->rx_task);
++	spin_lock_init(&info->lock);
++	spin_lock_init(&info->clocks_lock);
++	skb_queue_head_init(&info->txq);
++	init_timer(&info->tx_pm_timer);
++	info->tx_pm_timer.function = hci_h4p_tx_pm_timer;
++	info->tx_pm_timer.data = (unsigned long)info;
++	init_timer(&info->rx_pm_timer);
++	info->rx_pm_timer.function = hci_h4p_rx_pm_timer;
++	info->rx_pm_timer.data = (unsigned long)info;
++
++	if (pdev->dev.platform_data == NULL) {
++		dev_err(&pdev->dev, "Could not get Bluetooth config data\n");
++		return -ENODATA;
++	}
++
++	bt_config = pdev->dev.platform_data;
++	info->chip_type = bt_config->chip_type;
++	info->bt_wakeup_gpio = bt_config->bt_wakeup_gpio;
++	info->host_wakeup_gpio = bt_config->host_wakeup_gpio;
++	info->reset_gpio = bt_config->reset_gpio;
++	info->bt_sysclk = bt_config->bt_sysclk;
++
++	NBT_DBG("RESET gpio: %d\n", info->reset_gpio);
++	NBT_DBG("BTWU gpio: %d\n", info->bt_wakeup_gpio);
++	NBT_DBG("HOSTWU gpio: %d\n", info->host_wakeup_gpio);
++	NBT_DBG("Uart: %d\n", bt_config->bt_uart);
++	NBT_DBG("sysclk: %d\n", info->bt_sysclk);
++
++	err = gpio_request(info->reset_gpio, "BT reset");
++	if (err < 0) {
++		dev_err(&pdev->dev, "Cannot get GPIO line %d\n",
++			info->reset_gpio);
++		kfree(info);
++		goto cleanup;
++	}
++
++	err = gpio_request(info->bt_wakeup_gpio, "BT wakeup");
++	if (err < 0)
++	{
++		dev_err(info->dev, "Cannot get GPIO line 0x%d",
++			info->bt_wakeup_gpio);
++		gpio_free(info->reset_gpio);
++		kfree(info);
++		goto cleanup;
++	}
++
++	err = gpio_request(info->host_wakeup_gpio, "BT host wakeup");
++	if (err < 0)
++	{
++		dev_err(info->dev, "Cannot get GPIO line %d",
++		       info->host_wakeup_gpio);
++		gpio_free(info->reset_gpio);
++		gpio_free(info->bt_wakeup_gpio);
++		kfree(info);
++		goto cleanup;
++	}
++
++	gpio_direction_output(info->reset_gpio, 0);
++	gpio_direction_output(info->bt_wakeup_gpio, 0);
++	gpio_direction_input(info->host_wakeup_gpio);
++
++	switch (bt_config->bt_uart) {
++	case 1:
++		if (cpu_is_omap16xx()) {
++			irq = INT_UART1;
++			info->uart_fclk = clk_get(NULL, "uart1_ck");
++		} else if (cpu_is_omap24xx()) {
++			irq = INT_24XX_UART1_IRQ;
++			info->uart_iclk = clk_get(NULL, "uart1_ick");
++			info->uart_fclk = clk_get(NULL, "uart1_fck");
++		}
++		/* FIXME: Use platform_get_resource for the port */
++		info->uart_base = ioremap(OMAP_UART1_BASE, 0x16);
++		if (!info->uart_base)
++			goto cleanup;
++		break;
++	case 2:
++		if (cpu_is_omap16xx()) {
++			irq = INT_UART2;
++			info->uart_fclk = clk_get(NULL, "uart2_ck");
++		} else {
++			irq = INT_24XX_UART2_IRQ;
++			info->uart_iclk = clk_get(NULL, "uart2_ick");
++			info->uart_fclk = clk_get(NULL, "uart2_fck");
++		}
++		/* FIXME: Use platform_get_resource for the port */
++		info->uart_base = ioremap(OMAP_UART2_BASE, 0x16);
++		if (!info->uart_base)
++			goto cleanup;
++		break;
++	case 3:
++		if (cpu_is_omap16xx()) {
++			irq = INT_UART3;
++			info->uart_fclk = clk_get(NULL, "uart3_ck");
++		} else {
++			irq = INT_24XX_UART3_IRQ;
++			info->uart_iclk = clk_get(NULL, "uart3_ick");
++			info->uart_fclk = clk_get(NULL, "uart3_fck");
++		}
++		/* FIXME: Use platform_get_resource for the port */
++		info->uart_base = ioremap(OMAP_UART3_BASE, 0x16);
++		if (!info->uart_base)
++			goto cleanup;
++		break;
++	default:
++		dev_err(info->dev, "No uart defined\n");
++		goto cleanup;
++	}
++
++	info->irq = irq;
++	err = request_irq(irq, hci_h4p_interrupt, 0, "hci_h4p", (void *)info);
++	if (err < 0) {
++		dev_err(info->dev, "hci_h4p: unable to get IRQ %d\n", irq);
++		goto cleanup;
++	}
++
++	err = request_irq(gpio_to_irq(info->host_wakeup_gpio),
++			  hci_h4p_wakeup_interrupt,
++				IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
++			  "hci_h4p_wkup", (void *)info);
++	if (err < 0) {
++		dev_err(info->dev, "hci_h4p: unable to get wakeup IRQ %d\n",
++			  gpio_to_irq(info->host_wakeup_gpio));
++		free_irq(irq, (void *)info);
++		goto cleanup;
++	}
++
++	hci_h4p_set_clk(info, &info->tx_clocks_en, 1);
++	hci_h4p_set_auto_ctsrts(info, 0, UART_EFR_CTS | UART_EFR_RTS);
++	err = hci_h4p_init_uart(info);
++	if (err < 0)
++		goto cleanup_irq;
++	err = hci_h4p_reset(info);
++	if (err < 0)
++		goto cleanup_irq;
++	err = hci_h4p_wait_for_cts(info, 1, 10);
++	if (err < 0)
++		goto cleanup_irq;
++	hci_h4p_set_clk(info, &info->tx_clocks_en, 0);
++
++	platform_set_drvdata(pdev, info);
++	err = hci_h4p_sysfs_create_files(info->dev);
++	if (err < 0)
++		goto cleanup_irq;
++
++	if (hci_h4p_register_hdev(info) < 0) {
++		dev_err(info->dev, "failed to register hci_h4p hci device\n");
++		goto cleanup_irq;
++	}
++	gpio_set_value(info->reset_gpio, 0);
++
++	return 0;
++
++cleanup_irq:
++	free_irq(irq, (void *)info);
++	free_irq(gpio_to_irq(info->host_wakeup_gpio), (void *)info);
++cleanup:
++	gpio_set_value(info->reset_gpio, 0);
++	gpio_free(info->reset_gpio);
++	gpio_free(info->bt_wakeup_gpio);
++	gpio_free(info->host_wakeup_gpio);
++	kfree(info);
++
++	return err;
++
++}
++
++static int hci_h4p_remove(struct platform_device *dev)
++{
++	struct hci_h4p_info *info;
++
++	info = platform_get_drvdata(dev);
++
++	hci_h4p_hci_close(info->hdev);
++	free_irq(gpio_to_irq(info->host_wakeup_gpio), (void *) info);
++	hci_free_dev(info->hdev);
++	gpio_free(info->reset_gpio);
++	gpio_free(info->bt_wakeup_gpio);
++	gpio_free(info->host_wakeup_gpio);
++	free_irq(info->irq, (void *) info);
++	kfree(info);
++
++	return 0;
++}
++
++static struct platform_driver hci_h4p_driver = {
++	.probe		= hci_h4p_probe,
++	.remove		= hci_h4p_remove,
++	.driver		= {
++		.name	= "hci_h4p",
++	},
++};
++
++static int __init hci_h4p_init(void)
++{
++	int err = 0;
++
++	/* Register the driver with LDM */
++	err = platform_driver_register(&hci_h4p_driver);
++	if (err < 0)
++		printk(KERN_WARNING "failed to register hci_h4p driver\n");
++
++	return err;
++}
++
++static void __exit hci_h4p_exit(void)
++{
++	platform_driver_unregister(&hci_h4p_driver);
++}
++
++module_init(hci_h4p_init);
++module_exit(hci_h4p_exit);
++
++MODULE_DESCRIPTION("h4 driver with nokia extensions");
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Ville Tervo");
+Index: linux-2.6.35/drivers/bluetooth/hci_h4p/fw.c
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/drivers/bluetooth/hci_h4p/fw.c	2010-08-08 12:57:24.000000000 +0200
+@@ -0,0 +1,155 @@
++/*
++ * This file is part of hci_h4p bluetooth driver
++ *
++ * Copyright (C) 2005, 2006 Nokia Corporation.
++ *
++ * Contact: Ville Tervo <[email protected]>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * version 2 as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
++ * 02110-1301 USA
++ *
++ */
++
++#include <linux/skbuff.h>
++#include <linux/firmware.h>
++#include <linux/clk.h>
++
++#include <net/bluetooth/bluetooth.h>
++
++#include "hci_h4p.h"
++
++#define BT_CHIP_TI	2
++#define BT_CHIP_CSR	1
++
++static int fw_pos;
++
++/* Firmware handling */
++static int hci_h4p_open_firmware(struct hci_h4p_info *info,
++				 const struct firmware **fw_entry)
++{
++	int err;
++
++	fw_pos = 0;
++	NBT_DBG_FW("Opening %d firmware\n", info->chip_type);
++	switch (info->chip_type) {
++	case BT_CHIP_TI:
++		err = request_firmware(fw_entry, "brf6150fw.bin", info->dev);
++		break;
++	case BT_CHIP_CSR:
++		err = request_firmware(fw_entry, "bc4fw.bin", info->dev);
++		break;
++	default:
++		dev_err(info->dev, "Invalid chip type\n");
++		*fw_entry = NULL;
++		err = -EINVAL;
++	}
++
++	return err;
++}
++
++static void hci_h4p_close_firmware(const struct firmware *fw_entry)
++{
++	release_firmware(fw_entry);
++}
++
++/* Read fw. Return length of the command. If no more commands in
++ * fw 0 is returned. In error case return value is negative.
++ */
++static int hci_h4p_read_fw_cmd(struct hci_h4p_info *info, struct sk_buff **skb,
++			       const struct firmware *fw_entry, int how)
++{
++	unsigned int cmd_len;
++
++	if (fw_pos >= fw_entry->size) {
++		return 0;
++	}
++
++	cmd_len = fw_entry->data[fw_pos++];
++	if (!cmd_len)
++		return 0;
++
++	if (fw_pos + cmd_len > fw_entry->size) {
++		dev_err(info->dev, "Corrupted firmware image\n");
++		return -EMSGSIZE;
++	}
++
++	*skb = bt_skb_alloc(cmd_len, how);
++	if (!*skb) {
++		dev_err(info->dev, "Cannot reserve memory for buffer\n");
++		return -ENOMEM;
++	}
++	memcpy(skb_put(*skb, cmd_len), &fw_entry->data[fw_pos], cmd_len);
++
++	fw_pos += cmd_len;
++
++	return (*skb)->len;
++}
++
++int hci_h4p_read_fw(struct hci_h4p_info *info, struct sk_buff_head *fw_queue)
++{
++	const struct firmware *fw_entry = NULL;
++	struct sk_buff *skb = NULL;
++	int err;
++
++	err = hci_h4p_open_firmware(info, &fw_entry);
++	if (err < 0 || !fw_entry)
++		goto err_clean;
++
++	while ((err = hci_h4p_read_fw_cmd(info, &skb, fw_entry, GFP_KERNEL))) {
++		if (err < 0 || !skb)
++			goto err_clean;
++
++		skb_queue_tail(fw_queue, skb);
++	}
++
++err_clean:
++	hci_h4p_close_firmware(fw_entry);
++	return err;
++}
++
++int hci_h4p_send_fw(struct hci_h4p_info *info, struct sk_buff_head *fw_queue)
++{
++	int err;
++
++	switch(info->chip_type) {
++	case BT_CHIP_CSR:
++		err = hci_h4p_bc4_send_fw(info, fw_queue);
++		break;
++	case BT_CHIP_TI:
++		err = hci_h4p_brf6150_send_fw(info, fw_queue);
++		break;
++	default:
++		dev_err(info->dev, "Don't know how to send firmware\n");
++		err = -EINVAL;
++	}
++
++	return err;
++}
++
++void hci_h4p_parse_fw_event(struct hci_h4p_info *info, struct sk_buff *skb)
++{
++	switch (info->chip_type) {
++	case BT_CHIP_CSR:
++		hci_h4p_bc4_parse_fw_event(info, skb);
++		break;
++	case BT_CHIP_TI:
++		hci_h4p_brf6150_parse_fw_event(info, skb);
++		break;
++	default:
++		dev_err(info->dev, "Don't know how to parse fw event\n");
++		info->fw_error = -EINVAL;
++	}
++
++	return;
++}
+Index: linux-2.6.35/drivers/bluetooth/hci_h4p/fw-csr.c
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/drivers/bluetooth/hci_h4p/fw-csr.c	2010-08-08 12:57:25.000000000 +0200
+@@ -0,0 +1,149 @@
++/*
++ * This file is part of hci_h4p bluetooth driver
++ *
++ * Copyright (C) 2005, 2006 Nokia Corporation.
++ *
++ * Contact: Ville Tervo <[email protected]>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * version 2 as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
++ * 02110-1301 USA
++ *
++ */
++
++#include <linux/skbuff.h>
++#include <linux/delay.h>
++#include <linux/serial_reg.h>
++
++#include "hci_h4p.h"
++
++void hci_h4p_bc4_parse_fw_event(struct hci_h4p_info *info, struct sk_buff *skb)
++{
++	/* Check if this is fw packet */
++	if (skb->data[0] != 0xff) {
++		hci_recv_frame(skb);
++		return;
++	}
++
++	if (skb->data[11] || skb->data[12]) {
++		dev_err(info->dev, "Firmware sending command failed\n");
++		info->fw_error = -EPROTO;
++	}
++
++	kfree_skb(skb);
++	complete(&info->fw_completion);
++}
++
++int hci_h4p_bc4_send_fw(struct hci_h4p_info *info,
++			struct sk_buff_head *fw_queue)
++{
++	struct sk_buff *skb;
++	unsigned int offset;
++	int retries, count, i;
++
++	info->fw_error = 0;
++
++	NBT_DBG_FW("Sending firmware\n");
++	skb = skb_dequeue(fw_queue);
++
++	if (!skb)
++		return -ENOMSG;
++
++	info->bdaddr[0] = 0x00;
++	info->bdaddr[1] = 0x1D;
++	info->bdaddr[2] = 0x6E;
++	info->bdaddr[3] = 0xD4;
++	info->bdaddr[4] = 0xF0;
++	info->bdaddr[5] = 0x37;
++
++	/* Check if this is bd_address packet */
++	if (skb->data[15] == 0x01 && skb->data[16] == 0x00) {
++		dev_info(info->dev, "bd_address packet found\n");
++		offset = 21;
++		skb->data[offset + 1] = 0x00;
++		skb->data[offset + 5] = 0x00;
++		skb->data[offset + 7] = info->bdaddr[0];
++		skb->data[offset + 6] = info->bdaddr[1];
++		skb->data[offset + 4] = info->bdaddr[2];
++		skb->data[offset + 0] = info->bdaddr[3];
++		skb->data[offset + 3] = info->bdaddr[4];
++		skb->data[offset + 2] = info->bdaddr[5];
++	}
++
++	for (i = 0; i < 6; i++) {
++		if (info->bdaddr[i] != 0x00)
++			break;
++	}
++
++	/* if (i > 5) {
++		dev_info(info->dev, "Valid bluetooth address not found.\n");
++		kfree_skb(skb);
++		return -ENODEV;
++	} */
++
++	for (count = 1; ; count++) {
++		NBT_DBG_FW("Sending firmware command %d\n", count);
++		init_completion(&info->fw_completion);
++		skb_queue_tail(&info->txq, skb);
++		tasklet_schedule(&info->tx_task);
++
++		skb = skb_dequeue(fw_queue);
++		if (!skb)
++			break;
++
++		if (!wait_for_completion_timeout(&info->fw_completion,
++						 msecs_to_jiffies(1000))) {
++			dev_err(info->dev, "No reply to fw command\n");
++			return -ETIMEDOUT;
++		}
++
++		if (info->fw_error) {
++			dev_err(info->dev, "FW error\n");
++			return -EPROTO;
++		}
++	};
++
++	/* Wait for chip warm reset */
++	retries = 100;
++	while ((!skb_queue_empty(&info->txq) ||
++	       !(hci_h4p_inb(info, UART_LSR) & UART_LSR_TEMT)) &&
++	       retries--) {
++		msleep(10);
++	}
++	if (!retries) {
++		dev_err(info->dev, "Transmitter not empty\n");
++		return -ETIMEDOUT;
++	}
++
++	hci_h4p_change_speed(info, BC4_MAX_BAUD_RATE);
++
++	if (hci_h4p_wait_for_cts(info, 1, 100)) {
++		dev_err(info->dev, "cts didn't go down after final speed change\n");
++		return -ETIMEDOUT;
++	}
++
++	retries = 100;
++	do {
++		init_completion(&info->init_completion);
++		hci_h4p_send_alive_packet(info);
++		retries--;
++	} while (!wait_for_completion_timeout(&info->init_completion, 100) &&
++		 retries > 0);
++
++	if (!retries) {
++		dev_err(info->dev, "No alive reply after speed change\n");
++		return -ETIMEDOUT;
++	}
++
++	return 0;
++}
+Index: linux-2.6.35/drivers/bluetooth/hci_h4p/fw-ti.c
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/drivers/bluetooth/hci_h4p/fw-ti.c	2010-08-08 12:57:26.000000000 +0200
+@@ -0,0 +1,90 @@
++/*
++ * This file is part of hci_h4p bluetooth driver
++ *
++ * Copyright (C) 2005, 2006 Nokia Corporation.
++ *
++ * Contact: Ville Tervo <[email protected]>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * version 2 as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
++ * 02110-1301 USA
++ *
++ */
++
++#include <linux/skbuff.h>
++
++#include "hci_h4p.h"
++
++void hci_h4p_brf6150_parse_fw_event(struct hci_h4p_info *info,
++				    struct sk_buff *skb)
++{
++	struct hci_fw_event *ev;
++	int err = 0;
++
++	if (bt_cb(skb)->pkt_type != H4_EVT_PKT) {
++		dev_err(info->dev, "Got non event fw packet.\n");
++		err = -EPROTO;
++		goto ret;
++	}
++
++	ev = (struct hci_fw_event *)skb->data;
++	if (ev->hev.evt != HCI_EV_CMD_COMPLETE) {
++		dev_err(info->dev, "Got non cmd complete fw event\n");
++		err = -EPROTO;
++		goto ret;
++	}
++
++	if (ev->status != 0) {
++		dev_err(info->dev, "Got error status from fw command\n");
++		err = -EPROTO;
++		goto ret;
++	}
++
++ret:
++	info->fw_error = err;
++	complete(&info->fw_completion);
++}
++
++int hci_h4p_brf6150_send_fw(struct hci_h4p_info *info, struct sk_buff_head *fw_queue)
++{
++	struct sk_buff *skb;
++	int err = 0;
++
++	info->fw_error = 0;
++
++	while ((skb = skb_dequeue(fw_queue)) != NULL) {
++		/* We should allways send word aligned data to h4+ devices */
++		if (skb->len % 2) {
++			err = skb_pad(skb, 1);
++		}
++		if (err)
++			return err;
++
++		init_completion(&info->fw_completion);
++		skb_queue_tail(&info->txq, skb);
++		tasklet_schedule(&info->tx_task);
++
++		if (!wait_for_completion_timeout(&info->fw_completion, HZ)) {
++			dev_err(info->dev, "Timeout while sending brf6150 fw\n");
++			return -ETIMEDOUT;
++		}
++
++		if (info->fw_error) {
++			dev_err(info->dev, "There was fw_error while sending bfr6150 fw\n");
++			return -EPROTO;
++		}
++	}
++	NBT_DBG_FW("Firmware sent\n");
++
++	return 0;
++}
+Index: linux-2.6.35/drivers/bluetooth/hci_h4p/hci_h4p.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/drivers/bluetooth/hci_h4p/hci_h4p.h	2010-08-08 12:57:26.000000000 +0200
+@@ -0,0 +1,183 @@
++/*
++ * This file is part of hci_h4p bluetooth driver
++ *
++ * Copyright (C) 2005, 2006 Nokia Corporation.
++ *
++ * Contact: Ville Tervo <[email protected]>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * version 2 as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
++ * 02110-1301 USA
++ *
++ */
++
++#include <mach/board.h>
++
++#include <net/bluetooth/bluetooth.h>
++#include <net/bluetooth/hci_core.h>
++#include <net/bluetooth/hci.h>
++
++#ifndef __DRIVERS_BLUETOOTH_HCI_H4P_H
++#define __DRIVERS_BLUETOOTH_HCI_H4P_H
++
++#define UART_SYSC_OMAP_RESET	0x03
++#define UART_SYSS_RESETDONE	0x01
++#define UART_OMAP_SCR_EMPTY_THR	0x08
++#define UART_OMAP_SCR_WAKEUP	0x10
++#define UART_OMAP_SSR_WAKEUP	0x02
++#define UART_OMAP_SSR_TXFULL	0x01
++
++#if 0
++#define NBT_DBG(fmt, arg...)  printk("%s: " fmt "" , __FUNCTION__ , ## arg)
++#else
++#define NBT_DBG(...)
++#endif
++
++#if 0
++#define NBT_DBG_FW(fmt, arg...)  printk("%s: " fmt "" , __FUNCTION__ , ## arg)
++#else
++#define NBT_DBG_FW(...)
++#endif
++
++#if 0
++#define NBT_DBG_POWER(fmt, arg...)  printk("%s: " fmt "" , __FUNCTION__ , ## arg)
++#else
++#define NBT_DBG_POWER(...)
++#endif
++
++#if 0
++#define NBT_DBG_TRANSFER(fmt, arg...)  printk("%s: " fmt "" , __FUNCTION__ , ## arg)
++#else
++#define NBT_DBG_TRANSFER(...)
++#endif
++
++#if 0
++#define NBT_DBG_TRANSFER_NF(fmt, arg...)  printk(fmt "" , ## arg)
++#else
++#define NBT_DBG_TRANSFER_NF(...)
++#endif
++
++#if 0
++#define NBT_DBG_DMA(fmt, arg...)  printk("%s: " fmt "" , __FUNCTION__ , ## arg)
++#else
++#define NBT_DBG_DMA(...)
++#endif
++
++struct hci_h4p_info {
++	struct hci_dev *hdev;
++	spinlock_t lock;
++
++	void __iomem *uart_base;
++	unsigned long uart_phys_base;
++	int irq;
++	struct device *dev;
++	u8 bdaddr[6];
++	u8 chip_type;
++	u8 bt_wakeup_gpio;
++	u8 host_wakeup_gpio;
++	u8 reset_gpio;
++	u8 bt_sysclk;
++
++
++	struct sk_buff_head fw_queue;
++	struct sk_buff *alive_cmd_skb;
++	struct completion init_completion;
++	struct completion fw_completion;
++	int fw_error;
++	int init_error;
++
++	struct sk_buff_head txq;
++	struct tasklet_struct tx_task;
++
++	struct sk_buff *rx_skb;
++	long rx_count;
++	unsigned long rx_state;
++	unsigned long garbage_bytes;
++	struct tasklet_struct rx_task;
++
++	int pm_enabled;
++	int tx_pm_enabled;
++	int rx_pm_enabled;
++	struct timer_list tx_pm_timer;
++	struct timer_list rx_pm_timer;
++
++	int tx_clocks_en;
++	int rx_clocks_en;
++	spinlock_t clocks_lock;
++	struct clk *uart_iclk;
++	struct clk *uart_fclk;
++};
++
++#define MAX_BAUD_RATE		921600
++#define BC4_MAX_BAUD_RATE	3692300
++#define UART_CLOCK		48000000
++#define BT_INIT_DIVIDER		320
++#define BT_BAUDRATE_DIVIDER	384000000
++#define BT_SYSCLK_DIV		1000
++#define INIT_SPEED		120000
++
++#define H4_TYPE_SIZE		1
++
++/* H4+ packet types */
++#define H4_CMD_PKT		0x01
++#define H4_ACL_PKT		0x02
++#define H4_SCO_PKT		0x03
++#define H4_EVT_PKT		0x04
++#define H4_NEG_PKT		0x06
++#define H4_ALIVE_PKT		0x07
++
++/* TX states */
++#define WAIT_FOR_PKT_TYPE	1
++#define WAIT_FOR_HEADER		2
++#define WAIT_FOR_DATA		3
++
++struct hci_fw_event {
++	struct hci_event_hdr hev;
++	struct hci_ev_cmd_complete cmd;
++	u8 status;
++} __attribute__ ((packed));
++
++struct hci_bc4_set_bdaddr {
++	u8 type;
++	struct hci_command_hdr cmd_hdr;
++} __attribute__ ((packed));
++
++int hci_h4p_send_alive_packet(struct hci_h4p_info *info);
++
++void hci_h4p_bc4_parse_fw_event(struct hci_h4p_info *info,
++				struct sk_buff *skb);
++int hci_h4p_bc4_send_fw(struct hci_h4p_info *info,
++			struct sk_buff_head *fw_queue);
++
++void hci_h4p_brf6150_parse_fw_event(struct hci_h4p_info *info,
++				    struct sk_buff *skb);
++int hci_h4p_brf6150_send_fw(struct hci_h4p_info *info,
++			    struct sk_buff_head *fw_queue);
++
++int hci_h4p_read_fw(struct hci_h4p_info *info, struct sk_buff_head *fw_queue);
++int hci_h4p_send_fw(struct hci_h4p_info *info, struct sk_buff_head *fw_queue);
++void hci_h4p_parse_fw_event(struct hci_h4p_info *info, struct sk_buff *skb);
++
++int hci_h4p_sysfs_create_files(struct device *dev);
++
++void hci_h4p_outb(struct hci_h4p_info *info, unsigned int offset, u8 val);
++u8 hci_h4p_inb(struct hci_h4p_info *info, unsigned int offset);
++void hci_h4p_set_rts(struct hci_h4p_info *info, int active);
++int hci_h4p_wait_for_cts(struct hci_h4p_info *info, int active, int timeout_ms);
++void __hci_h4p_set_auto_ctsrts(struct hci_h4p_info *info, int on, u8 which);
++void hci_h4p_set_auto_ctsrts(struct hci_h4p_info *info, int on, u8 which);
++void hci_h4p_change_speed(struct hci_h4p_info *info, unsigned long speed);
++int hci_h4p_reset_uart(struct hci_h4p_info *info);
++int hci_h4p_init_uart(struct hci_h4p_info *info);
++
++#endif /* __DRIVERS_BLUETOOTH_HCI_H4P_H */
+Index: linux-2.6.35/drivers/bluetooth/hci_h4p/Makefile
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/drivers/bluetooth/hci_h4p/Makefile	2010-08-08 12:57:27.000000000 +0200
+@@ -0,0 +1,7 @@
++#
++# Makefile for the Linux Bluetooth HCI device drivers.
++#
++
++obj-$(CONFIG_BT_HCIH4P)		+= hci_h4p.o
++
++hci_h4p-objs := core.o fw.o uart.o sysfs.o fw-ti.o fw-csr.o
+Index: linux-2.6.35/drivers/bluetooth/hci_h4p/sysfs.c
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/drivers/bluetooth/hci_h4p/sysfs.c	2010-08-08 12:57:27.000000000 +0200
+@@ -0,0 +1,84 @@
++/*
++ * This file is part of hci_h4p bluetooth driver
++ *
++ * Copyright (C) 2005, 2006 Nokia Corporation.
++ *
++ * Contact: Ville Tervo <[email protected]>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * version 2 as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
++ * 02110-1301 USA
++ *
++ */
++
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/device.h>
++#include <linux/platform_device.h>
++
++#include "hci_h4p.h"
++
++#ifdef CONFIG_SYSFS
++
++static ssize_t hci_h4p_store_bdaddr(struct device *dev, struct device_attribute *attr,
++				    const char *buf, size_t count)
++{
++	struct hci_h4p_info *info = (struct hci_h4p_info*)dev_get_drvdata(dev);
++	unsigned int bdaddr[6];
++	int ret, i;
++
++	dev_info(info->dev, "HCI_H4P_STORE_BDADDR called\n");
++
++	ret = sscanf(buf, "%2x:%2x:%2x:%2x:%2x:%2x\n",
++			&bdaddr[0], &bdaddr[1], &bdaddr[2],
++			&bdaddr[3], &bdaddr[4], &bdaddr[5]);
++
++	if (ret != 6) {
++		dev_info(info->dev, "bdaddr isn't found\n");
++		return -EINVAL;
++	}
++
++	//for (i = 0; i < 6; i++)
++		//info->bdaddr[i] = bdaddr[i] & 0xff;
++
++	info->bdaddr[0] = 0x00;
++	info->bdaddr[1] = 0x1D;
++	info->bdaddr[2] = 0x6E;
++	info->bdaddr[3] = 0xD4;
++	info->bdaddr[4] = 0xF0;
++	info->bdaddr[5] = 0x37;
++
++	return count;
++}
++
++static ssize_t hci_h4p_show_bdaddr(struct device *dev, struct device_attribute *attr,
++				   char *buf)
++{
++	struct hci_h4p_info *info = (struct hci_h4p_info*)dev_get_drvdata(dev);
++
++	return sprintf(buf, "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
++		       info->bdaddr[0],
++		       info->bdaddr[1],
++		       info->bdaddr[2],
++		       info->bdaddr[3],
++		       info->bdaddr[4],
++		       info->bdaddr[5]);
++}
++
++static DEVICE_ATTR(bdaddr, S_IRUGO | S_IWUSR, hci_h4p_show_bdaddr, hci_h4p_store_bdaddr);
++int hci_h4p_sysfs_create_files(struct device *dev)
++{
++	return device_create_file(dev, &dev_attr_bdaddr);
++}
++
++#endif
+Index: linux-2.6.35/drivers/bluetooth/hci_h4p/uart.c
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.35/drivers/bluetooth/hci_h4p/uart.c	2010-08-08 12:57:28.000000000 +0200
+@@ -0,0 +1,169 @@
++/*
++ * This file is part of hci_h4p bluetooth driver
++ *
++ * Copyright (C) 2005, 2006 Nokia Corporation.
++ *
++ * Contact: Ville Tervo <[email protected]>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * version 2 as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
++ * 02110-1301 USA
++ *
++ */
++
++#include <linux/serial_reg.h>
++#include <linux/delay.h>
++#include <linux/clk.h>
++
++#include <asm/io.h>
++
++#include "hci_h4p.h"
++
++inline void hci_h4p_outb(struct hci_h4p_info *info, unsigned int offset, u8 val)
++{
++	offset <<= 2;
++	__raw_writeb(val, info->uart_base + offset);
++	//outb(val, info->uart_base + (offset << 2));
++}
++
++inline u8 hci_h4p_inb(struct hci_h4p_info *info, unsigned int offset)
++{
++	offset <<= 2;
++	return (u8)__raw_readb(info->uart_base + offset);
++	//return (unsigned int)__raw_readb(up->membase + offset);
++	//return inb(info->uart_base + (offset << 2));
++}
++
++void hci_h4p_set_rts(struct hci_h4p_info *info, int active)
++{
++	u8 b;
++
++	b = hci_h4p_inb(info, UART_MCR);
++	if (active)
++		b |= UART_MCR_RTS;
++	else
++		b &= ~UART_MCR_RTS;
++	hci_h4p_outb(info, UART_MCR, b);
++}
++
++int hci_h4p_wait_for_cts(struct hci_h4p_info *info, int active,
++			 int timeout_ms)
++{
++	int okay;
++	unsigned long timeout;
++
++	okay = 0;
++	timeout = jiffies + msecs_to_jiffies(timeout_ms);
++	for (;;) {
++		int state;
++
++		state = hci_h4p_inb(info, UART_MSR) & UART_MSR_CTS;
++		if (active) {
++			if (state)
++				return 0;
++		} else {
++			if (!state)
++				return 0;
++		}
++		if (time_after(jiffies, timeout))
++			return -ETIMEDOUT;
++	}
++}
++
++void __hci_h4p_set_auto_ctsrts(struct hci_h4p_info *info, int on, u8 which)
++{
++	u8 lcr, b;
++
++	lcr = hci_h4p_inb(info, UART_LCR);
++	hci_h4p_outb(info, UART_LCR, 0xbf);
++	b = hci_h4p_inb(info, UART_EFR);
++	if (on)
++		b |= which;
++	else
++		b &= ~which;
++	hci_h4p_outb(info, UART_EFR, b);
++	hci_h4p_outb(info, UART_LCR, lcr);
++}
++
++void hci_h4p_set_auto_ctsrts(struct hci_h4p_info *info, int on, u8 which)
++{
++	unsigned long flags;
++
++	spin_lock_irqsave(&info->lock, flags);
++	__hci_h4p_set_auto_ctsrts(info, on, which);
++	spin_unlock_irqrestore(&info->lock, flags);
++}
++
++void hci_h4p_change_speed(struct hci_h4p_info *info, unsigned long speed)
++{
++	unsigned int divisor;
++	u8 lcr, mdr1;
++
++	NBT_DBG("Setting speed %lu\n", speed);
++
++	if (speed >= 460800) {
++		divisor = UART_CLOCK / 13 / speed;
++		mdr1 = 3;
++	} else {
++		divisor = UART_CLOCK / 16 / speed;
++		mdr1 = 0;
++	}
++
++	hci_h4p_outb(info, UART_OMAP_MDR1, 7); /* Make sure UART mode is disabled */
++	lcr = hci_h4p_inb(info, UART_LCR);
++	hci_h4p_outb(info, UART_LCR, UART_LCR_DLAB);     /* Set DLAB */
++	hci_h4p_outb(info, UART_DLL, divisor & 0xff);    /* Set speed */
++	hci_h4p_outb(info, UART_DLM, divisor >> 8);
++	hci_h4p_outb(info, UART_LCR, lcr);
++	hci_h4p_outb(info, UART_OMAP_MDR1, mdr1); /* Make sure UART mode is enabled */
++}
++
++int hci_h4p_reset_uart(struct hci_h4p_info *info)
++{
++	int count = 0;
++
++	/* Reset the  UART */
++	hci_h4p_outb(info, UART_OMAP_SYSC, UART_SYSC_OMAP_RESET);
++	while (!(hci_h4p_inb(info, UART_OMAP_SYSS) & UART_SYSS_RESETDONE)) {
++		if (count++ > 20000) {
++			dev_err(info->dev, "hci_h4p: UART reset timeout\n");
++			return -ENODEV;
++		}
++		udelay(1);
++	}
++
++	return 0;
++}
++
++int hci_h4p_init_uart(struct hci_h4p_info *info)
++{
++	int err;
++
++	err = hci_h4p_reset_uart(info);
++	if (err < 0)
++		return err;
++
++	/* Enable and setup FIFO */
++	hci_h4p_outb(info, UART_LCR, UART_LCR_WLEN8);
++	hci_h4p_outb(info, UART_OMAP_MDR1, 0x00); /* Make sure UART mode is enabled */
++	hci_h4p_outb(info, UART_OMAP_SCR, 0x80);
++	hci_h4p_outb(info, UART_EFR, UART_EFR_ECB);
++	hci_h4p_outb(info, UART_MCR, UART_MCR_TCRTLR);
++	hci_h4p_outb(info, UART_TI752_TLR, 0x1f);
++	hci_h4p_outb(info, UART_TI752_TCR, 0xef);
++	hci_h4p_outb(info, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR |
++		     UART_FCR_CLEAR_XMIT | UART_FCR_R_TRIG_00);
++	hci_h4p_outb(info, UART_IER, UART_IER_RDI);
++
++	return 0;
++}
+Index: linux-2.6.35/drivers/bluetooth/Kconfig
+===================================================================
+--- linux-2.6.35.orig/drivers/bluetooth/Kconfig	2010-08-08 12:56:10.000000000 +0200
++++ linux-2.6.35/drivers/bluetooth/Kconfig	2010-08-08 12:57:29.000000000 +0200
+@@ -161,6 +161,16 @@ config BT_HCIBTUART
+ 	  Say Y here to compile support for HCI UART devices into the
+ 	  kernel or say M to compile it as module (btuart_cs).
+ 
++config BT_HCIH4P
++	tristate "HCI driver with H4 Nokia extensions"
++	depends on BT && ARCH_OMAP
++	help
++	  Bluetooth HCI driver with H4 extensions.  This driver provides
++	  support for H4+ Bluetooth chip with vendor-specific H4 extensions.
++
++	  Say Y here to compile support for h4 extended devices into the kernel
++	  or say M to compile it as module (hci_h4p).
++
+ config BT_HCIVHCI
+ 	tristate "HCI VHCI (Virtual HCI device) driver"
+ 	help
+Index: linux-2.6.35/drivers/bluetooth/Makefile
+===================================================================
+--- linux-2.6.35.orig/drivers/bluetooth/Makefile	2010-08-08 12:56:10.000000000 +0200
++++ linux-2.6.35/drivers/bluetooth/Makefile	2010-08-08 12:57:29.000000000 +0200
+@@ -11,6 +11,7 @@ obj-$(CONFIG_BT_HCIDTL1)	+= dtl1_cs.o
+ obj-$(CONFIG_BT_HCIBT3C)	+= bt3c_cs.o
+ obj-$(CONFIG_BT_HCIBLUECARD)	+= bluecard_cs.o
+ obj-$(CONFIG_BT_HCIBTUART)	+= btuart_cs.o
++obj-$(CONFIG_BT_HCIH4P)		+= hci_h4p/
+ 
+ obj-$(CONFIG_BT_HCIBTUSB)	+= btusb.o
+ obj-$(CONFIG_BT_HCIBTSDIO)	+= btsdio.o

+ 4612 - 0
target/linux/omap24xx/patches-2.6.35/500-cbus.patch

@@ -0,0 +1,4612 @@
+---
+ arch/arm/Kconfig               |    4 
+ drivers/Makefile               |    2 
+ drivers/cbus/Kconfig           |   89 ++++
+ drivers/cbus/Makefile          |   14 
+ drivers/cbus/cbus.c            |  309 ++++++++++++++++
+ drivers/cbus/cbus.h            |   36 +
+ drivers/cbus/retu-headset.c    |  355 ++++++++++++++++++
+ drivers/cbus/retu-pwrbutton.c  |  118 ++++++
+ drivers/cbus/retu-rtc.c        |  477 +++++++++++++++++++++++++
+ drivers/cbus/retu-user.c       |  425 ++++++++++++++++++++++
+ drivers/cbus/retu-wdt.c        |  388 ++++++++++++++++++++
+ drivers/cbus/retu.c            |  468 ++++++++++++++++++++++++
+ drivers/cbus/retu.h            |   77 ++++
+ drivers/cbus/tahvo-usb.c       |  777 +++++++++++++++++++++++++++++++++++++++++
+ drivers/cbus/tahvo-user.c      |  407 +++++++++++++++++++++
+ drivers/cbus/tahvo.c           |  443 +++++++++++++++++++++++
+ drivers/cbus/tahvo.h           |   61 +++
+ drivers/cbus/user_retu_tahvo.h |   75 +++
+ 18 files changed, 4524 insertions(+), 1 deletion(-)
+
+--- /dev/null
++++ linux-2.6.35/drivers/cbus/cbus.c
+@@ -0,0 +1,309 @@
++/*
++ * drivers/cbus/cbus.c
++ *
++ * Support functions for CBUS serial protocol
++ *
++ * Copyright (C) 2004, 2005 Nokia Corporation
++ *
++ * Written by Juha Yrjölä <[email protected]>,
++ *	      David Weinehall <[email protected]>, and
++ *	      Mikko Ylinen <[email protected]>
++ *
++ * 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.
++ *
++ * 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/device.h>
++#include <linux/init.h>
++#include <linux/kernel.h>
++#include <linux/delay.h>
++#include <linux/spinlock.h>
++#include <linux/gpio.h>
++#include <linux/platform_device.h>
++#include <linux/slab.h>
++
++#include <asm/io.h>
++#include <asm/mach-types.h>
++
++#include <plat/board.h>
++#include <plat/cbus.h>
++
++#include "cbus.h"
++
++struct cbus_host *cbus_host = NULL;
++EXPORT_SYMBOL(cbus_host);
++
++#ifdef CONFIG_ARCH_OMAP1
++/* We use our own MPUIO functions to get closer to 1MHz bus speed */
++
++static inline void cbus_set_gpio_direction(u32 base, int mpuio, int is_input)
++{
++	u16 w;
++
++	mpuio &= 0x0f;
++	w = __raw_readw(base + OMAP_MPUIO_IO_CNTL);
++	if (is_input)
++		w |= 1 << mpuio;
++	else
++		w &= ~(1 << mpuio);
++	__raw_writew(w, base + OMAP_MPUIO_IO_CNTL);
++
++}
++
++static inline void cbus_set_gpio_dataout(u32 base, int mpuio, int enable)
++{
++	u16 w;
++
++	mpuio &= 0x0f;
++	w = __raw_readw(base + OMAP_MPUIO_OUTPUT);
++	if (enable)
++		w |= 1 << mpuio;
++	else
++		w &= ~(1 << mpuio);
++	__raw_writew(w, base + OMAP_MPUIO_OUTPUT);
++}
++
++static inline int cbus_get_gpio_datain(u32 base, int mpuio)
++{
++	mpuio &= 0x0f;
++
++	return (__raw_readw(base + OMAP_MPUIO_INPUT_LATCH) & (1 << mpuio)) != 0;
++}
++
++static void cbus_send_bit(struct cbus_host *host, u32 base, int bit,
++			  int set_to_input)
++{
++	cbus_set_gpio_dataout(base, host->dat_gpio, bit ? 1 : 0);
++	cbus_set_gpio_dataout(base, host->clk_gpio, 1);
++
++	/* The data bit is read on the rising edge of CLK */
++	if (set_to_input)
++		cbus_set_gpio_direction(base, host->dat_gpio, 1);
++
++	cbus_set_gpio_dataout(base, host->clk_gpio, 0);
++}
++
++static u8 cbus_receive_bit(struct cbus_host *host, u32 base)
++{
++	u8 ret;
++
++	cbus_set_gpio_dataout(base, host->clk_gpio, 1);
++	ret = cbus_get_gpio_datain(base, host->dat_gpio);
++	cbus_set_gpio_dataout(base, host->clk_gpio, 0);
++
++	return ret;
++}
++
++#define cbus_output(base, gpio, val)	cbus_set_gpio_direction(base, gpio, 0)
++
++#else
++
++#define cbus_output(base, gpio, val)	gpio_direction_output(gpio, val)
++#define cbus_set_gpio_dataout(base, gpio, enable) gpio_set_value(gpio, enable)
++#define cbus_get_gpio_datain(base, int, gpio) gpio_get_value(gpio)
++
++static void _cbus_send_bit(struct cbus_host *host, int bit, int set_to_input)
++{
++	gpio_set_value(host->dat_gpio, bit ? 1 : 0);
++	gpio_set_value(host->clk_gpio, 1);
++
++	/* The data bit is read on the rising edge of CLK */
++	if (set_to_input)
++		gpio_direction_input(host->dat_gpio);
++
++	gpio_set_value(host->clk_gpio, 0);
++}
++
++static u8 _cbus_receive_bit(struct cbus_host *host)
++{
++	u8 ret;
++
++	gpio_set_value(host->clk_gpio, 1);
++	ret = gpio_get_value(host->dat_gpio);
++	gpio_set_value(host->clk_gpio, 0);
++
++	return ret;
++}
++
++#define cbus_send_bit(host, base, bit, set_to_input) _cbus_send_bit(host, bit, set_to_input)
++#define cbus_receive_bit(host, base) _cbus_receive_bit(host)
++
++#endif
++
++static int cbus_transfer(struct cbus_host *host, int dev, int reg, int data)
++{
++	int i;
++	int is_read = 0;
++	unsigned long flags;
++	u32 base;
++
++#ifdef CONFIG_ARCH_OMAP1
++	base = OMAP1_IO_ADDRESS(OMAP1_MPUIO_BASE);
++#else
++	base = 0;
++#endif
++
++	if (data < 0)
++		is_read = 1;
++
++	/* We don't want interrupts disturbing our transfer */
++	spin_lock_irqsave(&host->lock, flags);
++
++	/* Reset state and start of transfer, SEL stays down during transfer */
++	cbus_set_gpio_dataout(base, host->sel_gpio, 0);
++
++	/* Set the DAT pin to output */
++	cbus_output(base, host->dat_gpio, 1);
++
++	/* Send the device address */
++	for (i = 3; i > 0; i--)
++		cbus_send_bit(host, base, dev & (1 << (i - 1)), 0);
++
++	/* Send the rw flag */
++	cbus_send_bit(host, base, is_read, 0);
++
++	/* Send the register address */
++	for (i = 5; i > 0; i--) {
++		int set_to_input = 0;
++
++		if (is_read && i == 1)
++			set_to_input = 1;
++
++		cbus_send_bit(host, base, reg & (1 << (i - 1)), set_to_input);
++	}
++
++	if (!is_read) {
++		for (i = 16; i > 0; i--)
++			cbus_send_bit(host, base, data & (1 << (i - 1)), 0);
++	} else {
++		cbus_set_gpio_dataout(base, host->clk_gpio, 1);
++		data = 0;
++
++		for (i = 16; i > 0; i--) {
++			u8 bit = cbus_receive_bit(host, base);
++
++			if (bit)
++				data |= 1 << (i - 1);
++		}
++	}
++
++	/* Indicate end of transfer, SEL goes up until next transfer */
++	cbus_set_gpio_dataout(base, host->sel_gpio, 1);
++	cbus_set_gpio_dataout(base, host->clk_gpio, 1);
++	cbus_set_gpio_dataout(base, host->clk_gpio, 0);
++
++	spin_unlock_irqrestore(&host->lock, flags);
++
++	return is_read ? data : 0;
++}
++
++/*
++ * Read a given register from the device
++ */
++int cbus_read_reg(struct cbus_host *host, int dev, int reg)
++{
++	return cbus_host ? cbus_transfer(host, dev, reg, -1) : -ENODEV;
++}
++EXPORT_SYMBOL(cbus_read_reg);
++
++/*
++ * Write to a given register of the device
++ */
++int cbus_write_reg(struct cbus_host *host, int dev, int reg, u16 val)
++{
++	return cbus_host ? cbus_transfer(host, dev, reg, (int)val) : -ENODEV;
++}
++EXPORT_SYMBOL(cbus_write_reg);
++
++static int __init cbus_bus_probe(struct platform_device *pdev)
++{
++	struct cbus_host *chost;
++	struct cbus_host_platform_data *pdata = pdev->dev.platform_data;
++	int ret;
++
++	chost = kzalloc(sizeof (*chost), GFP_KERNEL);
++	if (chost == NULL)
++		return -ENOMEM;
++
++	spin_lock_init(&chost->lock);
++
++	chost->clk_gpio = pdata->clk_gpio;
++	chost->dat_gpio = pdata->dat_gpio;
++	chost->sel_gpio = pdata->sel_gpio;
++
++	if ((ret = gpio_request(chost->clk_gpio, "CBUS clk")) < 0)
++		goto exit1;
++
++	if ((ret = gpio_request(chost->dat_gpio, "CBUS data")) < 0)
++		goto exit2;
++
++	if ((ret = gpio_request(chost->sel_gpio, "CBUS sel")) < 0)
++		goto exit3;
++
++	gpio_direction_output(chost->clk_gpio, 0);
++	gpio_direction_input(chost->dat_gpio);
++	gpio_direction_output(chost->sel_gpio, 1);
++
++	gpio_set_value(chost->clk_gpio, 1);
++	gpio_set_value(chost->clk_gpio, 0);
++
++	platform_set_drvdata(pdev, chost);
++
++	cbus_host = chost;
++
++	return 0;
++exit3:
++	gpio_free(chost->dat_gpio);
++exit2:
++	gpio_free(chost->clk_gpio);
++exit1:
++	kfree(chost);
++
++	return ret;
++}
++
++static void __exit cbus_bus_remove(struct platform_device *pdev)
++{
++	struct cbus_host	*chost = platform_get_drvdata(pdev);
++
++	gpio_free(chost->dat_gpio);
++	gpio_free(chost->clk_gpio);
++	kfree(chost);
++}
++
++static struct platform_driver cbus_driver = {
++	.remove		= __exit_p(cbus_bus_remove),
++	.driver		= {
++		.name	= "cbus",
++	},
++};
++
++static int __init cbus_bus_init(void)
++{
++	return platform_driver_probe(&cbus_driver, cbus_bus_probe);
++}
++
++subsys_initcall(cbus_bus_init);
++
++static void __exit cbus_bus_exit(void)
++{
++	platform_driver_unregister(&cbus_driver);
++}
++module_exit(cbus_bus_exit);
++
++MODULE_DESCRIPTION("CBUS serial protocol");
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Juha Yrjölä");
++MODULE_AUTHOR("David Weinehall");
++MODULE_AUTHOR("Mikko Ylinen");
++
+--- /dev/null
++++ linux-2.6.35/drivers/cbus/cbus.h
+@@ -0,0 +1,36 @@
++/*
++ * drivers/cbus/cbus.h
++ *
++ * Copyright (C) 2004, 2005 Nokia Corporation
++ *
++ * Written by Juha Yrjölä <[email protected]> and
++ *	      David Weinehall <[email protected]>
++ *
++ * 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.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ */
++
++#ifndef __DRIVERS_CBUS_CBUS_H
++#define __DRIVERS_CBUS_CBUS_H
++
++struct cbus_host {
++	int clk_gpio, dat_gpio, sel_gpio;
++        spinlock_t lock;
++};
++
++extern struct cbus_host *cbus_host;
++
++extern int cbus_read_reg(struct cbus_host *host, int dev, int reg);
++extern int cbus_write_reg(struct cbus_host *host, int dev, int reg, u16 val);
++
++#endif /* __DRIVERS_CBUS_CBUS_H */
+--- /dev/null
++++ linux-2.6.35/drivers/cbus/Kconfig
+@@ -0,0 +1,89 @@
++#
++# CBUS device configuration
++#
++
++menu "CBUS support"
++
++config CBUS
++	depends on ARCH_OMAP
++	bool "CBUS support on OMAP"
++	---help---
++	  CBUS is a proprietary serial protocol by Nokia.  It is mainly
++	  used for accessing Energy Management auxiliary chips.
++
++	  If you want CBUS support, you should say Y here.
++
++config CBUS_TAHVO
++	depends on CBUS
++	bool "Support for Tahvo"
++	---help---
++	  Tahvo is a mixed signal ASIC with some system features
++
++	  If you want Tahvo support, you should say Y here.
++
++config CBUS_TAHVO_USER
++	depends on CBUS_TAHVO
++	bool "Support for Tahvo user space functions"
++	---help---
++	  If you want support for Tahvo's user space read/write etc. functions,
++	  you should say Y here.
++
++config CBUS_TAHVO_USB
++	depends on CBUS_TAHVO && USB
++	tristate "Support for Tahvo USB transceiver"
++	---help---
++	  If you want Tahvo support for USB transceiver, say Y or M here.
++
++config CBUS_TAHVO_USB_HOST_BY_DEFAULT
++	depends on CBUS_TAHVO_USB && USB_OTG
++	boolean "Device in USB host mode by default"
++	---help---
++	  Say Y here, if you want the device to enter USB host mode
++	  by default on bootup.
++
++config CBUS_RETU
++	depends on CBUS
++	bool "Support for Retu"
++	---help---
++	  Retu is a mixed signal ASIC with some system features
++
++	  If you want Retu support, you should say Y here.
++
++config CBUS_RETU_USER
++	depends on CBUS_RETU
++	bool "Support for Retu user space functions"
++	---help---
++	  If you want support for Retu's user space read/write etc. functions,
++	  you should say Y here.
++
++config CBUS_RETU_POWERBUTTON
++	depends on CBUS_RETU
++	bool "Support for Retu power button"
++	---help---
++	  The power button on Nokia 770 is connected to the Retu ASIC.
++
++	  If you want support for the Retu power button, you should say Y here.
++
++config CBUS_RETU_RTC
++	depends on CBUS_RETU && SYSFS
++	tristate "Support for Retu pseudo-RTC"
++	---help---
++	  Say Y here if you want support for the device that alleges to be an
++	  RTC in Retu. This will expose a sysfs interface for it.
++
++config CBUS_RETU_WDT
++	depends on CBUS_RETU && SYSFS && WATCHDOG
++	tristate "Support for Retu watchdog timer"
++	---help---
++	  Say Y here if you want support for the watchdog in Retu. This will
++	  expose a sysfs interface to grok it.
++
++config CBUS_RETU_HEADSET
++	depends on CBUS_RETU && SYSFS
++	tristate "Support for headset detection with Retu/Vilma"
++	---help---
++	  Say Y here if you want support detecting a headset that's connected
++	  to Retu/Vilma. Detection state and events are exposed through
++	  sysfs.
++
++endmenu
+--- /dev/null
++++ linux-2.6.35/drivers/cbus/Makefile
+@@ -0,0 +1,14 @@
++#
++# Makefile for CBUS.
++#
++
++obj-$(CONFIG_CBUS)		+= cbus.o
++obj-$(CONFIG_CBUS_TAHVO)	+= tahvo.o
++obj-$(CONFIG_CBUS_RETU)		+= retu.o
++obj-$(CONFIG_CBUS_TAHVO_USB)	+= tahvo-usb.o
++obj-$(CONFIG_CBUS_RETU_POWERBUTTON) += retu-pwrbutton.o
++obj-$(CONFIG_CBUS_RETU_RTC)	+= retu-rtc.o
++obj-$(CONFIG_CBUS_RETU_WDT)	+= retu-wdt.o
++obj-$(CONFIG_CBUS_TAHVO_USER)	+= tahvo-user.o
++obj-$(CONFIG_CBUS_RETU_USER)	+= retu-user.o
++obj-$(CONFIG_CBUS_RETU_HEADSET)	+= retu-headset.o
+--- /dev/null
++++ linux-2.6.35/drivers/cbus/retu.c
+@@ -0,0 +1,468 @@
++/**
++ * drivers/cbus/retu.c
++ *
++ * Support functions for Retu ASIC
++ *
++ * Copyright (C) 2004, 2005 Nokia Corporation
++ *
++ * Written by Juha Yrjölä <[email protected]>,
++ *	      David Weinehall <[email protected]>, and
++ *	      Mikko Ylinen <[email protected]>
++ *
++ * 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.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ */
++
++#include <linux/module.h>
++#include <linux/init.h>
++
++#include <linux/kernel.h>
++#include <linux/errno.h>
++#include <linux/device.h>
++#include <linux/miscdevice.h>
++#include <linux/poll.h>
++#include <linux/fs.h>
++#include <linux/irq.h>
++#include <linux/interrupt.h>
++#include <linux/platform_device.h>
++#include <linux/gpio.h>
++
++#include <asm/uaccess.h>
++#include <asm/mach-types.h>
++
++#include <plat/mux.h>
++#include <plat/board.h>
++
++#include "cbus.h"
++#include "retu.h"
++
++#define RETU_ID			0x01
++#define PFX			"retu: "
++
++static int retu_initialized;
++static int retu_irq_pin;
++static int retu_is_vilma;
++
++static struct tasklet_struct retu_tasklet;
++spinlock_t retu_lock = SPIN_LOCK_UNLOCKED;
++
++static struct completion device_release;
++
++struct retu_irq_handler_desc {
++	int (*func)(unsigned long);
++	unsigned long arg;
++	char name[8];
++};
++
++static struct retu_irq_handler_desc retu_irq_handlers[MAX_RETU_IRQ_HANDLERS];
++
++/**
++ * retu_read_reg - Read a value from a register in Retu
++ * @reg: the register to read from
++ *
++ * This function returns the contents of the specified register
++ */
++int retu_read_reg(int reg)
++{
++	BUG_ON(!retu_initialized);
++	return cbus_read_reg(cbus_host, RETU_ID, reg);
++}
++
++/**
++ * retu_write_reg - Write a value to a register in Retu
++ * @reg: the register to write to
++ * @reg: the value to write to the register
++ *
++ * This function writes a value to the specified register
++ */
++void retu_write_reg(int reg, u16 val)
++{
++	BUG_ON(!retu_initialized);
++	cbus_write_reg(cbus_host, RETU_ID, reg, val);
++}
++
++void retu_set_clear_reg_bits(int reg, u16 set, u16 clear)
++{
++	unsigned long flags;
++	u16 w;
++
++	spin_lock_irqsave(&retu_lock, flags);
++	w = retu_read_reg(reg);
++	w &= ~clear;
++	w |= set;
++	retu_write_reg(reg, w);
++	spin_unlock_irqrestore(&retu_lock, flags);
++}
++
++#define ADC_MAX_CHAN_NUMBER	13
++
++int retu_read_adc(int channel)
++{
++	unsigned long flags;
++	int res;
++
++	if (channel < 0 || channel > ADC_MAX_CHAN_NUMBER)
++		return -EINVAL;
++
++	spin_lock_irqsave(&retu_lock, flags);
++
++	if ((channel == 8) && retu_is_vilma) {
++		int scr = retu_read_reg(RETU_REG_ADCSCR);
++		int ch = (retu_read_reg(RETU_REG_ADCR) >> 10) & 0xf;
++		if (((scr & 0xff) != 0) && (ch != 8))
++			retu_write_reg (RETU_REG_ADCSCR, (scr & ~0xff));
++	}
++
++	/* Select the channel and read result */
++	retu_write_reg(RETU_REG_ADCR, channel << 10);
++	res = retu_read_reg(RETU_REG_ADCR) & 0x3ff;
++
++	if (retu_is_vilma)
++		retu_write_reg(RETU_REG_ADCR, (1 << 13));
++
++	/* Unlock retu */
++	spin_unlock_irqrestore(&retu_lock, flags);
++
++	return res;
++}
++
++
++static u16 retu_disable_bogus_irqs(u16 mask)
++{
++       int i;
++
++       for (i = 0; i < MAX_RETU_IRQ_HANDLERS; i++) {
++               if (mask & (1 << i))
++                       continue;
++               if (retu_irq_handlers[i].func != NULL)
++                       continue;
++               /* an IRQ was enabled but we don't have a handler for it */
++               printk(KERN_INFO PFX "disabling bogus IRQ %d\n", i);
++               mask |= (1 << i);
++       }
++       return mask;
++}
++
++/*
++ * Disable given RETU interrupt
++ */
++void retu_disable_irq(int id)
++{
++	unsigned long flags;
++	u16 mask;
++
++	spin_lock_irqsave(&retu_lock, flags);
++	mask = retu_read_reg(RETU_REG_IMR);
++	mask |= 1 << id;
++	mask = retu_disable_bogus_irqs(mask);
++	retu_write_reg(RETU_REG_IMR, mask);
++	spin_unlock_irqrestore(&retu_lock, flags);
++}
++
++/*
++ * Enable given RETU interrupt
++ */
++void retu_enable_irq(int id)
++{
++	unsigned long flags;
++	u16 mask;
++
++	if (id == 3) {
++		printk("Enabling Retu IRQ %d\n", id);
++		dump_stack();
++	}
++	spin_lock_irqsave(&retu_lock, flags);
++	mask = retu_read_reg(RETU_REG_IMR);
++	mask &= ~(1 << id);
++	mask = retu_disable_bogus_irqs(mask);
++	retu_write_reg(RETU_REG_IMR, mask);
++	spin_unlock_irqrestore(&retu_lock, flags);
++}
++
++/*
++ * Acknowledge given RETU interrupt
++ */
++void retu_ack_irq(int id)
++{
++	retu_write_reg(RETU_REG_IDR, 1 << id);
++}
++
++/*
++ * RETU interrupt handler. Only schedules the tasklet.
++ */
++static irqreturn_t retu_irq_handler(int irq, void *dev_id)
++{
++	tasklet_schedule(&retu_tasklet);
++	return IRQ_HANDLED;
++}
++
++/*
++ * Tasklet handler
++ */
++static void retu_tasklet_handler(unsigned long data)
++{
++	struct retu_irq_handler_desc *hnd;
++	u16 id;
++	u16 im;
++	int i;
++
++	for (;;) {
++		id = retu_read_reg(RETU_REG_IDR);
++		im = ~retu_read_reg(RETU_REG_IMR);
++		id &= im;
++
++		if (!id)
++			break;
++
++		for (i = 0; id != 0; i++, id >>= 1) {
++			if (!(id & 1))
++				continue;
++			hnd = &retu_irq_handlers[i];
++			if (hnd->func == NULL) {
++                               /* Spurious retu interrupt - disable and ack it */
++				printk(KERN_INFO "Spurious Retu interrupt "
++						 "(id %d)\n", i);
++				retu_disable_irq(i);
++				retu_ack_irq(i);
++				continue;
++			}
++			hnd->func(hnd->arg);
++			/*
++			 * Don't acknowledge the interrupt here
++			 * It must be done explicitly
++			 */
++		}
++	}
++}
++
++/*
++ * Register the handler for a given RETU interrupt source.
++ */
++int retu_request_irq(int id, void *irq_handler, unsigned long arg, char *name)
++{
++	struct retu_irq_handler_desc *hnd;
++
++	if (irq_handler == NULL || id >= MAX_RETU_IRQ_HANDLERS ||
++	    name == NULL) {
++		printk(KERN_ERR PFX "Invalid arguments to %s\n",
++		       __FUNCTION__);
++		return -EINVAL;
++	}
++	hnd = &retu_irq_handlers[id];
++	if (hnd->func != NULL) {
++		printk(KERN_ERR PFX "IRQ %d already reserved\n", id);
++		return -EBUSY;
++	}
++	printk(KERN_INFO PFX "Registering interrupt %d for device %s\n",
++	       id, name);
++	hnd->func = irq_handler;
++	hnd->arg = arg;
++	strlcpy(hnd->name, name, sizeof(hnd->name));
++
++	retu_ack_irq(id);
++	retu_enable_irq(id);
++
++	return 0;
++}
++
++/*
++ * Unregister the handler for a given RETU interrupt source.
++ */
++void retu_free_irq(int id)
++{
++	struct retu_irq_handler_desc *hnd;
++
++	if (id >= MAX_RETU_IRQ_HANDLERS) {
++		printk(KERN_ERR PFX "Invalid argument to %s\n",
++		       __FUNCTION__);
++		return;
++	}
++	hnd = &retu_irq_handlers[id];
++	if (hnd->func == NULL) {
++		printk(KERN_ERR PFX "IRQ %d already freed\n", id);
++		return;
++	}
++
++	retu_disable_irq(id);
++	hnd->func = NULL;
++}
++
++/**
++ * retu_power_off - Shut down power to system
++ *
++ * This function puts the system in power off state
++ */
++static void retu_power_off(void)
++{
++	/* Ignore power button state */
++	retu_write_reg(RETU_REG_CC1, retu_read_reg(RETU_REG_CC1) | 2);
++	/* Expire watchdog immediately */
++	retu_write_reg(RETU_REG_WATCHDOG, 0);
++	/* Wait for poweroff*/
++	for (;;);
++}
++
++/**
++ * retu_probe - Probe for Retu ASIC
++ * @dev: the Retu device
++ *
++ * Probe for the Retu ASIC and allocate memory
++ * for its device-struct if found
++ */
++static int __devinit retu_probe(struct device *dev)
++{
++	int rev, ret;
++
++	/* Prepare tasklet */
++	tasklet_init(&retu_tasklet, retu_tasklet_handler, 0);
++
++	/* REVISIT: Pass these from board-*.c files in platform_data */
++	if (machine_is_nokia770()) {
++		retu_irq_pin = 62;
++	} else if (machine_is_nokia_n800() || machine_is_nokia_n810() ||
++			machine_is_nokia_n810_wimax()) {
++		retu_irq_pin = 108;
++	} else {
++		printk(KERN_ERR "cbus: Unsupported board for tahvo\n");
++		return -ENODEV;
++	}
++
++	if ((ret = gpio_request(retu_irq_pin, "RETU irq")) < 0) {
++		printk(KERN_ERR PFX "Unable to reserve IRQ GPIO\n");
++		return ret;
++	}
++
++	/* Set the pin as input */
++	gpio_direction_input(retu_irq_pin);
++
++	/* Rising edge triggers the IRQ */
++	set_irq_type(gpio_to_irq(retu_irq_pin), IRQ_TYPE_EDGE_RISING);
++
++	retu_initialized = 1;
++
++	rev = retu_read_reg(RETU_REG_ASICR) & 0xff;
++	if (rev & (1 << 7))
++		retu_is_vilma = 1;
++
++	printk(KERN_INFO "%s v%d.%d found\n", retu_is_vilma ? "Vilma" : "Retu",
++	       (rev >> 4) & 0x07, rev & 0x0f);
++
++	/* Mask all RETU interrupts */
++	retu_write_reg(RETU_REG_IMR, 0xffff);
++
++	ret = request_irq(gpio_to_irq(retu_irq_pin), retu_irq_handler, 0,
++			  "retu", 0);
++	if (ret < 0) {
++		printk(KERN_ERR PFX "Unable to register IRQ handler\n");
++		gpio_free(retu_irq_pin);
++		return ret;
++	}
++	set_irq_wake(gpio_to_irq(retu_irq_pin), 1);
++
++	/* Register power off function */
++	pm_power_off = retu_power_off;
++
++#ifdef CONFIG_CBUS_RETU_USER
++	/* Initialize user-space interface */
++	if (retu_user_init() < 0) {
++		printk(KERN_ERR "Unable to initialize driver\n");
++		free_irq(gpio_to_irq(retu_irq_pin), 0);
++		gpio_free(retu_irq_pin);
++		return ret;
++	}
++#endif
++
++	return 0;
++}
++
++static int retu_remove(struct device *dev)
++{
++#ifdef CONFIG_CBUS_RETU_USER
++	retu_user_cleanup();
++#endif
++	/* Mask all RETU interrupts */
++	retu_write_reg(RETU_REG_IMR, 0xffff);
++	free_irq(gpio_to_irq(retu_irq_pin), 0);
++	gpio_free(retu_irq_pin);
++	tasklet_kill(&retu_tasklet);
++
++	return 0;
++}
++
++static void retu_device_release(struct device *dev)
++{
++	complete(&device_release);
++}
++
++static struct device_driver retu_driver = {
++	.name		= "retu",
++	.bus		= &platform_bus_type,
++	.probe		= retu_probe,
++	.remove		= retu_remove,
++};
++
++static struct platform_device retu_device = {
++	.name		= "retu",
++	.id		= -1,
++	.dev = {
++		.release = retu_device_release,
++	}
++};
++
++/**
++ * retu_init - initialise Retu driver
++ *
++ * Initialise the Retu driver and return 0 if everything worked ok
++ */
++static int __init retu_init(void)
++{
++	int ret = 0;
++
++	printk(KERN_INFO "Retu/Vilma driver initialising\n");
++
++	init_completion(&device_release);
++
++	if ((ret = driver_register(&retu_driver)) < 0)
++		return ret;
++
++	if ((ret = platform_device_register(&retu_device)) < 0) {
++		driver_unregister(&retu_driver);
++		return ret;
++	}
++	return 0;
++}
++
++/*
++ * Cleanup
++ */
++static void __exit retu_exit(void)
++{
++	platform_device_unregister(&retu_device);
++	driver_unregister(&retu_driver);
++	wait_for_completion(&device_release);
++}
++
++EXPORT_SYMBOL(retu_request_irq);
++EXPORT_SYMBOL(retu_free_irq);
++EXPORT_SYMBOL(retu_enable_irq);
++EXPORT_SYMBOL(retu_disable_irq);
++EXPORT_SYMBOL(retu_ack_irq);
++EXPORT_SYMBOL(retu_read_reg);
++EXPORT_SYMBOL(retu_write_reg);
++
++subsys_initcall(retu_init);
++module_exit(retu_exit);
++
++MODULE_DESCRIPTION("Retu ASIC control");
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Juha Yrjölä, David Weinehall, and Mikko Ylinen");
+--- /dev/null
++++ linux-2.6.35/drivers/cbus/retu.h
+@@ -0,0 +1,77 @@
++/**
++ * drivers/cbus/retu.h
++ *
++ * Copyright (C) 2004, 2005 Nokia Corporation
++ *
++ * Written by Juha Yrjölä <[email protected]> and
++ *	      David Weinehall <[email protected]>
++ *
++ * 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.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ */
++
++#ifndef __DRIVERS_CBUS_RETU_H
++#define __DRIVERS_CBUS_RETU_H
++
++#include <linux/types.h>
++
++/* Registers */
++#define RETU_REG_ASICR		0x00	/* ASIC ID & revision */
++#define RETU_REG_IDR		0x01	/* Interrupt ID */
++#define RETU_REG_IMR		0x02	/* Interrupt mask */
++#define RETU_REG_RTCDSR		0x03	/* RTC seconds register */
++#define RETU_REG_RTCHMR		0x04	/* RTC hours and minutes register */
++#define RETU_REG_RTCHMAR	0x05	/* RTC hours and minutes alarm and time set register */
++#define RETU_REG_RTCCALR	0x06	/* RTC calibration register */
++#define RETU_REG_ADCR		0x08	/* ADC result */
++#define RETU_REG_ADCSCR		0x09	/* ADC sample ctrl */
++#define RETU_REG_CC1		0x0d	/* Common control register 1 */
++#define RETU_REG_CC2		0x0e	/* Common control register 2 */
++#define RETU_REG_CTRL_CLR	0x0f	/* Regulator clear register */
++#define RETU_REG_CTRL_SET	0x10	/* Regulator set register */
++#define RETU_REG_STATUS		0x16	/* Status register */
++#define RETU_REG_WATCHDOG	0x17	/* Watchdog register */
++#define RETU_REG_AUDTXR		0x18	/* Audio Codec Tx register */
++#define RETU_REG_MAX		0x1f
++
++/* Interrupt sources */
++#define RETU_INT_PWR		0
++#define RETU_INT_CHAR		1
++#define RETU_INT_RTCS		2
++#define RETU_INT_RTCM		3
++#define RETU_INT_RTCD		4
++#define RETU_INT_RTCA		5
++#define RETU_INT_HOOK		6
++#define RETU_INT_HEAD		7
++#define RETU_INT_ADCS		8
++
++#define	MAX_RETU_IRQ_HANDLERS	16
++
++int retu_read_reg(int reg);
++void retu_write_reg(int reg, u16 val);
++void retu_set_clear_reg_bits(int reg, u16 set, u16 clear);
++int retu_read_adc(int channel);
++int retu_request_irq(int id, void *irq_handler, unsigned long arg, char *name);
++void retu_free_irq(int id);
++void retu_enable_irq(int id);
++void retu_disable_irq(int id);
++void retu_ack_irq(int id);
++
++#ifdef CONFIG_CBUS_RETU_USER
++int retu_user_init(void);
++void retu_user_cleanup(void);
++#endif
++
++extern spinlock_t retu_lock;
++
++#endif /* __DRIVERS_CBUS_RETU_H */
+--- /dev/null
++++ linux-2.6.35/drivers/cbus/retu-headset.c
+@@ -0,0 +1,355 @@
++/**
++ * Retu/Vilma headset detection
++ *
++ * Copyright (C) 2006 Nokia Corporation
++ *
++ * Written by Juha Yrjölä
++ *
++ * 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.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ */
++
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/kernel.h>
++#include <linux/delay.h>
++#include <linux/input.h>
++#include <linux/platform_device.h>
++
++#include "retu.h"
++
++#define RETU_ADC_CHANNEL_HOOKDET	0x05
++
++#define RETU_HEADSET_KEY		KEY_PHONE
++
++struct retu_headset {
++	spinlock_t			lock;
++	struct mutex			mutex;
++	struct platform_device		*pdev;
++	struct input_dev		*idev;
++	unsigned			bias_enabled;
++	unsigned			detection_enabled;
++	unsigned			pressed;
++	struct timer_list		enable_timer;
++	struct timer_list		detect_timer;
++};
++
++static void retu_headset_set_bias(int enable)
++{
++	if (enable) {
++		retu_set_clear_reg_bits(RETU_REG_AUDTXR,
++					(1 << 0) | (1 << 1), 0);
++		msleep(2);
++		retu_set_clear_reg_bits(RETU_REG_AUDTXR, 1 << 3, 0);
++	} else {
++		retu_set_clear_reg_bits(RETU_REG_AUDTXR, 0,
++					(1 << 0) | (1 << 1) | (1 << 3));
++	}
++}
++
++static void retu_headset_enable(struct retu_headset *hs)
++{
++	mutex_lock(&hs->mutex);
++	if (!hs->bias_enabled) {
++		hs->bias_enabled = 1;
++		retu_headset_set_bias(1);
++	}
++	mutex_unlock(&hs->mutex);
++}
++
++static void retu_headset_disable(struct retu_headset *hs)
++{
++	mutex_lock(&hs->mutex);
++	if (hs->bias_enabled) {
++		hs->bias_enabled = 0;
++		retu_headset_set_bias(0);
++	}
++	mutex_unlock(&hs->mutex);
++}
++
++static void retu_headset_det_enable(struct retu_headset *hs)
++{
++	mutex_lock(&hs->mutex);
++	if (!hs->detection_enabled) {
++		hs->detection_enabled = 1;
++		retu_set_clear_reg_bits(RETU_REG_CC1, (1 << 10) | (1 << 8), 0);
++		retu_enable_irq(RETU_INT_HOOK);
++	}
++	mutex_unlock(&hs->mutex);
++}
++
++static void retu_headset_det_disable(struct retu_headset *hs)
++{
++	unsigned long flags;
++
++	mutex_lock(&hs->mutex);
++	if (hs->detection_enabled) {
++		hs->detection_enabled = 0;
++		retu_disable_irq(RETU_INT_HOOK);
++		del_timer_sync(&hs->enable_timer);
++		del_timer_sync(&hs->detect_timer);
++		spin_lock_irqsave(&hs->lock, flags);
++		if (hs->pressed)
++			input_report_key(hs->idev, RETU_HEADSET_KEY, 0);
++		spin_unlock_irqrestore(&hs->lock, flags);
++		retu_set_clear_reg_bits(RETU_REG_CC1, 0, (1 << 10) | (1 << 8));
++	}
++	mutex_unlock(&hs->mutex);
++}
++
++static ssize_t retu_headset_hookdet_show(struct device *dev,
++					 struct device_attribute *attr,
++					 char *buf)
++{
++	int val;
++
++	val = retu_read_adc(RETU_ADC_CHANNEL_HOOKDET);
++	return sprintf(buf, "%d\n", val);
++}
++
++static DEVICE_ATTR(hookdet, S_IRUGO, retu_headset_hookdet_show, NULL);
++
++static ssize_t retu_headset_enable_show(struct device *dev,
++					struct device_attribute *attr,
++					char *buf)
++{
++	struct retu_headset *hs = dev_get_drvdata(dev);
++
++	return sprintf(buf, "%u\n", hs->bias_enabled);
++}
++
++static ssize_t retu_headset_enable_store(struct device *dev,
++					 struct device_attribute *attr,
++					 const char *buf, size_t count)
++{
++	struct retu_headset *hs = dev_get_drvdata(dev);
++	int enable;
++
++	if (sscanf(buf, "%u", &enable) != 1)
++		return -EINVAL;
++	if (enable)
++		retu_headset_enable(hs);
++	else
++	        retu_headset_disable(hs);
++	return count;
++}
++
++static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR | S_IWGRP,
++		   retu_headset_enable_show, retu_headset_enable_store);
++
++static ssize_t retu_headset_enable_det_show(struct device *dev,
++					    struct device_attribute *attr,
++					    char *buf)
++{
++	struct retu_headset *hs = dev_get_drvdata(dev);
++
++	return sprintf(buf, "%u\n", hs->detection_enabled);
++}
++
++static ssize_t retu_headset_enable_det_store(struct device *dev,
++					     struct device_attribute *attr,
++					     const char *buf, size_t count)
++{
++	struct retu_headset *hs = dev_get_drvdata(dev);
++	int enable;
++
++	if (sscanf(buf, "%u", &enable) != 1)
++		return -EINVAL;
++	if (enable)
++		retu_headset_det_enable(hs);
++	else
++	        retu_headset_det_disable(hs);
++	return count;
++}
++
++static DEVICE_ATTR(enable_det, S_IRUGO | S_IWUSR | S_IWGRP,
++		   retu_headset_enable_det_show,
++		   retu_headset_enable_det_store);
++
++static void retu_headset_hook_interrupt(unsigned long arg)
++{
++	struct retu_headset *hs = (struct retu_headset *) arg;
++	unsigned long flags;
++
++	retu_ack_irq(RETU_INT_HOOK);
++	spin_lock_irqsave(&hs->lock, flags);
++	if (!hs->pressed) {
++		/* Headset button was just pressed down. */
++		hs->pressed = 1;
++		input_report_key(hs->idev, RETU_HEADSET_KEY, 1);
++	}
++	spin_unlock_irqrestore(&hs->lock, flags);
++	retu_set_clear_reg_bits(RETU_REG_CC1, 0, (1 << 10) | (1 << 8));
++	mod_timer(&hs->enable_timer, jiffies + msecs_to_jiffies(50));
++}
++
++static void retu_headset_enable_timer(unsigned long arg)
++{
++	struct retu_headset *hs = (struct retu_headset *) arg;
++
++	retu_set_clear_reg_bits(RETU_REG_CC1, (1 << 10) | (1 << 8), 0);
++	mod_timer(&hs->detect_timer, jiffies + msecs_to_jiffies(350));
++}
++
++static void retu_headset_detect_timer(unsigned long arg)
++{
++	struct retu_headset *hs = (struct retu_headset *) arg;
++	unsigned long flags;
++
++	spin_lock_irqsave(&hs->lock, flags);
++	if (hs->pressed) {
++		hs->pressed = 0;
++		input_report_key(hs->idev, RETU_HEADSET_KEY, 0);
++	}
++	spin_unlock_irqrestore(&hs->lock, flags);
++}
++
++static int __init retu_headset_probe(struct platform_device *pdev)
++{
++	struct retu_headset *hs;
++	int r;
++
++	hs = kzalloc(sizeof(*hs), GFP_KERNEL);
++	if (hs == NULL)
++		return -ENOMEM;
++
++	hs->pdev = pdev;
++
++	hs->idev = input_allocate_device();
++	if (hs->idev == NULL) {
++		r = -ENOMEM;
++		goto err1;
++	}
++	hs->idev->name = "retu-headset";
++	hs->idev->dev.parent = &pdev->dev;
++	set_bit(EV_KEY, hs->idev->evbit);
++	set_bit(RETU_HEADSET_KEY, hs->idev->keybit);
++	r = input_register_device(hs->idev);
++	if (r < 0)
++		goto err2;
++
++	r = device_create_file(&pdev->dev, &dev_attr_hookdet);
++	if (r < 0)
++		goto err3;
++	r = device_create_file(&pdev->dev, &dev_attr_enable);
++	if (r < 0)
++		goto err4;
++	r = device_create_file(&pdev->dev, &dev_attr_enable_det);
++	if (r < 0)
++		goto err5;
++	platform_set_drvdata(pdev, hs);
++
++	spin_lock_init(&hs->lock);
++	mutex_init(&hs->mutex);
++	setup_timer(&hs->enable_timer, retu_headset_enable_timer,
++		    (unsigned long) hs);
++	setup_timer(&hs->detect_timer, retu_headset_detect_timer,
++		    (unsigned long) hs);
++
++	r = retu_request_irq(RETU_INT_HOOK, retu_headset_hook_interrupt,
++			     (unsigned long) hs, "hookdet");
++	if (r != 0) {
++		dev_err(&pdev->dev, "hookdet IRQ not available\n");
++		goto err6;
++	}
++	retu_disable_irq(RETU_INT_HOOK);
++	return 0;
++err6:
++	device_remove_file(&pdev->dev, &dev_attr_enable_det);
++err5:
++	device_remove_file(&pdev->dev, &dev_attr_enable);
++err4:
++	device_remove_file(&pdev->dev, &dev_attr_hookdet);
++err3:
++	input_unregister_device(hs->idev);
++err2:
++	input_free_device(hs->idev);
++err1:
++	kfree(hs);
++	return r;
++}
++
++static int retu_headset_remove(struct platform_device *pdev)
++{
++	struct retu_headset *hs = platform_get_drvdata(pdev);
++
++	device_remove_file(&pdev->dev, &dev_attr_hookdet);
++	device_remove_file(&pdev->dev, &dev_attr_enable);
++	device_remove_file(&pdev->dev, &dev_attr_enable_det);
++	retu_headset_disable(hs);
++	retu_headset_det_disable(hs);
++	retu_free_irq(RETU_INT_HOOK);
++	input_unregister_device(hs->idev);
++	input_free_device(hs->idev);
++	return 0;
++}
++
++static int retu_headset_suspend(struct platform_device *pdev,
++				pm_message_t mesg)
++{
++	struct retu_headset *hs = platform_get_drvdata(pdev);
++
++	mutex_lock(&hs->mutex);
++	if (hs->bias_enabled)
++		retu_headset_set_bias(0);
++	mutex_unlock(&hs->mutex);
++
++	return 0;
++}
++
++static int retu_headset_resume(struct platform_device *pdev)
++{
++	struct retu_headset *hs = platform_get_drvdata(pdev);
++
++	mutex_lock(&hs->mutex);
++	if (hs->bias_enabled)
++		retu_headset_set_bias(1);
++	mutex_unlock(&hs->mutex);
++
++	return 0;
++}
++
++static struct platform_driver retu_headset_driver = {
++	.probe		= retu_headset_probe,
++	.remove		= retu_headset_remove,
++	.suspend	= retu_headset_suspend,
++	.resume		= retu_headset_resume,
++	.driver		= {
++		.name	= "retu-headset",
++	},
++};
++
++static int __init retu_headset_init(void)
++{
++	int r;
++
++	printk(KERN_INFO "Retu/Vilma headset driver initializing\n");
++
++	r = platform_driver_register(&retu_headset_driver);
++	if (r < 0)
++		return r;
++
++	return 0;
++}
++
++static void __exit retu_headset_exit(void)
++{
++	platform_driver_unregister(&retu_headset_driver);
++}
++
++module_init(retu_headset_init);
++module_exit(retu_headset_exit);
++
++MODULE_DESCRIPTION("Retu/Vilma headset detection");
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Juha Yrjölä");
+--- /dev/null
++++ linux-2.6.35/drivers/cbus/retu-pwrbutton.c
+@@ -0,0 +1,118 @@
++/**
++ * drivers/cbus/retu-pwrbutton.c
++ *
++ * Driver for sending retu power button event to input-layer
++ *
++ * Copyright (C) 2004 Nokia Corporation
++ *
++ * Written by Ari Saastamoinen <[email protected]>
++ *
++ * Contact Juha Yrjölä <[email protected]>
++ *
++ * 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.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ */
++
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/kernel.h>
++#include <linux/errno.h>
++#include <linux/input.h>
++#include <linux/timer.h>
++#include <linux/jiffies.h>
++#include <linux/bitops.h>
++
++#include "retu.h"
++
++#define RETU_STATUS_PWRONX	(1 << 5)
++
++#define PWRBTN_DELAY		20
++#define PWRBTN_UP		0
++#define PWRBTN_PRESSED		1
++
++static int pwrbtn_state;
++static struct input_dev *pwrbtn_dev;
++static struct timer_list pwrbtn_timer;
++
++static void retubutton_timer_func(unsigned long arg)
++{
++	int state;
++
++	if (retu_read_reg(RETU_REG_STATUS) & RETU_STATUS_PWRONX)
++		state = PWRBTN_UP;
++	else
++		state = PWRBTN_PRESSED;
++
++	if (pwrbtn_state != state) {
++		input_report_key(pwrbtn_dev, KEY_POWER, state);
++		pwrbtn_state = state;
++	}
++}
++
++/**
++ * Interrupt function is called whenever power button key is pressed
++ * or released.
++ */
++static void retubutton_irq(unsigned long arg)
++{
++	retu_ack_irq(RETU_INT_PWR);
++	mod_timer(&pwrbtn_timer, jiffies + msecs_to_jiffies(PWRBTN_DELAY));
++}
++
++/**
++ * Init function.
++ * Allocates interrupt for power button and registers itself to input layer.
++ */
++static int __init retubutton_init(void)
++{
++	int irq;
++
++	printk(KERN_INFO "Retu power button driver initialized\n");
++	irq = RETU_INT_PWR;
++
++	init_timer(&pwrbtn_timer);
++	pwrbtn_timer.function = retubutton_timer_func;
++
++	if (retu_request_irq(irq, &retubutton_irq, 0, "PwrOnX") < 0) {
++		printk(KERN_ERR "%s@%s: Cannot allocate irq\n",
++		       __FUNCTION__, __FILE__);
++		return -EBUSY;
++	}
++
++	pwrbtn_dev = input_allocate_device();
++	if (!pwrbtn_dev)
++		return -ENOMEM;
++
++	pwrbtn_dev->evbit[0] = BIT_MASK(EV_KEY);
++	pwrbtn_dev->keybit[BIT_WORD(KEY_POWER)] = BIT_MASK(KEY_POWER);
++	pwrbtn_dev->name = "retu-pwrbutton";
++
++	return input_register_device(pwrbtn_dev);
++}
++
++/**
++ * Cleanup function which is called when driver is unloaded
++ */
++static void __exit retubutton_exit(void)
++{
++	retu_free_irq(RETU_INT_PWR);
++	del_timer_sync(&pwrbtn_timer);
++	input_unregister_device(pwrbtn_dev);
++}
++
++module_init(retubutton_init);
++module_exit(retubutton_exit);
++
++MODULE_DESCRIPTION("Retu Power Button");
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Ari Saastamoinen");
+--- /dev/null
++++ linux-2.6.35/drivers/cbus/retu-rtc.c
+@@ -0,0 +1,477 @@
++/**
++ * drivers/cbus/retu-rtc.c
++ *
++ * Support for Retu RTC
++ *
++ * Copyright (C) 2004, 2005 Nokia Corporation
++ *
++ * Written by Paul Mundt <[email protected]> and
++ *            Igor Stoppa <[email protected]>
++ *
++ * The Retu RTC is essentially a partial read-only RTC that gives us Retu's
++ * idea of what time actually is. It's left as a userspace excercise to map
++ * this back to time in the real world and ensure that calibration settings
++ * are sane to compensate for any horrible drift (on account of not being able
++ * to set the clock to anything).
++ *
++ * Days are semi-writeable. Namely, Retu will only track 255 days for us
++ * consecutively, after which the counter is explicitly stuck at 255 until
++ * someone comes along and clears it with a write. In the event that no one
++ * comes along and clears it, we no longer have any idea what day it is.
++ *
++ * 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.
++ *
++ * 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/device.h>
++#include <linux/init.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/completion.h>
++#include <linux/platform_device.h>
++#include <linux/mutex.h>
++#include <linux/workqueue.h>
++
++#include "cbus.h"
++#include "retu.h"
++
++static struct mutex retu_rtc_mutex;
++static u16 retu_rtc_alarm_expired;
++static u16 retu_rtc_reset_occurred;
++
++static DECLARE_COMPLETION(retu_rtc_exited);
++static DECLARE_COMPLETION(retu_rtc_sync);
++
++static void retu_rtc_barrier(void);
++
++static void retu_rtc_device_release(struct device *dev)
++{
++	complete(&retu_rtc_exited);
++}
++
++static ssize_t retu_rtc_time_show(struct device *dev, struct device_attribute *attr,
++				  char *buf)
++{
++	u16 dsr, hmr, dsr2;
++
++	mutex_lock(&retu_rtc_mutex);
++
++	do {
++		u16 dummy;
++
++		/*
++		 * Not being in_interrupt() for a retu rtc IRQ, we need to
++		 * read twice for consistency..
++		 */
++		dummy	= retu_read_reg(RETU_REG_RTCDSR);
++		dsr	= retu_read_reg(RETU_REG_RTCDSR);
++
++		dummy	= retu_read_reg(RETU_REG_RTCHMR);
++		hmr	= retu_read_reg(RETU_REG_RTCHMR);
++
++		dummy	= retu_read_reg(RETU_REG_RTCDSR);
++		dsr2	= retu_read_reg(RETU_REG_RTCDSR);
++	} while ((dsr != dsr2));
++
++	mutex_unlock(&retu_rtc_mutex);
++
++	/*
++	 * Format a 32-bit date-string for userspace
++	 *
++	 * days | hours | minutes | seconds
++	 *
++	 * 8 bits for each.
++	 *
++	 * This mostly sucks because days and seconds are tracked in RTCDSR
++	 * while hours and minutes are tracked in RTCHMR. And yes, there
++	 * really are no words that can describe an 8 bit day register (or
++	 * rather, none that will be reprinted here).
++	 */
++	return sprintf(buf, "0x%08x\n", (((dsr >> 8) & 0xff) << 24) |
++				        (((hmr >> 8) & 0x1f) << 16) |
++					 ((hmr & 0x3f) << 8) | (dsr & 0x3f));
++}
++
++static ssize_t retu_rtc_time_store(struct device *dev, struct device_attribute *attr,
++				   const char *buf, size_t count)
++{
++	mutex_lock(&retu_rtc_mutex);
++	/*
++	 * Writing anything to the day counter forces it to 0
++	 * The seconds counter would be cleared by resetting the minutes counter,
++	 * however this won't happen, since we are using the hh:mm counters as
++	 * a set of free running counters and the day counter as a multiple
++	 * overflow holder.
++	 */
++
++	/* Reset day counter, but keep Temperature Shutdown state */
++	retu_write_reg(RETU_REG_RTCDSR,
++		       retu_read_reg(RETU_REG_RTCDSR) & (1 << 6));
++
++	mutex_unlock(&retu_rtc_mutex);
++
++	return count;
++}
++
++static DEVICE_ATTR(time, S_IRUGO | S_IWUSR, retu_rtc_time_show,
++		   retu_rtc_time_store);
++
++
++static ssize_t retu_rtc_reset_show(struct device *dev, struct device_attribute *attr, char *buf)
++{
++	/*
++	 * Returns the status of the rtc
++	 *
++	 * 0: no reset has occurred or the status has been cleared
++	 * 1: a reset has occurred
++	 *
++	 * RTC needs to be reset only when both main battery
++	 * _AND_ backup battery are discharged
++	 */
++	return sprintf(buf, "%u\n", retu_rtc_reset_occurred);
++}
++
++static void retu_rtc_do_reset(void)
++{
++	u16 ccr1;
++
++	ccr1 = retu_read_reg(RETU_REG_CC1);
++	/* RTC in reset */
++	retu_write_reg(RETU_REG_CC1, ccr1 | 0x0001);
++	/* RTC in normal operating mode */
++	retu_write_reg(RETU_REG_CC1, ccr1 & ~0x0001);
++
++	retu_rtc_barrier();
++	/* Disable alarm and RTC WD */
++	retu_write_reg(RETU_REG_RTCHMAR, 0x7f3f);
++	/* Set Calibration register to default value */
++	retu_write_reg(RETU_REG_RTCCALR, 0x00c0);
++
++	retu_rtc_alarm_expired = 0;
++	retu_rtc_reset_occurred = 1;
++}
++
++static ssize_t retu_rtc_reset_store(struct device *dev, struct device_attribute *attr,
++				    const char *buf, size_t count)
++{
++	unsigned choice;
++
++	if(sscanf(buf, "%u", &choice) != 1)
++		return count;
++	mutex_lock(&retu_rtc_mutex);
++	if (choice == 0)
++		retu_rtc_reset_occurred = 0;
++	else if (choice == 1)
++		retu_rtc_do_reset();
++	mutex_unlock(&retu_rtc_mutex);
++	return count;
++}
++
++static DEVICE_ATTR(reset, S_IRUGO | S_IWUSR, retu_rtc_reset_show,
++		   retu_rtc_reset_store);
++
++static ssize_t retu_rtc_alarm_show(struct device *dev, struct device_attribute *attr,
++				   char *buf)
++{
++	u16 chmar;
++	ssize_t retval;
++
++	mutex_lock(&retu_rtc_mutex);
++	/*
++	 * Format a 16-bit date-string for userspace
++	 *
++	 * hours | minutes
++	 * 8 bits for each.
++	 */
++	chmar = retu_read_reg(RETU_REG_RTCHMAR);
++	/* No shifting needed, only masking unrelated bits */
++	retval = sprintf(buf, "0x%04x\n", chmar & 0x1f3f);
++	mutex_unlock(&retu_rtc_mutex);
++
++	return retval;
++}
++
++static ssize_t retu_rtc_alarm_store(struct device *dev, struct device_attribute *attr,
++				    const char *buf, size_t count)
++{
++	u16 chmar;
++	unsigned alrm;
++	unsigned hours;
++	unsigned minutes;
++
++	mutex_lock(&retu_rtc_mutex);
++
++	if(sscanf(buf, "%x", &alrm) != 1)
++		return count;
++	hours = (alrm >> 8) & 0x001f;
++	minutes = (alrm >> 0) & 0x003f;
++	if ((hours < 24 && minutes < 60) || (hours == 24 && minutes == 60)) {
++		/*
++		 * OK, the time format for the alarm is valid (including the
++		 * disabling values)
++		 */
++		/* Keeps the RTC watchdog status */
++		chmar = retu_read_reg(RETU_REG_RTCHMAR) & 0x6000;
++		chmar |= alrm & 0x1f3f;	/* Stores the requested alarm */
++		retu_rtc_barrier();
++		retu_write_reg(RETU_REG_RTCHMAR, chmar);
++		/* If the alarm is being disabled */
++		if (hours == 24 && minutes == 60) {
++			/* disable the interrupt */
++			retu_disable_irq(RETU_INT_RTCA);
++			retu_rtc_alarm_expired = 0;
++		} else
++			/* enable the interrupt */
++			retu_enable_irq(RETU_INT_RTCA);
++	}
++	mutex_unlock(&retu_rtc_mutex);
++
++	return count;
++}
++
++static DEVICE_ATTR(alarm, S_IRUGO | S_IWUSR, retu_rtc_alarm_show,
++		   retu_rtc_alarm_store);
++
++static ssize_t retu_rtc_alarm_expired_show(struct device *dev, struct device_attribute *attr,
++					   char *buf)
++{
++	ssize_t retval;
++
++	retval = sprintf(buf, "%u\n", retu_rtc_alarm_expired);
++
++	return retval;
++}
++
++static ssize_t retu_rtc_alarm_expired_store(struct device *dev, struct device_attribute *attr,
++					    const char *buf, size_t count)
++{
++	retu_rtc_alarm_expired = 0;
++
++	return count;
++}
++
++static DEVICE_ATTR(alarm_expired, S_IRUGO | S_IWUSR, retu_rtc_alarm_expired_show,
++		   retu_rtc_alarm_expired_store);
++
++
++static ssize_t retu_rtc_cal_show(struct device *dev, struct device_attribute *attr,
++				 char *buf)
++{
++	u16 rtccalr1;
++
++	mutex_lock(&retu_rtc_mutex);
++	rtccalr1 = retu_read_reg(RETU_REG_RTCCALR);
++	mutex_unlock(&retu_rtc_mutex);
++
++	/*
++	 * Shows the status of the Calibration Register.
++	 *
++	 * Default, after power loss: 0x0000
++	 * Default, for R&D: 0x00C0
++	 * Default, for factory: 0x00??
++	 *
++	 */
++	return sprintf(buf, "0x%04x\n", rtccalr1 & 0x00ff);
++}
++
++static ssize_t retu_rtc_cal_store(struct device *dev, struct device_attribute *attr,
++				  const char *buf, size_t count)
++{
++	unsigned calibration_value;
++
++	if (sscanf(buf, "%x", &calibration_value) != 1)
++		return count;
++
++	mutex_lock(&retu_rtc_mutex);
++	retu_rtc_barrier();
++	retu_write_reg(RETU_REG_RTCCALR, calibration_value & 0x00ff);
++	mutex_unlock(&retu_rtc_mutex);
++
++	return count;
++}
++
++static DEVICE_ATTR(cal, S_IRUGO | S_IWUSR, retu_rtc_cal_show,
++		   retu_rtc_cal_store);
++
++static struct platform_device retu_rtc_device;
++
++static void retu_rtca_disable(void)
++{
++	retu_disable_irq(RETU_INT_RTCA);
++	retu_rtc_alarm_expired = 1;
++	retu_rtc_barrier();
++	retu_write_reg(RETU_REG_RTCHMAR, (24 << 8) | 60);
++}
++
++static void retu_rtca_expired(struct work_struct *unused)
++{
++	retu_rtca_disable();
++	sysfs_notify(&retu_rtc_device.dev.kobj, NULL, "alarm_expired");
++}
++
++DECLARE_WORK(retu_rtca_work, retu_rtca_expired);
++
++/*
++ * RTCHMR RTCHMAR RTCCAL must be accessed within 0.9 s since the seconds
++ * interrupt has been signaled in the IDR register
++ */
++static void retu_rtcs_interrupt(unsigned long unused)
++{
++	retu_ack_irq(RETU_INT_RTCS);
++	complete_all(&retu_rtc_sync);
++}
++
++static void retu_rtca_interrupt(unsigned long unused)
++{
++	retu_ack_irq(RETU_INT_RTCA);
++	schedule_work(&retu_rtca_work);
++}
++
++static int retu_rtc_init_irq(void)
++{
++	int ret;
++
++	ret = retu_request_irq(RETU_INT_RTCS, retu_rtcs_interrupt, 0, "RTCS");
++	if (ret != 0)
++		return ret;
++	/*
++	 * We will take care of enabling and disabling the interrupt
++	 * elsewhere, so leave it off by default..
++	 */
++	retu_disable_irq(RETU_INT_RTCS);
++
++	ret = retu_request_irq(RETU_INT_RTCA, retu_rtca_interrupt, 0, "RTCA");
++	if (ret != 0) {
++		retu_free_irq(RETU_INT_RTCS);
++		return ret;
++	}
++	retu_disable_irq(RETU_INT_RTCA);
++
++	return 0;
++}
++
++
++static int __devinit retu_rtc_probe(struct device *dev)
++{
++	int r;
++
++	retu_rtc_alarm_expired = retu_read_reg(RETU_REG_IDR) &
++					       (0x1 << RETU_INT_RTCA);
++
++	if ((r = retu_rtc_init_irq()) != 0)
++		return r;
++
++	mutex_init(&retu_rtc_mutex);
++
++	/* If the calibration register is zero, we've probably lost
++	 * power */
++	if (retu_read_reg(RETU_REG_RTCCALR) & 0x00ff)
++		retu_rtc_reset_occurred = 0;
++	else
++		retu_rtc_do_reset();
++
++	if ((r = device_create_file(dev, &dev_attr_time)) != 0)
++		return r;
++	else if ((r = device_create_file(dev, &dev_attr_reset)) != 0)
++		goto err_unregister_time;
++	else if ((r = device_create_file(dev, &dev_attr_alarm)) != 0)
++		goto err_unregister_reset;
++	else if ((r = device_create_file(dev, &dev_attr_alarm_expired)) != 0)
++		goto err_unregister_alarm;
++	else if ((r = device_create_file(dev, &dev_attr_cal)) != 0)
++		goto err_unregister_alarm_expired;
++	else
++		return r;
++
++err_unregister_alarm_expired:
++	device_remove_file(dev, &dev_attr_alarm_expired);
++err_unregister_alarm:
++	device_remove_file(dev, &dev_attr_alarm);
++err_unregister_reset:
++	device_remove_file(dev, &dev_attr_reset);
++err_unregister_time:
++	device_remove_file(dev, &dev_attr_time);
++	return r;
++}
++
++static int __devexit retu_rtc_remove(struct device *dev)
++{
++	retu_disable_irq(RETU_INT_RTCS);
++	retu_free_irq(RETU_INT_RTCS);
++	retu_free_irq(RETU_INT_RTCA);
++	device_remove_file(dev, &dev_attr_cal);
++	device_remove_file(dev, &dev_attr_alarm_expired);
++	device_remove_file(dev, &dev_attr_alarm);
++	device_remove_file(dev, &dev_attr_reset);
++	device_remove_file(dev, &dev_attr_time);
++	return 0;
++}
++
++static struct device_driver retu_rtc_driver = {
++	.name		= "retu-rtc",
++	.bus		= &platform_bus_type,
++	.probe		= retu_rtc_probe,
++	.remove		= __devexit_p(retu_rtc_remove),
++};
++
++static struct platform_device retu_rtc_device = {
++	.name		= "retu-rtc",
++	.id		= -1,
++	.dev		= {
++		.release	= retu_rtc_device_release,
++	},
++};
++
++/* This function provides syncronization with the RTCS interrupt handler */
++static void retu_rtc_barrier(void)
++{
++	INIT_COMPLETION(retu_rtc_sync);
++	retu_ack_irq(RETU_INT_RTCS);
++	retu_enable_irq(RETU_INT_RTCS);
++	wait_for_completion(&retu_rtc_sync);
++	retu_disable_irq(RETU_INT_RTCS);
++}
++
++static int __init retu_rtc_init(void)
++{
++	int ret;
++
++	init_completion(&retu_rtc_exited);
++
++	if ((ret = driver_register(&retu_rtc_driver)) != 0)
++		return ret;
++
++	if ((ret = platform_device_register(&retu_rtc_device)) != 0)
++		goto err_unregister_driver;
++
++	return 0;
++
++err_unregister_driver:
++	driver_unregister(&retu_rtc_driver);
++	return ret;
++}
++
++static void __exit retu_rtc_exit(void)
++{
++	platform_device_unregister(&retu_rtc_device);
++	driver_unregister(&retu_rtc_driver);
++
++	wait_for_completion(&retu_rtc_exited);
++}
++
++module_init(retu_rtc_init);
++module_exit(retu_rtc_exit);
++
++MODULE_DESCRIPTION("Retu RTC");
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Paul Mundt and Igor Stoppa");
+--- /dev/null
++++ linux-2.6.35/drivers/cbus/retu-user.c
+@@ -0,0 +1,425 @@
++/**
++ * drivers/cbus/retu-user.c
++ *
++ * Retu user space interface functions
++ *
++ * Copyright (C) 2004, 2005 Nokia Corporation
++ *
++ * Written by Mikko Ylinen <[email protected]>
++ *
++ * 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.
++ *
++ * 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/kernel.h>
++#include <linux/interrupt.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/fs.h>
++#include <linux/miscdevice.h>
++#include <linux/poll.h>
++#include <linux/list.h>
++#include <linux/spinlock.h>
++#include <linux/sched.h>
++#include <linux/mutex.h>
++#include <linux/slab.h>
++
++#include <asm/uaccess.h>
++
++#include "retu.h"
++
++#include "user_retu_tahvo.h"
++
++/* Maximum size of IRQ node buffer/pool */
++#define RETU_MAX_IRQ_BUF_LEN	16
++
++#define PFX			"retu-user: "
++
++/* Bitmap for marking the interrupt sources as having the handlers */
++static u32 retu_irq_bits;
++
++/* For allowing only one user process to subscribe to the retu interrupts */
++static struct file *retu_irq_subscr = NULL;
++
++/* For poll and IRQ passing */
++struct retu_irq {
++	u32 id;
++	struct list_head node;
++};
++
++static spinlock_t retu_irqs_lock;
++static struct retu_irq *retu_irq_block;
++static LIST_HEAD(retu_irqs);
++static LIST_HEAD(retu_irqs_reserve);
++
++/* Wait queue - used when user wants to read the device */
++DECLARE_WAIT_QUEUE_HEAD(retu_user_waitqueue);
++
++/* Semaphore to protect irq subscription sequence */
++static struct mutex retu_mutex;
++
++/* This array specifies RETU register types (read/write/toggle) */
++static const u8 retu_access_bits[] = {
++	1,
++	4,
++	3,
++	3,
++	1,
++	3,
++	3,
++	0,
++	3,
++	3,
++	3,
++	3,
++	3,
++	3,
++	3,
++	4,
++	4,
++	3,
++	0,
++	0,
++	0,
++	0,
++	1,
++	3,
++	3,
++	3,
++	3,
++	3,
++	3,
++	3,
++	3,
++	3
++};
++
++/*
++ * The handler for all RETU interrupts.
++ *
++ * arg is the interrupt source in RETU.
++ */
++static void retu_user_irq_handler(unsigned long arg)
++{
++	struct retu_irq *irq;
++
++	retu_ack_irq(arg);
++
++	spin_lock(&retu_irqs_lock);
++	if (list_empty(&retu_irqs_reserve)) {
++		spin_unlock(&retu_irqs_lock);
++		return;
++	}
++	irq = list_entry((&retu_irqs_reserve)->next, struct retu_irq, node);
++	irq->id = arg;
++	list_move_tail(&irq->node, &retu_irqs);
++	spin_unlock(&retu_irqs_lock);
++
++	/* wake up waiting thread */
++	wake_up(&retu_user_waitqueue);
++}
++
++/*
++ * This routine sets up the interrupt handler and marks an interrupt source
++ * in RETU as a candidate for signal delivery to the user process.
++ */
++static int retu_user_subscribe_to_irq(int id, struct file *filp)
++{
++	int ret;
++
++	mutex_lock(&retu_mutex);
++	if ((retu_irq_subscr != NULL) && (retu_irq_subscr != filp)) {
++		mutex_unlock(&retu_mutex);
++		return -EBUSY;
++	}
++	/* Store the file pointer of the first user process registering IRQs */
++	retu_irq_subscr = filp;
++	mutex_unlock(&retu_mutex);
++
++	if (retu_irq_bits & (1 << id))
++		return 0;
++
++	ret = retu_request_irq(id, retu_user_irq_handler, id, "");
++	if (ret < 0)
++		return ret;
++
++	/* Mark that this interrupt has a handler */
++	retu_irq_bits |= 1 << id;
++
++	return 0;
++}
++
++/*
++ * Unregisters all RETU interrupt handlers.
++ */
++static void retu_unreg_irq_handlers(void)
++{
++	int id;
++
++	if (!retu_irq_bits)
++		return;
++
++	for (id = 0; id < MAX_RETU_IRQ_HANDLERS; id++)
++		if (retu_irq_bits & (1 << id))
++			retu_free_irq(id);
++
++	retu_irq_bits = 0;
++}
++
++/*
++ * Write to RETU register.
++ * Returns 0 upon success, a negative error value otherwise.
++ */
++static int retu_user_write_with_mask(u32 field, u16 value)
++{
++	u32 mask;
++	u32 reg;
++	u_short tmp;
++	unsigned long flags;
++
++	mask = MASK(field);
++	reg = REG(field);
++
++	/* Detect bad mask and reg */
++	if (mask == 0 || reg > RETU_REG_MAX ||
++	    retu_access_bits[reg] == READ_ONLY) {
++		printk(KERN_ERR PFX "invalid arguments (reg=%#x, mask=%#x)\n",
++		       reg, mask);
++		return -EINVAL;
++	}
++
++	/* Justify value according to mask */
++	while (!(mask & 1)) {
++		value = value << 1;
++		mask = mask >> 1;
++	}
++
++	spin_lock_irqsave(&retu_lock, flags);
++	if (retu_access_bits[reg] == TOGGLE) {
++		/* No need to detect previous content of register */
++		tmp = 0;
++	} else {
++		/* Read current value of register */
++		tmp = retu_read_reg(reg);
++	}
++
++	/* Generate new value */
++	tmp = (tmp & ~MASK(field)) | (value & MASK(field));
++	/* Write data to RETU */
++	retu_write_reg(reg, tmp);
++	spin_unlock_irqrestore(&retu_lock, flags);
++
++	return 0;
++}
++
++/*
++ * Read RETU register.
++ */
++static u32 retu_user_read_with_mask(u32 field)
++{
++	u_short value;
++	u32 mask, reg;
++
++	mask = MASK(field);
++	reg = REG(field);
++
++	/* Detect bad mask and reg */
++	if (mask == 0 || reg > RETU_REG_MAX) {
++		printk(KERN_ERR PFX "invalid arguments (reg=%#x, mask=%#x)\n",
++		       reg, mask);
++		return -EINVAL;
++	}
++
++	/* Read the register */
++	value = retu_read_reg(reg) & mask;
++
++	/* Right justify value */
++	while (!(mask & 1)) {
++		value = value >> 1;
++		mask = mask >> 1;
++	}
++
++	return value;
++}
++
++/*
++ * Close device
++ */
++static int retu_close(struct inode *inode, struct file *filp)
++{
++	/* Unregister all interrupts that have been registered */
++	if (retu_irq_subscr == filp) {
++		retu_unreg_irq_handlers();
++		retu_irq_subscr = NULL;
++	}
++
++	return 0;
++}
++
++/*
++ * Device control (ioctl)
++ */
++static int retu_ioctl(struct inode *inode, struct file *filp,
++		      unsigned int cmd, unsigned long arg)
++{
++	struct retu_tahvo_write_parms par;
++	int ret;
++
++	switch (cmd) {
++	case URT_IOCT_IRQ_SUBSCR:
++		return retu_user_subscribe_to_irq(arg, filp);
++	case RETU_IOCH_READ:
++		return retu_user_read_with_mask(arg);
++	case RETU_IOCX_WRITE:
++		ret = copy_from_user(&par, (void __user *) arg, sizeof(par));
++		if (ret)
++			printk(KERN_ERR "copy_from_user failed: %d\n", ret);
++		par.result = retu_user_write_with_mask(par.field, par.value);
++		ret = copy_to_user((void __user *) arg, &par, sizeof(par));
++		if (ret)
++			printk(KERN_ERR "copy_to_user failed: %d\n", ret);
++		break;
++	case RETU_IOCH_ADC_READ:
++		return retu_read_adc(arg);
++	default:
++		return -ENOIOCTLCMD;
++	}
++	return 0;
++}
++
++/*
++ * Read from device
++ */
++static ssize_t retu_read(struct file *filp, char *buf, size_t count,
++			 loff_t * offp)
++{
++	struct retu_irq *irq;
++
++	u32 nr, i;
++
++	/* read not permitted if neither filp nor anyone has registered IRQs */
++	if (retu_irq_subscr != filp)
++		return -EPERM;
++
++	if ((count < sizeof(u32)) || ((count % sizeof(u32)) != 0))
++		return -EINVAL;
++
++	nr = count / sizeof(u32);
++
++	for (i = 0; i < nr; i++) {
++		unsigned long flags;
++		u32 irq_id;
++		int ret;
++
++		ret = wait_event_interruptible(retu_user_waitqueue,
++					       !list_empty(&retu_irqs));
++		if (ret < 0)
++			return ret;
++
++		spin_lock_irqsave(&retu_irqs_lock, flags);
++		irq = list_entry((&retu_irqs)->next, struct retu_irq, node);
++		irq_id = irq->id;
++		list_move(&irq->node, &retu_irqs_reserve);
++		spin_unlock_irqrestore(&retu_irqs_lock, flags);
++
++		ret = copy_to_user(buf + i * sizeof(irq_id), &irq_id,
++				   sizeof(irq_id));
++		if (ret)
++			printk(KERN_ERR "copy_to_user failed: %d\n", ret);
++	}
++
++	return count;
++}
++
++/*
++ * Poll method
++ */
++static unsigned retu_poll(struct file *filp, struct poll_table_struct *pt)
++{
++	if (!list_empty(&retu_irqs))
++		return POLLIN;
++
++	poll_wait(filp, &retu_user_waitqueue, pt);
++
++	if (!list_empty(&retu_irqs))
++		return POLLIN;
++	else
++		return 0;
++}
++
++static struct file_operations retu_user_fileops = {
++	.owner = THIS_MODULE,
++	.ioctl = retu_ioctl,
++	.read = retu_read,
++	.release = retu_close,
++	.poll = retu_poll
++};
++
++static struct miscdevice retu_device = {
++	.minor = MISC_DYNAMIC_MINOR,
++	.name = "retu",
++	.fops = &retu_user_fileops
++};
++
++/*
++ * Initialization
++ *
++ * @return 0 if successful, error value otherwise.
++ */
++int retu_user_init(void)
++{
++	struct retu_irq *irq;
++	int res, i;
++
++	irq = kmalloc(sizeof(*irq) * RETU_MAX_IRQ_BUF_LEN, GFP_KERNEL);
++	if (irq == NULL) {
++		printk(KERN_ERR PFX "kmalloc failed\n");
++		return -ENOMEM;
++	}
++	memset(irq, 0, sizeof(*irq) * RETU_MAX_IRQ_BUF_LEN);
++	for (i = 0; i < RETU_MAX_IRQ_BUF_LEN; i++)
++		list_add(&irq[i].node, &retu_irqs_reserve);
++
++	retu_irq_block = irq;
++
++	spin_lock_init(&retu_irqs_lock);
++	mutex_init(&retu_mutex);
++
++	/* Request a misc device */
++	res = misc_register(&retu_device);
++	if (res < 0) {
++		printk(KERN_ERR PFX "unable to register misc device for %s\n",
++		       retu_device.name);
++		kfree(irq);
++		return res;
++	}
++
++	return 0;
++}
++
++/*
++ * Cleanup.
++ */
++void retu_user_cleanup(void)
++{
++	/* Unregister our misc device */
++	misc_deregister(&retu_device);
++	/* Unregister and disable all RETU interrupts used by this module */
++	retu_unreg_irq_handlers();
++	kfree(retu_irq_block);
++}
++
++MODULE_DESCRIPTION("Retu ASIC user space functions");
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Mikko Ylinen");
+--- /dev/null
++++ linux-2.6.35/drivers/cbus/retu-wdt.c
+@@ -0,0 +1,388 @@
++/**
++ * drivers/cbus/retu-wdt.c
++ *
++ * Driver for Retu watchdog
++ *
++ * Copyright (C) 2004, 2005 Nokia Corporation
++ *
++ * Written by Amit Kucheria <[email protected]>
++ *
++ * 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.
++ *
++ * 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/kernel.h>
++#include <linux/module.h>
++#include <linux/device.h>
++#include <linux/init.h>
++#include <linux/fs.h>
++#include <linux/io.h>
++#include <linux/platform_device.h>
++#include <linux/slab.h>
++
++#include <linux/completion.h>
++#include <linux/errno.h>
++#include <linux/moduleparam.h>
++#include <linux/platform_device.h>
++#include <linux/miscdevice.h>
++#include <linux/watchdog.h>
++
++#include <asm/uaccess.h>
++
++#include <plat/prcm.h>
++
++#include "cbus.h"
++#include "retu.h"
++
++/* Watchdog timeout in seconds */
++#define RETU_WDT_MIN_TIMER 0
++#define RETU_WDT_DEFAULT_TIMER 32
++#define RETU_WDT_MAX_TIMER 63
++
++static struct completion retu_wdt_completion;
++static DEFINE_MUTEX(retu_wdt_mutex);
++
++/* Current period of watchdog */
++static unsigned int period_val = RETU_WDT_DEFAULT_TIMER;
++static int counter_param = RETU_WDT_MAX_TIMER;
++
++struct retu_wdt_dev {
++	struct device		*dev;
++	int			users;
++	struct miscdevice	retu_wdt_miscdev;
++	struct timer_list	ping_timer;
++};
++
++static struct retu_wdt_dev *retu_wdt;
++
++static void retu_wdt_set_ping_timer(unsigned long enable);
++
++static int _retu_modify_counter(unsigned int new)
++{
++	retu_write_reg(RETU_REG_WATCHDOG, (u16)new);
++
++	return 0;
++}
++
++static int retu_modify_counter(unsigned int new)
++{
++	if (new < RETU_WDT_MIN_TIMER || new > RETU_WDT_MAX_TIMER)
++		return -EINVAL;
++
++	mutex_lock(&retu_wdt_mutex);
++	period_val = new;
++	_retu_modify_counter(period_val);
++	mutex_unlock(&retu_wdt_mutex);
++
++	return 0;
++}
++
++static ssize_t retu_wdt_period_show(struct device *dev,
++				struct device_attribute *attr, char *buf)
++{
++	/* Show current max counter */
++	return sprintf(buf, "%u\n", (u16)period_val);
++}
++
++/*
++ * Note: This inteface is non-standard and likely to disappear!
++ * Use /dev/watchdog instead, that's the standard.
++ */
++static ssize_t retu_wdt_period_store(struct device *dev,
++				struct device_attribute *attr,
++				const char *buf, size_t count)
++{
++	unsigned int new_period;
++	int ret;
++
++#ifdef CONFIG_WATCHDOG_NOWAYOUT
++	retu_wdt_set_ping_timer(0);
++#endif
++
++	if (sscanf(buf, "%u", &new_period) != 1) {
++		printk(KERN_ALERT "retu_wdt_period_store: Invalid input\n");
++		return -EINVAL;
++	}
++
++	ret = retu_modify_counter(new_period);
++	if (ret < 0)
++		return ret;
++
++	return strnlen(buf, count);
++}
++
++static ssize_t retu_wdt_counter_show(struct device *dev,
++				struct device_attribute *attr, char *buf)
++{
++	u16 counter;
++
++	/* Show current value in watchdog counter */
++	counter = retu_read_reg(RETU_REG_WATCHDOG);
++
++	/* Only the 5 LSB are important */
++	return snprintf(buf, PAGE_SIZE, "%u\n", (counter & 0x3F));
++}
++
++static DEVICE_ATTR(period, S_IRUGO | S_IWUSR, retu_wdt_period_show, \
++			retu_wdt_period_store);
++static DEVICE_ATTR(counter, S_IRUGO, retu_wdt_counter_show, NULL);
++
++/*----------------------------------------------------------------------------*/
++
++/*
++ * Since retu watchdog cannot be disabled in hardware, we must kick it
++ * with a timer until userspace watchdog software takes over. Do this
++ * unless /dev/watchdog is open or CONFIG_WATCHDOG_NOWAYOUT is set.
++ */
++static void retu_wdt_set_ping_timer(unsigned long enable)
++{
++	_retu_modify_counter(RETU_WDT_MAX_TIMER);
++	if (enable)
++		mod_timer(&retu_wdt->ping_timer,
++				jiffies + RETU_WDT_DEFAULT_TIMER * HZ);
++	else
++		del_timer_sync(&retu_wdt->ping_timer);
++}
++
++static int retu_wdt_open(struct inode *inode, struct file *file)
++{
++	if (test_and_set_bit(1, (unsigned long *)&(retu_wdt->users)))
++		return -EBUSY;
++
++	file->private_data = (void *)retu_wdt;
++	retu_wdt_set_ping_timer(0);
++
++	return nonseekable_open(inode, file);
++}
++
++static int retu_wdt_release(struct inode *inode, struct file *file)
++{
++	struct retu_wdt_dev *wdev = file->private_data;
++
++#ifndef CONFIG_WATCHDOG_NOWAYOUT
++	retu_wdt_set_ping_timer(1);
++#endif
++	wdev->users = 0;
++
++	return 0;
++}
++
++static ssize_t retu_wdt_write(struct file *file, const char __user *data,
++						size_t len, loff_t *ppos)
++{
++	if (len)
++		retu_modify_counter(RETU_WDT_MAX_TIMER);
++
++	return len;
++}
++
++static int retu_wdt_ioctl(struct inode *inode, struct file *file,
++					unsigned int cmd, unsigned long arg)
++{
++	int new_margin;
++
++	static struct watchdog_info ident = {
++		.identity = "Retu Watchdog",
++		.options = WDIOF_SETTIMEOUT,
++		.firmware_version = 0,
++	};
++
++	switch (cmd) {
++	default:
++		return -ENOTTY;
++	case WDIOC_GETSUPPORT:
++		return copy_to_user((struct watchdog_info __user *)arg, &ident,
++							sizeof(ident));
++	case WDIOC_GETSTATUS:
++		return put_user(0, (int __user *)arg);
++	case WDIOC_GETBOOTSTATUS:
++		if (cpu_is_omap16xx())
++			return put_user(omap_readw(ARM_SYSST),
++					(int __user *)arg);
++		if (cpu_is_omap24xx())
++			return put_user(omap_prcm_get_reset_sources(),
++					(int __user *)arg);
++	case WDIOC_KEEPALIVE:
++		retu_modify_counter(RETU_WDT_MAX_TIMER);
++		break;
++	case WDIOC_SETTIMEOUT:
++		if (get_user(new_margin, (int __user *)arg))
++			return -EFAULT;
++		retu_modify_counter(new_margin);
++		/* Fall through */
++	case WDIOC_GETTIMEOUT:
++		return put_user(period_val, (int __user *)arg);
++	}
++
++	return 0;
++}
++
++/* Start kicking retu watchdog until user space starts doing the kicking */
++static int __init retu_wdt_ping(void)
++{
++
++#ifdef CONFIG_WATCHDOG_NOWAYOUT
++	retu_modify_counter(RETU_WDT_MAX_TIMER);
++#else
++	retu_wdt_set_ping_timer(1);
++#endif
++
++	return 0;
++}
++late_initcall(retu_wdt_ping);
++
++static const struct file_operations retu_wdt_fops = {
++	.owner = THIS_MODULE,
++	.write = retu_wdt_write,
++	.ioctl = retu_wdt_ioctl,
++	.open = retu_wdt_open,
++	.release = retu_wdt_release,
++};
++
++/*----------------------------------------------------------------------------*/
++
++static int __devinit retu_wdt_probe(struct device *dev)
++{
++	struct retu_wdt_dev *wdev;
++	int ret;
++
++	wdev = kzalloc(sizeof(struct retu_wdt_dev), GFP_KERNEL);
++	if (!wdev)
++		return -ENOMEM;
++
++	wdev->users = 0;
++
++	ret = device_create_file(dev, &dev_attr_period);
++	if (ret) {
++		printk(KERN_ERR "retu_wdt_probe: Error creating "
++					"sys device file: period\n");
++		goto free1;
++	}
++
++	ret = device_create_file(dev, &dev_attr_counter);
++	if (ret) {
++		printk(KERN_ERR "retu_wdt_probe: Error creating "
++					"sys device file: counter\n");
++		goto free2;
++	}
++
++	dev_set_drvdata(dev, wdev);
++	retu_wdt = wdev;
++	wdev->retu_wdt_miscdev.parent = dev;
++	wdev->retu_wdt_miscdev.minor = WATCHDOG_MINOR;
++	wdev->retu_wdt_miscdev.name = "watchdog";
++	wdev->retu_wdt_miscdev.fops = &retu_wdt_fops;
++
++	ret = misc_register(&(wdev->retu_wdt_miscdev));
++	if (ret)
++		goto free3;
++
++	setup_timer(&wdev->ping_timer, retu_wdt_set_ping_timer, 1);
++
++	/* Kick the watchdog for kernel booting to finish */
++	retu_modify_counter(RETU_WDT_MAX_TIMER);
++
++	return 0;
++
++free3:
++	device_remove_file(dev, &dev_attr_counter);
++
++free2:
++	device_remove_file(dev, &dev_attr_period);
++free1:
++	kfree(wdev);
++
++	return ret;
++}
++
++static int __devexit retu_wdt_remove(struct device *dev)
++{
++	struct retu_wdt_dev *wdev;
++
++	wdev = dev_get_drvdata(dev);
++	misc_deregister(&(wdev->retu_wdt_miscdev));
++	device_remove_file(dev, &dev_attr_period);
++	device_remove_file(dev, &dev_attr_counter);
++	kfree(wdev);
++
++	return 0;
++}
++
++static void retu_wdt_device_release(struct device *dev)
++{
++	complete(&retu_wdt_completion);
++}
++
++static struct platform_device retu_wdt_device = {
++	.name = "retu-watchdog",
++	.id = -1,
++	.dev = {
++		.release = retu_wdt_device_release,
++	},
++};
++
++static struct device_driver retu_wdt_driver = {
++	.name = "retu-watchdog",
++	.bus = &platform_bus_type,
++	.probe = retu_wdt_probe,
++	.remove = __devexit_p(retu_wdt_remove),
++};
++
++static int __init retu_wdt_init(void)
++{
++	int ret;
++
++	init_completion(&retu_wdt_completion);
++
++	ret = driver_register(&retu_wdt_driver);
++	if (ret)
++		return ret;
++
++	ret = platform_device_register(&retu_wdt_device);
++	if (ret)
++		goto exit1;
++
++	/* passed as module parameter? */
++	ret = retu_modify_counter(counter_param);
++	if (ret == -EINVAL) {
++		ret = retu_modify_counter(RETU_WDT_DEFAULT_TIMER);
++		printk(KERN_INFO
++		       "retu_wdt_init: Intializing to default value\n");
++	}
++
++	printk(KERN_INFO "Retu watchdog driver initialized\n");
++	return ret;
++
++exit1:
++	driver_unregister(&retu_wdt_driver);
++	wait_for_completion(&retu_wdt_completion);
++
++	return ret;
++}
++
++static void __exit retu_wdt_exit(void)
++{
++	platform_device_unregister(&retu_wdt_device);
++	driver_unregister(&retu_wdt_driver);
++
++	wait_for_completion(&retu_wdt_completion);
++}
++
++module_init(retu_wdt_init);
++module_exit(retu_wdt_exit);
++module_param(counter_param, int, 0);
++
++MODULE_DESCRIPTION("Retu WatchDog");
++MODULE_AUTHOR("Amit Kucheria");
++MODULE_LICENSE("GPL");
++
+--- /dev/null
++++ linux-2.6.35/drivers/cbus/tahvo.c
+@@ -0,0 +1,443 @@
++/**
++ * drivers/cbus/tahvo.c
++ *
++ * Support functions for Tahvo ASIC
++ *
++ * Copyright (C) 2004, 2005 Nokia Corporation
++ *
++ * Written by Juha Yrjölä <[email protected]>,
++ *	      David Weinehall <[email protected]>, and
++ *	      Mikko Ylinen <[email protected]>
++ *
++ * 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.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ */
++
++#include <linux/module.h>
++#include <linux/init.h>
++
++#include <linux/kernel.h>
++#include <linux/errno.h>
++#include <linux/device.h>
++#include <linux/miscdevice.h>
++#include <linux/poll.h>
++#include <linux/fs.h>
++#include <linux/irq.h>
++#include <linux/interrupt.h>
++#include <linux/platform_device.h>
++#include <linux/gpio.h>
++
++#include <asm/uaccess.h>
++#include <asm/mach-types.h>
++
++#include <plat/mux.h>
++#include <plat/board.h>
++
++#include "cbus.h"
++#include "tahvo.h"
++
++#define TAHVO_ID		0x02
++#define PFX			"tahvo: "
++
++static int tahvo_initialized;
++static int tahvo_irq_pin;
++static int tahvo_is_betty;
++
++static struct tasklet_struct tahvo_tasklet;
++spinlock_t tahvo_lock = SPIN_LOCK_UNLOCKED;
++
++static struct completion device_release;
++
++struct tahvo_irq_handler_desc {
++	int (*func)(unsigned long);
++	unsigned long arg;
++	char name[8];
++};
++
++static struct tahvo_irq_handler_desc tahvo_irq_handlers[MAX_TAHVO_IRQ_HANDLERS];
++
++/**
++ * tahvo_read_reg - Read a value from a register in Tahvo
++ * @reg: the register to read from
++ *
++ * This function returns the contents of the specified register
++ */
++int tahvo_read_reg(int reg)
++{
++	BUG_ON(!tahvo_initialized);
++	return cbus_read_reg(cbus_host, TAHVO_ID, reg);
++}
++
++/**
++ * tahvo_write_reg - Write a value to a register in Tahvo
++ * @reg: the register to write to
++ * @reg: the value to write to the register
++ *
++ * This function writes a value to the specified register
++ */
++void tahvo_write_reg(int reg, u16 val)
++{
++	BUG_ON(!tahvo_initialized);
++	cbus_write_reg(cbus_host, TAHVO_ID, reg, val);
++}
++
++/**
++ * tahvo_set_clear_reg_bits - set and clear register bits atomically
++ * @reg: the register to write to
++ * @bits: the bits to set
++ *
++ * This function sets and clears the specified Tahvo register bits atomically
++ */
++void tahvo_set_clear_reg_bits(int reg, u16 set, u16 clear)
++{
++	unsigned long flags;
++	u16 w;
++
++	spin_lock_irqsave(&tahvo_lock, flags);
++	w = tahvo_read_reg(reg);
++	w &= ~clear;
++	w |= set;
++	tahvo_write_reg(reg, w);
++	spin_unlock_irqrestore(&tahvo_lock, flags);
++}
++
++/*
++ * Disable given TAHVO interrupt
++ */
++void tahvo_disable_irq(int id)
++{
++	unsigned long flags;
++	u16 mask;
++
++	spin_lock_irqsave(&tahvo_lock, flags);
++	mask = tahvo_read_reg(TAHVO_REG_IMR);
++	mask |= 1 << id;
++	tahvo_write_reg(TAHVO_REG_IMR, mask);
++	spin_unlock_irqrestore(&tahvo_lock, flags);
++}
++
++/*
++ * Enable given TAHVO interrupt
++ */
++void tahvo_enable_irq(int id)
++{
++	unsigned long flags;
++	u16 mask;
++
++	spin_lock_irqsave(&tahvo_lock, flags);
++	mask = tahvo_read_reg(TAHVO_REG_IMR);
++	mask &= ~(1 << id);
++	tahvo_write_reg(TAHVO_REG_IMR, mask);
++	spin_unlock_irqrestore(&tahvo_lock, flags);
++}
++
++/*
++ * Acknowledge given TAHVO interrupt
++ */
++void tahvo_ack_irq(int id)
++{
++	tahvo_write_reg(TAHVO_REG_IDR, 1 << id);
++}
++
++static int tahvo_7bit_backlight;
++
++int tahvo_get_backlight_level(void)
++{
++	int mask;
++
++	if (tahvo_7bit_backlight)
++		mask = 0x7f;
++	else
++		mask = 0x0f;
++	return tahvo_read_reg(TAHVO_REG_LEDPWMR) & mask;
++}
++
++int tahvo_get_max_backlight_level(void)
++{
++	if (tahvo_7bit_backlight)
++		return 0x7f;
++	else
++		return 0x0f;
++}
++
++void tahvo_set_backlight_level(int level)
++{
++	int max_level;
++
++	max_level = tahvo_get_max_backlight_level();
++	if (level > max_level)
++		level = max_level;
++	tahvo_write_reg(TAHVO_REG_LEDPWMR, level);
++}
++
++/*
++ * TAHVO interrupt handler. Only schedules the tasklet.
++ */
++static irqreturn_t tahvo_irq_handler(int irq, void *dev_id)
++{
++	tasklet_schedule(&tahvo_tasklet);
++	return IRQ_HANDLED;
++}
++
++/*
++ * Tasklet handler
++ */
++static void tahvo_tasklet_handler(unsigned long data)
++{
++	struct tahvo_irq_handler_desc *hnd;
++	u16 id;
++	u16 im;
++	int i;
++
++	for (;;) {
++		id = tahvo_read_reg(TAHVO_REG_IDR);
++		im = ~tahvo_read_reg(TAHVO_REG_IMR);
++		id &= im;
++
++		if (!id)
++			break;
++
++		for (i = 0; id != 0; i++, id >>= 1) {
++			if (!(id & 1))
++				continue;
++			hnd = &tahvo_irq_handlers[i];
++			if (hnd->func == NULL) {
++				/* Spurious tahvo interrupt - just ack it */
++				printk(KERN_INFO "Spurious Tahvo interrupt "
++						 "(id %d)\n", i);
++				tahvo_disable_irq(i);
++				tahvo_ack_irq(i);
++				continue;
++			}
++			hnd->func(hnd->arg);
++			/*
++			 * Don't acknowledge the interrupt here
++			 * It must be done explicitly
++			 */
++		}
++	}
++}
++
++/*
++ * Register the handler for a given TAHVO interrupt source.
++ */
++int tahvo_request_irq(int id, void *irq_handler, unsigned long arg, char *name)
++{
++	struct tahvo_irq_handler_desc *hnd;
++
++	if (irq_handler == NULL || id >= MAX_TAHVO_IRQ_HANDLERS ||
++	    name == NULL) {
++		printk(KERN_ERR PFX "Invalid arguments to %s\n",
++		       __FUNCTION__);
++		return -EINVAL;
++	}
++	hnd = &tahvo_irq_handlers[id];
++	if (hnd->func != NULL) {
++		printk(KERN_ERR PFX "IRQ %d already reserved\n", id);
++		return -EBUSY;
++	}
++	printk(KERN_INFO PFX "Registering interrupt %d for device %s\n",
++	       id, name);
++	hnd->func = irq_handler;
++	hnd->arg = arg;
++	strlcpy(hnd->name, name, sizeof(hnd->name));
++
++	tahvo_ack_irq(id);
++	tahvo_enable_irq(id);
++
++	return 0;
++}
++
++/*
++ * Unregister the handler for a given TAHVO interrupt source.
++ */
++void tahvo_free_irq(int id)
++{
++	struct tahvo_irq_handler_desc *hnd;
++
++	if (id >= MAX_TAHVO_IRQ_HANDLERS) {
++		printk(KERN_ERR PFX "Invalid argument to %s\n",
++		       __FUNCTION__);
++		return;
++	}
++	hnd = &tahvo_irq_handlers[id];
++	if (hnd->func == NULL) {
++		printk(KERN_ERR PFX "IRQ %d already freed\n", id);
++		return;
++	}
++
++	tahvo_disable_irq(id);
++	hnd->func = NULL;
++}
++
++/**
++ * tahvo_probe - Probe for Tahvo ASIC
++ * @dev: the Tahvo device
++ *
++ * Probe for the Tahvo ASIC and allocate memory
++ * for its device-struct if found
++ */
++static int __devinit tahvo_probe(struct device *dev)
++{
++	int rev, id, ret;
++
++	/* Prepare tasklet */
++	tasklet_init(&tahvo_tasklet, tahvo_tasklet_handler, 0);
++
++	tahvo_initialized = 1;
++
++	rev = tahvo_read_reg(TAHVO_REG_ASICR);
++
++	id = (rev >> 8) & 0xff;
++	if (id == 0x03) {
++		if ((rev & 0xff) >= 0x50)
++			tahvo_7bit_backlight = 1;
++	} else if (id == 0x0b) {
++		tahvo_is_betty = 1;
++		tahvo_7bit_backlight = 1;
++	} else {
++		printk(KERN_ERR "Tahvo/Betty chip not found");
++		return -ENODEV;
++	}
++
++	printk(KERN_INFO "%s v%d.%d found\n", tahvo_is_betty ? "Betty" : "Tahvo",
++	       (rev >> 4) & 0x0f, rev & 0x0f);
++
++	/* REVISIT: Pass these from board-*.c files in platform_data */
++	if (machine_is_nokia770()) {
++		tahvo_irq_pin = 40;
++	} else if (machine_is_nokia_n800() || machine_is_nokia_n810() ||
++			machine_is_nokia_n810_wimax()) {
++		tahvo_irq_pin = 111;
++	} else {
++		printk(KERN_ERR "cbus: Unsupported board for tahvo\n");
++		return -ENODEV;
++	}
++
++	if ((ret = gpio_request(tahvo_irq_pin, "TAHVO irq")) < 0) {
++		printk(KERN_ERR PFX "Unable to reserve IRQ GPIO\n");
++		return ret;
++	}
++
++	/* Set the pin as input */
++	gpio_direction_input(tahvo_irq_pin);
++
++	/* Rising edge triggers the IRQ */
++	set_irq_type(gpio_to_irq(tahvo_irq_pin), IRQ_TYPE_EDGE_RISING);
++
++	/* Mask all TAHVO interrupts */
++	tahvo_write_reg(TAHVO_REG_IMR, 0xffff);
++
++	ret = request_irq(gpio_to_irq(tahvo_irq_pin), tahvo_irq_handler, 0,
++			  "tahvo", 0);
++	if (ret < 0) {
++		printk(KERN_ERR PFX "Unable to register IRQ handler\n");
++		gpio_free(tahvo_irq_pin);
++		return ret;
++	}
++#ifdef CONFIG_CBUS_TAHVO_USER
++	/* Initialize user-space interface */
++	if (tahvo_user_init() < 0) {
++		printk(KERN_ERR "Unable to initialize driver\n");
++		free_irq(gpio_to_irq(tahvo_irq_pin), 0);
++		gpio_free(tahvo_irq_pin);
++		return ret;
++	}
++#endif
++	return 0;
++}
++
++static int tahvo_remove(struct device *dev)
++{
++#ifdef CONFIG_CBUS_TAHVO_USER
++	tahvo_user_cleanup();
++#endif
++	/* Mask all TAHVO interrupts */
++	tahvo_write_reg(TAHVO_REG_IMR, 0xffff);
++	free_irq(gpio_to_irq(tahvo_irq_pin), 0);
++	gpio_free(tahvo_irq_pin);
++	tasklet_kill(&tahvo_tasklet);
++
++	return 0;
++}
++
++static void tahvo_device_release(struct device *dev)
++{
++	complete(&device_release);
++}
++
++static struct device_driver tahvo_driver = {
++	.name		= "tahvo",
++	.bus		= &platform_bus_type,
++	.probe		= tahvo_probe,
++	.remove		= tahvo_remove,
++};
++
++static struct platform_device tahvo_device = {
++	.name		= "tahvo",
++	.id		= -1,
++	.dev = {
++		.release = tahvo_device_release,
++	}
++};
++
++/**
++ * tahvo_init - initialise Tahvo driver
++ *
++ * Initialise the Tahvo driver and return 0 if everything worked ok
++ */
++static int __init tahvo_init(void)
++{
++	int ret = 0;
++
++	printk(KERN_INFO "Tahvo/Betty driver initialising\n");
++
++	init_completion(&device_release);
++
++	if ((ret = driver_register(&tahvo_driver)) < 0)
++		return ret;
++
++	if ((ret = platform_device_register(&tahvo_device)) < 0) {
++		driver_unregister(&tahvo_driver);
++		return ret;
++	}
++	return 0;
++}
++
++/*
++ * Cleanup
++ */
++static void __exit tahvo_exit(void)
++{
++	platform_device_unregister(&tahvo_device);
++	driver_unregister(&tahvo_driver);
++	wait_for_completion(&device_release);
++}
++
++EXPORT_SYMBOL(tahvo_request_irq);
++EXPORT_SYMBOL(tahvo_free_irq);
++EXPORT_SYMBOL(tahvo_enable_irq);
++EXPORT_SYMBOL(tahvo_disable_irq);
++EXPORT_SYMBOL(tahvo_ack_irq);
++EXPORT_SYMBOL(tahvo_read_reg);
++EXPORT_SYMBOL(tahvo_write_reg);
++EXPORT_SYMBOL(tahvo_get_backlight_level);
++EXPORT_SYMBOL(tahvo_get_max_backlight_level);
++EXPORT_SYMBOL(tahvo_set_backlight_level);
++
++subsys_initcall(tahvo_init);
++module_exit(tahvo_exit);
++
++MODULE_DESCRIPTION("Tahvo ASIC control");
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Juha Yrjölä, David Weinehall, and Mikko Ylinen");
+--- /dev/null
++++ linux-2.6.35/drivers/cbus/tahvo.h
+@@ -0,0 +1,61 @@
++/*
++ * drivers/cbus/tahvo.h
++ *
++ * Copyright (C) 2004, 2005 Nokia Corporation
++ *
++ * Written by Juha Yrjölä <[email protected]> and
++ *	      David Weinehall <[email protected]>
++ *
++ * 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.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ */
++
++#ifndef __DRIVERS_CBUS_TAHVO_H
++#define __DRIVERS_CBUS_TAHVO_H
++
++#include <linux/types.h>
++
++/* Registers */
++#define TAHVO_REG_ASICR		0x00	/* ASIC ID & revision */
++#define TAHVO_REG_IDR		0x01	/* Interrupt ID */
++#define TAHVO_REG_IDSR		0x02	/* Interrupt status */
++#define TAHVO_REG_IMR		0x03	/* Interrupt mask */
++#define TAHVO_REG_LEDPWMR	0x05	/* LED PWM */
++#define TAHVO_REG_USBR		0x06	/* USB control */
++#define TAHVO_REG_MAX		0x0d
++
++/* Interrupt sources */
++#define TAHVO_INT_VBUSON	0
++
++#define MAX_TAHVO_IRQ_HANDLERS	8
++
++int tahvo_read_reg(int reg);
++void tahvo_write_reg(int reg, u16 val);
++void tahvo_set_clear_reg_bits(int reg, u16 set, u16 clear);
++int tahvo_request_irq(int id, void *irq_handler, unsigned long arg, char *name);
++void tahvo_free_irq(int id);
++void tahvo_enable_irq(int id);
++void tahvo_disable_irq(int id);
++void tahvo_ack_irq(int id);
++int tahvo_get_backlight_level(void);
++int tahvo_get_max_backlight_level(void);
++void tahvo_set_backlight_level(int level);
++
++#ifdef CONFIG_CBUS_TAHVO_USER
++int tahvo_user_init(void);
++void tahvo_user_cleanup(void);
++#endif
++
++extern spinlock_t tahvo_lock;
++
++#endif /* __DRIVERS_CBUS_TAHVO_H */
+--- /dev/null
++++ linux-2.6.35/drivers/cbus/tahvo-usb.c
+@@ -0,0 +1,777 @@
++/**
++ * drivers/cbus/tahvo-usb.c
++ *
++ * Tahvo USB transeiver
++ *
++ * Copyright (C) 2005-2006 Nokia Corporation
++ *
++ * Parts copied from drivers/i2c/chips/isp1301_omap.c
++ * Copyright (C) 2004 Texas Instruments
++ * Copyright (C) 2004 David Brownell
++ *
++ * Written by Juha Yrjölä <[email protected]>,
++ *	      Tony Lindgren <[email protected]>, and
++ *	      Timo Teräs <[email protected]>
++ *
++ * 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.
++ *
++ * 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/kernel.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/slab.h>
++#include <linux/io.h>
++#include <linux/interrupt.h>
++#include <linux/platform_device.h>
++#include <linux/usb/ch9.h>
++#include <linux/usb/gadget.h>
++#include <linux/usb.h>
++#include <linux/usb/otg.h>
++#include <linux/i2c.h>
++#include <linux/workqueue.h>
++#include <linux/kobject.h>
++#include <linux/clk.h>
++#include <linux/mutex.h>
++
++#include <asm/irq.h>
++#include <plat/usb.h>
++
++#include "cbus.h"
++#include "tahvo.h"
++
++#define DRIVER_NAME     "tahvo-usb"
++
++#define USBR_SLAVE_CONTROL	(1 << 8)
++#define USBR_VPPVIO_SW		(1 << 7)
++#define USBR_SPEED		(1 << 6)
++#define USBR_REGOUT		(1 << 5)
++#define USBR_MASTER_SW2		(1 << 4)
++#define USBR_MASTER_SW1		(1 << 3)
++#define USBR_SLAVE_SW		(1 << 2)
++#define USBR_NSUSPEND		(1 << 1)
++#define USBR_SEMODE		(1 << 0)
++
++/* bits in OTG_CTRL */
++
++/* Bits that are controlled by OMAP OTG and are read-only */
++#define OTG_CTRL_OMAP_MASK	(OTG_PULLDOWN|OTG_PULLUP|OTG_DRV_VBUS|\
++				OTG_PD_VBUS|OTG_PU_VBUS|OTG_PU_ID)
++/* Bits that are controlled by transceiver */
++#define OTG_CTRL_XCVR_MASK	(OTG_ASESSVLD|OTG_BSESSEND|\
++				OTG_BSESSVLD|OTG_VBUSVLD|OTG_ID)
++/* Bits that are controlled by system */
++#define OTG_CTRL_SYS_MASK	(OTG_A_BUSREQ|OTG_A_SETB_HNPEN|OTG_B_BUSREQ|\
++				OTG_B_HNPEN|OTG_BUSDROP)
++
++#if defined(CONFIG_USB_OHCI_HCD) && !defined(CONFIG_USB_OTG)
++#error tahvo-otg.c does not work with OCHI yet!
++#endif
++
++#define TAHVO_MODE_HOST		0
++#define TAHVO_MODE_PERIPHERAL	1
++
++#ifdef CONFIG_USB_OTG
++#define TAHVO_MODE(tu)		(tu)->tahvo_mode
++#elif defined(CONFIG_USB_GADGET_OMAP)
++#define TAHVO_MODE(tu)		TAHVO_MODE_PERIPHERAL
++#else
++#define TAHVO_MODE(tu)		TAHVO_MODE_HOST
++#endif
++
++struct tahvo_usb {
++	struct platform_device *pt_dev;
++	struct otg_transceiver otg;
++	int vbus_state;
++	struct work_struct irq_work;
++	struct mutex serialize;
++#ifdef CONFIG_USB_OTG
++	int tahvo_mode;
++#endif
++};
++static struct platform_device tahvo_usb_device;
++
++/*
++ * ---------------------------------------------------------------------------
++ * OTG related functions
++ *
++ * These shoud be separated into omap-otg.c driver module, as they are used
++ * by various transceivers. These functions are needed in the UDC-only case
++ * as well. These functions are copied from GPL isp1301_omap.c
++ * ---------------------------------------------------------------------------
++ */
++static struct platform_device *tahvo_otg_dev;
++
++static irqreturn_t omap_otg_irq(int irq, void *arg)
++{
++	struct platform_device *otg_dev = arg;
++	struct tahvo_usb *tu = platform_get_drvdata(otg_dev);
++	u16 otg_irq;
++
++	otg_irq = omap_readw(OTG_IRQ_SRC);
++	if (otg_irq & OPRT_CHG) {
++		omap_writew(OPRT_CHG, OTG_IRQ_SRC);
++	} else if (otg_irq & B_SRP_TMROUT) {
++		omap_writew(B_SRP_TMROUT, OTG_IRQ_SRC);
++	} else if (otg_irq & B_HNP_FAIL) {
++		omap_writew(B_HNP_FAIL, OTG_IRQ_SRC);
++	} else if (otg_irq & A_SRP_DETECT) {
++		omap_writew(A_SRP_DETECT, OTG_IRQ_SRC);
++	} else if (otg_irq & A_REQ_TMROUT) {
++		omap_writew(A_REQ_TMROUT, OTG_IRQ_SRC);
++	} else if (otg_irq & A_VBUS_ERR) {
++		omap_writew(A_VBUS_ERR, OTG_IRQ_SRC);
++	} else if (otg_irq & DRIVER_SWITCH) {
++		if ((!(omap_readl(OTG_CTRL) & OTG_DRIVER_SEL)) &&
++		   tu->otg.host && tu->otg.state == OTG_STATE_A_HOST) {
++			/* role is host */
++			usb_bus_start_enum(tu->otg.host,
++					   tu->otg.host->otg_port);
++		}
++		omap_writew(DRIVER_SWITCH, OTG_IRQ_SRC);
++	} else
++		return IRQ_NONE;
++
++	return IRQ_HANDLED;
++
++}
++
++static int omap_otg_init(void)
++{
++	u32 l;
++
++#ifdef CONFIG_USB_OTG
++	if (!tahvo_otg_dev) {
++		printk("tahvo-usb: no tahvo_otg_dev\n");
++		return -ENODEV;
++	}
++#endif
++
++	l = omap_readl(OTG_SYSCON_1);
++	l &= ~OTG_IDLE_EN;
++	omap_writel(l, OTG_SYSCON_1);
++	udelay(100);
++
++	/* some of these values are board-specific... */
++	l = omap_readl(OTG_SYSCON_2);
++	l |= OTG_EN
++		/* for B-device: */
++		| SRP_GPDATA		/* 9msec Bdev D+ pulse */
++		| SRP_GPDVBUS		/* discharge after VBUS pulse */
++		// | (3 << 24)		/* 2msec VBUS pulse */
++		/* for A-device: */
++		| (0 << 20)		/* 200ms nominal A_WAIT_VRISE timer */
++		| SRP_DPW		/* detect 167+ns SRP pulses */
++		| SRP_DATA | SRP_VBUS;	/* accept both kinds of SRP pulse */
++	omap_writel(l, OTG_SYSCON_2);
++
++	omap_writew(DRIVER_SWITCH | OPRT_CHG
++			| B_SRP_TMROUT | B_HNP_FAIL
++				  | A_VBUS_ERR | A_SRP_DETECT | A_REQ_TMROUT,
++					OTG_IRQ_EN);
++	l = omap_readl(OTG_SYSCON_2);
++	l |= OTG_EN;
++	omap_writel(l, OTG_SYSCON_2);
++
++	return 0;
++}
++
++static int omap_otg_probe(struct device *dev)
++{
++	int ret;
++
++	tahvo_otg_dev = to_platform_device(dev);
++	ret = omap_otg_init();
++	if (ret != 0) {
++		printk(KERN_ERR "tahvo-usb: omap_otg_init failed\n");
++		return ret;
++	}
++
++	return request_irq(tahvo_otg_dev->resource[1].start,
++			   omap_otg_irq, IRQF_DISABLED, DRIVER_NAME,
++			   &tahvo_usb_device);
++}
++
++static int omap_otg_remove(struct device *dev)
++{
++	free_irq(tahvo_otg_dev->resource[1].start, &tahvo_usb_device);
++	tahvo_otg_dev = NULL;
++
++	return 0;
++}
++
++struct device_driver omap_otg_driver = {
++	.name		= "omap_otg",
++	.bus		= &platform_bus_type,
++	.probe		= omap_otg_probe,
++	.remove		= omap_otg_remove,
++};
++
++/*
++ * ---------------------------------------------------------------------------
++ * Tahvo related functions
++ * These are Nokia proprietary code, except for the OTG register settings,
++ * which are copied from isp1301.c
++ * ---------------------------------------------------------------------------
++ */
++static ssize_t vbus_state_show(struct device *device,
++			       struct device_attribute *attr, char *buf)
++{
++	struct tahvo_usb *tu = dev_get_drvdata(device);
++	return sprintf(buf, "%d\n", tu->vbus_state);
++}
++static DEVICE_ATTR(vbus_state, 0444, vbus_state_show, NULL);
++
++int vbus_active = 0;
++
++#if 0
++
++static int host_suspend(struct tahvo_usb *tu)
++{
++	struct device	*dev;
++
++	if (!tu->otg.host)
++		return -ENODEV;
++
++	/* Currently ASSUMES only the OTG port matters;
++	 * other ports could be active...
++	 */
++	dev = tu->otg.host->controller;
++	return dev->driver->suspend(dev, PMSG_SUSPEND);
++}
++
++static int host_resume(struct tahvo_usb *tu)
++{
++	struct device	*dev;
++
++	if (!tu->otg.host)
++		return -ENODEV;
++
++	dev = tu->otg.host->controller;
++	return dev->driver->resume(dev);
++}
++
++#else
++
++static int host_suspend(struct tahvo_usb *tu)
++{
++	return 0;
++}
++
++static int host_resume(struct tahvo_usb *tu)
++{
++	return 0;
++}
++
++#endif
++
++static void check_vbus_state(struct tahvo_usb *tu)
++{
++	int reg, prev_state;
++
++	reg = tahvo_read_reg(TAHVO_REG_IDSR);
++	if (reg & 0x01) {
++		u32 l;
++
++		vbus_active = 1;
++		switch (tu->otg.state) {
++		case OTG_STATE_B_IDLE:
++			/* Enable the gadget driver */
++			if (tu->otg.gadget)
++				usb_gadget_vbus_connect(tu->otg.gadget);
++			/* Set B-session valid and not B-sessio ended to indicate
++			 * Vbus to be ok. */
++			l = omap_readl(OTG_CTRL);
++			l &= ~OTG_BSESSEND;
++			l |= OTG_BSESSVLD;
++			omap_writel(l, OTG_CTRL);
++
++			tu->otg.state = OTG_STATE_B_PERIPHERAL;
++			break;
++		case OTG_STATE_A_IDLE:
++			/* Session is now valid assuming the USB hub is driving Vbus */
++			tu->otg.state = OTG_STATE_A_HOST;
++			host_resume(tu);
++			break;
++		default:
++			break;
++		}
++		printk("USB cable connected\n");
++	} else {
++		switch (tu->otg.state) {
++		case OTG_STATE_B_PERIPHERAL:
++			if (tu->otg.gadget)
++				usb_gadget_vbus_disconnect(tu->otg.gadget);
++			tu->otg.state = OTG_STATE_B_IDLE;
++			break;
++		case OTG_STATE_A_HOST:
++			tu->otg.state = OTG_STATE_A_IDLE;
++			break;
++		default:
++			break;
++		}
++		printk("USB cable disconnected\n");
++		vbus_active = 0;
++	}
++
++	prev_state = tu->vbus_state;
++	tu->vbus_state = reg & 0x01;
++	if (prev_state != tu->vbus_state)
++		sysfs_notify(&tu->pt_dev->dev.kobj, NULL, "vbus_state");
++}
++
++static void tahvo_usb_become_host(struct tahvo_usb *tu)
++{
++	u32 l;
++
++	/* Clear system and transceiver controlled bits
++	 * also mark the A-session is always valid */
++	omap_otg_init();
++
++	l = omap_readl(OTG_CTRL);
++	l &= ~(OTG_CTRL_XCVR_MASK | OTG_CTRL_SYS_MASK);
++	l |= OTG_ASESSVLD;
++	omap_writel(l, OTG_CTRL);
++
++	/* Power up the transceiver in USB host mode */
++	tahvo_write_reg(TAHVO_REG_USBR, USBR_REGOUT | USBR_NSUSPEND |
++			USBR_MASTER_SW2 | USBR_MASTER_SW1);
++	tu->otg.state = OTG_STATE_A_IDLE;
++
++	check_vbus_state(tu);
++}
++
++static void tahvo_usb_stop_host(struct tahvo_usb *tu)
++{
++	host_suspend(tu);
++	tu->otg.state = OTG_STATE_A_IDLE;
++}
++
++static void tahvo_usb_become_peripheral(struct tahvo_usb *tu)
++{
++	u32 l;
++
++	/* Clear system and transceiver controlled bits
++	 * and enable ID to mark peripheral mode and
++	 * BSESSEND to mark no Vbus */
++	omap_otg_init();
++	l = omap_readl(OTG_CTRL);
++	l &= ~(OTG_CTRL_XCVR_MASK | OTG_CTRL_SYS_MASK | OTG_BSESSVLD);
++	l |= OTG_ID | OTG_BSESSEND;
++	omap_writel(l, OTG_CTRL);
++
++	/* Power up transceiver and set it in USB perhiperal mode */
++	tahvo_write_reg(TAHVO_REG_USBR, USBR_SLAVE_CONTROL | USBR_REGOUT | USBR_NSUSPEND | USBR_SLAVE_SW);
++	tu->otg.state = OTG_STATE_B_IDLE;
++
++	check_vbus_state(tu);
++}
++
++static void tahvo_usb_stop_peripheral(struct tahvo_usb *tu)
++{
++	u32 l;
++
++	l = omap_readl(OTG_CTRL);
++	l &= ~OTG_BSESSVLD;
++	l |= OTG_BSESSEND;
++	omap_writel(l, OTG_CTRL);
++
++	if (tu->otg.gadget)
++		usb_gadget_vbus_disconnect(tu->otg.gadget);
++	tu->otg.state = OTG_STATE_B_IDLE;
++
++}
++
++static void tahvo_usb_power_off(struct tahvo_usb *tu)
++{
++	u32 l;
++	int id;
++
++	/* Disable gadget controller if any */
++	if (tu->otg.gadget)
++		usb_gadget_vbus_disconnect(tu->otg.gadget);
++
++	host_suspend(tu);
++
++	/* Disable OTG and interrupts */
++	if (TAHVO_MODE(tu) == TAHVO_MODE_PERIPHERAL)
++		id = OTG_ID;
++	else
++		id = 0;
++	l = omap_readl(OTG_CTRL);
++	l &= ~(OTG_CTRL_XCVR_MASK | OTG_CTRL_SYS_MASK | OTG_BSESSVLD);
++	l |= id | OTG_BSESSEND;
++	omap_writel(l, OTG_CTRL);
++	omap_writew(0, OTG_IRQ_EN);
++
++	l = omap_readl(OTG_SYSCON_2);
++	l &= ~OTG_EN;
++	omap_writel(l, OTG_SYSCON_2);
++
++	l = omap_readl(OTG_SYSCON_1);
++	l |= OTG_IDLE_EN;
++	omap_writel(l, OTG_SYSCON_1);
++
++	/* Power off transceiver */
++	tahvo_write_reg(TAHVO_REG_USBR, 0);
++	tu->otg.state = OTG_STATE_UNDEFINED;
++}
++
++
++static int tahvo_usb_set_power(struct otg_transceiver *dev, unsigned mA)
++{
++	struct tahvo_usb *tu = container_of(dev, struct tahvo_usb, otg);
++
++	dev_dbg(&tu->pt_dev->dev, "set_power %d mA\n", mA);
++
++	if (dev->state == OTG_STATE_B_PERIPHERAL) {
++		/* REVISIT: Can Tahvo charge battery from VBUS? */
++	}
++	return 0;
++}
++
++static int tahvo_usb_set_suspend(struct otg_transceiver *dev, int suspend)
++{
++	struct tahvo_usb *tu = container_of(dev, struct tahvo_usb, otg);
++	u16 w;
++
++	dev_dbg(&tu->pt_dev->dev, "set_suspend\n");
++
++	w = tahvo_read_reg(TAHVO_REG_USBR);
++	if (suspend)
++		w &= ~USBR_NSUSPEND;
++	else
++		w |= USBR_NSUSPEND;
++	tahvo_write_reg(TAHVO_REG_USBR, w);
++
++	return 0;
++}
++
++static int tahvo_usb_start_srp(struct otg_transceiver *dev)
++{
++	struct tahvo_usb *tu = container_of(dev, struct tahvo_usb, otg);
++	u32 otg_ctrl;
++
++	dev_dbg(&tu->pt_dev->dev, "start_srp\n");
++
++	if (!dev || tu->otg.state != OTG_STATE_B_IDLE)
++		return -ENODEV;
++
++	otg_ctrl = omap_readl(OTG_CTRL);
++	if (!(otg_ctrl & OTG_BSESSEND))
++		return -EINVAL;
++
++	otg_ctrl |= OTG_B_BUSREQ;
++	otg_ctrl &= ~OTG_A_BUSREQ & OTG_CTRL_SYS_MASK;
++	omap_writel(otg_ctrl, OTG_CTRL);
++	tu->otg.state = OTG_STATE_B_SRP_INIT;
++
++	return 0;
++}
++
++static int tahvo_usb_start_hnp(struct otg_transceiver *otg)
++{
++	struct tahvo_usb *tu = container_of(otg, struct tahvo_usb, otg);
++
++	dev_dbg(&tu->pt_dev->dev, "start_hnp\n");
++#ifdef CONFIG_USB_OTG
++	/* REVISIT: Add this for OTG */
++#endif
++	return -EINVAL;
++}
++
++static int tahvo_usb_set_host(struct otg_transceiver *otg, struct usb_bus *host)
++{
++	struct tahvo_usb *tu = container_of(otg, struct tahvo_usb, otg);
++	u32 l;
++
++	dev_dbg(&tu->pt_dev->dev, "set_host %p\n", host);
++
++	if (otg == NULL)
++		return -ENODEV;
++
++#if defined(CONFIG_USB_OTG) || !defined(CONFIG_USB_GADGET_OMAP)
++
++	mutex_lock(&tu->serialize);
++
++	if (host == NULL) {
++		if (TAHVO_MODE(tu) == TAHVO_MODE_HOST)
++			tahvo_usb_power_off(tu);
++		tu->otg.host = NULL;
++		mutex_unlock(&tu->serialize);
++		return 0;
++	}
++
++	l = omap_readl(OTG_SYSCON_1);
++	l &= ~(OTG_IDLE_EN | HST_IDLE_EN | DEV_IDLE_EN);
++	omap_writel(l, OTG_SYSCON_1);
++
++	if (TAHVO_MODE(tu) == TAHVO_MODE_HOST) {
++		tu->otg.host = NULL;
++		tahvo_usb_become_host(tu);
++	} else
++		host_suspend(tu);
++
++	tu->otg.host = host;
++
++	mutex_unlock(&tu->serialize);
++#else
++	/* No host mode configured, so do not allow host controlled to be set */
++	return -EINVAL;
++#endif
++
++	return 0;
++}
++
++static int tahvo_usb_set_peripheral(struct otg_transceiver *otg, struct usb_gadget *gadget)
++{
++	struct tahvo_usb *tu = container_of(otg, struct tahvo_usb, otg);
++
++	dev_dbg(&tu->pt_dev->dev, "set_peripheral %p\n", gadget);
++
++	if (!otg)
++		return -ENODEV;
++
++#if defined(CONFIG_USB_OTG) || defined(CONFIG_USB_GADGET_OMAP)
++
++	mutex_lock(&tu->serialize);
++
++	if (!gadget) {
++		if (TAHVO_MODE(tu) == TAHVO_MODE_PERIPHERAL)
++			tahvo_usb_power_off(tu);
++		tu->otg.gadget = NULL;
++		mutex_unlock(&tu->serialize);
++		return 0;
++	}
++
++	tu->otg.gadget = gadget;
++	if (TAHVO_MODE(tu) == TAHVO_MODE_PERIPHERAL)
++		tahvo_usb_become_peripheral(tu);
++
++	mutex_unlock(&tu->serialize);
++#else
++	/* No gadget mode configured, so do not allow host controlled to be set */
++	return -EINVAL;
++#endif
++
++	return 0;
++}
++
++static void tahvo_usb_irq_work(struct work_struct *work)
++{
++	struct tahvo_usb *tu = container_of(work, struct tahvo_usb, irq_work);
++
++	mutex_lock(&tu->serialize);
++	check_vbus_state(tu);
++	mutex_unlock(&tu->serialize);
++}
++
++static void tahvo_usb_vbus_interrupt(unsigned long arg)
++{
++	struct tahvo_usb *tu = (struct tahvo_usb *) arg;
++
++	tahvo_ack_irq(TAHVO_INT_VBUSON);
++	/* Seems we need this to acknowledge the interrupt */
++	tahvo_read_reg(TAHVO_REG_IDSR);
++	schedule_work(&tu->irq_work);
++}
++
++#ifdef CONFIG_USB_OTG
++static ssize_t otg_mode_show(struct device *device,
++			     struct device_attribute *attr, char *buf)
++{
++	struct tahvo_usb *tu = dev_get_drvdata(device);
++	switch (tu->tahvo_mode) {
++	case TAHVO_MODE_HOST:
++		return sprintf(buf, "host\n");
++	case TAHVO_MODE_PERIPHERAL:
++		return sprintf(buf, "peripheral\n");
++	}
++	return sprintf(buf, "unknown\n");
++}
++
++static ssize_t otg_mode_store(struct device *device,
++			      struct device_attribute *attr,
++			      const char *buf, size_t count)
++{
++	struct tahvo_usb *tu = dev_get_drvdata(device);
++	int r;
++
++	r = strlen(buf);
++	mutex_lock(&tu->serialize);
++	if (strncmp(buf, "host", 4) == 0) {
++		if (tu->tahvo_mode == TAHVO_MODE_PERIPHERAL)
++			tahvo_usb_stop_peripheral(tu);
++		tu->tahvo_mode = TAHVO_MODE_HOST;
++		if (tu->otg.host) {
++			printk(KERN_INFO "Selected HOST mode: host controller present.\n");
++			tahvo_usb_become_host(tu);
++		} else {
++			printk(KERN_INFO "Selected HOST mode: no host controller, powering off.\n");
++			tahvo_usb_power_off(tu);
++		}
++	} else if (strncmp(buf, "peripheral", 10) == 0) {
++		if (tu->tahvo_mode == TAHVO_MODE_HOST)
++			tahvo_usb_stop_host(tu);
++		tu->tahvo_mode = TAHVO_MODE_PERIPHERAL;
++		if (tu->otg.gadget) {
++			printk(KERN_INFO "Selected PERIPHERAL mode: gadget driver present.\n");
++			tahvo_usb_become_peripheral(tu);
++		} else {
++			printk(KERN_INFO "Selected PERIPHERAL mode: no gadget driver, powering off.\n");
++			tahvo_usb_power_off(tu);
++		}
++	} else
++		r = -EINVAL;
++
++	mutex_unlock(&tu->serialize);
++	return r;
++}
++
++static DEVICE_ATTR(otg_mode, 0644, otg_mode_show, otg_mode_store);
++#endif
++
++static int tahvo_usb_probe(struct device *dev)
++{
++	struct tahvo_usb *tu;
++	int ret;
++
++	dev_dbg(dev, "probe\n");
++
++	/* Create driver data */
++	tu = kmalloc(sizeof(*tu), GFP_KERNEL);
++	if (!tu)
++		return -ENOMEM;
++	memset(tu, 0, sizeof(*tu));
++	tu->pt_dev = container_of(dev, struct platform_device, dev);
++#ifdef CONFIG_USB_OTG
++	/* Default mode */
++#ifdef CONFIG_CBUS_TAHVO_USB_HOST_BY_DEFAULT
++	tu->tahvo_mode = TAHVO_MODE_HOST;
++#else
++	tu->tahvo_mode = TAHVO_MODE_PERIPHERAL;
++#endif
++#endif
++
++	INIT_WORK(&tu->irq_work, tahvo_usb_irq_work);
++	mutex_init(&tu->serialize);
++
++	/* Set initial state, so that we generate kevents only on
++	 * state changes */
++	tu->vbus_state = tahvo_read_reg(TAHVO_REG_IDSR) & 0x01;
++
++	/* We cannot enable interrupt until omap_udc is initialized */
++	ret = tahvo_request_irq(TAHVO_INT_VBUSON, tahvo_usb_vbus_interrupt,
++				(unsigned long) tu, "vbus_interrupt");
++	if (ret != 0) {
++		kfree(tu);
++		printk(KERN_ERR "Could not register Tahvo interrupt for VBUS\n");
++		return ret;
++	}
++
++	/* Attributes */
++	ret = device_create_file(dev, &dev_attr_vbus_state);
++#ifdef CONFIG_USB_OTG
++	ret |= device_create_file(dev, &dev_attr_otg_mode);
++#endif
++	if (ret)
++		printk(KERN_ERR "attribute creation failed: %d\n", ret);
++
++	/* Create OTG interface */
++	tahvo_usb_power_off(tu);
++	tu->otg.state = OTG_STATE_UNDEFINED;
++	tu->otg.label = DRIVER_NAME;
++	tu->otg.set_host = tahvo_usb_set_host;
++	tu->otg.set_peripheral = tahvo_usb_set_peripheral;
++	tu->otg.set_power = tahvo_usb_set_power;
++	tu->otg.set_suspend = tahvo_usb_set_suspend;
++	tu->otg.start_srp = tahvo_usb_start_srp;
++	tu->otg.start_hnp = tahvo_usb_start_hnp;
++
++	ret = otg_set_transceiver(&tu->otg);
++	if (ret < 0) {
++		printk(KERN_ERR "Cannot register USB transceiver\n");
++		kfree(tu);
++		tahvo_free_irq(TAHVO_INT_VBUSON);
++		return ret;
++	}
++
++	dev_set_drvdata(dev, tu);
++
++	/* Act upon current vbus state once at startup. A vbus state irq may or
++	 * may not be generated in addition to this. */
++	schedule_work(&tu->irq_work);
++	return 0;
++}
++
++static int tahvo_usb_remove(struct device *dev)
++{
++	dev_dbg(dev, "remove\n");
++
++	tahvo_free_irq(TAHVO_INT_VBUSON);
++	flush_scheduled_work();
++	otg_set_transceiver(0);
++	device_remove_file(dev, &dev_attr_vbus_state);
++#ifdef CONFIG_USB_OTG
++	device_remove_file(dev, &dev_attr_otg_mode);
++#endif
++	return 0;
++}
++
++static struct device_driver tahvo_usb_driver = {
++	.name		= "tahvo-usb",
++	.bus		= &platform_bus_type,
++	.probe		= tahvo_usb_probe,
++	.remove		= tahvo_usb_remove,
++};
++
++static struct platform_device tahvo_usb_device = {
++	.name		= "tahvo-usb",
++	.id		= -1,
++};
++
++static int __init tahvo_usb_init(void)
++{
++	int ret = 0;
++
++	printk(KERN_INFO "Tahvo USB transceiver driver initializing\n");
++	ret = driver_register(&tahvo_usb_driver);
++	if (ret)
++		return ret;
++	ret = platform_device_register(&tahvo_usb_device);
++	if (ret < 0) {
++		driver_unregister(&tahvo_usb_driver);
++		return ret;
++	}
++	ret = driver_register(&omap_otg_driver);
++	if (ret) {
++		platform_device_unregister(&tahvo_usb_device);
++		driver_unregister(&tahvo_usb_driver);
++		return ret;
++	}
++	return 0;
++}
++
++subsys_initcall(tahvo_usb_init);
++
++static void __exit tahvo_usb_exit(void)
++{
++	driver_unregister(&omap_otg_driver);
++	platform_device_unregister(&tahvo_usb_device);
++	driver_unregister(&tahvo_usb_driver);
++}
++module_exit(tahvo_usb_exit);
++
++MODULE_DESCRIPTION("Tahvo USB OTG Transceiver Driver");
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Juha Yrjölä, Tony Lindgren, and Timo Teräs");
+--- /dev/null
++++ linux-2.6.35/drivers/cbus/tahvo-user.c
+@@ -0,0 +1,407 @@
++/**
++ * drivers/cbus/tahvo-user.c
++ *
++ * Tahvo user space interface functions
++ *
++ * Copyright (C) 2004, 2005 Nokia Corporation
++ *
++ * Written by Mikko Ylinen <[email protected]>
++ *
++ * 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.
++ *
++ * 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/kernel.h>
++#include <linux/interrupt.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/fs.h>
++#include <linux/miscdevice.h>
++#include <linux/poll.h>
++#include <linux/list.h>
++#include <linux/spinlock.h>
++#include <linux/sched.h>
++#include <linux/mutex.h>
++#include <linux/slab.h>
++
++#include <asm/uaccess.h>
++
++#include "tahvo.h"
++
++#include "user_retu_tahvo.h"
++
++/* Maximum size of IRQ node buffer/pool */
++#define TAHVO_MAX_IRQ_BUF_LEN	16
++
++#define PFX			"tahvo-user: "
++
++/* Bitmap for marking the interrupt sources as having the handlers */
++static u32 tahvo_irq_bits;
++
++/* For allowing only one user process to subscribe to the tahvo interrupts */
++static struct file *tahvo_irq_subscr = NULL;
++
++/* For poll and IRQ passing */
++struct tahvo_irq {
++	u32 id;
++	struct list_head node;
++};
++
++static spinlock_t tahvo_irqs_lock;
++static struct tahvo_irq *tahvo_irq_block;
++static LIST_HEAD(tahvo_irqs);
++static LIST_HEAD(tahvo_irqs_reserve);
++
++/* Wait queue - used when user wants to read the device */
++DECLARE_WAIT_QUEUE_HEAD(tahvo_user_waitqueue);
++
++/* Semaphore to protect irq subscription sequence */
++static struct mutex tahvo_mutex;
++
++/* This array specifies TAHVO register types (read/write/toggle) */
++static const u8 tahvo_access_bits[] = {
++	1,
++	4,
++	1,
++	3,
++	3,
++	3,
++	3,
++	3,
++	3,
++	3,
++	3,
++	3,
++	3,
++	1
++};
++
++/*
++ * The handler for all TAHVO interrupts.
++ *
++ * arg is the interrupt source in TAHVO.
++ */
++static void tahvo_user_irq_handler(unsigned long arg)
++{
++	struct tahvo_irq *irq;
++
++	/* user has to re-enable the interrupt once ready
++	 * for receiving them again */
++	tahvo_disable_irq(arg);
++	tahvo_ack_irq(arg);
++
++	spin_lock(&tahvo_irqs_lock);
++	if (list_empty(&tahvo_irqs_reserve)) {
++		spin_unlock(&tahvo_irqs_lock);
++		return;
++	}
++	irq = list_entry((&tahvo_irqs_reserve)->next, struct tahvo_irq, node);
++	irq->id = arg;
++	list_move_tail(&irq->node, &tahvo_irqs);
++	spin_unlock(&tahvo_irqs_lock);
++
++	/* wake up waiting thread */
++	wake_up(&tahvo_user_waitqueue);
++}
++
++/*
++ * This routine sets up the interrupt handler and marks an interrupt source
++ * in TAHVO as a candidate for signal delivery to the user process.
++ */
++static int tahvo_user_subscribe_to_irq(int id, struct file *filp)
++{
++	int ret;
++
++	mutex_lock(&tahvo_mutex);
++	if ((tahvo_irq_subscr != NULL) && (tahvo_irq_subscr != filp)) {
++		mutex_unlock(&tahvo_mutex);
++		return -EBUSY;
++	}
++	/* Store the file pointer of the first user process registering IRQs */
++	tahvo_irq_subscr = filp;
++	mutex_unlock(&tahvo_mutex);
++
++	if (tahvo_irq_bits & (1 << id))
++		return 0;
++
++	ret = tahvo_request_irq(id, tahvo_user_irq_handler, id, "");
++	if (ret < 0)
++		return ret;
++
++	/* Mark that this interrupt has a handler */
++	tahvo_irq_bits |= 1 << id;
++
++	return 0;
++}
++
++/*
++ * Unregister all TAHVO interrupt handlers
++ */
++static void tahvo_unreg_irq_handlers(void)
++{
++	int id;
++
++	if (!tahvo_irq_bits)
++		return;
++
++	for (id = 0; id < MAX_TAHVO_IRQ_HANDLERS; id++)
++		if (tahvo_irq_bits & (1 << id))
++			tahvo_free_irq(id);
++
++	tahvo_irq_bits = 0;
++}
++
++/*
++ * Write to TAHVO register.
++ * Returns 0 upon success, a negative error value otherwise.
++ */
++static int tahvo_user_write_with_mask(u32 field, u16 value)
++{
++	u32 mask;
++	u32 reg;
++	u_short tmp;
++	unsigned long flags;
++
++	mask = MASK(field);
++	reg = REG(field);
++
++	/* Detect bad mask and reg */
++	if (mask == 0 || reg > TAHVO_REG_MAX ||
++	    tahvo_access_bits[reg] == READ_ONLY) {
++		printk(KERN_ERR PFX "invalid arguments (reg=%#x, mask=%#x)\n",
++		       reg, mask);
++		return -EINVAL;
++	}
++
++	/* Justify value according to mask */
++	while (!(mask & 1)) {
++		value = value << 1;
++		mask = mask >> 1;
++	}
++
++	spin_lock_irqsave(&tahvo_lock, flags);
++	if (tahvo_access_bits[reg] == TOGGLE) {
++		/* No need to detect previous content of register */
++		tmp = 0;
++	} else {
++		/* Read current value of register */
++		tmp = tahvo_read_reg(reg);
++	}
++	/* Generate a new value */
++	tmp = (tmp & ~MASK(field)) | (value & MASK(field));
++	/* Write data to TAHVO */
++	tahvo_write_reg(reg, tmp);
++	spin_unlock_irqrestore(&tahvo_lock, flags);
++
++	return 0;
++}
++
++/*
++ * Read TAHVO register.
++ */
++static u32 tahvo_user_read_with_mask(u32 field)
++{
++	u_short value;
++	u32 mask, reg;
++
++	mask = MASK(field);
++	reg = REG(field);
++
++	/* Detect bad mask and reg */
++	if (mask == 0 || reg > TAHVO_REG_MAX) {
++		printk(KERN_ERR PFX "invalid arguments (reg=%#x, mask=%#x)\n",
++		       reg, mask);
++		return -EINVAL;
++	}
++
++	/* Read the register */
++	value = tahvo_read_reg(reg) & mask;
++
++	/* Right justify value */
++	while (!(mask & 1)) {
++		value = value >> 1;
++		mask = mask >> 1;
++	}
++
++	return value;
++}
++
++/*
++ * Close device
++ */
++static int tahvo_close(struct inode *inode, struct file *filp)
++{
++	/* Unregister all interrupts that have been registered */
++	if (tahvo_irq_subscr == filp) {
++		tahvo_unreg_irq_handlers();
++		tahvo_irq_subscr = NULL;
++	}
++
++	return 0;
++}
++
++/*
++ * Device control (ioctl)
++ */
++static int tahvo_ioctl(struct inode *inode, struct file *filp,
++		       unsigned int cmd, unsigned long arg)
++{
++	struct retu_tahvo_write_parms par;
++	int ret;
++
++	switch (cmd) {
++	case URT_IOCT_IRQ_SUBSCR:
++		return tahvo_user_subscribe_to_irq(arg, filp);
++	case TAHVO_IOCH_READ:
++		return tahvo_user_read_with_mask(arg);
++	case TAHVO_IOCX_WRITE:
++		ret = copy_from_user(&par, (void __user *) arg, sizeof(par));
++		if (ret)
++			printk(KERN_ERR "copy_from_user failed: %d\n", ret);
++		par.result = tahvo_user_write_with_mask(par.field, par.value);
++		ret = copy_to_user((void __user *) arg, &par, sizeof(par));
++		if (ret)
++			printk(KERN_ERR "copy_to_user failed: %d\n", ret);
++		break;
++	default:
++		return -ENOIOCTLCMD;
++	}
++	return 0;
++}
++
++/*
++ * Read from device
++ */
++static ssize_t tahvo_read(struct file *filp, char *buf, size_t count,
++			  loff_t * offp)
++{
++	struct tahvo_irq *irq;
++
++	u32 nr, i;
++
++	/* read not permitted if neither filp nor anyone has registered IRQs */
++	if (tahvo_irq_subscr != filp)
++		return -EPERM;
++
++	if ((count < sizeof(u32)) || ((count % sizeof(u32)) != 0))
++		return -EINVAL;
++
++	nr = count / sizeof(u32);
++
++	for (i = 0; i < nr; i++) {
++		unsigned long flags;
++		u32 irq_id;
++		int ret;
++
++		ret = wait_event_interruptible(tahvo_user_waitqueue,
++					       !list_empty(&tahvo_irqs));
++		if (ret < 0)
++			return ret;
++
++		spin_lock_irqsave(&tahvo_irqs_lock, flags);
++		irq = list_entry((&tahvo_irqs)->next, struct tahvo_irq, node);
++		irq_id = irq->id;
++		list_move(&irq->node, &tahvo_irqs_reserve);
++		spin_unlock_irqrestore(&tahvo_irqs_lock, flags);
++
++		ret = copy_to_user(buf + i * sizeof(irq_id), &irq_id,
++                                  sizeof(irq_id));
++		if (ret)
++			printk(KERN_ERR "copy_to_user failed: %d\n", ret);
++	}
++
++	return count;
++}
++
++/*
++ * Poll method
++ */
++static unsigned tahvo_poll(struct file *filp, struct poll_table_struct *pt)
++{
++	if (!list_empty(&tahvo_irqs))
++		return POLLIN;
++
++	poll_wait(filp, &tahvo_user_waitqueue, pt);
++
++	if (!list_empty(&tahvo_irqs))
++		return POLLIN;
++	else
++		return 0;
++}
++
++static struct file_operations tahvo_user_fileops = {
++	.owner = THIS_MODULE,
++	.ioctl = tahvo_ioctl,
++	.read = tahvo_read,
++	.release = tahvo_close,
++	.poll = tahvo_poll
++};
++
++static struct miscdevice tahvo_device = {
++	.minor = MISC_DYNAMIC_MINOR,
++	.name = "tahvo",
++	.fops = &tahvo_user_fileops
++};
++
++/*
++ * Initialization
++ *
++ * @return 0 if successful, error value otherwise.
++ */
++int tahvo_user_init(void)
++{
++	struct tahvo_irq *irq;
++	int res, i;
++
++	irq = kmalloc(sizeof(*irq) * TAHVO_MAX_IRQ_BUF_LEN, GFP_KERNEL);
++	if (irq == NULL) {
++		printk(KERN_ERR PFX "kmalloc failed\n");
++		return -ENOMEM;
++	}
++	memset(irq, 0, sizeof(*irq) * TAHVO_MAX_IRQ_BUF_LEN);
++	for (i = 0; i < TAHVO_MAX_IRQ_BUF_LEN; i++)
++		list_add(&irq[i].node, &tahvo_irqs_reserve);
++
++	tahvo_irq_block = irq;
++
++	spin_lock_init(&tahvo_irqs_lock);
++	mutex_init(&tahvo_mutex);
++
++	/* Request a misc device */
++	res = misc_register(&tahvo_device);
++	if (res < 0) {
++		printk(KERN_ERR PFX "unable to register misc device for %s\n",
++		       tahvo_device.name);
++		kfree(irq);
++		return res;
++	}
++
++	return 0;
++}
++
++/*
++ * Cleanup.
++ */
++void tahvo_user_cleanup(void)
++{
++	/* Unregister our misc device */
++	misc_deregister(&tahvo_device);
++	/* Unregister and disable all TAHVO interrupts */
++	tahvo_unreg_irq_handlers();
++	kfree(tahvo_irq_block);
++}
++
++MODULE_DESCRIPTION("Tahvo ASIC user space functions");
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Mikko Ylinen");
+--- /dev/null
++++ linux-2.6.35/drivers/cbus/user_retu_tahvo.h
+@@ -0,0 +1,75 @@
++/**
++ * drivers/cbus/user_retu_tahvo.h
++ *
++ * Copyright (C) 2004, 2005 Nokia Corporation
++ *
++ * Written by Mikko Ylinen <[email protected]>
++ *
++ * Definitions and types used by both retu-user and tahvo-user.
++ *
++ * 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.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ */
++
++#ifndef _USER_RETU_TAHVO_H
++#define _USER_RETU_TAHVO_H
++
++/* Chip IDs */
++#define CHIP_RETU	1
++#define CHIP_TAHVO	2
++
++/* Register access type bits */
++#define READ_ONLY		1
++#define WRITE_ONLY		2
++#define READ_WRITE		3
++#define TOGGLE			4
++
++#define MASK(field)		((u16)(field & 0xFFFF))
++#define REG(field)		((u16)((field >> 16) & 0x3F))
++
++/*** IOCTL definitions. These should be kept in sync with user space **********/
++
++#define URT_IOC_MAGIC '`'
++
++/*
++ * IOCTL function naming conventions:
++ * ==================================
++ *  0 -- No argument and return value
++ *  S -- Set through a pointer
++ *  T -- Tell directly with the argument value
++ *  G -- Reply by setting through a pointer
++ *  Q -- response is on the return value
++ *  X -- S and G atomically
++ *  H -- T and Q atomically
++ */
++
++/* General */
++#define URT_IOCT_IRQ_SUBSCR		_IO(URT_IOC_MAGIC, 0)
++
++/* RETU */
++#define RETU_IOCH_READ			_IO(URT_IOC_MAGIC, 1)
++#define RETU_IOCX_WRITE			_IO(URT_IOC_MAGIC, 2)
++#define RETU_IOCH_ADC_READ		_IO(URT_IOC_MAGIC, 3)
++
++/* TAHVO */
++#define TAHVO_IOCH_READ			_IO(URT_IOC_MAGIC, 4)
++#define TAHVO_IOCX_WRITE		_IO(URT_IOC_MAGIC, 5)
++
++/* This structure is used for writing RETU/TAHVO registers */
++struct retu_tahvo_write_parms {
++    u32	field;
++    u16	value;
++    u8	result;
++};
++
++#endif
+--- linux-2.6.35.orig/drivers/Makefile
++++ linux-2.6.35/drivers/Makefile
+@@ -74,7 +74,7 @@ obj-$(CONFIG_GAMEPORT)		+= input/gamepor
+ obj-$(CONFIG_INPUT)		+= input/
+ obj-$(CONFIG_I2O)		+= message/
+ obj-$(CONFIG_RTC_LIB)		+= rtc/
+-obj-y				+= i2c/ media/
++obj-y				+= i2c/ media/ cbus/
+ obj-$(CONFIG_PPS)		+= pps/
+ obj-$(CONFIG_W1)		+= w1/
+ obj-$(CONFIG_POWER_SUPPLY)	+= power/
+--- linux-2.6.35.orig/arch/arm/Kconfig
++++ linux-2.6.35/arch/arm/Kconfig
+@@ -1669,6 +1669,10 @@ source "net/Kconfig"
+ 
+ source "drivers/Kconfig"
+ 
++if ARCH_OMAP
++source "drivers/cbus/Kconfig"
++endif
++
+ source "fs/Kconfig"
+ 
+ source "arch/arm/Kconfig.debug"

+ 1031 - 0
target/linux/omap24xx/patches-2.6.35/600-tsc2005.patch

@@ -0,0 +1,1031 @@
+---
+ drivers/input/touchscreen/Kconfig   |   11 
+ drivers/input/touchscreen/Makefile  |    1 
+ drivers/input/touchscreen/tsc2005.c |  958 ++++++++++++++++++++++++++++++++++++
+ include/linux/spi/tsc2005.h         |   30 +
+ 4 files changed, 1000 insertions(+)
+
+--- linux-2.6.35.orig/drivers/input/touchscreen/Kconfig
++++ linux-2.6.35/drivers/input/touchscreen/Kconfig
+@@ -561,6 +561,17 @@ config TOUCHSCREEN_TOUCHIT213
+ 	  To compile this driver as a module, choose M here: the
+ 	  module will be called touchit213.
+ 
++config TOUCHSCREEN_TSC2005
++        tristate "TSC2005 based touchscreens"
++        depends on SPI_MASTER
++        help
++          Say Y here if you have a TSC2005 based touchscreen.
++
++	  If unsure, say N.
++
++	  To compile this driver as a module, choose M here: the
++	  module will be called tsc2005.
++
+ config TOUCHSCREEN_TSC2007
+ 	tristate "TSC2007 based touchscreens"
+ 	depends on I2C
+--- linux-2.6.35.orig/drivers/input/touchscreen/Makefile
++++ linux-2.6.35/drivers/input/touchscreen/Makefile
+@@ -34,6 +34,7 @@ obj-$(CONFIG_TOUCHSCREEN_S3C2410)	+= s3c
+ obj-$(CONFIG_TOUCHSCREEN_TOUCHIT213)	+= touchit213.o
+ obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT)	+= touchright.o
+ obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN)	+= touchwin.o
++obj-$(CONFIG_TOUCHSCREEN_TSC2005)	+= tsc2005.o
+ obj-$(CONFIG_TOUCHSCREEN_TSC2007)	+= tsc2007.o
+ obj-$(CONFIG_TOUCHSCREEN_UCB1400)	+= ucb1400_ts.o
+ obj-$(CONFIG_TOUCHSCREEN_WACOM_W8001)	+= wacom_w8001.o
+--- /dev/null
++++ linux-2.6.35/drivers/input/touchscreen/tsc2005.c
+@@ -0,0 +1,958 @@
++/*
++ * TSC2005 touchscreen driver
++ *
++ * Copyright (C) 2006-2008 Nokia Corporation
++ *
++ * Author: Lauri Leukkunen <[email protected]>
++ * based on TSC2301 driver by Klaus K. Pedersen <[email protected]>
++ *
++ * 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/kernel.h>
++#include <linux/module.h>
++#include <linux/input.h>
++#include <linux/interrupt.h>
++#include <linux/delay.h>
++#include <linux/spi/spi.h>
++
++#include <linux/spi/tsc2005.h>
++
++/**
++ * The touchscreen interface operates as follows:
++ *
++ * Initialize:
++ *    Request access to GPIO103 (DAV)
++ *    tsc2005_ts_irq_handler will trigger when DAV line goes down
++ *
++ *  1) Pen is pressed against touchscreeen
++ *  2) TSC2005 performs AD conversion
++ *  3) After the conversion is done TSC2005 drives DAV line down
++ *  4) GPIO IRQ is received and tsc2005_ts_irq_handler is called
++ *  5) tsc2005_ts_irq_handler queues up an spi transfer to fetch
++ *     the x, y, z1, z2 values
++ *  6) tsc2005_ts_rx() reports coordinates to input layer and
++ *     sets up tsc2005_ts_timer() to be called after TSC2005_TS_SCAN_TIME
++ *  7)  When the penup_timer expires, there have not been DAV interrupts
++ *     during the last 20ms which means the pen has been lifted.
++ */
++
++#define TSC2005_VDD_LOWER_27
++
++#ifdef TSC2005_VDD_LOWER_27
++#define TSC2005_HZ     (10000000)
++#else
++#define TSC2005_HZ     (25000000)
++#endif
++
++#define TSC2005_CMD	(0x80)
++#define TSC2005_REG	(0x00)
++
++#define TSC2005_CMD_STOP	(1)
++#define TSC2005_CMD_10BIT	(0 << 2)
++#define TSC2005_CMD_12BIT	(1 << 2)
++
++#define TSC2005_CMD_SCAN_XYZZ	(0 << 3)
++#define TSC2005_CMD_SCAN_XY	(1 << 3)
++#define TSC2005_CMD_SCAN_X	(2 << 3)
++#define TSC2005_CMD_SCAN_Y	(3 << 3)
++#define TSC2005_CMD_SCAN_ZZ	(4 << 3)
++#define TSC2005_CMD_AUX_SINGLE	(5 << 3)
++#define TSC2005_CMD_TEMP1	(6 << 3)
++#define TSC2005_CMD_TEMP2	(7 << 3)
++#define TSC2005_CMD_AUX_CONT	(8 << 3)
++#define TSC2005_CMD_TEST_X_CONN	(9 << 3)
++#define TSC2005_CMD_TEST_Y_CONN	(10 << 3)
++#define TSC2005_CMD_TEST_SHORT	(11 << 3)
++/* command 12 reserved, according to 2008-03 erratum */
++#define TSC2005_CMD_DRIVE_XX	(13 << 3)
++#define TSC2005_CMD_DRIVE_YY	(14 << 3)
++#define TSC2005_CMD_DRIVE_YX	(15 << 3)
++
++#define TSC2005_REG_X		(0 << 3)
++#define TSC2005_REG_Y		(1 << 3)
++#define TSC2005_REG_Z1		(2 << 3)
++#define TSC2005_REG_Z2		(3 << 3)
++#define TSC2005_REG_AUX		(4 << 3)
++#define TSC2005_REG_TEMP1	(5 << 3)
++#define TSC2005_REG_TEMP2	(6 << 3)
++#define TSC2005_REG_STATUS	(7 << 3)
++#define TSC2005_REG_AUX_HIGH	(8 << 3)
++#define TSC2005_REG_AUX_LOW	(9 << 3)
++#define TSC2005_REG_TEMP_HIGH	(10 << 3)
++#define TSC2005_REG_TEMP_LOW	(11 << 3)
++#define TSC2005_REG_CFR0	(12 << 3)
++#define TSC2005_REG_CFR1	(13 << 3)
++#define TSC2005_REG_CFR2	(14 << 3)
++#define TSC2005_REG_FUNCTION	(15 << 3)
++
++#define TSC2005_REG_PND0	(1 << 1)
++#define TSC2005_REG_READ	(0x01)
++#define TSC2005_REG_WRITE	(0x00)
++
++
++#define TSC2005_CFR0_LONGSAMPLING	(1)
++#define TSC2005_CFR0_DETECTINWAIT	(1 << 1)
++#define TSC2005_CFR0_SENSETIME_32US	(0)
++#define TSC2005_CFR0_SENSETIME_96US	(1 << 2)
++#define TSC2005_CFR0_SENSETIME_544US	(1 << 3)
++#define TSC2005_CFR0_SENSETIME_2080US	(1 << 4)
++#define TSC2005_CFR0_SENSETIME_2656US	(0x001C)
++#define TSC2005_CFR0_PRECHARGE_20US	(0x0000)
++#define TSC2005_CFR0_PRECHARGE_84US	(0x0020)
++#define TSC2005_CFR0_PRECHARGE_276US	(0x0040)
++#define TSC2005_CFR0_PRECHARGE_1044US	(0x0080)
++#define TSC2005_CFR0_PRECHARGE_1364US	(0x00E0)
++#define TSC2005_CFR0_STABTIME_0US	(0x0000)
++#define TSC2005_CFR0_STABTIME_100US	(0x0100)
++#define TSC2005_CFR0_STABTIME_500US	(0x0200)
++#define TSC2005_CFR0_STABTIME_1MS	(0x0300)
++#define TSC2005_CFR0_STABTIME_5MS	(0x0400)
++#define TSC2005_CFR0_STABTIME_100MS	(0x0700)
++#define TSC2005_CFR0_CLOCK_4MHZ		(0x0000)
++#define TSC2005_CFR0_CLOCK_2MHZ		(0x0800)
++#define TSC2005_CFR0_CLOCK_1MHZ		(0x1000)
++#define TSC2005_CFR0_RESOLUTION12	(0x2000)
++#define TSC2005_CFR0_STATUS		(0x4000)
++#define TSC2005_CFR0_PENMODE		(0x8000)
++
++#define TSC2005_CFR0_INITVALUE	(TSC2005_CFR0_STABTIME_1MS  |	\
++				 TSC2005_CFR0_CLOCK_1MHZ    |	\
++				 TSC2005_CFR0_RESOLUTION12  |	\
++				 TSC2005_CFR0_PRECHARGE_276US | \
++				 TSC2005_CFR0_PENMODE)
++
++/* Bits common to both read and write of config register 0 */
++#define	TSC2005_CFR0_RW_MASK	0x3fff
++
++#define TSC2005_CFR1_BATCHDELAY_0MS	(0x0000)
++#define TSC2005_CFR1_BATCHDELAY_1MS	(0x0001)
++#define TSC2005_CFR1_BATCHDELAY_2MS	(0x0002)
++#define TSC2005_CFR1_BATCHDELAY_4MS	(0x0003)
++#define TSC2005_CFR1_BATCHDELAY_10MS	(0x0004)
++#define TSC2005_CFR1_BATCHDELAY_20MS	(0x0005)
++#define TSC2005_CFR1_BATCHDELAY_40MS	(0x0006)
++#define TSC2005_CFR1_BATCHDELAY_100MS	(0x0007)
++
++#define TSC2005_CFR1_INITVALUE	(TSC2005_CFR1_BATCHDELAY_4MS)
++
++#define TSC2005_CFR2_MAVE_TEMP	(0x0001)
++#define TSC2005_CFR2_MAVE_AUX	(0x0002)
++#define TSC2005_CFR2_MAVE_Z	(0x0004)
++#define TSC2005_CFR2_MAVE_Y	(0x0008)
++#define TSC2005_CFR2_MAVE_X	(0x0010)
++#define TSC2005_CFR2_AVG_1	(0x0000)
++#define TSC2005_CFR2_AVG_3	(0x0400)
++#define TSC2005_CFR2_AVG_7	(0x0800)
++#define TSC2005_CFR2_MEDIUM_1	(0x0000)
++#define TSC2005_CFR2_MEDIUM_3	(0x1000)
++#define TSC2005_CFR2_MEDIUM_7	(0x2000)
++#define TSC2005_CFR2_MEDIUM_15	(0x3000)
++
++#define TSC2005_CFR2_IRQ_MASK   (0xC000)
++#define TSC2005_CFR2_IRQ_DAV	(0x4000)
++#define TSC2005_CFR2_IRQ_PEN	(0x8000)
++#define TSC2005_CFR2_IRQ_PENDAV	(0x0000)
++
++#define TSC2005_CFR2_INITVALUE	(TSC2005_CFR2_IRQ_PENDAV |	\
++				 TSC2005_CFR2_MAVE_X    |	\
++				 TSC2005_CFR2_MAVE_Y    |	\
++				 TSC2005_CFR2_MAVE_Z    |	\
++				 TSC2005_CFR2_MEDIUM_15 |	\
++				 TSC2005_CFR2_AVG_7)
++
++#define MAX_12BIT					((1 << 12) - 1)
++#define TS_SAMPLES					4
++#define TSC2005_TS_PENUP_TIME				40
++
++static const u32 tsc2005_read_reg[] = {
++	(TSC2005_REG | TSC2005_REG_X | TSC2005_REG_READ) << 16,
++	(TSC2005_REG | TSC2005_REG_Y | TSC2005_REG_READ) << 16,
++	(TSC2005_REG | TSC2005_REG_Z1 | TSC2005_REG_READ) << 16,
++	(TSC2005_REG | TSC2005_REG_Z2 | TSC2005_REG_READ) << 16,
++};
++#define NUM_READ_REGS	(sizeof(tsc2005_read_reg)/sizeof(tsc2005_read_reg[0]))
++
++struct tsc2005 {
++	struct spi_device	*spi;
++
++	struct input_dev	*idev;
++	char			phys[32];
++	struct timer_list	penup_timer;
++
++	/* ESD recovery via a hardware reset if the tsc2005
++	 * doesn't respond after a configurable period (in ms) of
++	 * IRQ/SPI inactivity. If esd_timeout is 0, timer and work
++	 * fields are used.
++	 */
++	u32			esd_timeout;
++	struct timer_list	esd_timer;
++	struct work_struct	esd_work;
++
++	spinlock_t		lock;
++	struct mutex		mutex;
++
++	struct spi_message	read_msg;
++	struct spi_transfer	read_xfer[NUM_READ_REGS];
++	u32                     data[NUM_READ_REGS];
++
++	/* previously reported x,y,p (if pen_down) */
++	int			out_x;
++	int			out_y;
++	int			out_p;
++	/* fudge parameters - changes must exceed one of these. */
++	int			fudge_x;
++	int			fudge_y;
++	int			fudge_p;
++	/* raw copy of previous x,y,z */
++	int			in_x;
++	int			in_y;
++	int			in_z1;
++	int			in_z2;
++	/* average accumulators for each component */
++	int			sample_cnt;
++	int			avg_x;
++	int			avg_y;
++	int			avg_z1;
++	int			avg_z2;
++	/* configuration */
++	int			x_plate_ohm;
++	int			hw_avg_max;
++	int			stab_time;
++	int			p_max;
++	int			touch_pressure;
++	/* status */
++	u8			sample_sent;
++	u8			pen_down;
++	u8			disabled;
++	u8			disable_depth;
++	u8			spi_pending;
++
++	void (*set_reset)(bool enable);
++};
++
++static void tsc2005_cmd(struct tsc2005 *ts, u8 cmd)
++{
++	u8 data = TSC2005_CMD | TSC2005_CMD_12BIT | cmd;
++	struct spi_message msg;
++	struct spi_transfer xfer = { 0 };
++
++	xfer.tx_buf = &data;
++	xfer.rx_buf = NULL;
++	xfer.len = 1;
++	xfer.bits_per_word = 8;
++
++	spi_message_init(&msg);
++	spi_message_add_tail(&xfer, &msg);
++	spi_sync(ts->spi, &msg);
++}
++
++static void tsc2005_write(struct tsc2005 *ts, u8 reg, u16 value)
++{
++	u32 tx;
++	struct spi_message msg;
++	struct spi_transfer xfer = { 0 };
++
++	tx = (TSC2005_REG | reg | TSC2005_REG_PND0 |
++	       TSC2005_REG_WRITE) << 16;
++	tx |= value;
++
++	xfer.tx_buf = &tx;
++	xfer.rx_buf = NULL;
++	xfer.len = 4;
++	xfer.bits_per_word = 24;
++
++	spi_message_init(&msg);
++	spi_message_add_tail(&xfer, &msg);
++	spi_sync(ts->spi, &msg);
++}
++
++static void tsc2005_read(struct tsc2005 *ts, u8 reg, u16 *value)
++{
++	u32 tx;
++	u32 rx = 0;
++	struct spi_message msg;
++	struct spi_transfer xfer = { 0 };
++
++	tx = (TSC2005_REG | reg | TSC2005_REG_READ) << 16;
++
++	xfer.tx_buf = &tx;
++	xfer.rx_buf = &rx;
++	xfer.len = 4;
++	xfer.bits_per_word = 24;
++
++	spi_message_init(&msg);
++	spi_message_add_tail(&xfer, &msg);
++	spi_sync(ts->spi, &msg);
++	*value = rx;
++}
++
++static void tsc2005_ts_update_pen_state(struct tsc2005 *ts,
++					int x, int y, int pressure)
++{
++	if (pressure) {
++		input_report_abs(ts->idev, ABS_X, x);
++		input_report_abs(ts->idev, ABS_Y, y);
++		input_report_abs(ts->idev, ABS_PRESSURE, pressure);
++		if (!ts->pen_down) {
++			input_report_key(ts->idev, BTN_TOUCH, 1);
++			ts->pen_down = 1;
++		}
++	} else {
++		input_report_abs(ts->idev, ABS_PRESSURE, 0);
++		if (ts->pen_down) {
++			input_report_key(ts->idev, BTN_TOUCH, 0);
++			ts->pen_down = 0;
++		}
++	}
++
++	input_sync(ts->idev);
++}
++
++/*
++ * This function is called by the SPI framework after the coordinates
++ * have been read from TSC2005
++ */
++static void tsc2005_ts_rx(void *arg)
++{
++	struct tsc2005 *ts = arg;
++	unsigned long flags;
++	int inside_rect, pressure_limit;
++	int x, y, z1, z2, pressure;
++
++	spin_lock_irqsave(&ts->lock, flags);
++
++	if (ts->disable_depth) {
++		ts->spi_pending = 0;
++		goto out;
++	}
++
++	x = ts->data[0];
++	y = ts->data[1];
++	z1 = ts->data[2];
++	z2 = ts->data[3];
++
++	/* validate pressure and position */
++	if (x > MAX_12BIT || y > MAX_12BIT)
++		goto out;
++
++	/* skip coords if the pressure-components are out of range */
++	if (z1 < 100 || z2 > MAX_12BIT || z1 >= z2)
++		goto out;
++
++	/* skip point if this is a pen down with the exact same values as
++	 * the value before pen-up - that implies SPI fed us stale data
++	 */
++	if (!ts->pen_down &&
++	    ts->in_x == x &&
++	    ts->in_y == y &&
++	    ts->in_z1 == z1 &&
++	    ts->in_z2 == z2)
++		goto out;
++
++	/* At this point we are happy we have a valid and useful reading.
++	 * Remember it for later comparisons. We may now begin downsampling
++	 */
++	ts->in_x = x;
++	ts->in_y = y;
++	ts->in_z1 = z1;
++	ts->in_z2 = z2;
++
++	/* don't run average on the "pen down" event */
++	if (ts->sample_sent) {
++		ts->avg_x += x;
++		ts->avg_y += y;
++		ts->avg_z1 += z1;
++		ts->avg_z2 += z2;
++
++		if (++ts->sample_cnt < TS_SAMPLES)
++			goto out;
++
++		x = ts->avg_x / TS_SAMPLES;
++		y = ts->avg_y / TS_SAMPLES;
++		z1 = ts->avg_z1 / TS_SAMPLES;
++		z2 = ts->avg_z2 / TS_SAMPLES;
++	}
++
++	ts->sample_cnt = 0;
++	ts->avg_x = 0;
++	ts->avg_y = 0;
++	ts->avg_z1 = 0;
++	ts->avg_z2 = 0;
++
++	pressure = x * (z2 - z1) / z1;
++	pressure = pressure * ts->x_plate_ohm / 4096;
++
++	pressure_limit = ts->sample_sent ? ts->p_max : ts->touch_pressure;
++	if (pressure > pressure_limit)
++		goto out;
++
++	/* Discard the event if it still is within the previous rect -
++	 * unless the pressure is clearly harder, but then use previous
++	 * x,y position. If any coordinate deviates enough, fudging
++	 * of all three will still take place in the input layer.
++	 */
++	inside_rect = (ts->sample_sent &&
++		x > (int)ts->out_x - ts->fudge_x &&
++		x < (int)ts->out_x + ts->fudge_x &&
++		y > (int)ts->out_y - ts->fudge_y &&
++		y < (int)ts->out_y + ts->fudge_y);
++	if (inside_rect)
++		x = ts->out_x, y = ts->out_y;
++
++	if (!inside_rect || pressure < (ts->out_p - ts->fudge_p)) {
++		tsc2005_ts_update_pen_state(ts, x, y, pressure);
++		ts->sample_sent = 1;
++		ts->out_x = x;
++		ts->out_y = y;
++		ts->out_p = pressure;
++	}
++out:
++	if (ts->spi_pending > 1) {
++		/* One or more interrupts (sometimes several dozens)
++		 * occured while waiting for the SPI read - get
++		 * another read going.
++		 */
++		ts->spi_pending = 1;
++		if (spi_async(ts->spi, &ts->read_msg)) {
++			dev_err(&ts->spi->dev, "ts: spi_async() failed");
++			ts->spi_pending = 0;
++		}
++	} else
++		ts->spi_pending = 0;
++
++	/* kick pen up timer - to make sure it expires again(!) */
++	if (ts->sample_sent) {
++		mod_timer(&ts->penup_timer,
++			  jiffies + msecs_to_jiffies(TSC2005_TS_PENUP_TIME));
++		/* Also kick the watchdog, as we still think we're alive */
++		if (ts->esd_timeout && ts->disable_depth == 0) {
++			unsigned long wdj = msecs_to_jiffies(ts->esd_timeout);
++			mod_timer(&ts->esd_timer, round_jiffies(jiffies+wdj));
++		}
++	}
++	spin_unlock_irqrestore(&ts->lock, flags);
++}
++
++/* This penup timer is very forgiving of delayed SPI reads. The
++ * (ESD) watchdog will rescue us if spi_pending remains set, unless
++ * we are enterring the disabled state. In that case we must just
++ * handle the pen up, and let disabling complete.
++ */
++static void tsc2005_ts_penup_timer_handler(unsigned long data)
++{
++	struct tsc2005 *ts = (struct tsc2005 *)data;
++	if ((!ts->spi_pending || ts->disable_depth) &&
++	    ts->sample_sent) {
++		tsc2005_ts_update_pen_state(ts, 0, 0, 0);
++		ts->sample_sent = 0;
++	}
++}
++
++/*
++ * This interrupt is called when pen is down and coordinates are
++ * available. That is indicated by a either:
++ * a) a rising edge on PINTDAV or (PENDAV mode)
++ * b) a falling edge on DAV line (DAV mode)
++ * depending on the setting of the IRQ bits in the CFR2 setting above.
++ */
++static irqreturn_t tsc2005_ts_irq_handler(int irq, void *dev_id)
++{
++	struct tsc2005 *ts = dev_id;
++	if (ts->disable_depth)
++		goto out;
++
++	if (!ts->spi_pending) {
++		if (spi_async(ts->spi, &ts->read_msg)) {
++			dev_err(&ts->spi->dev, "ts: spi_async() failed");
++			goto out;
++		}
++	}
++	/* By shifting in 1s we can never wrap */
++	ts->spi_pending = (ts->spi_pending<<1)+1;
++
++	/* Kick pen up timer only if it's not been started yet. Strictly,
++	 * it isn't even necessary to start it at all here,  but doing so
++	 * keeps an equivalence between pen state and timer state.
++	 * The SPI read loop will keep pushing it into the future.
++	 * If it times out with an SPI pending, it's ignored anyway.
++	 */
++	if (!timer_pending(&ts->penup_timer)) {
++		unsigned long pu = msecs_to_jiffies(TSC2005_TS_PENUP_TIME);
++		ts->penup_timer.expires = jiffies + pu;
++		add_timer(&ts->penup_timer);
++	}
++out:
++	return IRQ_HANDLED;
++}
++
++static void tsc2005_ts_setup_spi_xfer(struct tsc2005 *ts)
++{
++	struct spi_message *m = &ts->read_msg;
++	struct spi_transfer *x = &ts->read_xfer[0];
++	int i;
++
++	spi_message_init(m);
++
++	for (i = 0; i < NUM_READ_REGS; i++, x++) {
++		x->tx_buf = &tsc2005_read_reg[i];
++		x->rx_buf = &ts->data[i];
++		x->len = 4;
++		x->bits_per_word = 24;
++		x->cs_change = i < (NUM_READ_REGS - 1);
++		spi_message_add_tail(x, m);
++	}
++
++	m->complete = tsc2005_ts_rx;
++	m->context = ts;
++}
++
++static ssize_t tsc2005_ts_pen_down_show(struct device *dev,
++					struct device_attribute *attr,
++					char *buf)
++{
++	struct tsc2005 *ts = dev_get_drvdata(dev);
++
++	return sprintf(buf, "%u\n", ts->pen_down);
++}
++
++static DEVICE_ATTR(pen_down, S_IRUGO, tsc2005_ts_pen_down_show, NULL);
++
++static int tsc2005_configure(struct tsc2005 *ts, int flags)
++{
++	tsc2005_write(ts, TSC2005_REG_CFR0, TSC2005_CFR0_INITVALUE);
++	tsc2005_write(ts, TSC2005_REG_CFR1, TSC2005_CFR1_INITVALUE);
++	tsc2005_write(ts, TSC2005_REG_CFR2, TSC2005_CFR2_INITVALUE);
++	tsc2005_cmd(ts, flags);
++
++	return 0;
++}
++
++static void tsc2005_start_scan(struct tsc2005 *ts)
++{
++	tsc2005_configure(ts, TSC2005_CMD_SCAN_XYZZ);
++}
++
++static void tsc2005_stop_scan(struct tsc2005 *ts)
++{
++	tsc2005_cmd(ts, TSC2005_CMD_STOP);
++}
++
++/* Must be called with mutex held */
++static void tsc2005_disable(struct tsc2005 *ts)
++{
++	if (ts->disable_depth++ != 0)
++		return;
++
++	disable_irq(ts->spi->irq);
++	if (ts->esd_timeout)
++		del_timer(&ts->esd_timer);
++
++	/* wait until penup timer expire normally */
++	do {
++		msleep(4);
++	} while (ts->sample_sent);
++
++	tsc2005_stop_scan(ts);
++}
++
++static void tsc2005_enable(struct tsc2005 *ts)
++{
++	if (ts->disable_depth != 1)
++		goto out;
++
++	if (ts->esd_timeout) {
++		unsigned long wdj = msecs_to_jiffies(ts->esd_timeout);
++		ts->esd_timer.expires = round_jiffies(jiffies+wdj);
++		add_timer(&ts->esd_timer);
++	}
++	tsc2005_start_scan(ts);
++	enable_irq(ts->spi->irq);
++out:
++	--ts->disable_depth;
++}
++
++static ssize_t tsc2005_disable_show(struct device *dev,
++				    struct device_attribute *attr, char *buf)
++{
++	struct tsc2005 *ts = dev_get_drvdata(dev);
++
++	return sprintf(buf, "%u\n", ts->disabled);
++}
++
++static ssize_t tsc2005_disable_store(struct device *dev,
++				     struct device_attribute *attr,
++				     const char *buf, size_t count)
++{
++	struct tsc2005		*ts = dev_get_drvdata(dev);
++	unsigned long res;
++	int i;
++
++	if (strict_strtoul(buf, 10, &res) < 0)
++		return -EINVAL;
++	i = res ? 1 : 0;
++
++	mutex_lock(&ts->mutex);
++	if (i == ts->disabled)
++		goto out;
++	ts->disabled = i;
++
++	if (i)
++		tsc2005_disable(ts);
++	else
++		tsc2005_enable(ts);
++out:
++	mutex_unlock(&ts->mutex);
++	return count;
++}
++
++static DEVICE_ATTR(disable_ts, 0664, tsc2005_disable_show,
++		   tsc2005_disable_store);
++
++static ssize_t tsc2005_ctrl_selftest_show(struct device *dev,
++					  struct device_attribute *attr,
++					  char *buf)
++{
++	u16 temp_high_orig, temp_high_test, temp_high;
++	unsigned int result = 1;
++	struct tsc2005 *ts = dev_get_drvdata(dev);
++
++	if (!ts->set_reset) {
++		dev_warn(&ts->spi->dev,
++			 "unable to selftest: reset not configured\n");
++		result = 0;
++		goto out;
++	}
++
++	mutex_lock(&ts->mutex);
++	tsc2005_disable(ts);
++
++	/* Test ctrl communications via temp high / low registers */
++	tsc2005_read(ts, TSC2005_REG_TEMP_HIGH, &temp_high_orig);
++
++	temp_high_test = (temp_high_orig - 1) & 0x0FFF;
++
++	tsc2005_write(ts, TSC2005_REG_TEMP_HIGH, temp_high_test);
++
++	tsc2005_read(ts, TSC2005_REG_TEMP_HIGH, &temp_high);
++
++	if (temp_high != temp_high_test) {
++		result = 0;
++		dev_warn(dev, "selftest failed: %d != %d\n",
++			 temp_high, temp_high_test);
++	}
++
++	/* HW Reset */
++	ts->set_reset(0);
++	msleep(1); /* only 10us required */
++	ts->set_reset(1);
++
++	tsc2005_enable(ts);
++
++	/* Test that reset really happened */
++	tsc2005_read(ts, TSC2005_REG_TEMP_HIGH, &temp_high);
++
++	if (temp_high != temp_high_orig) {
++		result = 0;
++		dev_warn(dev, "selftest failed after reset: "
++			 "%d != %d\n",
++			 temp_high, temp_high_orig);
++	}
++
++	mutex_unlock(&ts->mutex);
++
++out:
++	return sprintf(buf, "%u\n", result);
++}
++
++static DEVICE_ATTR(ts_ctrl_selftest, S_IRUGO, tsc2005_ctrl_selftest_show, NULL);
++
++static void tsc2005_esd_timer_handler(unsigned long data)
++{
++	struct tsc2005 *ts = (struct tsc2005 *)data;
++	if (!ts->disable_depth)
++		schedule_work(&ts->esd_work);
++}
++
++static void tsc2005_rst_handler(struct work_struct *work)
++{
++	u16 reg_val;
++	struct tsc2005 *ts = container_of(work, struct tsc2005, esd_work);
++	unsigned long wdj;
++
++	mutex_lock(&ts->mutex);
++
++	/* If we are disabled, or the a touch has been detected,
++	 * then ignore this timeout. The enable will restart the
++	 * watchdog, as it restarts scanning
++	 */
++	if (ts->disable_depth)
++		goto out;
++
++	/* If we cannot read our known value from configuration register 0
++	 * then reset the controller as if from power-up and start
++	 * scanning again. Always re-arm the watchdog.
++	 */
++	tsc2005_read(ts, TSC2005_REG_CFR0, &reg_val);
++	if ((reg_val ^ TSC2005_CFR0_INITVALUE) & TSC2005_CFR0_RW_MASK) {
++		dev_info(&ts->spi->dev, "TSC not responding, resetting.\n");
++		/* If this timer kicked in, the penup timer, if ever active
++		 * at all, must have expired ages ago, so no need to del it.
++		 */
++		ts->set_reset(0);
++		if (ts->sample_sent) {
++			tsc2005_ts_update_pen_state(ts, 0, 0, 0);
++			ts->sample_sent = 0;
++		}
++		ts->spi_pending = 0;
++		msleep(1); /* only 10us required */
++		ts->set_reset(1);
++		tsc2005_start_scan(ts);
++	}
++	wdj = msecs_to_jiffies(ts->esd_timeout);
++	mod_timer(&ts->esd_timer, round_jiffies(jiffies+wdj));
++
++out:
++	mutex_unlock(&ts->mutex);
++}
++
++static int __devinit tsc2005_ts_init(struct tsc2005 *ts,
++				     struct tsc2005_platform_data *pdata)
++{
++	struct input_dev *idev;
++	int r;
++	int x_max, y_max;
++
++	init_timer(&ts->penup_timer);
++	setup_timer(&ts->penup_timer, tsc2005_ts_penup_timer_handler,
++			(unsigned long)ts);
++
++	spin_lock_init(&ts->lock);
++	mutex_init(&ts->mutex);
++
++	ts->x_plate_ohm		= pdata->ts_x_plate_ohm ? : 280;
++	ts->hw_avg_max		= pdata->ts_hw_avg;
++	ts->stab_time		= pdata->ts_stab_time;
++	x_max			= pdata->ts_x_max ? : 4096;
++	ts->fudge_x		= pdata->ts_x_fudge ? : 4;
++	y_max			= pdata->ts_y_max ? : 4096;
++	ts->fudge_y		= pdata->ts_y_fudge ? : 8;
++	ts->p_max		= pdata->ts_pressure_max ? : MAX_12BIT;
++	ts->touch_pressure	= pdata->ts_touch_pressure ? : ts->p_max;
++	ts->fudge_p		= pdata->ts_pressure_fudge ? : 2;
++
++	ts->set_reset		= pdata->set_reset;
++
++	idev = input_allocate_device();
++	if (idev == NULL) {
++		r = -ENOMEM;
++		goto err1;
++	}
++
++	idev->name = "TSC2005 touchscreen";
++	snprintf(ts->phys, sizeof(ts->phys), "%s/input-ts",
++		 dev_name(&ts->spi->dev));
++	idev->phys = ts->phys;
++
++	idev->evbit[0] = BIT(EV_ABS) | BIT(EV_KEY);
++	idev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE);
++	idev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
++	ts->idev = idev;
++
++	tsc2005_ts_setup_spi_xfer(ts);
++
++	input_set_abs_params(idev, ABS_X, 0, x_max, ts->fudge_x, 0);
++	input_set_abs_params(idev, ABS_Y, 0, y_max, ts->fudge_y, 0);
++	input_set_abs_params(idev, ABS_PRESSURE, 0, ts->p_max, ts->fudge_p, 0);
++
++	tsc2005_start_scan(ts);
++
++	r = request_irq(ts->spi->irq, tsc2005_ts_irq_handler,
++			(((TSC2005_CFR2_INITVALUE & TSC2005_CFR2_IRQ_MASK) ==
++			  TSC2005_CFR2_IRQ_PENDAV)
++			 ? IRQF_TRIGGER_RISING
++			 : IRQF_TRIGGER_FALLING) |
++			IRQF_DISABLED, "tsc2005", ts);
++	if (r < 0) {
++		dev_err(&ts->spi->dev, "unable to get DAV IRQ");
++		goto err2;
++	}
++
++	set_irq_wake(ts->spi->irq, 1);
++
++	r = input_register_device(idev);
++	if (r < 0) {
++		dev_err(&ts->spi->dev, "can't register touchscreen device\n");
++		goto err3;
++	}
++
++	/* We can tolerate these failing */
++	r = device_create_file(&ts->spi->dev, &dev_attr_ts_ctrl_selftest);
++	if (r < 0)
++		dev_warn(&ts->spi->dev, "can't create sysfs file for %s: %d\n",
++			 dev_attr_ts_ctrl_selftest.attr.name, r);
++
++	r = device_create_file(&ts->spi->dev, &dev_attr_pen_down);
++	if (r < 0)
++		dev_warn(&ts->spi->dev, "can't create sysfs file for %s: %d\n",
++			 dev_attr_pen_down.attr.name, r);
++
++	r = device_create_file(&ts->spi->dev, &dev_attr_disable_ts);
++	if (r < 0)
++		dev_warn(&ts->spi->dev, "can't create sysfs file for %s: %d\n",
++			 dev_attr_disable_ts.attr.name, r);
++
++	/* Finally, configure and start the optional EDD watchdog. */
++	ts->esd_timeout = pdata->esd_timeout;
++	if (ts->esd_timeout && ts->set_reset) {
++		unsigned long wdj;
++		setup_timer(&ts->esd_timer, tsc2005_esd_timer_handler,
++			    (unsigned long)ts);
++		INIT_WORK(&ts->esd_work, tsc2005_rst_handler);
++		wdj = msecs_to_jiffies(ts->esd_timeout);
++		ts->esd_timer.expires = round_jiffies(jiffies+wdj);
++		add_timer(&ts->esd_timer);
++	}
++
++	return 0;
++err3:
++	free_irq(ts->spi->irq, ts);
++err2:
++	tsc2005_stop_scan(ts);
++	input_free_device(idev);
++err1:
++	return r;
++}
++
++static int __devinit tsc2005_probe(struct spi_device *spi)
++{
++	struct tsc2005			*ts;
++	struct tsc2005_platform_data	*pdata = spi->dev.platform_data;
++	int r;
++
++	if (spi->irq < 0) {
++		dev_dbg(&spi->dev, "no irq?\n");
++		return -ENODEV;
++	}
++	if (!pdata) {
++		dev_dbg(&spi->dev, "no platform data?\n");
++		return -ENODEV;
++	}
++
++	ts = kzalloc(sizeof(*ts), GFP_KERNEL);
++	if (ts == NULL)
++		return -ENOMEM;
++
++	dev_set_drvdata(&spi->dev, ts);
++	ts->spi = spi;
++	spi->dev.power.power_state = PMSG_ON;
++
++	spi->mode = SPI_MODE_0;
++	spi->bits_per_word = 8;
++	/* The max speed might've been defined by the board-specific
++	 * struct */
++	if (!spi->max_speed_hz)
++		spi->max_speed_hz = TSC2005_HZ;
++
++	spi_setup(spi);
++
++	r = tsc2005_ts_init(ts, pdata);
++	if (r)
++		goto err1;
++
++	return 0;
++
++err1:
++	kfree(ts);
++	return r;
++}
++
++static int __devexit tsc2005_remove(struct spi_device *spi)
++{
++	struct tsc2005 *ts = dev_get_drvdata(&spi->dev);
++
++	mutex_lock(&ts->mutex);
++	tsc2005_disable(ts);
++	mutex_unlock(&ts->mutex);
++
++	device_remove_file(&ts->spi->dev, &dev_attr_disable_ts);
++	device_remove_file(&ts->spi->dev, &dev_attr_pen_down);
++	device_remove_file(&ts->spi->dev, &dev_attr_ts_ctrl_selftest);
++
++	free_irq(ts->spi->irq, ts);
++	input_unregister_device(ts->idev);
++
++	if (ts->esd_timeout)
++		del_timer(&ts->esd_timer);
++	kfree(ts);
++
++	return 0;
++}
++
++#ifdef CONFIG_PM
++static int tsc2005_suspend(struct spi_device *spi, pm_message_t mesg)
++{
++	struct tsc2005 *ts = dev_get_drvdata(&spi->dev);
++
++	mutex_lock(&ts->mutex);
++	tsc2005_disable(ts);
++	mutex_unlock(&ts->mutex);
++
++	return 0;
++}
++
++static int tsc2005_resume(struct spi_device *spi)
++{
++	struct tsc2005 *ts = dev_get_drvdata(&spi->dev);
++
++	mutex_lock(&ts->mutex);
++	tsc2005_enable(ts);
++	mutex_unlock(&ts->mutex);
++
++	return 0;
++}
++#endif
++
++static struct spi_driver tsc2005_driver = {
++	.driver = {
++		.name = "tsc2005",
++		.owner = THIS_MODULE,
++	},
++#ifdef CONFIG_PM
++	.suspend = tsc2005_suspend,
++	.resume = tsc2005_resume,
++#endif
++	.probe = tsc2005_probe,
++	.remove = __devexit_p(tsc2005_remove),
++};
++
++static int __init tsc2005_init(void)
++{
++	printk(KERN_INFO "TSC2005 driver initializing\n");
++
++	return spi_register_driver(&tsc2005_driver);
++}
++module_init(tsc2005_init);
++
++static void __exit tsc2005_exit(void)
++{
++	spi_unregister_driver(&tsc2005_driver);
++}
++module_exit(tsc2005_exit);
++
++MODULE_AUTHOR("Lauri Leukkunen <[email protected]>");
++MODULE_LICENSE("GPL");
++MODULE_ALIAS("platform:tsc2005");
+--- /dev/null
++++ linux-2.6.35/include/linux/spi/tsc2005.h
+@@ -0,0 +1,30 @@
++#ifndef _LINUX_SPI_TSC2005_H
++#define _LINUX_SPI_TSC2005_H
++
++#include <linux/types.h>
++
++struct tsc2005_platform_data {
++	u16	ts_x_plate_ohm;
++	u32	ts_stab_time;	/* voltage settling time */
++	u8	ts_hw_avg;	/* HW assiseted averaging. Can be
++				   0, 4, 8, 16 samples per reading */
++	u32	ts_touch_pressure;	/* Pressure limit until we report a
++					   touch event. After that we switch
++					   to ts_max_pressure. */
++	u32	ts_pressure_max;/* Samples with bigger pressure value will
++				   be ignored, since the corresponding X, Y
++				   values are unreliable */
++	u32	ts_pressure_fudge;
++	u32	ts_x_max;
++	u32	ts_x_fudge;
++	u32	ts_y_max;
++	u32	ts_y_fudge;
++
++	u32	esd_timeout;    /* msec of inactivity before we check */
++
++	unsigned ts_ignore_last:1;
++
++	void (*set_reset)(bool enable);
++};
++
++#endif

+ 198 - 0
target/linux/omap24xx/patches-2.6.35/700-video-omap.patch

@@ -0,0 +1,198 @@
+Index: linux-2.6.35/drivers/video/omap/dispc.c
+===================================================================
+--- linux-2.6.35.orig/drivers/video/omap/dispc.c	2010-08-08 12:56:09.000000000 +0200
++++ linux-2.6.35/drivers/video/omap/dispc.c	2010-08-08 12:57:42.000000000 +0200
+@@ -190,6 +190,11 @@ static struct {
+ 	struct omapfb_color_key	color_key;
+ } dispc;
+ 
++struct platform_device omapdss_device = {
++	.name		= "omapdss",
++	.id		= -1,
++};
++
+ static void enable_lcd_clocks(int enable);
+ 
+ static void inline dispc_write_reg(int idx, u32 val)
+@@ -916,20 +921,20 @@ static irqreturn_t omap_dispc_irq_handle
+ 
+ static int get_dss_clocks(void)
+ {
+-	dispc.dss_ick = clk_get(&dispc.fbdev->dssdev->dev, "ick");
++	dispc.dss_ick = clk_get(&omapdss_device.dev, "ick");
+ 	if (IS_ERR(dispc.dss_ick)) {
+ 		dev_err(dispc.fbdev->dev, "can't get ick\n");
+ 		return PTR_ERR(dispc.dss_ick);
+ 	}
+ 
+-	dispc.dss1_fck = clk_get(&dispc.fbdev->dssdev->dev, "dss1_fck");
++	dispc.dss1_fck = clk_get(&omapdss_device.dev, "dss1_fck");
+ 	if (IS_ERR(dispc.dss1_fck)) {
+ 		dev_err(dispc.fbdev->dev, "can't get dss1_fck\n");
+ 		clk_put(dispc.dss_ick);
+ 		return PTR_ERR(dispc.dss1_fck);
+ 	}
+ 
+-	dispc.dss_54m_fck = clk_get(&dispc.fbdev->dssdev->dev, "tv_fck");
++	dispc.dss_54m_fck = clk_get(&omapdss_device.dev, "tv_fck");
+ 	if (IS_ERR(dispc.dss_54m_fck)) {
+ 		dev_err(dispc.fbdev->dev, "can't get tv_fck\n");
+ 		clk_put(dispc.dss_ick);
+@@ -1381,6 +1386,12 @@ static int omap_dispc_init(struct omapfb
+ 	int skip_init = 0;
+ 	int i;
+ 
++	r = platform_device_register(&omapdss_device);
++	if (r) {
++		dev_err(fbdev->dev, "can't register omapdss device\n");
++		return r;
++	}
++
+ 	memset(&dispc, 0, sizeof(dispc));
+ 
+ 	dispc.base = ioremap(DISPC_BASE, SZ_1K);
+@@ -1524,6 +1535,7 @@ static void omap_dispc_cleanup(void)
+ 	free_irq(INT_24XX_DSS_IRQ, dispc.fbdev);
+ 	put_dss_clocks();
+ 	iounmap(dispc.base);
++	platform_device_unregister(&omapdss_device);
+ }
+ 
+ const struct lcd_ctrl omap2_int_ctrl = {
+Index: linux-2.6.35/drivers/video/omap/lcd_htcherald.c
+===================================================================
+--- linux-2.6.35.orig/drivers/video/omap/lcd_htcherald.c	2010-08-08 12:56:09.000000000 +0200
++++ linux-2.6.35/drivers/video/omap/lcd_htcherald.c	2010-08-08 12:57:43.000000000 +0200
+@@ -115,12 +115,12 @@ struct platform_driver htcherald_panel_d
+ 	},
+ };
+ 
+-static int __init htcherald_panel_drv_init(void)
++static int htcherald_panel_drv_init(void)
+ {
+ 	return platform_driver_register(&htcherald_panel_driver);
+ }
+ 
+-static void __exit htcherald_panel_drv_cleanup(void)
++static void htcherald_panel_drv_cleanup(void)
+ {
+ 	platform_driver_unregister(&htcherald_panel_driver);
+ }
+Index: linux-2.6.35/drivers/video/omap/lcd_mipid.c
+===================================================================
+--- linux-2.6.35.orig/drivers/video/omap/lcd_mipid.c	2010-08-08 12:56:09.000000000 +0200
++++ linux-2.6.35/drivers/video/omap/lcd_mipid.c	2010-08-08 12:57:44.000000000 +0200
+@@ -551,9 +551,9 @@ static int mipid_detect(struct mipid_dev
+ 		md->esd_check = ls041y3_esd_check;
+ 		break;
+ 	default:
+-		md->panel.name = "unknown";
+-		dev_err(&md->spi->dev, "invalid display ID\n");
+-		return -ENODEV;
++		dev_err(&md->spi->dev, "FIXME: LCD panel detection failed! ID: %02x%02x%02x\n", display_id[0], display_id[1], display_id[2]);
++		md->panel.name = "ls041y3";
++		md->esd_check = ls041y3_esd_check;
+ 	}
+ 
+ 	md->revision = display_id[1];
+Index: linux-2.6.35/drivers/video/omap/omapfb.h
+===================================================================
+--- linux-2.6.35.orig/drivers/video/omap/omapfb.h	2010-08-08 12:56:09.000000000 +0200
++++ linux-2.6.35/drivers/video/omap/omapfb.h	2010-08-08 12:57:45.000000000 +0200
+@@ -203,8 +203,6 @@ struct omapfb_device {
+ 
+ 	struct omapfb_mem_desc		mem_desc;
+ 	struct fb_info			*fb_info[OMAPFB_PLANE_NUM];
+-
+-	struct platform_device	*dssdev;	/* dummy dev for clocks */
+ };
+ 
+ #ifdef CONFIG_ARCH_OMAP1
+@@ -226,4 +224,6 @@ extern int  omapfb_update_window_async(s
+ 				       void (*callback)(void *),
+ 				       void *callback_data);
+ 
++extern struct platform_device omapdss_device;
++
+ #endif /* __OMAPFB_H */
+Index: linux-2.6.35/drivers/video/omap/omapfb_main.c
+===================================================================
+--- linux-2.6.35.orig/drivers/video/omap/omapfb_main.c	2010-08-08 12:56:09.000000000 +0200
++++ linux-2.6.35/drivers/video/omap/omapfb_main.c	2010-08-08 12:57:46.000000000 +0200
+@@ -84,19 +84,6 @@ static struct caps_table_struct color_ca
+ 	{ 1 << OMAPFB_COLOR_YUY422,	"YUY422", },
+ };
+ 
+-static void omapdss_release(struct device *dev)
+-{
+-}
+-
+-/* dummy device for clocks */
+-static struct platform_device omapdss_device = {
+-	.name		= "omapdss",
+-	.id		= -1,
+-	.dev            = {
+-		.release = omapdss_release,
+-	},
+-};
+-
+ /*
+  * ---------------------------------------------------------------------------
+  * LCD panel
+@@ -1715,7 +1702,6 @@ static int omapfb_do_probe(struct platfo
+ 
+ 	fbdev->dev = &pdev->dev;
+ 	fbdev->panel = panel;
+-	fbdev->dssdev = &omapdss_device;
+ 	platform_set_drvdata(pdev, fbdev);
+ 
+ 	mutex_init(&fbdev->rqueue_mutex);
+@@ -1830,16 +1816,8 @@ cleanup:
+ 
+ static int omapfb_probe(struct platform_device *pdev)
+ {
+-	int r;
+-
+ 	BUG_ON(fbdev_pdev != NULL);
+ 
+-	r = platform_device_register(&omapdss_device);
+-	if (r) {
+-		dev_err(&pdev->dev, "can't register omapdss device\n");
+-		return r;
+-	}
+-
+ 	/* Delay actual initialization until the LCD is registered */
+ 	fbdev_pdev = pdev;
+ 	if (fbdev_panel != NULL)
+@@ -1867,9 +1845,6 @@ static int omapfb_remove(struct platform
+ 	fbdev->state = OMAPFB_DISABLED;
+ 	omapfb_free_resources(fbdev, saved_state);
+ 
+-	platform_device_unregister(&omapdss_device);
+-	fbdev->dssdev = NULL;
+-
+ 	return 0;
+ }
+ 
+---
+ drivers/video/omap/rfbi.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- linux-2.6.35.orig/drivers/video/omap/rfbi.c
++++ linux-2.6.35/drivers/video/omap/rfbi.c
+@@ -84,13 +84,13 @@ static inline u32 rfbi_read_reg(int idx)
+ 
+ static int rfbi_get_clocks(void)
+ {
+-	rfbi.dss_ick = clk_get(&rfbi.fbdev->dssdev->dev, "ick");
++	rfbi.dss_ick = clk_get(&omapdss_device.dev, "ick");
+ 	if (IS_ERR(rfbi.dss_ick)) {
+ 		dev_err(rfbi.fbdev->dev, "can't get ick\n");
+ 		return PTR_ERR(rfbi.dss_ick);
+ 	}
+ 
+-	rfbi.dss1_fck = clk_get(&rfbi.fbdev->dssdev->dev, "dss1_fck");
++	rfbi.dss1_fck = clk_get(&omapdss_device.dev, "dss1_fck");
+ 	if (IS_ERR(rfbi.dss1_fck)) {
+ 		dev_err(rfbi.fbdev->dev, "can't get dss1_fck\n");
+ 		clk_put(rfbi.dss_ick);

+ 17 - 0
target/linux/omap24xx/patches-2.6.35/800-decompress-unlzo-fixes.patch

@@ -0,0 +1,17 @@
+---
+ lib/decompress_unlzo.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- linux-2.6.35.orig/lib/decompress_unlzo.c
++++ linux-2.6.35/lib/decompress_unlzo.c
+@@ -50,6 +50,10 @@ static const unsigned char lzop_magic[]
+ #define LZO_BLOCK_SIZE        (256*1024l)
+ #define HEADER_HAS_FILTER      0x00000800L
+ 
++#ifndef INIT
++#define INIT /* nothing */
++#endif
++
+ STATIC inline int INIT parse_header(u8 *input, u8 *skip)
+ {
+ 	int l;

+ 17 - 0
target/linux/omap24xx/profiles/100-n810.mk

@@ -0,0 +1,17 @@
+#
+# Copyright (C) 2010 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+define Profile/n810
+  NAME:=Nokia n810
+  PACKAGES:=
+endef
+
+define Profile/n810/Description
+	Package set compatible with Nokia n810 hardware
+endef
+$(eval $(call Profile,n810))
+