mirror of
git://projects.qi-hardware.com/openwrt-xburst.git
synced 2024-11-28 01:11:52 +02:00
1df0438a5e
Add support for Raspberry Pi / brcm2708 / 2835 Signed-off-by: Ian Ridge <ianridge [at] gmail.com> git-svn-id: svn://svn.openwrt.org/openwrt/trunk@32825 3c298f89-4303-0410-b956-a3cf2f4a3e73
10489 lines
310 KiB
Diff
10489 lines
310 KiB
Diff
--- 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_
|