--- 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 #include #include +#include #include #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 #include #include +#include #include #include #include @@ -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 #include #include +#include +#include +#include #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; iclient_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 #include #include +#include #include +#include #include #include @@ -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 #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 + * */ #include #include #include #include #include -#include #include #include #include @@ -22,6 +25,8 @@ #include #include #include +#include +#include #include #include @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#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 +#include + +#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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 + +#include +#include +#include + +#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 +#include +#include +#include +#include +#include +#include +#include +#include + +/* #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_