diff options
Diffstat (limited to 'target/linux/brcm2708/patches-3.3/0500-rpi-patches-geaf792a-9efb4705.patch')
-rw-r--r-- | target/linux/brcm2708/patches-3.3/0500-rpi-patches-geaf792a-9efb4705.patch | 10488 |
1 files changed, 10488 insertions, 0 deletions
diff --git a/target/linux/brcm2708/patches-3.3/0500-rpi-patches-geaf792a-9efb4705.patch b/target/linux/brcm2708/patches-3.3/0500-rpi-patches-geaf792a-9efb4705.patch new file mode 100644 index 0000000000..b5211d9caa --- /dev/null +++ b/target/linux/brcm2708/patches-3.3/0500-rpi-patches-geaf792a-9efb4705.patch @@ -0,0 +1,10488 @@ +--- a/arch/arm/configs/bcmrpi_cutdown_defconfig ++++ b/arch/arm/configs/bcmrpi_cutdown_defconfig +@@ -1,1307 +1,436 @@ +-# +-# Automatically generated file; DO NOT EDIT. +-# Linux/arm 3.1.9 Kernel Configuration +-# +-CONFIG_ARM=y +-CONFIG_SYS_SUPPORTS_APM_EMULATION=y +-CONFIG_GENERIC_GPIO=y +-# CONFIG_ARCH_USES_GETTIMEOFFSET is not set +-CONFIG_GENERIC_CLOCKEVENTS=y +-CONFIG_KTIME_SCALAR=y +-CONFIG_HAVE_PROC_CPU=y +-CONFIG_STACKTRACE_SUPPORT=y +-CONFIG_HAVE_LATENCYTOP_SUPPORT=y +-CONFIG_LOCKDEP_SUPPORT=y +-CONFIG_TRACE_IRQFLAGS_SUPPORT=y +-CONFIG_HARDIRQS_SW_RESEND=y +-CONFIG_GENERIC_IRQ_PROBE=y +-CONFIG_RWSEM_GENERIC_SPINLOCK=y +-CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +-CONFIG_GENERIC_HWEIGHT=y +-CONFIG_GENERIC_CALIBRATE_DELAY=y +-CONFIG_NEED_DMA_MAP_STATE=y +-CONFIG_VECTORS_BASE=0xffff0000 +-# CONFIG_ARM_PATCH_PHYS_VIRT is not set +-CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +-CONFIG_HAVE_IRQ_WORK=y +- +-# +-# General setup +-# + CONFIG_EXPERIMENTAL=y +-CONFIG_BROKEN_ON_SMP=y +-CONFIG_INIT_ENV_ARG_LIMIT=32 +-CONFIG_CROSS_COMPILE="" +-CONFIG_LOCALVERSION="" + # CONFIG_LOCALVERSION_AUTO is not set +-CONFIG_HAVE_KERNEL_GZIP=y +-CONFIG_HAVE_KERNEL_LZMA=y +-CONFIG_HAVE_KERNEL_LZO=y +-CONFIG_KERNEL_GZIP=y +-# CONFIG_KERNEL_LZMA is not set +-# CONFIG_KERNEL_LZO is not set +-CONFIG_DEFAULT_HOSTNAME="(none)" +-CONFIG_SWAP=y + CONFIG_SYSVIPC=y +-CONFIG_SYSVIPC_SYSCTL=y + CONFIG_POSIX_MQUEUE=y +-CONFIG_POSIX_MQUEUE_SYSCTL=y +-# CONFIG_BSD_PROCESS_ACCT is not set +-# CONFIG_FHANDLE is not set +-# CONFIG_TASKSTATS is not set +-# CONFIG_AUDIT is not set +-CONFIG_HAVE_GENERIC_HARDIRQS=y +- +-# +-# IRQ subsystem +-# +-CONFIG_GENERIC_HARDIRQS=y +-CONFIG_HAVE_SPARSE_IRQ=y +-CONFIG_GENERIC_IRQ_SHOW=y +-# CONFIG_SPARSE_IRQ is not set +- +-# +-# RCU Subsystem +-# +-CONFIG_TINY_RCU=y +-# CONFIG_PREEMPT_RCU is not set +-# CONFIG_RCU_TRACE is not set +-# CONFIG_TREE_RCU_TRACE is not set + CONFIG_IKCONFIG=y + CONFIG_IKCONFIG_PROC=y +-CONFIG_LOG_BUF_SHIFT=17 +-# CONFIG_CGROUPS is not set +-# CONFIG_NAMESPACES is not set +-# CONFIG_SCHED_AUTOGROUP is not set +-# CONFIG_SYSFS_DEPRECATED is not set +-# CONFIG_RELAY is not set +-# CONFIG_BLK_DEV_INITRD is not set +-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +-CONFIG_SYSCTL=y +-CONFIG_ANON_INODES=y +-CONFIG_EXPERT=y + # CONFIG_UID16 is not set +-CONFIG_SYSCTL_SYSCALL=y + # CONFIG_KALLSYMS is not set +-CONFIG_HOTPLUG=y +-CONFIG_PRINTK=y +-CONFIG_BUG=y +-# CONFIG_ELF_CORE is not set +-CONFIG_BASE_FULL=y +-CONFIG_FUTEX=y +-CONFIG_EPOLL=y +-CONFIG_SIGNALFD=y +-CONFIG_TIMERFD=y +-CONFIG_EVENTFD=y +-CONFIG_SHMEM=y +-CONFIG_AIO=y + CONFIG_EMBEDDED=y +-CONFIG_HAVE_PERF_EVENTS=y +-CONFIG_PERF_USE_VMALLOC=y +- +-# +-# Kernel Performance Events And Counters +-# +-# CONFIG_PERF_EVENTS is not set +-# CONFIG_PERF_COUNTERS is not set + # CONFIG_VM_EVENT_COUNTERS is not set + # CONFIG_COMPAT_BRK is not set + CONFIG_SLAB=y +-# CONFIG_SLUB is not set +-# CONFIG_SLOB is not set +-# CONFIG_PROFILING is not set +-CONFIG_HAVE_OPROFILE=y +-# CONFIG_KPROBES is not set +-CONFIG_HAVE_KPROBES=y +-CONFIG_HAVE_KRETPROBES=y +-CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y +-CONFIG_HAVE_CLK=y +-CONFIG_HAVE_DMA_API_DEBUG=y +- +-# +-# GCOV-based kernel profiling +-# +-CONFIG_HAVE_GENERIC_DMA_COHERENT=y +-CONFIG_SLABINFO=y +-CONFIG_RT_MUTEXES=y +-CONFIG_BASE_SMALL=0 + CONFIG_MODULES=y +-# CONFIG_MODULE_FORCE_LOAD is not set + CONFIG_MODULE_UNLOAD=y +-# CONFIG_MODULE_FORCE_UNLOAD is not set + CONFIG_MODVERSIONS=y + CONFIG_MODULE_SRCVERSION_ALL=y +-CONFIG_BLOCK=y +-CONFIG_LBDAF=y + # CONFIG_BLK_DEV_BSG is not set +-# CONFIG_BLK_DEV_BSGLIB is not set +-# CONFIG_BLK_DEV_INTEGRITY is not set +- +-# +-# IO Schedulers +-# +-CONFIG_IOSCHED_NOOP=y +-CONFIG_IOSCHED_DEADLINE=y +-CONFIG_IOSCHED_CFQ=y +-# CONFIG_DEFAULT_DEADLINE is not set +-CONFIG_DEFAULT_CFQ=y +-# CONFIG_DEFAULT_NOOP is not set +-CONFIG_DEFAULT_IOSCHED="cfq" +-# CONFIG_INLINE_SPIN_TRYLOCK is not set +-# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +-# CONFIG_INLINE_SPIN_LOCK is not set +-# CONFIG_INLINE_SPIN_LOCK_BH is not set +-# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +-# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +-CONFIG_INLINE_SPIN_UNLOCK=y +-# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +-CONFIG_INLINE_SPIN_UNLOCK_IRQ=y +-# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +-# CONFIG_INLINE_READ_TRYLOCK is not set +-# CONFIG_INLINE_READ_LOCK is not set +-# CONFIG_INLINE_READ_LOCK_BH is not set +-# CONFIG_INLINE_READ_LOCK_IRQ is not set +-# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +-CONFIG_INLINE_READ_UNLOCK=y +-# CONFIG_INLINE_READ_UNLOCK_BH is not set +-CONFIG_INLINE_READ_UNLOCK_IRQ=y +-# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +-# CONFIG_INLINE_WRITE_TRYLOCK is not set +-# CONFIG_INLINE_WRITE_LOCK is not set +-# CONFIG_INLINE_WRITE_LOCK_BH is not set +-# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +-# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +-CONFIG_INLINE_WRITE_UNLOCK=y +-# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +-CONFIG_INLINE_WRITE_UNLOCK_IRQ=y +-# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +-# CONFIG_MUTEX_SPIN_ON_OWNER is not set +-CONFIG_FREEZER=y +- +-# +-# System Type +-# +-CONFIG_MMU=y +-# CONFIG_ARCH_INTEGRATOR is not set +-# CONFIG_ARCH_REALVIEW is not set +-# CONFIG_ARCH_VERSATILE is not set +-# CONFIG_ARCH_VEXPRESS is not set +-# CONFIG_ARCH_AT91 is not set +-# CONFIG_ARCH_BCMRING is not set +-# CONFIG_ARCH_CLPS711X is not set +-# CONFIG_ARCH_CNS3XXX is not set +-# CONFIG_ARCH_GEMINI is not set +-# CONFIG_ARCH_PRIMA2 is not set +-# CONFIG_ARCH_EBSA110 is not set +-# CONFIG_ARCH_EP93XX is not set +-# CONFIG_ARCH_FOOTBRIDGE is not set +-# CONFIG_ARCH_MXC is not set +-# CONFIG_ARCH_MXS is not set +-# CONFIG_ARCH_NETX is not set +-# CONFIG_ARCH_H720X is not set +-# CONFIG_ARCH_IOP13XX is not set +-# CONFIG_ARCH_IOP32X is not set +-# CONFIG_ARCH_IOP33X is not set +-# CONFIG_ARCH_IXP23XX is not set +-# CONFIG_ARCH_IXP2000 is not set +-# CONFIG_ARCH_IXP4XX is not set +-# CONFIG_ARCH_DOVE is not set +-# CONFIG_ARCH_KIRKWOOD is not set +-# CONFIG_ARCH_LPC32XX is not set +-# CONFIG_ARCH_MV78XX0 is not set +-# CONFIG_ARCH_ORION5X is not set +-# CONFIG_ARCH_MMP is not set +-# CONFIG_ARCH_KS8695 is not set +-# CONFIG_ARCH_W90X900 is not set +-# CONFIG_ARCH_NUC93X is not set +-# CONFIG_ARCH_TEGRA is not set +-# CONFIG_ARCH_PNX4008 is not set +-# CONFIG_ARCH_PXA is not set +-# CONFIG_ARCH_MSM is not set +-# CONFIG_ARCH_SHMOBILE is not set +-# CONFIG_ARCH_RPC is not set +-# CONFIG_ARCH_SA1100 is not set +-# CONFIG_ARCH_S3C2410 is not set +-# CONFIG_ARCH_S3C64XX is not set +-# CONFIG_ARCH_S5P64X0 is not set +-# CONFIG_ARCH_S5PC100 is not set +-# CONFIG_ARCH_S5PV210 is not set +-# CONFIG_ARCH_EXYNOS4 is not set +-# CONFIG_ARCH_SHARK is not set +-# CONFIG_ARCH_TCC_926 is not set +-# CONFIG_ARCH_U300 is not set +-# CONFIG_ARCH_U8500 is not set +-# CONFIG_ARCH_NOMADIK is not set +-# CONFIG_ARCH_DAVINCI is not set +-# CONFIG_ARCH_OMAP is not set +-# CONFIG_PLAT_SPEAR is not set + CONFIG_ARCH_BCM2708=y +-# CONFIG_ARCH_VT8500 is not set +-# CONFIG_ARCH_ZYNQ is not set +- +-# +-# System MMU +-# +- +-# +-# Broadcom BCM2708 Implementations +-# +-CONFIG_MACH_BCM2708=y +-CONFIG_BCM2708_GPIO=y +-CONFIG_BCM2708_VCMEM=y +- +-# +-# Processor Type +-# +-CONFIG_CPU_V6=y +-CONFIG_CPU_32v6=y +-CONFIG_CPU_ABRT_EV6=y +-CONFIG_CPU_PABRT_V6=y +-CONFIG_CPU_CACHE_V6=y +-CONFIG_CPU_CACHE_VIPT=y +-CONFIG_CPU_COPY_V6=y +-CONFIG_CPU_TLB_V6=y +-CONFIG_CPU_HAS_ASID=y +-CONFIG_CPU_CP15=y +-CONFIG_CPU_CP15_MMU=y +-CONFIG_CPU_USE_DOMAINS=y +- +-# +-# Processor Features +-# +-CONFIG_ARM_THUMB=y +-# CONFIG_CPU_ICACHE_DISABLE is not set +-# CONFIG_CPU_DCACHE_DISABLE is not set +-# CONFIG_CPU_BPREDICT_DISABLE is not set +-CONFIG_ARM_L1_CACHE_SHIFT=5 +-CONFIG_ARM_DMA_MEM_BUFFERABLE=y +-CONFIG_CPU_HAS_PMU=y +-CONFIG_ARM_ERRATA_411920=y +-# CONFIG_ARM_ERRATA_364296 is not set +- +-# +-# Bus support +-# +-CONFIG_ARM_AMBA=y +-# CONFIG_PCI_SYSCALL is not set +-# CONFIG_ARCH_SUPPORTS_MSI is not set +-# CONFIG_PCCARD is not set +- +-# +-# Kernel Features +-# +-CONFIG_TICK_ONESHOT=y + CONFIG_NO_HZ=y +-# CONFIG_HIGH_RES_TIMERS is not set +-CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +-CONFIG_VMSPLIT_3G=y +-# CONFIG_VMSPLIT_2G is not set +-# CONFIG_VMSPLIT_1G is not set +-CONFIG_PAGE_OFFSET=0xC0000000 +-CONFIG_PREEMPT_NONE=y +-# CONFIG_PREEMPT_VOLUNTARY is not set +-# CONFIG_PREEMPT is not set +-CONFIG_HZ=100 ++CONFIG_HIGH_RES_TIMERS=y + CONFIG_AEABI=y +-CONFIG_OABI_COMPAT=y +-# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set +-# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set +-CONFIG_HAVE_ARCH_PFN_VALID=y +-# CONFIG_HIGHMEM is not set +-CONFIG_SELECT_MEMORY_MODEL=y +-CONFIG_FLATMEM_MANUAL=y +-CONFIG_FLATMEM=y +-CONFIG_FLAT_NODE_MEM_MAP=y +-CONFIG_HAVE_MEMBLOCK=y +-CONFIG_PAGEFLAGS_EXTENDED=y +-CONFIG_SPLIT_PTLOCK_CPUS=4 +-# CONFIG_COMPACTION is not set +-# CONFIG_PHYS_ADDR_T_64BIT is not set +-CONFIG_ZONE_DMA_FLAG=0 +-CONFIG_VIRT_TO_BUS=y +-# CONFIG_KSM is not set +-CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +-CONFIG_NEED_PER_CPU_KM=y +-# CONFIG_CLEANCACHE is not set +-CONFIG_FORCE_MAX_ZONEORDER=11 +-CONFIG_ALIGNMENT_TRAP=y +-# CONFIG_UACCESS_WITH_MEMCPY is not set +-# CONFIG_SECCOMP is not set +-# CONFIG_CC_STACKPROTECTOR is not set +-# CONFIG_DEPRECATED_PARAM_STRUCT is not set +- +-# +-# Boot options +-# +-# CONFIG_USE_OF is not set + CONFIG_ZBOOT_ROM_TEXT=0x0 + CONFIG_ZBOOT_ROM_BSS=0x0 + CONFIG_CMDLINE="dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 root=/dev/mmcblk0p2 rootfstype=ext3 rootwait" +-CONFIG_CMDLINE_FROM_BOOTLOADER=y +-# CONFIG_CMDLINE_EXTEND is not set +-# CONFIG_CMDLINE_FORCE is not set +-# CONFIG_XIP_KERNEL is not set +-# CONFIG_KEXEC is not set +-# CONFIG_CRASH_DUMP is not set +-# CONFIG_AUTO_ZRELADDR is not set +- +-# +-# CPU Power Management +-# + CONFIG_CPU_IDLE=y +-CONFIG_CPU_IDLE_GOV_LADDER=y +-CONFIG_CPU_IDLE_GOV_MENU=y +- +-# +-# Floating point emulation +-# +- +-# +-# At least one emulation must be selected +-# +-# CONFIG_FPE_NWFPE is not set +-# CONFIG_FPE_FASTFPE is not set + CONFIG_VFP=y +- +-# +-# Userspace binary formats +-# +-CONFIG_BINFMT_ELF=y +-CONFIG_HAVE_AOUT=y +-# CONFIG_BINFMT_AOUT is not set +-# CONFIG_BINFMT_MISC is not set +- +-# +-# Power management options +-# +-CONFIG_SUSPEND=y +-CONFIG_SUSPEND_FREEZER=y +-CONFIG_PM_SLEEP=y +-# CONFIG_PM_RUNTIME is not set +-CONFIG_PM=y +-# CONFIG_PM_DEBUG is not set +-# CONFIG_APM_EMULATION is not set +-CONFIG_PM_CLK=y +-CONFIG_ARCH_SUSPEND_POSSIBLE=y ++CONFIG_BINFMT_MISC=m + CONFIG_NET=y +- +-# +-# Networking options +-# + CONFIG_PACKET=y + CONFIG_UNIX=y +-CONFIG_XFRM=y + CONFIG_XFRM_USER=y +-# CONFIG_XFRM_SUB_POLICY is not set +-# CONFIG_XFRM_MIGRATE is not set +-# CONFIG_XFRM_STATISTICS is not set + CONFIG_NET_KEY=m +-# CONFIG_NET_KEY_MIGRATE is not set + CONFIG_INET=y + CONFIG_IP_MULTICAST=y +-# CONFIG_IP_ADVANCED_ROUTER is not set + CONFIG_IP_PNP=y + CONFIG_IP_PNP_DHCP=y +-# CONFIG_IP_PNP_BOOTP is not set + CONFIG_IP_PNP_RARP=y +-# CONFIG_NET_IPIP is not set +-# CONFIG_NET_IPGRE_DEMUX is not set +-# CONFIG_IP_MROUTE is not set +-# CONFIG_ARPD is not set + CONFIG_SYN_COOKIES=y +-# CONFIG_INET_AH is not set +-# CONFIG_INET_ESP is not set +-# CONFIG_INET_IPCOMP is not set +-# CONFIG_INET_XFRM_TUNNEL is not set +-# CONFIG_INET_TUNNEL is not set + # CONFIG_INET_XFRM_MODE_TRANSPORT is not set + # CONFIG_INET_XFRM_MODE_TUNNEL is not set + # CONFIG_INET_XFRM_MODE_BEET is not set + # CONFIG_INET_LRO is not set + # CONFIG_INET_DIAG is not set +-# CONFIG_TCP_CONG_ADVANCED is not set +-CONFIG_TCP_CONG_CUBIC=y +-CONFIG_DEFAULT_TCP_CONG="cubic" +-# CONFIG_TCP_MD5SIG is not set + # CONFIG_IPV6 is not set +-# CONFIG_NETWORK_SECMARK is not set +-# CONFIG_NETWORK_PHY_TIMESTAMPING is not set +-# CONFIG_NETFILTER is not set +-# CONFIG_IP_DCCP is not set +-# CONFIG_IP_SCTP is not set +-# CONFIG_RDS is not set +-# CONFIG_TIPC is not set +-# CONFIG_ATM is not set +-# CONFIG_L2TP is not set +-# CONFIG_BRIDGE is not set +-# CONFIG_NET_DSA is not set +-# CONFIG_VLAN_8021Q is not set +-# CONFIG_DECNET is not set +-# CONFIG_LLC2 is not set +-# CONFIG_IPX is not set +-# CONFIG_ATALK is not set +-# CONFIG_X25 is not set +-# CONFIG_LAPB is not set +-# CONFIG_ECONET is not set +-# CONFIG_WAN_ROUTER is not set +-# CONFIG_PHONET is not set +-# CONFIG_IEEE802154 is not set +-# CONFIG_NET_SCHED is not set +-# CONFIG_DCB is not set +-CONFIG_DNS_RESOLVER=y +-# CONFIG_BATMAN_ADV is not set +- +-# +-# Network testing +-# + CONFIG_NET_PKTGEN=m +-# CONFIG_HAMRADIO is not set +-# CONFIG_CAN is not set +-# CONFIG_IRDA is not set +-# CONFIG_BT is not set +-# CONFIG_AF_RXRPC is not set +-CONFIG_WIRELESS=y +-CONFIG_WEXT_CORE=y +-CONFIG_WEXT_PROC=y +-CONFIG_CFG80211=y +-# CONFIG_NL80211_TESTMODE is not set +-# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set +-# CONFIG_CFG80211_REG_DEBUG is not set +-CONFIG_CFG80211_DEFAULT_PS=y +-# CONFIG_CFG80211_INTERNAL_REGDB is not set +-CONFIG_CFG80211_WEXT=y +-CONFIG_WIRELESS_EXT_SYSFS=y +-# CONFIG_LIB80211 is not set +-# CONFIG_MAC80211 is not set +-# CONFIG_WIMAX is not set +-# CONFIG_RFKILL is not set +-# CONFIG_NET_9P is not set +-# CONFIG_CAIF is not set +-# CONFIG_CEPH_LIB is not set +-# CONFIG_NFC is not set +- +-# +-# Device Drivers +-# +- +-# +-# Generic Driver Options +-# +-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +-# CONFIG_DEVTMPFS is not set +-CONFIG_STANDALONE=y +-CONFIG_PREVENT_FIRMWARE_BUILD=y +-CONFIG_FW_LOADER=y +-CONFIG_FIRMWARE_IN_KERNEL=y +-CONFIG_EXTRA_FIRMWARE="" +-# CONFIG_DEBUG_DRIVER is not set +-# CONFIG_DEBUG_DEVRES is not set +-# CONFIG_SYS_HYPERVISOR is not set +-# CONFIG_CONNECTOR is not set +-# CONFIG_MTD is not set +-# CONFIG_PARPORT is not set +-CONFIG_BLK_DEV=y +-# CONFIG_BLK_DEV_COW_COMMON is not set ++CONFIG_IRDA=m ++CONFIG_IRLAN=m ++CONFIG_IRCOMM=m ++CONFIG_IRDA_ULTRA=y ++CONFIG_IRDA_CACHE_LAST_LSAP=y ++CONFIG_IRDA_FAST_RR=y ++CONFIG_IRTTY_SIR=m ++CONFIG_KINGSUN_DONGLE=m ++CONFIG_KSDAZZLE_DONGLE=m ++CONFIG_KS959_DONGLE=m ++CONFIG_USB_IRDA=m ++CONFIG_SIGMATEL_FIR=m ++CONFIG_MCS_FIR=m ++CONFIG_BT=m ++CONFIG_BT_L2CAP=y ++CONFIG_BT_SCO=y ++CONFIG_BT_RFCOMM=m ++CONFIG_BT_RFCOMM_TTY=y ++CONFIG_BT_BNEP=m ++CONFIG_BT_BNEP_MC_FILTER=y ++CONFIG_BT_BNEP_PROTO_FILTER=y ++CONFIG_BT_HIDP=m ++CONFIG_BT_HCIBTUSB=m ++CONFIG_BT_HCIBCM203X=m ++CONFIG_BT_HCIBPA10X=m ++CONFIG_BT_HCIBFUSB=m ++CONFIG_BT_HCIVHCI=m ++CONFIG_BT_MRVL=m ++CONFIG_BT_MRVL_SDIO=m ++CONFIG_BT_ATH3K=m ++CONFIG_CFG80211=m ++CONFIG_MAC80211=m ++CONFIG_MAC80211_RC_PID=y ++CONFIG_MAC80211_MESH=y ++CONFIG_WIMAX=m ++CONFIG_NET_9P=m ++CONFIG_NFC=m ++CONFIG_NFC_PN533=m ++CONFIG_DEVTMPFS=y + CONFIG_BLK_DEV_LOOP=y +-CONFIG_BLK_DEV_LOOP_MIN_COUNT=8 +-# CONFIG_BLK_DEV_CRYPTOLOOP is not set +- +-# +-# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +-# +-# CONFIG_BLK_DEV_NBD is not set +-# CONFIG_BLK_DEV_UB is not set ++CONFIG_BLK_DEV_CRYPTOLOOP=m ++CONFIG_BLK_DEV_NBD=m + CONFIG_BLK_DEV_RAM=y +-CONFIG_BLK_DEV_RAM_COUNT=16 +-CONFIG_BLK_DEV_RAM_SIZE=4096 +-# CONFIG_BLK_DEV_XIP is not set +-# CONFIG_CDROM_PKTCDVD is not set +-# CONFIG_ATA_OVER_ETH is not set +-# CONFIG_MG_DISK is not set +-# CONFIG_BLK_DEV_RBD is not set +-# CONFIG_SENSORS_LIS3LV02D is not set ++CONFIG_CDROM_PKTCDVD=m + CONFIG_MISC_DEVICES=y +-# CONFIG_ENCLOSURE_SERVICES is not set +-# CONFIG_C2PORT is not set +- +-# +-# EEPROM support +-# +-# CONFIG_EEPROM_93CX6 is not set +-# CONFIG_IWMC3200TOP is not set +- +-# +-# Texas Instruments shared transport line discipline +-# +-# CONFIG_TI_ST is not set +-CONFIG_BCM2708_VCHIQ=y +-CONFIG_HAVE_IDE=y +-# CONFIG_IDE is not set +- +-# +-# SCSI device support +-# +-CONFIG_SCSI_MOD=y +-# CONFIG_RAID_ATTRS is not set + CONFIG_SCSI=y +-CONFIG_SCSI_DMA=y +-# CONFIG_SCSI_TGT is not set +-# CONFIG_SCSI_NETLINK is not set + # CONFIG_SCSI_PROC_FS is not set +- +-# +-# SCSI support type (disk, tape, CD-ROM) +-# +-CONFIG_BLK_DEV_SD=m +-# CONFIG_CHR_DEV_ST is not set +-# CONFIG_CHR_DEV_OSST is not set ++CONFIG_BLK_DEV_SD=y + CONFIG_BLK_DEV_SR=m +-# CONFIG_BLK_DEV_SR_VENDOR is not set +-# CONFIG_CHR_DEV_SG is not set +-# CONFIG_CHR_DEV_SCH is not set + CONFIG_SCSI_MULTI_LUN=y +-# CONFIG_SCSI_CONSTANTS is not set +-# CONFIG_SCSI_LOGGING is not set +-# CONFIG_SCSI_SCAN_ASYNC is not set +-CONFIG_SCSI_WAIT_SCAN=m +- +-# +-# SCSI Transports +-# +-# CONFIG_SCSI_SPI_ATTRS is not set +-# CONFIG_SCSI_FC_ATTRS is not set +-# CONFIG_SCSI_ISCSI_ATTRS is not set +-# CONFIG_SCSI_SAS_ATTRS is not set +-# CONFIG_SCSI_SAS_LIBSAS is not set +-# CONFIG_SCSI_SRP_ATTRS is not set + # CONFIG_SCSI_LOWLEVEL is not set +-# CONFIG_SCSI_DH is not set +-# CONFIG_SCSI_OSD_INITIATOR is not set +-# CONFIG_ATA is not set +-# CONFIG_MD is not set +-# CONFIG_TARGET_CORE is not set + CONFIG_NETDEVICES=y +-# CONFIG_DUMMY is not set +-# CONFIG_BONDING is not set +-# CONFIG_MACVLAN is not set +-# CONFIG_EQUALIZER is not set + CONFIG_TUN=m +-# CONFIG_VETH is not set +-CONFIG_MII=y + CONFIG_PHYLIB=m +- +-# +-# MII PHY device drivers +-# +-# CONFIG_MARVELL_PHY is not set +-# CONFIG_DAVICOM_PHY is not set +-# CONFIG_QSEMI_PHY is not set +-# CONFIG_LXT_PHY is not set +-# CONFIG_CICADA_PHY is not set +-# CONFIG_VITESSE_PHY is not set +-# CONFIG_SMSC_PHY is not set +-# CONFIG_BROADCOM_PHY is not set +-# CONFIG_ICPLUS_PHY is not set +-# CONFIG_REALTEK_PHY is not set +-# CONFIG_NATIONAL_PHY is not set +-# CONFIG_STE10XP is not set +-# CONFIG_LSI_ET1011C_PHY is not set +-# CONFIG_MICREL_PHY is not set + CONFIG_MDIO_BITBANG=m +-# CONFIG_MDIO_GPIO is not set + CONFIG_NET_ETHERNET=y +-CONFIG_AX88796=m +-# CONFIG_AX88796_93CX6 is not set +-# CONFIG_SMC91X is not set +-# CONFIG_DM9000 is not set +-# CONFIG_ETHOC is not set +-# CONFIG_SMC911X is not set +-# CONFIG_SMSC911X is not set +-# CONFIG_DNET is not set +-# CONFIG_IBM_NEW_EMAC_ZMII is not set +-# CONFIG_IBM_NEW_EMAC_RGMII is not set +-# CONFIG_IBM_NEW_EMAC_TAH is not set +-# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +-# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +-# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +-# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +-# CONFIG_B44 is not set +-# CONFIG_KS8851_MLL is not set +-# CONFIG_FTMAC100 is not set + # CONFIG_NETDEV_1000 is not set + # CONFIG_NETDEV_10000 is not set +-# CONFIG_WLAN is not set +- +-# +-# Enable WiMAX (Networking options) to see the WiMAX drivers +-# +- +-# +-# USB Network Adapters +-# +-# CONFIG_USB_CATC is not set +-# CONFIG_USB_KAWETH is not set +-# CONFIG_USB_PEGASUS is not set +-# CONFIG_USB_RTL8150 is not set ++CONFIG_LIBERTAS_THINFIRM=m ++CONFIG_LIBERTAS_THINFIRM_USB=m ++CONFIG_AT76C50X_USB=m ++CONFIG_USB_ZD1201=m ++CONFIG_USB_NET_RNDIS_WLAN=m ++CONFIG_RTL8187=m ++CONFIG_MAC80211_HWSIM=m ++CONFIG_ATH_COMMON=m ++CONFIG_ATH9K=m ++CONFIG_ATH9K_HTC=m ++CONFIG_CARL9170=m ++CONFIG_B43=m ++CONFIG_B43LEGACY=m ++CONFIG_HOSTAP=m ++CONFIG_IWM=m ++CONFIG_LIBERTAS=m ++CONFIG_LIBERTAS_USB=m ++CONFIG_LIBERTAS_SDIO=m ++CONFIG_P54_COMMON=m ++CONFIG_P54_USB=m ++CONFIG_RT2X00=m ++CONFIG_RT2500USB=m ++CONFIG_RT73USB=m ++CONFIG_RT2800USB=m ++CONFIG_RT2800USB_RT53XX=y ++CONFIG_RTL8192CU=m ++CONFIG_WL1251=m ++CONFIG_WL12XX_MENU=m ++CONFIG_ZD1211RW=m ++CONFIG_MWIFIEX=m ++CONFIG_MWIFIEX_SDIO=m ++CONFIG_WIMAX_I2400M_USB=m ++CONFIG_USB_CATC=m ++CONFIG_USB_KAWETH=m ++CONFIG_USB_PEGASUS=m ++CONFIG_USB_RTL8150=m + CONFIG_USB_USBNET=y + CONFIG_USB_NET_AX8817X=m +-# CONFIG_USB_NET_CDCETHER is not set +-# CONFIG_USB_NET_CDC_EEM is not set +-CONFIG_USB_NET_CDC_NCM=y +-# CONFIG_USB_NET_DM9601 is not set +-# CONFIG_USB_NET_SMSC75XX is not set ++CONFIG_USB_NET_CDCETHER=m ++CONFIG_USB_NET_CDC_EEM=m ++CONFIG_USB_NET_DM9601=m ++CONFIG_USB_NET_SMSC75XX=m + CONFIG_USB_NET_SMSC95XX=y +-# CONFIG_USB_NET_GL620A is not set +-# CONFIG_USB_NET_NET1080 is not set +-# CONFIG_USB_NET_PLUSB is not set +-# CONFIG_USB_NET_MCS7830 is not set +-# CONFIG_USB_NET_RNDIS_HOST is not set +-# CONFIG_USB_NET_CDC_SUBSET is not set ++CONFIG_USB_NET_GL620A=m ++CONFIG_USB_NET_NET1080=m ++CONFIG_USB_NET_PLUSB=m ++CONFIG_USB_NET_MCS7830=m ++CONFIG_USB_NET_CDC_SUBSET=m ++CONFIG_USB_ALI_M5632=y ++CONFIG_USB_AN2720=y ++CONFIG_USB_KC2190=y + # CONFIG_USB_NET_ZAURUS is not set +-# CONFIG_USB_NET_CX82310_ETH is not set +-# CONFIG_USB_NET_KALMIA is not set +-# CONFIG_USB_NET_INT51X1 is not set +-# CONFIG_USB_IPHETH is not set +-# CONFIG_USB_SIERRA_NET is not set +-# CONFIG_WAN is not set +- +-# +-# CAIF transport drivers +-# +-# CONFIG_PPP is not set +-# CONFIG_SLIP is not set +-# CONFIG_NETCONSOLE is not set +-# CONFIG_NETPOLL is not set +-# CONFIG_NET_POLL_CONTROLLER is not set +-# CONFIG_ISDN is not set +-# CONFIG_PHONE is not set +- +-# +-# Input device support +-# +-CONFIG_INPUT=y +-# CONFIG_INPUT_FF_MEMLESS is not set +-# CONFIG_INPUT_POLLDEV is not set +-# CONFIG_INPUT_SPARSEKMAP is not set +- +-# +-# Userland interfaces +-# +-CONFIG_INPUT_MOUSEDEV=y ++CONFIG_USB_NET_CX82310_ETH=m ++CONFIG_USB_NET_KALMIA=m ++CONFIG_USB_NET_INT51X1=m ++CONFIG_USB_IPHETH=m ++CONFIG_USB_SIERRA_NET=m ++CONFIG_USB_VL600=m ++CONFIG_PPP=m ++CONFIG_PPP_ASYNC=m ++CONFIG_PPP_SYNC_TTY=m ++CONFIG_PPP_DEFLATE=m ++CONFIG_PPP_BSDCOMP=m ++CONFIG_SLIP=m ++CONFIG_SLIP_COMPRESSED=y ++CONFIG_NETCONSOLE=m ++CONFIG_INPUT_POLLDEV=m + # CONFIG_INPUT_MOUSEDEV_PSAUX is not set +-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +-# CONFIG_INPUT_JOYDEV is not set ++CONFIG_INPUT_JOYDEV=m + CONFIG_INPUT_EVDEV=m +-# CONFIG_INPUT_EVBUG is not set +- +-# +-# Input Device Drivers +-# + # CONFIG_INPUT_KEYBOARD is not set + # CONFIG_INPUT_MOUSE is not set +-# CONFIG_INPUT_JOYSTICK is not set +-# CONFIG_INPUT_TABLET is not set +-# CONFIG_INPUT_TOUCHSCREEN is not set + CONFIG_INPUT_MISC=y +-# CONFIG_INPUT_AD714X is not set +-# CONFIG_INPUT_ATI_REMOTE is not set +-# CONFIG_INPUT_ATI_REMOTE2 is not set +-# CONFIG_INPUT_KEYSPAN_REMOTE is not set +-# CONFIG_INPUT_POWERMATE is not set +-# CONFIG_INPUT_YEALINK is not set +-# CONFIG_INPUT_CM109 is not set ++CONFIG_INPUT_AD714X=m ++CONFIG_INPUT_ATI_REMOTE=m ++CONFIG_INPUT_ATI_REMOTE2=m ++CONFIG_INPUT_KEYSPAN_REMOTE=m ++CONFIG_INPUT_POWERMATE=m ++CONFIG_INPUT_YEALINK=m ++CONFIG_INPUT_CM109=m + CONFIG_INPUT_UINPUT=m +-# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set +-# CONFIG_INPUT_ADXL34X is not set +-# CONFIG_INPUT_CMA3000 is not set +- +-# +-# Hardware I/O ports +-# ++CONFIG_INPUT_GPIO_ROTARY_ENCODER=m ++CONFIG_INPUT_ADXL34X=m ++CONFIG_INPUT_CMA3000=m + CONFIG_SERIO=m +-CONFIG_SERIO_SERPORT=m +-# CONFIG_SERIO_AMBAKMI is not set +-# CONFIG_SERIO_LIBPS2 is not set + CONFIG_SERIO_RAW=m +-# CONFIG_SERIO_ALTERA_PS2 is not set +-# CONFIG_SERIO_PS2MULT is not set + CONFIG_GAMEPORT=m + CONFIG_GAMEPORT_NS558=m + CONFIG_GAMEPORT_L4=m +- +-# +-# Character devices +-# +-CONFIG_VT=y +-CONFIG_CONSOLE_TRANSLATIONS=y +-CONFIG_VT_CONSOLE=y +-CONFIG_HW_CONSOLE=y + CONFIG_VT_HW_CONSOLE_BINDING=y +-CONFIG_UNIX98_PTYS=y +-# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set + # CONFIG_LEGACY_PTYS is not set +-# CONFIG_SERIAL_NONSTANDARD is not set +-# CONFIG_N_GSM is not set +-# CONFIG_TRACE_SINK is not set + # CONFIG_DEVKMEM is not set +- +-# +-# Serial drivers +-# +-# CONFIG_SERIAL_8250 is not set +- +-# +-# Non-8250 serial port support +-# +-# CONFIG_SERIAL_AMBA_PL010 is not set + CONFIG_SERIAL_AMBA_PL011=y + CONFIG_SERIAL_AMBA_PL011_CONSOLE=y +-CONFIG_SERIAL_CORE=y +-CONFIG_SERIAL_CORE_CONSOLE=y +-# CONFIG_SERIAL_TIMBERDALE is not set +-# CONFIG_SERIAL_ALTERA_JTAGUART is not set +-# CONFIG_SERIAL_ALTERA_UART is not set +-# CONFIG_SERIAL_XILINX_PS_UART is not set +-# CONFIG_TTY_PRINTK is not set +-# CONFIG_HVC_DCC is not set +-# CONFIG_IPMI_HANDLER is not set + # CONFIG_HW_RANDOM is not set +-# CONFIG_R3964 is not set + CONFIG_RAW_DRIVER=y +-CONFIG_MAX_RAW_DEVS=256 +-# CONFIG_TCG_TPM is not set +-# CONFIG_RAMOOPS is not set +-# CONFIG_I2C is not set +-# CONFIG_SPI is not set +- +-# +-# PPS support +-# +-# CONFIG_PPS is not set +- +-# +-# PPS generators support +-# +- +-# +-# PTP clock support +-# +- +-# +-# Enable Device Drivers -> PPS to see the PTP clock options. +-# +-CONFIG_ARCH_REQUIRE_GPIOLIB=y +-CONFIG_GPIOLIB=y +-# CONFIG_DEBUG_GPIO is not set + CONFIG_GPIO_SYSFS=y +- +-# +-# Memory mapped GPIO drivers: +-# +-# CONFIG_GPIO_GENERIC_PLATFORM is not set +-# CONFIG_GPIO_IT8761E is not set +-# CONFIG_GPIO_PL061 is not set +- +-# +-# I2C GPIO expanders: +-# +- +-# +-# PCI GPIO expanders: +-# +- +-# +-# SPI GPIO expanders: +-# +- +-# +-# AC97 GPIO expanders: +-# +- +-# +-# MODULbus GPIO expanders: +-# +-# CONFIG_W1 is not set +-# CONFIG_POWER_SUPPLY is not set + # CONFIG_HWMON is not set +-# CONFIG_THERMAL is not set +-# CONFIG_WATCHDOG is not set +-CONFIG_SSB_POSSIBLE=y +- +-# +-# Sonics Silicon Backplane +-# +-# CONFIG_SSB is not set +-CONFIG_BCMA_POSSIBLE=y +- +-# +-# Broadcom specific AMBA +-# +-# CONFIG_BCMA is not set ++CONFIG_WATCHDOG=y ++CONFIG_BCM2708_WDT=m + # CONFIG_MFD_SUPPORT is not set +-# CONFIG_REGULATOR is not set +-# CONFIG_MEDIA_SUPPORT is not set +- +-# +-# Graphics support +-# +-# CONFIG_DRM is not set +-# CONFIG_VGASTATE is not set +-# CONFIG_VIDEO_OUTPUT_CONTROL is not set + CONFIG_FB=y +-# CONFIG_FIRMWARE_EDID is not set +-# CONFIG_FB_DDC is not set +-# CONFIG_FB_BOOT_VESA_SUPPORT is not set +-CONFIG_FB_CFB_FILLRECT=y +-CONFIG_FB_CFB_COPYAREA=y +-CONFIG_FB_CFB_IMAGEBLIT=y +-# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +-# CONFIG_FB_SYS_FILLRECT is not set +-# CONFIG_FB_SYS_COPYAREA is not set +-# CONFIG_FB_SYS_IMAGEBLIT is not set +-# CONFIG_FB_FOREIGN_ENDIAN is not set +-# CONFIG_FB_SYS_FOPS is not set +-# CONFIG_FB_WMT_GE_ROPS is not set +-# CONFIG_FB_SVGALIB is not set +-# CONFIG_FB_MACMODES is not set +-# CONFIG_FB_BACKLIGHT is not set +-# CONFIG_FB_MODE_HELPERS is not set +-# CONFIG_FB_TILEBLITTING is not set +- +-# +-# Frame buffer hardware drivers +-# + CONFIG_FB_BCM2708=y +-# CONFIG_FB_ARMCLCD is not set +-# CONFIG_FB_S1D13XXX is not set +-# CONFIG_FB_UDL is not set +-# CONFIG_FB_VIRTUAL is not set +-# CONFIG_FB_METRONOME is not set +-# CONFIG_FB_BROADSHEET is not set +-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set +- +-# +-# Display device support +-# +-# CONFIG_DISPLAY_SUPPORT is not set +- +-# +-# Console display driver support +-# +-CONFIG_DUMMY_CONSOLE=y + CONFIG_FRAMEBUFFER_CONSOLE=y +-# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +-# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +-# CONFIG_FONTS is not set +-CONFIG_FONT_8x8=y +-CONFIG_FONT_8x16=y + CONFIG_LOGO=y + # CONFIG_LOGO_LINUX_MONO is not set + # CONFIG_LOGO_LINUX_VGA16 is not set +-CONFIG_LOGO_LINUX_CLUT224=y +-# CONFIG_SOUND is not set +-CONFIG_HID_SUPPORT=y +-CONFIG_HID=y +-# CONFIG_HIDRAW is not set +- +-# +-# USB Input Devices +-# +-CONFIG_USB_HID=y ++CONFIG_SOUND=y ++CONFIG_SND=m ++CONFIG_SND_SEQUENCER=m ++CONFIG_SND_SEQ_DUMMY=m ++CONFIG_SND_MIXER_OSS=m ++CONFIG_SND_PCM_OSS=m ++CONFIG_SND_SEQUENCER_OSS=y ++CONFIG_SND_HRTIMER=m ++CONFIG_SND_DUMMY=m ++CONFIG_SND_ALOOP=m ++CONFIG_SND_VIRMIDI=m ++CONFIG_SND_MTPAV=m ++CONFIG_SND_SERIAL_U16550=m ++CONFIG_SND_MPU401=m ++CONFIG_SND_BCM2835=m ++CONFIG_SND_USB_AUDIO=m ++CONFIG_SND_USB_UA101=m ++CONFIG_SND_USB_CAIAQ=m ++CONFIG_SND_USB_6FIRE=m ++CONFIG_SOUND_PRIME=m + CONFIG_HID_PID=y + CONFIG_USB_HIDDEV=y +- +-# +-# Special HID drivers +-# + CONFIG_HID_A4TECH=m +-# CONFIG_HID_ACRUX is not set ++CONFIG_HID_ACRUX=m + CONFIG_HID_APPLE=m + CONFIG_HID_BELKIN=m + CONFIG_HID_CHERRY=m + CONFIG_HID_CHICONY=m + CONFIG_HID_CYPRESS=m + CONFIG_HID_DRAGONRISE=m +-# CONFIG_DRAGONRISE_FF is not set +-# CONFIG_HID_EMS_FF is not set ++CONFIG_HID_EMS_FF=m ++CONFIG_HID_ELECOM=m + CONFIG_HID_EZKEY=m +-# CONFIG_HID_HOLTEK is not set +-# CONFIG_HID_KEYTOUCH is not set ++CONFIG_HID_HOLTEK=m ++CONFIG_HID_KEYTOUCH=m + CONFIG_HID_KYE=m +-# CONFIG_HID_UCLOGIC is not set +-# CONFIG_HID_WALTOP is not set ++CONFIG_HID_UCLOGIC=m ++CONFIG_HID_WALTOP=m + CONFIG_HID_GYRATION=m + CONFIG_HID_TWINHAN=m + CONFIG_HID_KENSINGTON=m +-# CONFIG_HID_LCPOWER is not set ++CONFIG_HID_LCPOWER=m + CONFIG_HID_LOGITECH=m +-# CONFIG_LOGITECH_FF is not set +-# CONFIG_LOGIRUMBLEPAD2_FF is not set +-# CONFIG_LOGIG940_FF is not set +-# CONFIG_LOGIWII_FF is not set ++CONFIG_HID_MAGICMOUSE=m + CONFIG_HID_MICROSOFT=m + CONFIG_HID_MONTEREY=m +-# CONFIG_HID_MULTITOUCH is not set +-# CONFIG_HID_NTRIG is not set ++CONFIG_HID_MULTITOUCH=m ++CONFIG_HID_NTRIG=m + CONFIG_HID_ORTEK=m + CONFIG_HID_PANTHERLORD=m +-# CONFIG_PANTHERLORD_FF is not set + CONFIG_HID_PETALYNX=m +-# CONFIG_HID_PICOLCD is not set +-# CONFIG_HID_QUANTA is not set +-# CONFIG_HID_ROCCAT is not set ++CONFIG_HID_PICOLCD=m ++CONFIG_HID_QUANTA=m ++CONFIG_HID_ROCCAT=m + CONFIG_HID_SAMSUNG=m + CONFIG_HID_SONY=m +-# CONFIG_HID_SPEEDLINK is not set ++CONFIG_HID_SPEEDLINK=m + CONFIG_HID_SUNPLUS=m + CONFIG_HID_GREENASIA=m +-# CONFIG_GREENASIA_FF is not set + CONFIG_HID_SMARTJOYPLUS=m +-# CONFIG_SMARTJOYPLUS_FF is not set + CONFIG_HID_TOPSEED=m + CONFIG_HID_THRUSTMASTER=m +-# CONFIG_THRUSTMASTER_FF is not set ++CONFIG_HID_WACOM=m ++CONFIG_HID_WIIMOTE=m + CONFIG_HID_ZEROPLUS=m +-# CONFIG_ZEROPLUS_FF is not set +-# CONFIG_HID_ZYDACRON is not set +-CONFIG_USB_SUPPORT=y +-CONFIG_USB_ARCH_HAS_HCD=y +-# CONFIG_USB_ARCH_HAS_OHCI is not set +-# CONFIG_USB_ARCH_HAS_EHCI is not set ++CONFIG_HID_ZYDACRON=m + CONFIG_USB=y +-# CONFIG_USB_DEBUG is not set + CONFIG_USB_ANNOUNCE_NEW_DEVICES=y +- +-# +-# Miscellaneous USB options +-# +-# CONFIG_USB_DEVICEFS is not set +-CONFIG_USB_DEVICE_CLASS=y +-# CONFIG_USB_DYNAMIC_MINORS is not set +-# CONFIG_USB_OTG_WHITELIST is not set +-# CONFIG_USB_OTG_BLACKLIST_HUB is not set + CONFIG_USB_MON=m +-# CONFIG_USB_WUSB is not set +-# CONFIG_USB_WUSB_CBAF is not set +- +-# +-# USB Host Controller Drivers +-# +-# CONFIG_USB_C67X00_HCD is not set +-# CONFIG_USB_OXU210HP_HCD is not set +-# CONFIG_USB_ISP116X_HCD is not set +-# CONFIG_USB_ISP1760_HCD is not set +-# CONFIG_USB_ISP1362_HCD is not set +-# CONFIG_USB_SL811_HCD is not set +-# CONFIG_USB_R8A66597_HCD is not set +-# CONFIG_USB_HWA_HCD is not set + CONFIG_USB_DWCOTG=y +- +-# +-# USB Device Class drivers +-# +-# CONFIG_USB_ACM is not set +-# CONFIG_USB_PRINTER is not set +-# CONFIG_USB_WDM is not set +-# CONFIG_USB_TMC is not set +- +-# +-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +-# +- +-# +-# also be needed; see USB_STORAGE Help for more info +-# + CONFIG_USB_STORAGE=y +-# CONFIG_USB_STORAGE_DEBUG is not set +-# CONFIG_USB_STORAGE_REALTEK is not set +-# CONFIG_USB_STORAGE_DATAFAB is not set +-# CONFIG_USB_STORAGE_FREECOM is not set +-# CONFIG_USB_STORAGE_ISD200 is not set +-# CONFIG_USB_STORAGE_USBAT is not set +-# CONFIG_USB_STORAGE_SDDR09 is not set +-# CONFIG_USB_STORAGE_SDDR55 is not set +-# CONFIG_USB_STORAGE_JUMPSHOT is not set +-# CONFIG_USB_STORAGE_ALAUDA is not set +-# CONFIG_USB_STORAGE_ONETOUCH is not set +-# CONFIG_USB_STORAGE_KARMA is not set +-# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set +-# CONFIG_USB_STORAGE_ENE_UB6250 is not set +-# CONFIG_USB_UAS is not set ++CONFIG_USB_STORAGE_REALTEK=m ++CONFIG_USB_STORAGE_DATAFAB=m ++CONFIG_USB_STORAGE_FREECOM=m ++CONFIG_USB_STORAGE_ISD200=m ++CONFIG_USB_STORAGE_USBAT=m ++CONFIG_USB_STORAGE_SDDR09=m ++CONFIG_USB_STORAGE_SDDR55=m ++CONFIG_USB_STORAGE_JUMPSHOT=m ++CONFIG_USB_STORAGE_ALAUDA=m ++CONFIG_USB_STORAGE_ONETOUCH=m ++CONFIG_USB_STORAGE_KARMA=m ++CONFIG_USB_STORAGE_CYPRESS_ATACB=m ++CONFIG_USB_STORAGE_ENE_UB6250=m ++CONFIG_USB_UAS=y + CONFIG_USB_LIBUSUAL=y +- +-# +-# USB Imaging devices +-# +-# CONFIG_USB_MDC800 is not set +-# CONFIG_USB_MICROTEK is not set +- +-# +-# USB port drivers +-# +-# CONFIG_USB_SERIAL is not set +- +-# +-# USB Miscellaneous drivers +-# +-# CONFIG_USB_EMI62 is not set +-# CONFIG_USB_EMI26 is not set +-# CONFIG_USB_ADUTUX is not set +-# CONFIG_USB_SEVSEG is not set +-# CONFIG_USB_RIO500 is not set +-# CONFIG_USB_LEGOTOWER is not set +-# CONFIG_USB_LCD is not set +-# CONFIG_USB_LED is not set +-# CONFIG_USB_CYPRESS_CY7C63 is not set +-# CONFIG_USB_CYTHERM is not set +-# CONFIG_USB_IDMOUSE is not set +-# CONFIG_USB_FTDI_ELAN is not set +-# CONFIG_USB_APPLEDISPLAY is not set +-# CONFIG_USB_LD is not set +-# CONFIG_USB_TRANCEVIBRATOR is not set +-# CONFIG_USB_IOWARRIOR is not set +-# CONFIG_USB_TEST is not set +-# CONFIG_USB_ISIGHTFW is not set +-# CONFIG_USB_YUREX is not set +-# CONFIG_USB_GADGET is not set +- +-# +-# OTG and related infrastructure +-# +-# CONFIG_USB_GPIO_VBUS is not set +-# CONFIG_USB_ULPI is not set +-# CONFIG_NOP_USB_XCEIV is not set ++CONFIG_USB_MDC800=m ++CONFIG_USB_MICROTEK=m ++CONFIG_USB_SERIAL=m ++CONFIG_USB_SERIAL_GENERIC=y ++CONFIG_USB_SERIAL_AIRCABLE=m ++CONFIG_USB_SERIAL_ARK3116=m ++CONFIG_USB_SERIAL_BELKIN=m ++CONFIG_USB_SERIAL_CH341=m ++CONFIG_USB_SERIAL_WHITEHEAT=m ++CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m ++CONFIG_USB_SERIAL_CP210X=m ++CONFIG_USB_SERIAL_CYPRESS_M8=m ++CONFIG_USB_SERIAL_EMPEG=m ++CONFIG_USB_SERIAL_FTDI_SIO=m ++CONFIG_USB_SERIAL_FUNSOFT=m ++CONFIG_USB_SERIAL_VISOR=m ++CONFIG_USB_SERIAL_IPAQ=m ++CONFIG_USB_SERIAL_IR=m ++CONFIG_USB_SERIAL_EDGEPORT=m ++CONFIG_USB_SERIAL_EDGEPORT_TI=m ++CONFIG_USB_SERIAL_GARMIN=m ++CONFIG_USB_SERIAL_IPW=m ++CONFIG_USB_SERIAL_IUU=m ++CONFIG_USB_SERIAL_KEYSPAN_PDA=m ++CONFIG_USB_SERIAL_KEYSPAN=m ++CONFIG_USB_SERIAL_KLSI=m ++CONFIG_USB_SERIAL_KOBIL_SCT=m ++CONFIG_USB_SERIAL_MCT_U232=m ++CONFIG_USB_SERIAL_MOS7720=m ++CONFIG_USB_SERIAL_MOS7840=m ++CONFIG_USB_SERIAL_MOTOROLA=m ++CONFIG_USB_SERIAL_NAVMAN=m ++CONFIG_USB_SERIAL_PL2303=m ++CONFIG_USB_SERIAL_OTI6858=m ++CONFIG_USB_SERIAL_QCAUX=m ++CONFIG_USB_SERIAL_QUALCOMM=m ++CONFIG_USB_SERIAL_SPCP8X5=m ++CONFIG_USB_SERIAL_HP4X=m ++CONFIG_USB_SERIAL_SAFE=m ++CONFIG_USB_SERIAL_SIEMENS_MPI=m ++CONFIG_USB_SERIAL_SIERRAWIRELESS=m ++CONFIG_USB_SERIAL_SYMBOL=m ++CONFIG_USB_SERIAL_TI=m ++CONFIG_USB_SERIAL_CYBERJACK=m ++CONFIG_USB_SERIAL_XIRCOM=m ++CONFIG_USB_SERIAL_OPTION=m ++CONFIG_USB_SERIAL_OMNINET=m ++CONFIG_USB_SERIAL_OPTICON=m ++CONFIG_USB_SERIAL_VIVOPAY_SERIAL=m ++CONFIG_USB_SERIAL_ZIO=m ++CONFIG_USB_SERIAL_SSU100=m ++CONFIG_USB_SERIAL_DEBUG=m ++CONFIG_USB_EMI62=m ++CONFIG_USB_EMI26=m ++CONFIG_USB_ADUTUX=m ++CONFIG_USB_SEVSEG=m ++CONFIG_USB_RIO500=m ++CONFIG_USB_LEGOTOWER=m ++CONFIG_USB_LCD=m ++CONFIG_USB_LED=m ++CONFIG_USB_CYPRESS_CY7C63=m ++CONFIG_USB_CYTHERM=m ++CONFIG_USB_IDMOUSE=m ++CONFIG_USB_FTDI_ELAN=m ++CONFIG_USB_APPLEDISPLAY=m ++CONFIG_USB_LD=m ++CONFIG_USB_TRANCEVIBRATOR=m ++CONFIG_USB_IOWARRIOR=m ++CONFIG_USB_TEST=m ++CONFIG_USB_ISIGHTFW=m ++CONFIG_USB_YUREX=m + CONFIG_MMC=y +-# CONFIG_MMC_DEBUG is not set +-# CONFIG_MMC_UNSAFE_RESUME is not set +-# CONFIG_MMC_CLKGATE is not set +- +-# +-# MMC/SD/SDIO Card Drivers +-# +-CONFIG_MMC_BLOCK=y +-CONFIG_MMC_BLOCK_MINORS=8 +-CONFIG_MMC_BLOCK_BOUNCE=y +-# CONFIG_SDIO_UART is not set +-# CONFIG_MMC_TEST is not set +- +-# +-# MMC/SD/SDIO Host Controller Drivers +-# +-# CONFIG_MMC_ARMMMCI is not set + CONFIG_MMC_SDHCI=y +-CONFIG_MMC_SDHCI_IO_ACCESSORS=y + CONFIG_MMC_SDHCI_PLTFM=y +-# CONFIG_MMC_SDHCI_PXAV3 is not set +-# CONFIG_MMC_SDHCI_PXAV2 is not set + CONFIG_MMC_SDHCI_BCM2708=y + CONFIG_MMC_SDHCI_BCM2708_DMA=y +-# CONFIG_MMC_BCM2708 is not set +-# CONFIG_MMC_DW is not set +-# CONFIG_MMC_VUB300 is not set +-# CONFIG_MMC_USHC is not set +-# CONFIG_MEMSTICK is not set +-CONFIG_NEW_LEDS=y +-CONFIG_LEDS_CLASS=y +- +-# +-# LED drivers +-# + CONFIG_LEDS_GPIO=y +-# CONFIG_LEDS_LT3593 is not set +-CONFIG_LEDS_TRIGGERS=y +- +-# +-# LED Triggers +-# + CONFIG_LEDS_TRIGGER_TIMER=m + CONFIG_LEDS_TRIGGER_HEARTBEAT=m +-# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set +-# CONFIG_LEDS_TRIGGER_GPIO is not set + CONFIG_LEDS_TRIGGER_DEFAULT_ON=m +- +-# +-# iptables trigger is under Netfilter config (LED target) +-# +-# CONFIG_ACCESSIBILITY is not set +-CONFIG_RTC_LIB=y +-# CONFIG_RTC_CLASS is not set +-# CONFIG_DMADEVICES is not set +-# CONFIG_AUXDISPLAY is not set +-# CONFIG_UIO is not set +- +-# +-# Virtio drivers +-# +-# CONFIG_VIRTIO_BALLOON is not set +-# CONFIG_STAGING is not set +-CONFIG_CLKDEV_LOOKUP=y ++CONFIG_UIO=m ++CONFIG_UIO_PDRV=m ++CONFIG_UIO_PDRV_GENIRQ=m + # CONFIG_IOMMU_SUPPORT is not set +-# CONFIG_VIRT_DRIVERS is not set +- +-# +-# File systems +-# +-CONFIG_EXT2_FS=m +-CONFIG_EXT2_FS_XATTR=y +-CONFIG_EXT2_FS_POSIX_ACL=y +-CONFIG_EXT2_FS_SECURITY=y +-CONFIG_EXT2_FS_XIP=y +-CONFIG_EXT3_FS=y +-# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set +-CONFIG_EXT3_FS_XATTR=y +-CONFIG_EXT3_FS_POSIX_ACL=y +-CONFIG_EXT3_FS_SECURITY=y +-CONFIG_EXT4_FS=m +-CONFIG_EXT4_FS_XATTR=y ++CONFIG_EXT4_FS=y + CONFIG_EXT4_FS_POSIX_ACL=y + CONFIG_EXT4_FS_SECURITY=y +-# CONFIG_EXT4_DEBUG is not set +-CONFIG_FS_XIP=y +-CONFIG_JBD=y +-CONFIG_JBD2=m +-CONFIG_FS_MBCACHE=y +-# CONFIG_REISERFS_FS is not set +-# CONFIG_JFS_FS is not set +-# CONFIG_XFS_FS is not set +-# CONFIG_GFS2_FS is not set +-# CONFIG_OCFS2_FS is not set +-# CONFIG_BTRFS_FS is not set +-# CONFIG_NILFS2_FS is not set +-CONFIG_FS_POSIX_ACL=y +-CONFIG_FILE_LOCKING=y +-CONFIG_FSNOTIFY=y +-CONFIG_DNOTIFY=y +-CONFIG_INOTIFY_USER=y +-# CONFIG_FANOTIFY is not set +-# CONFIG_QUOTA is not set +-# CONFIG_QUOTACTL is not set ++CONFIG_REISERFS_FS=m ++CONFIG_REISERFS_FS_XATTR=y ++CONFIG_REISERFS_FS_POSIX_ACL=y ++CONFIG_REISERFS_FS_SECURITY=y ++CONFIG_JFS_FS=m ++CONFIG_JFS_POSIX_ACL=y ++CONFIG_JFS_SECURITY=y ++CONFIG_XFS_FS=m ++CONFIG_XFS_QUOTA=y ++CONFIG_XFS_POSIX_ACL=y ++CONFIG_XFS_RT=y ++CONFIG_GFS2_FS=m ++CONFIG_OCFS2_FS=m ++CONFIG_BTRFS_FS=m ++CONFIG_BTRFS_FS_POSIX_ACL=y ++CONFIG_NILFS2_FS=m + CONFIG_AUTOFS4_FS=y + CONFIG_FUSE_FS=m + CONFIG_CUSE=m +- +-# +-# Caches +-# + CONFIG_FSCACHE=y +-# CONFIG_FSCACHE_STATS is not set +-# CONFIG_FSCACHE_HISTOGRAM is not set +-# CONFIG_FSCACHE_DEBUG is not set +-# CONFIG_FSCACHE_OBJECT_LIST is not set + CONFIG_CACHEFILES=y +-# CONFIG_CACHEFILES_DEBUG is not set +-# CONFIG_CACHEFILES_HISTOGRAM is not set +- +-# +-# CD-ROM/DVD Filesystems +-# + CONFIG_ISO9660_FS=m + CONFIG_JOLIET=y + CONFIG_ZISOFS=y + CONFIG_UDF_FS=m +-CONFIG_UDF_NLS=y +- +-# +-# DOS/FAT/NT Filesystems +-# +-CONFIG_FAT_FS=y + CONFIG_MSDOS_FS=y + CONFIG_VFAT_FS=y +-CONFIG_FAT_DEFAULT_CODEPAGE=437 + CONFIG_FAT_DEFAULT_IOCHARSET="ascii" + CONFIG_NTFS_FS=m +-# CONFIG_NTFS_DEBUG is not set +-# CONFIG_NTFS_RW is not set +- +-# +-# Pseudo filesystems +-# +-CONFIG_PROC_FS=y +-CONFIG_PROC_SYSCTL=y +-CONFIG_PROC_PAGE_MONITOR=y +-CONFIG_SYSFS=y + CONFIG_TMPFS=y +-# CONFIG_TMPFS_POSIX_ACL is not set +-# CONFIG_TMPFS_XATTR is not set +-# CONFIG_HUGETLB_PAGE is not set ++CONFIG_TMPFS_POSIX_ACL=y + CONFIG_CONFIGFS_FS=y +-CONFIG_MISC_FILESYSTEMS=y +-# CONFIG_ADFS_FS is not set +-# CONFIG_AFFS_FS is not set +-# CONFIG_ECRYPT_FS is not set +-# CONFIG_HFS_FS is not set +-# CONFIG_HFSPLUS_FS is not set +-# CONFIG_BEFS_FS is not set +-# CONFIG_BFS_FS is not set +-# CONFIG_EFS_FS is not set +-# CONFIG_LOGFS is not set +-# CONFIG_CRAMFS is not set +-# CONFIG_SQUASHFS is not set +-# CONFIG_VXFS_FS is not set +-# CONFIG_MINIX_FS is not set +-# CONFIG_OMFS_FS is not set +-# CONFIG_HPFS_FS is not set +-# CONFIG_QNX4FS_FS is not set +-# CONFIG_ROMFS_FS is not set +-# CONFIG_PSTORE is not set +-# CONFIG_SYSV_FS is not set +-# CONFIG_UFS_FS is not set +-CONFIG_NETWORK_FILESYSTEMS=y ++CONFIG_SQUASHFS=m ++CONFIG_SQUASHFS_XATTR=y ++CONFIG_SQUASHFS_LZO=y ++CONFIG_SQUASHFS_XZ=y + CONFIG_NFS_FS=y + CONFIG_NFS_V3=y + CONFIG_NFS_V3_ACL=y + CONFIG_NFS_V4=y +-# CONFIG_NFS_V4_1 is not set + CONFIG_ROOT_NFS=y + CONFIG_NFS_FSCACHE=y +-# CONFIG_NFS_USE_LEGACY_DNS is not set +-CONFIG_NFS_USE_KERNEL_DNS=y +-# CONFIG_NFS_USE_NEW_IDMAPPER is not set +-# CONFIG_NFSD is not set +-CONFIG_LOCKD=y +-CONFIG_LOCKD_V4=y +-CONFIG_NFS_ACL_SUPPORT=y +-CONFIG_NFS_COMMON=y +-CONFIG_SUNRPC=y +-CONFIG_SUNRPC_GSS=y +-# CONFIG_CEPH_FS is not set + CONFIG_CIFS=m +-# CONFIG_CIFS_STATS is not set + CONFIG_CIFS_WEAK_PW_HASH=y +-# CONFIG_CIFS_UPCALL is not set + CONFIG_CIFS_XATTR=y + CONFIG_CIFS_POSIX=y +-# CONFIG_CIFS_DEBUG2 is not set +-# CONFIG_CIFS_DFS_UPCALL is not set +-# CONFIG_CIFS_FSCACHE is not set +-# CONFIG_CIFS_ACL is not set +-# CONFIG_NCP_FS is not set +-# CONFIG_CODA_FS is not set +-# CONFIG_AFS_FS is not set +- +-# +-# Partition Types +-# ++CONFIG_9P_FS=m + CONFIG_PARTITION_ADVANCED=y +-# CONFIG_ACORN_PARTITION is not set +-# CONFIG_OSF_PARTITION is not set +-# CONFIG_AMIGA_PARTITION is not set +-# CONFIG_ATARI_PARTITION is not set + CONFIG_MAC_PARTITION=y +-CONFIG_MSDOS_PARTITION=y +-# CONFIG_BSD_DISKLABEL is not set +-# CONFIG_MINIX_SUBPARTITION is not set +-# CONFIG_SOLARIS_X86_PARTITION is not set +-# CONFIG_UNIXWARE_DISKLABEL is not set +-# CONFIG_LDM_PARTITION is not set +-# CONFIG_SGI_PARTITION is not set +-# CONFIG_ULTRIX_PARTITION is not set +-# CONFIG_SUN_PARTITION is not set +-# CONFIG_KARMA_PARTITION is not set + CONFIG_EFI_PARTITION=y +-# CONFIG_SYSV68_PARTITION is not set +-CONFIG_NLS=y + CONFIG_NLS_DEFAULT="utf8" + CONFIG_NLS_CODEPAGE_437=y + CONFIG_NLS_CODEPAGE_737=m +@@ -1341,218 +470,25 @@ CONFIG_NLS_ISO8859_15=m + CONFIG_NLS_KOI8_R=m + CONFIG_NLS_KOI8_U=m + CONFIG_NLS_UTF8=m +-# CONFIG_DLM is not set +- +-# +-# Kernel hacking +-# +-# CONFIG_PRINTK_TIME is not set +-CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4 +-CONFIG_ENABLE_WARN_DEPRECATED=y +-CONFIG_ENABLE_MUST_CHECK=y +-CONFIG_FRAME_WARN=1024 +-# CONFIG_MAGIC_SYSRQ is not set +-# CONFIG_STRIP_ASM_SYMS is not set +-# CONFIG_UNUSED_SYMBOLS is not set +-# CONFIG_DEBUG_FS is not set +-# CONFIG_HEADERS_CHECK is not set +-# CONFIG_DEBUG_SECTION_MISMATCH is not set +-CONFIG_DEBUG_KERNEL=y +-# CONFIG_DEBUG_SHIRQ is not set +-# CONFIG_LOCKUP_DETECTOR is not set +-# CONFIG_HARDLOCKUP_DETECTOR is not set +-# CONFIG_DETECT_HUNG_TASK is not set + # CONFIG_SCHED_DEBUG is not set +-# CONFIG_SCHEDSTATS is not set +-# CONFIG_TIMER_STATS is not set +-# CONFIG_DEBUG_OBJECTS is not set +-# CONFIG_DEBUG_SLAB is not set +-# CONFIG_DEBUG_KMEMLEAK is not set +-# CONFIG_DEBUG_RT_MUTEXES is not set +-# CONFIG_RT_MUTEX_TESTER is not set +-# CONFIG_DEBUG_SPINLOCK is not set +-# CONFIG_DEBUG_MUTEXES is not set +-# CONFIG_DEBUG_LOCK_ALLOC is not set +-# CONFIG_PROVE_LOCKING is not set +-# CONFIG_SPARSE_RCU_POINTER is not set +-# CONFIG_LOCK_STAT is not set +-# CONFIG_DEBUG_ATOMIC_SLEEP is not set +-# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +-# CONFIG_DEBUG_STACK_USAGE is not set +-# CONFIG_DEBUG_KOBJECT is not set + # CONFIG_DEBUG_BUGVERBOSE is not set +-# CONFIG_DEBUG_INFO is not set +-# CONFIG_DEBUG_VM is not set +-# CONFIG_DEBUG_WRITECOUNT is not set +-# CONFIG_DEBUG_MEMORY_INIT is not set +-# CONFIG_DEBUG_LIST is not set +-# CONFIG_TEST_LIST_SORT is not set +-# CONFIG_DEBUG_SG is not set +-# CONFIG_DEBUG_NOTIFIERS is not set +-# CONFIG_DEBUG_CREDENTIALS is not set +-CONFIG_FRAME_POINTER=y +-# CONFIG_BOOT_PRINTK_DELAY is not set +-# CONFIG_RCU_TORTURE_TEST is not set +-# CONFIG_BACKTRACE_SELF_TEST is not set +-# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +-# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +-# CONFIG_FAULT_INJECTION is not set +-# CONFIG_LATENCYTOP is not set +-# CONFIG_SYSCTL_SYSCALL_CHECK is not set +-# CONFIG_DEBUG_PAGEALLOC is not set +-CONFIG_HAVE_FUNCTION_TRACER=y +-CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +-CONFIG_HAVE_DYNAMIC_FTRACE=y +-CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +-CONFIG_HAVE_C_RECORDMCOUNT=y +-CONFIG_TRACING_SUPPORT=y + # CONFIG_FTRACE is not set +-# CONFIG_DMA_API_DEBUG is not set +-# CONFIG_ATOMIC64_SELFTEST is not set +-# CONFIG_SAMPLES is not set +-CONFIG_HAVE_ARCH_KGDB=y +-# CONFIG_KGDB is not set +-# CONFIG_TEST_KSTRTOX is not set +-# CONFIG_STRICT_DEVMEM is not set + # CONFIG_ARM_UNWIND is not set +-# CONFIG_DEBUG_USER is not set +-# CONFIG_DEBUG_LL is not set +-# CONFIG_OC_ETM is not set +- +-# +-# Security options +-# +-CONFIG_KEYS=y +-# CONFIG_KEYS_DEBUG_PROC_KEYS is not set +-# CONFIG_SECURITY_DMESG_RESTRICT is not set +-# CONFIG_SECURITY is not set +-# CONFIG_SECURITYFS is not set +-CONFIG_DEFAULT_SECURITY_DAC=y +-CONFIG_DEFAULT_SECURITY="" +-CONFIG_CRYPTO=y +- +-# +-# Crypto core or helper +-# +-CONFIG_CRYPTO_ALGAPI=y +-CONFIG_CRYPTO_ALGAPI2=y +-CONFIG_CRYPTO_AEAD=m +-CONFIG_CRYPTO_AEAD2=y +-CONFIG_CRYPTO_BLKCIPHER=y +-CONFIG_CRYPTO_BLKCIPHER2=y +-CONFIG_CRYPTO_HASH=y +-CONFIG_CRYPTO_HASH2=y +-CONFIG_CRYPTO_RNG=m +-CONFIG_CRYPTO_RNG2=y +-CONFIG_CRYPTO_PCOMP2=y +-CONFIG_CRYPTO_MANAGER=y +-CONFIG_CRYPTO_MANAGER2=y +-CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y +-# CONFIG_CRYPTO_GF128MUL is not set +-# CONFIG_CRYPTO_NULL is not set +-CONFIG_CRYPTO_WORKQUEUE=y +-# CONFIG_CRYPTO_CRYPTD is not set + CONFIG_CRYPTO_AUTHENC=m +-# CONFIG_CRYPTO_TEST is not set +- +-# +-# Authenticated Encryption with Associated Data +-# +-# CONFIG_CRYPTO_CCM is not set +-# CONFIG_CRYPTO_GCM is not set + CONFIG_CRYPTO_SEQIV=m +- +-# +-# Block modes +-# + CONFIG_CRYPTO_CBC=y +-# CONFIG_CRYPTO_CTR is not set +-# CONFIG_CRYPTO_CTS is not set +-CONFIG_CRYPTO_ECB=m +-# CONFIG_CRYPTO_LRW is not set +-# CONFIG_CRYPTO_PCBC is not set +-# CONFIG_CRYPTO_XTS is not set +- +-# +-# Hash modes +-# + CONFIG_CRYPTO_HMAC=y + CONFIG_CRYPTO_XCBC=m +-# CONFIG_CRYPTO_VMAC is not set +- +-# +-# Digest +-# +-CONFIG_CRYPTO_CRC32C=y +-# CONFIG_CRYPTO_GHASH is not set +-CONFIG_CRYPTO_MD4=m + CONFIG_CRYPTO_MD5=y +-CONFIG_CRYPTO_MICHAEL_MIC=m +-# CONFIG_CRYPTO_RMD128 is not set +-# CONFIG_CRYPTO_RMD160 is not set +-# CONFIG_CRYPTO_RMD256 is not set +-# CONFIG_CRYPTO_RMD320 is not set + CONFIG_CRYPTO_SHA1=y + CONFIG_CRYPTO_SHA256=m + CONFIG_CRYPTO_SHA512=m + CONFIG_CRYPTO_TGR192=m + CONFIG_CRYPTO_WP512=m +- +-# +-# Ciphers +-# +-# CONFIG_CRYPTO_AES is not set +-# CONFIG_CRYPTO_ANUBIS is not set +-CONFIG_CRYPTO_ARC4=m +-# CONFIG_CRYPTO_BLOWFISH is not set +-# CONFIG_CRYPTO_CAMELLIA is not set + CONFIG_CRYPTO_CAST5=m +-# CONFIG_CRYPTO_CAST6 is not set + CONFIG_CRYPTO_DES=y +-# CONFIG_CRYPTO_FCRYPT is not set +-# CONFIG_CRYPTO_KHAZAD is not set +-# CONFIG_CRYPTO_SALSA20 is not set +-# CONFIG_CRYPTO_SEED is not set +-# CONFIG_CRYPTO_SERPENT is not set +-# CONFIG_CRYPTO_TEA is not set +-# CONFIG_CRYPTO_TWOFISH is not set +- +-# +-# Compression +-# + CONFIG_CRYPTO_DEFLATE=m +-# CONFIG_CRYPTO_ZLIB is not set +-# CONFIG_CRYPTO_LZO is not set +- +-# +-# Random Number Generation +-# + # CONFIG_CRYPTO_ANSI_CPRNG is not set +-# CONFIG_CRYPTO_USER_API_HASH is not set +-# CONFIG_CRYPTO_USER_API_SKCIPHER is not set + # CONFIG_CRYPTO_HW is not set +-# CONFIG_BINARY_PRINTF is not set +- +-# +-# Library routines +-# +-CONFIG_BITREVERSE=y +-CONFIG_CRC_CCITT=m +-CONFIG_CRC16=y +-# CONFIG_CRC_T10DIF is not set + CONFIG_CRC_ITU_T=y +-CONFIG_CRC32=y +-# CONFIG_CRC7 is not set + CONFIG_LIBCRC32C=y +-# CONFIG_CRC8 is not set +-CONFIG_ZLIB_INFLATE=m +-CONFIG_ZLIB_DEFLATE=m +-# CONFIG_XZ_DEC is not set +-# CONFIG_XZ_DEC_BCJ is not set +-CONFIG_HAS_IOMEM=y +-CONFIG_HAS_IOPORT=y +-CONFIG_HAS_DMA=y +-CONFIG_NLATTR=y +-CONFIG_GENERIC_ATOMIC64=y +-# CONFIG_AVERAGE is not set +-# CONFIG_CORDIC is not set +--- /dev/null ++++ b/arch/arm/configs/bcmrpi_defconfig +@@ -0,0 +1,530 @@ ++CONFIG_EXPERIMENTAL=y ++# CONFIG_LOCALVERSION_AUTO is not set ++CONFIG_SYSVIPC=y ++CONFIG_POSIX_MQUEUE=y ++CONFIG_BSD_PROCESS_ACCT=y ++CONFIG_BSD_PROCESS_ACCT_V3=y ++CONFIG_FHANDLE=y ++CONFIG_AUDIT=y ++CONFIG_IKCONFIG=y ++CONFIG_IKCONFIG_PROC=y ++CONFIG_CGROUP_FREEZER=y ++CONFIG_CGROUP_DEVICE=y ++CONFIG_CGROUP_CPUACCT=y ++CONFIG_RESOURCE_COUNTERS=y ++CONFIG_BLK_CGROUP=y ++CONFIG_NAMESPACES=y ++CONFIG_SCHED_AUTOGROUP=y ++CONFIG_EMBEDDED=y ++# CONFIG_COMPAT_BRK is not set ++CONFIG_SLAB=y ++CONFIG_PROFILING=y ++CONFIG_OPROFILE=m ++CONFIG_KPROBES=y ++CONFIG_MODULES=y ++CONFIG_MODULE_UNLOAD=y ++CONFIG_MODVERSIONS=y ++CONFIG_MODULE_SRCVERSION_ALL=y ++# CONFIG_BLK_DEV_BSG is not set ++CONFIG_BLK_DEV_THROTTLING=y ++CONFIG_CFQ_GROUP_IOSCHED=y ++CONFIG_ARCH_BCM2708=y ++CONFIG_NO_HZ=y ++CONFIG_HIGH_RES_TIMERS=y ++CONFIG_AEABI=y ++CONFIG_SECCOMP=y ++CONFIG_CC_STACKPROTECTOR=y ++CONFIG_ZBOOT_ROM_TEXT=0x0 ++CONFIG_ZBOOT_ROM_BSS=0x0 ++CONFIG_CMDLINE="dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 root=/dev/mmcblk0p2 rootfstype=ext3 rootwait" ++CONFIG_KEXEC=y ++CONFIG_CPU_IDLE=y ++CONFIG_VFP=y ++CONFIG_BINFMT_MISC=m ++CONFIG_NET=y ++CONFIG_PACKET=y ++CONFIG_UNIX=y ++CONFIG_XFRM_USER=y ++CONFIG_NET_KEY=m ++CONFIG_INET=y ++CONFIG_IP_MULTICAST=y ++CONFIG_IP_PNP=y ++CONFIG_IP_PNP_DHCP=y ++CONFIG_IP_PNP_RARP=y ++CONFIG_SYN_COOKIES=y ++# CONFIG_INET_XFRM_MODE_TRANSPORT is not set ++# CONFIG_INET_XFRM_MODE_TUNNEL is not set ++# CONFIG_INET_XFRM_MODE_BEET is not set ++# CONFIG_INET_LRO is not set ++# CONFIG_INET_DIAG is not set ++# CONFIG_IPV6 is not set ++CONFIG_NET_PKTGEN=m ++CONFIG_IRDA=m ++CONFIG_IRLAN=m ++CONFIG_IRCOMM=m ++CONFIG_IRDA_ULTRA=y ++CONFIG_IRDA_CACHE_LAST_LSAP=y ++CONFIG_IRDA_FAST_RR=y ++CONFIG_IRTTY_SIR=m ++CONFIG_KINGSUN_DONGLE=m ++CONFIG_KSDAZZLE_DONGLE=m ++CONFIG_KS959_DONGLE=m ++CONFIG_USB_IRDA=m ++CONFIG_SIGMATEL_FIR=m ++CONFIG_MCS_FIR=m ++CONFIG_BT=m ++CONFIG_BT_L2CAP=y ++CONFIG_BT_SCO=y ++CONFIG_BT_RFCOMM=m ++CONFIG_BT_RFCOMM_TTY=y ++CONFIG_BT_BNEP=m ++CONFIG_BT_BNEP_MC_FILTER=y ++CONFIG_BT_BNEP_PROTO_FILTER=y ++CONFIG_BT_HIDP=m ++CONFIG_BT_HCIBTUSB=m ++CONFIG_BT_HCIBCM203X=m ++CONFIG_BT_HCIBPA10X=m ++CONFIG_BT_HCIBFUSB=m ++CONFIG_BT_HCIVHCI=m ++CONFIG_BT_MRVL=m ++CONFIG_BT_MRVL_SDIO=m ++CONFIG_BT_ATH3K=m ++CONFIG_CFG80211=m ++CONFIG_MAC80211=m ++CONFIG_MAC80211_RC_PID=y ++CONFIG_MAC80211_MESH=y ++CONFIG_WIMAX=m ++CONFIG_NET_9P=m ++CONFIG_NFC=m ++CONFIG_NFC_PN533=m ++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" ++CONFIG_BLK_DEV_LOOP=y ++CONFIG_BLK_DEV_CRYPTOLOOP=m ++CONFIG_BLK_DEV_NBD=m ++CONFIG_BLK_DEV_RAM=y ++CONFIG_CDROM_PKTCDVD=m ++CONFIG_MISC_DEVICES=y ++CONFIG_SCSI=y ++# CONFIG_SCSI_PROC_FS is not set ++CONFIG_BLK_DEV_SD=y ++CONFIG_BLK_DEV_SR=m ++CONFIG_SCSI_MULTI_LUN=y ++# CONFIG_SCSI_LOWLEVEL is not set ++CONFIG_MD=y ++CONFIG_NETDEVICES=y ++CONFIG_TUN=m ++CONFIG_PHYLIB=m ++CONFIG_MDIO_BITBANG=m ++CONFIG_NET_ETHERNET=y ++# CONFIG_NETDEV_1000 is not set ++# CONFIG_NETDEV_10000 is not set ++CONFIG_LIBERTAS_THINFIRM=m ++CONFIG_LIBERTAS_THINFIRM_USB=m ++CONFIG_AT76C50X_USB=m ++CONFIG_USB_ZD1201=m ++CONFIG_USB_NET_RNDIS_WLAN=m ++CONFIG_RTL8187=m ++CONFIG_MAC80211_HWSIM=m ++CONFIG_ATH_COMMON=m ++CONFIG_ATH9K=m ++CONFIG_ATH9K_HTC=m ++CONFIG_CARL9170=m ++CONFIG_B43=m ++CONFIG_B43LEGACY=m ++CONFIG_HOSTAP=m ++CONFIG_IWM=m ++CONFIG_LIBERTAS=m ++CONFIG_LIBERTAS_USB=m ++CONFIG_LIBERTAS_SDIO=m ++CONFIG_P54_COMMON=m ++CONFIG_P54_USB=m ++CONFIG_RT2X00=m ++CONFIG_RT2500USB=m ++CONFIG_RT73USB=m ++CONFIG_RT2800USB=m ++CONFIG_RT2800USB_RT53XX=y ++CONFIG_RTL8192CU=m ++CONFIG_WL1251=m ++CONFIG_WL12XX_MENU=m ++CONFIG_ZD1211RW=m ++CONFIG_MWIFIEX=m ++CONFIG_MWIFIEX_SDIO=m ++CONFIG_WIMAX_I2400M_USB=m ++CONFIG_USB_CATC=m ++CONFIG_USB_KAWETH=m ++CONFIG_USB_PEGASUS=m ++CONFIG_USB_RTL8150=m ++CONFIG_USB_USBNET=y ++CONFIG_USB_NET_AX8817X=m ++CONFIG_USB_NET_CDCETHER=m ++CONFIG_USB_NET_CDC_EEM=m ++CONFIG_USB_NET_DM9601=m ++CONFIG_USB_NET_SMSC75XX=m ++CONFIG_USB_NET_SMSC95XX=y ++CONFIG_USB_NET_GL620A=m ++CONFIG_USB_NET_NET1080=m ++CONFIG_USB_NET_PLUSB=m ++CONFIG_USB_NET_MCS7830=m ++CONFIG_USB_NET_CDC_SUBSET=m ++CONFIG_USB_ALI_M5632=y ++CONFIG_USB_AN2720=y ++CONFIG_USB_KC2190=y ++# CONFIG_USB_NET_ZAURUS is not set ++CONFIG_USB_NET_CX82310_ETH=m ++CONFIG_USB_NET_KALMIA=m ++CONFIG_USB_NET_INT51X1=m ++CONFIG_USB_IPHETH=m ++CONFIG_USB_SIERRA_NET=m ++CONFIG_USB_VL600=m ++CONFIG_PPP=m ++CONFIG_PPP_ASYNC=m ++CONFIG_PPP_SYNC_TTY=m ++CONFIG_PPP_DEFLATE=m ++CONFIG_PPP_BSDCOMP=m ++CONFIG_SLIP=m ++CONFIG_SLIP_COMPRESSED=y ++CONFIG_NETCONSOLE=m ++CONFIG_INPUT_POLLDEV=m ++# CONFIG_INPUT_MOUSEDEV_PSAUX is not set ++CONFIG_INPUT_JOYDEV=m ++CONFIG_INPUT_EVDEV=m ++# CONFIG_INPUT_KEYBOARD is not set ++# CONFIG_INPUT_MOUSE is not set ++CONFIG_INPUT_MISC=y ++CONFIG_INPUT_AD714X=m ++CONFIG_INPUT_ATI_REMOTE=m ++CONFIG_INPUT_ATI_REMOTE2=m ++CONFIG_INPUT_KEYSPAN_REMOTE=m ++CONFIG_INPUT_POWERMATE=m ++CONFIG_INPUT_YEALINK=m ++CONFIG_INPUT_CM109=m ++CONFIG_INPUT_UINPUT=m ++CONFIG_INPUT_GPIO_ROTARY_ENCODER=m ++CONFIG_INPUT_ADXL34X=m ++CONFIG_INPUT_CMA3000=m ++CONFIG_SERIO=m ++CONFIG_SERIO_RAW=m ++CONFIG_GAMEPORT=m ++CONFIG_GAMEPORT_NS558=m ++CONFIG_GAMEPORT_L4=m ++CONFIG_VT_HW_CONSOLE_BINDING=y ++# CONFIG_LEGACY_PTYS is not set ++# CONFIG_DEVKMEM is not set ++CONFIG_SERIAL_AMBA_PL011=y ++CONFIG_SERIAL_AMBA_PL011_CONSOLE=y ++# CONFIG_HW_RANDOM is not set ++CONFIG_RAW_DRIVER=y ++CONFIG_GPIO_SYSFS=y ++# CONFIG_HWMON is not set ++CONFIG_WATCHDOG=y ++CONFIG_BCM2708_WDT=m ++# CONFIG_MFD_SUPPORT is not set ++CONFIG_FB=y ++CONFIG_FB_BCM2708=y ++CONFIG_FRAMEBUFFER_CONSOLE=y ++CONFIG_LOGO=y ++# CONFIG_LOGO_LINUX_MONO is not set ++# CONFIG_LOGO_LINUX_VGA16 is not set ++CONFIG_SOUND=y ++CONFIG_SND=m ++CONFIG_SND_SEQUENCER=m ++CONFIG_SND_SEQ_DUMMY=m ++CONFIG_SND_MIXER_OSS=m ++CONFIG_SND_PCM_OSS=m ++CONFIG_SND_SEQUENCER_OSS=y ++CONFIG_SND_HRTIMER=m ++CONFIG_SND_DUMMY=m ++CONFIG_SND_ALOOP=m ++CONFIG_SND_VIRMIDI=m ++CONFIG_SND_MTPAV=m ++CONFIG_SND_SERIAL_U16550=m ++CONFIG_SND_MPU401=m ++CONFIG_SND_BCM2835=m ++CONFIG_SND_USB_AUDIO=m ++CONFIG_SND_USB_UA101=m ++CONFIG_SND_USB_CAIAQ=m ++CONFIG_SND_USB_6FIRE=m ++CONFIG_SOUND_PRIME=m ++CONFIG_HID_PID=y ++CONFIG_USB_HIDDEV=y ++CONFIG_HID_A4TECH=m ++CONFIG_HID_ACRUX=m ++CONFIG_HID_APPLE=m ++CONFIG_HID_BELKIN=m ++CONFIG_HID_CHERRY=m ++CONFIG_HID_CHICONY=m ++CONFIG_HID_CYPRESS=m ++CONFIG_HID_DRAGONRISE=m ++CONFIG_HID_EMS_FF=m ++CONFIG_HID_ELECOM=m ++CONFIG_HID_EZKEY=m ++CONFIG_HID_HOLTEK=m ++CONFIG_HID_KEYTOUCH=m ++CONFIG_HID_KYE=m ++CONFIG_HID_UCLOGIC=m ++CONFIG_HID_WALTOP=m ++CONFIG_HID_GYRATION=m ++CONFIG_HID_TWINHAN=m ++CONFIG_HID_KENSINGTON=m ++CONFIG_HID_LCPOWER=m ++CONFIG_HID_LOGITECH=m ++CONFIG_HID_MAGICMOUSE=m ++CONFIG_HID_MICROSOFT=m ++CONFIG_HID_MONTEREY=m ++CONFIG_HID_MULTITOUCH=m ++CONFIG_HID_NTRIG=m ++CONFIG_HID_ORTEK=m ++CONFIG_HID_PANTHERLORD=m ++CONFIG_HID_PETALYNX=m ++CONFIG_HID_PICOLCD=m ++CONFIG_HID_QUANTA=m ++CONFIG_HID_ROCCAT=m ++CONFIG_HID_SAMSUNG=m ++CONFIG_HID_SONY=m ++CONFIG_HID_SPEEDLINK=m ++CONFIG_HID_SUNPLUS=m ++CONFIG_HID_GREENASIA=m ++CONFIG_HID_SMARTJOYPLUS=m ++CONFIG_HID_TOPSEED=m ++CONFIG_HID_THRUSTMASTER=m ++CONFIG_HID_WACOM=m ++CONFIG_HID_WIIMOTE=m ++CONFIG_HID_ZEROPLUS=m ++CONFIG_HID_ZYDACRON=m ++CONFIG_USB=y ++CONFIG_USB_ANNOUNCE_NEW_DEVICES=y ++CONFIG_USB_MON=m ++CONFIG_USB_DWCOTG=y ++CONFIG_USB_STORAGE=y ++CONFIG_USB_STORAGE_REALTEK=m ++CONFIG_USB_STORAGE_DATAFAB=m ++CONFIG_USB_STORAGE_FREECOM=m ++CONFIG_USB_STORAGE_ISD200=m ++CONFIG_USB_STORAGE_USBAT=m ++CONFIG_USB_STORAGE_SDDR09=m ++CONFIG_USB_STORAGE_SDDR55=m ++CONFIG_USB_STORAGE_JUMPSHOT=m ++CONFIG_USB_STORAGE_ALAUDA=m ++CONFIG_USB_STORAGE_ONETOUCH=m ++CONFIG_USB_STORAGE_KARMA=m ++CONFIG_USB_STORAGE_CYPRESS_ATACB=m ++CONFIG_USB_STORAGE_ENE_UB6250=m ++CONFIG_USB_UAS=y ++CONFIG_USB_LIBUSUAL=y ++CONFIG_USB_MDC800=m ++CONFIG_USB_MICROTEK=m ++CONFIG_USB_SERIAL=m ++CONFIG_USB_SERIAL_GENERIC=y ++CONFIG_USB_SERIAL_AIRCABLE=m ++CONFIG_USB_SERIAL_ARK3116=m ++CONFIG_USB_SERIAL_BELKIN=m ++CONFIG_USB_SERIAL_CH341=m ++CONFIG_USB_SERIAL_WHITEHEAT=m ++CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m ++CONFIG_USB_SERIAL_CP210X=m ++CONFIG_USB_SERIAL_CYPRESS_M8=m ++CONFIG_USB_SERIAL_EMPEG=m ++CONFIG_USB_SERIAL_FTDI_SIO=m ++CONFIG_USB_SERIAL_FUNSOFT=m ++CONFIG_USB_SERIAL_VISOR=m ++CONFIG_USB_SERIAL_IPAQ=m ++CONFIG_USB_SERIAL_IR=m ++CONFIG_USB_SERIAL_EDGEPORT=m ++CONFIG_USB_SERIAL_EDGEPORT_TI=m ++CONFIG_USB_SERIAL_GARMIN=m ++CONFIG_USB_SERIAL_IPW=m ++CONFIG_USB_SERIAL_IUU=m ++CONFIG_USB_SERIAL_KEYSPAN_PDA=m ++CONFIG_USB_SERIAL_KEYSPAN=m ++CONFIG_USB_SERIAL_KLSI=m ++CONFIG_USB_SERIAL_KOBIL_SCT=m ++CONFIG_USB_SERIAL_MCT_U232=m ++CONFIG_USB_SERIAL_MOS7720=m ++CONFIG_USB_SERIAL_MOS7840=m ++CONFIG_USB_SERIAL_MOTOROLA=m ++CONFIG_USB_SERIAL_NAVMAN=m ++CONFIG_USB_SERIAL_PL2303=m ++CONFIG_USB_SERIAL_OTI6858=m ++CONFIG_USB_SERIAL_QCAUX=m ++CONFIG_USB_SERIAL_QUALCOMM=m ++CONFIG_USB_SERIAL_SPCP8X5=m ++CONFIG_USB_SERIAL_HP4X=m ++CONFIG_USB_SERIAL_SAFE=m ++CONFIG_USB_SERIAL_SIEMENS_MPI=m ++CONFIG_USB_SERIAL_SIERRAWIRELESS=m ++CONFIG_USB_SERIAL_SYMBOL=m ++CONFIG_USB_SERIAL_TI=m ++CONFIG_USB_SERIAL_CYBERJACK=m ++CONFIG_USB_SERIAL_XIRCOM=m ++CONFIG_USB_SERIAL_OPTION=m ++CONFIG_USB_SERIAL_OMNINET=m ++CONFIG_USB_SERIAL_OPTICON=m ++CONFIG_USB_SERIAL_VIVOPAY_SERIAL=m ++CONFIG_USB_SERIAL_ZIO=m ++CONFIG_USB_SERIAL_SSU100=m ++CONFIG_USB_SERIAL_DEBUG=m ++CONFIG_USB_EMI62=m ++CONFIG_USB_EMI26=m ++CONFIG_USB_ADUTUX=m ++CONFIG_USB_SEVSEG=m ++CONFIG_USB_RIO500=m ++CONFIG_USB_LEGOTOWER=m ++CONFIG_USB_LCD=m ++CONFIG_USB_LED=m ++CONFIG_USB_CYPRESS_CY7C63=m ++CONFIG_USB_CYTHERM=m ++CONFIG_USB_IDMOUSE=m ++CONFIG_USB_FTDI_ELAN=m ++CONFIG_USB_APPLEDISPLAY=m ++CONFIG_USB_LD=m ++CONFIG_USB_TRANCEVIBRATOR=m ++CONFIG_USB_IOWARRIOR=m ++CONFIG_USB_TEST=m ++CONFIG_USB_ISIGHTFW=m ++CONFIG_USB_YUREX=m ++CONFIG_MMC=y ++CONFIG_MMC_SDHCI=y ++CONFIG_MMC_SDHCI_PLTFM=y ++CONFIG_MMC_SDHCI_BCM2708=y ++CONFIG_MMC_SDHCI_BCM2708_DMA=y ++CONFIG_LEDS_GPIO=y ++CONFIG_LEDS_TRIGGER_TIMER=m ++CONFIG_LEDS_TRIGGER_HEARTBEAT=m ++CONFIG_LEDS_TRIGGER_DEFAULT_ON=m ++CONFIG_UIO=m ++CONFIG_UIO_PDRV=m ++CONFIG_UIO_PDRV_GENIRQ=m ++# CONFIG_IOMMU_SUPPORT is not set ++CONFIG_EXT4_FS=y ++CONFIG_EXT4_FS_POSIX_ACL=y ++CONFIG_EXT4_FS_SECURITY=y ++CONFIG_REISERFS_FS=m ++CONFIG_REISERFS_FS_XATTR=y ++CONFIG_REISERFS_FS_POSIX_ACL=y ++CONFIG_REISERFS_FS_SECURITY=y ++CONFIG_JFS_FS=m ++CONFIG_JFS_POSIX_ACL=y ++CONFIG_JFS_SECURITY=y ++CONFIG_JFS_STATISTICS=y ++CONFIG_XFS_FS=m ++CONFIG_XFS_QUOTA=y ++CONFIG_XFS_POSIX_ACL=y ++CONFIG_XFS_RT=y ++CONFIG_GFS2_FS=m ++CONFIG_OCFS2_FS=m ++CONFIG_BTRFS_FS=m ++CONFIG_BTRFS_FS_POSIX_ACL=y ++CONFIG_NILFS2_FS=m ++CONFIG_FANOTIFY=y ++CONFIG_AUTOFS4_FS=y ++CONFIG_FUSE_FS=m ++CONFIG_CUSE=m ++CONFIG_FSCACHE=y ++CONFIG_FSCACHE_STATS=y ++CONFIG_FSCACHE_HISTOGRAM=y ++CONFIG_CACHEFILES=y ++CONFIG_ISO9660_FS=m ++CONFIG_JOLIET=y ++CONFIG_ZISOFS=y ++CONFIG_UDF_FS=m ++CONFIG_MSDOS_FS=y ++CONFIG_VFAT_FS=y ++CONFIG_FAT_DEFAULT_IOCHARSET="ascii" ++CONFIG_NTFS_FS=m ++CONFIG_TMPFS=y ++CONFIG_TMPFS_POSIX_ACL=y ++CONFIG_CONFIGFS_FS=y ++CONFIG_SQUASHFS=m ++CONFIG_SQUASHFS_XATTR=y ++CONFIG_SQUASHFS_LZO=y ++CONFIG_SQUASHFS_XZ=y ++CONFIG_NFS_FS=y ++CONFIG_NFS_V3=y ++CONFIG_NFS_V3_ACL=y ++CONFIG_NFS_V4=y ++CONFIG_ROOT_NFS=y ++CONFIG_NFS_FSCACHE=y ++CONFIG_CIFS=m ++CONFIG_CIFS_WEAK_PW_HASH=y ++CONFIG_CIFS_XATTR=y ++CONFIG_CIFS_POSIX=y ++CONFIG_9P_FS=m ++CONFIG_9P_FS_POSIX_ACL=y ++CONFIG_PARTITION_ADVANCED=y ++CONFIG_MAC_PARTITION=y ++CONFIG_EFI_PARTITION=y ++CONFIG_NLS_DEFAULT="utf8" ++CONFIG_NLS_CODEPAGE_437=y ++CONFIG_NLS_CODEPAGE_737=m ++CONFIG_NLS_CODEPAGE_775=m ++CONFIG_NLS_CODEPAGE_850=m ++CONFIG_NLS_CODEPAGE_852=m ++CONFIG_NLS_CODEPAGE_855=m ++CONFIG_NLS_CODEPAGE_857=m ++CONFIG_NLS_CODEPAGE_860=m ++CONFIG_NLS_CODEPAGE_861=m ++CONFIG_NLS_CODEPAGE_862=m ++CONFIG_NLS_CODEPAGE_863=m ++CONFIG_NLS_CODEPAGE_864=m ++CONFIG_NLS_CODEPAGE_865=m ++CONFIG_NLS_CODEPAGE_866=m ++CONFIG_NLS_CODEPAGE_869=m ++CONFIG_NLS_CODEPAGE_936=m ++CONFIG_NLS_CODEPAGE_950=m ++CONFIG_NLS_CODEPAGE_932=m ++CONFIG_NLS_CODEPAGE_949=m ++CONFIG_NLS_CODEPAGE_874=m ++CONFIG_NLS_ISO8859_8=m ++CONFIG_NLS_CODEPAGE_1250=m ++CONFIG_NLS_CODEPAGE_1251=m ++CONFIG_NLS_ASCII=y ++CONFIG_NLS_ISO8859_1=m ++CONFIG_NLS_ISO8859_2=m ++CONFIG_NLS_ISO8859_3=m ++CONFIG_NLS_ISO8859_4=m ++CONFIG_NLS_ISO8859_5=m ++CONFIG_NLS_ISO8859_6=m ++CONFIG_NLS_ISO8859_7=m ++CONFIG_NLS_ISO8859_9=m ++CONFIG_NLS_ISO8859_13=m ++CONFIG_NLS_ISO8859_14=m ++CONFIG_NLS_ISO8859_15=m ++CONFIG_NLS_KOI8_R=m ++CONFIG_NLS_KOI8_U=m ++CONFIG_NLS_UTF8=m ++CONFIG_PRINTK_TIME=y ++CONFIG_DETECT_HUNG_TASK=y ++CONFIG_TIMER_STATS=y ++CONFIG_DEBUG_STACK_USAGE=y ++CONFIG_DEBUG_INFO=y ++CONFIG_DEBUG_MEMORY_INIT=y ++CONFIG_BOOT_PRINTK_DELAY=y ++CONFIG_LATENCYTOP=y ++CONFIG_SYSCTL_SYSCALL_CHECK=y ++CONFIG_IRQSOFF_TRACER=y ++CONFIG_SCHED_TRACER=y ++CONFIG_STACK_TRACER=y ++CONFIG_BLK_DEV_IO_TRACE=y ++CONFIG_FUNCTION_PROFILER=y ++CONFIG_KGDB=y ++CONFIG_KGDB_KDB=y ++CONFIG_KDB_KEYBOARD=y ++CONFIG_STRICT_DEVMEM=y ++CONFIG_CRYPTO_AUTHENC=m ++CONFIG_CRYPTO_SEQIV=m ++CONFIG_CRYPTO_CBC=y ++CONFIG_CRYPTO_HMAC=y ++CONFIG_CRYPTO_XCBC=m ++CONFIG_CRYPTO_MD5=y ++CONFIG_CRYPTO_SHA1=y ++CONFIG_CRYPTO_SHA256=m ++CONFIG_CRYPTO_SHA512=m ++CONFIG_CRYPTO_TGR192=m ++CONFIG_CRYPTO_WP512=m ++CONFIG_CRYPTO_CAST5=m ++CONFIG_CRYPTO_DES=y ++CONFIG_CRYPTO_DEFLATE=m ++# CONFIG_CRYPTO_ANSI_CPRNG is not set ++# CONFIG_CRYPTO_HW is not set ++CONFIG_CRC_ITU_T=y ++CONFIG_LIBCRC32C=y +--- /dev/null ++++ b/arch/arm/configs/bcmrpi_emergency_defconfig +@@ -0,0 +1,532 @@ ++CONFIG_EXPERIMENTAL=y ++# CONFIG_LOCALVERSION_AUTO is not set ++CONFIG_SYSVIPC=y ++CONFIG_POSIX_MQUEUE=y ++CONFIG_BSD_PROCESS_ACCT=y ++CONFIG_BSD_PROCESS_ACCT_V3=y ++CONFIG_FHANDLE=y ++CONFIG_AUDIT=y ++CONFIG_IKCONFIG=y ++CONFIG_IKCONFIG_PROC=y ++CONFIG_BLK_DEV_INITRD=y ++CONFIG_INITRAMFS_SOURCE="../target_fs" ++CONFIG_CGROUP_FREEZER=y ++CONFIG_CGROUP_DEVICE=y ++CONFIG_CGROUP_CPUACCT=y ++CONFIG_RESOURCE_COUNTERS=y ++CONFIG_BLK_CGROUP=y ++CONFIG_NAMESPACES=y ++CONFIG_SCHED_AUTOGROUP=y ++CONFIG_EMBEDDED=y ++# CONFIG_COMPAT_BRK is not set ++CONFIG_SLAB=y ++CONFIG_PROFILING=y ++CONFIG_OPROFILE=m ++CONFIG_KPROBES=y ++CONFIG_MODULES=y ++CONFIG_MODULE_UNLOAD=y ++CONFIG_MODVERSIONS=y ++CONFIG_MODULE_SRCVERSION_ALL=y ++# CONFIG_BLK_DEV_BSG is not set ++CONFIG_BLK_DEV_THROTTLING=y ++CONFIG_CFQ_GROUP_IOSCHED=y ++CONFIG_ARCH_BCM2708=y ++CONFIG_NO_HZ=y ++CONFIG_HIGH_RES_TIMERS=y ++CONFIG_AEABI=y ++CONFIG_SECCOMP=y ++CONFIG_CC_STACKPROTECTOR=y ++CONFIG_ZBOOT_ROM_TEXT=0x0 ++CONFIG_ZBOOT_ROM_BSS=0x0 ++CONFIG_CMDLINE="dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 root=/dev/mmcblk0p2 rootfstype=ext3 rootwait" ++CONFIG_KEXEC=y ++CONFIG_CPU_IDLE=y ++CONFIG_VFP=y ++CONFIG_BINFMT_MISC=m ++CONFIG_NET=y ++CONFIG_PACKET=y ++CONFIG_UNIX=y ++CONFIG_XFRM_USER=y ++CONFIG_NET_KEY=m ++CONFIG_INET=y ++CONFIG_IP_MULTICAST=y ++CONFIG_IP_PNP=y ++CONFIG_IP_PNP_DHCP=y ++CONFIG_IP_PNP_RARP=y ++CONFIG_SYN_COOKIES=y ++# CONFIG_INET_XFRM_MODE_TRANSPORT is not set ++# CONFIG_INET_XFRM_MODE_TUNNEL is not set ++# CONFIG_INET_XFRM_MODE_BEET is not set ++# CONFIG_INET_LRO is not set ++# CONFIG_INET_DIAG is not set ++# CONFIG_IPV6 is not set ++CONFIG_NET_PKTGEN=m ++CONFIG_IRDA=m ++CONFIG_IRLAN=m ++CONFIG_IRCOMM=m ++CONFIG_IRDA_ULTRA=y ++CONFIG_IRDA_CACHE_LAST_LSAP=y ++CONFIG_IRDA_FAST_RR=y ++CONFIG_IRTTY_SIR=m ++CONFIG_KINGSUN_DONGLE=m ++CONFIG_KSDAZZLE_DONGLE=m ++CONFIG_KS959_DONGLE=m ++CONFIG_USB_IRDA=m ++CONFIG_SIGMATEL_FIR=m ++CONFIG_MCS_FIR=m ++CONFIG_BT=m ++CONFIG_BT_L2CAP=y ++CONFIG_BT_SCO=y ++CONFIG_BT_RFCOMM=m ++CONFIG_BT_RFCOMM_TTY=y ++CONFIG_BT_BNEP=m ++CONFIG_BT_BNEP_MC_FILTER=y ++CONFIG_BT_BNEP_PROTO_FILTER=y ++CONFIG_BT_HIDP=m ++CONFIG_BT_HCIBTUSB=m ++CONFIG_BT_HCIBCM203X=m ++CONFIG_BT_HCIBPA10X=m ++CONFIG_BT_HCIBFUSB=m ++CONFIG_BT_HCIVHCI=m ++CONFIG_BT_MRVL=m ++CONFIG_BT_MRVL_SDIO=m ++CONFIG_BT_ATH3K=m ++CONFIG_CFG80211=m ++CONFIG_MAC80211=m ++CONFIG_MAC80211_RC_PID=y ++CONFIG_MAC80211_MESH=y ++CONFIG_WIMAX=m ++CONFIG_NET_9P=m ++CONFIG_NFC=m ++CONFIG_NFC_PN533=m ++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" ++CONFIG_BLK_DEV_LOOP=y ++CONFIG_BLK_DEV_CRYPTOLOOP=m ++CONFIG_BLK_DEV_NBD=m ++CONFIG_BLK_DEV_RAM=y ++CONFIG_CDROM_PKTCDVD=m ++CONFIG_MISC_DEVICES=y ++CONFIG_SCSI=y ++# CONFIG_SCSI_PROC_FS is not set ++CONFIG_BLK_DEV_SD=y ++CONFIG_BLK_DEV_SR=m ++CONFIG_SCSI_MULTI_LUN=y ++# CONFIG_SCSI_LOWLEVEL is not set ++CONFIG_MD=y ++CONFIG_NETDEVICES=y ++CONFIG_TUN=m ++CONFIG_PHYLIB=m ++CONFIG_MDIO_BITBANG=m ++CONFIG_NET_ETHERNET=y ++# CONFIG_NETDEV_1000 is not set ++# CONFIG_NETDEV_10000 is not set ++CONFIG_LIBERTAS_THINFIRM=m ++CONFIG_LIBERTAS_THINFIRM_USB=m ++CONFIG_AT76C50X_USB=m ++CONFIG_USB_ZD1201=m ++CONFIG_USB_NET_RNDIS_WLAN=m ++CONFIG_RTL8187=m ++CONFIG_MAC80211_HWSIM=m ++CONFIG_ATH_COMMON=m ++CONFIG_ATH9K=m ++CONFIG_ATH9K_HTC=m ++CONFIG_CARL9170=m ++CONFIG_B43=m ++CONFIG_B43LEGACY=m ++CONFIG_HOSTAP=m ++CONFIG_IWM=m ++CONFIG_LIBERTAS=m ++CONFIG_LIBERTAS_USB=m ++CONFIG_LIBERTAS_SDIO=m ++CONFIG_P54_COMMON=m ++CONFIG_P54_USB=m ++CONFIG_RT2X00=m ++CONFIG_RT2500USB=m ++CONFIG_RT73USB=m ++CONFIG_RT2800USB=m ++CONFIG_RT2800USB_RT53XX=y ++CONFIG_RTL8192CU=m ++CONFIG_WL1251=m ++CONFIG_WL12XX_MENU=m ++CONFIG_ZD1211RW=m ++CONFIG_MWIFIEX=m ++CONFIG_MWIFIEX_SDIO=m ++CONFIG_WIMAX_I2400M_USB=m ++CONFIG_USB_CATC=m ++CONFIG_USB_KAWETH=m ++CONFIG_USB_PEGASUS=m ++CONFIG_USB_RTL8150=m ++CONFIG_USB_USBNET=y ++CONFIG_USB_NET_AX8817X=m ++CONFIG_USB_NET_CDCETHER=m ++CONFIG_USB_NET_CDC_EEM=m ++CONFIG_USB_NET_DM9601=m ++CONFIG_USB_NET_SMSC75XX=m ++CONFIG_USB_NET_SMSC95XX=y ++CONFIG_USB_NET_GL620A=m ++CONFIG_USB_NET_NET1080=m ++CONFIG_USB_NET_PLUSB=m ++CONFIG_USB_NET_MCS7830=m ++CONFIG_USB_NET_CDC_SUBSET=m ++CONFIG_USB_ALI_M5632=y ++CONFIG_USB_AN2720=y ++CONFIG_USB_KC2190=y ++# CONFIG_USB_NET_ZAURUS is not set ++CONFIG_USB_NET_CX82310_ETH=m ++CONFIG_USB_NET_KALMIA=m ++CONFIG_USB_NET_INT51X1=m ++CONFIG_USB_IPHETH=m ++CONFIG_USB_SIERRA_NET=m ++CONFIG_USB_VL600=m ++CONFIG_PPP=m ++CONFIG_PPP_ASYNC=m ++CONFIG_PPP_SYNC_TTY=m ++CONFIG_PPP_DEFLATE=m ++CONFIG_PPP_BSDCOMP=m ++CONFIG_SLIP=m ++CONFIG_SLIP_COMPRESSED=y ++CONFIG_NETCONSOLE=m ++CONFIG_INPUT_POLLDEV=m ++# CONFIG_INPUT_MOUSEDEV_PSAUX is not set ++CONFIG_INPUT_JOYDEV=m ++CONFIG_INPUT_EVDEV=m ++# CONFIG_INPUT_KEYBOARD is not set ++# CONFIG_INPUT_MOUSE is not set ++CONFIG_INPUT_MISC=y ++CONFIG_INPUT_AD714X=m ++CONFIG_INPUT_ATI_REMOTE=m ++CONFIG_INPUT_ATI_REMOTE2=m ++CONFIG_INPUT_KEYSPAN_REMOTE=m ++CONFIG_INPUT_POWERMATE=m ++CONFIG_INPUT_YEALINK=m ++CONFIG_INPUT_CM109=m ++CONFIG_INPUT_UINPUT=m ++CONFIG_INPUT_GPIO_ROTARY_ENCODER=m ++CONFIG_INPUT_ADXL34X=m ++CONFIG_INPUT_CMA3000=m ++CONFIG_SERIO=m ++CONFIG_SERIO_RAW=m ++CONFIG_GAMEPORT=m ++CONFIG_GAMEPORT_NS558=m ++CONFIG_GAMEPORT_L4=m ++CONFIG_VT_HW_CONSOLE_BINDING=y ++# CONFIG_LEGACY_PTYS is not set ++# CONFIG_DEVKMEM is not set ++CONFIG_SERIAL_AMBA_PL011=y ++CONFIG_SERIAL_AMBA_PL011_CONSOLE=y ++# CONFIG_HW_RANDOM is not set ++CONFIG_RAW_DRIVER=y ++CONFIG_GPIO_SYSFS=y ++# CONFIG_HWMON is not set ++CONFIG_WATCHDOG=y ++CONFIG_BCM2708_WDT=m ++# CONFIG_MFD_SUPPORT is not set ++CONFIG_FB=y ++CONFIG_FB_BCM2708=y ++CONFIG_FRAMEBUFFER_CONSOLE=y ++CONFIG_LOGO=y ++# CONFIG_LOGO_LINUX_MONO is not set ++# CONFIG_LOGO_LINUX_VGA16 is not set ++CONFIG_SOUND=y ++CONFIG_SND=m ++CONFIG_SND_SEQUENCER=m ++CONFIG_SND_SEQ_DUMMY=m ++CONFIG_SND_MIXER_OSS=m ++CONFIG_SND_PCM_OSS=m ++CONFIG_SND_SEQUENCER_OSS=y ++CONFIG_SND_HRTIMER=m ++CONFIG_SND_DUMMY=m ++CONFIG_SND_ALOOP=m ++CONFIG_SND_VIRMIDI=m ++CONFIG_SND_MTPAV=m ++CONFIG_SND_SERIAL_U16550=m ++CONFIG_SND_MPU401=m ++CONFIG_SND_BCM2835=m ++CONFIG_SND_USB_AUDIO=m ++CONFIG_SND_USB_UA101=m ++CONFIG_SND_USB_CAIAQ=m ++CONFIG_SND_USB_6FIRE=m ++CONFIG_SOUND_PRIME=m ++CONFIG_HID_PID=y ++CONFIG_USB_HIDDEV=y ++CONFIG_HID_A4TECH=m ++CONFIG_HID_ACRUX=m ++CONFIG_HID_APPLE=m ++CONFIG_HID_BELKIN=m ++CONFIG_HID_CHERRY=m ++CONFIG_HID_CHICONY=m ++CONFIG_HID_CYPRESS=m ++CONFIG_HID_DRAGONRISE=m ++CONFIG_HID_EMS_FF=m ++CONFIG_HID_ELECOM=m ++CONFIG_HID_EZKEY=m ++CONFIG_HID_HOLTEK=m ++CONFIG_HID_KEYTOUCH=m ++CONFIG_HID_KYE=m ++CONFIG_HID_UCLOGIC=m ++CONFIG_HID_WALTOP=m ++CONFIG_HID_GYRATION=m ++CONFIG_HID_TWINHAN=m ++CONFIG_HID_KENSINGTON=m ++CONFIG_HID_LCPOWER=m ++CONFIG_HID_LOGITECH=m ++CONFIG_HID_MAGICMOUSE=m ++CONFIG_HID_MICROSOFT=m ++CONFIG_HID_MONTEREY=m ++CONFIG_HID_MULTITOUCH=m ++CONFIG_HID_NTRIG=m ++CONFIG_HID_ORTEK=m ++CONFIG_HID_PANTHERLORD=m ++CONFIG_HID_PETALYNX=m ++CONFIG_HID_PICOLCD=m ++CONFIG_HID_QUANTA=m ++CONFIG_HID_ROCCAT=m ++CONFIG_HID_SAMSUNG=m ++CONFIG_HID_SONY=m ++CONFIG_HID_SPEEDLINK=m ++CONFIG_HID_SUNPLUS=m ++CONFIG_HID_GREENASIA=m ++CONFIG_HID_SMARTJOYPLUS=m ++CONFIG_HID_TOPSEED=m ++CONFIG_HID_THRUSTMASTER=m ++CONFIG_HID_WACOM=m ++CONFIG_HID_WIIMOTE=m ++CONFIG_HID_ZEROPLUS=m ++CONFIG_HID_ZYDACRON=m ++CONFIG_USB=y ++CONFIG_USB_ANNOUNCE_NEW_DEVICES=y ++CONFIG_USB_MON=m ++CONFIG_USB_DWCOTG=y ++CONFIG_USB_STORAGE=y ++CONFIG_USB_STORAGE_REALTEK=m ++CONFIG_USB_STORAGE_DATAFAB=m ++CONFIG_USB_STORAGE_FREECOM=m ++CONFIG_USB_STORAGE_ISD200=m ++CONFIG_USB_STORAGE_USBAT=m ++CONFIG_USB_STORAGE_SDDR09=m ++CONFIG_USB_STORAGE_SDDR55=m ++CONFIG_USB_STORAGE_JUMPSHOT=m ++CONFIG_USB_STORAGE_ALAUDA=m ++CONFIG_USB_STORAGE_ONETOUCH=m ++CONFIG_USB_STORAGE_KARMA=m ++CONFIG_USB_STORAGE_CYPRESS_ATACB=m ++CONFIG_USB_STORAGE_ENE_UB6250=m ++CONFIG_USB_UAS=y ++CONFIG_USB_LIBUSUAL=y ++CONFIG_USB_MDC800=m ++CONFIG_USB_MICROTEK=m ++CONFIG_USB_SERIAL=m ++CONFIG_USB_SERIAL_GENERIC=y ++CONFIG_USB_SERIAL_AIRCABLE=m ++CONFIG_USB_SERIAL_ARK3116=m ++CONFIG_USB_SERIAL_BELKIN=m ++CONFIG_USB_SERIAL_CH341=m ++CONFIG_USB_SERIAL_WHITEHEAT=m ++CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m ++CONFIG_USB_SERIAL_CP210X=m ++CONFIG_USB_SERIAL_CYPRESS_M8=m ++CONFIG_USB_SERIAL_EMPEG=m ++CONFIG_USB_SERIAL_FTDI_SIO=m ++CONFIG_USB_SERIAL_FUNSOFT=m ++CONFIG_USB_SERIAL_VISOR=m ++CONFIG_USB_SERIAL_IPAQ=m ++CONFIG_USB_SERIAL_IR=m ++CONFIG_USB_SERIAL_EDGEPORT=m ++CONFIG_USB_SERIAL_EDGEPORT_TI=m ++CONFIG_USB_SERIAL_GARMIN=m ++CONFIG_USB_SERIAL_IPW=m ++CONFIG_USB_SERIAL_IUU=m ++CONFIG_USB_SERIAL_KEYSPAN_PDA=m ++CONFIG_USB_SERIAL_KEYSPAN=m ++CONFIG_USB_SERIAL_KLSI=m ++CONFIG_USB_SERIAL_KOBIL_SCT=m ++CONFIG_USB_SERIAL_MCT_U232=m ++CONFIG_USB_SERIAL_MOS7720=m ++CONFIG_USB_SERIAL_MOS7840=m ++CONFIG_USB_SERIAL_MOTOROLA=m ++CONFIG_USB_SERIAL_NAVMAN=m ++CONFIG_USB_SERIAL_PL2303=m ++CONFIG_USB_SERIAL_OTI6858=m ++CONFIG_USB_SERIAL_QCAUX=m ++CONFIG_USB_SERIAL_QUALCOMM=m ++CONFIG_USB_SERIAL_SPCP8X5=m ++CONFIG_USB_SERIAL_HP4X=m ++CONFIG_USB_SERIAL_SAFE=m ++CONFIG_USB_SERIAL_SIEMENS_MPI=m ++CONFIG_USB_SERIAL_SIERRAWIRELESS=m ++CONFIG_USB_SERIAL_SYMBOL=m ++CONFIG_USB_SERIAL_TI=m ++CONFIG_USB_SERIAL_CYBERJACK=m ++CONFIG_USB_SERIAL_XIRCOM=m ++CONFIG_USB_SERIAL_OPTION=m ++CONFIG_USB_SERIAL_OMNINET=m ++CONFIG_USB_SERIAL_OPTICON=m ++CONFIG_USB_SERIAL_VIVOPAY_SERIAL=m ++CONFIG_USB_SERIAL_ZIO=m ++CONFIG_USB_SERIAL_SSU100=m ++CONFIG_USB_SERIAL_DEBUG=m ++CONFIG_USB_EMI62=m ++CONFIG_USB_EMI26=m ++CONFIG_USB_ADUTUX=m ++CONFIG_USB_SEVSEG=m ++CONFIG_USB_RIO500=m ++CONFIG_USB_LEGOTOWER=m ++CONFIG_USB_LCD=m ++CONFIG_USB_LED=m ++CONFIG_USB_CYPRESS_CY7C63=m ++CONFIG_USB_CYTHERM=m ++CONFIG_USB_IDMOUSE=m ++CONFIG_USB_FTDI_ELAN=m ++CONFIG_USB_APPLEDISPLAY=m ++CONFIG_USB_LD=m ++CONFIG_USB_TRANCEVIBRATOR=m ++CONFIG_USB_IOWARRIOR=m ++CONFIG_USB_TEST=m ++CONFIG_USB_ISIGHTFW=m ++CONFIG_USB_YUREX=m ++CONFIG_MMC=y ++CONFIG_MMC_SDHCI=y ++CONFIG_MMC_SDHCI_PLTFM=y ++CONFIG_MMC_SDHCI_BCM2708=y ++CONFIG_MMC_SDHCI_BCM2708_DMA=y ++CONFIG_LEDS_GPIO=y ++CONFIG_LEDS_TRIGGER_TIMER=m ++CONFIG_LEDS_TRIGGER_HEARTBEAT=m ++CONFIG_LEDS_TRIGGER_DEFAULT_ON=m ++CONFIG_UIO=m ++CONFIG_UIO_PDRV=m ++CONFIG_UIO_PDRV_GENIRQ=m ++# CONFIG_IOMMU_SUPPORT is not set ++CONFIG_EXT4_FS=y ++CONFIG_EXT4_FS_POSIX_ACL=y ++CONFIG_EXT4_FS_SECURITY=y ++CONFIG_REISERFS_FS=m ++CONFIG_REISERFS_FS_XATTR=y ++CONFIG_REISERFS_FS_POSIX_ACL=y ++CONFIG_REISERFS_FS_SECURITY=y ++CONFIG_JFS_FS=m ++CONFIG_JFS_POSIX_ACL=y ++CONFIG_JFS_SECURITY=y ++CONFIG_JFS_STATISTICS=y ++CONFIG_XFS_FS=m ++CONFIG_XFS_QUOTA=y ++CONFIG_XFS_POSIX_ACL=y ++CONFIG_XFS_RT=y ++CONFIG_GFS2_FS=m ++CONFIG_OCFS2_FS=m ++CONFIG_BTRFS_FS=m ++CONFIG_BTRFS_FS_POSIX_ACL=y ++CONFIG_NILFS2_FS=m ++CONFIG_FANOTIFY=y ++CONFIG_AUTOFS4_FS=y ++CONFIG_FUSE_FS=m ++CONFIG_CUSE=m ++CONFIG_FSCACHE=y ++CONFIG_FSCACHE_STATS=y ++CONFIG_FSCACHE_HISTOGRAM=y ++CONFIG_CACHEFILES=y ++CONFIG_ISO9660_FS=m ++CONFIG_JOLIET=y ++CONFIG_ZISOFS=y ++CONFIG_UDF_FS=m ++CONFIG_MSDOS_FS=y ++CONFIG_VFAT_FS=y ++CONFIG_FAT_DEFAULT_IOCHARSET="ascii" ++CONFIG_NTFS_FS=m ++CONFIG_TMPFS=y ++CONFIG_TMPFS_POSIX_ACL=y ++CONFIG_CONFIGFS_FS=y ++CONFIG_SQUASHFS=m ++CONFIG_SQUASHFS_XATTR=y ++CONFIG_SQUASHFS_LZO=y ++CONFIG_SQUASHFS_XZ=y ++CONFIG_NFS_FS=y ++CONFIG_NFS_V3=y ++CONFIG_NFS_V3_ACL=y ++CONFIG_NFS_V4=y ++CONFIG_ROOT_NFS=y ++CONFIG_NFS_FSCACHE=y ++CONFIG_CIFS=m ++CONFIG_CIFS_WEAK_PW_HASH=y ++CONFIG_CIFS_XATTR=y ++CONFIG_CIFS_POSIX=y ++CONFIG_9P_FS=m ++CONFIG_9P_FS_POSIX_ACL=y ++CONFIG_PARTITION_ADVANCED=y ++CONFIG_MAC_PARTITION=y ++CONFIG_EFI_PARTITION=y ++CONFIG_NLS_DEFAULT="utf8" ++CONFIG_NLS_CODEPAGE_437=y ++CONFIG_NLS_CODEPAGE_737=m ++CONFIG_NLS_CODEPAGE_775=m ++CONFIG_NLS_CODEPAGE_850=m ++CONFIG_NLS_CODEPAGE_852=m ++CONFIG_NLS_CODEPAGE_855=m ++CONFIG_NLS_CODEPAGE_857=m ++CONFIG_NLS_CODEPAGE_860=m ++CONFIG_NLS_CODEPAGE_861=m ++CONFIG_NLS_CODEPAGE_862=m ++CONFIG_NLS_CODEPAGE_863=m ++CONFIG_NLS_CODEPAGE_864=m ++CONFIG_NLS_CODEPAGE_865=m ++CONFIG_NLS_CODEPAGE_866=m ++CONFIG_NLS_CODEPAGE_869=m ++CONFIG_NLS_CODEPAGE_936=m ++CONFIG_NLS_CODEPAGE_950=m ++CONFIG_NLS_CODEPAGE_932=m ++CONFIG_NLS_CODEPAGE_949=m ++CONFIG_NLS_CODEPAGE_874=m ++CONFIG_NLS_ISO8859_8=m ++CONFIG_NLS_CODEPAGE_1250=m ++CONFIG_NLS_CODEPAGE_1251=m ++CONFIG_NLS_ASCII=y ++CONFIG_NLS_ISO8859_1=m ++CONFIG_NLS_ISO8859_2=m ++CONFIG_NLS_ISO8859_3=m ++CONFIG_NLS_ISO8859_4=m ++CONFIG_NLS_ISO8859_5=m ++CONFIG_NLS_ISO8859_6=m ++CONFIG_NLS_ISO8859_7=m ++CONFIG_NLS_ISO8859_9=m ++CONFIG_NLS_ISO8859_13=m ++CONFIG_NLS_ISO8859_14=m ++CONFIG_NLS_ISO8859_15=m ++CONFIG_NLS_KOI8_R=m ++CONFIG_NLS_KOI8_U=m ++CONFIG_NLS_UTF8=m ++CONFIG_PRINTK_TIME=y ++CONFIG_DETECT_HUNG_TASK=y ++CONFIG_TIMER_STATS=y ++CONFIG_DEBUG_STACK_USAGE=y ++CONFIG_DEBUG_INFO=y ++CONFIG_DEBUG_MEMORY_INIT=y ++CONFIG_BOOT_PRINTK_DELAY=y ++CONFIG_LATENCYTOP=y ++CONFIG_SYSCTL_SYSCALL_CHECK=y ++CONFIG_IRQSOFF_TRACER=y ++CONFIG_SCHED_TRACER=y ++CONFIG_STACK_TRACER=y ++CONFIG_BLK_DEV_IO_TRACE=y ++CONFIG_FUNCTION_PROFILER=y ++CONFIG_KGDB=y ++CONFIG_KGDB_KDB=y ++CONFIG_KDB_KEYBOARD=y ++CONFIG_STRICT_DEVMEM=y ++CONFIG_CRYPTO_AUTHENC=m ++CONFIG_CRYPTO_SEQIV=m ++CONFIG_CRYPTO_CBC=y ++CONFIG_CRYPTO_HMAC=y ++CONFIG_CRYPTO_XCBC=m ++CONFIG_CRYPTO_MD5=y ++CONFIG_CRYPTO_SHA1=y ++CONFIG_CRYPTO_SHA256=m ++CONFIG_CRYPTO_SHA512=m ++CONFIG_CRYPTO_TGR192=m ++CONFIG_CRYPTO_WP512=m ++CONFIG_CRYPTO_CAST5=m ++CONFIG_CRYPTO_DES=y ++CONFIG_CRYPTO_DEFLATE=m ++# CONFIG_CRYPTO_ANSI_CPRNG is not set ++# CONFIG_CRYPTO_HW is not set ++CONFIG_CRC_ITU_T=y ++CONFIG_LIBCRC32C=y +--- a/arch/arm/mach-bcm2708/Kconfig ++++ b/arch/arm/mach-bcm2708/Kconfig +@@ -22,4 +22,11 @@ config BCM2708_VCMEM + help + Helper for videocore memory access and total size allocation. + ++config BCM2708_NOL2CACHE ++ bool "Videocore L2 cache disable" ++ depends on MACH_BCM2708 ++ default n ++ help ++ Do not allow ARM to use GPU's L2 cache. Requires disable_l2cache in config.txt. ++ + endmenu +--- a/arch/arm/mach-bcm2708/bcm2708.c ++++ b/arch/arm/mach-bcm2708/bcm2708.c +@@ -29,6 +29,7 @@ + #include <linux/clockchips.h> + #include <linux/cnt32_to_63.h> + #include <linux/io.h> ++#include <linux/module.h> + + #include <linux/version.h> + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38) +@@ -68,6 +69,9 @@ + */ + #define DMA_MASK_BITS_COMMON 32 + ++/* command line parameters */ ++static unsigned boardrev, serial; ++ + static void __init bcm2708_init_led(void); + + void __init bcm2708_init_irq(void) +@@ -77,58 +81,57 @@ void __init bcm2708_init_irq(void) + + static struct map_desc bcm2708_io_desc[] __initdata = { + { +- .virtual = IO_ADDRESS(ARMCTRL_BASE), +- .pfn = __phys_to_pfn(ARMCTRL_BASE), +- .length = SZ_4K, +- .type = MT_DEVICE +- }, { +- .virtual = IO_ADDRESS(UART0_BASE), +- .pfn = __phys_to_pfn(UART0_BASE), +- .length = SZ_4K, +- .type = MT_DEVICE +- }, { +- .virtual = IO_ADDRESS(UART1_BASE), +- .pfn = __phys_to_pfn(UART1_BASE), +- .length = SZ_4K, +- .type = MT_DEVICE +- }, { +-#ifdef CONFIG_MMC_BCM2708 /* broadcom legacy SD */ +- .virtual = IO_ADDRESS(MMCI0_BASE), +- .pfn = __phys_to_pfn(MMCI0_BASE), +- .length = SZ_4K, +- .type = MT_DEVICE +- }, { +-#endif +- .virtual = IO_ADDRESS(DMA_BASE), +- .pfn = __phys_to_pfn(DMA_BASE), +- .length = SZ_4K, +- .type = MT_DEVICE +- }, { +- .virtual = IO_ADDRESS(MCORE_BASE), +- .pfn = __phys_to_pfn(MCORE_BASE), +- .length = SZ_4K, +- .type = MT_DEVICE +- }, { +- .virtual = IO_ADDRESS(ST_BASE), +- .pfn = __phys_to_pfn(ST_BASE), +- .length = SZ_4K, +- .type = MT_DEVICE +- }, { +- .virtual = IO_ADDRESS(USB_BASE), +- .pfn = __phys_to_pfn(USB_BASE), +- .length = SZ_128K, +- .type = MT_DEVICE +- }, { +- .virtual = IO_ADDRESS(PM_BASE), +- .pfn = __phys_to_pfn(PM_BASE), +- .length = SZ_4K, +- .type = MT_DEVICE +- }, { +- .virtual = IO_ADDRESS(GPIO_BASE), +- .pfn = __phys_to_pfn(GPIO_BASE), +- .length = SZ_4K, +- .type = MT_DEVICE +- } ++ .virtual = IO_ADDRESS(ARMCTRL_BASE), ++ .pfn = __phys_to_pfn(ARMCTRL_BASE), ++ .length = SZ_4K, ++ .type = MT_DEVICE}, ++ { ++ .virtual = IO_ADDRESS(UART0_BASE), ++ .pfn = __phys_to_pfn(UART0_BASE), ++ .length = SZ_4K, ++ .type = MT_DEVICE}, ++ { ++ .virtual = IO_ADDRESS(UART1_BASE), ++ .pfn = __phys_to_pfn(UART1_BASE), ++ .length = SZ_4K, ++ .type = MT_DEVICE}, ++#ifdef CONFIG_MMC_BCM2708 /* broadcom legacy SD */ ++ { ++ .virtual = IO_ADDRESS(MMCI0_BASE), ++ .pfn = __phys_to_pfn(MMCI0_BASE), ++ .length = SZ_4K, ++ .type = MT_DEVICE}, ++#endif ++ { ++ .virtual = IO_ADDRESS(DMA_BASE), ++ .pfn = __phys_to_pfn(DMA_BASE), ++ .length = SZ_4K, ++ .type = MT_DEVICE}, ++ { ++ .virtual = IO_ADDRESS(MCORE_BASE), ++ .pfn = __phys_to_pfn(MCORE_BASE), ++ .length = SZ_4K, ++ .type = MT_DEVICE}, ++ { ++ .virtual = IO_ADDRESS(ST_BASE), ++ .pfn = __phys_to_pfn(ST_BASE), ++ .length = SZ_4K, ++ .type = MT_DEVICE}, ++ { ++ .virtual = IO_ADDRESS(USB_BASE), ++ .pfn = __phys_to_pfn(USB_BASE), ++ .length = SZ_128K, ++ .type = MT_DEVICE}, ++ { ++ .virtual = IO_ADDRESS(PM_BASE), ++ .pfn = __phys_to_pfn(PM_BASE), ++ .length = SZ_4K, ++ .type = MT_DEVICE}, ++ { ++ .virtual = IO_ADDRESS(GPIO_BASE), ++ .pfn = __phys_to_pfn(GPIO_BASE), ++ .length = SZ_4K, ++ .type = MT_DEVICE} + }; + + void __init bcm2708_map_io(void) +@@ -136,74 +139,91 @@ void __init bcm2708_map_io(void) + iotable_init(bcm2708_io_desc, ARRAY_SIZE(bcm2708_io_desc)); + } + +-unsigned long frc_clock_ticks32(void) ++// The STC is a free running counter that increments at the rate of 1MHz ++#define STC_FREQ_HZ 1000000 ++ ++static cycle_t stc_read_cycles(struct clocksource *cs) + { + /* STC: a free running counter that increments at the rate of 1MHz */ +- return readl(__io_address(ST_BASE+0x04)); ++ return (cycle_t) readl(__io_address(ST_BASE + 0x04)); + } + +-unsigned long long frc_clock_ticks63(void) ++static struct clocksource clocksource_stc = { ++ .name = "stc", ++ .rating = 300, ++ .read = stc_read_cycles, ++ .mask = CLOCKSOURCE_MASK(32), ++ .flags = CLOCK_SOURCE_IS_CONTINUOUS, ++}; ++ ++unsigned long frc_clock_ticks32(void) + { +- unsigned long t = frc_clock_ticks32(); +- /* For cnt32_to_63 to work correctly we MUST call this routine +- * at least once every half-32-bit-wraparound period - that's once +- * every 35minutes or so - using it in sched_clock() should ensure this +- */ +- return cnt32_to_63(t); ++ return (unsigned long)stc_read_cycles(&clocksource_stc); ++} ++ ++static void __init bcm2708_clocksource_init(void) ++{ ++ // calculate .shift and .mult values and register clocksource ++ if (clocksource_register_hz(&clocksource_stc, STC_FREQ_HZ)) { ++ printk(KERN_ERR "timer: failed to initialize clock " ++ "source %s\n", clocksource_stc.name); ++ } + } + + unsigned long long sched_clock(void) + { +- return 1000ull * frc_clock_ticks63(); ++ return clocksource_cyc2ns(clocksource_stc.read(&clocksource_stc), ++ clocksource_stc.mult, clocksource_stc.shift); + } + + /* + * These are fixed clocks. + */ + static struct clk ref24_clk = { +- .rate = 3000000, /* The UART is clocked at 3MHz via APB_CLK */ ++ .rate = 3000000, /* The UART is clocked at 3MHz via APB_CLK */ + }; ++ + static struct clk osc_clk = { + #ifdef CONFIG_ARCH_BCM2708_CHIPIT +- .rate = 27000000, ++ .rate = 27000000, + #else +- .rate = 500000000, /* ARM clock is set from the VideoCore booter */ ++ .rate = 500000000, /* ARM clock is set from the VideoCore booter */ + #endif + }; ++ + /* warning - the USB needs a clock > 34MHz */ + + #ifdef CONFIG_MMC_BCM2708 + static struct clk sdhost_clk = { + #ifdef CONFIG_ARCH_BCM2708_CHIPIT +- .rate = 4000000, /* 4MHz */ ++ .rate = 4000000, /* 4MHz */ + #else +- .rate = 250000000, /* 250MHz */ ++ .rate = 250000000, /* 250MHz */ + #endif + }; + #endif + + static struct clk_lookup lookups[] = { +- { /* UART0 */ +- .dev_id = "dev:f1", +- .clk = &ref24_clk, +- }, +- { /* USB */ +- .dev_id = "bcm2708_usb", +- .clk = &osc_clk, ++ { /* UART0 */ ++ .dev_id = "dev:f1", ++ .clk = &ref24_clk, ++ }, ++ { /* USB */ ++ .dev_id = "bcm2708_usb", ++ .clk = &osc_clk, + #ifdef CONFIG_MMC_BCM2708 +- }, +- { /* MCI */ +- .dev_id = "bcm2708_mci.0", +- .clk = &sdhost_clk, ++ }, ++ { /* MCI */ ++ .dev_id = "bcm2708_mci.0", ++ .clk = &sdhost_clk, + #endif +- } ++ } + }; + +- + #define UART0_IRQ { IRQ_UART, NO_IRQ } + #define UART0_DMA { 15, 14 } + +-AMBA_DEVICE(uart0, "dev:f1", UART0, NULL); ++AMBA_DEVICE(uart0, "dev:f1", UART0, NULL); + + static struct amba_device *amba_devs[] __initdata = { + &uart0_device, +@@ -211,262 +231,232 @@ static struct amba_device *amba_devs[] _ + + static struct resource bcm2708_dmaman_resources[] = { + { +- .start = DMA_BASE, +- .end = DMA_BASE + SZ_4K - 1, +- .flags = IORESOURCE_MEM, +- } ++ .start = DMA_BASE, ++ .end = DMA_BASE + SZ_4K - 1, ++ .flags = IORESOURCE_MEM, ++ } + }; + + static struct platform_device bcm2708_dmaman_device = { +- .name = BCM_DMAMAN_DRIVER_NAME, +- .id = 0, /* first bcm2708_dma */ +- .resource = bcm2708_dmaman_resources, +- .num_resources = ARRAY_SIZE(bcm2708_dmaman_resources), ++ .name = BCM_DMAMAN_DRIVER_NAME, ++ .id = 0, /* first bcm2708_dma */ ++ .resource = bcm2708_dmaman_resources, ++ .num_resources = ARRAY_SIZE(bcm2708_dmaman_resources), + }; + + #ifdef CONFIG_MMC_BCM2708 + static struct resource bcm2708_mci_resources[] = { + { +- .start = MMCI0_BASE, +- .end = MMCI0_BASE + SZ_4K - 1, +- .flags = IORESOURCE_MEM, +- }, { +- .start = IRQ_SDIO, +- .end = IRQ_SDIO, +- .flags = IORESOURCE_IRQ, +- } ++ .start = MMCI0_BASE, ++ .end = MMCI0_BASE + SZ_4K - 1, ++ .flags = IORESOURCE_MEM, ++ }, ++ { ++ .start = IRQ_SDIO, ++ .end = IRQ_SDIO, ++ .flags = IORESOURCE_IRQ, ++ } + }; + +- + static struct platform_device bcm2708_mci_device = { +- .name = "bcm2708_mci", +- .id = 0, /* first bcm2708_mci */ +- .resource = bcm2708_mci_resources, +- .num_resources = ARRAY_SIZE(bcm2708_mci_resources), +- .dev = { +- .coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON), +- }, ++ .name = "bcm2708_mci", ++ .id = 0, /* first bcm2708_mci */ ++ .resource = bcm2708_mci_resources, ++ .num_resources = ARRAY_SIZE(bcm2708_mci_resources), ++ .dev = { ++ .coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON), ++ }, + }; + #endif /* CONFIG_MMC_BCM2708 */ + +- + static u64 fb_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); + + static struct platform_device bcm2708_fb_device = { +- .name = "bcm2708_fb", +- .id = -1, /* only one bcm2708_fb */ +- .resource = NULL, +- .num_resources = 0, +- .dev = { +- .dma_mask = &fb_dmamask, +- .coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON), +- }, ++ .name = "bcm2708_fb", ++ .id = -1, /* only one bcm2708_fb */ ++ .resource = NULL, ++ .num_resources = 0, ++ .dev = { ++ .dma_mask = &fb_dmamask, ++ .coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON), ++ }, + }; + + static struct plat_serial8250_port bcm2708_uart1_platform_data[] = { + { +- .mapbase = UART1_BASE + 0x40, +- .irq = IRQ_AUX, +- .uartclk = 125000000, +- .regshift = 2, +- .iotype = UPIO_MEM, +- .flags = UPF_FIXED_TYPE | UPF_IOREMAP | UPF_SKIP_TEST, +- .type = PORT_8250, +- }, +- { }, ++ .mapbase = UART1_BASE + 0x40, ++ .irq = IRQ_AUX, ++ .uartclk = 125000000, ++ .regshift = 2, ++ .iotype = UPIO_MEM, ++ .flags = UPF_FIXED_TYPE | UPF_IOREMAP | UPF_SKIP_TEST, ++ .type = PORT_8250, ++ }, ++ {}, + }; + + static struct platform_device bcm2708_uart1_device = { +- .name = "serial8250", +- .id = PLAT8250_DEV_PLATFORM, +- .dev = { +- .platform_data = bcm2708_uart1_platform_data, +- }, ++ .name = "serial8250", ++ .id = PLAT8250_DEV_PLATFORM, ++ .dev = { ++ .platform_data = bcm2708_uart1_platform_data, ++ }, + }; + + static struct resource bcm2708_usb_resources[] = { +- [0] = { +- .start = USB_BASE, +- .end = USB_BASE + SZ_128K - 1, +- .flags = IORESOURCE_MEM, +- }, +- [1] = { +- .start = IRQ_USB, +- .end = IRQ_USB, +- .flags = IORESOURCE_IRQ, +- }, ++ [0] = { ++ .start = USB_BASE, ++ .end = USB_BASE + SZ_128K - 1, ++ .flags = IORESOURCE_MEM, ++ }, ++ [1] = { ++ .start = IRQ_USB, ++ .end = IRQ_USB, ++ .flags = IORESOURCE_IRQ, ++ }, + }; + + static u64 usb_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); + + static struct platform_device bcm2708_usb_device = { +- .name = "bcm2708_usb", +- .id = -1, /* only one bcm2708_usb */ +- .resource = bcm2708_usb_resources, +- .num_resources = ARRAY_SIZE(bcm2708_usb_resources), +- .dev = { +- .dma_mask = &usb_dmamask, +- .coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON), +- }, ++ .name = "bcm2708_usb", ++ .id = -1, /* only one bcm2708_usb */ ++ .resource = bcm2708_usb_resources, ++ .num_resources = ARRAY_SIZE(bcm2708_usb_resources), ++ .dev = { ++ .dma_mask = &usb_dmamask, ++ .coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON), ++ }, + }; + + static struct resource bcm2708_vcio_resources[] = { +- [0] = { /* mailbox/semaphore/doorbell access */ +- .start = MCORE_BASE, +- .end = MCORE_BASE + SZ_4K - 1, +- .flags = IORESOURCE_MEM, +- }, ++ [0] = { /* mailbox/semaphore/doorbell access */ ++ .start = MCORE_BASE, ++ .end = MCORE_BASE + SZ_4K - 1, ++ .flags = IORESOURCE_MEM, ++ }, + }; + + static u64 vcio_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); + + static struct platform_device bcm2708_vcio_device = { +- .name = BCM_VCIO_DRIVER_NAME, +- .id = -1, /* only one VideoCore I/O area */ +- .resource = bcm2708_vcio_resources, +- .num_resources = ARRAY_SIZE(bcm2708_vcio_resources), +- .dev = { +- .dma_mask = &vcio_dmamask, +- .coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON), +- }, ++ .name = BCM_VCIO_DRIVER_NAME, ++ .id = -1, /* only one VideoCore I/O area */ ++ .resource = bcm2708_vcio_resources, ++ .num_resources = ARRAY_SIZE(bcm2708_vcio_resources), ++ .dev = { ++ .dma_mask = &vcio_dmamask, ++ .coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON), ++ }, + }; + + #ifdef CONFIG_BCM2708_GPIO + #define BCM_GPIO_DRIVER_NAME "bcm2708_gpio" + + static struct resource bcm2708_gpio_resources[] = { +- [0] = { /* general purpose I/O */ +- .start = GPIO_BASE, +- .end = GPIO_BASE + SZ_4K - 1, +- .flags = IORESOURCE_MEM, +- }, ++ [0] = { /* general purpose I/O */ ++ .start = GPIO_BASE, ++ .end = GPIO_BASE + SZ_4K - 1, ++ .flags = IORESOURCE_MEM, ++ }, + }; + + static u64 gpio_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); + + static struct platform_device bcm2708_gpio_device = { +- .name = BCM_GPIO_DRIVER_NAME, +- .id = -1, /* only one VideoCore I/O area */ +- .resource = bcm2708_gpio_resources, +- .num_resources = ARRAY_SIZE(bcm2708_gpio_resources), +- .dev = { +- .dma_mask = &gpio_dmamask, +- .coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON), +- }, +-}; +-#endif +- +-#ifdef CONFIG_BCM2708_BUTTONS +-static struct resource bcm2708_vcbuttons_resources[] = { +-}; +- +-static u64 vcbuttons_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); +- +-static struct platform_device bcm2708_vcbuttons_device = { +- .name = "bcm2708_vcbuttons", +- .id = -1, /* only one VideoCore I/O area */ +- .resource = bcm2708_vcbuttons_resources, +- .num_resources = ARRAY_SIZE(bcm2708_vcbuttons_resources), +- .dev = { +- .dma_mask = &vcbuttons_dmamask, +- .coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON), +- }, +-}; +-#endif +- +-#ifdef CONFIG_BCM2708_TOUCHSCREEN +-static struct resource bcm2708_vctouch_resources[] = { +-}; +- +-static u64 vctouch_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); +- +-static struct platform_device bcm2708_vctouch_device = { +- .name = "bcm2708_vctouch", +- .id = -1, /* only one VideoCore I/O area */ +- .resource = bcm2708_vctouch_resources, +- .num_resources = ARRAY_SIZE(bcm2708_vctouch_resources), +- .dev = { +- .dma_mask = &vctouch_dmamask, +- .coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON), +- }, ++ .name = BCM_GPIO_DRIVER_NAME, ++ .id = -1, /* only one VideoCore I/O area */ ++ .resource = bcm2708_gpio_resources, ++ .num_resources = ARRAY_SIZE(bcm2708_gpio_resources), ++ .dev = { ++ .dma_mask = &gpio_dmamask, ++ .coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON), ++ }, + }; + #endif + + static struct resource bcm2708_systemtimer_resources[] = { +- [0] = { /* system timer access */ +- .start = ST_BASE, +- .end = ST_BASE + SZ_4K - 1, +- .flags = IORESOURCE_MEM, +- }, { +- .start = IRQ_TIMER3, +- .end = IRQ_TIMER3, +- .flags = IORESOURCE_IRQ, +- } +- ++ [0] = { /* system timer access */ ++ .start = ST_BASE, ++ .end = ST_BASE + SZ_4K - 1, ++ .flags = IORESOURCE_MEM, ++ }, ++ { ++ .start = IRQ_TIMER3, ++ .end = IRQ_TIMER3, ++ .flags = IORESOURCE_IRQ, ++ } + + }; + + static u64 systemtimer_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); + + static struct platform_device bcm2708_systemtimer_device = { +- .name = "bcm2708_systemtimer", +- .id = -1, /* only one VideoCore I/O area */ +- .resource = bcm2708_systemtimer_resources, +- .num_resources = ARRAY_SIZE(bcm2708_systemtimer_resources), +- .dev = { +- .dma_mask = &systemtimer_dmamask, +- .coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON), +- }, ++ .name = "bcm2708_systemtimer", ++ .id = -1, /* only one VideoCore I/O area */ ++ .resource = bcm2708_systemtimer_resources, ++ .num_resources = ARRAY_SIZE(bcm2708_systemtimer_resources), ++ .dev = { ++ .dma_mask = &systemtimer_dmamask, ++ .coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON), ++ }, + }; + +-#ifdef CONFIG_MMC_SDHCI_BCM2708 /* Arasan emmc SD */ ++#ifdef CONFIG_MMC_SDHCI_BCM2708 /* Arasan emmc SD */ + static struct resource bcm2708_emmc_resources[] = { + [0] = { +- .start = EMMC_BASE, +- .end = EMMC_BASE + SZ_256 - 1, /* we only need this area */ +- /* the memory map actually makes SZ_4K available */ +- .flags = IORESOURCE_MEM, +- }, ++ .start = EMMC_BASE, ++ .end = EMMC_BASE + SZ_256 - 1, /* we only need this area */ ++ /* the memory map actually makes SZ_4K available */ ++ .flags = IORESOURCE_MEM, ++ }, + [1] = { +- .start = IRQ_ARASANSDIO, +- .end = IRQ_ARASANSDIO, +- .flags = IORESOURCE_IRQ, +- }, ++ .start = IRQ_ARASANSDIO, ++ .end = IRQ_ARASANSDIO, ++ .flags = IORESOURCE_IRQ, ++ }, + }; + + static u64 bcm2708_emmc_dmamask = 0xffffffffUL; + + struct platform_device bcm2708_emmc_device = { +- .name = "bcm2708_sdhci", +- .id = 0, +- .num_resources = ARRAY_SIZE(bcm2708_emmc_resources), +- .resource = bcm2708_emmc_resources, +- .dev = { +- .dma_mask = &bcm2708_emmc_dmamask, +- .coherent_dma_mask = 0xffffffffUL +- }, ++ .name = "bcm2708_sdhci", ++ .id = 0, ++ .num_resources = ARRAY_SIZE(bcm2708_emmc_resources), ++ .resource = bcm2708_emmc_resources, ++ .dev = { ++ .dma_mask = &bcm2708_emmc_dmamask, ++ .coherent_dma_mask = 0xffffffffUL}, + }; + #endif /* CONFIG_MMC_SDHCI_BCM2708 */ + + static struct resource bcm2708_powerman_resources[] = { + [0] = { +- .start = PM_BASE, +- .end = PM_BASE + SZ_256 - 1, +- .flags = IORESOURCE_MEM, +- }, ++ .start = PM_BASE, ++ .end = PM_BASE + SZ_256 - 1, ++ .flags = IORESOURCE_MEM, ++ }, + }; + + static u64 powerman_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); + + struct platform_device bcm2708_powerman_device = { +- .name = "bcm2708_powerman", +- .id = 0, +- .num_resources = ARRAY_SIZE(bcm2708_powerman_resources), +- .resource = bcm2708_powerman_resources, +- .dev = { +- .dma_mask = &powerman_dmamask, +- .coherent_dma_mask = 0xffffffffUL +- }, ++ .name = "bcm2708_powerman", ++ .id = 0, ++ .num_resources = ARRAY_SIZE(bcm2708_powerman_resources), ++ .resource = bcm2708_powerman_resources, ++ .dev = { ++ .dma_mask = &powerman_dmamask, ++ .coherent_dma_mask = 0xffffffffUL}, ++}; ++ ++static struct platform_device bcm2708_alsa_devices[] = { ++ [0] = { ++ .name = "bcm2835_AUD0", ++ .id = 0, /* first audio device */ ++ .resource = 0, ++ .num_resources = 0, ++ }, + }; + + int __init bcm_register_device(struct platform_device *pdev) +@@ -500,30 +490,29 @@ void __init bcm2708_init(void) + bcm_register_device(&bcm2708_fb_device); + bcm_register_device(&bcm2708_usb_device); + bcm_register_device(&bcm2708_uart1_device); +-#ifdef CONFIG_BCM2708_BUTTONS +- bcm_register_device(&bcm2708_vcbuttons_device); +-#endif +-#ifdef CONFIG_BCM2708_TOUCHSCREEN +- bcm_register_device(&bcm2708_vctouch_device); +-#endif + bcm_register_device(&bcm2708_powerman_device); + #ifdef CONFIG_MMC_SDHCI_BCM2708 + bcm_register_device(&bcm2708_emmc_device); + #endif +- bcm2708_init_led(); ++ bcm2708_init_led(); ++ for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++) ++ bcm_register_device(&bcm2708_alsa_devices[i]); ++ + #ifdef CONFIG_BCM2708_VCMEM +-{ +- extern void vc_mem_connected_init(void); +- vc_mem_connected_init(); +-} ++ { ++ extern void vc_mem_connected_init(void); ++ vc_mem_connected_init(); ++ } + #endif + for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { + struct amba_device *d = amba_devs[i]; + amba_device_register(d, &iomem_resource); + } ++ system_rev = boardrev; ++ system_serial_low = serial; + } + +-#define TIMER_PERIOD 10000 /* HZ in microsecs */ ++#define TIMER_PERIOD 10000 /* HZ in microsecs */ + + static void timer_set_mode(enum clock_event_mode mode, + struct clock_event_device *clk) +@@ -532,37 +521,36 @@ static void timer_set_mode(enum clock_ev + + switch (mode) { + case CLOCK_EVT_MODE_PERIODIC: +- stc = readl(__io_address(ST_BASE+0x04)); +- writel(stc + TIMER_PERIOD, +- __io_address(ST_BASE+0x18));/* stc3 */ ++ stc = readl(__io_address(ST_BASE + 0x04)); ++ writel(stc + TIMER_PERIOD, __io_address(ST_BASE + 0x18)); /* stc3 */ + break; + case CLOCK_EVT_MODE_ONESHOT: + case CLOCK_EVT_MODE_UNUSED: + case CLOCK_EVT_MODE_SHUTDOWN: + default: + printk(KERN_ERR "timer_set_mode: unhandled mode:%d\n", +- (int)mode); ++ (int)mode); + break; + } + + } + +-static int timer_set_next_event(unsigned long evt, ++static int timer_set_next_event(unsigned long cycles, + struct clock_event_device *unused) + { + unsigned long stc; + +- stc = readl(__io_address(ST_BASE + 0x04)); +- writel(stc + TIMER_PERIOD, __io_address(ST_BASE+0x18)); /* stc3 */ ++ stc = readl(__io_address(ST_BASE + 0x04)); ++ writel(stc + cycles, __io_address(ST_BASE + 0x18)); /* stc3 */ + return 0; + } + +-static struct clock_event_device timer0_clockevent = { +- .name = "timer0", +- .shift = 32, +- .features = CLOCK_EVT_FEAT_ONESHOT, +- .set_mode = timer_set_mode, +- .set_next_event = timer_set_next_event, ++static struct clock_event_device timer0_clockevent = { ++ .name = "timer0", ++ .shift = 32, ++ .features = CLOCK_EVT_FEAT_ONESHOT, ++ .set_mode = timer_set_mode, ++ .set_next_event = timer_set_next_event, + }; + + /* +@@ -572,7 +560,7 @@ static irqreturn_t bcm2708_timer_interru + { + struct clock_event_device *evt = &timer0_clockevent; + +- writel(1<<3, __io_address(ST_BASE+0x00)); /* stcs clear timer int */ ++ writel(1 << 3, __io_address(ST_BASE + 0x00)); /* stcs clear timer int */ + + evt->event_handler(evt); + +@@ -580,9 +568,9 @@ static irqreturn_t bcm2708_timer_interru + } + + static struct irqaction bcm2708_timer_irq = { +- .name = "BCM2708 Timer Tick", +- .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, +- .handler = bcm2708_timer_interrupt, ++ .name = "BCM2708 Timer Tick", ++ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, ++ .handler = bcm2708_timer_interrupt, + }; + + /* +@@ -590,6 +578,9 @@ static struct irqaction bcm2708_timer_ir + */ + static void __init bcm2708_timer_init(void) + { ++ /* init high res timer */ ++ bcm2708_clocksource_init(); ++ + /* + * Initialise to a known state (all timers off) + */ +@@ -600,18 +591,18 @@ static void __init bcm2708_timer_init(vo + setup_irq(IRQ_TIMER3, &bcm2708_timer_irq); + + timer0_clockevent.mult = +- div_sc(1000000, NSEC_PER_SEC, timer0_clockevent.shift); ++ div_sc(STC_FREQ_HZ, NSEC_PER_SEC, timer0_clockevent.shift); + timer0_clockevent.max_delta_ns = +- clockevent_delta2ns(0xffffffff, &timer0_clockevent); ++ clockevent_delta2ns(0xffffffff, &timer0_clockevent); + timer0_clockevent.min_delta_ns = +- clockevent_delta2ns(0xf, &timer0_clockevent); ++ clockevent_delta2ns(0xf, &timer0_clockevent); + + timer0_clockevent.cpumask = cpumask_of(0); + clockevents_register_device(&timer0_clockevent); + } + + struct sys_timer bcm2708_timer = { +- .init = bcm2708_timer_init, ++ .init = bcm2708_timer_init, + }; + + #if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE) +@@ -619,24 +610,24 @@ struct sys_timer bcm2708_timer = { + + static struct gpio_led bcm2708_leds[] = { + [0] = { +- .gpio = 16, +- .name = "led0", +- .default_trigger = "mmc0", +- .active_low = 0, +- }, ++ .gpio = 16, ++ .name = "led0", ++ .default_trigger = "mmc0", ++ .active_low = 1, ++ }, + }; + + static struct gpio_led_platform_data bcm2708_led_pdata = { +- .num_leds = ARRAY_SIZE(bcm2708_leds), +- .leds = bcm2708_leds, ++ .num_leds = ARRAY_SIZE(bcm2708_leds), ++ .leds = bcm2708_leds, + }; + + static struct platform_device bcm2708_led_device = { +- .name = "leds-gpio", +- .id = -1, +- .dev = { +- .platform_data = &bcm2708_led_pdata, +- }, ++ .name = "leds-gpio", ++ .id = -1, ++ .dev = { ++ .platform_data = &bcm2708_led_pdata, ++ }, + }; + + static void __init bcm2708_init_led(void) +@@ -644,14 +635,14 @@ static void __init bcm2708_init_led(void + platform_device_register(&bcm2708_led_device); + } + #else +-static inline void bcm2708_init_led(void) {} ++static inline void bcm2708_init_led(void) ++{ ++} + #endif + +- + MACHINE_START(BCM2708, "BCM2708") +- /* Maintainer: Broadcom Europe Ltd. */ +- .map_io = bcm2708_map_io, +- .init_irq = bcm2708_init_irq, +- .timer = &bcm2708_timer, +- .init_machine = bcm2708_init, +-MACHINE_END ++ /* Maintainer: Broadcom Europe Ltd. */ ++ .map_io = bcm2708_map_io,.init_irq = bcm2708_init_irq,.timer = ++ &bcm2708_timer,.init_machine = ++ bcm2708_init, MACHINE_END module_param(boardrev, uint, 0644); ++module_param(serial, uint, 0644); +--- a/arch/arm/mach-bcm2708/include/mach/memory.h ++++ b/arch/arm/mach-bcm2708/include/mach/memory.h +@@ -32,9 +32,14 @@ + /* + * Physical DRAM offset. + */ +-#define PHYS_OFFSET UL(0x00000000) ++#define PLAT_PHYS_OFFSET UL(0x00000000) + #define ARMMEM_OFFSET UL(0x00000000) /* offset in VC of ARM memory */ +-#define _REAL_BUS_OFFSET UL(0xC0000000) /* don't use L1 or L2 caches */ ++ ++#ifdef CONFIG_BCM2708_NOL2CACHE ++ #define _REAL_BUS_OFFSET UL(0xC0000000) /* don't use L1 or L2 caches */ ++#else ++ #define _REAL_BUS_OFFSET UL(0x40000000) /* use L2 cache */ ++#endif + + /* We're using the memory at 64M in the VideoCore for Linux - this adjustment + * will provide the offset into this area as well as setting the bits that +@@ -46,8 +51,8 @@ + #define BUS_OFFSET (ARMMEM_OFFSET + _REAL_BUS_OFFSET) + #define __virt_to_bus(x) ((x) + (BUS_OFFSET - PAGE_OFFSET)) + #define __bus_to_virt(x) ((x) - (BUS_OFFSET - PAGE_OFFSET)) +-#define __pfn_to_bus(x) (__pfn_to_phys(x) + (BUS_OFFSET - PHYS_OFFSET)) +-#define __bus_to_pfn(x) __phys_to_pfn((x) - (BUS_OFFSET - PHYS_OFFSET)) ++#define __pfn_to_bus(x) (__pfn_to_phys(x) + (BUS_OFFSET - PLAT_PHYS_OFFSET)) ++#define __bus_to_pfn(x) __phys_to_pfn((x) - (BUS_OFFSET - PLAT_PHYS_OFFSET)) + + /* + * Consistent DMA area set to 2M. Framebuffer now allocated on host +--- a/arch/arm/mach-bcm2708/include/mach/vc_mem.h ++++ b/arch/arm/mach-bcm2708/include/mach/vc_mem.h +@@ -21,6 +21,7 @@ + + #define VC_MEM_IOC_MEM_PHYS_ADDR _IOR( VC_MEM_IOC_MAGIC, 0, unsigned long ) + #define VC_MEM_IOC_MEM_SIZE _IOR( VC_MEM_IOC_MAGIC, 1, unsigned int ) ++#define VC_MEM_IOC_MEM_BASE _IOR( VC_MEM_IOC_MAGIC, 2, unsigned int ) + + #if defined( __KERNEL__ ) + #define VC_MEM_TO_ARM_ADDR_MASK 0x3FFFFFFF +--- a/arch/arm/mach-bcm2708/power.c ++++ b/arch/arm/mach-bcm2708/power.c +@@ -14,6 +14,7 @@ + #include <linux/module.h> + #include <linux/semaphore.h> + #include <linux/bug.h> ++#include <linux/delay.h> + #include <mach/power.h> + #include <mach/vcio.h> + #include <mach/arm_power.h> +@@ -96,7 +97,6 @@ int bcm_power_request(BCM_POWER_HANDLE_T + bcm_mailbox_write(MBOX_CHAN_POWER, + global_request << 4); + +- /* Wait for a response during power-up */ + if (global_request & ~g_state.global_request) { + rc = bcm_mailbox_read(MBOX_CHAN_POWER, + &actual); +@@ -111,14 +111,14 @@ int bcm_power_request(BCM_POWER_HANDLE_T + + if (rc == 0) { + if (actual != global_request) { +- printk(KERN_ERR +- "%s: prev global %x, new global %x, actual %x, request %x, others_request %x\n", ++ printk(KERN_INFO ++ "%s: Fail: prev global %x, new global %x, actual %x request %x, others_request %x\n", + __func__, + g_state.global_request, + global_request, actual, request, others_request); + /* A failure */ +- BUG_ON((others_request & actual) +- != others_request); ++ // BUG_ON((others_request & actual) ++ // != others_request); + request &= actual; + rc = -EIO; + } +@@ -161,6 +161,7 @@ static int __init bcm_power_init(void) + int i; + + printk(KERN_INFO "bcm_power: Broadcom power driver\n"); ++ bcm_mailbox_write(MBOX_CHAN_POWER, 0); + + for (i = 0; i < BCM_POWER_MAXCLIENTS; i++) + g_state.client_request[i] = BCM_POWER_NOCLIENT; +--- a/arch/arm/mach-bcm2708/vc_mem.c ++++ b/arch/arm/mach-bcm2708/vc_mem.c +@@ -85,9 +85,11 @@ unsigned long mm_vc_mem_phys_addr = MM_A + #endif + + unsigned int mm_vc_mem_size = 0; ++unsigned int mm_vc_mem_base = 0; + + EXPORT_SYMBOL(mm_vc_mem_phys_addr); + EXPORT_SYMBOL(mm_vc_mem_size); ++EXPORT_SYMBOL(mm_vc_mem_base); + + /**************************************************************************** + * +@@ -132,36 +134,19 @@ vc_mem_release(struct inode *inode, stru + static void + vc_mem_get_size(void) + { +-#ifdef CONFIG_ARCH_BCM2708 + mm_vc_mem_size = 256 * 1024 * 1024; // Static for now +-#else +- CHAL_IPC_HANDLE ipc_handle; +- uint32_t wakeup_register; +- +- // Get the videocore memory size from the IPC mailbox if not yet +- // assigned. +- if (mm_vc_mem_size == 0) { +- ipc_handle = chal_ipc_config(NULL); +- if (ipc_handle == NULL) { +- LOG_ERR("%s: failed to get IPC handlle", __func__); +- return; +- } ++} + +- chal_ipc_query_wakeup_vc(ipc_handle, &wakeup_register); +- if ((wakeup_register & ~1) == 0) { +- LOG_DBG("%s: videocore not yet loaded, skipping...", +- __func__); +- } else { +- if (chal_ipc_read_mailbox(ipc_handle, +- IPC_MAILBOX_ID_0, +- &mm_vc_mem_size) != +- BCM_SUCCESS) { +- LOG_ERR("%s: failed to read from IPC mailbox", +- __func__); +- } +- } +- } +-#endif ++/**************************************************************************** ++* ++* vc_mem_get_base ++* ++***************************************************************************/ ++ ++static void ++vc_mem_get_base(void) ++{ ++ mm_vc_mem_base = 128 * 1024 * 1024; // Static for now + } + + /**************************************************************************** +@@ -220,6 +205,20 @@ vc_mem_ioctl(struct file *file, unsigned + rc = -EFAULT; + } + break; ++ } ++ case VC_MEM_IOC_MEM_BASE: ++ { ++ // Get the videocore memory base ++ vc_mem_get_base(); ++ ++ LOG_DBG("%s: VC_MEM_IOC_MEM_BASE=%u", __func__, ++ mm_vc_mem_base); ++ ++ if (copy_to_user((void *) arg, &mm_vc_mem_base, ++ sizeof (mm_vc_mem_base)) != 0) { ++ rc = -EFAULT; ++ } ++ break; + } + default: + { +--- a/arch/arm/mach-bcm2708/vcio.c ++++ b/arch/arm/mach-bcm2708/vcio.c +@@ -119,8 +119,7 @@ static int mbox_read(struct vc_mailbox * + if (mbox->magic != MBOX_MAGIC) + rc = -EINVAL; + else { +- if (mbox->msg[chan] || +- (down_interruptible(&mbox->sema[chan]) == 0)) { ++ if (down_interruptible(&mbox->sema[chan]) == 0) { + *data28 = MBOX_DATA28(mbox->msg[chan]); + mbox->msg[chan] = 0; + rc = 0; +--- a/drivers/misc/vc04_services/Makefile ++++ b/drivers/misc/vc04_services/Makefile +@@ -2,6 +2,8 @@ obj-$(CONFIG_BCM2708_VCHIQ) += vchiq.o + + vchiq-objs := \ + interface/vchiq_arm/vchiq_core.o \ ++ interface/vchiq_arm/vchiq_shim.o \ ++ interface/vchiq_arm/vchiq_util.o \ + interface/vchiq_arm/vchiq_arm.o \ + interface/vchiq_arm/vchiq_kern_lib.o \ + interface/vchiq_arm/vchiq_2835_arm.o \ +@@ -13,7 +15,7 @@ vchiq-objs := \ + interface/vcos/generic/vcos_mem_from_malloc.o \ + interface/vcos/generic/vcos_cmd.o + +-EXTRA_CFLAGS += -DVCOS_VERIFY_BKPTS=1 -Idrivers/misc/vc04_services -Idrivers/misc/vc04_services/interface/vcos/linuxkernel ++EXTRA_CFLAGS += -DVCOS_VERIFY_BKPTS=1 -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -Idrivers/misc/vc04_services -Idrivers/misc/vc04_services/interface/vcos/linuxkernel + + + +--- /dev/null ++++ b/drivers/misc/vc04_services/interface/vchi/connections/connection.h +@@ -0,0 +1,309 @@ ++/* ++ * Copyright (c) 2010-2011 Broadcom Corporation. All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++#ifndef CONNECTION_H_ ++#define CONNECTION_H_ ++ ++#include "interface/vchi/vchi_cfg_internal.h" ++#include "interface/vchi/vchi_common.h" ++#include "interface/vchi/message_drivers/message.h" ++ ++/****************************************************************************** ++ Global defs ++ *****************************************************************************/ ++ ++// Opaque handle for a connection / service pair ++typedef struct opaque_vchi_connection_connected_service_handle_t *VCHI_CONNECTION_SERVICE_HANDLE_T; ++ ++// opaque handle to the connection state information ++typedef struct opaque_vchi_connection_info_t VCHI_CONNECTION_STATE_T; ++ ++typedef struct vchi_connection_t VCHI_CONNECTION_T; ++ ++ ++/****************************************************************************** ++ API ++ *****************************************************************************/ ++ ++// Routine to init a connection with a particular low level driver ++typedef VCHI_CONNECTION_STATE_T * (*VCHI_CONNECTION_INIT_T)( struct vchi_connection_t * connection, ++ const VCHI_MESSAGE_DRIVER_T * driver ); ++ ++// Routine to control CRC enabling at a connection level ++typedef int32_t (*VCHI_CONNECTION_CRC_CONTROL_T)( VCHI_CONNECTION_STATE_T *state_handle, ++ VCHI_CRC_CONTROL_T control ); ++ ++// Routine to create a service ++typedef int32_t (*VCHI_CONNECTION_SERVICE_CONNECT_T)( VCHI_CONNECTION_STATE_T *state_handle, ++ vcos_fourcc_t service_id, ++ uint32_t rx_fifo_size, ++ uint32_t tx_fifo_size, ++ int server, ++ VCHI_CALLBACK_T callback, ++ void *callback_param, ++ vcos_bool_t want_crc, ++ vcos_bool_t want_unaligned_bulk_rx, ++ vcos_bool_t want_unaligned_bulk_tx, ++ VCHI_CONNECTION_SERVICE_HANDLE_T *service_handle ); ++ ++// Routine to close a service ++typedef int32_t (*VCHI_CONNECTION_SERVICE_DISCONNECT_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service_handle ); ++ ++// Routine to queue a message ++typedef int32_t (*VCHI_CONNECTION_SERVICE_QUEUE_MESSAGE_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service_handle, ++ const void *data, ++ uint32_t data_size, ++ VCHI_FLAGS_T flags, ++ void *msg_handle ); ++ ++// scatter-gather (vector) message queueing ++typedef int32_t (*VCHI_CONNECTION_SERVICE_QUEUE_MESSAGEV_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service_handle, ++ VCHI_MSG_VECTOR_T *vector, ++ uint32_t count, ++ VCHI_FLAGS_T flags, ++ void *msg_handle ); ++ ++// Routine to dequeue a message ++typedef int32_t (*VCHI_CONNECTION_SERVICE_DEQUEUE_MESSAGE_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service_handle, ++ void *data, ++ uint32_t max_data_size_to_read, ++ uint32_t *actual_msg_size, ++ VCHI_FLAGS_T flags ); ++ ++// Routine to peek at a message ++typedef int32_t (*VCHI_CONNECTION_SERVICE_PEEK_MESSAGE_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service_handle, ++ void **data, ++ uint32_t *msg_size, ++ VCHI_FLAGS_T flags ); ++ ++// Routine to hold a message ++typedef int32_t (*VCHI_CONNECTION_SERVICE_HOLD_MESSAGE_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service_handle, ++ void **data, ++ uint32_t *msg_size, ++ VCHI_FLAGS_T flags, ++ void **message_handle ); ++ ++// Routine to initialise a received message iterator ++typedef int32_t (*VCHI_CONNECTION_SERVICE_LOOKAHEAD_MESSAGE_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service_handle, ++ VCHI_MSG_ITER_T *iter, ++ VCHI_FLAGS_T flags ); ++ ++// Routine to release a held message ++typedef int32_t (*VCHI_CONNECTION_HELD_MSG_RELEASE_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service_handle, ++ void *message_handle ); ++ ++// Routine to get info on a held message ++typedef int32_t (*VCHI_CONNECTION_HELD_MSG_INFO_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service_handle, ++ void *message_handle, ++ void **data, ++ int32_t *msg_size, ++ uint32_t *tx_timestamp, ++ uint32_t *rx_timestamp ); ++ ++// Routine to check whether the iterator has a next message ++typedef vcos_bool_t (*VCHI_CONNECTION_MSG_ITER_HAS_NEXT_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service, ++ const VCHI_MSG_ITER_T *iter ); ++ ++// Routine to advance the iterator ++typedef int32_t (*VCHI_CONNECTION_MSG_ITER_NEXT_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service, ++ VCHI_MSG_ITER_T *iter, ++ void **data, ++ uint32_t *msg_size ); ++ ++// Routine to remove the last message returned by the iterator ++typedef int32_t (*VCHI_CONNECTION_MSG_ITER_REMOVE_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service, ++ VCHI_MSG_ITER_T *iter ); ++ ++// Routine to hold the last message returned by the iterator ++typedef int32_t (*VCHI_CONNECTION_MSG_ITER_HOLD_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service, ++ VCHI_MSG_ITER_T *iter, ++ void **msg_handle ); ++ ++// Routine to transmit bulk data ++typedef int32_t (*VCHI_CONNECTION_BULK_QUEUE_TRANSMIT_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service_handle, ++ const void *data_src, ++ uint32_t data_size, ++ VCHI_FLAGS_T flags, ++ void *bulk_handle ); ++ ++// Routine to receive data ++typedef int32_t (*VCHI_CONNECTION_BULK_QUEUE_RECEIVE_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service_handle, ++ void *data_dst, ++ uint32_t data_size, ++ VCHI_FLAGS_T flags, ++ void *bulk_handle ); ++ ++// Routine to report if a server is available ++typedef int32_t (*VCHI_CONNECTION_SERVER_PRESENT)( VCHI_CONNECTION_STATE_T *state, vcos_fourcc_t service_id, int32_t peer_flags ); ++ ++// Routine to report the number of RX slots available ++typedef int (*VCHI_CONNECTION_RX_SLOTS_AVAILABLE)( const VCHI_CONNECTION_STATE_T *state ); ++ ++// Routine to report the RX slot size ++typedef uint32_t (*VCHI_CONNECTION_RX_SLOT_SIZE)( const VCHI_CONNECTION_STATE_T *state ); ++ ++// Callback to indicate that the other side has added a buffer to the rx bulk DMA FIFO ++typedef void (*VCHI_CONNECTION_RX_BULK_BUFFER_ADDED)(VCHI_CONNECTION_STATE_T *state, ++ vcos_fourcc_t service, ++ uint32_t length, ++ MESSAGE_TX_CHANNEL_T channel, ++ uint32_t channel_params, ++ uint32_t data_length, ++ uint32_t data_offset); ++ ++// Callback to inform a service that a Xon or Xoff message has been received ++typedef void (*VCHI_CONNECTION_FLOW_CONTROL)(VCHI_CONNECTION_STATE_T *state, vcos_fourcc_t service_id, int32_t xoff); ++ ++// Callback to inform a service that a server available reply message has been received ++typedef void (*VCHI_CONNECTION_SERVER_AVAILABLE_REPLY)(VCHI_CONNECTION_STATE_T *state, vcos_fourcc_t service_id, uint32_t flags); ++ ++// Callback to indicate that bulk auxiliary messages have arrived ++typedef void (*VCHI_CONNECTION_BULK_AUX_RECEIVED)(VCHI_CONNECTION_STATE_T *state); ++ ++// Callback to indicate that bulk auxiliary messages have arrived ++typedef void (*VCHI_CONNECTION_BULK_AUX_TRANSMITTED)(VCHI_CONNECTION_STATE_T *state, void *handle); ++ ++// Callback with all the connection info you require ++typedef void (*VCHI_CONNECTION_INFO)(VCHI_CONNECTION_STATE_T *state, uint32_t protocol_version, uint32_t slot_size, uint32_t num_slots, uint32_t min_bulk_size); ++ ++// Callback to inform of a disconnect ++typedef void (*VCHI_CONNECTION_DISCONNECT)(VCHI_CONNECTION_STATE_T *state, uint32_t flags); ++ ++// Callback to inform of a power control request ++typedef void (*VCHI_CONNECTION_POWER_CONTROL)(VCHI_CONNECTION_STATE_T *state, MESSAGE_TX_CHANNEL_T channel, vcos_bool_t enable); ++ ++// allocate memory suitably aligned for this connection ++typedef void * (*VCHI_BUFFER_ALLOCATE)(VCHI_CONNECTION_SERVICE_HANDLE_T service_handle, uint32_t * length); ++ ++// free memory allocated by buffer_allocate ++typedef void (*VCHI_BUFFER_FREE)(VCHI_CONNECTION_SERVICE_HANDLE_T service_handle, void * address); ++ ++ ++/****************************************************************************** ++ System driver struct ++ *****************************************************************************/ ++ ++struct opaque_vchi_connection_api_t ++{ ++ // Routine to init the connection ++ VCHI_CONNECTION_INIT_T init; ++ ++ // Connection-level CRC control ++ VCHI_CONNECTION_CRC_CONTROL_T crc_control; ++ ++ // Routine to connect to or create service ++ VCHI_CONNECTION_SERVICE_CONNECT_T service_connect; ++ ++ // Routine to disconnect from a service ++ VCHI_CONNECTION_SERVICE_DISCONNECT_T service_disconnect; ++ ++ // Routine to queue a message ++ VCHI_CONNECTION_SERVICE_QUEUE_MESSAGE_T service_queue_msg; ++ ++ // scatter-gather (vector) message queue ++ VCHI_CONNECTION_SERVICE_QUEUE_MESSAGEV_T service_queue_msgv; ++ ++ // Routine to dequeue a message ++ VCHI_CONNECTION_SERVICE_DEQUEUE_MESSAGE_T service_dequeue_msg; ++ ++ // Routine to peek at a message ++ VCHI_CONNECTION_SERVICE_PEEK_MESSAGE_T service_peek_msg; ++ ++ // Routine to hold a message ++ VCHI_CONNECTION_SERVICE_HOLD_MESSAGE_T service_hold_msg; ++ ++ // Routine to initialise a received message iterator ++ VCHI_CONNECTION_SERVICE_LOOKAHEAD_MESSAGE_T service_look_ahead_msg; ++ ++ // Routine to release a message ++ VCHI_CONNECTION_HELD_MSG_RELEASE_T held_msg_release; ++ ++ // Routine to get information on a held message ++ VCHI_CONNECTION_HELD_MSG_INFO_T held_msg_info; ++ ++ // Routine to check for next message on iterator ++ VCHI_CONNECTION_MSG_ITER_HAS_NEXT_T msg_iter_has_next; ++ ++ // Routine to get next message on iterator ++ VCHI_CONNECTION_MSG_ITER_NEXT_T msg_iter_next; ++ ++ // Routine to remove the last message returned by iterator ++ VCHI_CONNECTION_MSG_ITER_REMOVE_T msg_iter_remove; ++ ++ // Routine to hold the last message returned by iterator ++ VCHI_CONNECTION_MSG_ITER_HOLD_T msg_iter_hold; ++ ++ // Routine to transmit bulk data ++ VCHI_CONNECTION_BULK_QUEUE_TRANSMIT_T bulk_queue_transmit; ++ ++ // Routine to receive data ++ VCHI_CONNECTION_BULK_QUEUE_RECEIVE_T bulk_queue_receive; ++ ++ // Routine to report the available servers ++ VCHI_CONNECTION_SERVER_PRESENT server_present; ++ ++ // Routine to report the number of RX slots available ++ VCHI_CONNECTION_RX_SLOTS_AVAILABLE connection_rx_slots_available; ++ ++ // Routine to report the RX slot size ++ VCHI_CONNECTION_RX_SLOT_SIZE connection_rx_slot_size; ++ ++ // Callback to indicate that the other side has added a buffer to the rx bulk DMA FIFO ++ VCHI_CONNECTION_RX_BULK_BUFFER_ADDED rx_bulk_buffer_added; ++ ++ // Callback to inform a service that a Xon or Xoff message has been received ++ VCHI_CONNECTION_FLOW_CONTROL flow_control; ++ ++ // Callback to inform a service that a server available reply message has been received ++ VCHI_CONNECTION_SERVER_AVAILABLE_REPLY server_available_reply; ++ ++ // Callback to indicate that bulk auxiliary messages have arrived ++ VCHI_CONNECTION_BULK_AUX_RECEIVED bulk_aux_received; ++ ++ // Callback to indicate that a bulk auxiliary message has been transmitted ++ VCHI_CONNECTION_BULK_AUX_TRANSMITTED bulk_aux_transmitted; ++ ++ // Callback to provide information about the connection ++ VCHI_CONNECTION_INFO connection_info; ++ ++ // Callback to notify that peer has requested disconnect ++ VCHI_CONNECTION_DISCONNECT disconnect; ++ ++ // Callback to notify that peer has requested power change ++ VCHI_CONNECTION_POWER_CONTROL power_control; ++ ++ // allocate memory suitably aligned for this connection ++ VCHI_BUFFER_ALLOCATE buffer_allocate; ++ ++ // free memory allocated by buffer_allocate ++ VCHI_BUFFER_FREE buffer_free; ++ ++}; ++ ++struct vchi_connection_t { ++ const VCHI_CONNECTION_API_T *api; ++ VCHI_CONNECTION_STATE_T *state; ++#ifdef VCHI_COARSE_LOCKING ++ VCOS_SEMAPHORE_T sem; ++#endif ++}; ++ ++ ++#endif /* CONNECTION_H_ */ ++ ++/****************************** End of file **********************************/ +--- /dev/null ++++ b/drivers/misc/vc04_services/interface/vchi/message_drivers/message.h +@@ -0,0 +1,186 @@ ++/* ++ * Copyright (c) 2010-2011 Broadcom Corporation. All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++#ifndef _VCHI_MESSAGE_H_ ++#define _VCHI_MESSAGE_H_ ++ ++#include "interface/vchi/vchi_cfg_internal.h" ++#include "interface/vcos/vcos.h" ++#include "interface/vchi/vchi_common.h" ++ ++ ++typedef enum message_event_type { ++ MESSAGE_EVENT_NONE, ++ MESSAGE_EVENT_NOP, ++ MESSAGE_EVENT_MESSAGE, ++ MESSAGE_EVENT_SLOT_COMPLETE, ++ MESSAGE_EVENT_RX_BULK_PAUSED, ++ MESSAGE_EVENT_RX_BULK_COMPLETE, ++ MESSAGE_EVENT_TX_COMPLETE, ++ MESSAGE_EVENT_MSG_DISCARDED ++} MESSAGE_EVENT_TYPE_T; ++ ++typedef enum vchi_msg_flags ++{ ++ VCHI_MSG_FLAGS_NONE = 0x0, ++ VCHI_MSG_FLAGS_TERMINATE_DMA = 0x1 ++} VCHI_MSG_FLAGS_T; ++ ++typedef enum message_tx_channel ++{ ++ MESSAGE_TX_CHANNEL_MESSAGE = 0, ++ MESSAGE_TX_CHANNEL_BULK = 1 // drivers may provide multiple bulk channels, from 1 upwards ++} MESSAGE_TX_CHANNEL_T; ++ ++// Macros used for cycling through bulk channels ++#define MESSAGE_TX_CHANNEL_BULK_PREV(c) (MESSAGE_TX_CHANNEL_BULK+((c)-MESSAGE_TX_CHANNEL_BULK+VCHI_MAX_BULK_TX_CHANNELS_PER_CONNECTION-1)%VCHI_MAX_BULK_TX_CHANNELS_PER_CONNECTION) ++#define MESSAGE_TX_CHANNEL_BULK_NEXT(c) (MESSAGE_TX_CHANNEL_BULK+((c)-MESSAGE_TX_CHANNEL_BULK+1)%VCHI_MAX_BULK_TX_CHANNELS_PER_CONNECTION) ++ ++typedef enum message_rx_channel ++{ ++ MESSAGE_RX_CHANNEL_MESSAGE = 0, ++ MESSAGE_RX_CHANNEL_BULK = 1 // drivers may provide multiple bulk channels, from 1 upwards ++} MESSAGE_RX_CHANNEL_T; ++ ++// Message receive slot information ++typedef struct rx_msg_slot_info { ++ ++ struct rx_msg_slot_info *next; ++ //struct slot_info *prev; ++#if !defined VCHI_COARSE_LOCKING ++ VCOS_SEMAPHORE_T sem; ++#endif ++ ++ uint8_t *addr; // base address of slot ++ uint32_t len; // length of slot in bytes ++ ++ uint32_t write_ptr; // hardware causes this to advance ++ uint32_t read_ptr; // this module does the reading ++ int active; // is this slot in the hardware dma fifo? ++ uint32_t msgs_parsed; // count how many messages are in this slot ++ uint32_t msgs_released; // how many messages have been released ++ void *state; // connection state information ++ uint8_t ref_count[VCHI_MAX_SERVICES_PER_CONNECTION]; // reference count for slots held by services ++} RX_MSG_SLOTINFO_T; ++ ++// The message driver no longer needs to know about the fields of RX_BULK_SLOTINFO_T - sort this out. ++// In particular, it mustn't use addr and len - they're the client buffer, but the message ++// driver will be tasked with sending the aligned core section. ++typedef struct rx_bulk_slotinfo_t { ++ struct rx_bulk_slotinfo_t *next; ++ ++ VCOS_SEMAPHORE_T *blocking; ++ ++ // needed by DMA ++ void *addr; ++ uint32_t len; ++ ++ // needed for the callback ++ void *service; ++ void *handle; ++ VCHI_FLAGS_T flags; ++} RX_BULK_SLOTINFO_T; ++ ++ ++/* ---------------------------------------------------------------------- ++ * each connection driver will have a pool of the following struct. ++ * ++ * the pool will be managed by vchi_qman_* ++ * this means there will be multiple queues (single linked lists) ++ * a given struct message_info will be on exactly one of these queues ++ * at any one time ++ * -------------------------------------------------------------------- */ ++typedef struct rx_message_info { ++ ++ struct message_info *next; ++ //struct message_info *prev; ++ ++ uint8_t *addr; ++ uint32_t len; ++ RX_MSG_SLOTINFO_T *slot; // points to whichever slot contains this message ++ uint32_t tx_timestamp; ++ uint32_t rx_timestamp; ++ ++} RX_MESSAGE_INFO_T; ++ ++typedef struct { ++ MESSAGE_EVENT_TYPE_T type; ++ ++ struct { ++ // for messages ++ void *addr; // address of message ++ uint16_t slot_delta; // whether this message indicated slot delta ++ uint32_t len; // length of message ++ RX_MSG_SLOTINFO_T *slot; // slot this message is in ++ vcos_fourcc_t service; // service id this message is destined for ++ uint32_t tx_timestamp; // timestamp from the header ++ uint32_t rx_timestamp; // timestamp when we parsed it ++ } message; ++ ++ // FIXME: cleanup slot reporting... ++ RX_MSG_SLOTINFO_T *rx_msg; ++ RX_BULK_SLOTINFO_T *rx_bulk; ++ void *tx_handle; ++ MESSAGE_TX_CHANNEL_T tx_channel; ++ ++} MESSAGE_EVENT_T; ++ ++ ++// callbacks ++typedef void VCHI_MESSAGE_DRIVER_EVENT_CALLBACK_T( void *state ); ++ ++typedef struct { ++ VCHI_MESSAGE_DRIVER_EVENT_CALLBACK_T *event_callback; ++} VCHI_MESSAGE_DRIVER_OPEN_T; ++ ++ ++// handle to this instance of message driver (as returned by ->open) ++typedef struct opaque_mhandle_t *VCHI_MDRIVER_HANDLE_T; ++ ++struct opaque_vchi_message_driver_t { ++ VCHI_MDRIVER_HANDLE_T *(*open)( VCHI_MESSAGE_DRIVER_OPEN_T *params, void *state ); ++ int32_t (*suspending)( VCHI_MDRIVER_HANDLE_T *handle ); ++ int32_t (*resumed)( VCHI_MDRIVER_HANDLE_T *handle ); ++ int32_t (*power_control)( VCHI_MDRIVER_HANDLE_T *handle, MESSAGE_TX_CHANNEL_T, vcos_bool_t enable ); ++ int32_t (*add_msg_rx_slot)( VCHI_MDRIVER_HANDLE_T *handle, RX_MSG_SLOTINFO_T *slot ); // rx message ++ int32_t (*add_bulk_rx)( VCHI_MDRIVER_HANDLE_T *handle, void *data, uint32_t len, RX_BULK_SLOTINFO_T *slot ); // rx data (bulk) ++ int32_t (*send)( VCHI_MDRIVER_HANDLE_T *handle, MESSAGE_TX_CHANNEL_T channel, const void *data, uint32_t len, VCHI_MSG_FLAGS_T flags, void *send_handle ); // tx (message & bulk) ++ void (*next_event)( VCHI_MDRIVER_HANDLE_T *handle, MESSAGE_EVENT_T *event ); // get the next event from message_driver ++ int32_t (*enable)( VCHI_MDRIVER_HANDLE_T *handle ); ++ int32_t (*form_message)( VCHI_MDRIVER_HANDLE_T *handle, vcos_fourcc_t service_id, VCHI_MSG_VECTOR_T *vector, uint32_t count, void ++ *address, uint32_t length_avail, uint32_t max_total_length, vcos_bool_t pad_to_fill, vcos_bool_t allow_partial ); ++ ++ int32_t (*update_message)( VCHI_MDRIVER_HANDLE_T *handle, void *dest, int16_t *slot_count ); ++ int32_t (*buffer_aligned)( VCHI_MDRIVER_HANDLE_T *handle, int tx, int uncached, const void *address, const uint32_t length ); ++ void * (*allocate_buffer)( VCHI_MDRIVER_HANDLE_T *handle, uint32_t *length ); ++ void (*free_buffer)( VCHI_MDRIVER_HANDLE_T *handle, void *address ); ++ int (*rx_slot_size)( VCHI_MDRIVER_HANDLE_T *handle, int msg_size ); ++ int (*tx_slot_size)( VCHI_MDRIVER_HANDLE_T *handle, int msg_size ); ++ ++ vcos_bool_t (*tx_supports_terminate)( const VCHI_MDRIVER_HANDLE_T *handle, MESSAGE_TX_CHANNEL_T channel ); ++ uint32_t (*tx_bulk_chunk_size)( const VCHI_MDRIVER_HANDLE_T *handle, MESSAGE_TX_CHANNEL_T channel ); ++ int (*tx_alignment)( const VCHI_MDRIVER_HANDLE_T *handle, MESSAGE_TX_CHANNEL_T channel ); ++ int (*rx_alignment)( const VCHI_MDRIVER_HANDLE_T *handle, MESSAGE_RX_CHANNEL_T channel ); ++ void (*form_bulk_aux)( VCHI_MDRIVER_HANDLE_T *handle, MESSAGE_TX_CHANNEL_T channel, const void *data, uint32_t len, uint32_t chunk_size, const void **aux_data, int32_t *aux_len ); ++ void (*debug)( VCHI_MDRIVER_HANDLE_T *handle ); ++}; ++ ++ ++#endif // _VCHI_MESSAGE_H_ ++ ++/****************************** End of file ***********************************/ +--- /dev/null ++++ b/drivers/misc/vc04_services/interface/vchi/vchi.h +@@ -0,0 +1,347 @@ ++/* ++ * Copyright (c) 2010-2011 Broadcom Corporation. All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++/*============================================================================= ++Contains the protypes for the vchi functions. ++=============================================================================*/ ++ ++#ifndef VCHI_H_ ++#define VCHI_H_ ++ ++#include "interface/vcos/vcos.h" ++#include "interface/vchi/vchi_cfg.h" ++#include "interface/vchi/vchi_common.h" ++#include "interface/vchi/connections/connection.h" ++#include "vchi_mh.h" ++ ++ ++/****************************************************************************** ++ Global defs ++ *****************************************************************************/ ++ ++#define VCHI_BULK_ROUND_UP(x) ((((unsigned long)(x))+VCHI_BULK_ALIGN-1) & ~(VCHI_BULK_ALIGN-1)) ++#define VCHI_BULK_ROUND_DOWN(x) (((unsigned long)(x)) & ~(VCHI_BULK_ALIGN-1)) ++#define VCHI_BULK_ALIGN_NBYTES(x) (VCHI_BULK_ALIGNED(x) ? 0 : (VCHI_BULK_ALIGN - ((unsigned long)(x) & (VCHI_BULK_ALIGN-1)))) ++ ++#ifdef USE_VCHIQ_ARM ++#define VCHI_BULK_ALIGNED(x) 1 ++#else ++#define VCHI_BULK_ALIGNED(x) (((unsigned long)(x) & (VCHI_BULK_ALIGN-1)) == 0) ++#endif ++ ++ ++typedef enum ++{ ++ VCHI_VEC_POINTER, ++ VCHI_VEC_HANDLE, ++ VCHI_VEC_LIST ++} VCHI_MSG_VECTOR_TYPE_T; ++ ++typedef struct vchi_msg_vector_ex { ++ ++ VCHI_MSG_VECTOR_TYPE_T type; ++ union ++ { ++ // a memory handle ++ struct ++ { ++ VCHI_MEM_HANDLE_T handle; ++ uint32_t offset; ++ int32_t vec_len; ++ } handle; ++ ++ // an ordinary data pointer ++ struct ++ { ++ const void *vec_base; ++ int32_t vec_len; ++ } ptr; ++ ++ // a nested vector list ++ struct ++ { ++ struct vchi_msg_vector_ex *vec; ++ uint32_t vec_len; ++ } list; ++ } u; ++} VCHI_MSG_VECTOR_EX_T; ++ ++ ++// Construct an entry in a msg vector for a pointer (p) of length (l) ++#define VCHI_VEC_POINTER(p,l) VCHI_VEC_POINTER, { { (VCHI_MEM_HANDLE_T)(p), (l) } } ++ ++// Construct an entry in a msg vector for a message handle (h), starting at offset (o) of length (l) ++#define VCHI_VEC_HANDLE(h,o,l) VCHI_VEC_HANDLE, { { (h), (o), (l) } } ++ ++// Macros to manipulate fourcc_t values ++#define MAKE_FOURCC(x) ((fourcc_t)( (x[0] << 24) | (x[1] << 16) | (x[2] << 8) | x[3] )) ++#define FOURCC_TO_CHAR(x) (x >> 24) & 0xFF,(x >> 16) & 0xFF,(x >> 8) & 0xFF, x & 0xFF ++ ++ ++// Opaque service information ++struct opaque_vchi_service_t; ++ ++// Descriptor for a held message. Allocated by client, initialised by vchi_msg_hold, ++// vchi_msg_iter_hold or vchi_msg_iter_hold_next. Fields are for internal VCHI use only. ++typedef struct ++{ ++ struct opaque_vchi_service_t *service; ++ void *message; ++} VCHI_HELD_MSG_T; ++ ++ ++ ++// structure used to provide the information needed to open a server or a client ++typedef struct { ++ vcos_fourcc_t service_id; ++ VCHI_CONNECTION_T *connection; ++ uint32_t rx_fifo_size; ++ uint32_t tx_fifo_size; ++ VCHI_CALLBACK_T callback; ++ void *callback_param; ++ vcos_bool_t want_unaligned_bulk_rx; // client intends to receive bulk transfers of odd lengths or into unaligned buffers ++ vcos_bool_t want_unaligned_bulk_tx; // client intends to transmit bulk transfers of odd lengths or out of unaligned buffers ++ vcos_bool_t want_crc; // client wants to check CRCs on (bulk) transfers. Only needs to be set at 1 end - will do both directions. ++} SERVICE_CREATION_T; ++ ++// Opaque handle for a VCHI instance ++typedef struct opaque_vchi_instance_handle_t *VCHI_INSTANCE_T; ++ ++// Opaque handle for a server or client ++typedef struct opaque_vchi_service_handle_t *VCHI_SERVICE_HANDLE_T; ++ ++// Service registration & startup ++typedef void (*VCHI_SERVICE_INIT)(VCHI_INSTANCE_T initialise_instance, VCHI_CONNECTION_T **connections, uint32_t num_connections); ++ ++typedef struct service_info_tag { ++ const char * const vll_filename; /* VLL to load to start this service. This is an empty string if VLL is "static" */ ++ VCHI_SERVICE_INIT init; /* Service initialisation function */ ++ void *vll_handle; /* VLL handle; NULL when unloaded or a "static VLL" in build */ ++} SERVICE_INFO_T; ++ ++/****************************************************************************** ++ Global funcs - implementation is specific to which side you are on (local / remote) ++ *****************************************************************************/ ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++extern /*@observer@*/ VCHI_CONNECTION_T * vchi_create_connection( const VCHI_CONNECTION_API_T * function_table, ++ const VCHI_MESSAGE_DRIVER_T * low_level); ++ ++ ++// Routine used to initialise the vchi on both local + remote connections ++extern int32_t vchi_initialise( VCHI_INSTANCE_T *instance_handle ); ++ ++extern int32_t vchi_exit( void ); ++ ++extern int32_t vchi_connect( VCHI_CONNECTION_T **connections, ++ const uint32_t num_connections, ++ VCHI_INSTANCE_T instance_handle ); ++ ++//When this is called, ensure that all services have no data pending. ++//Bulk transfers can remain 'queued' ++extern int32_t vchi_disconnect( VCHI_INSTANCE_T instance_handle ); ++ ++// Global control over bulk CRC checking ++extern int32_t vchi_crc_control( VCHI_CONNECTION_T *connection, ++ VCHI_CRC_CONTROL_T control ); ++ ++// helper functions ++extern void * vchi_allocate_buffer(VCHI_SERVICE_HANDLE_T handle, uint32_t *length); ++extern void vchi_free_buffer(VCHI_SERVICE_HANDLE_T handle, void *address); ++extern uint32_t vchi_current_time(VCHI_INSTANCE_T instance_handle); ++ ++ ++/****************************************************************************** ++ Global service API ++ *****************************************************************************/ ++// Routine to create a named service ++extern int32_t vchi_service_create( VCHI_INSTANCE_T instance_handle, ++ SERVICE_CREATION_T *setup, ++ VCHI_SERVICE_HANDLE_T *handle ); ++ ++// Routine to destory a service ++extern int32_t vchi_service_destroy( const VCHI_SERVICE_HANDLE_T handle ); ++ ++// Routine to open a named service ++extern int32_t vchi_service_open( VCHI_INSTANCE_T instance_handle, ++ SERVICE_CREATION_T *setup, ++ VCHI_SERVICE_HANDLE_T *handle); ++ ++// Routine to close a named service ++extern int32_t vchi_service_close( const VCHI_SERVICE_HANDLE_T handle ); ++ ++// Routine to increment ref count on a named service ++extern int32_t vchi_service_use( const VCHI_SERVICE_HANDLE_T handle ); ++ ++// Routine to decrement ref count on a named service ++extern int32_t vchi_service_release( const VCHI_SERVICE_HANDLE_T handle ); ++ ++// Routine to send a message accross a service ++extern int32_t vchi_msg_queue( VCHI_SERVICE_HANDLE_T handle, ++ const void *data, ++ uint32_t data_size, ++ VCHI_FLAGS_T flags, ++ void *msg_handle ); ++ ++// scatter-gather (vector) and send message ++int32_t vchi_msg_queuev_ex( VCHI_SERVICE_HANDLE_T handle, ++ VCHI_MSG_VECTOR_EX_T *vector, ++ uint32_t count, ++ VCHI_FLAGS_T flags, ++ void *msg_handle ); ++ ++// legacy scatter-gather (vector) and send message, only handles pointers ++int32_t vchi_msg_queuev( VCHI_SERVICE_HANDLE_T handle, ++ VCHI_MSG_VECTOR_T *vector, ++ uint32_t count, ++ VCHI_FLAGS_T flags, ++ void *msg_handle ); ++ ++// Routine to receive a msg from a service ++// Dequeue is equivalent to hold, copy into client buffer, release ++extern int32_t vchi_msg_dequeue( VCHI_SERVICE_HANDLE_T handle, ++ void *data, ++ uint32_t max_data_size_to_read, ++ uint32_t *actual_msg_size, ++ VCHI_FLAGS_T flags ); ++ ++// Routine to look at a message in place. ++// The message is not dequeued, so a subsequent call to peek or dequeue ++// will return the same message. ++extern int32_t vchi_msg_peek( VCHI_SERVICE_HANDLE_T handle, ++ void **data, ++ uint32_t *msg_size, ++ VCHI_FLAGS_T flags ); ++ ++// Routine to remove a message after it has been read in place with peek ++// The first message on the queue is dequeued. ++extern int32_t vchi_msg_remove( VCHI_SERVICE_HANDLE_T handle ); ++ ++// Routine to look at a message in place. ++// The message is dequeued, so the caller is left holding it; the descriptor is ++// filled in and must be released when the user has finished with the message. ++extern int32_t vchi_msg_hold( VCHI_SERVICE_HANDLE_T handle, ++ void **data, // } may be NULL, as info can be ++ uint32_t *msg_size, // } obtained from HELD_MSG_T ++ VCHI_FLAGS_T flags, ++ VCHI_HELD_MSG_T *message_descriptor ); ++ ++// Initialise an iterator to look through messages in place ++extern int32_t vchi_msg_look_ahead( VCHI_SERVICE_HANDLE_T handle, ++ VCHI_MSG_ITER_T *iter, ++ VCHI_FLAGS_T flags ); ++ ++/****************************************************************************** ++ Global service support API - operations on held messages and message iterators ++ *****************************************************************************/ ++ ++// Routine to get the address of a held message ++extern void *vchi_held_msg_ptr( const VCHI_HELD_MSG_T *message ); ++ ++// Routine to get the size of a held message ++extern int32_t vchi_held_msg_size( const VCHI_HELD_MSG_T *message ); ++ ++// Routine to get the transmit timestamp as written into the header by the peer ++extern uint32_t vchi_held_msg_tx_timestamp( const VCHI_HELD_MSG_T *message ); ++ ++// Routine to get the reception timestamp, written as we parsed the header ++extern uint32_t vchi_held_msg_rx_timestamp( const VCHI_HELD_MSG_T *message ); ++ ++// Routine to release a held message after it has been processed ++extern int32_t vchi_held_msg_release( VCHI_HELD_MSG_T *message ); ++ ++// Indicates whether the iterator has a next message. ++extern vcos_bool_t vchi_msg_iter_has_next( const VCHI_MSG_ITER_T *iter ); ++ ++// Return the pointer and length for the next message and advance the iterator. ++extern int32_t vchi_msg_iter_next( VCHI_MSG_ITER_T *iter, ++ void **data, ++ uint32_t *msg_size ); ++ ++// Remove the last message returned by vchi_msg_iter_next. ++// Can only be called once after each call to vchi_msg_iter_next. ++extern int32_t vchi_msg_iter_remove( VCHI_MSG_ITER_T *iter ); ++ ++// Hold the last message returned by vchi_msg_iter_next. ++// Can only be called once after each call to vchi_msg_iter_next. ++extern int32_t vchi_msg_iter_hold( VCHI_MSG_ITER_T *iter, ++ VCHI_HELD_MSG_T *message ); ++ ++// Return information for the next message, and hold it, advancing the iterator. ++extern int32_t vchi_msg_iter_hold_next( VCHI_MSG_ITER_T *iter, ++ void **data, // } may be NULL ++ uint32_t *msg_size, // } ++ VCHI_HELD_MSG_T *message ); ++ ++ ++/****************************************************************************** ++ Global bulk API ++ *****************************************************************************/ ++ ++// Routine to prepare interface for a transfer from the other side ++extern int32_t vchi_bulk_queue_receive( VCHI_SERVICE_HANDLE_T handle, ++ void *data_dst, ++ uint32_t data_size, ++ VCHI_FLAGS_T flags, ++ void *transfer_handle ); ++ ++ ++// Prepare interface for a transfer from the other side into relocatable memory. ++int32_t vchi_bulk_queue_receive_reloc( const VCHI_SERVICE_HANDLE_T handle, ++ VCHI_MEM_HANDLE_T h_dst, ++ uint32_t offset, ++ uint32_t data_size, ++ const VCHI_FLAGS_T flags, ++ void * const bulk_handle ); ++ ++// Routine to queue up data ready for transfer to the other (once they have signalled they are ready) ++extern int32_t vchi_bulk_queue_transmit( VCHI_SERVICE_HANDLE_T handle, ++ const void *data_src, ++ uint32_t data_size, ++ VCHI_FLAGS_T flags, ++ void *transfer_handle ); ++ ++ ++/****************************************************************************** ++ Configuration plumbing ++ *****************************************************************************/ ++ ++// function prototypes for the different mid layers (the state info gives the different physical connections) ++extern const VCHI_CONNECTION_API_T *single_get_func_table( void ); ++//extern const VCHI_CONNECTION_API_T *local_server_get_func_table( void ); ++//extern const VCHI_CONNECTION_API_T *local_client_get_func_table( void ); ++ ++// declare all message drivers here ++const VCHI_MESSAGE_DRIVER_T *vchi_mphi_message_driver_func_table( void ); ++ ++#ifdef __cplusplus ++} ++#endif ++ ++extern int32_t vchi_bulk_queue_transmit_reloc( VCHI_SERVICE_HANDLE_T handle, ++ VCHI_MEM_HANDLE_T h_src, ++ uint32_t offset, ++ uint32_t data_size, ++ VCHI_FLAGS_T flags, ++ void *transfer_handle ); ++#endif /* VCHI_H_ */ ++ ++/****************************** End of file **********************************/ +--- /dev/null ++++ b/drivers/misc/vc04_services/interface/vchi/vchi_cfg.h +@@ -0,0 +1,214 @@ ++/* ++ * Copyright (c) 2010-2011 Broadcom Corporation. All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++/*============================================================================= ++Contains the #defines for the number of servers / clients etc, these can be ++over-ridden from the platform makefile if needed ++=============================================================================*/ ++ ++#ifndef VCHI_CFG_H_ ++#define VCHI_CFG_H_ ++ ++/**************************************************************************************** ++ * Defines in this first section are part of the VCHI API and may be examined by VCHI ++ * services. ++ ***************************************************************************************/ ++ ++/* Required alignment of base addresses for bulk transfer, if unaligned transfers are not enabled */ ++/* Really determined by the message driver, and should be available from a run-time call. */ ++#ifndef VCHI_BULK_ALIGN ++# if __VCCOREVER__ >= 0x04000000 ++# define VCHI_BULK_ALIGN 32 // Allows for the need to do cache cleans ++# else ++# define VCHI_BULK_ALIGN 16 ++# endif ++#endif ++ ++/* Required length multiple for bulk transfers, if unaligned transfers are not enabled */ ++/* May be less than or greater than VCHI_BULK_ALIGN */ ++/* Really determined by the message driver, and should be available from a run-time call. */ ++#ifndef VCHI_BULK_GRANULARITY ++# if __VCCOREVER__ >= 0x04000000 ++# define VCHI_BULK_GRANULARITY 32 // Allows for the need to do cache cleans ++# else ++# define VCHI_BULK_GRANULARITY 16 ++# endif ++#endif ++ ++/* The largest possible message to be queued with vchi_msg_queue. */ ++#ifndef VCHI_MAX_MSG_SIZE ++# if defined VCHI_LOCAL_HOST_PORT ++# define VCHI_MAX_MSG_SIZE 16384 // makes file transfers fast, but should they be using bulk? ++# else ++# define VCHI_MAX_MSG_SIZE 4096 // NOTE: THIS MUST BE LARGER THAN OR EQUAL TO THE SIZE OF THE KHRONOS MERGE BUFFER!! ++# endif ++#endif ++ ++/****************************************************************************************** ++ * Defines below are system configuration options, and should not be used by VCHI services. ++ *****************************************************************************************/ ++ ++/* How many connections can we support? A localhost implementation uses 2 connections, ++ * 1 for host-app, 1 for VMCS, and these are hooked together by a loopback MPHI VCFW ++ * driver. */ ++#ifndef VCHI_MAX_NUM_CONNECTIONS ++# define VCHI_MAX_NUM_CONNECTIONS 3 ++#endif ++ ++/* How many services can we open per connection? Extending this doesn't cost processing time, just a small ++ * amount of static memory. */ ++#ifndef VCHI_MAX_SERVICES_PER_CONNECTION ++# define VCHI_MAX_SERVICES_PER_CONNECTION 36 ++#endif ++ ++/* Adjust if using a message driver that supports more logical TX channels */ ++#ifndef VCHI_MAX_BULK_TX_CHANNELS_PER_CONNECTION ++# define VCHI_MAX_BULK_TX_CHANNELS_PER_CONNECTION 9 // 1 MPHI + 8 CCP2 logical channels ++#endif ++ ++/* Adjust if using a message driver that supports more logical RX channels */ ++#ifndef VCHI_MAX_BULK_RX_CHANNELS_PER_CONNECTION ++# define VCHI_MAX_BULK_RX_CHANNELS_PER_CONNECTION 1 // 1 MPHI ++#endif ++ ++/* How many receive slots do we use. This times VCHI_MAX_MSG_SIZE gives the effective ++ * receive queue space, less message headers. */ ++#ifndef VCHI_NUM_READ_SLOTS ++# if defined(VCHI_LOCAL_HOST_PORT) ++# define VCHI_NUM_READ_SLOTS 4 ++# else ++# define VCHI_NUM_READ_SLOTS 48 ++# endif ++#endif ++ ++/* Do we utilise overrun facility for receive message slots? Can aid peer transmit ++ * performance. Only define on VideoCore end, talking to host. ++ */ ++//#define VCHI_MSG_RX_OVERRUN ++ ++/* How many transmit slots do we use. Generally don't need many, as the hardware driver ++ * underneath VCHI will usually have its own buffering. */ ++#ifndef VCHI_NUM_WRITE_SLOTS ++# define VCHI_NUM_WRITE_SLOTS 4 ++#endif ++ ++/* If a service has held or queued received messages in VCHI_XOFF_THRESHOLD or more slots, ++ * then it's taking up too much buffer space, and the peer service will be told to stop ++ * transmitting with an XOFF message. For this to be effective, the VCHI_NUM_READ_SLOTS ++ * needs to be considerably bigger than VCHI_NUM_WRITE_SLOTS, or the transmit latency ++ * is too high. */ ++#ifndef VCHI_XOFF_THRESHOLD ++# define VCHI_XOFF_THRESHOLD (VCHI_NUM_READ_SLOTS / 2) ++#endif ++ ++/* After we've sent an XOFF, the peer will be told to resume transmission once the local ++ * service has dequeued/released enough messages that it's now occupying ++ * VCHI_XON_THRESHOLD slots or fewer. */ ++#ifndef VCHI_XON_THRESHOLD ++# define VCHI_XON_THRESHOLD (VCHI_NUM_READ_SLOTS / 4) ++#endif ++ ++/* A size below which a bulk transfer omits the handshake completely and always goes ++ * via the message channel, if bulk auxiliary is being sent on that service. (The user ++ * can guarantee this by enabling unaligned transmits). ++ * Not API. */ ++#ifndef VCHI_MIN_BULK_SIZE ++# define VCHI_MIN_BULK_SIZE ( VCHI_MAX_MSG_SIZE / 2 < 4096 ? VCHI_MAX_MSG_SIZE / 2 : 4096 ) ++#endif ++ ++/* Maximum size of bulk transmission chunks, for each interface type. A trade-off between ++ * speed and latency; the smaller the chunk size the better change of messages and other ++ * bulk transmissions getting in when big bulk transfers are happening. Set to 0 to not ++ * break transmissions into chunks. ++ */ ++#ifndef VCHI_MAX_BULK_CHUNK_SIZE_MPHI ++# define VCHI_MAX_BULK_CHUNK_SIZE_MPHI (16 * 1024) ++#endif ++ ++/* NB Chunked CCP2 transmissions violate the letter of the CCP2 spec by using "JPEG8" mode ++ * with multiple-line frames. Only use if the receiver can cope. */ ++#ifndef VCHI_MAX_BULK_CHUNK_SIZE_CCP2 ++# define VCHI_MAX_BULK_CHUNK_SIZE_CCP2 0 ++#endif ++ ++/* How many TX messages can we have pending in our transmit slots. Once exhausted, ++ * vchi_msg_queue will be blocked. */ ++#ifndef VCHI_TX_MSG_QUEUE_SIZE ++# define VCHI_TX_MSG_QUEUE_SIZE 256 ++#endif ++ ++/* How many RX messages can we have parsed in the receive slots. Once exhausted, parsing ++ * will be suspended until older messages are dequeued/released. */ ++#ifndef VCHI_RX_MSG_QUEUE_SIZE ++# define VCHI_RX_MSG_QUEUE_SIZE 256 ++#endif ++ ++/* Really should be able to cope if we run out of received message descriptors, by ++ * suspending parsing as the comment above says, but we don't. This sweeps the issue ++ * under the carpet. */ ++#if VCHI_RX_MSG_QUEUE_SIZE < (VCHI_MAX_MSG_SIZE/16 + 1) * VCHI_NUM_READ_SLOTS ++# undef VCHI_RX_MSG_QUEUE_SIZE ++# define VCHI_RX_MSG_QUEUE_SIZE (VCHI_MAX_MSG_SIZE/16 + 1) * VCHI_NUM_READ_SLOTS ++#endif ++ ++/* How many bulk transmits can we have pending. Once exhausted, vchi_bulk_queue_transmit ++ * will be blocked. */ ++#ifndef VCHI_TX_BULK_QUEUE_SIZE ++# define VCHI_TX_BULK_QUEUE_SIZE 64 ++#endif ++ ++/* How many bulk receives can we have pending. Once exhausted, vchi_bulk_queue_receive ++ * will be blocked. */ ++#ifndef VCHI_RX_BULK_QUEUE_SIZE ++# define VCHI_RX_BULK_QUEUE_SIZE 64 ++#endif ++ ++/* A limit on how many outstanding bulk requests we expect the peer to give us. If ++ * the peer asks for more than this, VCHI will fail and assert. The number is determined ++ * by the peer's hardware - it's the number of outstanding requests that can be queued ++ * on all bulk channels. VC3's MPHI peripheral allows 16. */ ++#ifndef VCHI_MAX_PEER_BULK_REQUESTS ++# define VCHI_MAX_PEER_BULK_REQUESTS 32 ++#endif ++ ++/* Define VCHI_CCP2TX_MANUAL_POWER if the host tells us when to turn the CCP2 ++ * transmitter on and off. ++ */ ++/*#define VCHI_CCP2TX_MANUAL_POWER*/ ++ ++#ifndef VCHI_CCP2TX_MANUAL_POWER ++ ++/* Timeout (in milliseconds) for putting the CCP2TX interface into IDLE state. Set ++ * negative for no IDLE. ++ */ ++# ifndef VCHI_CCP2TX_IDLE_TIMEOUT ++# define VCHI_CCP2TX_IDLE_TIMEOUT 5 ++# endif ++ ++/* Timeout (in milliseconds) for putting the CCP2TX interface into OFF state. Set ++ * negative for no OFF. ++ */ ++# ifndef VCHI_CCP2TX_OFF_TIMEOUT ++# define VCHI_CCP2TX_OFF_TIMEOUT 1000 ++# endif ++ ++#endif /* VCHI_CCP2TX_MANUAL_POWER */ ++ ++#endif /* VCHI_CFG_H_ */ ++ ++/****************************** End of file **********************************/ +--- /dev/null ++++ b/drivers/misc/vc04_services/interface/vchi/vchi_cfg_internal.h +@@ -0,0 +1,56 @@ ++/* ++ * Copyright (c) 2010-2011 Broadcom Corporation. All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++#ifndef VCHI_CFG_INTERNAL_H_ ++#define VCHI_CFG_INTERNAL_H_ ++ ++/**************************************************************************************** ++ * Control optimisation attempts. ++ ***************************************************************************************/ ++ ++// Don't use lots of short-term locks - use great long ones, reducing the overall locks-per-second ++#define VCHI_COARSE_LOCKING ++ ++// Avoid lock then unlock on exit from blocking queue operations (msg tx, bulk rx/tx) ++// (only relevant if VCHI_COARSE_LOCKING) ++#define VCHI_ELIDE_BLOCK_EXIT_LOCK ++ ++// Avoid lock on non-blocking peek ++// (only relevant if VCHI_COARSE_LOCKING) ++#define VCHI_AVOID_PEEK_LOCK ++ ++// Use one slot-handler thread per connection, rather than 1 thread dealing with all connections in rotation. ++#define VCHI_MULTIPLE_HANDLER_THREADS ++ ++// Put free descriptors onto the head of the free queue, rather than the tail, so that we don't thrash ++// our way through the pool of descriptors. ++#define VCHI_PUSH_FREE_DESCRIPTORS_ONTO_HEAD ++ ++// Don't issue a MSG_AVAILABLE callback for every single message. Possibly only safe if VCHI_COARSE_LOCKING. ++#define VCHI_FEWER_MSG_AVAILABLE_CALLBACKS ++ ++// Don't use message descriptors for TX messages that don't need them ++#define VCHI_MINIMISE_TX_MSG_DESCRIPTORS ++ ++// Nano-locks for multiqueue ++//#define VCHI_MQUEUE_NANOLOCKS ++ ++// Lock-free(er) dequeuing ++//#define VCHI_RX_NANOLOCKS ++ ++#endif /*VCHI_CFG_INTERNAL_H_*/ +--- /dev/null ++++ b/drivers/misc/vc04_services/interface/vchi/vchi_common.h +@@ -0,0 +1,152 @@ ++/* ++ * Copyright (c) 2010-2011 Broadcom Corporation. All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++/*============================================================================= ++Contains global defs used by submodules within vchi. ++=============================================================================*/ ++ ++#ifndef VCHI_COMMON_H_ ++#define VCHI_COMMON_H_ ++ ++ ++//flags used when sending messages (must be bitmapped) ++typedef enum ++{ ++ VCHI_FLAGS_NONE = 0x0, ++ VCHI_FLAGS_BLOCK_UNTIL_OP_COMPLETE = 0x1, // waits for message to be received, or sent (NB. not the same as being seen on other side) ++ VCHI_FLAGS_CALLBACK_WHEN_OP_COMPLETE = 0x2, // run a callback when message sent ++ VCHI_FLAGS_BLOCK_UNTIL_QUEUED = 0x4, // return once the transfer is in a queue ready to go ++ VCHI_FLAGS_ALLOW_PARTIAL = 0x8, ++ VCHI_FLAGS_BLOCK_UNTIL_DATA_READ = 0x10, ++ VCHI_FLAGS_CALLBACK_WHEN_DATA_READ = 0x20, ++ ++ VCHI_FLAGS_ALIGN_SLOT = 0x000080, // internal use only ++ VCHI_FLAGS_BULK_AUX_QUEUED = 0x010000, // internal use only ++ VCHI_FLAGS_BULK_AUX_COMPLETE = 0x020000, // internal use only ++ VCHI_FLAGS_BULK_DATA_QUEUED = 0x040000, // internal use only ++ VCHI_FLAGS_BULK_DATA_COMPLETE = 0x080000, // internal use only ++ VCHI_FLAGS_INTERNAL = 0xFF0000 ++} VCHI_FLAGS_T; ++ ++// constants for vchi_crc_control() ++typedef enum { ++ VCHI_CRC_NOTHING = -1, ++ VCHI_CRC_PER_SERVICE = 0, ++ VCHI_CRC_EVERYTHING = 1, ++} VCHI_CRC_CONTROL_T; ++ ++//callback reasons when an event occurs on a service ++typedef enum ++{ ++ VCHI_CALLBACK_REASON_MIN, ++ ++ //This indicates that there is data available ++ //handle is the msg id that was transmitted with the data ++ // When a message is received and there was no FULL message available previously, send callback ++ // Tasks get kicked by the callback, reset their event and try and read from the fifo until it fails ++ VCHI_CALLBACK_MSG_AVAILABLE, ++ VCHI_CALLBACK_MSG_SENT, ++ VCHI_CALLBACK_MSG_SPACE_AVAILABLE, // XXX not yet implemented ++ ++ // This indicates that a transfer from the other side has completed ++ VCHI_CALLBACK_BULK_RECEIVED, ++ //This indicates that data queued up to be sent has now gone ++ //handle is the msg id that was used when sending the data ++ VCHI_CALLBACK_BULK_SENT, ++ VCHI_CALLBACK_BULK_RX_SPACE_AVAILABLE, // XXX not yet implemented ++ VCHI_CALLBACK_BULK_TX_SPACE_AVAILABLE, // XXX not yet implemented ++ ++ VCHI_CALLBACK_SERVICE_CLOSED, ++ ++ // this side has sent XOFF to peer due to lack of data consumption by service ++ // (suggests the service may need to take some recovery action if it has ++ // been deliberately holding off consuming data) ++ VCHI_CALLBACK_SENT_XOFF, ++ VCHI_CALLBACK_SENT_XON, ++ ++ // indicates that a bulk transfer has finished reading the source buffer ++ VCHI_CALLBACK_BULK_DATA_READ, ++ ++ // power notification events (currently host side only) ++ VCHI_CALLBACK_PEER_OFF, ++ VCHI_CALLBACK_PEER_SUSPENDED, ++ VCHI_CALLBACK_PEER_ON, ++ VCHI_CALLBACK_PEER_RESUMED, ++ VCHI_CALLBACK_FORCED_POWER_OFF, ++ ++#ifdef USE_VCHIQ_ARM ++ // some extra notifications provided by vchiq_arm ++ VCHI_CALLBACK_SERVICE_OPENED, ++ VCHI_CALLBACK_BULK_RECEIVE_ABORTED, ++ VCHI_CALLBACK_BULK_TRANSMIT_ABORTED, ++#endif ++ ++ VCHI_CALLBACK_REASON_MAX ++} VCHI_CALLBACK_REASON_T; ++ ++//Calback used by all services / bulk transfers ++typedef void (*VCHI_CALLBACK_T)( void *callback_param, //my service local param ++ VCHI_CALLBACK_REASON_T reason, ++ void *handle ); //for transmitting msg's only ++ ++ ++ ++/* ++ * Define vector struct for scatter-gather (vector) operations ++ * Vectors can be nested - if a vector element has negative length, then ++ * the data pointer is treated as pointing to another vector array, with ++ * '-vec_len' elements. Thus to append a header onto an existing vector, ++ * you can do this: ++ * ++ * void foo(const VCHI_MSG_VECTOR_T *v, int n) ++ * { ++ * VCHI_MSG_VECTOR_T nv[2]; ++ * nv[0].vec_base = my_header; ++ * nv[0].vec_len = sizeof my_header; ++ * nv[1].vec_base = v; ++ * nv[1].vec_len = -n; ++ * ... ++ * ++ */ ++typedef struct vchi_msg_vector { ++ const void *vec_base; ++ int32_t vec_len; ++} VCHI_MSG_VECTOR_T; ++ ++// Opaque type for a connection API ++typedef struct opaque_vchi_connection_api_t VCHI_CONNECTION_API_T; ++ ++// Opaque type for a message driver ++typedef struct opaque_vchi_message_driver_t VCHI_MESSAGE_DRIVER_T; ++ ++ ++// Iterator structure for reading ahead through received message queue. Allocated by client, ++// initialised by vchi_msg_look_ahead. Fields are for internal VCHI use only. ++// Iterates over messages in queue at the instant of the call to vchi_msg_lookahead - ++// will not proceed to messages received since. Behaviour is undefined if an iterator ++// is used again after messages for that service are removed/dequeued by any ++// means other than vchi_msg_iter_... calls on the iterator itself. ++typedef struct { ++ struct opaque_vchi_service_t *service; ++ void *last; ++ void *next; ++ void *remove; ++} VCHI_MSG_ITER_T; ++ ++ ++#endif // VCHI_COMMON_H_ +--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c ++++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c +@@ -36,7 +36,7 @@ + #define TOTAL_SLOTS (VCHIQ_SLOT_ZERO_SLOTS + 2 * 32) + + #define VCHIQ_DOORBELL_IRQ IRQ_ARM_DOORBELL_0 +-#define VCHIQ_ARM_ADDRESS(x) __virt_to_bus(x) ++#define VCHIQ_ARM_ADDRESS(x) ((void *)__virt_to_bus((unsigned)x)) + + #include "vchiq_arm.h" + #include "vchiq_2835.h" +@@ -182,7 +182,15 @@ remote_event_signal(REMOTE_EVENT_T *even + int + vchiq_copy_from_user(void *dst, const void *src, int size) + { +- return copy_from_user(dst, src, size); ++ if ( (uint32_t)src < TASK_SIZE) ++ { ++ return copy_from_user(dst, src, size); ++ } ++ else ++ { ++ memcpy( dst, src, size ); ++ return 0; ++ } + } + + VCHIQ_STATUS_T +@@ -239,6 +247,22 @@ vchiq_dump_platform_state(void *dump_con + vchiq_dump(dump_context, buf, len + 1); + } + ++VCHIQ_STATUS_T ++vchiq_platform_suspend(VCHIQ_STATE_T *state) ++{ ++ vcos_unused(state); ++ vcos_assert_msg(0, "Suspend/resume not supported"); ++ return VCHIQ_ERROR; ++} ++ ++VCHIQ_STATUS_T ++vchiq_platform_resume(VCHIQ_STATE_T *state) ++{ ++ vcos_unused(state); ++ vcos_assert_msg(0, "Suspend/resume not supported"); ++ return VCHIQ_ERROR; ++} ++ + void + vchiq_platform_paused(VCHIQ_STATE_T *state) + { +@@ -253,33 +277,40 @@ vchiq_platform_resumed(VCHIQ_STATE_T *st + vcos_assert_msg(0, "Suspend/resume not supported"); + } + +-VCHIQ_STATUS_T +-vchiq_use_service(VCHIQ_SERVICE_HANDLE_T handle) ++int ++vchiq_platform_videocore_wanted(VCHIQ_STATE_T* state) + { +- VCHIQ_SERVICE_T *service = (VCHIQ_SERVICE_T *)handle; +- if (!service) +- return VCHIQ_ERROR; +- return VCHIQ_SUCCESS; ++ vcos_unused(state); ++ return 1; // autosuspend not supported - videocore always wanted + } + +-VCHIQ_STATUS_T +-vchiq_release_service(VCHIQ_SERVICE_HANDLE_T handle) ++#if VCOS_HAVE_TIMER ++int ++vchiq_platform_use_suspend_timer(void) + { +- VCHIQ_SERVICE_T *service = (VCHIQ_SERVICE_T *)handle; +- if (!service) +- return VCHIQ_ERROR; +- return VCHIQ_SUCCESS; ++ return 0; ++} ++#endif ++void ++vchiq_dump_platform_use_state(VCHIQ_STATE_T *state) ++{ ++ vcos_unused(state); + } + + VCHIQ_STATUS_T +-vchiq_check_service(VCHIQ_SERVICE_HANDLE_T handle) ++vchiq_platform_init_state(VCHIQ_STATE_T *state) + { +- VCHIQ_SERVICE_T *service = (VCHIQ_SERVICE_T *)handle; +- if (!service) +- return VCHIQ_ERROR; ++ vcos_unused(state); + return VCHIQ_SUCCESS; + } + ++VCHIQ_ARM_STATE_T* ++vchiq_platform_get_arm_state(VCHIQ_STATE_T *state) ++{ ++ vcos_unused(state); ++ return NULL; ++} ++ + /* + * Local functions + */ +@@ -479,9 +510,3 @@ free_pagelist(PAGELIST_T *pagelist, int + kfree(pagelist); + } + +-VCHIQ_STATUS_T +-vchiq_platform_suspend(VCHIQ_STATE_T *state) +-{ +- vcos_unused(state); +- return VCHIQ_ERROR; +-} +--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c ++++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c +@@ -23,6 +23,9 @@ + #include <linux/cdev.h> + #include <linux/fs.h> + #include <linux/device.h> ++#include <linux/mm.h> ++#include <linux/highmem.h> ++#include <linux/pagemap.h> + + #include "vchiq_core.h" + #include "vchiq_ioctl.h" +@@ -44,6 +47,15 @@ + + #define VCOS_LOG_CATEGORY (&vchiq_arm_log_category) + ++#define VCHIQ_ARM_VCSUSPEND_TASK_STACK 4096 ++ ++#if VCOS_HAVE_TIMER ++#define SUSPEND_TIMER_TIMEOUT_MS 100 ++static VCOS_TIMER_T g_suspend_timer; ++static void suspend_timer_callback(void *context); ++#endif ++ ++ + typedef struct client_service_struct { + VCHIQ_SERVICE_T *service; + void *userdata; +@@ -106,10 +118,17 @@ static const char *ioctl_names[] = + "GET_CONFIG", + "CLOSE_SERVICE", + "USE_SERVICE", +- "RELEASE_SERIVCE" ++ "RELEASE_SERVICE", ++ "SET_SERVICE_OPTION", ++ "DUMP_PHYS_MEM" + }; + +-VCOS_LOG_LEVEL_T vchiq_default_arm_log_level = VCOS_LOG_WARN; ++vcos_static_assert(vcos_countof(ioctl_names) == (VCHIQ_IOC_MAX + 1)); ++ ++VCOS_LOG_LEVEL_T vchiq_default_arm_log_level = VCOS_LOG_ERROR; ++ ++static void ++dump_phys_mem( void *virt_addr, uint32_t num_bytes ); + + /**************************************************************************** + * +@@ -118,7 +137,7 @@ VCOS_LOG_LEVEL_T vchiq_default_arm_log_l + ***************************************************************************/ + + static inline USER_SERVICE_T *find_service_by_handle( +- VCHIQ_INSTANCE_T instance, int handle ) ++ VCHIQ_INSTANCE_T instance, int handle ) + { + USER_SERVICE_T *user_service; + +@@ -524,7 +543,7 @@ vchiq_ioctl(struct file *file, unsigned + status = (cmd == VCHIQ_IOC_USE_SERVICE) ? vchiq_use_service(&user_service->service->base) : vchiq_release_service(&user_service->service->base); + if (status != VCHIQ_SUCCESS) + { +- ret = -EINVAL; // ??? ++ ret = -EINVAL; /* ??? */ + } + } + } +@@ -872,6 +891,21 @@ vchiq_ioctl(struct file *file, unsigned + } + break; + ++ case VCHIQ_IOC_DUMP_PHYS_MEM: ++ { ++ VCHIQ_DUMP_MEM_T args; ++ ++ if (copy_from_user ++ (&args, (const void __user *)arg, ++ sizeof(args)) != 0) { ++ ret = -EFAULT; ++ break; ++ } ++ dump_phys_mem( args.virt_addr, args.num_bytes ); ++ } ++ break; ++ ++ + default: + ret = -ENOTTY; + break; +@@ -1060,7 +1094,7 @@ vchiq_dump(void *dump_context, const cha + char cr = '\n'; + if (copy_to_user(context->buf + context->actual - 1, &cr, 1)) + { +- context->actual = -EFAULT; ++ context->actual = -EFAULT; + } + } + } +@@ -1153,6 +1187,88 @@ vchiq_dump_platform_service_state(void * + + /**************************************************************************** + * ++* dump_user_mem ++* ++***************************************************************************/ ++ ++static void ++dump_phys_mem( void *virt_addr, uint32_t num_bytes ) ++{ ++ int rc; ++ uint8_t *end_virt_addr = virt_addr + num_bytes; ++ int num_pages; ++ int offset; ++ int end_offset; ++ int page_idx; ++ int prev_idx; ++ struct page *page; ++ struct page **pages; ++ uint8_t *kmapped_virt_ptr; ++ ++ // Align virtAddr and endVirtAddr to 16 byte boundaries. ++ ++ virt_addr = (void *)((unsigned long)virt_addr & ~0x0fuL ); ++ end_virt_addr = (void *)(( (unsigned long)end_virt_addr + 15uL ) & ~0x0fuL); ++ ++ offset = (int)(long)virt_addr & ( PAGE_SIZE - 1 ); ++ end_offset = (int)(long)end_virt_addr & ( PAGE_SIZE - 1 ); ++ ++ num_pages = (offset + num_bytes + PAGE_SIZE - 1) / PAGE_SIZE; ++ ++ if (( pages = kmalloc( sizeof( struct page *) * num_pages, GFP_KERNEL )) == NULL ) ++ { ++ printk( KERN_ERR "Unable to allocation memory for %d pages\n", num_pages ); ++ return; ++ } ++ ++ down_read( ¤t->mm->mmap_sem ); ++ rc = get_user_pages( current, /* task */ ++ current->mm, /* mm */ ++ (unsigned long)virt_addr, /* start */ ++ num_pages, /* len */ ++ 0, /* write */ ++ 0, /* force */ ++ pages, /* pages (array of pointers to page) */ ++ NULL ); /* vmas */ ++ up_read( ¤t->mm->mmap_sem ); ++ ++ prev_idx = -1; ++ page = NULL; ++ ++ while ( offset < end_offset ) { ++ ++ int page_offset = offset % PAGE_SIZE; ++ page_idx = offset / PAGE_SIZE; ++ ++ if ( page_idx != prev_idx ) { ++ ++ if (page != NULL) { ++ kunmap( page ); ++ } ++ page = pages[page_idx]; ++ kmapped_virt_ptr = kmap( page ); ++ ++ prev_idx = page_idx; ++ } ++ ++ vcos_log_dump_mem_impl( &vchiq_arm_log_category, "ph", ++ (uint32_t)(unsigned long)&kmapped_virt_ptr[page_offset], ++ &kmapped_virt_ptr[page_offset], 16 ); ++ ++ offset += 16; ++ } ++ if (page != NULL) { ++ kunmap( page ); ++ } ++ ++ for ( page_idx = 0; page_idx < num_pages; page_idx++ ) { ++ page_cache_release( pages[page_idx] ); ++ } ++ kfree( pages ); ++} ++ ++/**************************************************************************** ++* + * vchiq_read + * + ***************************************************************************/ +@@ -1204,6 +1320,505 @@ vchiq_fops = { + .read = vchiq_read + }; + ++/* ++ * Autosuspend related functionality ++ */ ++ ++static int vchiq_videocore_wanted(VCHIQ_STATE_T* state) ++{ ++ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state); ++ if(!arm_state) ++ { // autosuspend not supported - always return wanted ++ return 1; ++ } ++ else if(!arm_state->videocore_use_count) ++ { // usage count zero - check for override ++ return vchiq_platform_videocore_wanted(state); ++ } ++ else ++ { // non-zero usage count - videocore still required ++ return 1; ++ } ++} ++ ++ ++/* Called by the lp thread */ ++static void * ++lp_func(void *v) ++{ ++ VCHIQ_STATE_T *state = (VCHIQ_STATE_T *) v; ++ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state); ++ ++ while (1) { ++ vcos_event_wait(&arm_state->lp_evt); ++ ++ vcos_mutex_lock(&arm_state->use_count_mutex); ++ if (!vchiq_videocore_wanted(state)) ++ { ++ arm_state->suspend_pending = 1; ++ } ++ vcos_mutex_unlock(&arm_state->use_count_mutex); ++ ++ vchiq_arm_vcsuspend(state); ++ } ++ return NULL; ++} ++/* Called by the hp thread */ ++static void * ++hp_func(void *v) ++{ ++ VCHIQ_STATE_T *state = (VCHIQ_STATE_T *) v; ++ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state); ++ int send_pending; ++ ++ while (1) { ++ vcos_event_wait(&arm_state->hp_evt); ++ ++ send_pending = 0; ++ ++ vcos_mutex_lock(&arm_state->use_count_mutex); ++ if (vchiq_videocore_wanted(state)) ++ { ++ vchiq_arm_vcresume(state); ++ } ++ if(arm_state->use_notify_pending) ++ { ++ send_pending = arm_state->use_notify_pending; ++ arm_state->use_notify_pending=0; ++ } ++ vcos_mutex_unlock(&arm_state->use_count_mutex); ++ while(send_pending--) ++ { ++ vcos_log_info( "%s sending VCHIQ_MSG_REMOTE_USE_ACTIVE", __func__); ++ if ( vchiq_send_remote_use_active(state) != VCHIQ_SUCCESS) ++ { ++ BUG(); /* vc should be resumed, so shouldn't be a problem sending message */ ++ } ++ } ++ } ++ return NULL; ++} ++ ++VCHIQ_STATUS_T ++vchiq_arm_init_state(VCHIQ_STATE_T* state, VCHIQ_ARM_STATE_T *arm_state) ++{ ++ VCHIQ_STATUS_T status = VCHIQ_SUCCESS; ++ VCOS_THREAD_ATTR_T attrs; ++ char threadname[10]; ++ ++ if(arm_state) ++ { ++ vcos_mutex_create(&arm_state->use_count_mutex, "v.use_count_mutex"); ++ vcos_mutex_create(&arm_state->suspend_resume_mutex, "v.susp_res_mutex"); ++ ++ vcos_event_create(&arm_state->lp_evt, "LP_EVT"); ++ vcos_event_create(&arm_state->hp_evt, "HP_EVT"); ++ ++ vcos_thread_attr_init(&attrs); ++ vcos_thread_attr_setstacksize(&attrs, VCHIQ_ARM_VCSUSPEND_TASK_STACK); ++ vcos_thread_attr_setpriority(&attrs, VCOS_THREAD_PRI_LOWEST); ++ vcos_snprintf(threadname, sizeof(threadname), "VCHIQl-%d", state->id); ++ if(vcos_thread_create(&arm_state->lp_thread, threadname, &attrs, lp_func, state) != VCOS_SUCCESS) ++ { ++ vcos_log_error("vchiq: FATAL: couldn't create thread %s", threadname); ++ status = VCHIQ_ERROR; ++ } ++ else ++ { ++ vcos_thread_attr_init(&attrs); ++ vcos_thread_attr_setstacksize(&attrs, VCHIQ_ARM_VCSUSPEND_TASK_STACK); ++ vcos_thread_attr_setpriority(&attrs, VCOS_THREAD_PRI_HIGHEST); ++ vcos_snprintf(threadname, sizeof(threadname), "VCHIQh-%d", state->id); ++ ++ if(vcos_thread_create(&arm_state->hp_thread, threadname, &attrs, hp_func, state) != VCOS_SUCCESS) ++ { ++ vcos_log_error("vchiq: FATAL: couldn't create thread %s", threadname); ++ status = VCHIQ_ERROR; ++ } ++ } ++ } ++ return status; ++} ++ ++ ++VCHIQ_STATUS_T ++vchiq_arm_vcsuspend(VCHIQ_STATE_T *state) ++{ ++ VCHIQ_STATUS_T status = VCHIQ_SUCCESS; ++ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state); ++ ++ if (state->conn_state != VCHIQ_CONNSTATE_CONNECTED) ++ return VCHIQ_ERROR; ++ ++ if(arm_state->suspend_pending) ++ { ++ vcos_mutex_lock(&arm_state->suspend_resume_mutex); ++ if(arm_state->videocore_suspended) ++ { ++ vcos_log_info("%s - already suspended", __func__); ++ } ++ else ++ { ++ vcos_log_info("%s - suspending", __func__); ++ ++ status = vchiq_platform_suspend(state); ++ arm_state->videocore_suspended = (status == VCHIQ_SUCCESS) ? 1 : 0; ++ ++ vcos_mutex_unlock(&arm_state->suspend_resume_mutex); ++ ++ vcos_mutex_lock(&arm_state->use_count_mutex); ++ if(!arm_state->suspend_pending) ++ { /* Something has changed the suspend_pending state while we were suspending. ++ Run the HP task to check if we need to resume */ ++ vcos_log_info( "%s trigger HP task to check resume", __func__); ++ vcos_event_signal(&arm_state->hp_evt); ++ } ++ arm_state->suspend_pending = 0; ++ vcos_mutex_unlock(&arm_state->use_count_mutex); ++ } ++ } ++ else ++ { ++ vchiq_check_resume(state); ++ } ++ return status; ++} ++ ++ ++VCHIQ_STATUS_T ++vchiq_arm_vcresume(VCHIQ_STATE_T *state) ++{ ++ VCHIQ_STATUS_T status = VCHIQ_SUCCESS; ++ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state); ++ vcos_mutex_lock(&arm_state->suspend_resume_mutex); ++ ++ status = vchiq_platform_resume(state); ++ arm_state->videocore_suspended = (status == VCHIQ_RETRY) ? 1 : 0; ++ ++ vcos_mutex_unlock(&arm_state->suspend_resume_mutex); ++ ++ return status; ++} ++ ++void ++vchiq_check_resume(VCHIQ_STATE_T* state) ++{ ++ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state); ++ vcos_mutex_lock(&arm_state->use_count_mutex); ++ ++ if (arm_state->videocore_suspended && vchiq_videocore_wanted(state)) ++ { /* signal high priority task to resume vc */ ++ vcos_event_signal(&arm_state->hp_evt); ++ } ++ ++ vcos_mutex_unlock(&arm_state->use_count_mutex); ++} ++ ++void ++vchiq_check_suspend(VCHIQ_STATE_T* state) ++{ ++ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state); ++ ++ vcos_mutex_lock(&arm_state->use_count_mutex); ++ ++ if (!arm_state->videocore_suspended && !vchiq_videocore_wanted(state)) ++ { /* signal low priority task to suspend vc */ ++ vcos_event_signal(&arm_state->lp_evt); ++ } ++ ++ vcos_mutex_unlock(&arm_state->use_count_mutex); ++} ++ ++ ++ ++static VCHIQ_STATUS_T ++vchiq_use_internal(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service, int block_while_resume) ++{ ++ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state); ++ VCHIQ_STATUS_T ret = VCHIQ_SUCCESS; ++ char entity[10]; ++ int* entity_uc; ++ ++ if(arm_state) ++ { ++ vcos_mutex_lock(&arm_state->use_count_mutex); ++ ++ if (service) ++ { ++ sprintf(entity, "%c%c%c%c:%03d",VCHIQ_FOURCC_AS_4CHARS(service->base.fourcc), service->client_id); ++ entity_uc = &service->service_use_count; ++ } ++ else ++ { ++ sprintf(entity, "PEER: "); ++ entity_uc = &arm_state->peer_use_count; ++ } ++ ++ if (!arm_state->videocore_suspended && !vchiq_videocore_wanted(state)) ++ { ++#if VCOS_HAVE_TIMER ++ if (vchiq_platform_use_suspend_timer()) ++ { ++ vcos_log_trace( "%s %s - cancel suspend timer", __func__, entity); ++ } ++ vcos_timer_cancel(&g_suspend_timer); ++#endif ++ } ++ ++ arm_state->videocore_use_count++; ++ (*entity_uc)++; ++ arm_state->suspend_pending = 0; ++ ++ if (arm_state->videocore_suspended && vchiq_videocore_wanted(state)) ++ { ++ vcos_log_info( "%s %s count %d, state count %d", __func__, entity, *entity_uc, arm_state->videocore_use_count); ++ if(block_while_resume) ++ { ++ ret = vchiq_arm_vcresume(state); ++ } ++ else ++ { ++ vcos_log_info( "%s trigger HP task to do resume", __func__); /* triggering is done below */ ++ } ++ } ++ else ++ { ++ vcos_log_trace( "%s %s count %d, state count %d", __func__, entity, *entity_uc, arm_state->videocore_use_count); ++ } ++ if(!block_while_resume) ++ { ++ arm_state->use_notify_pending++; ++ vcos_event_signal(&arm_state->hp_evt); /* hp task will check if we need to resume and also send use notify */ ++ } ++ ++ if (ret == VCHIQ_RETRY) ++ { /* if we're told to retry, decrement the counters. VCHIQ_ERROR probably means we're already resumed. */ ++ (*entity_uc)--; ++ arm_state->videocore_use_count--; ++ } ++ ++ vcos_mutex_unlock(&arm_state->use_count_mutex); ++ } ++ return ret; ++} ++ ++static VCHIQ_STATUS_T ++vchiq_release_internal(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service) ++{ ++ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state); ++ VCHIQ_STATUS_T ret = VCHIQ_SUCCESS; ++ char entity[10]; ++ int* entity_uc; ++ ++ if(arm_state) ++ { ++ vcos_mutex_lock(&arm_state->use_count_mutex); ++ ++ if (service) ++ { ++ sprintf(entity, "%c%c%c%c:%03d",VCHIQ_FOURCC_AS_4CHARS(service->base.fourcc), service->client_id); ++ entity_uc = &service->service_use_count; ++ } ++ else ++ { ++ sprintf(entity, "PEER: "); ++ entity_uc = &arm_state->peer_use_count; ++ } ++ ++ if (*entity_uc && arm_state->videocore_use_count) ++ { ++ arm_state->videocore_use_count--; ++ (*entity_uc)--; ++ ++ if (!vchiq_videocore_wanted(state)) ++ { ++#if VCOS_HAVE_TIMER ++ if (vchiq_platform_use_suspend_timer()) ++ { ++ vcos_log_trace( "%s %s count %d, state count %d - starting suspend timer", __func__, entity, *entity_uc, arm_state->videocore_use_count); ++ vcos_timer_cancel(&g_suspend_timer); ++ vcos_timer_set(&g_suspend_timer, SUSPEND_TIMER_TIMEOUT_MS); ++ } ++ else ++#endif ++ { ++ vcos_log_info( "%s %s count %d, state count %d - suspend pending", __func__, entity, *entity_uc, arm_state->videocore_use_count); ++ vcos_event_signal(&arm_state->lp_evt); /* kick the lp thread to do the suspend */ ++ } ++ } ++ else ++ { ++ vcos_log_trace( "%s %s count %d, state count %d", __func__, entity, *entity_uc, arm_state->videocore_use_count); ++ } ++ } ++ else ++ { ++ vcos_log_error( "%s %s ERROR releasing service; count %d, state count %d", __func__, entity, *entity_uc, arm_state->videocore_use_count); ++ ret = VCHIQ_ERROR; ++ } ++ ++ vcos_mutex_unlock(&arm_state->use_count_mutex); ++ } ++ return ret; ++} ++ ++VCHIQ_STATUS_T ++vchiq_on_remote_use(VCHIQ_STATE_T *state) ++{ ++ vcos_log_info("%s state %p", __func__, state); ++ return state ? vchiq_use_internal(state, NULL, 0) : VCHIQ_ERROR; ++} ++ ++VCHIQ_STATUS_T ++vchiq_on_remote_release(VCHIQ_STATE_T *state) ++{ ++ vcos_log_info("%s state %p", __func__, state); ++ return state ? vchiq_release_internal(state, NULL) : VCHIQ_ERROR; ++} ++ ++VCHIQ_STATUS_T ++vchiq_use_service_internal(VCHIQ_SERVICE_T *service) ++{ ++ VCHIQ_STATE_T* state = NULL; ++ ++ if (service) ++ { ++ state = service->state; ++ } ++ ++ if (!service || !state) ++ { ++ return VCHIQ_ERROR; ++ } ++ return vchiq_use_internal(state, service, 1); ++} ++ ++VCHIQ_STATUS_T ++vchiq_release_service_internal(VCHIQ_SERVICE_T *service) ++{ ++ VCHIQ_STATE_T* state = NULL; ++ ++ if (service) ++ { ++ state = service->state; ++ } ++ ++ if (!service || !state) ++ { ++ return VCHIQ_ERROR; ++ } ++ return vchiq_release_internal(state, service); ++} ++ ++ ++#if VCOS_HAVE_TIMER ++static void suspend_timer_callback(void* context) ++{ ++ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state((VCHIQ_STATE_T*)context); ++ vcos_log_info( "%s - suspend pending", __func__); ++ vcos_event_signal(&arm_state->lp_evt); ++} ++#endif ++ ++VCHIQ_STATUS_T ++vchiq_use_service(VCHIQ_SERVICE_HANDLE_T handle) ++{ ++ VCHIQ_STATUS_T ret = VCHIQ_ERROR; ++ VCHIQ_SERVICE_T *service = (VCHIQ_SERVICE_T *) handle; ++ if (service) ++ { ++ ret = vchiq_use_service_internal(service); ++ } ++ return ret; ++} ++ ++VCHIQ_STATUS_T ++vchiq_release_service(VCHIQ_SERVICE_HANDLE_T handle) ++{ ++ VCHIQ_STATUS_T ret = VCHIQ_ERROR; ++ VCHIQ_SERVICE_T *service = (VCHIQ_SERVICE_T *) handle; ++ if (service) ++ { ++ ret = vchiq_release_service_internal(service); ++ } ++ return ret; ++} ++ ++void ++vchiq_dump_service_use_state(VCHIQ_STATE_T *state) ++{ ++ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state); ++ int i; ++ if(arm_state) ++ { ++ vcos_mutex_lock(&arm_state->suspend_resume_mutex); ++ if (arm_state->videocore_suspended) ++ { ++ vcos_log_warn("--VIDEOCORE SUSPENDED--"); ++ } ++ else ++ { ++ vcos_log_warn("--VIDEOCORE AWAKE--"); ++ } ++ for (i = 0; i < state->unused_service; i++) { ++ VCHIQ_SERVICE_T *service_ptr = state->services[i]; ++ if (service_ptr && (service_ptr->srvstate != VCHIQ_SRVSTATE_FREE)) ++ { ++ if (service_ptr->service_use_count) ++ vcos_log_error("----- %c%c%c%c:%d service count %d <-- preventing suspend", VCHIQ_FOURCC_AS_4CHARS(service_ptr->base.fourcc), service_ptr->client_id, service_ptr->service_use_count); ++ else ++ vcos_log_warn("----- %c%c%c%c:%d service count 0", VCHIQ_FOURCC_AS_4CHARS(service_ptr->base.fourcc), service_ptr->client_id); ++ } ++ } ++ vcos_log_warn("----- PEER use count count %d", arm_state->peer_use_count); ++ vcos_log_warn("--- Overall vchiq instance use count %d", arm_state->videocore_use_count); ++ ++ vchiq_dump_platform_use_state(state); ++ ++ vcos_mutex_unlock(&arm_state->suspend_resume_mutex); ++ } ++} ++ ++VCHIQ_STATUS_T ++vchiq_check_service(VCHIQ_SERVICE_T * service) ++{ ++ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(service->state); ++ VCHIQ_STATUS_T ret = VCHIQ_ERROR; ++ /* on 2835 vchiq does not have an arm_state */ ++ if (!arm_state) ++ return VCHIQ_SUCCESS; ++ if (service && arm_state) ++ { ++ vcos_mutex_lock(&arm_state->use_count_mutex); ++ if (!service->service_use_count) ++ { ++ vcos_log_error( "%s ERROR - %c%c%c%c:%d service count %d, state count %d, videocore_suspended %d", __func__,VCHIQ_FOURCC_AS_4CHARS(service->base.fourcc), service->client_id, service->service_use_count, arm_state->videocore_use_count, arm_state->videocore_suspended); ++ vchiq_dump_service_use_state(service->state); ++ vcos_assert(0); // vcos_assert should kill the calling thread, so a user thread shouldn't be able to kill the kernel. ++ } ++ else ++ { ++ ret = VCHIQ_SUCCESS; ++ } ++ vcos_mutex_unlock(&arm_state->use_count_mutex); ++ } ++ return ret; ++} ++ ++/* stub functions */ ++void vchiq_on_remote_use_active(VCHIQ_STATE_T *state) ++{ ++ vcos_unused(state); ++} ++ ++void vchiq_platform_conn_state_changed(VCHIQ_STATE_T *state, VCHIQ_CONNSTATE_T oldstate, VCHIQ_CONNSTATE_T newstate) ++{ ++ vcos_unused(state); ++ vcos_unused(oldstate); ++ vcos_unused(oldstate); ++} ++ ++ + /**************************************************************************** + * + * vchiq_init - called when the module is loaded. +@@ -1250,6 +1865,10 @@ vchiq_init(void) + if (err != 0) + goto failed_platform_init; + ++#if VCOS_HAVE_TIMER ++ vcos_timer_create( &g_suspend_timer, "suspend_timer", suspend_timer_callback, (void*)(&g_state)); ++#endif ++ + vcos_log_error("vchiq: initialised - version %d (min %d), device %d.%d", + VCHIQ_VERSION, VCHIQ_VERSION_MIN, + MAJOR(vchiq_devid), MINOR(vchiq_devid)); +--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.h ++++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.h +@@ -21,6 +21,40 @@ + + #include "vchiq_core.h" + ++ ++typedef struct vchiq_arm_state_struct { ++ ++ VCOS_THREAD_T lp_thread; /* processes low priority messages (eg suspend) */ ++ VCOS_THREAD_T hp_thread; /* processes high priority messages (eg resume) */ ++ ++ VCOS_EVENT_T lp_evt; ++ VCOS_EVENT_T hp_evt; ++ ++ VCOS_MUTEX_T use_count_mutex; ++ VCOS_MUTEX_T suspend_resume_mutex; ++ ++ int suspend_pending; ++ ++ /* Global use count for videocore. ++ * This is equal to the sum of the use counts for all services. When this hits ++ * zero the videocore suspend procedure will be initiated. */ ++ int videocore_use_count; ++ ++ /* Use count to track requests from videocore peer. ++ * This use count is not associated with a service, so needs to be tracked separately ++ * with the state. ++ */ ++ int peer_use_count; ++ ++ /* Flag to indicate whether videocore is currently suspended */ ++ int videocore_suspended; ++ ++ /* Flag to indicate whether a notification is pending back to videocore that it's ++ * "remote use request" has been actioned */ ++ int use_notify_pending; ++} VCHIQ_ARM_STATE_T; ++ ++ + extern VCOS_LOG_CAT_T vchiq_arm_log_category; + + extern int __init +@@ -35,4 +69,50 @@ vchiq_platform_exit(VCHIQ_STATE_T *state + extern VCHIQ_STATE_T * + vchiq_get_state(void); + ++extern VCHIQ_STATUS_T ++vchiq_arm_vcsuspend(VCHIQ_STATE_T *state); ++ ++extern VCHIQ_STATUS_T ++vchiq_arm_vcresume(VCHIQ_STATE_T *state); ++ ++extern VCHIQ_STATUS_T ++vchiq_arm_init_state(VCHIQ_STATE_T *state, VCHIQ_ARM_STATE_T *arm_state); ++ ++extern void ++vchiq_check_resume(VCHIQ_STATE_T* state); ++ ++extern void ++vchiq_check_suspend(VCHIQ_STATE_T* state); ++ ++extern VCHIQ_STATUS_T ++vchiq_use_service(VCHIQ_SERVICE_HANDLE_T handle); ++ ++extern VCHIQ_STATUS_T ++vchiq_release_service(VCHIQ_SERVICE_HANDLE_T handle); ++ ++extern VCHIQ_STATUS_T ++vchiq_check_service(VCHIQ_SERVICE_T * service); ++ ++extern VCHIQ_STATUS_T ++vchiq_platform_suspend(VCHIQ_STATE_T *state); ++ ++extern VCHIQ_STATUS_T ++vchiq_platform_resume(VCHIQ_STATE_T *state); ++ ++extern int ++vchiq_platform_videocore_wanted(VCHIQ_STATE_T* state); ++ ++extern int ++vchiq_platform_use_suspend_timer(void); ++ ++extern void ++vchiq_dump_platform_use_state(VCHIQ_STATE_T *state); ++ ++extern void ++vchiq_dump_service_use_state(VCHIQ_STATE_T *state); ++ ++extern VCHIQ_ARM_STATE_T* ++vchiq_platform_get_arm_state(VCHIQ_STATE_T *state); ++ ++ + #endif /* VCHIQ_ARM_H */ +--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c ++++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c +@@ -30,6 +30,11 @@ + + #define BULK_INDEX(x) (x & (VCHIQ_NUM_SERVICE_BULKS - 1)) + ++ ++/* Used to check use counts allow vchiq use. */ ++extern VCHIQ_STATUS_T vchiq_check_service(VCHIQ_SERVICE_T * service); ++ ++ + typedef struct bulk_waiter_struct + { + VCOS_EVENT_T event; +@@ -114,6 +119,13 @@ vchiq_set_service_state(VCHIQ_SERVICE_T + service->srvstate = newstate; + } + ++static inline int ++is_valid_service(VCHIQ_SERVICE_T *service) ++{ ++ return ((service != NULL) && ++ (service->srvstate != VCHIQ_SRVSTATE_FREE)); ++} ++ + static inline VCHIQ_STATUS_T + make_service_callback(VCHIQ_SERVICE_T *service, VCHIQ_REASON_T reason, + VCHIQ_HEADER_T *header, void *bulk_userdata) +@@ -127,10 +139,12 @@ make_service_callback(VCHIQ_SERVICE_T *s + static inline void + vchiq_set_conn_state(VCHIQ_STATE_T *state, VCHIQ_CONNSTATE_T newstate) + { ++ VCHIQ_CONNSTATE_T oldstate = state->conn_state; + vcos_log_info("%d: %s->%s", state->id, +- conn_state_names[state->conn_state], ++ conn_state_names[oldstate], + conn_state_names[newstate]); + state->conn_state = newstate; ++ vchiq_platform_conn_state_changed(state, oldstate, newstate); + } + + static inline void +@@ -323,7 +337,7 @@ process_free_queue(VCHIQ_STATE_T *state) + + while (slot_queue_available != local->slot_queue_recycle) + { +- int pos; ++ unsigned int pos; + int slot_index = local->slot_queue[slot_queue_available++ & VCHIQ_SLOT_QUEUE_MASK]; + char *data = (char *)SLOT_DATA_FROM_INDEX(state, slot_index); + +@@ -343,17 +357,37 @@ process_free_queue(VCHIQ_STATE_T *state) + if (VCHIQ_MSG_TYPE(msgid) == VCHIQ_MSG_DATA) + { + int port = VCHIQ_MSG_SRCPORT(msgid); ++ VCHIQ_SERVICE_QUOTA_T *service_quota = ++ &state->service_quotas[port]; ++ int count; ++ count = service_quota->message_use_count; ++ if (count > 0) ++ { ++ service_quota->message_use_count = count - 1; ++ if (count == service_quota->message_quota) ++ { ++ /* Signal the service that it has dropped below its quota */ ++ vcos_event_signal(&service_quota->quota_event); ++ } ++ } ++ else ++ { ++ vcos_log_error("service %d message_use_count=%d (header %x," ++ " msgid %x, header->msgid %x, header->size %x)", ++ port, service_quota->message_use_count, ++ (unsigned int)header, msgid, header->msgid, ++ header->size); ++ vcos_assert(0); ++ } + if (!BITSET_IS_SET(service_found, port)) + { +- VCHIQ_SERVICE_QUOTA_T *service_quota = +- &state->service_quotas[port]; +- + /* Set the found bit for this service */ + BITSET_SET(service_found, port); + +- if (service_quota->slot_use_count > 0) ++ count = service_quota->slot_use_count; ++ if (count > 0) + { +- service_quota->slot_use_count--; ++ service_quota->slot_use_count = count - 1; + /* Signal the service in case it has dropped below its quota */ + vcos_event_signal(&service_quota->quota_event); + vcos_log_trace("%d: pfq:%d %x@%x - slot_use->%d", +@@ -376,7 +410,7 @@ process_free_queue(VCHIQ_STATE_T *state) + pos += calc_stride(header->size); + if (pos > VCHIQ_SLOT_SIZE) + { +- vcos_log_error("pos %x: header %x, msgid %x, header->msgid %x, header->size %x", ++ vcos_log_error("pfq - pos %x: header %x, msgid %x, header->msgid %x, header->size %x", + pos, (unsigned int)header, msgid, header->msgid, header->size); + vcos_assert(0); + } +@@ -431,20 +465,21 @@ queue_message(VCHIQ_STATE_T *state, VCHI + + service_quota = &state->service_quotas[service->localport]; + +- /* ...ensure it doesn't use more than its quota of slots */ +- while ((tx_end_index != service_quota->previous_tx_index) && +- (service_quota->slot_use_count == service_quota->slot_quota)) ++ /* ...ensure it doesn't use more than its quota of messages or slots */ ++ while ((service_quota->message_use_count == service_quota->message_quota) || ++ ((tx_end_index != service_quota->previous_tx_index) && ++ (service_quota->slot_use_count == service_quota->slot_quota))) + { +- vcos_log_trace("%d: qm:%d %s,%x - quota stall", ++ vcos_log_trace("%d: qm:%d %s,%x - quota stall (msg %d, slot %d)", + state->id, service->localport, +- msg_type_str(VCHIQ_MSG_TYPE(msgid)), size); ++ msg_type_str(VCHIQ_MSG_TYPE(msgid)), size, ++ service_quota->message_use_count, service_quota->slot_use_count); + VCHIQ_SERVICE_STATS_INC(service, quota_stalls); + vcos_mutex_unlock(&state->slot_mutex); + if (vcos_event_wait(&service_quota->quota_event) != VCOS_SUCCESS) + return VCHIQ_RETRY; + if (vcos_mutex_lock(&state->slot_mutex) != VCOS_SUCCESS) + return VCHIQ_RETRY; +- vcos_assert(service_quota->slot_use_count <= service_quota->slot_quota); + tx_end_index = SLOT_QUEUE_INDEX_FROM_POS(state->local_tx_pos + stride - 1); + } + } +@@ -498,6 +533,7 @@ queue_message(VCHIQ_STATE_T *state, VCHI + } + + service_quota->previous_tx_index = tx_end_index; ++ service_quota->message_use_count++; + VCHIQ_SERVICE_STATS_INC(service, ctrl_tx_count); + VCHIQ_SERVICE_STATS_ADD(service, ctrl_tx_bytes, size); + } else { +@@ -1232,6 +1268,17 @@ parse_rx_slots(VCHIQ_STATE_T *state) + vchiq_set_conn_state(state, VCHIQ_CONNSTATE_CONNECTED); + vchiq_platform_resumed(state); + break; ++ ++ case VCHIQ_MSG_REMOTE_USE: ++ vchiq_on_remote_use(state); ++ break; ++ case VCHIQ_MSG_REMOTE_RELEASE: ++ vchiq_on_remote_release(state); ++ break; ++ case VCHIQ_MSG_REMOTE_USE_ACTIVE: ++ vchiq_on_remote_use_active(state); ++ break; ++ + default: + vcos_log_error("%d: prs invalid msgid %x@%x,%x", + state->id, msgid, (unsigned int)header, size); +@@ -1326,8 +1373,6 @@ slot_handler_func(void *v) + return NULL; + } + +-extern VCHIQ_STATUS_T +-vchiq_platform_suspend(VCHIQ_STATE_T *state); + + /* Called by the recycle thread */ + static void * +@@ -1348,23 +1393,6 @@ recycle_func(void *v) + return NULL; + } + +-/* Called by the lp thread */ +-static void * +-lp_func(void *v) +-{ +- VCHIQ_STATE_T *state = (VCHIQ_STATE_T *) v; +- +- while (1) { +- vcos_event_wait(&state->lp_evt); +- vcos_mutex_lock(&state->use_count_mutex); +- if (state->videocore_use_count == 0) +- { +- vchiq_platform_suspend(state); +- } +- vcos_mutex_unlock(&state->use_count_mutex); +- } +- return NULL; +-} + + static void + init_bulk_queue(VCHIQ_BULK_QUEUE_T *queue) +@@ -1417,6 +1445,7 @@ vchiq_init_state(VCHIQ_STATE_T *state, V + VCHIQ_SHARED_STATE_T *local; + VCHIQ_SHARED_STATE_T *remote; + VCOS_THREAD_ATTR_T attrs; ++ VCHIQ_STATUS_T status; + char threadname[10]; + static int id = 0; + int i; +@@ -1426,7 +1455,7 @@ vchiq_init_state(VCHIQ_STATE_T *state, V + vcos_log_register("vchiq_core", &vchiq_core_log_category); + vcos_log_register("vchiq_core_msg", &vchiq_core_msg_log_category); + +- vcos_log_warn( "%s: slot_zero = 0x%08lx, is_master = %d\n", __func__, (unsigned long)slot_zero, is_master ); ++ vcos_log_warn( "%s: slot_zero = 0x%08lx, is_master = %d", __func__, (unsigned long)slot_zero, is_master ); + + /* Check the input configuration */ + +@@ -1501,6 +1530,7 @@ vchiq_init_state(VCHIQ_STATE_T *state, V + } + + memset(state, 0, sizeof(VCHIQ_STATE_T)); ++ vcos_log_warn( "%s: called", __func__); + state->id = id++; + state->is_master = is_master; + +@@ -1523,8 +1553,6 @@ vchiq_init_state(VCHIQ_STATE_T *state, V + + vcos_mutex_create(&state->slot_mutex, "v.slot_mutex"); + vcos_mutex_create(&state->recycle_mutex, "v.recycle_mutex"); +- vcos_mutex_create(&state->use_count_mutex, "v.use_count_mutex"); +- vcos_mutex_create(&state->suspend_resume_mutex, "v.susp_res_mutex"); + + vcos_event_create(&state->slot_available_event, "v.slot_available_event"); + vcos_event_create(&state->slot_remove_event, "v.slot_remove_event"); +@@ -1543,6 +1571,7 @@ vchiq_init_state(VCHIQ_STATE_T *state, V + } + + state->default_slot_quota = state->slot_queue_available/2; ++ state->default_message_quota = vcos_min(state->default_slot_quota * 256, (unsigned short)~0); + + local->trigger.event = &state->trigger_event; + remote_event_create(&local->trigger); +@@ -1552,8 +1581,6 @@ vchiq_init_state(VCHIQ_STATE_T *state, V + remote_event_create(&local->recycle); + local->slot_queue_recycle = state->slot_queue_available; + +- vcos_event_create(&state->lp_evt, "LP_EVT"); +- + local->debug[DEBUG_ENTRIES] = DEBUG_MAX; + + /* +@@ -1566,7 +1593,10 @@ vchiq_init_state(VCHIQ_STATE_T *state, V + vcos_snprintf(threadname, sizeof(threadname), "VCHIQ-%d", state->id); + if (vcos_thread_create(&state->slot_handler_thread, threadname, + &attrs, slot_handler_func, state) != VCOS_SUCCESS) ++ { ++ vcos_log_error("vchiq: FATAL: couldn't create thread %s", threadname); + return VCHIQ_ERROR; ++ } + + vcos_thread_attr_init(&attrs); + vcos_thread_attr_setstacksize(&attrs, VCHIQ_SLOT_HANDLER_STACK); +@@ -1574,20 +1604,17 @@ vchiq_init_state(VCHIQ_STATE_T *state, V + vcos_snprintf(threadname, sizeof(threadname), "VCHIQr-%d", state->id); + if (vcos_thread_create(&state->recycle_thread, threadname, + &attrs, recycle_func, state) != VCOS_SUCCESS) ++ { ++ vcos_log_error("vchiq: FATAL: couldn't create thread %s", threadname); + return VCHIQ_ERROR; ++ } + +- vcos_thread_attr_init(&attrs); +- vcos_thread_attr_setstacksize(&attrs, VCHIQ_SLOT_HANDLER_STACK); +- vcos_thread_attr_setpriority(&attrs, VCOS_THREAD_PRI_LOWEST); +- vcos_snprintf(threadname, sizeof(threadname), "VCHIQl-%d", state->id); +- if (vcos_thread_create(&state->lp_thread, threadname, +- &attrs, lp_func, state) != VCOS_SUCCESS) +- return VCHIQ_ERROR; ++ status = vchiq_platform_init_state(state); + + /* Indicate readiness to the other side */ + local->initialised = 1; + +- return VCHIQ_SUCCESS; ++ return status; + } + + /* Called from application thread when a client or server service is created. */ +@@ -1684,6 +1711,7 @@ vchiq_add_service_internal(VCHIQ_STATE_T + init_bulk_queue(&service->bulk_tx); + init_bulk_queue(&service->bulk_rx); + service_quota->slot_quota = state->default_slot_quota; ++ service_quota->message_quota = state->default_message_quota; + if (service_quota->slot_use_count == 0) + service_quota->previous_tx_index = + SLOT_QUEUE_INDEX_FROM_POS(state->local_tx_pos) - 1; +@@ -1833,9 +1861,13 @@ vchiq_close_service_internal(VCHIQ_SERVI + + if (service->srvstate == VCHIQ_SRVSTATE_CLOSING) + { ++ int i; ++ int uc = service->service_use_count; + /* Complete the close process */ +- vchiq_release_service(&service->base); +- ++ for( i=0; i<uc; i++) ++ { /* cater for cases where close is forced and the client may not close all it's handles */ ++ vchiq_release_service_internal(service); ++ } + service->client_id = 0; + + /* Now tell the client that the services is closed */ +@@ -1912,7 +1944,7 @@ vchiq_free_service_internal(VCHIQ_SERVIC + if (slot_info->release_count != slot_info->use_count) + { + char *data = (char *)SLOT_DATA_FROM_INDEX(state, i); +- int pos, end; ++ unsigned int pos, end; + + end = VCHIQ_SLOT_SIZE; + if (data == state->rx_data) +@@ -1938,6 +1970,12 @@ vchiq_free_service_internal(VCHIQ_SERVIC + } + } + pos += calc_stride(header->size); ++ if (pos > VCHIQ_SLOT_SIZE) ++ { ++ vcos_log_error("fsi - pos %x: header %x, msgid %x, header->msgid %x, header->size %x", ++ pos, (unsigned int)header, msgid, header->msgid, header->size); ++ vcos_assert(0); ++ } + } + } + } +@@ -2050,7 +2088,7 @@ vchiq_close_service(VCHIQ_SERVICE_HANDLE + VCHIQ_SERVICE_T *service = (VCHIQ_SERVICE_T *) handle; + VCHIQ_STATUS_T status = VCHIQ_ERROR; + +- if (service == NULL) ++ if (!is_valid_service(service)) + return VCHIQ_ERROR; + + vcos_log_info("%d: close_service:%d", service->state->id, service->localport); +@@ -2080,7 +2118,7 @@ vchiq_remove_service(VCHIQ_SERVICE_HANDL + VCHIQ_SERVICE_T *service = (VCHIQ_SERVICE_T *) handle; + VCHIQ_STATUS_T status = VCHIQ_SUCCESS; + +- if (service == NULL) ++ if (!is_valid_service(service)) + return VCHIQ_ERROR; + + vcos_log_info("%d: remove_service:%d", service->state->id, service->localport); +@@ -2137,15 +2175,14 @@ vchiq_bulk_transfer(VCHIQ_SERVICE_T *ser + const int dir_msgtype = (dir == VCHIQ_BULK_TRANSMIT) ? VCHIQ_MSG_BULK_TX : VCHIQ_MSG_BULK_RX; + VCHIQ_STATUS_T status = VCHIQ_ERROR; + +- if ((service == NULL) || +- ((memhandle == VCHI_MEM_HANDLE_INVALID) && (offset == NULL))) ++ if (!is_valid_service(service) || ++ (service->srvstate != VCHIQ_SRVSTATE_OPEN) || ++ ((memhandle == VCHI_MEM_HANDLE_INVALID) && (offset == NULL)) || ++ (vchiq_check_service(service) != VCHIQ_SUCCESS)) + return VCHIQ_ERROR; + + state = service->state; + +- if (service->srvstate != VCHIQ_SRVSTATE_OPEN) +- return VCHIQ_ERROR; /* Must be connected */ +- + if (vcos_mutex_lock(&service->bulk_mutex) != VCOS_SUCCESS) + return VCHIQ_RETRY; + +@@ -2325,8 +2362,9 @@ vchiq_queue_message(VCHIQ_SERVICE_HANDLE + unsigned int size = 0; + unsigned int i; + +- if ((service == NULL) || +- (service->srvstate != VCHIQ_SRVSTATE_OPEN)) ++ if (!is_valid_service(service) || ++ (service->srvstate != VCHIQ_SRVSTATE_OPEN) || ++ (vchiq_check_service(service) != VCHIQ_SUCCESS)) + return VCHIQ_ERROR; + + for (i = 0; i < (unsigned int)count; i++) +@@ -2361,7 +2399,7 @@ vchiq_release_message(VCHIQ_SERVICE_HAND + int slot_index; + int msgid; + +- if (service == NULL) ++ if (!is_valid_service(service)) + return; + + state = service->state; +@@ -2418,7 +2456,7 @@ vchiq_set_service_option(VCHIQ_SERVICE_H + VCHIQ_SERVICE_T *service = (VCHIQ_SERVICE_T *)handle; + VCHIQ_STATUS_T status = VCHIQ_ERROR; + +- if (service) ++ if (is_valid_service(service)) + { + switch (option) + { +@@ -2427,6 +2465,48 @@ vchiq_set_service_option(VCHIQ_SERVICE_H + status = VCHIQ_SUCCESS; + break; + ++ case VCHIQ_SERVICE_OPTION_SLOT_QUOTA: ++ { ++ VCHIQ_SERVICE_QUOTA_T *service_quota = ++ &service->state->service_quotas[service->localport]; ++ if (value == 0) ++ value = service->state->default_slot_quota; ++ if ((value >= service_quota->slot_use_count) && ++ (value < (unsigned short)~0)) ++ { ++ service_quota->slot_quota = value; ++ if ((value >= service_quota->slot_use_count) && ++ (service_quota->message_quota >= service_quota->message_use_count)) ++ { ++ /* Signal the service that it may have dropped below its quota */ ++ vcos_event_signal(&service_quota->quota_event); ++ } ++ status = VCHIQ_SUCCESS; ++ } ++ } ++ break; ++ ++ case VCHIQ_SERVICE_OPTION_MESSAGE_QUOTA: ++ { ++ VCHIQ_SERVICE_QUOTA_T *service_quota = ++ &service->state->service_quotas[service->localport]; ++ if (value == 0) ++ value = service->state->default_message_quota; ++ if ((value >= service_quota->message_use_count) && ++ (value < (unsigned short)~0)) ++ { ++ service_quota->message_quota = value; ++ if ((value >= service_quota->message_use_count) && ++ (service_quota->slot_quota >= service_quota->slot_use_count)) ++ { ++ /* Signal the service that it may have dropped below its quota */ ++ vcos_event_signal(&service_quota->quota_event); ++ } ++ status = VCHIQ_SUCCESS; ++ } ++ } ++ break; ++ + default: + break; + } +@@ -2568,9 +2648,11 @@ vchiq_dump_service_state(void *dump_cont + vcos_strcpy(remoteport, "n/a"); + + len += vcos_snprintf(buf + len, sizeof(buf) - len, +- " '%c%c%c%c' remote %s (slot use %d/%d)", ++ " '%c%c%c%c' remote %s (msg use %d/%d, slot use %d/%d)", + VCHIQ_FOURCC_AS_4CHARS(fourcc), + remoteport, ++ service_quota->message_use_count, ++ service_quota->message_quota, + service_quota->slot_use_count, + service_quota->slot_quota); + +@@ -2602,3 +2684,34 @@ vchiq_dump_service_state(void *dump_cont + + vchiq_dump_platform_service_state(dump_context, service); + } ++ ++ ++VCHIQ_STATUS_T vchiq_send_remote_use(VCHIQ_STATE_T * state) ++{ ++ VCHIQ_STATUS_T status = VCHIQ_RETRY; ++ if(state->conn_state != VCHIQ_CONNSTATE_DISCONNECTED) ++ { ++ status = queue_message(state, NULL, VCHIQ_MAKE_MSG(VCHIQ_MSG_REMOTE_USE, 0, 0), NULL, 0, 0, 0); ++ } ++ return status; ++} ++ ++VCHIQ_STATUS_T vchiq_send_remote_release(VCHIQ_STATE_T * state) ++{ ++ VCHIQ_STATUS_T status = VCHIQ_RETRY; ++ if(state->conn_state != VCHIQ_CONNSTATE_DISCONNECTED) ++ { ++ status = queue_message(state, NULL, VCHIQ_MAKE_MSG(VCHIQ_MSG_REMOTE_RELEASE, 0, 0), NULL, 0, 0, 0); ++ } ++ return status; ++} ++ ++VCHIQ_STATUS_T vchiq_send_remote_use_active(VCHIQ_STATE_T * state) ++{ ++ VCHIQ_STATUS_T status = VCHIQ_RETRY; ++ if(state->conn_state != VCHIQ_CONNSTATE_DISCONNECTED) ++ { ++ status = queue_message(state, NULL, VCHIQ_MAKE_MSG(VCHIQ_MSG_REMOTE_USE_ACTIVE, 0, 0), NULL, 0, 0, 0); ++ } ++ return status; ++} +--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.h ++++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.h +@@ -47,6 +47,9 @@ vcos_static_assert(IS_POW2(VCHIQ_MAX_SLO + #define VCHIQ_MSG_BULK_TX_DONE 9 // + (srcport, dstport), actual + #define VCHIQ_MSG_PAUSE 10 // - + #define VCHIQ_MSG_RESUME 11 // - ++#define VCHIQ_MSG_REMOTE_USE 12 // - ++#define VCHIQ_MSG_REMOTE_RELEASE 13 // - ++#define VCHIQ_MSG_REMOTE_USE_ACTIVE 14 // - + + #define VCHIQ_PORT_MAX (VCHIQ_MAX_SERVICES - 1) + #define VCHIQ_PORT_FREE 0x1000 +@@ -194,6 +197,8 @@ typedef struct remote_event_struct { + VCOS_EVENT_T * event; + } REMOTE_EVENT_T; + ++typedef struct opaque_platform_state_t* VCHIQ_PLATFORM_STATE_T; ++ + typedef struct vchiq_state_struct VCHIQ_STATE_T; + + typedef struct vchiq_slot_struct { +@@ -253,8 +258,10 @@ typedef struct vchiq_service_struct { + usage is carried over between users of the same port number. + */ + typedef struct vchiq_service_quota_struct { +- int slot_quota; +- int slot_use_count; ++ unsigned short slot_quota; ++ unsigned short slot_use_count; ++ unsigned short message_quota; ++ unsigned short message_use_count; + VCOS_EVENT_T quota_event; + int previous_tx_index; + } VCHIQ_SERVICE_QUOTA_T; +@@ -314,7 +321,8 @@ struct vchiq_state_struct { + VCHIQ_SHARED_STATE_T *remote; + VCHIQ_SLOT_T *slot_data; + +- int default_slot_quota; ++ unsigned short default_slot_quota; ++ unsigned short default_message_quota; + + VCOS_EVENT_T connect; // event indicating connect message received + VCOS_MUTEX_T mutex; // mutex protecting services +@@ -322,7 +330,6 @@ struct vchiq_state_struct { + + VCOS_THREAD_T slot_handler_thread; // processes incoming messages + VCOS_THREAD_T recycle_thread; // processes recycled slots +- VCOS_THREAD_T lp_thread; // processes low priority messages (eg suspend) + + /* Local implementation of the trigger remote event */ + VCOS_EVENT_T trigger_event; +@@ -330,8 +337,6 @@ struct vchiq_state_struct { + /* Local implementation of the recycle remote event */ + VCOS_EVENT_T recycle_event; + +- VCOS_EVENT_T lp_evt; +- + char *tx_data; + char *rx_data; + VCHIQ_SLOT_INFO_T *rx_info; +@@ -340,17 +345,6 @@ struct vchiq_state_struct { + + VCOS_MUTEX_T recycle_mutex; + +- VCOS_MUTEX_T suspend_resume_mutex; +- VCOS_MUTEX_T use_count_mutex; +- +- /* Global use count for videocore. +- * This is equal to the sum of the use counts for all services. When this hits +- * zero the videocore suspend procedure will be initiated. */ +- int videocore_use_count; +- +- /* Flag to indicate whether videocore is currently suspended */ +- int videocore_suspended; +- + /* Indicates the byte position within the stream from where the next message + will be read. The least significant bits are an index into the slot. + The next bits are the index of the slot in remote->slot_queue. */ +@@ -388,6 +382,8 @@ struct vchiq_state_struct { + VCHIQ_SERVICE_T *services[VCHIQ_MAX_SERVICES]; + VCHIQ_SERVICE_QUOTA_T service_quotas[VCHIQ_MAX_SERVICES]; + VCHIQ_SLOT_INFO_T slot_info[VCHIQ_MAX_SLOTS]; ++ ++ VCHIQ_PLATFORM_STATE_T platform_state; + }; + + extern VCHIQ_SLOT_ZERO_T * +@@ -477,4 +473,34 @@ extern void + vchiq_dump_platform_service_state(void *dump_context, + VCHIQ_SERVICE_T *service); + ++extern VCHIQ_STATUS_T ++vchiq_use_service_internal(VCHIQ_SERVICE_T *service); ++ ++extern VCHIQ_STATUS_T ++vchiq_release_service_internal(VCHIQ_SERVICE_T *service); ++ ++extern VCHIQ_STATUS_T ++vchiq_on_remote_use(VCHIQ_STATE_T *state); ++ ++extern VCHIQ_STATUS_T ++vchiq_on_remote_release(VCHIQ_STATE_T *state); ++ ++extern VCHIQ_STATUS_T ++vchiq_platform_init_state(VCHIQ_STATE_T *state); ++ ++extern void ++vchiq_on_remote_use_active(VCHIQ_STATE_T *state); ++ ++extern VCHIQ_STATUS_T ++vchiq_send_remote_use(VCHIQ_STATE_T * state); ++ ++extern VCHIQ_STATUS_T ++vchiq_send_remote_release(VCHIQ_STATE_T * state); ++ ++extern VCHIQ_STATUS_T ++vchiq_send_remote_use_active(VCHIQ_STATE_T * state); ++ ++extern void ++vchiq_platform_conn_state_changed(VCHIQ_STATE_T* state, VCHIQ_CONNSTATE_T oldstate, VCHIQ_CONNSTATE_T newstate); ++ + #endif +--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_if.h ++++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_if.h +@@ -55,7 +55,9 @@ typedef enum + + typedef enum + { +- VCHIQ_SERVICE_OPTION_AUTOCLOSE ++ VCHIQ_SERVICE_OPTION_AUTOCLOSE, ++ VCHIQ_SERVICE_OPTION_SLOT_QUOTA, ++ VCHIQ_SERVICE_OPTION_MESSAGE_QUOTA + } VCHIQ_SERVICE_OPTION_T; + + #ifdef __HIGHC__ +@@ -94,11 +96,11 @@ typedef struct vchiq_service_base_struct + } VCHIQ_SERVICE_BASE_T; + + typedef struct vchiq_service_params_struct { +- int fourcc; +- VCHIQ_CALLBACK_T callback; +- void *userdata; +- short version; /* Increment for non-trivial changes */ +- short version_min; /* Update for incompatible changes */ ++ int fourcc; ++ VCHIQ_CALLBACK_T callback; ++ void *userdata; ++ short version; /* Increment for non-trivial changes */ ++ short version_min; /* Update for incompatible changes */ + } VCHIQ_SERVICE_PARAMS_T; + + typedef struct vchiq_config_struct { +@@ -112,6 +114,8 @@ typedef struct vchiq_config_struct { + } VCHIQ_CONFIG_T; + + typedef struct vchiq_instance_struct *VCHIQ_INSTANCE_T; ++typedef void (*VCHIQ_REMOTE_USE_CALLBACK_T)(void* cb_arg); ++ + + extern VCHIQ_STATUS_T vchiq_initialise(VCHIQ_INSTANCE_T *pinstance); + extern VCHIQ_STATUS_T vchiq_shutdown(VCHIQ_INSTANCE_T instance); +@@ -143,6 +147,9 @@ extern int vchiq_get_client_i + extern VCHIQ_STATUS_T vchiq_get_config(VCHIQ_INSTANCE_T instance, int config_size, VCHIQ_CONFIG_T *pconfig); + extern VCHIQ_STATUS_T vchiq_set_service_option(VCHIQ_SERVICE_HANDLE_T service, VCHIQ_SERVICE_OPTION_T option, int value); + ++extern VCHIQ_STATUS_T vchiq_remote_use(VCHIQ_INSTANCE_T instance, VCHIQ_REMOTE_USE_CALLBACK_T callback, void* cb_arg); ++extern VCHIQ_STATUS_T vchiq_remote_release(VCHIQ_INSTANCE_T instance); ++ + extern VCHIQ_STATUS_T vchiq_dump_phys_mem( VCHIQ_SERVICE_HANDLE_T service, void *ptr, size_t num_bytes ); + + #endif /* VCHIQ_IF_H */ +--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_ioctl.h ++++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_ioctl.h +@@ -91,15 +91,15 @@ typedef struct { + #define VCHIQ_IOC_QUEUE_MESSAGE _IOW(VCHIQ_IOC_MAGIC, 4, VCHIQ_QUEUE_MESSAGE_T) + #define VCHIQ_IOC_QUEUE_BULK_TRANSMIT _IOW(VCHIQ_IOC_MAGIC, 5, VCHIQ_QUEUE_BULK_TRANSFER_T) + #define VCHIQ_IOC_QUEUE_BULK_RECEIVE _IOW(VCHIQ_IOC_MAGIC, 6, VCHIQ_QUEUE_BULK_TRANSFER_T) +-#define VCHIQ_IOC_AWAIT_COMPLETION _IOW(VCHIQ_IOC_MAGIC, 7, VCHIQ_AWAIT_COMPLETION_T) +-#define VCHIQ_IOC_DEQUEUE_MESSAGE _IOW(VCHIQ_IOC_MAGIC, 8, VCHIQ_DEQUEUE_MESSAGE_T) ++#define VCHIQ_IOC_AWAIT_COMPLETION _IOWR(VCHIQ_IOC_MAGIC, 7, VCHIQ_AWAIT_COMPLETION_T) ++#define VCHIQ_IOC_DEQUEUE_MESSAGE _IOWR(VCHIQ_IOC_MAGIC, 8, VCHIQ_DEQUEUE_MESSAGE_T) + #define VCHIQ_IOC_GET_CLIENT_ID _IO(VCHIQ_IOC_MAGIC, 9) +-#define VCHIQ_IOC_GET_CONFIG _IOW(VCHIQ_IOC_MAGIC, 10, VCHIQ_GET_CONFIG_T) +-#define VCHIQ_IOC_CLOSE_SERVICE _IO(VCHIQ_IOC_MAGIC, 11) +-#define VCHIQ_IOC_USE_SERVICE _IO(VCHIQ_IOC_MAGIC, 12) +-#define VCHIQ_IOC_RELEASE_SERVICE _IO(VCHIQ_IOC_MAGIC, 13) +-#define VCHIQ_IOC_SET_SERVICE_OPTION _IOW(VCHIQ_IOC_MAGIC, 14, VCHIQ_SET_SERVICE_OPTION_T) +-#define VCHIQ_IOC_DUMP_PHYS_MEM _IOW(VCHIQ_IOC_MAGIC, 15, VCHIQ_DUMP_MEM_T) ++#define VCHIQ_IOC_GET_CONFIG _IOWR(VCHIQ_IOC_MAGIC, 10, VCHIQ_GET_CONFIG_T) ++#define VCHIQ_IOC_CLOSE_SERVICE _IO(VCHIQ_IOC_MAGIC, 11) ++#define VCHIQ_IOC_USE_SERVICE _IO(VCHIQ_IOC_MAGIC, 12) ++#define VCHIQ_IOC_RELEASE_SERVICE _IO(VCHIQ_IOC_MAGIC, 13) ++#define VCHIQ_IOC_SET_SERVICE_OPTION _IOW(VCHIQ_IOC_MAGIC, 14, VCHIQ_SET_SERVICE_OPTION_T) ++#define VCHIQ_IOC_DUMP_PHYS_MEM _IOW(VCHIQ_IOC_MAGIC, 15, VCHIQ_DUMP_MEM_T) + #define VCHIQ_IOC_MAX 15 + + #endif +--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_lib.c ++++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_lib.c +@@ -97,6 +97,12 @@ is_valid_instance(VCHIQ_INSTANCE_T insta + return (instance == &vchiq_instance) && (instance->initialised > 0); + } + ++static __inline int ++is_valid_service(VCHIQ_SERVICE_T *service) ++{ ++ return ((service != NULL) && (service->fd != VCHIQ_INVALID_HANDLE)); ++} ++ + /* + * VCHIQ API + */ +@@ -318,6 +324,9 @@ vchiq_close_service(VCHIQ_SERVICE_HANDLE + + vcos_log_trace( "%s called service handle = 0x%08x", __func__, (uint32_t)handle ); + ++ if (!is_valid_service(service)) ++ return VCHIQ_ERROR; ++ + RETRY(ret,ioctl(service->fd, VCHIQ_IOC_CLOSE_SERVICE, service->handle)); + + if (ret != 0) +@@ -335,6 +344,9 @@ vchiq_remove_service(VCHIQ_SERVICE_HANDL + + vcos_log_trace( "%s called service handle = 0x%08x", __func__, (uint32_t)handle ); + ++ if (!is_valid_service(service)) ++ return VCHIQ_ERROR; ++ + RETRY(ret,ioctl(service->fd, VCHIQ_IOC_REMOVE_SERVICE, service->handle)); + + if (ret != 0) +@@ -355,6 +367,9 @@ vchiq_queue_message(VCHIQ_SERVICE_HANDLE + + vcos_log_trace( "%s called service handle = 0x%08x", __func__, (uint32_t)handle ); + ++ if (!is_valid_service(service)) ++ return VCHIQ_ERROR; ++ + args.handle = service->handle; + args.elements = elements; + args.count = count; +@@ -384,6 +399,9 @@ vchiq_queue_bulk_transmit(VCHIQ_SERVICE_ + + vcos_log_trace( "%s called service handle = 0x%08x", __func__, (uint32_t)handle ); + ++ if (!is_valid_service(service)) ++ return VCHIQ_ERROR; ++ + args.handle = service->handle; + args.data = (void *)data; + args.size = size; +@@ -406,6 +424,9 @@ vchiq_queue_bulk_receive(VCHIQ_SERVICE_H + + vcos_log_trace( "%s called service handle = 0x%08x", __func__, (uint32_t)handle ); + ++ if (!is_valid_service(service)) ++ return VCHIQ_ERROR; ++ + args.handle = service->handle; + args.data = data; + args.size = size; +@@ -457,6 +478,9 @@ vchiq_bulk_transmit(VCHIQ_SERVICE_HANDLE + + vcos_log_trace( "%s called service handle = 0x%08x", __func__, (uint32_t)handle ); + ++ if (!is_valid_service(service)) ++ return VCHIQ_ERROR; ++ + args.handle = service->handle; + args.data = (void *)data; + args.size = size; +@@ -480,6 +504,9 @@ vchiq_bulk_receive(VCHIQ_SERVICE_HANDLE_ + + vcos_log_trace( "%s called service handle = 0x%08x", __func__, (uint32_t)handle ); + ++ if (!is_valid_service(service)) ++ return VCHIQ_ERROR; ++ + args.handle = service->handle; + args.data = data; + args.size = size; +@@ -521,6 +548,9 @@ vchiq_get_client_id(VCHIQ_SERVICE_HANDLE + { + VCHIQ_SERVICE_T *service = (VCHIQ_SERVICE_T *)handle; + ++ if (!is_valid_service(service)) ++ return VCHIQ_ERROR; ++ + return ioctl(service->fd, VCHIQ_IOC_GET_CLIENT_ID, service->handle); + } + +@@ -546,10 +576,14 @@ vchiq_get_config(VCHIQ_INSTANCE_T instan + int32_t + vchiq_use_service( const VCHIQ_SERVICE_HANDLE_T handle ) + { +- VCHIQ_SERVICE_T *service = (VCHIQ_SERVICE_T *)handle; +- int ret; +- RETRY(ret,ioctl(service->fd, VCHIQ_IOC_USE_SERVICE, service->handle)); +- return ret; ++ VCHIQ_SERVICE_T *service = (VCHIQ_SERVICE_T *)handle; ++ int ret; ++ ++ if (!is_valid_service(service)) ++ return VCHIQ_ERROR; ++ ++ RETRY(ret,ioctl(service->fd, VCHIQ_IOC_USE_SERVICE, service->handle)); ++ return ret; + } + + int32_t +@@ -569,6 +603,9 @@ vchiq_set_service_option(VCHIQ_SERVICE_H + VCHIQ_SERVICE_T *service = (VCHIQ_SERVICE_T *)handle; + int ret; + ++ if (!is_valid_service(service)) ++ return VCHIQ_ERROR; ++ + args.handle = service->handle; + args.option = option; + args.value = value; +@@ -633,6 +670,9 @@ vchi_msg_peek( VCHI_SERVICE_HANDLE_T han + VCHI_SERVICE_T *service = (VCHI_SERVICE_T *)handle; + int ret; + ++ if (!is_valid_service(service)) ++ return VCHIQ_ERROR; ++ + ret = fill_peek_buf(service, flags); + + if (ret == 0) +@@ -659,6 +699,9 @@ vchi_msg_remove( VCHI_SERVICE_HANDLE_T h + { + VCHI_SERVICE_T *service = (VCHI_SERVICE_T *)handle; + ++ if (!is_valid_service(service)) ++ return VCHIQ_ERROR; ++ + /* Why would you call vchi_msg_remove without calling vchi_msg_peek first? */ + vcos_assert(service->peek_size >= 0); + +@@ -697,6 +740,9 @@ vchi_msg_queue( VCHI_SERVICE_HANDLE_T ha + vcos_unused(msg_handle); + vcos_assert(flags == VCHI_FLAGS_BLOCK_UNTIL_QUEUED); + ++ if (!is_valid_service(service)) ++ return VCHIQ_ERROR; ++ + args.handle = service->handle; + args.elements = &element; + args.count = 1; +@@ -730,6 +776,9 @@ vchi_bulk_queue_receive( VCHI_SERVICE_HA + VCHIQ_QUEUE_BULK_TRANSFER_T args; + int ret; + ++ if (!is_valid_service(service)) ++ return VCHIQ_ERROR; ++ + switch ((int)flags) { + case VCHI_FLAGS_CALLBACK_WHEN_OP_COMPLETE | VCHI_FLAGS_BLOCK_UNTIL_QUEUED: + args.mode = VCHIQ_BULK_MODE_CALLBACK; +@@ -780,6 +829,9 @@ vchi_bulk_queue_transmit( VCHI_SERVICE_H + VCHIQ_QUEUE_BULK_TRANSFER_T args; + int ret; + ++ if (!is_valid_service(service)) ++ return VCHIQ_ERROR; ++ + switch ((int)flags) { + case VCHI_FLAGS_CALLBACK_WHEN_OP_COMPLETE | VCHI_FLAGS_BLOCK_UNTIL_QUEUED: + args.mode = VCHIQ_BULK_MODE_CALLBACK; +@@ -833,6 +885,9 @@ vchi_msg_dequeue( VCHI_SERVICE_HANDLE_T + + vcos_assert(flags == VCHI_FLAGS_NONE || flags == VCHI_FLAGS_BLOCK_UNTIL_OP_COMPLETE); + ++ if (!is_valid_service(service)) ++ return VCHIQ_ERROR; ++ + if (service->peek_size >= 0) + { + fprintf(stderr, "vchi_msg_dequeue -> using peek buffer\n"); +@@ -903,6 +958,9 @@ vchi_msg_queuev( VCHI_SERVICE_HANDLE_T h + + vcos_assert(flags == VCHI_FLAGS_BLOCK_UNTIL_QUEUED); + ++ if (!is_valid_service(service)) ++ return VCHIQ_ERROR; ++ + args.handle = service->handle; + args.elements = (const VCHIQ_ELEMENT_T *)vector; + args.count = count; +@@ -961,6 +1019,9 @@ vchi_msg_hold( VCHI_SERVICE_HANDLE_T han + VCHI_SERVICE_T *service = (VCHI_SERVICE_T *)handle; + int ret; + ++ if (!is_valid_service(service)) ++ return VCHIQ_ERROR; ++ + ret = fill_peek_buf(service, flags); + + if (ret == 0) +@@ -1116,6 +1177,10 @@ vchi_service_close( const VCHI_SERVICE_H + { + VCHI_SERVICE_T *service = (VCHI_SERVICE_T *)handle; + int ret; ++ ++ if (!is_valid_service(service)) ++ return VCHIQ_ERROR; ++ + RETRY(ret,ioctl(service->fd, VCHIQ_IOC_REMOVE_SERVICE, service->handle)); + + if (ret == 0) +@@ -1129,6 +1194,10 @@ vchi_service_destroy( const VCHI_SERVICE + { + VCHI_SERVICE_T *service = (VCHI_SERVICE_T *)handle; + int ret; ++ ++ if (!is_valid_service(service)) ++ return VCHIQ_ERROR; ++ + RETRY(ret,ioctl(service->fd, VCHIQ_IOC_REMOVE_SERVICE, service->handle)); + + if (ret == 0) +@@ -1200,6 +1269,10 @@ vchi_service_use( const VCHI_SERVICE_HAN + { + VCHI_SERVICE_T *service = (VCHI_SERVICE_T *)handle; + int ret; ++ ++ if (!is_valid_service(service)) ++ return VCHIQ_ERROR; ++ + RETRY(ret,ioctl(service->fd, VCHIQ_IOC_USE_SERVICE, service->handle)); + return ret; + } +@@ -1218,10 +1291,47 @@ int32_t vchi_service_release( const VCHI + { + VCHI_SERVICE_T *service = (VCHI_SERVICE_T *)handle; + int ret; ++ ++ if (!is_valid_service(service)) ++ return VCHIQ_ERROR; ++ + RETRY(ret,ioctl(service->fd, VCHIQ_IOC_RELEASE_SERVICE, service->handle)); + return ret; + } + ++/*********************************************************** ++ * Name: vchiq_dump_phys_mem ++ * ++ * Arguments: const VCHI_SERVICE_HANDLE_T handle ++ * void *buffer ++ * size_t num_bytes ++ * ++ * Description: Dumps the physical memory associated with ++ * a buffer. ++ * ++ * Returns: void ++ * ++ ***********************************************************/ ++VCHIQ_STATUS_T vchiq_dump_phys_mem( VCHIQ_SERVICE_HANDLE_T handle, ++ void *ptr, ++ size_t num_bytes ) ++{ ++ VCHIQ_SERVICE_T *service = (VCHIQ_SERVICE_T *)handle; ++ VCHIQ_DUMP_MEM_T dump_mem; ++ int ret; ++ ++ if (!is_valid_service(service)) ++ return VCHIQ_ERROR; ++ ++ dump_mem.virt_addr = ptr; ++ dump_mem.num_bytes = num_bytes; ++ ++ RETRY(ret,ioctl(service->fd, VCHIQ_IOC_DUMP_PHYS_MEM, &dump_mem)); ++ return (ret >= 0) ? VCHIQ_SUCCESS : VCHIQ_ERROR; ++} ++ ++ ++ + /* + * Support functions + */ +--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_shim.c ++++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_shim.c +@@ -859,10 +859,38 @@ int32_t vchi_service_create( VCHI_INSTAN + + int32_t vchi_service_close( const VCHI_SERVICE_HANDLE_T handle ) + { +- vcos_unused(handle); ++ int32_t ret = -1; ++ SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle; ++ if(service) ++ { ++ VCHIQ_STATUS_T status = vchiq_close_service(service->handle); ++ if (status == VCHIQ_SUCCESS) ++ { ++ service_free(service); ++ service = NULL; ++ } ++ ++ ret = vchiq_status_to_vchi( status ); ++ } ++ return ret; ++} + +- // YTI?? +- return 0; ++int32_t vchi_service_destroy( const VCHI_SERVICE_HANDLE_T handle ) ++{ ++ int32_t ret = -1; ++ SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle; ++ if(service) ++ { ++ VCHIQ_STATUS_T status = vchiq_remove_service(service->handle); ++ if (status == VCHIQ_SUCCESS) ++ { ++ service_free(service); ++ service = NULL; ++ } ++ ++ ret = vchiq_status_to_vchi( status ); ++ } ++ return ret; + } + + /* ---------------------------------------------------------------------- +@@ -962,9 +990,12 @@ EXPORT_SYMBOL(vchi_bulk_queue_transmit); + EXPORT_SYMBOL(vchi_msg_dequeue); + EXPORT_SYMBOL(vchi_msg_queue); + EXPORT_SYMBOL(vchi_msg_queuev); ++EXPORT_SYMBOL(vchi_msg_peek); ++EXPORT_SYMBOL(vchi_msg_remove); + EXPORT_SYMBOL(vchi_service_close); + EXPORT_SYMBOL(vchi_service_open); + EXPORT_SYMBOL(vchi_service_create); ++EXPORT_SYMBOL(vchi_service_destroy); + EXPORT_SYMBOL(vchi_service_use); + EXPORT_SYMBOL(vchi_service_release); + #endif +--- a/drivers/mmc/host/sdhci-bcm2708.c ++++ b/drivers/mmc/host/sdhci-bcm2708.c +@@ -26,7 +26,9 @@ + #include <linux/highmem.h> + #include <linux/platform_device.h> + #include <linux/module.h> ++#include <linux/mmc/mmc.h> + #include <linux/mmc/host.h> ++#include <linux/mmc/sd.h> + + #include <linux/io.h> + #include <linux/dma-mapping.h> +@@ -57,6 +59,9 @@ + //#define LOG_REGISTERS + + #define USE_SCHED_TIME ++#define USE_SPACED_WRITES_2CLK 1 /* space consecutive register writes */ ++#define USE_SOFTWARE_TIMEOUTS 1 /* not hardware timeouts */ ++#define SOFTWARE_ERASE_TIMEOUT_SEC 30 + + #define SDHCI_BCM_DMA_CHAN 4 /* this default is normally overriden */ + #define SDHCI_BCM_DMA_WAITS 0 /* delays slowing DMA transfers: 0-31 */ +@@ -68,6 +73,9 @@ + + #define BCM2708_SDHCI_SLEEP_TIMEOUT 1000 /* msecs */ + ++/* Mhz clock that the EMMC core is running at. Should match the platform clockman settings */ ++#define BCM2708_EMMC_CLOCK_FREQ 80000000 ++ + #define POWER_OFF 0 + #define POWER_LAZY_OFF 1 + #define POWER_ON 2 +@@ -222,6 +230,12 @@ u8 sdhci_bcm2708_readb(struct sdhci_host + + static void sdhci_bcm2708_raw_writel(struct sdhci_host *host, u32 val, int reg) + { ++ u32 ier; ++ ++#if USE_SPACED_WRITES_2CLK ++ static bool timeout_disabled = false; ++ unsigned int ns_2clk = 0; ++ + /* The Arasan has a bugette whereby it may lose the content of + * successive writes to registers that are within two SD-card clock + * cycles of each other (a clock domain crossing problem). +@@ -229,12 +243,11 @@ static void sdhci_bcm2708_raw_writel(str + * (Which is just as well - otherwise we'd have to nobble the DMA engine + * too) + */ +-#if 1 + if (reg != SDHCI_BUFFER && host->clock != 0) { + /* host->clock is the clock freq in Hz */ + static hptime_t last_write_hpt; + hptime_t now = hptime(); +- unsigned int ns_2clk = 2000000000/host->clock; ++ ns_2clk = 2000000000/host->clock; + + if (now == last_write_hpt || now == last_write_hpt+1) { + /* we can't guarantee any significant time has +@@ -250,6 +263,27 @@ static void sdhci_bcm2708_raw_writel(str + } + last_write_hpt = now; + } ++#if USE_SOFTWARE_TIMEOUTS ++ /* The Arasan is clocked for timeouts using the SD clock which is too ++ * fast for ERASE commands and causes issues. So we disable timeouts ++ * for ERASE */ ++ if (host->cmd != NULL && host->cmd->opcode == MMC_ERASE && ++ reg == (SDHCI_COMMAND & ~3)) { ++ mod_timer(&host->timer, ++ jiffies + SOFTWARE_ERASE_TIMEOUT_SEC * HZ); ++ ier = readl(host->ioaddr + SDHCI_SIGNAL_ENABLE); ++ ier &= ~SDHCI_INT_DATA_TIMEOUT; ++ writel(ier, host->ioaddr + SDHCI_SIGNAL_ENABLE); ++ timeout_disabled = true; ++ udelay((ns_2clk+1000-1)/1000); ++ } else if (timeout_disabled) { ++ ier = readl(host->ioaddr + SDHCI_SIGNAL_ENABLE); ++ ier |= SDHCI_INT_DATA_TIMEOUT; ++ writel(ier, host->ioaddr + SDHCI_SIGNAL_ENABLE); ++ timeout_disabled = false; ++ udelay((ns_2clk+1000-1)/1000); ++ } ++#endif + writel(val, host->ioaddr + reg); + #else + void __iomem * regaddr = host->ioaddr + reg; +@@ -325,14 +359,68 @@ void sdhci_bcm2708_writeb(struct sdhci_h + + static unsigned int sdhci_bcm2708_get_max_clock(struct sdhci_host *host) + { +- return 100000000; // this value is in Hz (100MHz/4) ++ return 20000000; // this value is in Hz (20MHz) + } + + static unsigned int sdhci_bcm2708_get_timeout_clock(struct sdhci_host *host) + { +- return 100000; // this value is in kHz (100MHz/4) ++ if(host->clock) ++ return (host->clock / 1000); // this value is in kHz (100MHz) ++ else ++ return (sdhci_bcm2708_get_max_clock(host) / 1000); + } + ++static void sdhci_bcm2708_set_clock(struct sdhci_host *host, unsigned int clock) ++{ ++ int div = 0; ++ u16 clk = 0; ++ unsigned long timeout; ++ ++ if (clock == host->clock) ++ return; ++ ++ sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL); ++ ++ if (clock == 0) ++ goto out; ++ ++ if (BCM2708_EMMC_CLOCK_FREQ <= clock) ++ div = 1; ++ else { ++ for (div = 2; div < SDHCI_MAX_DIV_SPEC_300; div += 2) { ++ if ((BCM2708_EMMC_CLOCK_FREQ / div) <= clock) ++ break; ++ } ++ } ++ ++ DBG( "desired SD clock: %d, actual: %d\n", ++ clock, BCM2708_EMMC_CLOCK_FREQ / div); ++ ++ clk |= (div & SDHCI_DIV_MASK) << SDHCI_DIVIDER_SHIFT; ++ clk |= ((div & SDHCI_DIV_HI_MASK) >> SDHCI_DIV_MASK_LEN) ++ << SDHCI_DIVIDER_HI_SHIFT; ++ clk |= SDHCI_CLOCK_INT_EN; ++ ++ sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); ++ ++ timeout = 20; ++ while (!((clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL)) ++ & SDHCI_CLOCK_INT_STABLE)) { ++ if (timeout == 0) { ++ printk(KERN_ERR "%s: Internal clock never " ++ "stabilised.\n", mmc_hostname(host->mmc)); ++ return; ++ } ++ timeout--; ++ mdelay(1); ++ } ++ ++ clk |= SDHCI_CLOCK_CARD_EN; ++ sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); ++out: ++ host->clock = clock; ++ } ++ + /*****************************************************************************\ + * * + * DMA Operation * +@@ -429,7 +517,8 @@ static void schci_bcm2708_cb_read(struct + cb->stride = 0; + + if (is_last) { +- cb->info |= BCM2708_DMA_INT_EN; ++ cb->info |= BCM2708_DMA_INT_EN | ++ BCM2708_DMA_WAIT_RESP; + cb->next = 0; + } else + cb->next = host->cb_handle + +@@ -460,7 +549,8 @@ static void schci_bcm2708_cb_write(struc + cb->stride = 0; + + if (is_last) { +- cb->info |= BCM2708_DMA_INT_EN; ++ cb->info |= BCM2708_DMA_INT_EN | ++ BCM2708_DMA_WAIT_RESP; + cb->next = 0; + } else + cb->next = host->cb_handle + +@@ -806,8 +896,7 @@ static void sdhci_bcm2708_dma_complete_i + We get CRC and DEND errors unless we wait for + the SD controller to finish reading/writing to the card. */ + u32 state_mask; +- int timeout=1000000; +- hptime_t now = hptime(); ++ int timeout=1000; + + DBG("PDMA over - sync card\n"); + if (data->flags & MMC_DATA_READ) +@@ -815,17 +904,12 @@ static void sdhci_bcm2708_dma_complete_i + else + state_mask = SDHCI_DOING_WRITE; + +- while (0 != (sdhci_bcm2708_raw_readl(host, +- SDHCI_PRESENT_STATE) & +- state_mask) && --timeout > 0) ++ while (0 != (sdhci_bcm2708_raw_readl(host, SDHCI_PRESENT_STATE) ++ & state_mask) && --timeout > 0) ++ { ++ udelay(100); + continue; +- +- if (1000000-timeout > 4000) /*ave. is about 3250*/ +- printk(KERN_INFO "%s: note - long %s sync %luns - " +- "%d its.\n", +- mmc_hostname(host->mmc), +- data->flags & MMC_DATA_READ? "read": "write", +- since_ns(now), 1000000-timeout); ++ } + if (timeout <= 0) + printk(KERN_ERR"%s: final %s to SD card still " + "running\n", +@@ -1201,6 +1285,11 @@ static unsigned int sdhci_bcm2708_uhs_br + return 1; + } + ++static unsigned int sdhci_bcm2708_missing_status(struct sdhci_host *host) ++{ ++ return 1; ++} ++ + /***************************************************************************** \ + * * + * Device ops * +@@ -1219,7 +1308,7 @@ static struct sdhci_ops sdhci_bcm2708_op + #error The BCM2708 SDHCI driver needs CONFIG_MMC_SDHCI_IO_ACCESSORS to be set + #endif + //.enable_dma = NULL, +- //.set_clock = NULL, ++ .set_clock = sdhci_bcm2708_set_clock, + .get_max_clock = sdhci_bcm2708_get_max_clock, + //.get_min_clock = NULL, + .get_timeout_clock = sdhci_bcm2708_get_timeout_clock, +@@ -1238,6 +1327,7 @@ static struct sdhci_ops sdhci_bcm2708_op + .spurious_crc_acmd51 = sdhci_bcm2708_quirk_spurious_crc, + .voltage_broken = sdhci_bcm2708_quirk_voltage_broken, + .uhs_broken = sdhci_bcm2708_uhs_broken, ++ .missing_status = sdhci_bcm2708_missing_status, + }; + + /*****************************************************************************\ +@@ -1282,7 +1372,9 @@ static int __devinit sdhci_bcm2708_probe + host->irq = platform_get_irq(pdev, 0); + + host->quirks = SDHCI_QUIRK_BROKEN_CARD_DETECTION | +- SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK; ++ SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | ++ SDHCI_QUIRK_BROKEN_TIMEOUT_VAL | ++ SDHCI_QUIRK_NONSTANDARD_CLOCK; + #ifdef CONFIG_MMC_SDHCI_BCM2708_DMA + host->flags = SDHCI_USE_PLATDMA; + #endif +@@ -1349,6 +1441,8 @@ static int __devinit sdhci_bcm2708_probe + host_priv->cb_base, (unsigned)host_priv->cb_handle, + host_priv->dma_chan, host_priv->dma_chan_base, + host_priv->dma_irq); ++ ++ host->mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED; + #endif + + ret = sdhci_add_host(host); +--- a/drivers/mmc/host/sdhci.c ++++ b/drivers/mmc/host/sdhci.c +@@ -974,6 +974,12 @@ static void sdhci_send_command(struct sd + if ((cmd->data != NULL) || (cmd->flags & MMC_RSP_BUSY)) + mask |= SDHCI_DATA_INHIBIT; + ++ if(host->ops->missing_status && (cmd->opcode == MMC_SEND_STATUS)) { ++ timeout = 5000; // Really obscenely large delay to send the status, due to bug in controller ++ // which might cause the STATUS command to get stuck when a data operation is in flow ++ mask |= SDHCI_DATA_INHIBIT; ++ } ++ + /* We shouldn't wait for data inihibit for stop commands, even + though they might use busy signaling */ + if (host->mrq->data && (cmd == host->mrq->data->stop)) +@@ -2098,7 +2104,7 @@ static void sdhci_timeout_timer(unsigned + + if (host->mrq) { + pr_err("%s: Timeout waiting for hardware " +- "interrupt.\n", mmc_hostname(host->mmc)); ++ "interrupt - cmd%d.\n", mmc_hostname(host->mmc), host->last_cmdop); + sdhci_dumpregs(host); + + if (host->data) { +@@ -3065,8 +3071,11 @@ int sdhci_add_host(struct sdhci_host *ho + mmc->caps |= MMC_CAP_MAX_CURRENT_200; + } + +- if(host->ops->voltage_broken) +- ocr_avail |= MMC_VDD_29_30 | MMC_VDD_30_31; ++ if(host->ops->voltage_broken) { ++ ocr_avail |= MMC_VDD_32_33 | MMC_VDD_33_34; ++ // Cannot support UHS modes is we are stuck at 3.3V; ++ mmc->caps &= ~(MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 | MMC_CAP_UHS_SDR104 | MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_DDR50); ++ } + + mmc->ocr_avail = ocr_avail; + mmc->ocr_avail_sdio = ocr_avail; +--- a/drivers/mmc/host/sdhci.h ++++ b/drivers/mmc/host/sdhci.h +@@ -291,6 +291,7 @@ struct sdhci_ops { + unsigned int (*spurious_crc_acmd51)(struct sdhci_host *host); + unsigned int (*voltage_broken)(struct sdhci_host *host); + unsigned int (*uhs_broken)(struct sdhci_host *host); ++ unsigned int (*missing_status)(struct sdhci_host *host); + + void (*hw_reset)(struct sdhci_host *host); + }; +--- a/drivers/net/usb/smsc95xx.c ++++ b/drivers/net/usb/smsc95xx.c +@@ -1073,6 +1073,7 @@ static int smsc95xx_bind(struct usbnet * + dev->net->ethtool_ops = &smsc95xx_ethtool_ops; + dev->net->flags |= IFF_MULTICAST; + dev->net->hard_header_len += SMSC95XX_TX_OVERHEAD_CSUM; ++ dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len; + return 0; + } + +--- a/drivers/usb/gadget/Kconfig ++++ b/drivers/usb/gadget/Kconfig +@@ -536,28 +536,6 @@ config USB_GADGET_SUPERSPEED + bool + depends on USB_GADGET_DUALSPEED + +-config USB_GADGET_SNPS_DWC_OTG +- boolean "Synopsys Driver for DWC_otg Controller" +- depends on USB && EXPERIMENTAL +- select USB_OTG +- select USB_GADGET_DUALSPEED +- help +- Selects the Synopsys Driver for the DWC_otg Controller. +- +-config USB_DWC_OTG_LPM +- boolean "Enable LPM support" +- depends on USB && EXPERIMENTAL +- help +- Enables LPM support. +- +-config USB_GADGET_SNPS_DWC_OTG +- boolean "Synopsys Driver for DWC_otg Controller" +- depends on USB && EXPERIMENTAL +- select USB_OTG +- select USB_GADGET_DUALSPEED +- help +- Selects the Synopsys Driver for the DWC_otg Controller. +- + config USB_DWC_OTG_LPM + boolean "Enable LPM support" + depends on USB && EXPERIMENTAL +--- a/drivers/usb/host/dwc_common_port/Makefile ++++ b/drivers/usb/host/dwc_common_port/Makefile +@@ -6,7 +6,9 @@ ifneq ($(KERNELRELEASE),) + + #CPPFLAGS += -DDEBUG_MEMORY + ++ifeq ($(CONFIG_USB_DEBUG),y) + CPPFLAGS += -DDEBUG ++endif + CPPFLAGS += -DDWC_LINUX + + obj-$(CONFIG_USB_DWCOTG) += dwc_common_port_lib.o +--- a/drivers/usb/host/dwc_common_port/dwc_os.h ++++ b/drivers/usb/host/dwc_common_port/dwc_os.h +@@ -216,6 +216,7 @@ extern void __DWC_DEBUG(char *format, .. + #endif + #else + #define __DWC_DEBUG printk ++#include <linux/kernel.h> + #endif + + /** +--- a/drivers/usb/host/dwc_otg/Makefile ++++ b/drivers/usb/host/dwc_otg/Makefile +@@ -9,7 +9,9 @@ ifeq ($(BUS_INTERFACE),) + BUS_INTERFACE = -DPLATFORM_INTERFACE=1 + endif + +-CPPFLAGS += -DDEBUG ++ifeq ($(CONFIG_USB_DEBUG),y) ++CPPFLAGS += -DDEBUG ++endif + + # Use one of the following flags to compile the software in host-only or + # device-only mode. +--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c ++++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c +@@ -909,6 +909,10 @@ static void assign_and_init_hc(dwc_otg_h + return 0; + #endif + ++ if (((urb->actual_length < 0) || (urb->actual_length > urb->length)) && !dwc_otg_hcd_is_pipe_in(&urb->pipe_info)) ++ urb->actual_length = urb->length; ++ ++ + hc = DWC_CIRCLEQ_FIRST(&hcd->free_hc_list); + + /* Remove the host channel from the free list. */ +--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd.h ++++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.h +@@ -628,7 +628,7 @@ static inline void dwc_otg_hcd_qh_remove + * @return Returns the memory allocate or NULL on error. */ + static inline dwc_otg_qh_t *dwc_otg_hcd_qh_alloc(void) + { +- return (dwc_otg_qh_t *) dwc_alloc(sizeof(dwc_otg_qh_t)); ++ return (dwc_otg_qh_t *) dwc_alloc_atomic(sizeof(dwc_otg_qh_t)); + } + + extern dwc_otg_qtd_t *dwc_otg_hcd_qtd_create(dwc_otg_hcd_urb_t * urb); +@@ -640,7 +640,7 @@ extern int dwc_otg_hcd_qtd_add(dwc_otg_q + * @return Returns the memory allocate or NULL on error. */ + static inline dwc_otg_qtd_t *dwc_otg_hcd_qtd_alloc(void) + { +- return (dwc_otg_qtd_t *) dwc_alloc(sizeof(dwc_otg_qtd_t)); ++ return (dwc_otg_qtd_t *) dwc_alloc_atomic(sizeof(dwc_otg_qtd_t)); + } + + /** Frees the memory for a QTD structure. QTD should already be removed from +--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c ++++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c +@@ -417,6 +417,9 @@ int hcd_init( + + hcd->regs = otg_dev->base; + ++ /* Integrate TT in root hub */ ++ hcd->has_tt = 1; ++ + /* Initialize the DWC OTG HCD. */ + dwc_otg_hcd = dwc_otg_hcd_alloc_hcd(); + if (!dwc_otg_hcd) { +@@ -668,6 +671,9 @@ static int urb_enqueue(struct usb_hcd *h + urb->number_of_packets, + mem_flags == GFP_ATOMIC ? 1 : 0); + ++ if(dwc_otg_urb == NULL) ++ return -ENOMEM; ++ + urb->hcpriv = dwc_otg_urb; + + dwc_otg_hcd_urb_set_pipeinfo(dwc_otg_urb, usb_pipedevice(urb->pipe), +@@ -755,10 +761,12 @@ static int urb_dequeue(struct usb_hcd *h + dump_urb_info(urb, "urb_dequeue"); + } + #endif +- dwc_otg_hcd_urb_dequeue(dwc_otg_hcd, (dwc_otg_hcd_urb_t *)urb->hcpriv); ++ if(urb->hcpriv != NULL) { ++ dwc_otg_hcd_urb_dequeue(dwc_otg_hcd, (dwc_otg_hcd_urb_t *)urb->hcpriv); + +- dwc_free(urb->hcpriv); +- urb->hcpriv = NULL; ++ urb->hcpriv = NULL; ++ dwc_free(urb->hcpriv); ++ } + + /* Higher layer software sets URB status. */ + #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)) +--- a/drivers/video/bcm2708_fb.c ++++ b/drivers/video/bcm2708_fb.c +@@ -7,14 +7,17 @@ + * License. See the file COPYING in the main directory of this archive + * for more details. + * +- * Broadcom simple framebuffer driver ++ * Broadcom simple framebuffer driver ++ * ++ * This file is derived from cirrusfb.c ++ * Copyright 1999-2001 Jeff Garzik <jgarzik@pobox.com> ++ * + */ + #include <linux/module.h> + #include <linux/kernel.h> + #include <linux/errno.h> + #include <linux/string.h> + #include <linux/slab.h> +-#include <linux/delay.h> + #include <linux/mm.h> + #include <linux/fb.h> + #include <linux/init.h> +@@ -22,6 +25,8 @@ + #include <linux/list.h> + #include <linux/platform_device.h> + #include <linux/clk.h> ++#include <linux/printk.h> ++#include <linux/console.h> + + #include <mach/platform.h> + #include <mach/vcio.h> +@@ -38,26 +43,24 @@ static const char *bcm2708_name = "BCM27 + /* this data structure describes each frame buffer device we find */ + + struct fbinfo_s { +- int xres, yres, xres_virtual, yres_virtual; +- int pitch, bpp; +- int xoffset, yoffset; +- int base; +- int screen_size; ++ u32 xres, yres, xres_virtual, yres_virtual; ++ u32 pitch, bpp; ++ u32 xoffset, yoffset; ++ u32 base; ++ u32 screen_size; + }; + + struct bcm2708_fb { +- struct fb_info fb; +- struct platform_device *dev; +- void __iomem *regs; +- volatile struct fbinfo_s *info; +- dma_addr_t dma; +- u32 cmap[16]; ++ struct fb_info fb; ++ struct platform_device *dev; ++ struct fbinfo_s *info; ++ dma_addr_t dma; ++ u32 cmap[16]; + }; + + #define to_bcm2708(info) container_of(info, struct bcm2708_fb, fb) + +-static int +-bcm2708_fb_set_bitfields(struct fb_var_screeninfo *var) ++static int bcm2708_fb_set_bitfields(struct fb_var_screeninfo *var) + { + int ret = 0; + +@@ -72,12 +75,12 @@ bcm2708_fb_set_bitfields(struct fb_var_s + case 2: + case 4: + case 8: +- var->red.length = var->bits_per_pixel; +- var->red.offset = 0; +- var->green.length = var->bits_per_pixel; +- var->green.offset = 0; +- var->blue.length = var->bits_per_pixel; +- var->blue.offset = 0; ++ var->red.length = var->bits_per_pixel; ++ var->red.offset = 0; ++ var->green.length = var->bits_per_pixel; ++ var->green.offset = 0; ++ var->blue.length = var->bits_per_pixel; ++ var->blue.offset = 0; + break; + case 16: + var->red.length = 5; +@@ -89,10 +92,16 @@ bcm2708_fb_set_bitfields(struct fb_var_s + if (var->green.length != 5 && var->green.length != 6) + var->green.length = 6; + break; ++ case 24: ++ var->red.length = 8; ++ var->blue.length = 8; ++ var->green.length = 8; ++ break; + case 32: +- var->red.length = 8; +- var->green.length = 8; +- var->blue.length = 8; ++ var->red.length = 8; ++ var->green.length = 8; ++ var->blue.length = 8; ++ var->transp.length = 8; + break; + default: + ret = -EINVAL; +@@ -104,134 +113,148 @@ bcm2708_fb_set_bitfields(struct fb_var_s + * encoded in the pixel data. Calculate their position from + * the bitfield length defined above. + */ +- if (ret == 0 && var->bits_per_pixel >= 16) { ++ if (ret == 0 && var->bits_per_pixel >= 24) { ++ var->red.offset = 0; ++ var->green.offset = var->red.offset + var->red.length; ++ var->blue.offset = var->green.offset + var->green.length; ++ var->transp.offset = var->blue.offset + var->blue.length; ++ } else if (ret == 0 && var->bits_per_pixel >= 16) { + var->blue.offset = 0; + var->green.offset = var->blue.offset + var->blue.length; + var->red.offset = var->green.offset + var->green.length; ++ var->transp.offset = var->red.offset + var->red.length; + } + + return ret; + } + +-static int bcm2708_fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) ++static int bcm2708_fb_check_var(struct fb_var_screeninfo *var, ++ struct fb_info *info) + { ++ /* info input, var output */ ++ int yres; ++ /* memory size in pixels */ ++ unsigned pixels = info->screen_size * 8 / var->bits_per_pixel; ++ ++ /* info input, var output */ ++ pr_info("bcm2708_fb_check_var info(%p) %dx%d (%dx%d), %d, %d\n", info, ++ info->var.xres, info->var.yres, info->var.xres_virtual, ++ info->var.yres_virtual, (int)info->screen_size, ++ info->var.bits_per_pixel); ++ pr_info("bcm2708_fb_check_var var(%p) %dx%d (%dx%d), %d, %d\n", var, ++ var->xres, var->yres, var->xres_virtual, var->yres_virtual, ++ var->bits_per_pixel, pixels); ++ ++ if (!var->bits_per_pixel) ++ var->bits_per_pixel = 16; ++ ++ if (bcm2708_fb_set_bitfields(var) != 0) { ++ pr_err("bcm2708_fb_check_var: invalid bits_per_pixel %d\n", ++ var->bits_per_pixel); ++ return -EINVAL; ++ } + +- // info input, var output +- int yres; +- /* memory size in pixels */ +- unsigned pixels = info->screen_size * 8 / var->bits_per_pixel; +- +- // info input, var output +- printk(KERN_ERR "bcm2708_fb_check_var info(%p) %dx%d (%dx%d), %d, %d\n", info, info->var.xres, info->var.yres, info->var.xres_virtual, info->var.yres_virtual, (int)info->screen_size, info->var.bits_per_pixel ); +- printk(KERN_ERR "bcm2708_fb_check_var var(%p) %dx%d (%dx%d), %d, %d\n", var, var->xres, var->yres, var->xres_virtual, var->yres_virtual, var->bits_per_pixel, pixels); +- +- if (!var->bits_per_pixel) var->bits_per_pixel = 16; +- +- if (0 && var->bits_per_pixel != 16 && var->bits_per_pixel != 32) { +- printk(KERN_ERR "bcm2708_fb_check_var: ERROR: bits_per_pixel=%d\n", var->bits_per_pixel); +- return -EINVAL; +- } +- +- bcm2708_fb_set_bitfields(var); +- +- if (var->xres_virtual < var->xres) +- var->xres_virtual = var->xres; +- /* use highest possible virtual resolution */ +- if (var->yres_virtual == -1) { +- var->yres_virtual = 480; //pixels / var->xres_virtual; +- +- printk(KERN_ERR +- "bcm2708_fb_check_var: virtual resolution set to maximum of %dx%d\n", +- var->xres_virtual, var->yres_virtual); +- } +- if (var->yres_virtual < var->yres) +- var->yres_virtual = var->yres; +- +- #if 0 +- if (var->xres_virtual * var->yres_virtual > pixels) { +- printk(KERN_ERR "bcm2708_fb_check_var: mode %dx%dx%d rejected... " +- "virtual resolution too high to fit into video memory!\n", +- var->xres_virtual, var->yres_virtual, +- var->bits_per_pixel); +- return -EINVAL; +- } +- #endif +- if (var->xoffset < 0) +- var->xoffset = 0; +- if (var->yoffset < 0) +- var->yoffset = 0; +- +- /* truncate xoffset and yoffset to maximum if too high */ +- if (var->xoffset > var->xres_virtual - var->xres) +- var->xoffset = var->xres_virtual - var->xres - 1; +- if (var->yoffset > var->yres_virtual - var->yres) +- var->yoffset = var->yres_virtual - var->yres - 1; +- +- var->red.msb_right = +- var->green.msb_right = +- var->blue.msb_right = +- var->transp.offset = +- var->transp.length = +- var->transp.msb_right = 0; +- +- yres = var->yres; +- if (var->vmode & FB_VMODE_DOUBLE) +- yres *= 2; +- else if (var->vmode & FB_VMODE_INTERLACED) +- yres = (yres + 1) / 2; +- +- if (yres > 1200) { +- printk(KERN_ERR "bcm2708_fb_check_var: ERROR: VerticalTotal >= 1200; " +- "special treatment required! (TODO)\n"); +- return -EINVAL; +- } + +- //if (cirrusfb_check_pixclock(var, info)) +- // return -EINVAL; ++ if (var->xres_virtual < var->xres) ++ var->xres_virtual = var->xres; ++ /* use highest possible virtual resolution */ ++ if (var->yres_virtual == -1) { ++ var->yres_virtual = 480; ++ ++ pr_err ++ ("bcm2708_fb_check_var: virtual resolution set to maximum of %dx%d\n", ++ var->xres_virtual, var->yres_virtual); ++ } ++ if (var->yres_virtual < var->yres) ++ var->yres_virtual = var->yres; + +- //if (!is_laguna(cinfo)) +- // var->accel_flags = FB_ACCELF_TEXT; ++ if (var->xoffset < 0) ++ var->xoffset = 0; ++ if (var->yoffset < 0) ++ var->yoffset = 0; ++ ++ /* truncate xoffset and yoffset to maximum if too high */ ++ if (var->xoffset > var->xres_virtual - var->xres) ++ var->xoffset = var->xres_virtual - var->xres - 1; ++ if (var->yoffset > var->yres_virtual - var->yres) ++ var->yoffset = var->yres_virtual - var->yres - 1; ++ ++ yres = var->yres; ++ if (var->vmode & FB_VMODE_DOUBLE) ++ yres *= 2; ++ else if (var->vmode & FB_VMODE_INTERLACED) ++ yres = (yres + 1) / 2; ++ ++ if (yres > 1200) { ++ pr_err("bcm2708_fb_check_var: ERROR: VerticalTotal >= 1200; " ++ "special treatment required! (TODO)\n"); ++ return -EINVAL; ++ } + +- return 0; ++ return 0; + } + + static int bcm2708_fb_set_par(struct fb_info *info) + { +- unsigned val = 0; ++ uint32_t val = 0; + struct bcm2708_fb *fb = to_bcm2708(info); +- volatile struct fbinfo_s *fbinfo = fb->info; +- fbinfo->xres = info->var.xres; +- fbinfo->yres = info->var.yres; +- fbinfo->xres_virtual = info->var.xres_virtual; +- fbinfo->yres_virtual = info->var.yres_virtual; +- fbinfo->bpp = info->var.bits_per_pixel; +- fbinfo->xoffset = info->var.xoffset; +- fbinfo->yoffset = info->var.yoffset; +- fbinfo->base = 0; // filled in by VC +- fbinfo->pitch = 0; // filled in by VC ++ volatile struct fbinfo_s *fbinfo = fb->info; ++ fbinfo->xres = info->var.xres; ++ fbinfo->yres = info->var.yres; ++ fbinfo->xres_virtual = info->var.xres_virtual; ++ fbinfo->yres_virtual = info->var.yres_virtual; ++ fbinfo->bpp = info->var.bits_per_pixel; ++ fbinfo->xoffset = info->var.xoffset; ++ fbinfo->yoffset = info->var.yoffset; ++ fbinfo->base = 0; /* filled in by VC */ ++ fbinfo->pitch = 0; /* filled in by VC */ ++ ++ pr_info("bcm2708_fb_set_par info(%p) %dx%d (%dx%d), %d, %d\n", info, ++ info->var.xres, info->var.yres, info->var.xres_virtual, ++ info->var.yres_virtual, (int)info->screen_size, ++ info->var.bits_per_pixel); + +- printk(KERN_ERR "bcm2708_fb_set_par info(%p) %dx%d (%dx%d), %d, %d\n", info, info->var.xres, info->var.yres, info->var.xres_virtual, info->var.yres_virtual, (int)info->screen_size, info->var.bits_per_pixel ); ++ /* ensure last write to fbinfo is visible to GPU */ ++ wmb(); + +- // inform vc about new framebuffer ++ /* inform vc about new framebuffer */ + bcm_mailbox_write(MBOX_CHAN_FB, fb->dma); + +- // wait for response +- bcm_mailbox_read(MBOX_CHAN_FB, &val); +- +- fb->fb.fix.line_length = fbinfo->pitch; ++ /* TODO: replace fb driver with vchiq version */ ++ /* wait for response */ ++ bcm_mailbox_read(MBOX_CHAN_FB, &val); ++ ++ /* ensure GPU writes are visible to us */ ++ rmb(); ++ ++ if (val == 0) { ++ fb->fb.fix.line_length = fbinfo->pitch; ++ ++ if (info->var.bits_per_pixel <= 8) ++ fb->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR; ++ else ++ fb->fb.fix.visual = FB_VISUAL_TRUECOLOR; ++ ++ fb->fb.fix.smem_start = fbinfo->base; ++ fb->fb.fix.smem_len = fbinfo->pitch * fbinfo->yres_virtual; ++ fb->fb.screen_size = fbinfo->screen_size; ++ if (fb->fb.screen_base) ++ iounmap(fb->fb.screen_base); ++ fb->fb.screen_base = ++ (void *)ioremap_wc(fb->fb.fix.smem_start, fb->fb.screen_size); ++ if (!fb->fb.screen_base) { ++ /* the console may currently be locked */ ++ console_trylock(); ++ console_unlock(); + +- if (info->var.bits_per_pixel <= 8) +- fb->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR; +- else +- fb->fb.fix.visual = FB_VISUAL_TRUECOLOR; +- +- fb->fb.fix.smem_start = fbinfo->base; +- fb->fb.fix.smem_len = fbinfo->pitch * fbinfo->yres_virtual; +- fb->fb.screen_size = fbinfo->screen_size; +- fb->fb.screen_base = (void *)ioremap_nocache(fb->fb.fix.smem_start, fb->fb.screen_size); +- +- printk(KERN_ERR "BCM2708FB: start = %p,%p,%p width=%d, height=%d, bpp=%d, pitch=%d\n", +- (void *)fb->fb.screen_base, (void *)fb->fb.fix.smem_start, (void *)val, fbinfo->xres, fbinfo->yres, fbinfo->bpp, fbinfo->pitch); ++ BUG(); /* what can we do here */ ++ } ++ } ++ pr_info ++ ("BCM2708FB: start = %p,%p width=%d, height=%d, bpp=%d, pitch=%d size=%d success=%d\n", ++ (void *)fb->fb.screen_base, (void *)fb->fb.fix.smem_start, ++ fbinfo->xres, fbinfo->yres, fbinfo->bpp, ++ fbinfo->pitch, (int)fb->fb.screen_size, val); + + return val; + } +@@ -243,58 +266,62 @@ static inline u32 convert_bitfield(int v + return (val >> (16 - bf->length) & mask) << bf->offset; + } + +-static int bcm2708_fb_setcolreg(unsigned int regno, unsigned int red, unsigned int green, +- unsigned int blue, unsigned int transp, struct fb_info *info) ++static int bcm2708_fb_setcolreg(unsigned int regno, unsigned int red, ++ unsigned int green, unsigned int blue, ++ unsigned int transp, struct fb_info *info) + { + struct bcm2708_fb *fb = to_bcm2708(info); + + if (regno < 16) + fb->cmap[regno] = convert_bitfield(transp, &fb->fb.var.transp) | +- convert_bitfield(blue, &fb->fb.var.blue) | +- convert_bitfield(green, &fb->fb.var.green) | +- convert_bitfield(red, &fb->fb.var.red); ++ convert_bitfield(blue, &fb->fb.var.blue) | ++ convert_bitfield(green, &fb->fb.var.green) | ++ convert_bitfield(red, &fb->fb.var.red); + + return regno > 255; + } + + static int bcm2708_fb_blank(int blank_mode, struct fb_info *info) + { +-//printk(KERN_ERR "bcm2708_fb_blank\n"); ++ /*pr_info("bcm2708_fb_blank\n"); */ + return -1; + } + +-static void bcm2708_fb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) ++static void bcm2708_fb_fillrect(struct fb_info *info, ++ const struct fb_fillrect *rect) + { +-// (is called) printk(KERN_ERR "bcm2708_fb_fillrect\n"); ++ /* (is called) pr_info("bcm2708_fb_fillrect\n"); */ + cfb_fillrect(info, rect); + } + +-static void bcm2708_fb_copyarea(struct fb_info *info, const struct fb_copyarea *region) ++static void bcm2708_fb_copyarea(struct fb_info *info, ++ const struct fb_copyarea *region) + { +-//printk(KERN_ERR "bcm2708_fb_copyarea\n"); ++ /*pr_info("bcm2708_fb_copyarea\n"); */ + cfb_copyarea(info, region); + } + +-static void bcm2708_fb_imageblit(struct fb_info *info, const struct fb_image *image) ++static void bcm2708_fb_imageblit(struct fb_info *info, ++ const struct fb_image *image) + { +-// (is called) printk(KERN_ERR "bcm2708_fb_imageblit\n"); ++ /* (is called) pr_info("bcm2708_fb_imageblit\n"); */ + cfb_imageblit(info, image); + } + + static struct fb_ops bcm2708_fb_ops = { +- .owner = THIS_MODULE, +- .fb_check_var = bcm2708_fb_check_var, +- .fb_set_par = bcm2708_fb_set_par, +- .fb_setcolreg = bcm2708_fb_setcolreg, +- .fb_blank = bcm2708_fb_blank, +- .fb_fillrect = bcm2708_fb_fillrect, +- .fb_copyarea = bcm2708_fb_copyarea, +- .fb_imageblit = bcm2708_fb_imageblit, ++ .owner = THIS_MODULE, ++ .fb_check_var = bcm2708_fb_check_var, ++ .fb_set_par = bcm2708_fb_set_par, ++ .fb_setcolreg = bcm2708_fb_setcolreg, ++ .fb_blank = bcm2708_fb_blank, ++ .fb_fillrect = bcm2708_fb_fillrect, ++ .fb_copyarea = bcm2708_fb_copyarea, ++ .fb_imageblit = bcm2708_fb_imageblit, + }; + +-static int FBWIDTH =800; /* module parameter */ +-static int FBHEIGHT =480; /* module parameter */ +- ++static int fbwidth = 800; /* module parameter */ ++static int fbheight = 480; /* module parameter */ ++static int fbdepth = 16; /* module parameter */ + + static int bcm2708_fb_register(struct bcm2708_fb *fb) + { +@@ -302,45 +329,47 @@ static int bcm2708_fb_register(struct bc + dma_addr_t dma; + void *mem; + +- mem = dma_alloc_coherent(NULL, PAGE_ALIGN(sizeof(*fb->info)), &dma, GFP_KERNEL); ++ mem = ++ dma_alloc_coherent(NULL, PAGE_ALIGN(sizeof(*fb->info)), &dma, ++ GFP_KERNEL); + + if (NULL == mem) { +- printk(KERN_ERR ": unable to allocate fbinfo buffer\n"); ++ pr_err(": unable to allocate fbinfo buffer\n"); + ret = -ENOMEM; + } else { + fb->info = (struct fbinfo_s *)mem; +- fb->dma = dma; +- } +- fb->fb.fbops = &bcm2708_fb_ops; +- fb->fb.flags = FBINFO_FLAG_DEFAULT | FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT | FBINFO_HWACCEL_IMAGEBLIT; +- fb->fb.pseudo_palette = fb->cmap; ++ fb->dma = dma; ++ } ++ fb->fb.fbops = &bcm2708_fb_ops; ++ fb->fb.flags = FBINFO_FLAG_DEFAULT; ++ fb->fb.pseudo_palette = fb->cmap; + + strncpy(fb->fb.fix.id, bcm2708_name, sizeof(fb->fb.fix.id)); +- fb->fb.fix.type = FB_TYPE_PACKED_PIXELS; +- fb->fb.fix.type_aux = 0; +- fb->fb.fix.xpanstep = 0; +- fb->fb.fix.ypanstep = 0; +- fb->fb.fix.ywrapstep = 0; +- fb->fb.fix.accel = FB_ACCEL_NONE; +- +- fb->fb.var.xres = FBWIDTH; +- fb->fb.var.yres = FBHEIGHT; +- fb->fb.var.xres_virtual = FBWIDTH; +- fb->fb.var.yres_virtual = FBHEIGHT; +- fb->fb.var.bits_per_pixel = 16; +- fb->fb.var.vmode = FB_VMODE_NONINTERLACED; +- fb->fb.var.activate = FB_ACTIVATE_NOW; +- fb->fb.var.nonstd = 0; +- fb->fb.var.height = FBWIDTH; +- fb->fb.var.width = FBHEIGHT; +- fb->fb.var.accel_flags = 0; +- +- fb->fb.monspecs.hfmin = 0; +- fb->fb.monspecs.hfmax = 100000; +- fb->fb.monspecs.vfmin = 0; +- fb->fb.monspecs.vfmax = 400; ++ fb->fb.fix.type = FB_TYPE_PACKED_PIXELS; ++ fb->fb.fix.type_aux = 0; ++ fb->fb.fix.xpanstep = 0; ++ fb->fb.fix.ypanstep = 0; ++ fb->fb.fix.ywrapstep = 0; ++ fb->fb.fix.accel = FB_ACCEL_NONE; ++ ++ fb->fb.var.xres = fbwidth; ++ fb->fb.var.yres = fbheight; ++ fb->fb.var.xres_virtual = fbwidth; ++ fb->fb.var.yres_virtual = fbheight; ++ fb->fb.var.bits_per_pixel = fbdepth; ++ fb->fb.var.vmode = FB_VMODE_NONINTERLACED; ++ fb->fb.var.activate = FB_ACTIVATE_NOW; ++ fb->fb.var.nonstd = 0; ++ fb->fb.var.height = fbwidth; ++ fb->fb.var.width = fbheight; ++ fb->fb.var.accel_flags = 0; ++ ++ fb->fb.monspecs.hfmin = 0; ++ fb->fb.monspecs.hfmax = 100000; ++ fb->fb.monspecs.vfmin = 0; ++ fb->fb.monspecs.vfmax = 400; + fb->fb.monspecs.dclkmin = 1000000; +- fb->fb.monspecs.dclkmax = 100000000; ++ fb->fb.monspecs.dclkmax = 100000000; + + bcm2708_fb_set_bitfields(&fb->fb.var); + +@@ -350,17 +379,16 @@ static int bcm2708_fb_register(struct bc + + fb_set_var(&fb->fb, &fb->fb.var); + +- printk(KERN_INFO "BCM2708FB: registering framebuffer (%d, %d)\n", FBWIDTH, FBHEIGHT); ++ pr_info("BCM2708FB: registering framebuffer (%dx%d@%d)\n", fbwidth, ++ fbheight, fbdepth); + + ret = register_framebuffer(&fb->fb); +- printk(KERN_ERR "BCM2708FB: register framebuffer (%d)\n", ret); ++ pr_info("BCM2708FB: register framebuffer (%d)\n", ret); + if (ret == 0) + goto out; + +- printk(KERN_ERR "BCM2708FB: cannot register framebuffer (%d)\n", ret); +- +- iounmap(fb->regs); +- out: ++ pr_info("BCM2708FB: cannot register framebuffer (%d)\n", ret); ++out: + return ret; + } + +@@ -371,7 +399,8 @@ static int bcm2708_fb_probe(struct platf + + fb = kmalloc(sizeof(struct bcm2708_fb), GFP_KERNEL); + if (!fb) { +- dev_err(&dev->dev, "could not allocate new bcm2708_fb struct\n"); ++ dev_err(&dev->dev, ++ "could not allocate new bcm2708_fb struct\n"); + ret = -ENOMEM; + goto free_region; + } +@@ -386,9 +415,9 @@ static int bcm2708_fb_probe(struct platf + } + + kfree(fb); +- free_region: ++free_region: + dev_err(&dev->dev, "probe failed, err %d\n", ret); +- out: ++out: + return ret; + } + +@@ -398,22 +427,24 @@ static int bcm2708_fb_remove(struct plat + + platform_set_drvdata(dev, NULL); + ++ if (fb->fb.screen_base) ++ iounmap(fb->fb.screen_base); + unregister_framebuffer(&fb->fb); +- iounmap(fb->regs); + +- dma_free_coherent(NULL, PAGE_ALIGN(sizeof(*fb->info)), (void *)fb->info, fb->dma); ++ dma_free_coherent(NULL, PAGE_ALIGN(sizeof(*fb->info)), (void *)fb->info, ++ fb->dma); + kfree(fb); + + return 0; + } + + static struct platform_driver bcm2708_fb_driver = { +- .probe = bcm2708_fb_probe, +- .remove = bcm2708_fb_remove, +- .driver = { +- .name = DRIVER_NAME, +- .owner = THIS_MODULE, +- }, ++ .probe = bcm2708_fb_probe, ++ .remove = bcm2708_fb_remove, ++ .driver = { ++ .name = DRIVER_NAME, ++ .owner = THIS_MODULE, ++ }, + }; + + static int __init bcm2708_fb_init(void) +@@ -430,11 +461,13 @@ static void __exit bcm2708_fb_exit(void) + + module_exit(bcm2708_fb_exit); + +-module_param(FBWIDTH, int, 0644); +-module_param(FBHEIGHT, int, 0644); ++module_param(fbwidth, int, 0644); ++module_param(fbheight, int, 0644); ++module_param(fbdepth, int, 0644); + + MODULE_DESCRIPTION("BCM2708 framebuffer driver"); + MODULE_LICENSE("GPL"); + +-MODULE_PARM_DESC(FBWIDTH, "Width of ARM Framebuffer"); +-MODULE_PARM_DESC(FBHEIGHT, "Height of ARM Framebuffer"); ++MODULE_PARM_DESC(fbwidth, "Width of ARM Framebuffer"); ++MODULE_PARM_DESC(fbheight, "Height of ARM Framebuffer"); ++MODULE_PARM_DESC(fbdepth, "Bit depth of ARM Framebuffer"); +--- a/sound/arm/Kconfig ++++ b/sound/arm/Kconfig +@@ -39,5 +39,12 @@ config SND_PXA2XX_AC97 + Say Y or M if you want to support any AC97 codec attached to + the PXA2xx AC97 interface. + ++config SND_BCM2835 ++ tristate "BCM2835 ALSA driver" ++ depends on ARCH_BCM2708 && SND ++ select SND_PCM ++ help ++ Say Y or M if you want to support BCM2835 Alsa pcm card driver ++ + endif # SND_ARM + +--- a/sound/arm/Makefile ++++ b/sound/arm/Makefile +@@ -14,3 +14,9 @@ snd-pxa2xx-lib-$(CONFIG_SND_PXA2XX_LIB_A + + obj-$(CONFIG_SND_PXA2XX_AC97) += snd-pxa2xx-ac97.o + snd-pxa2xx-ac97-objs := pxa2xx-ac97.o ++ ++obj-$(CONFIG_SND_BCM2835) += snd-bcm2835.o ++snd-bcm2835-objs := bcm2835.o bcm2835-ctl.o bcm2835-pcm.o bcm2835-vchiq.o ++ ++EXTRA_CFLAGS += -Idrivers/misc/vc04_services -Idrivers/misc/vc04_services/interface/vcos/linuxkernel -D__VCCOREVER__=0x04000000 ++ +--- /dev/null ++++ b/sound/arm/bcm2835-ctl.c +@@ -0,0 +1,172 @@ ++/***************************************************************************** ++* Copyright 2011 Broadcom Corporation. All rights reserved. ++* ++* Unless you and Broadcom execute a separate written software license ++* agreement governing use of this software, this software is licensed to you ++* under the terms of the GNU General Public License version 2, available at ++* http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). ++* ++* Notwithstanding the above, under no circumstances may you combine this ++* software in any way with any other Broadcom software provided under a ++* license other than the GPL, without Broadcom's express prior written ++* consent. ++*****************************************************************************/ ++ ++#include <linux/platform_device.h> ++#include <linux/init.h> ++#include <linux/io.h> ++#include <linux/jiffies.h> ++#include <linux/slab.h> ++#include <linux/time.h> ++#include <linux/wait.h> ++#include <linux/delay.h> ++#include <linux/moduleparam.h> ++#include <linux/sched.h> ++ ++#include <sound/core.h> ++#include <sound/control.h> ++#include <sound/pcm.h> ++#include <sound/pcm_params.h> ++#include <sound/rawmidi.h> ++#include <sound/initval.h> ++#include <sound/tlv.h> ++ ++#include "bcm2835.h" ++ ++static int snd_bcm2835_ctl_info(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_info *uinfo) ++{ ++ if (kcontrol->private_value == PCM_PLAYBACK_VOLUME) { ++ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; ++ uinfo->count = 1; ++ uinfo->value.integer.min = -10240; ++ uinfo->value.integer.max = 2303; ++ } else if (kcontrol->private_value == PCM_PLAYBACK_MUTE) { ++ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; ++ uinfo->count = 1; ++ uinfo->value.integer.min = 0; ++ uinfo->value.integer.max = 1; ++ } else if (kcontrol->private_value == PCM_PLAYBACK_DEVICE) { ++ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; ++ uinfo->count = 1; ++ uinfo->value.integer.min = 0; ++ uinfo->value.integer.max = AUDIO_DEST_MAX-0; ++ } ++ ++ return 0; ++} ++ ++static int snd_bcm2835_ctl_get(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol); ++ ++ BUG_ON(!chip && !(chip->avail_substreams & AVAIL_SUBSTREAMS_MASK)); ++ ++ if (kcontrol->private_value == PCM_PLAYBACK_VOLUME) ++ ucontrol->value.integer.value[0] = chip->volume; ++ else if (kcontrol->private_value == PCM_PLAYBACK_MUTE) ++ ucontrol->value.integer.value[0] = chip->mute; ++ else if (kcontrol->private_value == PCM_PLAYBACK_DEVICE) ++ ucontrol->value.integer.value[0] = chip->dest; ++ ++ return 0; ++} ++ ++static int snd_bcm2835_ctl_put(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol); ++ int changed = 0; ++ ++ if (kcontrol->private_value == PCM_PLAYBACK_VOLUME) { ++ if (chip->mute) { ++ chip->mute = 0; ++ changed = 1; ++ } ++ if (changed ++ || (ucontrol->value.integer.value[0] != chip->volume)) { ++ int atten; ++ ++ chip->volume = ucontrol->value.integer.value[0]; ++ changed = 1; ++ atten = -((chip->volume << 8) / 100); ++ chip->volume = atten; ++ } ++ ++ } else if (kcontrol->private_value == PCM_PLAYBACK_MUTE) { ++ /* Not implemented */ ++ if (ucontrol->value.integer.value[0] != chip->mute) { ++ chip->mute = ucontrol->value.integer.value[0]; ++ changed = 0; ++ } ++ } else if (kcontrol->private_value == PCM_PLAYBACK_DEVICE) { ++ if (ucontrol->value.integer.value[0] != chip->dest) { ++ chip->dest = ucontrol->value.integer.value[0]; ++ changed = 1; ++ } ++ } ++ ++ if (changed) { ++ if (bcm2835_audio_set_ctls(chip)) ++ printk(KERN_ERR "Failed to set ALSA controls..\n"); ++ } ++ ++ return changed; ++} ++ ++static DECLARE_TLV_DB_SCALE(snd_bcm2835_db_scale, -10240, 1, 1); ++ ++static struct snd_kcontrol_new snd_bcm2835_ctl[] __devinitdata = { ++ { ++ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, ++ .name = "PCM Playback Volume", ++ .index = 0, ++ .access = ++ SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE, ++ .private_value = PCM_PLAYBACK_VOLUME, ++ .info = snd_bcm2835_ctl_info, ++ .get = snd_bcm2835_ctl_get, ++ .put = snd_bcm2835_ctl_put, ++ .count = 1, ++ .tlv = {.p = snd_bcm2835_db_scale} ++ }, ++ { ++ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, ++ .name = "PCM Playback Switch", ++ .index = 0, ++ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, ++ .private_value = PCM_PLAYBACK_MUTE, ++ .info = snd_bcm2835_ctl_info, ++ .get = snd_bcm2835_ctl_get, ++ .put = snd_bcm2835_ctl_put, ++ .count = 1, ++ }, ++ { ++ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, ++ .name = "PCM Playback Route", ++ .index = 0, ++ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, ++ .private_value = PCM_PLAYBACK_DEVICE, ++ .info = snd_bcm2835_ctl_info, ++ .get = snd_bcm2835_ctl_get, ++ .put = snd_bcm2835_ctl_put, ++ .count = 1, ++ }, ++}; ++ ++int __devinit snd_bcm2835_new_ctl(bcm2835_chip_t * chip) ++{ ++ int err; ++ unsigned int idx; ++ ++ strcpy(chip->card->mixername, "Broadcom Mixer"); ++ for (idx = 0; idx < ARRAY_SIZE(snd_bcm2835_ctl); idx++) { ++ err = ++ snd_ctl_add(chip->card, ++ snd_ctl_new1(&snd_bcm2835_ctl[idx], chip)); ++ if (err < 0) ++ return err; ++ } ++ return 0; ++} +--- /dev/null ++++ b/sound/arm/bcm2835-pcm.c +@@ -0,0 +1,424 @@ ++/***************************************************************************** ++* Copyright 2011 Broadcom Corporation. All rights reserved. ++* ++* Unless you and Broadcom execute a separate written software license ++* agreement governing use of this software, this software is licensed to you ++* under the terms of the GNU General Public License version 2, available at ++* http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). ++* ++* Notwithstanding the above, under no circumstances may you combine this ++* software in any way with any other Broadcom software provided under a ++* license other than the GPL, without Broadcom's express prior written ++* consent. ++*****************************************************************************/ ++ ++#include <linux/interrupt.h> ++#include <linux/slab.h> ++ ++#include "bcm2835.h" ++ ++/* hardware definition */ ++static struct snd_pcm_hardware snd_bcm2835_playback_hw = { ++ .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER), ++ .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE, ++ .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, ++ .rate_min = 8000, ++ .rate_max = 48000, ++ .channels_min = 1, ++ .channels_max = 2, ++ .buffer_bytes_max = (4 * 8 - 1) * 1024, /* Needs to be less than audioplay buffer size */ ++ .period_bytes_min = 1 * 1024, ++ .period_bytes_max = (4 * 8 - 1) * 1024, ++ .periods_min = 1, ++ .periods_max = 4 * 8 - 1, ++}; ++ ++static void snd_bcm2835_playback_free(struct snd_pcm_runtime *runtime) ++{ ++ audio_info("Freeing up alsa stream here ..\n"); ++ if (runtime->private_data) ++ kfree(runtime->private_data); ++ runtime->private_data = NULL; ++} ++ ++static irqreturn_t bcm2835_playback_fifo_irq(int irq, void *dev_id) ++{ ++ bcm2835_alsa_stream_t *alsa_stream = (bcm2835_alsa_stream_t *) dev_id; ++ uint32_t consumed = 0; ++ int new_period = 0; ++ ++ audio_info(" .. IN\n"); ++ ++ audio_info("alsa_stream=%p substream=%p\n", alsa_stream, ++ alsa_stream ? alsa_stream->substream : 0); ++ ++ if (alsa_stream->open) ++ consumed = bcm2835_audio_retrieve_buffers(alsa_stream); ++ ++ /* We get called only if playback was triggered, So, the number of buffers we retrieve in ++ * each iteration are the buffers that have been played out already ++ */ ++ ++ if (alsa_stream->period_size) { ++ if ((alsa_stream->pos / alsa_stream->period_size) != ++ ((alsa_stream->pos + consumed) / alsa_stream->period_size)) ++ new_period = 1; ++ } ++ audio_debug("updating pos cur: %d + %d max:%d new_period:%d\n", ++ alsa_stream->pos, ++ (consumed /** AUDIO_IPC_BLOCK_BUFFER_SIZE*/ ), ++ alsa_stream->buffer_size, new_period); ++ if (alsa_stream->buffer_size) { ++ alsa_stream->pos += consumed; ++ alsa_stream->pos %= alsa_stream->buffer_size; ++ } ++ if (alsa_stream->substream) { ++ if (new_period) ++ snd_pcm_period_elapsed(alsa_stream->substream); ++ } else { ++ audio_warning(" unexpected NULL substream\n"); ++ } ++ audio_info(" .. OUT\n"); ++ ++ return IRQ_HANDLED; ++} ++ ++/* open callback */ ++static int snd_bcm2835_playback_open(struct snd_pcm_substream *substream) ++{ ++ bcm2835_chip_t *chip = snd_pcm_substream_chip(substream); ++ struct snd_pcm_runtime *runtime = substream->runtime; ++ bcm2835_alsa_stream_t *alsa_stream; ++ int idx; ++ int err; ++ ++ audio_info(" .. IN (%d)\n", substream->number); ++ ++ audio_warning("Alsa open (%d)\n", substream->number); ++ idx = substream->number; ++ ++ if (idx > MAX_SUBSTREAMS) { ++ audio_error ++ ("substream(%d) device doesn't exist max(%d) substreams allowed\n", ++ idx, MAX_SUBSTREAMS); ++ err = -ENODEV; ++ goto out; ++ } ++ ++ /* Check if we are ready */ ++ if (!(chip->avail_substreams & (1 << idx))) { ++ /* We are not ready yet */ ++ audio_error("substream(%d) device is not ready yet\n", idx); ++ err = -EAGAIN; ++ goto out; ++ } ++ ++ alsa_stream = kzalloc(sizeof(bcm2835_alsa_stream_t), GFP_KERNEL); ++ if (alsa_stream == NULL) { ++ return -ENOMEM; ++ } ++ ++ /* Initialise alsa_stream */ ++ alsa_stream->chip = chip; ++ alsa_stream->substream = substream; ++ alsa_stream->idx = idx; ++ chip->alsa_stream[idx] = alsa_stream; ++ ++ sema_init(&alsa_stream->buffers_update_sem, 0); ++ sema_init(&alsa_stream->control_sem, 0); ++ spin_lock_init(&alsa_stream->lock); ++ ++ /* Enabled in start trigger, called on each "fifo irq" after that */ ++ alsa_stream->enable_fifo_irq = 0; ++ alsa_stream->fifo_irq_handler = bcm2835_playback_fifo_irq; ++ ++ runtime->private_data = alsa_stream; ++ runtime->private_free = snd_bcm2835_playback_free; ++ runtime->hw = snd_bcm2835_playback_hw; ++ ++ /* minimum 16 bytes alignment (for vchiq bulk transfers) */ ++ snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, ++ 16); ++ ++ err = bcm2835_audio_open(alsa_stream); ++ if (err != 0) { ++ kfree(alsa_stream); ++ return err; ++ } ++ ++ alsa_stream->open = 1; ++ alsa_stream->draining = 1; ++ ++out: ++ audio_info(" .. OUT =%d\n", err); ++ ++ return err; ++} ++ ++/* close callback */ ++static int snd_bcm2835_playback_close(struct snd_pcm_substream *substream) ++{ ++ /* the hardware-specific codes will be here */ ++ ++ struct snd_pcm_runtime *runtime = substream->runtime; ++ bcm2835_alsa_stream_t *alsa_stream = runtime->private_data; ++ ++ audio_info(" .. IN\n"); ++ audio_warning("Alsa close\n"); ++ ++ /* ++ * Call stop if it's still running. This happens when app ++ * is force killed and we don't get a stop trigger. ++ */ ++ if (alsa_stream->running) { ++ int err; ++ err = bcm2835_audio_stop(alsa_stream); ++ alsa_stream->running = 0; ++ if (err != 0) ++ audio_error(" Failed to STOP alsa device\n"); ++ } ++ ++ alsa_stream->period_size = 0; ++ alsa_stream->buffer_size = 0; ++ ++ if (alsa_stream->open) { ++ alsa_stream->open = 0; ++ bcm2835_audio_close(alsa_stream); ++ } ++ if (alsa_stream->chip) ++ alsa_stream->chip->alsa_stream[alsa_stream->idx] = NULL; ++ /* ++ * Do not free up alsa_stream here, it will be freed up by ++ * runtime->private_free callback we registered in *_open above ++ */ ++ ++ audio_info(" .. OUT\n"); ++ ++ return 0; ++} ++ ++/* hw_params callback */ ++static int snd_bcm2835_pcm_hw_params(struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params) ++{ ++ int err; ++ struct snd_pcm_runtime *runtime = substream->runtime; ++ bcm2835_alsa_stream_t *alsa_stream = ++ (bcm2835_alsa_stream_t *) runtime->private_data; ++ ++ audio_info(" .. IN\n"); ++ ++ err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params)); ++ if (err < 0) { ++ audio_error ++ (" pcm_lib_malloc failed to allocated pages for buffers\n"); ++ return err; ++ } ++ ++ err = bcm2835_audio_set_params(alsa_stream, params_channels(params), ++ params_rate(params), ++ snd_pcm_format_width(params_format ++ (params))); ++ if (err < 0) { ++ audio_error(" error setting hw params\n"); ++ } ++ ++ bcm2835_audio_setup(alsa_stream); ++ audio_info(" .. OUT\n"); ++ ++ return err; ++} ++ ++/* hw_free callback */ ++static int snd_bcm2835_pcm_hw_free(struct snd_pcm_substream *substream) ++{ ++ audio_info(" .. IN\n"); ++ return snd_pcm_lib_free_pages(substream); ++} ++ ++/* prepare callback */ ++static int snd_bcm2835_pcm_prepare(struct snd_pcm_substream *substream) ++{ ++ struct snd_pcm_runtime *runtime = substream->runtime; ++ bcm2835_alsa_stream_t *alsa_stream = runtime->private_data; ++ ++ audio_info(" .. IN\n"); ++ ++ alsa_stream->buffer_size = snd_pcm_lib_buffer_bytes(substream); ++ alsa_stream->period_size = snd_pcm_lib_period_bytes(substream); ++ alsa_stream->pos = 0; ++ ++ audio_debug("buffer_size=%d, period_size=%d pos=%d frame_bits=%d\n", ++ alsa_stream->buffer_size, alsa_stream->period_size, ++ alsa_stream->pos, runtime->frame_bits); ++ ++ audio_info(" .. OUT\n"); ++ return 0; ++} ++ ++/* trigger callback */ ++static int snd_bcm2835_pcm_trigger(struct snd_pcm_substream *substream, int cmd) ++{ ++ struct snd_pcm_runtime *runtime = substream->runtime; ++ bcm2835_alsa_stream_t *alsa_stream = runtime->private_data; ++ int err = 0; ++ ++ audio_info(" .. IN\n"); ++ ++ switch (cmd) { ++ case SNDRV_PCM_TRIGGER_START: ++ audio_debug("bcm2835_AUDIO_TRIGGER_START running=%d\n", ++ alsa_stream->running); ++ if (!alsa_stream->running) { ++ err = bcm2835_audio_start(alsa_stream); ++ if (err == 0) { ++ alsa_stream->running = 1; ++ alsa_stream->draining = 1; ++ } ++ } ++ break; ++ case SNDRV_PCM_TRIGGER_STOP: ++ audio_debug ++ ("bcm2835_AUDIO_TRIGGER_STOP running=%d draining=%d\n", ++ runtime->status->state == SNDRV_PCM_STATE_DRAINING, ++ alsa_stream->running); ++ if (runtime->status->state == SNDRV_PCM_STATE_DRAINING) { ++ audio_info("DRAINING\n"); ++ alsa_stream->draining = 1; ++ } else { ++ audio_info("DROPPING\n"); ++ alsa_stream->draining = 0; ++ } ++ if (alsa_stream->running) { ++ err = bcm2835_audio_stop(alsa_stream); ++ if (err != 0) ++ audio_error(" Failed to STOP alsa device\n"); ++ alsa_stream->running = 0; ++ } ++ break; ++ default: ++ err = -EINVAL; ++ } ++ ++ audio_info(" .. OUT\n"); ++ return err; ++} ++ ++/* pointer callback */ ++static snd_pcm_uframes_t ++snd_bcm2835_pcm_pointer(struct snd_pcm_substream *substream) ++{ ++ struct snd_pcm_runtime *runtime = substream->runtime; ++ bcm2835_alsa_stream_t *alsa_stream = runtime->private_data; ++ ++ audio_info(" .. IN\n"); ++ ++ audio_debug("pcm_pointer... (%d) hwptr=%d appl=%d pos=%d\n", 0, ++ frames_to_bytes(runtime, runtime->status->hw_ptr), ++ frames_to_bytes(runtime, runtime->control->appl_ptr), ++ alsa_stream->pos); ++ ++ audio_info(" .. OUT\n"); ++ return bytes_to_frames(runtime, alsa_stream->pos); ++} ++ ++static int snd_bcm2835_pcm_copy(struct snd_pcm_substream *substream, ++ int channel, snd_pcm_uframes_t pos, void *src, ++ snd_pcm_uframes_t count) ++{ ++ int ret; ++ struct snd_pcm_runtime *runtime = substream->runtime; ++ bcm2835_alsa_stream_t *alsa_stream = runtime->private_data; ++ ++ audio_info(" .. IN\n"); ++ audio_debug("copy.......... (%d) hwptr=%d appl=%d pos=%d\n", ++ frames_to_bytes(runtime, count), frames_to_bytes(runtime, ++ runtime-> ++ status-> ++ hw_ptr), ++ frames_to_bytes(runtime, runtime->control->appl_ptr), ++ alsa_stream->pos); ++ ret = ++ bcm2835_audio_write(alsa_stream, frames_to_bytes(runtime, count), ++ src); ++ audio_info(" .. OUT\n"); ++ return ret; ++} ++ ++static int snd_bcm2835_pcm_silence(struct snd_pcm_substream *substream, ++ int channel, snd_pcm_uframes_t post, ++ snd_pcm_uframes_t count) ++{ ++ int ret; ++ struct snd_pcm_runtime *runtime = substream->runtime; ++ bcm2835_alsa_stream_t *alsa_stream = runtime->private_data; ++ ++ audio_info(" .. IN\n"); ++ audio_debug("silence....... (%d) hwptr=%d appl=%d pos=%d\n", ++ frames_to_bytes(runtime, count), frames_to_bytes(runtime, ++ runtime-> ++ status-> ++ hw_ptr), ++ frames_to_bytes(runtime, runtime->control->appl_ptr), ++ alsa_stream->pos); ++ ret = ++ bcm2835_audio_write(alsa_stream, frames_to_bytes(runtime, count), ++ NULL); ++ audio_info(" .. OUT\n"); ++ return ret; ++} ++ ++static int snd_bcm2835_pcm_lib_ioctl(struct snd_pcm_substream *substream, ++ unsigned int cmd, void *arg) ++{ ++ int ret = snd_pcm_lib_ioctl(substream, cmd, arg); ++ audio_info(" .. substream=%p, cmd=%d, arg=%p (%x) ret=%d\n", substream, ++ cmd, arg, arg ? *(unsigned *)arg : 0, ret); ++ return ret; ++} ++ ++/* operators */ ++static struct snd_pcm_ops snd_bcm2835_playback_ops = { ++ .open = snd_bcm2835_playback_open, ++ .close = snd_bcm2835_playback_close, ++ .ioctl = snd_bcm2835_pcm_lib_ioctl, ++ .hw_params = snd_bcm2835_pcm_hw_params, ++ .hw_free = snd_bcm2835_pcm_hw_free, ++ .prepare = snd_bcm2835_pcm_prepare, ++ .trigger = snd_bcm2835_pcm_trigger, ++ .pointer = snd_bcm2835_pcm_pointer, ++ .copy = snd_bcm2835_pcm_copy, ++ .silence = snd_bcm2835_pcm_silence, ++}; ++ ++/* create a pcm device */ ++int __devinit snd_bcm2835_new_pcm(bcm2835_chip_t * chip) ++{ ++ struct snd_pcm *pcm; ++ int err; ++ ++ audio_info(" .. IN\n"); ++ err = ++ snd_pcm_new(chip->card, "bcm2835 ALSA", 0, MAX_SUBSTREAMS, 0, &pcm); ++ if (err < 0) ++ return err; ++ pcm->private_data = chip; ++ strcpy(pcm->name, "bcm2835 ALSA"); ++ chip->pcm = pcm; ++ chip->dest = AUDIO_DEST_AUTO; ++ chip->volume = 100; ++ /* set operators */ ++ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, ++ &snd_bcm2835_playback_ops); ++ ++ /* pre-allocation of buffers */ ++ /* NOTE: this may fail */ ++ snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS, ++ snd_dma_continuous_data ++ (GFP_KERNEL), 64 * 1024, ++ 64 * 1024); ++ ++ audio_info(" .. OUT\n"); ++ ++ return 0; ++} +--- /dev/null ++++ b/sound/arm/bcm2835-vchiq.c +@@ -0,0 +1,818 @@ ++/***************************************************************************** ++* Copyright 2011 Broadcom Corporation. All rights reserved. ++* ++* Unless you and Broadcom execute a separate written software license ++* agreement governing use of this software, this software is licensed to you ++* under the terms of the GNU General Public License version 2, available at ++* http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). ++* ++* Notwithstanding the above, under no circumstances may you combine this ++* software in any way with any other Broadcom software provided under a ++* license other than the GPL, without Broadcom's express prior written ++* consent. ++*****************************************************************************/ ++ ++#include <linux/device.h> ++#include <sound/core.h> ++#include <sound/initval.h> ++#include <sound/pcm.h> ++#include <linux/io.h> ++#include <linux/interrupt.h> ++#include <linux/fs.h> ++#include <linux/file.h> ++#include <linux/mm.h> ++#include <linux/syscalls.h> ++#include <asm/uaccess.h> ++#include <linux/slab.h> ++#include <linux/delay.h> ++#include <linux/atomic.h> ++ ++#include "bcm2835.h" ++ ++/* ---- Include Files -------------------------------------------------------- */ ++ ++#include "interface/vchi/vchi.h" ++#include "interface/vcos/vcos.h" ++#include "interface/vcos/vcos_logging.h" ++#include "vc_vchi_audioserv_defs.h" ++ ++/* ---- Private Constants and Types ------------------------------------------ */ ++ ++/* VCOS logging category for this service */ ++#define VCOS_LOG_CATEGORY (&audio_log_category) ++ ++/* Default VCOS logging level */ ++#define LOG_LEVEL VCOS_LOG_WARN ++ ++/* Logging macros (for remapping to other logging mechanisms, i.e., printf) */ ++#define LOG_ERR( fmt, arg... ) vcos_log_error( "%s:%d " fmt, __func__, __LINE__, ##arg) ++#define LOG_WARN( fmt, arg... ) vcos_log_warn( "%s:%d " fmt, __func__, __LINE__, ##arg) ++#define LOG_INFO( fmt, arg... ) vcos_log_info( "%s:%d " fmt, __func__, __LINE__, ##arg) ++#define LOG_DBG( fmt, arg... ) vcos_log_info( "%s:%d " fmt, __func__, __LINE__, ##arg) ++ ++typedef struct opaque_AUDIO_INSTANCE_T { ++ uint32_t num_connections; ++ VCHI_SERVICE_HANDLE_T vchi_handle[VCHI_MAX_NUM_CONNECTIONS]; ++ VCOS_EVENT_T msg_avail_event; ++ VCOS_MUTEX_T vchi_mutex; ++ bcm2835_alsa_stream_t *alsa_stream; ++ int32_t result, got_result; ++} AUDIO_INSTANCE_T; ++ ++/* ---- Private Variables ---------------------------------------------------- */ ++ ++/* VCOS logging category for this service */ ++static VCOS_LOG_CAT_T audio_log_category; ++ ++/* ---- Private Function Prototypes ------------------------------------------ */ ++ ++/* ---- Private Functions ---------------------------------------------------- */ ++ ++static int bcm2835_audio_stop_worker(bcm2835_alsa_stream_t * alsa_stream); ++static int bcm2835_audio_start_worker(bcm2835_alsa_stream_t * alsa_stream); ++ ++typedef struct { ++ struct work_struct my_work; ++ bcm2835_alsa_stream_t *alsa_stream; ++ int x; ++} my_work_t; ++ ++static void my_wq_function(struct work_struct *work) ++{ ++ my_work_t *w = (my_work_t *) work; ++ int ret = -9; ++ LOG_DBG(" .. IN %p:%d\n", w->alsa_stream, w->x); ++ switch (w->x) { ++ case 1: ++ ret = bcm2835_audio_start_worker(w->alsa_stream); ++ break; ++ case 2: ++ ret = bcm2835_audio_stop_worker(w->alsa_stream); ++ break; ++ default: ++ LOG_ERR(" Unexpected work: %p:%d\n", w->alsa_stream, w->x); ++ break; ++ } ++ kfree((void *)work); ++ LOG_DBG(" .. OUT %d\n", ret); ++} ++ ++int bcm2835_audio_start(bcm2835_alsa_stream_t * alsa_stream) ++{ ++ int ret = -1; ++ LOG_DBG(" .. IN\n"); ++ if (alsa_stream->my_wq) { ++ my_work_t *work = kmalloc(sizeof(my_work_t), GFP_KERNEL); ++ /* Queue some work (item 1) */ ++ if (work) { ++ INIT_WORK((struct work_struct *)work, my_wq_function); ++ work->alsa_stream = alsa_stream; ++ work->x = 1; ++ if (queue_work ++ (alsa_stream->my_wq, (struct work_struct *)work)) ++ ret = 0; ++ } else ++ LOG_ERR(" .. Error: NULL work kmalloc\n"); ++ } ++ LOG_DBG(" .. OUT %d\n", ret); ++ return ret; ++} ++ ++int bcm2835_audio_stop(bcm2835_alsa_stream_t * alsa_stream) ++{ ++ int ret = -1; ++ LOG_DBG(" .. IN\n"); ++ if (alsa_stream->my_wq) { ++ my_work_t *work = kmalloc(sizeof(my_work_t), GFP_KERNEL); ++ /* Queue some work (item 1) */ ++ if (work) { ++ INIT_WORK((struct work_struct *)work, my_wq_function); ++ work->alsa_stream = alsa_stream; ++ work->x = 2; ++ if (queue_work ++ (alsa_stream->my_wq, (struct work_struct *)work)) ++ ret = 0; ++ } else ++ LOG_ERR(" .. Error: NULL work kmalloc\n"); ++ } ++ LOG_DBG(" .. OUT %d\n", ret); ++ return ret; ++} ++ ++void my_workqueue_init(bcm2835_alsa_stream_t * alsa_stream) ++{ ++ alsa_stream->my_wq = create_workqueue("my_queue"); ++} ++ ++void my_workqueue_quit(bcm2835_alsa_stream_t * alsa_stream) ++{ ++ if (alsa_stream->my_wq) { ++ flush_workqueue(alsa_stream->my_wq); ++ destroy_workqueue(alsa_stream->my_wq); ++ alsa_stream->my_wq = NULL; ++ } ++} ++ ++static void audio_vchi_callback(void *param, ++ const VCHI_CALLBACK_REASON_T reason, ++ void *msg_handle) ++{ ++ AUDIO_INSTANCE_T *instance = (AUDIO_INSTANCE_T *) param; ++ int32_t status; ++ int32_t msg_len; ++ VC_AUDIO_MSG_T m; ++ bcm2835_alsa_stream_t *alsa_stream = 0; ++ LOG_DBG(" .. IN instance=%p, param=%p, reason=%d, handle=%p\n", ++ instance, param, reason, msg_handle); ++ ++ if (!instance || reason != VCHI_CALLBACK_MSG_AVAILABLE) { ++ return; ++ } ++ alsa_stream = instance->alsa_stream; ++ status = vchi_msg_dequeue(instance->vchi_handle[0], ++ &m, sizeof m, &msg_len, VCHI_FLAGS_NONE); ++ if (m.type == VC_AUDIO_MSG_TYPE_RESULT) { ++ LOG_DBG ++ (" .. instance=%p, m.type=VC_AUDIO_MSG_TYPE_RESULT, success=%d\n", ++ instance, m.u.result.success); ++ BUG_ON(instance->got_result); ++ instance->result = m.u.result.success; ++ instance->got_result = 1; ++ vcos_event_signal(&instance->msg_avail_event); ++ } else if (m.type == VC_AUDIO_MSG_TYPE_COMPLETE) { ++ irq_handler_t callback = (irq_handler_t) m.u.complete.callback; ++ LOG_DBG ++ (" .. instance=%p, m.type=VC_AUDIO_MSG_TYPE_COMPLETE, complete=%d\n", ++ instance, m.u.complete.count); ++ if (alsa_stream && callback) { ++ atomic_add(m.u.complete.count, &alsa_stream->retrieved); ++ callback(0, alsa_stream); ++ } else { ++ LOG_DBG(" .. unexpected alsa_stream=%p, callback=%p\n", ++ alsa_stream, callback); ++ } ++ vcos_event_signal(&instance->msg_avail_event); ++ } else { ++ LOG_DBG(" .. unexpected m.type=%d\n", m.type); ++ } ++} ++ ++static AUDIO_INSTANCE_T *vc_vchi_audio_init(VCHI_INSTANCE_T vchi_instance, ++ VCHI_CONNECTION_T ** ++ vchi_connections, ++ uint32_t num_connections) ++{ ++ uint32_t i; ++ AUDIO_INSTANCE_T *instance; ++ VCOS_STATUS_T status; ++ ++ LOG_DBG("%s: start", __func__); ++ ++ if (num_connections > VCHI_MAX_NUM_CONNECTIONS) { ++ LOG_ERR("%s: unsupported number of connections %u (max=%u)", ++ __func__, num_connections, VCHI_MAX_NUM_CONNECTIONS); ++ ++ return NULL; ++ } ++ /* Allocate memory for this instance */ ++ instance = vcos_malloc(sizeof(*instance), "audio_instance"); ++ memset(instance, 0, sizeof(*instance)); ++ ++ instance->num_connections = num_connections; ++ /* Create the message available event */ ++ status = ++ vcos_event_create(&instance->msg_avail_event, "audio_msg_avail"); ++ if (status != VCOS_SUCCESS) { ++ LOG_ERR("%s: failed to create event (status=%d)", __func__, ++ status); ++ ++ goto err_free_mem; ++ } ++ /* Create a lock for exclusive, serialized VCHI connection access */ ++ status = vcos_mutex_create(&instance->vchi_mutex, "audio_vchi_mutex"); ++ if (status != VCOS_SUCCESS) { ++ LOG_ERR("%s: failed to create event (status=%d)", __func__, ++ status); ++ ++ goto err_delete_event; ++ } ++ /* Open the VCHI service connections */ ++ for (i = 0; i < num_connections; i++) { ++ SERVICE_CREATION_T params = { ++ VC_AUDIO_SERVER_NAME, // 4cc service code ++ vchi_connections[i], // passed in fn pointers ++ 0, // rx fifo size (unused) ++ 0, // tx fifo size (unused) ++ audio_vchi_callback, // service callback ++ instance, // service callback parameter ++ VCOS_TRUE, //TODO: remove VCOS_FALSE, // unaligned bulk recieves ++ VCOS_TRUE, //TODO: remove VCOS_FALSE, // unaligned bulk transmits ++ VCOS_FALSE // want crc check on bulk transfers ++ }; ++ ++ status = vchi_service_open(vchi_instance, ¶ms, ++ &instance->vchi_handle[i]); ++ if (status != VCOS_SUCCESS) { ++ LOG_ERR ++ ("%s: failed to open VCHI service connection (status=%d)", ++ __func__, status); ++ ++ goto err_close_services; ++ } ++ /* Finished with the service for now */ ++ vchi_service_release(instance->vchi_handle[i]); ++ } ++ ++ return instance; ++ ++err_close_services: ++ for (i = 0; i < instance->num_connections; i++) { ++ vchi_service_close(instance->vchi_handle[i]); ++ } ++ ++ vcos_mutex_delete(&instance->vchi_mutex); ++ ++err_delete_event: ++ vcos_event_delete(&instance->msg_avail_event); ++ ++err_free_mem: ++ vcos_free(instance); ++ ++ return NULL; ++} ++ ++static int32_t vc_vchi_audio_deinit(AUDIO_INSTANCE_T * instance) ++{ ++ uint32_t i; ++ ++ LOG_DBG(" .. IN\n"); ++ ++ if (instance == NULL) { ++ LOG_ERR("%s: invalid handle %p", __func__, instance); ++ ++ return -1; ++ } ++ ++ LOG_DBG(" .. about to lock (%d)\n", instance->num_connections); ++ vcos_mutex_lock(&instance->vchi_mutex); ++ ++ /* Close all VCHI service connections */ ++ for (i = 0; i < instance->num_connections; i++) { ++ int32_t success; ++ LOG_DBG(" .. %i:closing %p\n", i, instance->vchi_handle[i]); ++ vchi_service_use(instance->vchi_handle[i]); ++ ++ success = vchi_service_close(instance->vchi_handle[i]); ++ if (success != 0) { ++ LOG_ERR ++ ("%s: failed to close VCHI service connection (status=%d)", ++ __func__, success); ++ } ++ } ++ ++ vcos_mutex_unlock(&instance->vchi_mutex); ++ ++ vcos_mutex_delete(&instance->vchi_mutex); ++ ++ vcos_event_delete(&instance->msg_avail_event); ++ ++ vcos_free(instance); ++ ++ /* Unregister the log category so we can add it back next time */ ++ vcos_log_unregister(&audio_log_category); ++ ++ LOG_DBG(" .. OUT\n"); ++ ++ return 0; ++} ++ ++static int bcm2835_audio_open_connection(bcm2835_alsa_stream_t * alsa_stream) ++{ ++ static VCHI_INSTANCE_T vchi_instance; ++ static VCHI_CONNECTION_T *vchi_connection; ++ AUDIO_INSTANCE_T *instance = alsa_stream->instance; ++ int ret; ++ LOG_DBG(" .. IN\n"); ++ ++ LOG_INFO("%s: start", __func__); ++ //BUG_ON(instance); ++ if (instance) { ++ LOG_ERR("%s: VCHI instance already open (%p)", ++ __func__, instance); ++ instance->alsa_stream = alsa_stream; ++ alsa_stream->instance = instance; ++ ret = 0; // xxx todo -1; ++ goto err_free_mem; ++ } ++ ++ /* Initialize and create a VCHI connection */ ++ ret = vchi_initialise(&vchi_instance); ++ if (ret != 0) { ++ LOG_ERR("%s: failed to initialise VCHI instance (ret=%d)", ++ __func__, ret); ++ ++ ret = -EIO; ++ goto err_free_mem; ++ } ++ ret = vchi_connect(NULL, 0, vchi_instance); ++ if (ret != 0) { ++ LOG_ERR("%s: failed to connect VCHI instance (ret=%d)", ++ __func__, ret); ++ ++ ret = -EIO; ++ goto err_free_mem; ++ } ++ ++ /* Set up the VCOS logging */ ++ vcos_log_set_level(VCOS_LOG_CATEGORY, LOG_LEVEL); ++ vcos_log_register("audio", VCOS_LOG_CATEGORY); ++ ++ /* Initialize an instance of the audio service */ ++ instance = vc_vchi_audio_init(vchi_instance, &vchi_connection, 1); ++ ++ if (instance == NULL /*|| audio_handle != instance */ ) { ++ LOG_ERR("%s: failed to initialize audio service", __func__); ++ ++ ret = -EPERM; ++ goto err_free_mem; ++ } ++ ++ instance->alsa_stream = alsa_stream; ++ alsa_stream->instance = instance; ++ ++ LOG_DBG(" success !\n"); ++err_free_mem: ++ LOG_DBG(" .. OUT\n"); ++ ++ return ret; ++} ++ ++int bcm2835_audio_open(bcm2835_alsa_stream_t * alsa_stream) ++{ ++ AUDIO_INSTANCE_T *instance; ++ VC_AUDIO_MSG_T m; ++ int32_t success; ++ int ret; ++ LOG_DBG(" .. IN\n"); ++ ++ my_workqueue_init(alsa_stream); ++ ++ ret = bcm2835_audio_open_connection(alsa_stream); ++ if (ret != 0) { ++ ret = -1; ++ goto exit; ++ } ++ instance = alsa_stream->instance; ++ ++ vcos_mutex_lock(&instance->vchi_mutex); ++ vchi_service_use(instance->vchi_handle[0]); ++ ++ m.type = VC_AUDIO_MSG_TYPE_OPEN; ++ ++ /* Send the message to the videocore */ ++ success = vchi_msg_queue(instance->vchi_handle[0], ++ &m, sizeof m, ++ VCHI_FLAGS_BLOCK_UNTIL_QUEUED, NULL); ++ ++ if (success != 0) { ++ LOG_ERR("%s: failed on vchi_msg_queue (status=%d)", ++ __func__, success); ++ ++ ret = -1; ++ goto unlock; ++ } ++ ++ ret = 0; ++ ++unlock: ++ vchi_service_release(instance->vchi_handle[0]); ++ vcos_mutex_unlock(&instance->vchi_mutex); ++exit: ++ LOG_DBG(" .. OUT\n"); ++ return ret; ++} ++ ++static int bcm2835_audio_set_ctls_chan(bcm2835_alsa_stream_t * alsa_stream, ++ bcm2835_chip_t * chip) ++{ ++ VC_AUDIO_MSG_T m; ++ AUDIO_INSTANCE_T *instance = alsa_stream->instance; ++ int32_t success; ++ int ret; ++ LOG_DBG(" .. IN\n"); ++ ++ LOG_INFO ++ (" Setting ALSA dest(%d), volume(%d)\n", chip->dest, chip->volume); ++ ++ vcos_mutex_lock(&instance->vchi_mutex); ++ vchi_service_use(instance->vchi_handle[0]); ++ ++ instance->got_result = 0; ++ instance->result = -1; ++ ++ m.type = VC_AUDIO_MSG_TYPE_CONTROL; ++ m.u.control.dest = chip->dest; ++ m.u.control.volume = chip->volume; ++ ++ /* Send the message to the videocore */ ++ success = vchi_msg_queue(instance->vchi_handle[0], ++ &m, sizeof m, ++ VCHI_FLAGS_BLOCK_UNTIL_QUEUED, NULL); ++ ++ if (success != 0) { ++ LOG_ERR("%s: failed on vchi_msg_queue (status=%d)", ++ __func__, success); ++ ++ ret = -1; ++ goto unlock; ++ } ++ ++ /* We are expecting a reply from the videocore */ ++ while (!instance->got_result) { ++ success = vcos_event_wait(&instance->msg_avail_event); ++ if (success != VCOS_SUCCESS) { ++ LOG_ERR("%s: failed on waiting for event (status=%d)", ++ __func__, success); ++ ++ ret = -1; ++ goto unlock; ++ } ++ } ++ ++ if (instance->result != 0) { ++ LOG_ERR("%s: result=%d", __func__, instance->result); ++ ++ ret = -1; ++ goto unlock; ++ } ++ ++ ret = 0; ++ ++unlock: ++ vchi_service_release(instance->vchi_handle[0]); ++ vcos_mutex_unlock(&instance->vchi_mutex); ++ ++ LOG_DBG(" .. OUT\n"); ++ return ret; ++} ++ ++int bcm2835_audio_set_ctls(bcm2835_chip_t * chip) ++{ ++ int i; ++ int ret = 0; ++ LOG_DBG(" .. IN\n"); ++ /* change ctls for all substreams */ ++ for (i = 0; i < MAX_SUBSTREAMS; i++) { ++ if (chip->avail_substreams & (1 << i)) { ++ if (!chip->alsa_stream[i]) ++ ret = 0; ++ else if (bcm2835_audio_set_ctls_chan ++ (chip->alsa_stream[i], chip) != 0) ++ ret = -1; ++ } ++ } ++ LOG_DBG(" .. OUT ret=%d\n", ret); ++ return ret; ++} ++ ++int bcm2835_audio_set_params(bcm2835_alsa_stream_t * alsa_stream, ++ uint32_t channels, uint32_t samplerate, ++ uint32_t bps) ++{ ++ VC_AUDIO_MSG_T m; ++ AUDIO_INSTANCE_T *instance = alsa_stream->instance; ++ int32_t success; ++ int ret; ++ LOG_DBG(" .. IN\n"); ++ ++ LOG_INFO ++ (" Setting ALSA channels(%d), samplerate(%d), bits-per-sample(%d)\n", ++ channels, samplerate, bps); ++ ++ /* resend ctls - alsa_stream may not have been open when first send */ ++ ret = bcm2835_audio_set_ctls_chan(alsa_stream, alsa_stream->chip); ++ if (ret != 0) { ++ LOG_ERR(" Alsa controls not supported\n"); ++ return -EINVAL; ++ } ++ ++ vcos_mutex_lock(&instance->vchi_mutex); ++ vchi_service_use(instance->vchi_handle[0]); ++ ++ instance->got_result = 0; ++ instance->result = -1; ++ ++ m.type = VC_AUDIO_MSG_TYPE_CONFIG; ++ m.u.config.channels = channels; ++ m.u.config.samplerate = samplerate; ++ m.u.config.bps = bps; ++ ++ /* Send the message to the videocore */ ++ success = vchi_msg_queue(instance->vchi_handle[0], ++ &m, sizeof m, ++ VCHI_FLAGS_BLOCK_UNTIL_QUEUED, NULL); ++ ++ if (success != 0) { ++ LOG_ERR("%s: failed on vchi_msg_queue (status=%d)", ++ __func__, success); ++ ++ ret = -1; ++ goto unlock; ++ } ++ ++ /* We are expecting a reply from the videocore */ ++ while (!instance->got_result) { ++ success = vcos_event_wait(&instance->msg_avail_event); ++ if (success != VCOS_SUCCESS) { ++ LOG_ERR("%s: failed on waiting for event (status=%d)", ++ __func__, success); ++ ++ ret = -1; ++ goto unlock; ++ } ++ } ++ ++ if (instance->result != 0) { ++ LOG_ERR("%s: result=%d", __func__, instance->result); ++ ++ ret = -1; ++ goto unlock; ++ } ++ ++ ret = 0; ++ ++unlock: ++ vchi_service_release(instance->vchi_handle[0]); ++ vcos_mutex_unlock(&instance->vchi_mutex); ++ ++ LOG_DBG(" .. OUT\n"); ++ return ret; ++} ++ ++int bcm2835_audio_setup(bcm2835_alsa_stream_t * alsa_stream) ++{ ++ LOG_DBG(" .. IN\n"); ++ ++ LOG_DBG(" .. OUT\n"); ++ ++ return 0; ++} ++ ++static int bcm2835_audio_start_worker(bcm2835_alsa_stream_t * alsa_stream) ++{ ++ VC_AUDIO_MSG_T m; ++ AUDIO_INSTANCE_T *instance = alsa_stream->instance; ++ int32_t success; ++ int ret; ++ LOG_DBG(" .. IN\n"); ++ ++ vcos_mutex_lock(&instance->vchi_mutex); ++ vchi_service_use(instance->vchi_handle[0]); ++ ++ m.type = VC_AUDIO_MSG_TYPE_START; ++ ++ /* Send the message to the videocore */ ++ success = vchi_msg_queue(instance->vchi_handle[0], ++ &m, sizeof m, ++ VCHI_FLAGS_BLOCK_UNTIL_QUEUED, NULL); ++ ++ if (success != 0) { ++ LOG_ERR("%s: failed on vchi_msg_queue (status=%d)", ++ __func__, success); ++ ++ ret = -1; ++ goto unlock; ++ } ++ ++ ret = 0; ++ ++unlock: ++ vchi_service_release(instance->vchi_handle[0]); ++ vcos_mutex_unlock(&instance->vchi_mutex); ++ LOG_DBG(" .. OUT\n"); ++ return ret; ++} ++ ++static int bcm2835_audio_stop_worker(bcm2835_alsa_stream_t * alsa_stream) ++{ ++ VC_AUDIO_MSG_T m; ++ AUDIO_INSTANCE_T *instance = alsa_stream->instance; ++ int32_t success; ++ int ret; ++ LOG_DBG(" .. IN\n"); ++ ++ vcos_mutex_lock(&instance->vchi_mutex); ++ vchi_service_use(instance->vchi_handle[0]); ++ ++ m.type = VC_AUDIO_MSG_TYPE_STOP; ++ m.u.stop.draining = alsa_stream->draining; ++ ++ /* Send the message to the videocore */ ++ success = vchi_msg_queue(instance->vchi_handle[0], ++ &m, sizeof m, ++ VCHI_FLAGS_BLOCK_UNTIL_QUEUED, NULL); ++ ++ if (success != 0) { ++ LOG_ERR("%s: failed on vchi_msg_queue (status=%d)", ++ __func__, success); ++ ++ ret = -1; ++ goto unlock; ++ } ++ ++ ret = 0; ++ ++unlock: ++ vchi_service_release(instance->vchi_handle[0]); ++ vcos_mutex_unlock(&instance->vchi_mutex); ++ LOG_DBG(" .. OUT\n"); ++ return ret; ++} ++ ++int bcm2835_audio_close(bcm2835_alsa_stream_t * alsa_stream) ++{ ++ VC_AUDIO_MSG_T m; ++ AUDIO_INSTANCE_T *instance = alsa_stream->instance; ++ int32_t success; ++ int ret; ++ LOG_DBG(" .. IN\n"); ++ ++ my_workqueue_quit(alsa_stream); ++ ++ vcos_mutex_lock(&instance->vchi_mutex); ++ vchi_service_use(instance->vchi_handle[0]); ++ ++ m.type = VC_AUDIO_MSG_TYPE_CLOSE; ++ instance->got_result = 0; ++ /* Send the message to the videocore */ ++ success = vchi_msg_queue(instance->vchi_handle[0], ++ &m, sizeof m, ++ VCHI_FLAGS_BLOCK_UNTIL_QUEUED, NULL); ++ ++ if (success != 0) { ++ LOG_ERR("%s: failed on vchi_msg_queue (status=%d)", ++ __func__, success); ++ ret = -1; ++ goto unlock; ++ } ++ while (!instance->got_result) { ++ success = vcos_event_wait(&instance->msg_avail_event); ++ if (success != VCOS_SUCCESS) { ++ LOG_ERR("%s: failed on waiting for event (status=%d)", ++ __func__, success); ++ ++ ret = -1; ++ goto unlock; ++ } ++ } ++ if (instance->result != 0) { ++ LOG_ERR("%s: failed result (status=%d)", ++ __func__, instance->result); ++ ++ ret = -1; ++ goto unlock; ++ } ++ ++ ret = 0; ++ ++unlock: ++ vchi_service_release(instance->vchi_handle[0]); ++ vcos_mutex_unlock(&instance->vchi_mutex); ++ ++ /* Stop the audio service */ ++ if (instance) { ++ vc_vchi_audio_deinit(instance); ++ alsa_stream->instance = NULL; ++ } ++ LOG_DBG(" .. OUT\n"); ++ return ret; ++} ++ ++int bcm2835_audio_write(bcm2835_alsa_stream_t * alsa_stream, uint32_t count, ++ void *src) ++{ ++ VC_AUDIO_MSG_T m; ++ AUDIO_INSTANCE_T *instance = alsa_stream->instance; ++ int32_t success; ++ int ret; ++ ++ LOG_DBG(" .. IN\n"); ++ ++ LOG_INFO(" Writing %d bytes from %p\n", count, src); ++ ++ vcos_mutex_lock(&instance->vchi_mutex); ++ vchi_service_use(instance->vchi_handle[0]); ++ ++ m.type = VC_AUDIO_MSG_TYPE_WRITE; ++ m.u.write.count = count; ++ m.u.write.callback = alsa_stream->fifo_irq_handler; ++ m.u.write.cookie = alsa_stream; ++ m.u.write.silence = src == NULL; ++ ++ /* Send the message to the videocore */ ++ success = vchi_msg_queue(instance->vchi_handle[0], ++ &m, sizeof m, ++ VCHI_FLAGS_BLOCK_UNTIL_QUEUED, NULL); ++ ++ if (success != 0) { ++ LOG_ERR("%s: failed on vchi_msg_queue (status=%d)", ++ __func__, success); ++ ++ ret = -1; ++ goto unlock; ++ } ++ LOG_DBG(" ... sent header\n"); ++ if (!m.u.write.silence) { ++ /* Send the message to the videocore */ ++ success = vchi_bulk_queue_transmit(instance->vchi_handle[0], ++ src, count, ++ 0 * ++ VCHI_FLAGS_BLOCK_UNTIL_QUEUED ++ + ++ 1 * ++ VCHI_FLAGS_BLOCK_UNTIL_DATA_READ, ++ NULL); ++ if (success != 0) { ++ LOG_ERR ++ ("%s: failed on vchi_bulk_queue_transmit (status=%d)", ++ __func__, success); ++ ++ ret = -1; ++ goto unlock; ++ } ++ } ++ ret = 0; ++ ++unlock: ++ vchi_service_release(instance->vchi_handle[0]); ++ vcos_mutex_unlock(&instance->vchi_mutex); ++ LOG_DBG(" .. OUT\n"); ++ return ret; ++} ++ ++/** ++ * Returns all buffers from arm->vc ++ */ ++void bcm2835_audio_flush_buffers(bcm2835_alsa_stream_t * alsa_stream) ++{ ++ LOG_DBG(" .. IN\n"); ++ LOG_DBG(" .. OUT\n"); ++ return; ++} ++ ++/** ++ * Forces VC to flush(drop) its filled playback buffers and ++ * return them the us. (VC->ARM) ++ */ ++void bcm2835_audio_flush_playback_buffers(bcm2835_alsa_stream_t * alsa_stream) ++{ ++ LOG_DBG(" .. IN\n"); ++ LOG_DBG(" .. OUT\n"); ++} ++ ++uint32_t bcm2835_audio_retrieve_buffers(bcm2835_alsa_stream_t * alsa_stream) ++{ ++ uint32_t count = atomic_read(&alsa_stream->retrieved); ++ atomic_sub(count, &alsa_stream->retrieved); ++ return count; ++} +--- /dev/null ++++ b/sound/arm/bcm2835.c +@@ -0,0 +1,424 @@ ++/***************************************************************************** ++* Copyright 2011 Broadcom Corporation. All rights reserved. ++* ++* Unless you and Broadcom execute a separate written software license ++* agreement governing use of this software, this software is licensed to you ++* under the terms of the GNU General Public License version 2, available at ++* http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). ++* ++* Notwithstanding the above, under no circumstances may you combine this ++* software in any way with any other Broadcom software provided under a ++* license other than the GPL, without Broadcom's express prior written ++* consent. ++*****************************************************************************/ ++ ++#include <linux/platform_device.h> ++ ++#include <linux/init.h> ++#include <linux/slab.h> ++#include <linux/module.h> ++ ++#include "bcm2835.h" ++ ++/* module parameters (see "Module Parameters") */ ++/* SNDRV_CARDS: maximum number of cards supported by this module */ ++static int index[MAX_SUBSTREAMS] = {[0 ... (MAX_SUBSTREAMS - 1)] = -1 }; ++static char *id[MAX_SUBSTREAMS] = {[0 ... (MAX_SUBSTREAMS - 1)] = NULL }; ++static int enable[MAX_SUBSTREAMS] = {[0 ... (MAX_SUBSTREAMS - 1)] = 1 }; ++ ++/* HACKY global pointers needed for successive probes to work : ssp ++ * But compared against the changes we will have to do in VC audio_ipc code ++ * to export 8 audio_ipc devices as a single IPC device and then monitor all ++ * four devices in a thread, this gets things done quickly and should be easier ++ * to debug if we run into issues ++ */ ++ ++static struct snd_card *g_card = NULL; ++static bcm2835_chip_t *g_chip = NULL; ++ ++static int snd_bcm2835_free(bcm2835_chip_t * chip) ++{ ++ kfree(chip); ++ return 0; ++} ++ ++/* component-destructor ++ * (see "Management of Cards and Components") ++ */ ++static int snd_bcm2835_dev_free(struct snd_device *device) ++{ ++ return snd_bcm2835_free(device->device_data); ++} ++ ++/* chip-specific constructor ++ * (see "Management of Cards and Components") ++ */ ++static int __devinit snd_bcm2835_create(struct snd_card *card, ++ struct platform_device *pdev, ++ bcm2835_chip_t ** rchip) ++{ ++ bcm2835_chip_t *chip; ++ int err; ++ static struct snd_device_ops ops = { ++ .dev_free = snd_bcm2835_dev_free, ++ }; ++ ++ *rchip = NULL; ++ ++ chip = kzalloc(sizeof(*chip), GFP_KERNEL); ++ if (chip == NULL) ++ return -ENOMEM; ++ ++ chip->card = card; ++ ++ err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops); ++ if (err < 0) { ++ snd_bcm2835_free(chip); ++ return err; ++ } ++ ++ *rchip = chip; ++ return 0; ++} ++ ++static int __devinit snd_bcm2835_alsa_probe(struct platform_device *pdev) ++{ ++ static int dev; ++ bcm2835_chip_t *chip; ++ struct snd_card *card; ++ int err; ++ printk(KERN_INFO "### snd_bcm2835_alsa_probe %p ###", pdev); ++ ++ printk ++ ("############ PROBING FOR bcm2835 ALSA device (%d):(%d) ###############\n", ++ dev, enable[dev]); ++ ++ if (dev >= MAX_SUBSTREAMS) ++ return -ENODEV; ++ ++ if (!enable[dev]) { ++ dev++; ++ return -ENOENT; ++ } ++ ++ if (dev > 0) ++ goto add_register_map; ++ ++ printk("Creating card...\n"); ++ err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &g_card); ++ if (err < 0) ++ goto out; ++ ++ snd_card_set_dev(g_card, &pdev->dev); ++ strcpy(g_card->driver, "BRCM bcm2835 ALSA Driver"); ++ strcpy(g_card->shortname, "bcm2835 ALSA"); ++ sprintf(g_card->longname, "%s", g_card->shortname); ++ ++ printk("Creating device/chip ..\n"); ++ err = snd_bcm2835_create(g_card, pdev, &chip); ++ if (err < 0) { ++ printk(KERN_ERR "Failed to create bcm2835 chip\n"); ++ goto out_bcm2835_create; ++ } ++ ++ g_chip = chip; ++ err = snd_bcm2835_new_pcm(chip); ++ if (err < 0) { ++ printk(KERN_ERR "Failed to create new BCM2835 pcm device\n"); ++ goto out_bcm2835_new_pcm; ++ } ++ ++ printk("Adding controls ..\n"); ++ err = snd_bcm2835_new_ctl(chip); ++ if (err < 0) { ++ printk(KERN_ERR "Failed to create new BCM2835 ctl\n"); ++ goto out_bcm2835_new_ctl; ++ } ++ ++add_register_map: ++ card = g_card; ++ chip = g_chip; ++ ++ BUG_ON(!(card && chip)); ++ ++ chip->avail_substreams |= (1 << dev); ++ chip->pdev[dev] = pdev; ++ ++ if (dev == 0) { ++ printk("Registering card ....\n"); ++ err = snd_card_register(card); ++ if (err < 0) { ++ printk(KERN_ERR ++ "Failed to register bcm2835 ALSA card \n"); ++ goto out_card_register; ++ } ++ platform_set_drvdata(pdev, card); ++ printk("bcm2835 ALSA CARD CREATED!\n"); ++ } else { ++ printk("bcm2835 ALSA CHIP CREATED!\n"); ++ platform_set_drvdata(pdev, (void *)dev); ++ } ++ ++ dev++; ++ ++ return 0; ++ ++out_card_register: ++out_bcm2835_new_ctl: ++out_bcm2835_new_pcm: ++out_bcm2835_create: ++ BUG_ON(!g_card); ++ if (snd_card_free(g_card)) ++ printk(KERN_ERR "Failed to free Registered alsa card\n"); ++ g_card = NULL; ++out: ++ dev = SNDRV_CARDS; /* stop more avail_substreams from being probed */ ++ printk(KERN_ERR "BCM2835 ALSA Probe failed !!\n"); ++ return err; ++} ++ ++static int snd_bcm2835_alsa_remove(struct platform_device *pdev) ++{ ++ uint32_t idx; ++ void *drv_data; ++ ++ drv_data = platform_get_drvdata(pdev); ++ ++ if (drv_data == (void *)g_card) { ++ /* This is the card device */ ++ snd_card_free((struct snd_card *)drv_data); ++ g_card = NULL; ++ g_chip = NULL; ++ } else { ++ idx = (uint32_t) drv_data; ++ if (g_card != NULL) { ++ BUG_ON(!g_chip); ++ /* We pass chip device numbers in audio ipc devices ++ * other than the one we registered our card with ++ */ ++ idx = (uint32_t) drv_data; ++ BUG_ON(!idx || idx > MAX_SUBSTREAMS); ++ g_chip->avail_substreams &= ~(1 << idx); ++ /* There should be atleast one substream registered ++ * after we are done here, as it wil be removed when ++ * the *remove* is called for the card device ++ */ ++ BUG_ON(!g_chip->avail_substreams); ++ } ++ } ++ ++ platform_set_drvdata(pdev, NULL); ++ ++ return 0; ++} ++ ++#ifdef CONFIG_PM ++static int snd_bcm2835_alsa_suspend(struct platform_device *pdev, ++ pm_message_t state) ++{ ++ return 0; ++} ++ ++static int snd_bcm2835_alsa_resume(struct platform_device *pdev) ++{ ++ return 0; ++} ++ ++#endif ++ ++static struct platform_driver bcm2835_alsa0_driver = { ++ .probe = snd_bcm2835_alsa_probe, ++ .remove = snd_bcm2835_alsa_remove, ++#ifdef CONFIG_PM ++ .suspend = snd_bcm2835_alsa_suspend, ++ .resume = snd_bcm2835_alsa_resume, ++#endif ++ .driver = { ++ .name = "bcm2835_AUD0", ++ .owner = THIS_MODULE, ++ }, ++}; ++ ++static struct platform_driver bcm2835_alsa1_driver = { ++ .probe = snd_bcm2835_alsa_probe, ++ .remove = snd_bcm2835_alsa_remove, ++#ifdef CONFIG_PM ++ .suspend = snd_bcm2835_alsa_suspend, ++ .resume = snd_bcm2835_alsa_resume, ++#endif ++ .driver = { ++ .name = "bcm2835_AUD1", ++ .owner = THIS_MODULE, ++ }, ++}; ++ ++static struct platform_driver bcm2835_alsa2_driver = { ++ .probe = snd_bcm2835_alsa_probe, ++ .remove = snd_bcm2835_alsa_remove, ++#ifdef CONFIG_PM ++ .suspend = snd_bcm2835_alsa_suspend, ++ .resume = snd_bcm2835_alsa_resume, ++#endif ++ .driver = { ++ .name = "bcm2835_AUD2", ++ .owner = THIS_MODULE, ++ }, ++}; ++ ++static struct platform_driver bcm2835_alsa3_driver = { ++ .probe = snd_bcm2835_alsa_probe, ++ .remove = snd_bcm2835_alsa_remove, ++#ifdef CONFIG_PM ++ .suspend = snd_bcm2835_alsa_suspend, ++ .resume = snd_bcm2835_alsa_resume, ++#endif ++ .driver = { ++ .name = "bcm2835_AUD3", ++ .owner = THIS_MODULE, ++ }, ++}; ++ ++static struct platform_driver bcm2835_alsa4_driver = { ++ .probe = snd_bcm2835_alsa_probe, ++ .remove = snd_bcm2835_alsa_remove, ++#ifdef CONFIG_PM ++ .suspend = snd_bcm2835_alsa_suspend, ++ .resume = snd_bcm2835_alsa_resume, ++#endif ++ .driver = { ++ .name = "bcm2835_AUD4", ++ .owner = THIS_MODULE, ++ }, ++}; ++ ++static struct platform_driver bcm2835_alsa5_driver = { ++ .probe = snd_bcm2835_alsa_probe, ++ .remove = snd_bcm2835_alsa_remove, ++#ifdef CONFIG_PM ++ .suspend = snd_bcm2835_alsa_suspend, ++ .resume = snd_bcm2835_alsa_resume, ++#endif ++ .driver = { ++ .name = "bcm2835_AUD5", ++ .owner = THIS_MODULE, ++ }, ++}; ++ ++static struct platform_driver bcm2835_alsa6_driver = { ++ .probe = snd_bcm2835_alsa_probe, ++ .remove = snd_bcm2835_alsa_remove, ++#ifdef CONFIG_PM ++ .suspend = snd_bcm2835_alsa_suspend, ++ .resume = snd_bcm2835_alsa_resume, ++#endif ++ .driver = { ++ .name = "bcm2835_AUD6", ++ .owner = THIS_MODULE, ++ }, ++}; ++ ++static struct platform_driver bcm2835_alsa7_driver = { ++ .probe = snd_bcm2835_alsa_probe, ++ .remove = snd_bcm2835_alsa_remove, ++#ifdef CONFIG_PM ++ .suspend = snd_bcm2835_alsa_suspend, ++ .resume = snd_bcm2835_alsa_resume, ++#endif ++ .driver = { ++ .name = "bcm2835_AUD7", ++ .owner = THIS_MODULE, ++ }, ++}; ++ ++static int __devinit bcm2835_alsa_device_init(void) ++{ ++ int err; ++ err = platform_driver_register(&bcm2835_alsa0_driver); ++ if (err) { ++ printk("Error registering bcm2835_alsa0_driver %d .\n", err); ++ goto out; ++ } ++ ++ err = platform_driver_register(&bcm2835_alsa1_driver); ++ if (err) { ++ printk("Error registering bcm2835_alsa1_driver %d .\n", err); ++ goto unregister_0; ++ } ++ ++ err = platform_driver_register(&bcm2835_alsa2_driver); ++ if (err) { ++ printk("Error registering bcm2835_alsa2_driver %d .\n", err); ++ goto unregister_1; ++ } ++ ++ err = platform_driver_register(&bcm2835_alsa3_driver); ++ if (err) { ++ printk("Error registering bcm2835_alsa3_driver %d .\n", err); ++ goto unregister_2; ++ } ++ ++ err = platform_driver_register(&bcm2835_alsa4_driver); ++ if (err) { ++ printk("Error registering bcm2835_alsa4_driver %d .\n", err); ++ goto unregister_3; ++ } ++ ++ err = platform_driver_register(&bcm2835_alsa5_driver); ++ if (err) { ++ printk("Error registering bcm2835_alsa5_driver %d .\n", err); ++ goto unregister_4; ++ } ++ ++ err = platform_driver_register(&bcm2835_alsa6_driver); ++ if (err) { ++ printk("Error registering bcm2835_alsa6_driver %d .\n", err); ++ goto unregister_5; ++ } ++ ++ err = platform_driver_register(&bcm2835_alsa7_driver); ++ if (err) { ++ printk("Error registering bcm2835_alsa7_driver %d .\n", err); ++ goto unregister_6; ++ } ++ printk(KERN_INFO "### BCM2835 ALSA driver init %s ### \n", ++ err ? "FAILED" : "OK"); ++ ++ return 0; ++ ++unregister_6: ++ platform_driver_unregister(&bcm2835_alsa6_driver); ++unregister_5: ++ platform_driver_unregister(&bcm2835_alsa5_driver); ++unregister_4: ++ platform_driver_unregister(&bcm2835_alsa4_driver); ++unregister_3: ++ platform_driver_unregister(&bcm2835_alsa3_driver); ++unregister_2: ++ platform_driver_unregister(&bcm2835_alsa2_driver); ++unregister_1: ++ platform_driver_unregister(&bcm2835_alsa1_driver); ++unregister_0: ++ platform_driver_unregister(&bcm2835_alsa0_driver); ++out: ++ return err; ++} ++ ++static void __devexit bcm2835_alsa_device_exit(void) ++{ ++ platform_driver_unregister(&bcm2835_alsa0_driver); ++ platform_driver_unregister(&bcm2835_alsa1_driver); ++ platform_driver_unregister(&bcm2835_alsa2_driver); ++ platform_driver_unregister(&bcm2835_alsa3_driver); ++ platform_driver_unregister(&bcm2835_alsa4_driver); ++ platform_driver_unregister(&bcm2835_alsa5_driver); ++ platform_driver_unregister(&bcm2835_alsa6_driver); ++ platform_driver_unregister(&bcm2835_alsa7_driver); ++} ++ ++late_initcall(bcm2835_alsa_device_init); ++module_exit(bcm2835_alsa_device_exit); ++ ++MODULE_AUTHOR("Dom Cobley"); ++MODULE_DESCRIPTION("Alsa driver for BCM2835 chip"); ++MODULE_LICENSE("GPL"); ++MODULE_ALIAS("platform:bcm2835_alsa"); +--- /dev/null ++++ b/sound/arm/bcm2835.h +@@ -0,0 +1,242 @@ ++/***************************************************************************** ++* Copyright 2011 Broadcom Corporation. All rights reserved. ++* ++* Unless you and Broadcom execute a separate written software license ++* agreement governing use of this software, this software is licensed to you ++* under the terms of the GNU General Public License version 2, available at ++* http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). ++* ++* Notwithstanding the above, under no circumstances may you combine this ++* software in any way with any other Broadcom software provided under a ++* license other than the GPL, without Broadcom's express prior written ++* consent. ++*****************************************************************************/ ++ ++#ifndef __SOUND_ARM_BCM2835_H ++#define __SOUND_ARM_BCM2835_H ++ ++#define SUBSTREAM_NUM 1 ++ ++#include <linux/device.h> ++#include <linux/list.h> ++#include <linux/interrupt.h> ++#include <linux/wait.h> ++#include <sound/core.h> ++#include <sound/initval.h> ++#include <sound/pcm.h> ++#include <sound/pcm_params.h> ++#include <linux/workqueue.h> ++ ++/* #define DUMP_RAW_DATA */ ++//#define AUDIO_DEBUG_ENABLE ++//#define AUDIO_VERBOSE_DEBUG_ENABLE ++ ++/* Debug macros */ ++#ifdef AUDIO_DEBUG_ENABLE ++ ++#ifdef AUDIO_VERBOSE_DEBUG_ENABLE ++ ++#define audio_debug(fmt, arg...) \ ++ printk(KERN_INFO"%s:%d " fmt, __func__, __LINE__, ##arg) ++ ++#define audio_info(fmt, arg...) \ ++ printk(KERN_INFO"%s:%d " fmt, __func__, __LINE__, ##arg) ++ ++#else ++ ++#define audio_debug(fmt, arg...) do {} while (0) ++ ++#define audio_info(fmt, arg...) do {} while (0) ++ ++#endif /* AUDIO_VERBOSE_DEBUG_ENABLE */ ++ ++#else ++ ++#define audio_debug(fmt, arg...) do {} while (0) ++ ++#define audio_info(fmt, arg...) do {} while (0) ++ ++#endif /* AUDIO_DEBUG_ENABLE */ ++ ++#define audio_error(fmt, arg...) \ ++ printk(KERN_ERR"%s:%d " fmt, __func__, __LINE__, ##arg) ++ ++#define audio_warning(fmt, arg...) \ ++ printk(KERN_WARNING"%s:%d " fmt, __func__, __LINE__, ##arg) ++ ++#define audio_alert(fmt, arg...) \ ++ printk(KERN_ALERT"%s:%d " fmt, __func__, __LINE__, ##arg) ++ ++#define MAX_SUBSTREAMS (8) ++#define AVAIL_SUBSTREAMS_MASK (0xff) ++ ++#define AUDIO_IPC_BLOCK_NUM_BUFFERS (8) ++#define AUDIO_IPC_BLOCK_BUFFER_SIZE (1024*8) ++ ++#define AUDIO_CONTROL_OFFSET (0x00) ++#define CTRL_EN_SHIFT (0) ++#define CTRL_EN_MASK (0x00000001) ++#define CTRL_PLAY_SHIFT (1) ++#define CTRL_PLAY_MASK (0x00000002) ++#define CTRL_MUTE_SHIFT (2) ++#define CTRL_MUTE_MASK (0x00000004) ++#define CTRL_SETUP_SHIFT (3) ++#define CTRL_SETUP_MASK (0x00000008) ++#define CTRL_FLUSH_SHIFT (4) ++#define CTRL_FLUSH_MASK (0x00000010) ++#define CTRL_STOPMODE_SHIFT (5) ++#define CTRL_STOPMODE_MASK (0x00000020) ++ ++#define AUDIO_STATUS_OFFSET (0x04) ++#define STAT_EN_SHIFT (0) ++#define STAT_EN_MASK (0x00000001) ++#define STAT_PLAY_SHIFT (1) ++#define STAT_PLAY_MASK (0x00000002) ++#define STAT_MUTE_SHIFT (2) ++#define STAT_MUTE_MASK (0x00000004) ++#define STAT_SETUP_SHIFT (3) ++#define STAT_SETUP_MASK (0x00000008) ++#define STAT_FLUSH_SHIFT (4) ++#define STAT_FLUSH_MASK (0x00000010) ++#define STAT_STOPMODE_SHIFT (5) ++#define STAT_STOPMODE_MASK (0x00000020) ++ ++/* Interrupt status */ ++#define AUDIO_INTSTAT_OFFSET (0x08) ++#define INTSTAT_CONTROL_SHIFT (0) ++#define INTSTAT_CONTROL_MASK (0x0000000f) ++#define INTSTAT_FIFO_SHIFT (4) ++#define INTSTAT_FIFO_MASK (0x000000f0) ++ ++/* Configuration */ ++#define AUDIO_DESTINATION_OFFSET (0x0C) ++#define AUDIO_SAMPLE_RATE_OFFSET (0x10) ++#define AUDIO_BIT_RATE_OFFSET (0x14) ++#define AUDIO_VOLUME_OFFSET (0x18) ++#define AUDIO_CHANNELS_OFFSET (0x1C) ++ ++/* Implemention of peterson's algorithm for shared memory semaphores */ ++#define AUDIO_FLAG0_OFFSET (0x20) ++#define AUDIO_FLAG1_OFFSET (0x24) ++#define AUDIO_TURN_OFFSET (0x28) ++ ++/* Fifo registers */ ++#define AUDIO_IN_WRITE_PTR_OFFSET (0x30) ++#define AUDIO_IN_READ_PTR_OFFSET (0x34) ++#define AUDIO_IN_FIFO_SIZE_OFFSET (0x38) ++#define AUDIO_IN_FIFO_ENTRY_OFFSET (0x3C) ++#define AUDIO_IN_FIFO_START_OFFSET (0x40) ++ ++/* 8 entries here of 4 words each = 0x80 gap from 0x50 */ ++#define AUDIO_IN_FIFO_OFFSET (0x50) ++ ++#define AUDIO_OUT_WRITE_PTR_OFFSET (0xD0) ++#define AUDIO_OUT_READ_PTR_OFFSET (0xD4) ++#define AUDIO_OUT_FIFO_SIZE_OFFSET (0xD8) ++#define AUDIO_OUT_FIFO_ENTRY_OFFSET (0xDC) ++#define AUDIO_OUT_FIFO_START_OFFSET (0xE0) ++ ++/* 8 entries here of 4 words each = 0x80 gap from 0xF0 */ ++#define AUDIO_OUT_FIFO_OFFSET (0xF0) ++ ++/* Some constants for values .. */ ++typedef enum { ++ AUDIO_DEST_AUTO = 0, ++ AUDIO_DEST_HEADPHONES = 1, ++ AUDIO_DEST_HDMI = 2, ++ AUDIO_DEST_MAX, ++} SND_BCM2835_ROUTE_T; ++ ++typedef enum { ++ PCM_PLAYBACK_VOLUME, ++ PCM_PLAYBACK_MUTE, ++ PCM_PLAYBACK_DEVICE, ++} SND_BCM2835_CTRL_T; ++ ++/* this struct is tightly packed - its size is 16bytes */ ++typedef struct { ++ uint32_t buffer_id; ++ uint32_t buffer_size; ++ uint32_t buffer_ptr; ++ uint32_t spare; ++ ++} AUDIO_FIFO_ENTRY_T; ++ ++/* definition of the chip-specific record */ ++typedef struct bcm2835_chip { ++ struct snd_card *card; ++ struct snd_pcm *pcm; ++ /* Bitmat for valid reg_base and irq numbers */ ++ uint32_t avail_substreams; ++ struct platform_device *pdev[MAX_SUBSTREAMS]; ++ struct bcm2835_alsa_stream *alsa_stream[MAX_SUBSTREAMS]; ++ ++ int volume; ++ int dest; ++ int mute; ++} bcm2835_chip_t; ++ ++typedef struct bcm2835_audio_buffer { ++ uint32_t buffer_id; ++ phys_addr_t bus_addr; ++ uint8_t __iomem *start; ++ uint32_t size; ++ uint32_t data_left; ++ struct list_head link; ++ ++} bcm2835_audio_buffer_t; ++ ++typedef struct bcm2835_alsa_stream { ++ bcm2835_chip_t *chip; ++ struct snd_pcm_substream *substream; ++ ++ struct semaphore buffers_update_sem; ++ struct semaphore control_sem; ++ spinlock_t lock; ++ volatile uint32_t control; ++ volatile uint32_t status; ++ ++ int open; ++ int running; ++ int draining; ++ ++#ifdef DUMP_RAW_DATA ++ /* for debug */ ++ int file; ++#endif ++ unsigned int pos; ++ unsigned int buffer_size; ++ unsigned int period_size; ++ ++ uint32_t enable_fifo_irq; ++ irq_handler_t fifo_irq_handler; ++ ++ atomic_t retrieved; ++ struct opaque_AUDIO_INSTANCE_T *instance; ++ struct workqueue_struct *my_wq; ++ int idx; ++} bcm2835_alsa_stream_t; ++ ++int snd_bcm2835_new_ctl(bcm2835_chip_t * chip); ++int snd_bcm2835_new_pcm(bcm2835_chip_t * chip); ++ ++void bcm2835_audio_fifo_get_lock(bcm2835_alsa_stream_t * alsa_stream); ++void bcm2835_audio_fifo_put_lock(bcm2835_alsa_stream_t * alsa_stream); ++ ++int bcm2835_audio_open(bcm2835_alsa_stream_t * alsa_stream); ++int bcm2835_audio_close(bcm2835_alsa_stream_t * alsa_stream); ++int bcm2835_audio_set_params(bcm2835_alsa_stream_t * alsa_stream, ++ uint32_t channels, uint32_t samplerate, ++ uint32_t bps); ++int bcm2835_audio_setup(bcm2835_alsa_stream_t * alsa_stream); ++int bcm2835_audio_start(bcm2835_alsa_stream_t * alsa_stream); ++int bcm2835_audio_stop(bcm2835_alsa_stream_t * alsa_stream); ++int bcm2835_audio_set_ctls(bcm2835_chip_t * chip); ++int bcm2835_audio_write(bcm2835_alsa_stream_t * alsa_stream, uint32_t count, ++ void *src); ++//uint32_t bcm2835_audio_buffers_consumed_bytes(bcm2835_alsa_stream_t *alsa_stream); ++uint32_t bcm2835_audio_retrieve_buffers(bcm2835_alsa_stream_t * alsa_stream); ++void bcm2835_audio_flush_buffers(bcm2835_alsa_stream_t * alsa_stream); ++void bcm2835_audio_flush_playback_buffers(bcm2835_alsa_stream_t * alsa_stream); ++ ++#endif /* __SOUND_ARM_BCM2835_H */ +--- /dev/null ++++ b/sound/arm/vc_vchi_audioserv_defs.h +@@ -0,0 +1,112 @@ ++/***************************************************************************** ++* Copyright 2011 Broadcom Corporation. All rights reserved. ++* ++* Unless you and Broadcom execute a separate written software license ++* agreement governing use of this software, this software is licensed to you ++* under the terms of the GNU General Public License version 2, available at ++* http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). ++* ++* Notwithstanding the above, under no circumstances may you combine this ++* software in any way with any other Broadcom software provided under a ++* license other than the GPL, without Broadcom's express prior written ++* consent. ++*****************************************************************************/ ++ ++#ifndef _VC_AUDIO_DEFS_H_ ++#define _VC_AUDIO_DEFS_H_ ++ ++// FourCC code used for VCHI connection ++#define VC_AUDIO_SERVER_NAME MAKE_FOURCC("AUDS") ++ ++// Maximum message length ++#define VC_AUDIO_MAX_MSG_LEN (sizeof( VC_AUDIO_MSG_T )) ++ ++// List of screens that are currently supported ++// All message types supported for HOST->VC direction ++typedef enum { ++ VC_AUDIO_MSG_TYPE_RESULT, // Generic result ++ VC_AUDIO_MSG_TYPE_COMPLETE, // Generic result ++ VC_AUDIO_MSG_TYPE_CONFIG, // Configure audio ++ VC_AUDIO_MSG_TYPE_CONTROL, // Configure audio ++ VC_AUDIO_MSG_TYPE_OPEN, // Configure audio ++ VC_AUDIO_MSG_TYPE_CLOSE, // Configure audio ++ VC_AUDIO_MSG_TYPE_START, // Configure audio ++ VC_AUDIO_MSG_TYPE_STOP, // Configure audio ++ VC_AUDIO_MSG_TYPE_WRITE, // Configure audio ++ VC_AUDIO_MSG_TYPE_MAX ++} VC_AUDIO_MSG_TYPE; ++ ++// configure the audio ++typedef struct { ++ uint32_t channels; ++ uint32_t samplerate; ++ uint32_t bps; ++ ++} VC_AUDIO_CONFIG_T; ++ ++typedef struct { ++ uint32_t volume; ++ uint32_t dest; ++ ++} VC_AUDIO_CONTROL_T; ++ ++// audio ++typedef struct { ++ uint32_t dummy; ++ ++} VC_AUDIO_OPEN_T; ++ ++// audio ++typedef struct { ++ uint32_t dummy; ++ ++} VC_AUDIO_CLOSE_T; ++// audio ++typedef struct { ++ uint32_t dummy; ++ ++} VC_AUDIO_START_T; ++// audio ++typedef struct { ++ uint32_t draining; ++ ++} VC_AUDIO_STOP_T; ++ ++// configure the write audio samples ++typedef struct { ++ uint32_t count; // in bytes ++ void *callback; ++ void *cookie; ++ uint32_t silence; ++} VC_AUDIO_WRITE_T; ++ ++// Generic result for a request (VC->HOST) ++typedef struct { ++ int32_t success; // Success value ++ ++} VC_AUDIO_RESULT_T; ++ ++// Generic result for a request (VC->HOST) ++typedef struct { ++ int32_t count; // Success value ++ void *callback; ++ void *cookie; ++} VC_AUDIO_COMPLETE_T; ++ ++// Message header for all messages in HOST->VC direction ++typedef struct { ++ int32_t type; // Message type (VC_AUDIO_MSG_TYPE) ++ union { ++ VC_AUDIO_CONFIG_T config; ++ VC_AUDIO_CONTROL_T control; ++ VC_AUDIO_OPEN_T open; ++ VC_AUDIO_CLOSE_T close; ++ VC_AUDIO_START_T start; ++ VC_AUDIO_STOP_T stop; ++ VC_AUDIO_WRITE_T write; ++ VC_AUDIO_RESULT_T result; ++ VC_AUDIO_COMPLETE_T complete; ++ } u; ++} VC_AUDIO_MSG_T; ++ ++#endif // _VC_AUDIO_DEFS_H_ |